stephenminded

Lazy class loading with Zend_Loader_PluginLoader

without comments

In applications built on top of a library of reusable code, you may want to load your custom class components before those of the library. For example, your library has a user model of Lib_Model_User. In general, this class is enough for your needs, but for a particular case, you’d like to use a custom implementation specific to your application called Custom_Model_User. Furthermore, say you have a controller that needs the user model to perform some action, say Lib_Controller_User. Typically, your code for that controller might look something like this:

1
2
3
4
5
6
7
8
9
10
class Lib_Controller_User extends Lib_Controller
{
    public function registerAction()
    {
        if (!empty($_POST)) {
            $model = new Lib_Model_User;
            $model->save($_POST);
        }
    }
}

For your particular app, you want to use Custom_Model_User instead of Lib_Model_User… in order to do this, you’d probably subclass Lib_Controller_User and override the registerAction method. This definitely works, but there are a few better ways.

You could inject the model at some point before registerAction gets run. This might look something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Lib_Controller_User extends Lib_Controller
{
    protected $_model = null;
 
    public function __construct($model = null)
    {
        if ($model === null) {
            $model = new Lib_Model_User;
        }
        $this->setModel($model);
    }
 
    public function setModel($model)
    {
        $this->_model = $model;
    }
 
    public function registerAction()
    {
        if (!empty($_POST)) {
            $this->_model->save($_POST);
        }
    }
}
 
// In your bootstrap process
$user_controller->setModel(new Custom_User_Model);

This works fine, but I think that Zend_Plugin_Loader gives you a much nicer way of achieving this. Here is the same code refactored to use the plugin loader instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Lib_Controller_User extends Lib_Controller
{
    protected $_modelLoader = null;
 
    public function registerAction()
    {
        if (!empty($_POST)) {
            $this->_getModel('user')->save($_POST);
        }
    }
 
    protected function _getModel($name)
    {
        if ($this->_modelLoader === null) {
            $pl = new Zend_Loader_PluginLoader;
            $pl->addPrefixPath('Lib_Model', 'Lib/Model/');
            $pl->addPrefixPath('Custom_Model', 'Custom/Model/');
            $this->_modelLoader = $pl;
        }
        $model = $this->_modelLoader->load(ucfirst($name));
        return new $model;
    }
}

This will first look to see if Custom_Model_User exists, if it’s not found, it will load Lib_Model_User instead. It lazy loads your models using the order you specify. This makes your controller a lot more reusable and cuts down on the amount of bootstrap code you need. Note, if you wanted to use this in a real world scenario, you’d probably want to specify your custom loader paths through configuration instead.

Zend Framework makes use of plugin loaders quite a bit. Zend_Form is a great example because it allows you to specify where to load elements when using the available factory methods like Zend_Form::createElement and Zend_Form::addElement. Doing this makes code much more flexible, I like the approach.

Written by steve

June 18th, 2009 at 9:45 pm

Posted in PHP, zend framework

I fetched my twitter posts with jQuery, you can too!

without comments

I wanted to spice up my theme a bit with my latest twitter post. I also didn’t want to write any php to do it because I was feeling like writing some javascript instead. I also didn’t have a whole lot of time with the NHL playoffs on and all. This is where jQuery and twitter’s JSON api came to the rescue.

You can get your latest N posts from twitter from the following REST uri:

http://twitter.com/statuses/user_timeline/USERNAME.json?count=N

The api also supports JSONP callbacks which means that you can do a cross domain AJAX request without any problems. This is cool, because otherwise you would have to proxy it which means I would likely have to write some PHP and I didn’t want to do that ;)

Anyway, on to the jQuery:

1
2
3
4
5
6
$(document).ready(function() {
    $.getJSON("http://twitter.com/statuses/user_timeline/stephenminded.json?count=1&callback=?",
      function(data) {
        $("#tweets").prepend('<p>'+data[0].text+'</p>');
      });
  });

So, this makes a call to the twitter API asking for my latest tweet, once it gets that data it runs a callback which takes the tweet text and appends it in a paragraph tag to a div somewhere in my content (hint, it’s in the upper right corner). Oh, that “callback=?” part is the JSONP stuff, if that’s not there the request won’t work because of cross domain problems.

And with that I go back to watching the third period.

Written by steve

May 12th, 2009 at 10:54 pm

Posted in javascript, jquery

Tagged with ,

Zend Framework PEAR Channel — update

without comments

My last post talked about the available Zend Framework PEAR channels out there. I’ve been using one to grab our Zend Framework installs for work and it’s worked well. My only complaint is that the PEAR version is lagging behind the currently released ZF version. Tonight I thought I would take a look at the channel I decided not to use and see where it stood. It is in fact up to date with 1.7.7 where as the one I’m using is at 1.7.4. I guess it’s sort of a non-issue as it’s easy to switch to another channel.

Regardless, here is a breakdown of those two channels and their current ZF versions:

