SlideShare a Scribd company logo
Disregard Inputs




Acquire Zend_Form
Daniel Cousineau
Interactive Software Engineer @ RAPP
@dcousineau
http://dcousineau.com/
dcousineau@gmail.com
Disregard Inputs, Acquire Zend_Form
Zend_Acl              Zend_Gdata         Zend_Search_Lucene
Zend_Amf              Zend_Http          Zend_Serializer
Zend_Application      Zend_InfoCard      Zend_Server
Zend_Auth             Zend_Json          Zend_Service
Zend_Barcode          Zend_Layout        Zend_Session
Zend_Cache            Zend_Ldap          Zend_Soap
Zend_Captcha          Zend_Loader        Zend_Tag
Zend_Cloud            Zend_Locale        Zend_Test
Zend_CodeGenerator    Zend_Log           Zend_Text
Zend_Config            Zend_Mail          Zend_TimeSync
Zend_Config_Writer     Zend_Markup        Zend_Tool
Zend_Console_Getopt   Zend_Measure       Zend_Tool_Framework
Zend_Controller       Zend_Memory        Zend_Tool_Project
Zend_Currency         Zend_Mime          Zend_Translate
Zend_Date             Zend_Navigation    Zend_Uri
Zend_Db               Zend_Oauth         Zend_Validate
Zend_Debug            Zend_OpenId        Zend_Version
Zend_Dojo             Zend_Paginator     Zend_View
Zend_Dom              Zend_Pdf           Zend_Wildfire
Zend_Exception        Zend_ProgressBar   Zend_XmlRpc
Zend_Feed             Zend_Queue         ZendX_Console_Process_Unix
Zend_File             Zend_Reflection     ZendX_JQuery
Zend_Filter           Zend_Registry
Zend_Form             Zend_Rest
Zend_Acl              Zend_Gdata         Zend_Search_Lucene
Zend_Amf              Zend_Http          Zend_Serializer
Zend_Application      Zend_InfoCard      Zend_Server
Zend_Auth             Zend_Json          Zend_Service
Zend_Barcode          Zend_Layout        Zend_Session
Zend_Cache            Zend_Ldap          Zend_Soap
Zend_Captcha          Zend_Loader        Zend_Tag
Zend_Cloud            Zend_Locale        Zend_Test
Zend_CodeGenerator    Zend_Log           Zend_Text
Zend_Config            Zend_Mail          Zend_TimeSync
Zend_Config_Writer     Zend_Markup        Zend_Tool
Zend_Console_Getopt   Zend_Measure       Zend_Tool_Framework
Zend_Controller       Zend_Memory        Zend_Tool_Project
Zend_Currency         Zend_Mime          Zend_Translate
Zend_Date             Zend_Navigation    Zend_Uri
Zend_Db               Zend_Oauth         Zend_Validate
Zend_Debug            Zend_OpenId        Zend_Version
Zend_Dojo             Zend_Paginator     Zend_View
Zend_Dom              Zend_Pdf           Zend_Wildfire
Zend_Exception        Zend_ProgressBar   Zend_XmlRpc
Zend_Feed             Zend_Queue         ZendX_Console_Process_Unix
Zend_File             Zend_Reflection     ZendX_JQuery
Zend_Filter           Zend_Registry
Zend_Form             Zend_Rest
I CAN HAZ




                                       HAI WERLD!?!
http://snipsnsnailsandpuppydogtails.blogspot.com/2010/05/introducing-captain-jack-sparrow-and.html
Zend_Form
$form = new Zend_Form();

$form->setAction('/path/to/action')
     ->setMethod('post')
     ->setAttrib('id', 'FORMID');
Render Form
$output = $form->render();


<?php print $form; ?>



<form id="FORMID"
      enctype="application/x-www-form-urlencoded"
      action="/path/to/action"
      method="post">
  <dl class="zend_form"></dl>
</form>
Add Elements
$form->addElement('text', 'hello', array(
    'label' => 'Oh Hai Werld!',
    'required' => true,
));



$element = new Zend_Form_Element_Text('hello');
$element->setLabel('Oh Hai Werld!')
        ->setRequired(true);

$form->addElement($element, 'hello');
Add Elements
<dl>
  <dt id="hello-label">
     <label for="hello" class="required">
       Oh Hai Werld!
     </label>
  </dt>
  <dd id="hello-element">
     <input type="text" name="hello" id="hello" value="">
  </dd>
