Callbacks in CakePHP forms using events

If you ever have the need to inject fields or other things into a form, for example when building a blog or CMS system, you can use the event system that comes with CakePHP. The basic concept can be used every where within the views and is not limited to forms only, but a form is a good example.

You can find the complete sample as working application in the cake2-form-events branch of my Github cakephp-sample repository.

Please note that this sample code is using php 5.4 specific notations.

The form in a view file is dispatching two events, the View.Form.someFormStart and View.Form.someFormEnd event. The places where these callbacks are fired are the places where custom fields or other output is going to be injected by the triggered event listener callbacks.

The event listener class that will inject something to your form events.  I would not write a lot view code in the event listener itself, it is just done for demonstration purpose in this sample, I would always put the additional things I would like to display in an element and only echo that element from the event, to keep the view pieces it will inject separated from the event listener to respect separation of concerns.

You can put your event listeners into App/Event for example. After you’ve created your event listener and saved it to App/Event/FormListener.php you have to attach your listener to the CakeEventManager. In your App/Config/bootstrap.php add this to attach the listener to the global event manager.

The additional_fields element will output the user we fetched in the first event for demonstration purpose to give you an idea of what is possible and how it works and data is made available between the different steps.

I hope you enjoyed the article and learned something. Any kind of critic to improve it is welcome!

Tablel-less models in CakePHP that provide records or act like “enums”

This short article will cover two scenarios, one where you’ll store complete records in a model without a database connection for that model and another solution for enum like data or simply constants that can be wrapped in a model as well to give them a meaning.

Full multi-field records in a model without a database:

We are going to use the ArraySource from the community maintained Datasources plugin for CakePHP. Make sure you pick the right branch from the repository. There is a master (CakePHP 1.3), 2.0 and 2.3 branch available. Chose the branch that matches your projects CakePHP version.

Define a connection to the datasource in your app/Config/database.php:

In your Country model make sure it is using the datasource config you’ve just created and fill the Country::$records property with records:

A solution for single fields, enum like data:

If you don’t use a DB table and entries are limited, it is always good to use constants because you can’t do a typo without causing an error somewhere and UserLevel::USER is much more clear than a random ‘user’ string somewhere that could mean anything. Another advantage of this is the situation when you have to update your application because you suddenly get a lot more user models. All you have to do is to refactor your model to use a table then.

The Imagine plugin

The Imagine plugin for CakePHP, which has been available from the CakeDC account on GitHub, was written as a separate plugin, but complementary to my FileStorage plugin.

In the past, the good old CakePHP 1.3 times, we’ve had our Media plugin at the CakeDC which we never released. The main purpose of the plugin was to deal with file uploads, but only to the local system and to process images.

I’ve had to work with a few client projects that used phpthumb, which I’ve learned to dislike because it had its faults and issues. Before reinventing the wheel I simply tried to ask if somebody knows about something modern, OOP, PHP 5+, with unit tests, and had some luck.

Imagine is a modern PHP 5.3 library that provides an interface to different image processing back-ends like gd, imagick and imagick shell. Others can be implemented as well. I really recommend this lib over phpthumb, and suggest you to replace it with Imagine if your project is moving on.

The plugin for CakePHP is basically a wrapper around the Imagine library, that will autoload the library (because CakePHP 2.0 does not have it’s own autoloader until 3.0) and make it available as a behavior. The behavior provides some methods that handle commonly used image operations, like cropping and thumbnails.

Besides that, the plugin comes with a helper and a component, which allows it to generate versions of images on the fly. This was more done for backward compatibility for some apps, rather than being a concept that should be used. In fact, it is not the recommended way to handle this. I’ve written two other articles related to image processing and file storage that explain the issues with that.

Instead of creating images on the fly, which is just putting load on the server all the time, you should create the versions of an image after upload. The Imagine plugin works together with the FileStorage plugin, which can use Imagine to generate whatever images you want, right after upload.

I originally contributed this plugin, which I developed in my own free time, to CakeDC. But now, it is finally going back to my GitHub account, to pull some maintenance work away from the company. I’ll continue to maintain it, and hope you take some time to check it out, and contribute if possible.