ClamAV as a Validation Filter in Zend Framework

Matthew Setter writes a very interesting article; Ok, so you’re pretty comfortable with using the Zend Framework, specifically the use of Forms. Along with that, you have a good working knowledge of how to combine a host of standard validators such as CreditCardEmailAddressDb_RecordExists, and Hex, and standard filterssuch as Compress/DecompressBaseNameEncrypt, and RealPath. But what do you do when a situation arises that’s outside the scope of the pre-packaged validators and filters?

Let’s say you want to guard against users uploading files that contain viruses, for example. You would have to write a custom validator that checks the uploads aren’t infected. Today I’ll show you how to do just that – how to write a new file validation filter for Zend Framework that uses ClamAVto ensure uploaded files are virus-free.

Adding ClamAV Support to PHP

First you’ll need to install ClamAV support. I’m basing this installation procedure around Linux, specifically Ubuntu. If you’re using another distribution, you may need to adjust the commands accordingly. Unfortunately, if you’re using Windows however, you’ll need to use a Linux-based Virtual Appliance or setup a virtual machine running Linux to follow along since the php-clamav extension doesn’t support Windows as yet.

Full Story with Source » phpmaster.

A Zend Framwork compound form element for dates

Rob Allen writes; A while ago I needed to ask a user for their date of birth on a Zend_Form. The design showed three separate select elements to do this:

Screen shot of a 3 select boxes for a date on a form

A little bit of googling found this site http://codecaine.co.za/posts/compound-elements-with-zend-form which has not unfortunately disappeared, so the code in this article owes a lot of the author of that article.

It turns out to be remarkably simple to create a single Zend Form element that is rendered as multiple form elements. We create an element object and a view helper object and we’re done. Usage then looks like:

< ?php class Application_Form_Details extends Zend_Form { public function init() { $this->addPrefixPath('App_Form', 'App/Form/');

// other elements before

$this->addElement('date', 'date_of_birth', array(
'label' => 'Date of birth:'
));

// other elements after

$this->addElement('submit', 'Go');
}
}

Obviously, this form lives in application/forms/Detail.php and is rendered as usual in a view script. In our form definition, we have added an element called ‘date’ and with the addition of the addPrefixPath call have told the form that in addition to using the standard Zend Framework form elements, also look in library/App/Form. (Incidentally, we can also now override any supplied form element by simply dropping a replacement into the libraryApp/Form folder.)

The date form element lives in library/App/Form/Element/Date.php as Zend_Form knows to look in a subfolder for App/Form called Elements for any element objects and will look in the Decorator/ sub folder for decorator objects.

The Date element looks like this:

Read the rest at Rob Allen’s DevNotes.

Complete Doctrine 1.2x Integration with Zend Framework 1.10+

To achieve complete Doctrine 1 integration with Zend Framework some glue is required, Benjamin Eberlei has created a complete solution thats straight forward, easy to use and understand.

This project tries to offer a complete Integration of Doctrine 1 with Zend Framework. The following components belong to this Integration:

  • Zend_Application Resource
  • Zend Framework Modular Project Support
  • Zend_Tool Provider for Doctrine Model Generation, Migrations and Fixtures
  • Zend_Paginator Adapter for Doctrine Queries
  • Dynamic Zend_Form generation from Doctrine Models

This integration requires the latest Doctrine version 1.2.2 to work completely

Get it!

SVN Export or Externals

Github offers SVN Read support for a while now, you can either use svn export or svn:externals to include ZFDoctrine into your project or into your PHP Include Path.
svn checkout http://svn.github.com/beberlei/zf-doctrine.git

Git Clone

git clone git://github.com/beberlei/zf-doctrine.git
If you follow the tutorial and installation steps your will get this in ZFTool.