</dl>
Zend_Form_Element_Button
Zend_Form_Element_Captcha
Zend_Form_Element_Checkbox
Zend_Form_Element_File
Zend_Form_Element_Hidden
Zend_Form_Element_Hash
Zend_Form_Element_Image
Zend_Form_Element_MultiCheckbox
Zend_Form_Element_Multiselect
Zend_Form_Element_Radio
Zend_Form_Element_Reset
Zend_Form_Element_Select
Zend_Form_Element_Submit
Zend_Form_Element_Text
Zend_Form_Element_Textarea
Handle Input
if (!empty($_POST) && $form->isValid($_POST)) {
    $values = $form->getValues(); //FORM IS VALID
}



if ($this->getRequest()->isPost()
  && $form->isValid($this->getRequest()->getParams())) {
    $values = $form->getValues(); //FORM IS VALID
}
Add Validation
$form->addElement('text', 'hello', array(
    'label' => 'Oh Hai Werld!',
    'validators' => array(
        'Alnum' //@see Zend_Validate_Alnum
    ),
));



$form->addElement('text', 'hello', array(
    'label' => 'Oh Hai Werld!',
    'validators' => array(
        new Zend_Validate_Alnum(),
    ),
));
Add Filters
$form->addElement('text', 'hello', array(
    'label' => 'Oh Hai Werld!',
    'filters' => array(
        'StringTrim' //@see Zend_Filter_StringTrim
    ),
));



$form->addElement('text', 'hello', array(
    'label' => 'Oh Hai Werld!',
    'filters' => array(
        new Zend_Filter_StringTrim(),
    ),
));
COOL BEST PRACTICES BRO
Extend Zend_Form Object
class Namespace_Form_HelloWorld extends Zend_Form {
    public function init() {
        /* Form Elements & Other Definitions Here ... */
        $this->addElement('text', 'hello', array(
            'label'      => 'Oh Hai Werld!',
            'required'   => true,
            'validators' => array(
                'Alnum',
            ),
        ));

        $this->addElement('submit', 'submit', array(
            'label' => 'I Can Haz Submit',
        ));
    }
}
Extend Zend_Form Object

$form = new Zend_Form();


$form = new Namespace_Form_HelloWorld();
Store Forms By Module
STYLING
Decorator Pattern

BASICALLY: Wrappers for rendering
Element has list of decorators
  Render Decorator n
  Send output to Decorator n+1
  Repeat until no more decorators
Decorator Pattern

  2 “levels” of decorators
    Form-Level
    Element-Level
  Form level decorator “FormElements” loops through
  each element and triggers their render
FormElements DECORATOR

    ELEMENT       DECORATE
                  DECORATE
    ELEMENT
                  DECORATE
       ...

    ELEMENT
Default Form Decorators
$this->addDecorator('FormElements')
     ->addDecorator('HtmlTag', array(
       'tag' => 'dl', 'class' => 'zend_form')
     )
     ->addDecorator('Form');




                          <form>
                 <dl class=”zend_form”>
             Loop & Render Form Elements
Default Element Decorators
$this->addDecorator('ViewHelper')
    ->addDecorator('Errors')
    ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
    ->addDecorator('HtmlTag', array(
       'tag' => 'dd',
       'id' => array('callback' => $getId)
    ))
    ->addDecorator('Label', array('tag' => 'dt'));




                           <dt>LABEL</dt>
                           <dd id=”...”>
                   <p class=”description”></p>
                       RENDER ELEMENT
                    <ul><li>ERRORS</li></ul>
PLEASE EXPLAIN TO ME




HOW BEST PRACTICES FITS
  WITH PHILOSORAPTOR
Integrate Early

 If you’re using custom decorators, set the prefix paths
 EARLY. Constructor OR first few lines of init()
 Optionally have an application-wide parent Form class
 that all other forms extend
   Here you can do common things like set the prefix
   paths
Use render() Sparingly


Overriding Zend_Form::render() is tempting
Useful for bulk-altering element decorators
Just be very judicial
CUSTOM ELEMENTS
Extend Zend_Form_Element


Override loadDefaultDecorators()
  Usually copy original, but replace ViewHelper with
  custom decorator
Add flags and features to your hearts content
Create Decorator

Override render()
  Use an existing render from, say, HtmlTag, as a
  starting point