PEAR Channels Offering Zend Framework (as of March 17, 2009)
PEAR Channel Website Current ZF Version
pear.zfcampus.org Blog post explaining channel 1.7.4
zend.googlecode.com/svn Google Code Project 1.7.7

Do you know of any other PEAR channels offering Zend Framework?

Written by steve

March 18th, 2009 at 12:23 am

Posted in PHP, zend framework

Tagged with ,

Zend Framework PEAR Channel

with one comment

A while back I tried to find a Zend Framework PEAR channel, but was unsuccessful. Reading through the December issue of PHP|architect I was pumped that someone has been kind enough to start maintaining one. It is available here:

http://code.google.com/p/zend/

Update: After posting this to twitter, Matthew Weier O’Phinney let me know that there is another ZF PEAR channel setup. This one includes development versions, alphas, betas, rc’s etc. Check it out here:

http://ralphschindler.com/2009/01/07/the-semi-official-zend-framework-pear-channel

Written by steve

February 25th, 2009 at 12:02 am

Posted in PHP, zend framework

Moved to Wordpress

with 2 comments

I’ve moved this blog over to wordpress. I never gave my homegrown CakePHP blog engine the attention it deserved and it ended up becoming a hindrance. So, for now I’m stuck on a default wordpress theme until I can migrate my old theme over. Hopefully wordpress will let me focus a little more on blogging, we’ll see.

Written by steve

February 18th, 2009 at 9:24 pm

Posted in personal

Validating URLs with Zend Framework

without comments

It’s pretty common to want to validate a URL when processing a form. The Zend Framework has a lot of validators that can be used out of the box with Zend_Form. Unfortunately, there is no Zend_Validate_Uri. Upon closer inspection, you will find Zend_Uri, which indeed can be used to check for a valid URL; however, it does not implement the Zend_Validate_Interface and cannot be used as a drop-in form element validator. Fortunately, it is pretty easy to come up with something that can be dropped in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Url_Validator extends Zend_Validate_Abstract
{
    const INVALID_URL = 'invalidUrl';
 
    protected $_messageTemplates = array(
        self::INVALID_URL   => "'%value%' is not a valid URL.",
    );
 
    public function isValid($value)
    {
        $valueString = (string) $value;
        $this->_setValue($valueString);
 
        if (!Zend_Uri::check($value)) {
            $this->_error(self::INVALID_URL);
            return false;
        }
        return true;
    }
}
 
// When creating the form:
$website = $form->createElement('text', 'website');
$website->addValidator(new Url_Validator);

This reminds me of a senior coder I used to work under who constantly yelled at us to “Code to the interface!”. ;)

Note: I originally posted this as a response to a thread here.

Written by steve

February 9th, 2009 at 9:10 pm

Posted in PHP, zend framework

Getting Around Browser Cache with .htaccess

without comments

I originally wrote this on my employer’s blog, shift+control. I’m cross posting here because I don’t blog enough ;)


It’s pretty common to tweak your website assets from time to time. This may be an update to a stylesheet, some javascript, a logo or any other file. When doing this, you may notice that you don’t see the changes right away. You might have to refresh the page a few times or clear your browser cache in order to get the new version of the file. There are a few reasons this can happen:

1. When your browser requests a file, Apache may report that the file hasn’t changed. You can see this with a tool like firebug, any files that come back with a “304 Not Modified” header will not be re-downloaded by your browser.
304

2. When you first requested the file sometime in the past, Apache may have sent an expires header with the file. This means that until a specified date, your browser will never re-download the file. Unlike the #1 above, it doesn’t even ask Apache if it should re-download the file.

Note: I’m sure I missed a few ways a file can find it’s way into the cache, but that’s not the point of this post.

All this caching is great for the performance of your website, but it sucks when you actually want your users to download the new version of the file. Putting up “our site has changed, please clear your browser cache” is obviously out of the question. So, what can we do?

When your browser encounters a file that it hasn’t seen before it will always go ask Apache for the file. So, one option is to add a version number to the filename and update your source to point at the new file. This works, but adds a maintenance overhead because you have to make sure you maintain the version number of the file and deploy it with the proper filename. So, style.css could become style-20090109.css.

The problem with the above is that you have to maintain the file version in two places, once in your source html and again when you update the css file. We can get around this using htaccess by pointing all reguests to style*.css to style.css. So, when a request is made for style-20090109.css you get the updated contents of style.css and since the filename is unique you get around the cache issues. Yes, you still have to maintain the reference to the stylesheet in your html source, but you don’t have to worry about how to name the file. Anyway, here’s how you go about doing this.

Create a .htaccess file in the directory where your style.css file lives. In it put the following:

RewriteEngine On
RewriteRule ^style(.*).css$ style.css [QSA,L]

Now, when you request style-20090109.css or style-monkey.css you’ll always get the contents of style.css. There are other solutions, but I find that this works best for us. Hope someone will find it useful.

Written by steve

January 1st, 2009 at 7:15 pm

Posted in web development

Monitoring SVN commits with Twitter

without comments

