Zend Controller redirects and unit testing

This afternoon I found a bug in some old code that I’m refactoring and retrofitting unit tests into. Well, not a bug exactly but a Zend Framework controller quirk. It drove me absolutely nuts for ages until I went to Google and found a solution. Imagine the following example which is some methods from a class that extends the ControllerTestCase in the Zend_Test library:

public function testEmptyUrlParameterRedirctsCorrectly()
{
     $this->dispatch('/user/profile/');

     $this->assertModule('user');
     $this->assertController('profile');
     $this->assertAction('index');

    $this->assertRedirectTo('/user');
    $this->assertResponseCode('302');
    $this->assertRedirect();
}

public function testInvalidUrlParameterRedirctsCorrectly()
{
     $this->dispatch('/user/profile/invalid-username');

     $this->assertModule('user');
     $this->assertController('profile');
     $this->assertAction('index');

    $this->assertRedirectTo('/user/invalid');
    $this->assertResponseCode('302');
    $this->assertRedirect();
}

The controller is expecting a url like /user/profile/username. If the username is invalid or missing altogether we want to test that the page redirects elsewhere and displays any necessary feedback to the user. While this functionality had always seemed to work in the application, the unit tests were failing for some reason. After a bit of assert writing it turned out that the tests were returning a module/controller combination of default/error instead of user/profile. The error was nowhere to be seen in the application and it continued to redirect correctly as it always had.

A quick read on Nabble later and I came away with an interesting tip from Zend developer Matthew Weier O’Phinney.

“Whenever you _forward() or redirect, you should return immediately. As
an example:

if (!$form->isValid($request->getPost())) {
return $this->_forward(‘details’);
}

If you don’t, the action continues to process. This would definitely
have an impact on redirects as well.”

Now, I’ve always written my redirects in the following way:

$this->_redirect('user');

But after adding the return statement into the legacy code, all the new controller tests passed. I’m not really sure what this implies for any other redirects that have yet to be unit tested as no errors have been thrown by the application logs. It may be possible that redirects only operate this way during unit tests and will return automatically during normal execution. I’ll investigate this soon unless anyone else has any insightful thoughts on the matter?

Posted in PHP, PHPUnit, Zend Framework | Leave a comment

Twitter Lists

Twitter have introduced lists as a way to organise who you follow.  I’ve started building a PHP list that follows interesting sites and prominent members of the community. Check it out here:

http://twitter.com/teengenerate/php

Posted in General, Open Source, PHP, PHPUnit, Symfony, Twitter, Zend Framework | Leave a comment

Zend Framework FlashMessenger

For the uninitiated in the dark art of Zend Framework, the flashMessenger action helper is a session based message system that allows you to store and retrieve messages while redirecting and forwarding to different pages. A quick browse through the source code reveals that the flash messenger does nothing more complicated than adding a few arrays to a session object. But yet, when set up properly it can be a great replacement for any custom messaging systems you use to provide feedback to your users on a site.

Like most Zend Framework components, the FlashMessenger needs a bit of tweaking before it’s ready to be part of your application. The main bit of tweaking we need to do involves the namespace. The messenger only has one namespace set at initialisation (default). More than often we will need a few namespaces for messaging. For instance you would often want to separate out error messages from success messages or notifications. This is where namespacing comes in. The following examples are contained in controller actions:

$this->_flashMessenger = $this->_helper
                              ->getHelper('FlashMessenger');

if ($errrors) {
    $this->_flashMessenger->setNamespace('error');
    foreach ($errors as $errorItem) {
        $this->_flashMessenger->addMessage($errorItem);
    }
} else {
    $this->_flashMessenger->setNamespace('success');
    $this->_flashMessenger->addMessage('Success.');
}
$this->_flashMessenger->resetNamespace();

Once you have this set up you can retrieve messages from specific namespaces like so:

$this->_flashMessenger->setNamespace('error');
$this->view->errors = $this->_flashMessenger->getMessages();
$this->_flashMessenger->resetNamespace();

Always remember to reset the namespace after changing it or you might get confusing messages! Changing namespaces generates a lot of repeated code so it should really be moved into an messenger object of it’s own that will handle the namespace processing for you.

Posted in Open Source, PHP, Zend Framework | Leave a comment

Zend_Db_Expr and how to use it

One thing that comes up a lot when updating a database is incrementing values. You might have a value stored in a column and you want to increment it by one or more but you don’t want to query the record first. This adds additional overhead to the server by running an extra unnecessary query. To get around this you can increment the column. This is pretty standard stuff using straight SQL as you can update the column using a statement like:

UPDATE myTable SET myColumn=myColumn+1 WHERE rowId='123';