Use array notation on any sub-fields
  e.g. “fullyQualifiedName[foo]”, etc
Handle/Validate Input
 Override setValue() and getValue()

 setValue() will receive the value from $_FORM
 (including sub-arrays, etc)
 Override isValid() with caution:
   isValid() calls setValue()

   Possibly create custom Zend_Validate_ and
   attach in the custom element
Using

$form->getPluginLoader(Zend_Form::DECORATOR)
     ->addPrefixPath('Namespace_Form_Decorator', '/path/to/decorators');

$form->getPluginLoader(Zend_Form::ELEMENT)
     ->addPrefixPath('Namespace_Form_Element', 'path/to/elements');
Basic Example
Custom Element
class Namespace_Form_Element_Markup extends Zend_Form_Element_Xhtml
{
    public function isValid($value, $context = null) { return true; }

    public function loadDefaultDecorators() {
        if ($this->loadDefaultDecoratorsIsDisabled()) {
            return;
        }

        $decorators = $this->getDecorators();
        if (empty($decorators)) {
            $this->addDecorator(new Namespace_Form_Decorator_Markup())
                 ->addDecorator('HtmlTag', array('tag' => 'dd'));
        }
    }
}
Custom Decorator
class Namespace_Form_Decorator_Markup extends Zend_Form_Decorator_Abstract {
    public function render($content) {
        $element = $this->getElement();
        if (!$element instanceof Namespace_Form_Element_Markup)
            return $content;

        $name      = $element->getName();
        $separator = $this->getSeparator();
        $placement = $this->getPlacement();

        $markup = '<div id="' . $name . '" class="markup">' .
            $element->getValue() .
        '</div>';

        switch ($placement) {
            case self::PREPEND:
                return $markup . $separator . $content;
            case self::APPEND: default:
                return $content . $separator . $markup;
        }
    }
}
Complex Example
Custom Element
class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml {
    const DEFAULT_DATE_FORMAT = '%year%-%month%-%day%';
    //...
    public function loadDefaultDecorators(){
        if ($this->loadDefaultDecoratorsIsDisabled()) return;

        $this->addDecorator(new Namespace_Form_Decorator_Date())
             ->addDecorator('Errors')
             ->addDecorator('Description', array('tag' => 'p', 'class' =>
'description'))
             ->addDecorator('HtmlTag', array(
                'tag' => 'dd',
                'id' => $this->getName() . '-element')
             )
             ->addDecorator('Label', array('tag' => 'dt'));
    }

    public function getDateFormat() {}
    public function setDateFormat($dateFormat) {}
    //...
}
Custom Element
class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml {
    //...
    public function setValue($value) {
        if (is_array($value)) {
            $year = !empty($value['year']) ? $value['year'] : null;
            $month = !empty($value['month']) ? $value['month'] : null;
            $day    = !empty($value['day'])   ? $value['day'] : 1;
            if ($year && $month) {
                 $date = new DateTime();
                 $date->setDate((int)$year, (int)$month, (int) $day);
                 $date->setTime(0, 0, 0);
                 $this->setAutoInsertNotEmptyValidator(false);
                 $this->_value = $date;
            }
        } else {
            $this->_value = $value;
        }

        return $this;
    }
    //...
}
Custom Element
class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml {
    //...
    public function getValue() {
        switch ($this->getReturnType()) {
            case self::RETURN_TYPE_ARRAY:
                if ($this->_value === null)
                    return array('year' => null, 'month' => null, 'day' => null);

                $date = array(
                     'year' => date('Y', $this->_value->getTimestamp()),
                     'month' => date('m', $this->_value->getTimestamp()),
                     'day'   => date('d', $this->_value->getTimestamp())
                );
                array_walk_recursive($date, array($this, '_filterValue'));
                return $date;
            default:
                throw new Zend_Form_Element_Exception('Unknown return type: ' . $this-
>getReturnType());
        }
    }
    //...
}
class Namespace_Form_Decorator_Date extends Zend_Form_Decorator_Abstract {



Custom Decorator
    const DEFAULT_DISPLAY_FORMAT = '%year% / %month% / %day%';
    //...
    public function render($content) {
        $element = $this->getElement();
        if (!$element instanceof FormElementDate)
            return $content;

        $view = $element->getView();
        if (!$view instanceof Zend_View_Interface)
            throw new Zend_Form_Decorator_Exception('View object is required');
        //...
        $markup = str_replace(
            array('%year%', '%month%', '%day%'),
            array(
                $view->formSelect($name . '[year]', $year, $params, $years),
                $view->formSelect($name . '[month]', $month, $params, $months),
                $view->formSelect($name . '[day]', $day, $params, $days),
            ),
            $this->displayFormat
        );

        switch ($this->getPlacement()) {
            case self::PREPEND:
                return $markup . $this->getSeparator() . $content;
            case self::APPEND:
            default:
                return $content . $this->getSeparator() . $markup;
        }
    }
}
BEST PRACTICES