Zend Framework Command Line Console Tool v1.10.4
Actions supported by provider "Doctrine"
Doctrine
zf create-project doctrine dsn zend-project-style library-per-module single-library
zf build-project doctrine force load reload
zf create-database doctrine
zf drop-database doctrine force
zf create-tables doctrine
zf generate-sql doctrine
zf dql doctrine
zf load-data doctrine append
zf dump-data doctrine individual-files
zf generate-models-from-yaml doctrine
zf generate-yaml-from-models doctrine
zf generate-yaml-from-database doctrine
zf generate-migration doctrine class-name from-database from-models
zf excecute-migration doctrine to-version
zf show-migration doctrine
zf show doctrine

Read it ALL at beberlei’s zf-doctrine at master – GitHub.

Zend Framework + Doctrine 1 Integration

Benjamin Eberlei writes; Hello everyone,

I completed a first version of Zend + Doctrine 1 integration today and want to share it with all you. Since currently the status on a 1.11 release is unclear I contacted all the contributors to various Doctrine-related components and combined them into a single release and wrote some documentation on all the different parts and how they relate to each other.

http://github.com/beberlei/zf-doctrine

The code is under the New BSD License. There is a comprehensive getting started guide shipped with the Github Project.

The following parts are included in this release:

  • Application Resource contributed by Matt Lurz
  • Dynamic Form Generation contributed by Jani Hartikainen
  • Paginator Adapter contributed by Matt Lurz and Juozas Kaziukenas
  • Zend Tool Provider and modular Zend Project Style Support

Thanks to all the contributors and various other people that contributed ideas and code.

For any feedback regarding this integration, you can use the issue tracker on Github.

This release depends on Doctrine 1.2.2 to allow model code-generation from YAML files that supports Zend Framework Modular projects and their directory structure.

Most of the current glue code out there is made obsolete by generating Models that follow the Zend Framework naming conventions, into Zend Framework models/ directories. Additionally there is also support for modular applications whose model classes should follow the PEAR naming schema.

Additionally the dynamic form support allows to create simple forms that allow to create and edit Doctrine_Record instances and their relations.

This is a great help to rapidly prototype admin forms (however support for more complex forms is not yet included).

Since both projects are currently very focused on their 2.0 releases, this release aims to glue all the existing code for Doctrine 1.x and Zend Framework integration 1.x together, giving them a platform to flourish.

greetings,
Benjamin

Ajaxify Your Zend_Form Validation with jQuery

Jon Lebensold posts an update to his excellent screencast; We’re going to take what was put together in the last 3 videos and now include some server-side validation that will appear asynchronously. This is an example of using Zend_Form as a validation tool via JSON.

Grab a copy of the project or browse the repository.

UPDATE: as a couple people have mentioned, you can cut down your IndexController even more by using the Zend_Json view helper:

public function validateformAction()
{
$f = new Form_Registration();
$f->isValid($this->_getAllParams());
$this->_helper->json($f->getMessages());
}

Enjoy!

See it at Zendcasts.

Writing Composite Zend_Form Elements

Jon Lebensold writes; This video should help you build your own composite Zend_Form element. We’ll be building a phone element. The phone element will have 3 textboxes, one for geographic location, area code and local code. In the following videos will add a custom cell phone validator and some ajax validation.

Grab a copy of the project or browse the repository.

View the Screen cast: Writing Composite Zend_Form Elements

Tab Container Enabled Forms

Nathan Garlington wrote a nice solution for Tab based forms; Yes, it is possible to display a form in a tabContainer. I do it all the time, including using other dijit containers as well. keep in mind that this is just my solution…there are probably other ways to do this. Feel free to customize it according to your needs. Also, you may notice that I don’t include an action attrib or method attrib declaration to the form node itself…this is because I handle form submitting via xhr. Example code below:


