When you’re working with Zend Framework, and code in general, you keep your configuration as much out of code as you can – right? Well, if you want to write maintainable and flexible code you do. Well, if you’ve been working with Zend Framework and Zend Form for more than a little while, you know that it really makes that pretty simple via Zend_Config – well, some of the time.
That’s right, it’s not that simple, not by a long shot. Why’s that? There’s two key problems with using Zend Config to configure our Zend Forms:
That’s right, depending on your background, I’m sure that you’ve just labelled me that – or maybe worse. I admit that points 1 and two could be seen as just being lazy. What developer worth their salt isn’t prepared to dig through code to find out how libraries, frameworks and applications really work?
How often do we really rely on a manual to give us all we need. After all, there isn’t endless time to write countless examples, and that’s what self-documenting code is for – right?! Yes! But that aside, sometimes it helps to have a bit of a boost along and not have to do all of the investigation yourself, especially when you’re in a bit of a hurry, or under the pump to get work done.
So, given that perspective, with this series of posts, I’m going to start covering some of the key configuration options for Zend Form. In this series we’re going to be looking at the following:
In this one, I’m going to cover custom form filters.
Let’s say that we’ve written a custom filter to truncate text submitted in a form. How do we get that to simply work when the default is for Zend Framework to look for classes with a prefix of Zend_Filter_ and a path of Zend/Filter/?
Well, it’s easier than you think. Take a look at the form xml snippet below:
<phone_number> <type>text</type> <options> <label>phone number:</label> <size>12</size> <validators> <notempty> <validator>NotEmpty</validator> <options> <messages> <isEmpty>A phone number is required</isEmpty> </messages> </options> </notempty> </validators> <filters> <trim> <filter>StringTrim</filter> </trim> <truncate> <filter>Truncate</filter> <options> <stringLength>20</stringLength> </options> </truncate> </filters> <class>regTextInput</class> <required>false</required> <prefixPath> <prefix>MaltBlue_</prefix> <path>MaltBlue</path> <type>filter</type> </prefixPath> </options> </phone_number>
In this section we have two filters, trim and truncate. The trim filter is the built-in filter: Zend_Filter_StringTrim. The second one is our custom one, MaltBlue_Filter_Truncate. Without getting in to too much detail about the filter itself, it has one key option: stringLength. This sets the maximum length of the string that can be displayed for that element. Any text after that length will be truncated – it works as it says on the tin?
However, if we only added that the filter option in, then we’d see an exception thrown. Why, because only the default path and prefix are loaded. So we need to tell Zend Form where to find our new, custom, filter by providing it with a prefixPath.
To do this, look at thesection under the phoneNumber element and you’ll see that this provides it with three options:
What this translates to is analogous to us having called the following snippet on the element, had we done all this in code:
1 $element->addPrefixPath('MaltBlue_Filter', 'MaltBlue/Filter/', 'filter');
Now this is all well and good, but if we kept doing it this way, we’d have to include a prefixPath section for every element. Now this isn’t bad for one or two elements, but not for more than that; it’s just not very practical. Wouldn’t you agree? So how do we add them on a form-wide basis? Well, that’s a good question. Have a look at the code below which illustrates how to do this:
<?xml version="1.0" encoding="UTF-8"?> <forms> <radio> <action><your_form_action></action> <method>post</method> <name><your_form_name></name> <elementPrefixPath> <prefix>MaltBlue_</prefix> <path>MaltBlue</path> <type>filter</type> </elementPrefixPath> ... </forms>
Via the Zend_Form::setOptions() method, the above snippet has now added the prefix path to all elements added to the form. Now you can remove the prefixPath configuration from individual elements. If you’re curious, have a look at, approximately, line 317 in <your_library_path>/Zend/Form.php.
Now that we have both of these options in place, we’re now able, per/element or per/form or a combination of the two, to add custom filters to our form elements, without writing a specific line of code. What do you think? How do you see it helping you in your projects?