Y U NO USE THEM!?
Mimic Namespace
Mimic Zend_Form’s name spacing
  Namespace_Form_Decorator_
  Zend_Form_Decorator_
If you aren’t already, mimic Zend’s structure (PEAR
style)
  Namespace_Form_Decorator_Date → Namespace/
  Form/Decorator/Date.php
Use Prefix Paths Or Not


Either directly reference the custom classes throughout
your entire project, or don’t
Don’t jump back and forth
http://joind.in/2981

More Related Content

Disregard Inputs, Acquire Zend_Form

  • 2. Daniel Cousineau Interactive Software Engineer @ RAPP @dcousineau http://dcousineau.com/ dcousineau@gmail.com
  • 4. Zend_Acl Zend_Gdata Zend_Search_Lucene Zend_Amf Zend_Http Zend_Serializer Zend_Application Zend_InfoCard Zend_Server Zend_Auth Zend_Json Zend_Service Zend_Barcode Zend_Layout Zend_Session Zend_Cache Zend_Ldap Zend_Soap Zend_Captcha Zend_Loader Zend_Tag Zend_Cloud Zend_Locale Zend_Test Zend_CodeGenerator Zend_Log Zend_Text Zend_Config Zend_Mail Zend_TimeSync Zend_Config_Writer Zend_Markup Zend_Tool Zend_Console_Getopt Zend_Measure Zend_Tool_Framework Zend_Controller Zend_Memory Zend_Tool_Project Zend_Currency Zend_Mime Zend_Translate Zend_Date Zend_Navigation Zend_Uri Zend_Db Zend_Oauth Zend_Validate Zend_Debug Zend_OpenId Zend_Version Zend_Dojo Zend_Paginator Zend_View Zend_Dom Zend_Pdf Zend_Wildfire Zend_Exception Zend_ProgressBar Zend_XmlRpc Zend_Feed Zend_Queue ZendX_Console_Process_Unix Zend_File Zend_Reflection ZendX_JQuery Zend_Filter Zend_Registry Zend_Form Zend_Rest
  • 5. Zend_Acl Zend_Gdata Zend_Search_Lucene Zend_Amf Zend_Http Zend_Serializer Zend_Application Zend_InfoCard Zend_Server Zend_Auth Zend_Json Zend_Service Zend_Barcode Zend_Layout Zend_Session Zend_Cache Zend_Ldap Zend_Soap Zend_Captcha Zend_Loader Zend_Tag Zend_Cloud Zend_Locale Zend_Test Zend_CodeGenerator Zend_Log Zend_Text Zend_Config Zend_Mail Zend_TimeSync Zend_Config_Writer Zend_Markup Zend_Tool Zend_Console_Getopt Zend_Measure Zend_Tool_Framework Zend_Controller Zend_Memory Zend_Tool_Project Zend_Currency Zend_Mime Zend_Translate Zend_Date Zend_Navigation Zend_Uri Zend_Db Zend_Oauth Zend_Validate Zend_Debug Zend_OpenId Zend_Version Zend_Dojo Zend_Paginator Zend_View Zend_Dom Zend_Pdf Zend_Wildfire Zend_Exception Zend_ProgressBar Zend_XmlRpc Zend_Feed Zend_Queue ZendX_Console_Process_Unix Zend_File Zend_Reflection ZendX_JQuery Zend_Filter Zend_Registry Zend_Form Zend_Rest
  • 6. I CAN HAZ HAI WERLD!?! http://snipsnsnailsandpuppydogtails.blogspot.com/2010/05/introducing-captain-jack-sparrow-and.html
  • 7. Zend_Form $form = new Zend_Form(); $form->setAction('/path/to/action') ->setMethod('post') ->setAttrib('id', 'FORMID');
  • 8. Render Form $output = $form->render(); <?php print $form; ?> <form id="FORMID" enctype="application/x-www-form-urlencoded" action="/path/to/action" method="post"> <dl class="zend_form"></dl> </form>
  • 9. Add Elements $form->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'required' => true, )); $element = new Zend_Form_Element_Text('hello'); $element->setLabel('Oh Hai Werld!') ->setRequired(true); $form->addElement($element, 'hello');
  • 10. Add Elements <dl> <dt id="hello-label"> <label for="hello" class="required"> Oh Hai Werld! </label> </dt> <dd id="hello-element"> <input type="text" name="hello" id="hello" value=""> </dd> </dl>
  • 12. Handle Input if (!empty($_POST) && $form->isValid($_POST)) { $values = $form->getValues(); //FORM IS VALID } if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getParams())) { $values = $form->getValues(); //FORM IS VALID }
  • 13. Add Validation $form->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'validators' => array( 'Alnum' //@see Zend_Validate_Alnum ), )); $form->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'validators' => array( new Zend_Validate_Alnum(), ), ));
  • 14. Add Filters $form->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'filters' => array( 'StringTrim' //@see Zend_Filter_StringTrim ), )); $form->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'filters' => array( new Zend_Filter_StringTrim(), ), ));
  • 16. Extend Zend_Form Object class Namespace_Form_HelloWorld extends Zend_Form { public function init() { /* Form Elements & Other Definitions Here ... */ $this->addElement('text', 'hello', array( 'label' => 'Oh Hai Werld!', 'required' => true, 'validators' => array( 'Alnum', ), )); $this->addElement('submit', 'submit', array( 'label' => 'I Can Haz Submit', )); } }
  • 17. Extend Zend_Form Object $form = new Zend_Form(); $form = new Namespace_Form_HelloWorld();
  • 18. Store Forms By Module
  • 20. Decorator Pattern BASICALLY: Wrappers for rendering Element has list of decorators Render Decorator n Send output to Decorator n+1 Repeat until no more decorators
  • 21. Decorator Pattern 2 “levels” of decorators Form-Level Element-Level Form level decorator “FormElements” loops through each element and triggers their render
  • 22. FormElements DECORATOR ELEMENT DECORATE DECORATE ELEMENT DECORATE ... ELEMENT
  • 23. Default Form Decorators $this->addDecorator('FormElements') ->addDecorator('HtmlTag', array( 'tag' => 'dl', 'class' => 'zend_form') ) ->addDecorator('Form'); <form> <dl class=”zend_form”> Loop & Render Form Elements
  • 24. Default Element Decorators $this->addDecorator('ViewHelper') ->addDecorator('Errors') ->addDecorator('Description', array('tag' => 'p', 'class' => 'description')) ->addDecorator('HtmlTag', array( 'tag' => 'dd', 'id' => array('callback' => $getId) )) ->addDecorator('Label', array('tag' => 'dt')); <dt>LABEL</dt> <dd id=”...”> <p class=”description”></p> RENDER ELEMENT <ul><li>ERRORS</li></ul>
  • 25. PLEASE EXPLAIN TO ME HOW BEST PRACTICES FITS WITH PHILOSORAPTOR
  • 26. Integrate Early If you’re using custom decorators, set the prefix paths EARLY. Constructor OR first few lines of init() Optionally have an application-wide parent Form class that all other forms extend Here you can do common things like set the prefix paths
  • 27. Use render() Sparingly Overriding Zend_Form::render() is tempting Useful for bulk-altering element decorators Just be very judicial
  • 29. Extend Zend_Form_Element Override loadDefaultDecorators() Usually copy original, but replace ViewHelper with custom decorator Add flags and features to your hearts content
  • 30. Create Decorator Override render() Use an existing render from, say, HtmlTag, as a starting point Use array notation on any sub-fields e.g. “fullyQualifiedName[foo]”, etc
  • 31. Handle/Validate Input Override setValue() and getValue() setValue() will receive the value from $_FORM (including sub-arrays, etc) Override isValid() with caution: isValid() calls setValue() Possibly create custom Zend_Validate_ and attach in the custom element
  • 32. Using $form->getPluginLoader(Zend_Form::DECORATOR) ->addPrefixPath('Namespace_Form_Decorator', '/path/to/decorators'); $form->getPluginLoader(Zend_Form::ELEMENT) ->addPrefixPath('Namespace_Form_Element', 'path/to/elements');
  • 34. Custom Element class Namespace_Form_Element_Markup extends Zend_Form_Element_Xhtml { public function isValid($value, $context = null) { return true; } public function loadDefaultDecorators() { if ($this->loadDefaultDecoratorsIsDisabled()) { return; } $decorators = $this->getDecorators(); if (empty($decorators)) { $this->addDecorator(new Namespace_Form_Decorator_Markup()) ->addDecorator('HtmlTag', array('tag' => 'dd')); } } }
  • 35. Custom Decorator class Namespace_Form_Decorator_Markup extends Zend_Form_Decorator_Abstract { public function render($content) { $element = $this->getElement(); if (!$element instanceof Namespace_Form_Element_Markup) return $content; $name = $element->getName(); $separator = $this->getSeparator(); $placement = $this->getPlacement(); $markup = '<div id="' . $name . '" class="markup">' . $element->getValue() . '</div>'; switch ($placement) { case self::PREPEND: return $markup . $separator . $content; case self::APPEND: default: return $content . $separator . $markup; } } }
  • 37. Custom Element class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml { const DEFAULT_DATE_FORMAT = '%year%-%month%-%day%'; //... public function loadDefaultDecorators(){ if ($this->loadDefaultDecoratorsIsDisabled()) return; $this->addDecorator(new Namespace_Form_Decorator_Date()) ->addDecorator('Errors') ->addDecorator('Description', array('tag' => 'p', 'class' => 'description')) ->addDecorator('HtmlTag', array( 'tag' => 'dd', 'id' => $this->getName() . '-element') ) ->addDecorator('Label', array('tag' => 'dt')); } public function getDateFormat() {} public function setDateFormat($dateFormat) {} //... }
  • 38. Custom Element class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml { //... public function setValue($value) { if (is_array($value)) { $year = !empty($value['year']) ? $value['year'] : null; $month = !empty($value['month']) ? $value['month'] : null; $day = !empty($value['day']) ? $value['day'] : 1; if ($year && $month) { $date = new DateTime(); $date->setDate((int)$year, (int)$month, (int) $day); $date->setTime(0, 0, 0); $this->setAutoInsertNotEmptyValidator(false); $this->_value = $date; } } else { $this->_value = $value; } return $this; } //... }
  • 39. Custom Element class Namespace_Form_Element_Date extends Zend_Form_Element_Xhtml { //... public function getValue() { switch ($this->getReturnType()) { case self::RETURN_TYPE_ARRAY: if ($this->_value === null) return array('year' => null, 'month' => null, 'day' => null); $date = array( 'year' => date('Y', $this->_value->getTimestamp()), 'month' => date('m', $this->_value->getTimestamp()), 'day' => date('d', $this->_value->getTimestamp()) ); array_walk_recursive($date, array($this, '_filterValue')); return $date; default: throw new Zend_Form_Element_Exception('Unknown return type: ' . $this- >getReturnType()); } } //... }
  • 40. class Namespace_Form_Decorator_Date extends Zend_Form_Decorator_Abstract { Custom Decorator const DEFAULT_DISPLAY_FORMAT = '%year% / %month% / %day%'; //... public function render($content) { $element = $this->getElement(); if (!$element instanceof FormElementDate) return $content; $view = $element->getView(); if (!$view instanceof Zend_View_Interface) throw new Zend_Form_Decorator_Exception('View object is required'); //... $markup = str_replace( array('%year%', '%month%', '%day%'), array( $view->formSelect($name . '[year]', $year, $params, $years), $view->formSelect($name . '[month]', $month, $params, $months), $view->formSelect($name . '[day]', $day, $params, $days), ), $this->displayFormat ); switch ($this->getPlacement()) { case self::PREPEND: return $markup . $this->getSeparator() . $content; case self::APPEND: default: return $content . $this->getSeparator() . $markup; } } }
  • 41. BEST PRACTICES Y U NO USE THEM!?
  • 42. Mimic Namespace Mimic Zend_Form’s name spacing Namespace_Form_Decorator_ Zend_Form_Decorator_ If you aren’t already, mimic Zend’s structure (PEAR style) Namespace_Form_Decorator_Date → Namespace/ Form/Decorator/Date.php
  • 43. Use Prefix Paths Or Not Either directly reference the custom classes throughout your entire project, or don’t Don’t jump back and forth