Zend Framework poster from mayflower.de

without comments

Mayflower.de was nice enough to send me a Zend Framework reference poster when I asked for one. Very nice of them! They even sent it all the way from Germany. It’s a really large poster with lots of good info about ZF. Here’s a picture of it:

Zend Framework poster from Mayflower.de

Check out their blog post if you’d like one too.

Written by steve

August 2nd, 2009 at 11:53 am

Posted in general

Load custom elements with Zend_Form

without comments

My previous post talked about Zend_Plugin_Loader and how to use it in your code. In that post, I also mentioned that Zend_Plugin_Loader is used quite a bit throughout the Zend Framework code. In this post, I’m going to show you how to make use of the plugin loader to load your own custom elements into Zend_Form.

Zend_Form uses factory methods like createElement and addElement in order to simplify adding elements to your form. Using these methods, you can refer to default Zend Form elements by name and they will be instantiated for you and added to your form. For instance, to create a form with text field, your code might look something like this:

1
2
$form = new Zend_Form;
$form->addElement('text', 'user_name');

Behind the scenes, Zend_Form is using a plugin loader to look for the “text” element, which will then be instantiated and added to the form. In this case, you would get an instance of Zend_Form_Element_Text. What if you wanted to use your own custom text element instead? Your first instinct might be to do something like this:

1
2
3
$form = new Zend_Form;
$user_name = new My_Form_Element_Text('user_name');
$form->addElement($user_name);

This works fine, and for small forms is probably the way to go. However, making use of the built in plugin loaders in Zend_Form (I think) leads to a little cleaner and more flexible solution. Here’s what the same example looks like using Zend_Form’s plugin loader:

1
2
3
$form = new Zend_Form;
$form->addPrefixPath("My_Form", "My/Form/");
$form->addElement('text', 'user_name');

Your form instance will now look for My_Form_Element_Text first before loading the default Zend_Form elements. This also takes care of setting up the plugin loader for decorators as well. This is nice because you don’t have to change your actual form code beyond adding the new prefix paths. This allows your forms to be much more flexible with respect to what elements and decorators are loaded.

Plugin loaders for element validators, filters, and decorators

One last bit, similar to the form instance itself, each element also has plugin loaders for decorators, filters and validators. Conveniently, you can set the prefix path for all elements added to a form using the Zend_Form::addElementPrefixPath method. This is where you’ll begin to see a lot of the power of Zend_Form, loading custom validators for your elements just as you would any other validator. It’s fun stuff!

Conclusion

You now have a way to load your own custom elements and decorators for forms, and a way to load decorators, filters and validators for your custom (or standard) elements. Enjoy!

Written by steve

July 16th, 2009 at 11:26 pm

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

with one comment

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, code, 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