SlideShare a Scribd company logo
1 of 44
Download to read offline
Disregard Inputs




Acquire Zend_Form
Daniel Cousineau
Interactive Software Engineer @ RAPP
@dcousineau
http://dcousineau.com/
dcousineau@gmail.com
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

What's hot

Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoMohamed Mosaad
 
Dealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsDealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsViget Labs
 
Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend frameworkGeorge Mihailov
 
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2Atwix
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress sitereferences
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginningAnis Ahmad
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в MagentoMagecom Ukraine
 
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...GeeksLab Odessa
 
Top 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best PracticesTop 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best PracticesOleksandr Zarichnyi
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmdiKlaus
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"GeeksLab Odessa
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 

What's hot (20)

Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
Dealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsDealing With Legacy PHP Applications
Dealing With Legacy PHP Applications
 
Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend framework
 
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
 
Quality code by design
Quality code by designQuality code by design
Quality code by design
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
The new form framework
The new form frameworkThe new form framework
The new form framework
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
 
Top 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best PracticesTop 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best Practices
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmd
 
Os Nixon
Os NixonOs Nixon
Os Nixon
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 

Viewers also liked

Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Pointguest8a5f7a
 
Get ready for FRC 2015: Intro to Java 5 through 8 updates and Eclipse
Get ready for FRC 2015: Intro to Java 5 through 8 updates and EclipseGet ready for FRC 2015: Intro to Java 5 through 8 updates and Eclipse
Get ready for FRC 2015: Intro to Java 5 through 8 updates and EclipseJeanne Boyarsky
 
شرح خطوات التسجيل علي موقع Delicious
شرح خطوات التسجيل علي موقع Deliciousشرح خطوات التسجيل علي موقع Delicious
شرح خطوات التسجيل علي موقع DeliciousMostafa Salama
 
NI FIRST Robotics Controller Training
NI FIRST Robotics Controller TrainingNI FIRST Robotics Controller Training
NI FIRST Robotics Controller TrainingNI FIRST
 
Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Pointguest8a5f7a
 
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!Daniel Cousineau
 
Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Pointguest8a5f7a
 

Viewers also liked (9)

Delicious
DeliciousDelicious
Delicious
 
Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Point
 
Biomol ir
Biomol irBiomol ir
Biomol ir
 
Get ready for FRC 2015: Intro to Java 5 through 8 updates and Eclipse
Get ready for FRC 2015: Intro to Java 5 through 8 updates and EclipseGet ready for FRC 2015: Intro to Java 5 through 8 updates and Eclipse
Get ready for FRC 2015: Intro to Java 5 through 8 updates and Eclipse
 
شرح خطوات التسجيل علي موقع Delicious
شرح خطوات التسجيل علي موقع Deliciousشرح خطوات التسجيل علي موقع Delicious
شرح خطوات التسجيل علي موقع Delicious
 
NI FIRST Robotics Controller Training
NI FIRST Robotics Controller TrainingNI FIRST Robotics Controller Training
NI FIRST Robotics Controller Training
 
Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Point
 
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
 
Podcasting Power Point
Podcasting Power PointPodcasting Power Point
Podcasting Power Point
 

Similar to Disregard Inputs, Acquire Zend_Form

Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormMichelangelo van Dam
 
Utilization of zend an ultimate alternate for intense data processing
Utilization of zend  an ultimate alternate for intense data processingUtilization of zend  an ultimate alternate for intense data processing
Utilization of zend an ultimate alternate for intense data processingCareer at Elsner
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperGary Hockin
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend frameworkSaidur Rahman
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Introduction to Zend framework
Introduction to Zend framework Introduction to Zend framework
Introduction to Zend framework Matteo Magni
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
Apostrophe
ApostropheApostrophe
Apostrophetompunk
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Apostrophe (improved Paris edition)
Apostrophe (improved Paris edition)Apostrophe (improved Paris edition)
Apostrophe (improved Paris edition)tompunk
 

Similar to Disregard Inputs, Acquire Zend_Form (20)

Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
Utilization of zend an ultimate alternate for intense data processing
Utilization of zend  an ultimate alternate for intense data processingUtilization of zend  an ultimate alternate for intense data processing
Utilization of zend an ultimate alternate for intense data processing
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend framework
 
Getting up and running with Zend Framework
Getting up and running with Zend FrameworkGetting up and running with Zend Framework
Getting up and running with Zend Framework
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Introduction to Zend framework
Introduction to Zend framework Introduction to Zend framework
Introduction to Zend framework
 
Introduction to Zend Framework
Introduction to Zend FrameworkIntroduction to Zend Framework
Introduction to Zend Framework
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Apostrophe
ApostropheApostrophe
Apostrophe
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Apostrophe (improved Paris edition)
Apostrophe (improved Paris edition)Apostrophe (improved Paris edition)
Apostrophe (improved Paris edition)
 

Recently uploaded

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

Recently uploaded (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Disregard Inputs, Acquire Zend_Form

  • 2. Daniel Cousineau Interactive Software Engineer @ RAPP @dcousineau http://dcousineau.com/ dcousineau@gmail.com
  • 3.
  • 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