Zend Framework Poster

August 21st, 2009

After stumbling across an offer for a free Zend Framework Poster some time ago, I quickly dropped Mayflower an email.

Some time passed, and now it’s here at work, placed next to our all important tea, coffee and biscuits station.

Mayflower poster

It’s A0, covers nearly all of the major components and is well worth having! Top props to guys over there for pushing the Zend Framework like this. Cheers!

  • Digg
  • del.icio.us
  • NewsVine
  • Reddit
  • Furl
  • DZone
  • StumbleUpon
  • Technorati

Mozilla’s Content Security Policy (CSP)

June 30th, 2009

I saw this post via SlashDot and can’t help but think it’s a little overkill?

Content Security Policy is intended to mitigate a large class of Web Application Vulnerabilities: Cross Site Scripting. Cross Site Request Forgery has also become a large scale problem in Web Application Security, though it is not a primary focus of Content Security Policy.

In an ideal world, this would be great, but getting all the browsers on board and implemented may take a while. I was thinking about this the other day and I don’t see why the browsers/w3c can’t standardise on some sort of tag or conditional comments that says don’t execute any script in here. This would be simple to use and surely simple to implement. Browsers already know what to do with <noscript>

For Example:

<dontexecutescript>
    <?php echo $this->escape($userProvidedContent);?>
</dontexecutescript>

Or:

<!--[dontexecutescript] -->
    <?php echo $this->escape($userProvidedContent);?>
<!--[dontexecutescript]-->

I’m no expert on XSS, but I’m pretty sure this would solve most of the issues encountered.

Update:

Okay, so one obvious problem might be that the $userProvidedContent contains a closing </dontexecutescript> tag, but that’s just semantics. Unique identifiers for each block, ignoring tags that don’t match up, these browser developers are clever, they could come up with something.

  • Digg
  • del.icio.us
  • NewsVine
  • Reddit
  • Furl
  • DZone
  • StumbleUpon
  • Technorati

Using message queues to improve user experience

June 1st, 2009

A major part of the application I develop on my day job is a big DMS, part of which is the ability to distribute documents to staff and external parties. The distribution system works in such a way that, if sending a document to 300 people, there will actually be 300 individual emails created, rather than one email with a list of recipients. This is desired behavior. My problem is, sending 300 emails at the click of a button can take a little time, degrading the experience for the users. This portion of the call graph shows sending to just five people was taking 1+ seconds.

screenshot2

To solve this, I started out to implement a simple queuing system, whereby the distribution requests are added to a queue, before being sent out by a scheduled task.

Rather than refactor a lot of code and do this some fancy way, I quickly put in a solution that proved the concept and seems to work pretty well for now, with minimal effort. As an example (our code’s slightly more complex, I don’t get paid for nothing), here’s what I started with:

< ?php
class EmailSender {
    /**
     * Takes an array of addresses and sends an email to each one.
     *
     * @param array $address
     */
    public static function sendEmails($address) {
        /**
         * Code in here
         */
    }
}

The idea was fairly simple and I'm sure it's been done many times before. First step was to rename the existing method and make it private. I then wrote a new method, that checked to see if there was a queue available, if so adds the request to the queue, otherwise calls the old method. Then all I had to do was write a method that checks the queue, running any requests it finds through the original method. We've recently adopted the Zend Framework, so checking out Zend_Queue from the incubator, reading some documentation with my docbook goggles on (couldn't be bothered to build it) and it was pretty much in place.

< ?php
/**
 * Zend_Queue offline processing hack example
 *
 * @author      Dave Marshall
 * @version     $Rev: $
 * @since       $Date: $
 * @link        $URL: $
 */
class EmailSender {

    private static $queue = null;

    /**
     * Set Queue
     *
     * @param Zend_Queue $queue
     */
    public static function setQueue($queue)
    {
        self::$queue = $queue;
    }

    /**
     * Takes an array of addresses and sends an email to each one.
     *
     * @see reallySendEmail
     * @see sendQueuedEmails
     * @param array $address
     */
    public static function sendEmail($address)
    {
        if (self::$queue === null) {
            return self::reallySendEmail($address);
        }

        self::$queue->send(serialize(func_get_args()));
    }

    /**
     * Takes an array of addresses and sends an email to each one.
     *
     * @see sendEmail
     * @param array $address
     */
    private static function reallySendEmail($address)
    {
        /**
         * Code in here
         */
        echo 'Sending email to ' . implode(', ', $address) . PHP_EOL;
    }

    /**
     * Reads emails from the queue and sends them
     *
     * @param int $count - The number of queued items to process
     */
    public static function sendQueuedEmails($count)
    {
        /**
         * Should really check the queue is good here
         */

        $messages = self::$queue->receive(intval($count));
        foreach($messages as $msg) {
            $args = unserialize($msg->body);
            call_user_func_array(array(__CLASS__, 'reallySendEmail'), $args);
            self::$queue->deleteMessage($msg);
        }
    }
}

