Archive for December, 2014


niceScroll doesn’t play nice

Whilst working on a Pimcore site, I had this irritating problem with my wysiwig editors, in that if you pressed space, instead of typing a space, it scrolled the page. I knew it must be some javascript library or other included in my template, and it turns out that the culprit was niceScroll (http://areaaperta.com/nicescroll/).

Found some funny forum posts, some angry guy sarcastically saying, you know, space, that separates words?

Anyway, there’s an option to disable space bar scrolling (which in my opinion should be disabled by default). Anyway, to sort it, just feed in the spacebarenabled: false option:

//nicescroll
    $("html").niceScroll({
        zindex:999,
        cursorborder:"",
        cursorborderradius:"2px",
        cursorcolor:"#191919",
        cursoropacitymin:.5,
        spacebarenabled:false
    });
    function initNice() 
    {
        if($(window).innerWidth() <= 960) 
        {
            $('html').niceScroll().remove();
        } 
        else 
        {
            $("html").niceScroll({zindex:999,cursorborder:"",cursorborderradius:"2px",cursorcolor:"#191919",cursoropacitymin:.5});
        }
    }
    $(window).load(initNice);
    $(window).resize(initNice);
Advertisements

Getting Started with Pimcore

I’ve only just started using Pimcore, but of all the CMS’es out there, this looks the best. Anyway, in the admin panel, you can create new pages etc. As the developer, we can create the templates and views, but restrict to just the editable areas for standard cms users. These editable areas are called areablocks.

For instance, in my homepage.phtml, I have the following:

<?= $this->areablock('some-id-or-other'); ?>

Once there is an areablock on a view, when you are in the admin panel, you can select an area block from the collapsible menu and literally just drag it into place, and start editing.

Customised Area files go in the website/views/areas folder. I’m making a Carousel, so in website/views/areas, I created a gallery-carousel folder, and inside that I created a view.phtml file (or .php, depending on your pimcore prefs), and a area.xml:

<?xml version="1.0"?>
<zend-config xmlns:zf="http://framework.zend.com/xml/zend-config-xml/1.0/">
    <id>tabbed-slider-text</id>
    <name>Slider (Tabs/Text)</name>
    <description></description>
    <author>pimcore.org</author>
    <version>1.0</version>
</zend-config>
<section class="area-tabbed-slider-text">

    <?php if($this->editmode) { ?>
        <div class="alert alert-info">
            How many tabs you want to show?

            <?php
                // prepare the store
                $selectStore = [];
                for($i=2; $i<6; $i++) {
                    $selectStore[] = [$i, $i];
                }
            ?>
            <?= $this->select("slides",[
                "store" => $selectStore,
                "reload" => true,
                "width" => 60
            ]); ?>
        </div>
    <?php } ?>

    <?php
        $id = "tabbed-slider-" . uniqid();
        $slides = 2; // default value
        if(!$this->select("slides")->isEmpty())
        {
            $slides = (int) $this->select("slides")->getData();
        }
    ?>
    <div id="<?= $id ?>" class="tabbed-slider carousel slide">
        <div class="carousel-inner">
            <?php for($i=0; $i<$slides; $i++) { ?>
                <div class="item <?= ($i==0 ? "active" : "") ?> item-<?= $i ?> <?= $id . "-" . $i ?>">
                    <?php if(!$this->image("image_" . $i)->isEmpty() || $this->editmode) { ?>
                        <?= $this->image("image_" . $i, [
                            "dropClass" => $id . "-" . $i,
                            "thumbnail" => ""
                        ]); ?>
                    <?php } ?>
                    <div class="carousel-caption">
                        <h1><?= $this->input("headline_" . $i) ?></h1>
                        <p><?= $this->textarea("description_" . $i, ["nl2br" => true]) ?></p>
                    </div>
                </div>
            <?php } ?>
        </div>
        <!-- End Carousel Inner -->
        <ul class="nav nav-pills nav-justified">
            <?php for($i=0; $i<$slides; $i++) { ?>
                <li data-target="#<?= $id ?>" data-slide-to="<?= $i ?>" class="<?= ($i==0 ? "active" : "") ?> item-<?= $i ?>">
                    <a href="#">
                        <?= $this->input("pill-title_" . $i) ?>
                        <small><?= $this->input("pill-small_" . $i) ?></small>
                    </a></li>
            <?php } ?>
        </ul>
    </div>

</section>

The customised area blocks must be enabled before they will appear in Pimcore. Click on Extras -> Extensions in the Admin section, and you will see each folder you have added. Click the icon to enable/disable the area. Now if you refresh your page with the $this->areablock(…) code, you should see your customised area available to use!

Last thing! Pimcore has all manner of caching going on! Go into Settings > Cache in order to clear it and see your changes!

Pimcore looks to be a great CMS! I haven’t played around with it much but if you are a fan of Zend Framework 1 then you’ll be right at home using it!

Right now, I’m designing the front end for a small promotional site that requires a CMS admin panel etc, and I’m rendering a customised Navigation view, in order to get the Bootstrap classes that I want.

Pimcore allows you to run multiple sites from the one system. So first we put a check in our layout.phtml :

$navStartNode = $this->document->getProperty("navigationRoot");
    if(!$navStartNode instanceof Document_Page) 
    {
        if(Site::isSiteRequest()) 
        {
            $site = Site::getCurrentSite();
            $navStartNode = $site->getRootDocument();
        } 
        else 
        {
            $navStartNode = Document::getById(1);
        }
    }

The root site always has Document ID 1. In the Pimcore admin panel, you right click and add a new page, then right click and you can tell it to use that page as an actual site, so you can add as many as you like!

In the layout.phtml (or view partial like header.phtml), I have the following:

<div class="navbar-collapse collapse">
<?php
        $navigation = $this->pimcoreNavigation()->getNavigation($this->document, $navStartNode);;
        echo $this->navigation()->menu()->renderPartial($navigation, 'elements/theme-nav.phtml', array(
                "maxDepth" => 1,
                "ulClass" => "nav navbar-nav"
          ));
 ?>
</div>

Pimcore checks in the views folder for the partial (elements/theme-nav.phtml in my example). In my project the views folder is located in /website/views/scripts, so create an elements folder, and create theme-nav.phtml:

<ul class="nav navbar-nav"  data-0="margin-top:20px;" data-300="margin-top:5px;">
    <?php
    foreach ($this->container as $page) 
    {
        echo '<li>'.$this->navigation()->menu()->htmlify($page).'</li>';
    }
    ?>
</ul>

And that’s it! Your Navigation is now rendered in the way we want!

PHP CLI commands in Debian

This problem was infuriating. After having upgraded my Vagrant Box to run PHP 5.6, I was looking forward to trying out phpdbg, the new built in debugger that ships with PHP 5.6.

It turns out that Debian use their own moronic naming system for their PHP package commands. I was typing in phpdbg into the shell, and all I got in return was ‘command not found’.

I tried sudo apt-get install php5-phpdbg, yet it told me that it was already the latest version!

I eventually found it in the /usr/bin folder, under the name php5dbg. Why?

For reference, you can run this command to help find it: (if dpkg is installed)

dpkg -L <pkgname> | grep '/bin/'

What a waste of time, I hope this helps someone.

This is remarkably simple! First, BACK UP YOUR DB.

Backed up? Good. You dont need to back your web files up if they are being mounted from a shared folder.

Open your puPHPet config.yml, scroll down to the php section, and change version from ’55’ to ’56’, and save it.

Next, type vagrant destroy, to remove the old stuff, and then vagrant up, which will re-initialise the server with your shiny new PHP version!

Getting this error? Set your form to  enctype=”multipart/form-data”. Job done.

Injecting Closures into your Classes

I wanted to reuse a class of mine, which generated a <ul> with links, only this time I wanted to alter the link text using a custom function (closure) in the constructor.

<?= $this->generateUl($existing_arg1, $existing_arg2, function($args){ //do stuff } ); ?>

Inside the class constructor, I set the following:

public function __construct($existing_arg1, $existing_arg2, Callable $closure = null)
{
    $this->closure = $closure;
}

And here’s the wee catch: You can’t call it like a normal method, $this->closure($args); You need to assign it to a standard variable for whatever reason.

    /** 
     *  @param ESOS_Entity_Org $org
     *  @return string
     */
    private Function generateLinkText(ESOS_Entity_Organisation $org)
    {
        if(!$this->closure)
        {
            // This is my default functionality
            return $org->getName();
        }
        // There are two ways of doing this next bit:
        // $this->closure($args); won't work but $closure($args) will!
        // $closure = $this->closure; 
        // return $closure($org);

                // Here's the better way:
                return call_user_func($this->closure,$org);
    }

Doing this has made me realise just how awesome Callables can be, you could inject in all manner of functionality into a class! Play around with it!

Sometimes, you’ll want the same form in more than one place in your application, however occasionally, that means your forms look terrible! However you can specify a different view script to use (I put mine in a forms subdirectory):

$this->addDecorators(array(
    array('ViewScript', array('viewScript' => 'view_folder/different-looking-form.phtml'))
));

And the bit that confdused me for a while, accessing the form in that view is strangle called $this->element:

<?= $this->element; ?>

Of course, as you may know, you don’t have to render the form like that, which is kind of the point of this:

<?php
$form = $this->element;
$supply = $form->getSupply();
$fueltype = $form->getFueltype();

?>

<form id = "<?=$form->getAttrib('id') ?>"
    name = "<?=$form->getName() ?>"
    method = "<?=$form->getMethod(); ?>"
    enctype = "<?=$form->getEnctype(); ?>"
    >
    <dl class="zend_form">

        <dt><label>Supply / Meter</label></dt>
        <dd><?=$supply->getMeterNumber() ?></dd>

        <dt><label>Fuel Type</label></dt>
        <dd><?=$fueltype->getFueltype() ?></dd>

        <dt><label>Description</label></dt>
        <dd><?=$supply->getDescription() ?></dd>

    <?php
    foreach ($form->getElements() as $element)
    {
        echo $element;
    }
    ?>
    </dl>
</form>

Sorted! No need to encase your form in more divs and mess around with CSS! 🙂

If you have a multideminsional array and would like to generate a

    like this:
  • 30
    • 31
      • 40
      • 33
      • 36
        • 41
    • 32
      • 38
    • 34
      • 37
      • 35
  • 39

Try my class out for size:

class Tree
{
    private $data;
    private $html;
    
    public function buildTree(array $data, $parent_id)
    {
        $this->data = $data;
        $this->html = '<ul>';
        $this->getChildren($parent_id);
        $this->html .= '</ul>';
        return $this->html;
    }
    
    private function getChildren($parentId)
    {
        $children = array();
        foreach ($this->data as $row) {
            if ($row['parentid'] == $parentId) {
                $children[] = $row;
            }
        }
        foreach($children as $child)
        { 
            $this->html .= '<li>'.$child['name'].'<ul>';
            $this->getChildren($child['id']); 
            $this->html .= '</ul></li>';
        } 
    
    }
}
    

$tree = new Tree();
$ul = $tree->buildTree($data, 0);
echo $ul;

Bone Mvc Framework

As if there weren’t enough PHP frameworks out there, I went ahead and built one myself!

Announcing Bone MVC Framework, a bare bones MVC framework in a distinctly piratey flavour.

Gaaarrrr!

It be the mightiest bare bones framework it th’ seven seas!

Install it using Composer by typing into your terminal:

php composer.phar create-project delboy1978uk/bonemvc your/path/here dev-master

If you don’t have Composer type this in to download it first:

php -r "readfile('https://getcomposer.org/installer');" | php

Change the permissions for the data folder:

chmod -R 775 data

In config/config.php, you can set any default settings (anything at all) in here, and it will be available in the Registry (which a future version will be replaced by a dependency injection container), but there are some settings Bone uses such as routes and db connection for the PDO connection. Check the link above for more details.

Bone MVC Framework uses Twig for it’s view, but eventually we will be able to swap that out for any view library of our choice! Layouts can be found in the /App/View/layouts folder. The index and error folders correspond to the index and error controllers.

In the controllers, you have actions, and from within these you can call whatever the hell you like! Just remember the use statements for any classes you want to use. Bone comes with a few controller methods:

public function nonstopAction() 
{ 
    $this->getRequest(); // the Request object 
    $this->getParam('param'); // gets a single uri param 
    $this->getParams(); // gets an array of all the params 
    $this->getDbAdapter(); // a PDO connection t' yer Db 
    $this->getHeaders(); // returns a headers object for header manipulation
    $this->hasLayoutEnabled(); // boolean 
    $this->disableLayout(); // turns the layout off 
    $this->hasViewEnabled(); // boolean 
    $this->disableView(); // turns twig off 
    $this->getTwig(); // gets yer Twig object 
    $this->getBody(); // response body (when view disabled) 
    $this->setBody($body); // sets th' response body (when view disabled) 
}

Have a play with it! Fork it on GitHub! If you have any comments for improvements or any issues, again leave them on GitHub!

I’ll be making some more posts soon, talking about Unit, Functional, and Acceptance tests using Codeception, and Continuous Integration using Travis! Stay tuned!

http://bonemvc.delboysplace.co.uk