class My_Form extends Zend_Dojo_Form
{
public function init()
{
$this->setDisableLoadDefaultDecorators(true);

// setup the our default decorators
$this->setDecorators(array(
'FormElements',
array('TabContainer', array(
'id' => 'myTabContainer',
'style' => 'width: 950px; height: 420px;',
'dijitParams' => array('tabPosition' => 'top'),
)),
'DijitForm',
));

$this->setName('myAddTrailerForm');

$this->setElementDecorators(array(
array('DijitElement'),
array('Description'),
array('HtmlTag', array('tag' => 'dd')),
array('Label', array('tag' => 'dt')),
));

//call custom class methods to add form members
$this->_addElements()
->_addDisplayGroups();

}

private function _addElements()
{
$this->addElements(array(

// general information display group elements
new Zend_Dojo_Form_Element_FilteringSelect('field1', array(
'label' => 'First Field:',
'multiOptions' =>(array(
'option1' => 'option1',
'option2' => 'option2'
)),
'required' => true,
)),

new Zend_Dojo_Form_Element_CheckBox('cb1', array(
'label' => 'Are you sure?:',
)),

new Zend_Dojo_Form_Element_FilteringSelect('year', array(
'label' => 'Year:',
'multiOptions' => array(/*....*/),
'required' => true,
)),

new Zend_Dojo_Form_Element_ComboBox('comboBox1', array(
'label' => 'ComboBox1:',
'multiOptions' => array(/*....*/),
'required' => true,
'autocomplete' => false,
'attribs' => (array('propercase' => true, 'trim' =>true)),
)),

new Zend_Dojo_Form_Element_ValidationTextBox('validationBox1', array(
'label' => 'ValidationBox1:',
'required' => true,
'attribs' => array('uppercase' => true, 'trim' =>true),
)),

new Zend_Dojo_Form_Element_ValidationTextBox('validationBox2', array(
'label' => 'ValidationBox2:',
'required' => true,
'invalidMessage' => "Please enter a value",
'attribs' => array('maxlength' => 17, 'uppercase' => true, 'trim' =>true),
'filters' => array('StringToUpper'),
'validators' => array('Alnum'),
)),
)); // end $this->addElements

return $this;
} // end _addElements()

/**
* Create the tabbed container layout
*/
private function _addDisplayGroups()
{

// add the display groups
$this->addDisplayGroup(
array( // elements in the displayGroup
'field1',
'cb1'
),
'generalInformation' // displayGroupName
);

$this->generalInformation->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'dl')),
array(
'ContentPane', array(
'title' => 'General Information'
)
)
));

$this->addDisplayGroup(
array(
'year',
'comboBox1',
),
'tab2'
);

$this->tab2->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'dl'),
array(
'ContentPane', array(
'title' => 'Tab 2'
)
)
));

$this->addDisplayGroup(
array(
'validationBox1',
'validationBox2',
),
'tab2'
);

$this->tab2->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'dl', 'class' => 'addTrailer')),
array(
'ContentPane', array(
'title' => 'Axles'
)
)
));

return $this;
} // end _addDisplayGroups();

public function buttonsSubForm()
{
$subForm = new Zend_Dojo_Form_SubForm();
$subForm->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div', 'id' => 'buttonsSubForm', 'class' => 'span-7 push-3 prepend-top')),
))
->setElementDecorators(array(
array('DijitElement'),
))
->addElements(array(
new Zend_Dojo_Form_Element_Button('submit', array(
'type' => 'button',
'label' => 'Submit it!',
'attribs' => array('disabled' => 'disabled'),
)),

new Zend_Dojo_Form_Element_Button('cancel', array(
'label' => 'Cancel',
)),
));
$subForm->submit->removeDecorator('DtDdWrapper');
$subForm->cancel->removeDecorator('DtDdWrapper');
return $subForm;
} // end buttonsSubForm();
} // end class

That’s it. There may be some errors in there, but the idea is there. As you can see, once you see you how it goes together, it’s actually trivial to add dijit layout containers to a zend form. Be sure that you are in fact extending Zend_Dojo_Form, or using one of the other methods shown in the docs for dojo-enabling your form. You may or may not like the buttons subForm I use here either…I do this because otherwise the submit buttons have to be in their own tab, and that makes it confusing for some of my users…they don’t know where the buttons are to submit the form. So I display them in a div that renders outside the tab container, disable the submit button, and using dojo’s methods, I enable the button on the onValidStateChange dojo event. Let me know if you have any questions!

regards,
Nathan Garlington