While trying to fix a bug using this method and Zend_Db I realised that these kind of expressions have to be contained within a Zend_Db_Expr class. Hopefully the code example below will save someone a bit of  head scratching when trying to figure out why their columns aren’t incrementing.

This is the wrong way to do it (and will result in a failed update):

$data = array('myColumn' => 'myColumn+1');
$where = 'rowId=123';
$db->update('myTable', $data, $where);

The correct way:

$data = array('myColumn' => new Zend_Db_Expr('myColumn+1'));
$where = 'rowId=123';
$db->update('myTable', $data, $where);

Another use for Zend_Db_Expr is when you need to use any mathematical functions in your Zend_Db select statement. You can use it in your column definitions like in the example below which multiplies two columns together to report a total:

$totalGuests = 'quantity * guestsPerTicket';
$columns = array('totalGuests' => new Zend_Db_Expr($totalGuests));
Posted in PHP, Zend Framework | Leave a comment

Zend Form country lists

One task that comes up time and time again is creating a dropdown form element that is populated by a list of countries. In the past I solved this problem by keeping an key/value array of countries and their codes and loaded this in via a loop. Not any more. By using Zend_Locale and Zend_Form you can automate this task in a few lines of code.

$locale = new Zend_Locale('en_Gb');
$countries = ($locale->getTranslationList('Territory', 'en', 2));
asort($countries, SORT_LOCALE_STRING);

$form = new Zend_Form();
$country = new Zend_Form_Element_Select('country');
$country->setLabel('Country')
        ->addMultiOptions($countries)
        ->setValue('GB');
$form->addElement($country);

You can take this one step further and create a custom element to display country dropdowns but I’ll leave that to you.

Posted in PHP, Zend Framework | 1 Comment

htmlentities and character encoding

I recently came across a bug in some code I’d written where the input filters were doing something strange on certain peoples computers and truncating the inputted text when hitting a single quote. After a bit of googling I realised that the htmlentities filter I was using wasn’t set to the right character encoding. Everything on the site was running with UTF-8 but the htmlentities default encoding is ISO-8859-1. I don’t know if this will be updated to UTF-8 in future versions of PHP but if you’re encoding in UTF-8, you’ll need to set your input filters to process in this encoding.

Standard PHP

$clean = htmlentities($input, ENT_QUOTES, 'UTF-8');

Zend Framework

$encoding = array('quotestyle' => ENT_QUOTES, 'charset' => 'UTF-8');
$f = new Zend_Filter();
$f->addFilter(new Zend_Filter_HtmlEntities($encoding));
$clean = $f->filter($input);
Posted in PHP, Zend Framework | 2 Comments

First impressions of Symfony PHP Framework

In the last few years, every project I’ve worked on has run on top of Zend Framework or a custom in-house framework. Most of my work involves extending existing applications and that’s the major reason I haven’t looked into any of the alternative PHP frameworks out there. In the last few months there have been tons of blog posts on the subject of PHP frameworks so I decided to do a little self-motivation exercise and learn a new one.

I checked out most of the popular PHP framework websites, read a little about each, browsed the community and tutorial pages and after a few hours came to the conclusion that I was going to have a crack at building a site using Symfony. The main reason I chose Symfony is that it takes a completely different approach to building a website from ZF. Using Zend Framework sometimes feels like driving a tank, it’s beauty is that it’s completely flexible but the downside of this is that there’s a lot of code to write before you get to where you want. Not interesting code either. You have to write your controller skeletons, your basic models, your CRUD functions, your views. You know, the stuff you’ve written a million times. If John Rambo taught us anything, it’s that sometimes you don’t need a tank, you need a small, fast boat to get in quick and get the job done. Zend’s strength lies in long term projects that require scalability and customisation. Symfony on the other hand specialises in code generation and speeding through the boring, repetative tasks associated with getting a web application up and running.

One of the things that drew me to Symfony is the documentation. They have free books that teach you every aspect of the framework and a 24 day tutorial called Jobeet that walks you through every step of application building in Symfony. I decided to build the Jobeet app and see how it worked for me.

The first thing you notice once the environment is set up is the lack of coding needed. Symfony provides a PHP command line interface and it’s simply a case of writing some YAML configs and running various ORM scripts (Propel and Doctrine are the default ORMs). By using the command line and some simple configs you can generate the models, the database structure, the controllers, the views, the CRUD functions and associated forms. Within a few hours of work I had a fully functioning basic site and I was pretty impressed with the way Symfony handles code generation.

