Zend Form Mastery with Zend Config – Part 1 Custom Filter Paths

Zend Form Mastery with Zend Config
Update: Thank you to savvysketch for pointing out my lack of detail about setting form wide element prefix paths. This is now available.

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.

Unfortunately not always

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:

  1. The Manual – That’s right, the manual doesn’t place a lot of emphasis on using Zend_Config objects to configure forms. It does give some options, but doesn’t go in to much depth.
  2. Code Investigation – You have to know the Zend Form code or do regular digging when you need to know an option

What a Whinger!!!

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.

What’s in the Series

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:

  • How configuration works
  • paths:
    • filters
    • prefix
    • elementPrefix
    • displayGroupPrefix
    • elementDecorators
  • element:
    • filters
    • validators
    • options
  • form:
    • options

In this one, I’m going to cover custom form filters.

Custom Form Filters

Per-Element 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:

  • prefix – the class name prefix
  • path – the class path to start searching in
  • type – the prefix path type

What this translates to is analogous to us having called the following snippet on the element, had we done all this in code:

$element->addPrefixPath('MaltBlue_Filter', 'MaltBlue/Filter/', 'filter'); 

Form-wide Filters

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?

Intermediate PHP Tutorial Zend Config Zend Form Zend Framework