Zend_Form Decorators Explained

Jon Lebensold posts another great screen cast about one of the most confusing parts of Zend Framework ever created 🙂 ;

One of the pain points for folks who are starting to work with the Zend Framework is the Decorating functionality found in the depths of Zend_Form. I’ve witnessed countless instances when a developer becomes excited by Zend_Form’s easy-to-implement form validation and creation, only to become frustrated by countless hours of fighting with Zend_Form_Decorators. This video is a humble attempt on my part to walk through how Zend_Form Decorators work and how you can reason your way through a desire result. I couldn’t have gotten my own head around this implementation of the decorator pattern without Matthew Weier O’Phinney’s excellent posts and his original devzone article.

UPDATE: check out this blog post / tutorial for ZF 1.10.0: http://framework.zend.com/manual/en/learning.form.decorators.html

I’ll show you a bit about how Zend_Form_Decorators are constructed and how to take the default zend_form layout and transform it into a table.

Grab a copy of the project or browse the repository.

via Zendcasts.

Zend_Form Translated Country & Currency Lists

A very common question is how do I get a localized / translated list of countries, currencies etc for a company registration form or similar.

Here is a easy to use sample; For your cut’n’paste pleasure 🙂


'HtmlTag'),
array('tag' => 'div', 'class' => 'element')),
'Label',
array(array('row' => 'HtmlTag'),
array('tag' => 'li')),
);

private $buttonDecorators = array(
'ViewHelper',
array(array('data' => 'HtmlTag'),
array('tag' => 'div', 'class' => 'button')),
array(array('row' => 'HtmlTag'),
array('tag' => 'li')),
);

public function init()
{
$this->setMethod('post');

$companyName = new Zend_Form_Element_Text('name', array(
'decorators' => $this->elementDecorators,
'label' => _('Company name'),
'description' => _('Enter the company name'),
'required' => true,
'filters' => array(
'StringTrim'
),
'validators' => array(
array('StringLength', false, array(6, 50))
),
'class' => 'input-text'
));

$accountNumber = new Zend_Form_Element_Text('accountno', array(
'decorators' => $this->elementDecorators,
'label' => _('Account number'),
'description' => _('Enter the ORG/VAT number.'),
'required' => true,
'filters' => array(
'StringTrim'
),
'validators' => array(
array('StringLength', false, array(12, 25))
),
'class' => 'input-text'
));
/**
* Generate a Country select box with the localized country
* names based upon the current application wide locale.
*/
$locale = Zend_Registry::getInstance()->get("Zend_Locale");

$countries = ($locale->getTranslationList('Territory',
$locale->getLanguage(),
2));

asort($countries, SORT_LOCALE_STRING);

$country = new Zend_Form_Element_Select('country', array(
'decorators' => $this->elementDecorators,
'label' => _('Country'),
'description' => _('Select the Country of Incorporation.'),
'required' => true,
'filters' => array(
'StringTrim'
),
'class' => 'input-select'
));

$country->addMultiOptions($countries)
->setValue($locale->getRegion());

/**
* Generate a Currency select box with the localizes currency
* names based upon the current application wide locale.
*/
$currencies= ($locale->getTranslationList('NameToCurrency',
$locale->getLanguage(),
2));

asort($currencies, SORT_LOCALE_STRING);

$currency = new Zend_Form_Element_Select('currency', array(
'decorators' => $this->elementDecorators,
'label' => _('Currency'),
'description' => _('Select the billing currency.'),
'required' => true,
'filters' => array(
'StringTrim'
),
'class' => 'input-select'
));

$currency->addMultiOptions($currencies)
->setValue('EUR');

$submit = new Zend_Form_Element_Submit('register', array(
'decorators' => $this->buttonDecorators,
'label' => _('Register'),
'class' => 'input-submit'
));
$this->addElements(Array($companyName,
$country,
$accountNumber,
$currency,
$submit));
}
}

For some more samples and references for these types of functions, check out;
http://framework.zend.com/manual/en/zend.locale.functions.html