I originally wrote this on my employer’s blog, shift+control. I’m cross posting here because I don’t blog enough ;)


Like a lot of developers, we use SVN on a day to day basis. I can’t imagine working without it. We’ve been using it for over a year now. Svnlook on revision 1 give me this:

[steve@76design ~]$ svnlook info /svn -r 1
steve
2007-08-23 18:23:03 -0400 (Thu, 23 Aug 2007)
23
Created folder remotely

And svnlook youngest gives me this:

[steve@76design ~]$ svnlook youngest /svn
6567

In a year we have over 6500 commits and many projects contained in that (now not so little) repository. Given that there are so many commits going on, we thought it would be useful to have a feed of commits happening in real time. If we had that, we could get a good feel for the activity in the office over the day. One obvious choice for a feed is RSS, and we have that too, but we thought it could be fun to have a twitter stream of our commits.

I did some quick googling and came across a Google code project called twitvn. Unfortunately, due to hosting restrictions, I was unable to get it installed on our svn server. So, like any developer would do, I wrote my own ;)

SVN provides you with some interesting ways to interact with it pre and post commit. I wanted to hook in on post-commit and fire off a twitter message with some details about the commit. Turns out it’s fairly simple to do.

After every commit, if a script is available at [svn path]/hooks/post-commit, SVN will run that script. Two arguments are provided, the svn path and the revision number of the commit. Using these two pieces of info, you can then pull out whatever details you want about that particular commit and choose to do what you want with it. Knowing that, here is the approach I took:

  1. Get the particulars about the commit using ’svnlook info’
  2. Get the modified files using ’svnlook changed’
  3. Determine the author and the project that was being committed
  4. Create a twitter message and send it using Curl

I decided to write it using PHP, mostly because it’s what I know and I wanted to get it done quickly. In order to determine the project, I assumed that the top level folder of the first modified file is the project (this will depend on your repository layout so your mileage may vary here).

The final script is called tweeter.php, grab it here.

In order to run it, drop your twitter account details into CMD_CURL_TWITTER and add this line to your post-commit file:

[path-to-php5-cli] [path-to-tweeter.php] “${REPOS}” “${REV}”

Let me know if you get some use out of it!

Written by steve

December 11th, 2008 at 7:18 pm

Zend Framework Link Roundup

with one comment

I’ve recently been looking into the Zend Framework for a project at work. I found it tough to find good, up to date documentation out there for it. So, I thought I would present everything that I have found to be somewhat useful so far.

  • The Zend Framework Manual is always a good place to start. Its actually quite good, but I think it lacks the practical examples that other php frameworks have provided (read CakePHP, CodeIgniter) with something like a 15 minute blog tutorial.
  • The tutorial on the Zend Wiki its a little outdated, but it explains a lot of the core concepts behind the framework and alludes to how the core components can interact with the MVC framework.
  • The Tutorial at Akra’s DevNotes is probably one of the best of the lot so far. It has been kept up to date with the changes in the framework and is guaranteed to work fully on 1.0.0 (and with that, it should work fine on 1.0.1). He goes over key concepts like using Zend_Db_Table and Zend_Filter as well as how to work them into the MVC framework.
  • IBM’s Understanding the Zend Framework series is good, too. Its a bit outdated (June 2006) but goes into all the details that you can expect from an IBM developer works article.
  • Andries Seutens created a default scaffold for getting setup and going with Zend Framework. Just unzip the file into your web directory and you get:
    • A conventional directory structure
    • A bootstrap file
    • A configuration file with 2 stages: production, staging
    • An error controller
    • An index controller
    • A host of other goodies

The Zend Framework is great so far and offers a lot of power to those capable of digesting the documentation and actually arranging the components in a way that is reusable and avoids complexity. I think the framework would benefit greatly from some of the standards that have been set in other frameworks in terms of getting users started. Something like Cake’s Bake script or some screencasts demonstrating how to setup the MVC framework would be welcome.

With that all being said, I continue my learning and development with the Zend Framework and look forward to seeing what is in store for the future.

If you think I missed any particularly good references, please post them.

Written by steve

August 23rd, 2007 at 10:24 pm

Posted in general

Jonathan Snook Relaunches WithCake.com

without comments

When Jonathan Snook first got into CakePHP he launched withcake.com as a spot to share his experience using CakePHP. This served as an excellent reference for people starting out with Cake, as the documentation can sometimes be lacking in certain areas. WithCake provided help on a lot of issues that I had a hard time finding answers to — it was great.

A New Direction

Snook eventually stopped posting to WithCake and merged the posts back into his main site, Snook.ca. He has now relaunched the site as a free job board specifically for CakePHP developers. The site has been redesigned and it looks pretty good. The job board contains sections for both developers looking for work as well as companies looking to hire developers (as well as RSS feeds for both sections).

It’s a great idea that I’m sure will get a lot of attention as well as help out the CakePHP developer community. I think Snook should be commended for taking this on and offering it as a free service.

Go check it out!

Written by steve

April 6th, 2007 at 9:40 pm

Posted in general