Symfony also comes with two front controllers instead of one. One is for the actual web application and one is for the debug version. The debug version comes with full logging and analysis tools and it’s a really nice feature. I’m sure it’ll come in useful when making small edits in live environments or doing routine maintenance and performance upgrades.

As of writing this post, I’ve only had time to run through the first 6 chapters of the Jobeet project so I’ll be writing another post when I get a bit deeper into the workings of Symfony. That’s it for now but if you’re interested in learning more, head over to the Symfony website and have a run through some of their tutorials. Even if you’re not planning on using Symfony for production sites, it’s still a useful exercise to see how a ORM-based framework like this can cut down on the amount of boring coding you have to do.

Posted in Open Source, PHP, Symfony, Zend Framework | Leave a comment

Generating an SEO friendly URL in PHP

Everyone wants pretty URLs right? Lots of key/pair GET values in URL strings look ugly and are bad for SEO. I was just messing about with a big database table of records that needed converting to SEO friendly urls and needed a quick and easy fuction to automate the process. When I need to do a certain job like this I tend to add a static function to a tools class that I keep in my library. I know this isn’t considered particularly good practice and I should refactor the code out into a url class but for small scripting jobs I’ve always found this way is a lot more efficient.

First thing we do is take the page name and replace all the spaces with hyphens, then strip out any non-alpha-numeric characters using regex. This will give you a nice URL that will make the  SEO people at your company happy. I’ve also added a suffix option here that can be used to take care of any duplicates. The logic to handle this should be kept outside this function as it’s dependent on whatever database table you happen to be using at the time.

    /**
     * generates an SEO friendly url
     *
     * @param string $name
     * @param interger $suffix
     * @return string
     */
    public static function generateUrl($name, $suffix = 0)
    {

        $alias = str_replace(' ', '-', strtolower(trim($name)));
        $alias = preg_replace('/[^A-Za-z0-9-]/', '', $alias);
        $alias .= ($suffix > 0) ? $suffix : '';

        return $alias;

    }

By using this function in any admin scripts we can now generate urls for each record by looping through the database.

Eg. If the page title you have is “This is a new article! Is it helpful?”, it will be converted to “this-is-a-new-article-is-it-helpful”. Perfect for SEO.

Posted in Open Source, PHP, SEO | 1 Comment

jQuery 1.3.2 – To live is to die

I’m sure anyone that has developed in javascript has had monumental headaches over the years trying to write code that allows event handlers to operate on dynamically created elements. The main problem I always seem to come across is assigning event handlers to elements that are generated after the page has loaded. jQuery 1.2.x went some way to solving this by adding the bind and unbind events. Even with this functionality, you still had to manually bind an event handler to every new element and it seemed like a lot of work to achieve something relatively simple. These days people are coding fluid interfaces and letting javascript do a lot of the heavy lifting and dynamic element creation in javascript is a big part of the web at the moment.

The example below shows how bind() events are added to individual elements. Every time a button with the class ‘myButton’ is clicked, a link is added to the container div. Because the links do not exist when the page is created, the event handlers have to be created after each element using the bind method.

$('.myButton').click(function() {
    $('#myContainer').append('<a class="myElement">Click me</a>');
    $('.myElement').bind('click', function(){
        clickFunction();
        return false;
    });
});

function clickFunction() {
    // do something here with the click
   alert('This link has just been clicked!');
}

Thankfully  jQuery 1.3 has introduced the live() and die() events. By using the live() method, it is possible to assign an event handler to a selector, even if the element doesn’t exist. If the element is created in the future, the event handler will be automatically added to it. The example below will create a click event handler on any element with the class ‘myElement’ regardless if it exists or not.

$('.myElement').live('click', function() {
    clickFunction();
});

This example doesn’t really cut down on code but it does mean you can forget about tracking the event handlers. Just assign once and forget. Bugs won’t appear in your code just because you forgot a bind() function somewhere and every subsequent ‘myElement’ element that is created will have an event handler assigned to the click event.

This has already saved me considerable time banging my head against the screen. All hail the live() event! One thing I have noticed is there is a slight performance issue when using the live event as oppose to using the bind functions so you have to weigh up the pro’s and cons of using it in javascript intensive applications.

Posted in Javascript, Open Source, jQuery | Leave a comment

The aims of this blog

I find as a web developer that I’m constantly learning new things to get certain tasks done and then subsequently forgetting them if it’s not a skill that I use very often. This blog is an attempt to write down things as I learn them so I can reference them at a later date rather than go through the whole process of reading documentation again. It’s probably going to be a mix of PHP, Javascript, Linux and whatever else I pick up in my day to day tasks. Please feel free to leave comments and pick holes in what I’m doing as I know the holes are there!

Posted in General | Leave a comment