Understanding and Using Zend Form Decorators. Creating and Rendering Composite Elements

Translations of this material:

into Russian: 6.5 Понимание и использование Zend Form Decorators. Создание и визуализация составных элементов. 9% translated in draft.
Submitted for translation by antdmi 20.02.2011

Text

In the last section, we had an example showing a "date of birth element":

  01. <div class="element">

  02.     <?php echo $form->dateOfBirth->renderLabel() ?>

  03.     <?php echo $this->formText('dateOfBirth[day]', '', array(

  04.         'size' => 2, 'maxlength' => 2)) ?>

  05.     /

  06.     <?php echo $this->formText('dateOfBirth[month]', '', array(

  07.         'size' => 2, 'maxlength' => 2)) ?>

  08.     /

  09.     <?php echo $this->formText('dateOfBirth[year]', '', array(

  10.         'size' => 4, 'maxlength' => 4)) ?>

  11. </div>

How might you represent this element as a Zend_Form_Element? How might you write a decorator to render it?

The Element

The questions about how the element would work include:

    • How would you set and retrieve the value?

    • How would you validate the value?

    • Regardless, how would you then allow for discrete form inputs for the three segments (day, month, year)?

The first two questions center around the form element itself: how would setValue() and getValue() work? There's actually another question implied by the question about the decorator: how would you retrieve the discrete date segments from the element and/or set them?

The solution is to override the setValue() method of your element to provide some custom logic. In this particular case, our element should have three discrete behaviors:

    • If an integer timestamp is provided, it should be used to determine and store the day, month, and year.

    • If a textual string is provided, it should be cast to a timestamp, and then that value used to determine and store the day, month, and year.

    • If an array containing keys for date, month, and year is provided, those values should be stored.

Internally, the day, month, and year will be stored discretely. When the value of the element is retrieved, it will be done so in a normalized string format. We'll override getValue() as well to assemble the discrete date segments into a final string.

Here's what the class would look like:

  01. class My_Form_Element_Date extends Zend_Form_Element_Xhtml

  02. {

  03.     protected $_dateFormat = '%year%-%month%-%day%';

  04.     protected $_day;

  05.     protected $_month;

  06.     protected $_year;

  07. 

  08.     public function setDay($value)

  09.     {

  10.         $this->_day = (int) $value;

  11.         return $this;

  12.     }

  13. 

  14.     public function getDay()

  15.     {

  16.         return $this->_day;

  17.     }

  18. 

  19.     public function setMonth($value)

  20.     {

  21.         $this->_month = (int) $value;

  22.         return $this;

  23.     }

  24. 

  25.     public function getMonth()

  26.     {

  27.         return $this->_month;

  28.     }

  29. 

  30.     public function setYear($value)

  31.     {

  32.         $this->_year = (int) $value;

  33.         return $this;

  34.     }

  35. 

  36.     public function getYear()

  37.     {

  38.         return $this->_year;

  39.     }

  40. 

  41.     public function setValue($value)

  42.     {

  43.         if (is_int($value)) {

  44.             $this->setDay(date('d', $value))

  45.                  ->setMonth(date('m', $value))

  46.                  ->setYear(date('Y', $value));

  47.         } elseif (is_string($value)) {

  48.             $date = strtotime($value);

  49.             $this->setDay(date('d', $date))

  50.                  ->setMonth(date('m', $date))

  51.                  ->setYear(date('Y', $date));

  52.         } elseif (is_array($value)

  53.                  && (isset($value['day'])

  54.                      && isset($value['month'])

  55.                      && isset($value['year'])

  56.                  )

  57.         ) {

  58.             $this->setDay($value['day'])

  59.                  ->setMonth($value['month'])

  60.                  ->setYear($value['year']);

  61.         } else {

  62.             throw new Exception('Invalid date value provided');

  63.         }

  64. 

  65.         return $this;

  66.     }

  67. 

  68.     public function getValue()

  69.     {

  70.         return str_replace(

  71.             array('%year%', '%month%', '%day%'),

  72.             array($this->getYear(), $this->getMonth(), $this->getDay()),

  73.             $this->_dateFormat

  74.         );

  75.     }

Pages: ← previous Ctrl next
1 2 3