set_include_path(
    dirname(__FILE__) . '/src/Zend_Framework/library' . PATH_SEPARATOR
    . dirname(__FILE__) . '/src/ZendI/library' . PATH_SEPARATOR
    . get_include_path()
);

require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();

define('DB_SERVER', 'localhost');
define('DB_PORT', 3306);
define('DB_USER', 'root');
define('DB_PASS', 'password');
define('DB_NAME', 'queue_example');

/**
 * Transmittal Queue
 *
 */
$config = array(
    'name' => 'transmittal',
    'driverOptions' => array(
        'host'     => DB_SERVER,
        'port'     => DB_PORT,
        'username' => DB_USER,
        'password' => DB_PASS,
        'dbname'   => DB_NAME,
        'type'     => 'pdo_mysql'
    )
);

// Create a database queue
$queue = new Zend_Queue('Db', $config);
$queue->createQueue('myqueue'); // called for good measure

EmailSender::setQueue($queue);

/**
 * Usage for adding to the queue
 */
EmailSender::sendEmail(array('davemastergeneral@gmail.com'));

/**
 * Usage for scheduled task
 */
EmailSender::sendQueuedEmails(5);

This may not be the best practice in the world, but it got the job done. Check it out at ZFSnippets.com.

  • Digg
  • del.icio.us
  • NewsVine
  • Reddit
  • Furl
  • DZone
  • StumbleUpon
  • Technorati

Redmine Issue Tracker/Project Management

April 20th, 2009

redmine_logo_bw

We recently started using Redmine as our issue tracking software and we’re very pleased with it. I trialled several alternatives, both open source and commercial, including Jira, FogBugz, Mantis and Trac, but decided on Redmine. Jira and FogBugz look like excellent products, but I don’t feel we would use the extra functionality that warrants the price tag. Mantis looks a bit dated and although it’s been a while, last time I tried to install and configure Trac, it was a bit of a nightmare.

First thing first, here are some of our requirements for an issue tracker:

  • Multiple Projects
  • Time tracking
  • Notifications (email, rss, im etc.)
  • Wiki
  • SCM integration

Redmine does all of this and a little more, but we haven’t used the other features that much. It does what we want really well, so that’s good enough for us.

What I like

Editing issues in bulk is fantastic. We deploy our application fairly casually, and when we do we set all the issues that have been deployed as closed and assign them a version number. Highlight the issues, right click and set the version number.

screenshot-1

The SCM integration does all we need it to. If we add Fixes #500 or Implements #500 to a commit message, issue 500 will be set to resolved and 100% complete and the revision number and commit message appears on the issue’s page. Alternatively, just putting Refs #500 will show the revision number and commit message in the page, without changing the status.

screenshot21

Issues themselves can have custom fields, but we don’t use them all that much. We do make lots of use of the descriptions and notes as they both take wiki markup, meaning we can enter rich text including source code highlighting and images, linking to changesets, wiki pages, target versions, source code and other issues. I like the ability to embed screenshots and call graphs in issues.

What I don’t like

Here’s a couple of things that bother me, if I shift my arse I might look into creating patches for the simple ones.

No API! It would be really nice to have an API and there’s one in the works, but it’s sounds like it’s a bit of a ballache changing fat controllers into fat models.

I often wish a few more items where ‘clickable’. For instance when viewing the issue list, I’d like to be able to click the Category name in one of the rows and see a list of issues for that category.

You can save filters on the issue list, which is ace, but it would be nice if you can ’save as new’. I often create lots of very similar queries and have to build up each one from scratch.

  • Digg
  • del.icio.us
  • NewsVine
  • Reddit
  • Furl
  • DZone
  • StumbleUpon
  • Technorati

Rev=Canonical and all that Jazz

April 15th, 2009

If anybody missed it, the last few days has seen plenty of buzz around a new proposal on how to solve the problem with URL shorteners. I kind of got lost in all the different methods and proposals people are discussing, suggesting or implementing, but I went ahead and added some simple logic to lnkd.in, to do a HTTP HEAD request to the given URL, looking for headers in a couple of the formats suggested. I figured that was going to get out of date pretty quickly, so I modified it to use the RevCanonical API, seems to work pretty well, returning a rev=canonical url wherever possible.

I also contributed a basic bit of code to Rob Allen’s Shorter Links plugin for wordpress, allowing users to specifying a base url, davedevelopment.co.uk isn’t all that good for short URLs. Just need to upgrade the plugin and decide on a short domain for my blog now.

Update: registerd daved.in, works a treat

  • Digg
  • del.icio.us
  • NewsVine
  • Reddit
  • Furl
  • DZone
  • StumbleUpon
  • Technorati