⬆️ ⬇️

Working with complex decorators in the Zend Framework

Introduction



Zend Framework is a great system. This opinion has developed over a long time of close “communication” with this system. And it is wonderful not because of any super-capabilities provided to the programmer, but because this system surprisingly invites the programmer to his own improvement for him, the programmer, good, offering a simple and at the same time powerful foundation for his own developments.

Working on a project using the Zend Framework, I decided to try to make the most of its capabilities and immediately noticed the Zend_Form component (I deliberately call Zend_Form a component, not a class, because the Zend_Form component consists of the Zend_Form class and a whole set of related classes and interfaces). The documentation says quite simply: “Zend_Form makes it easy to create forms and manage them in your web applications.” In general, this is true, but without preliminary preparation, seven pots will come down from you before you can create and display one more or less complex form. Conceptually, a form in the Zend Framework consists of:Elements are, in fact, what we mean by form elements: input fields, drop-down lists, etc.

The decorator is the entire layout, which is logically connected with the form element (surrounds it), but is not part of it. Simply put, the decorator - the design element of the form.



In this article I will prove the need for a group decorator and publish its code. If you are too lazy to read the fruit of the author’s frauds, you can go directly to the code.

So what's the problem?



Work with decorators so far, in my opinion, the most difficult and painstaking part of the work on the introduction of forms. In the examples given in the documentation, everything is just fine, except for one thing - all these are very simple, I would even say, primitive examples.

But as soon as you need to display something like this



how problems immediately begin. The main problem is that the decorator's repository in the Zend_Form component has a single-level structure, that is, you cannot create nested decorators, you cannot create a decorator for the decorator, etc.

For example, the above form fragment is encoded with the following code:



As we can see, there are two independent branches in the element tree: a table cell, framing the form element itself (input), and a cell framing the label (label). The trouble is that the label is not a form element (it is also a decorator). So, to create such a structure you need to get out with the help of dirty hacks:

$ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

"_".'
);
* This source code was highlighted with Source Code Highlighter .
  1. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  2. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  3. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  4. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  5. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  6. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  7. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  8. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  9. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  10. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  11. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  12. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
  13. $ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

    "_".'
    ); * This source code was highlighted with Source Code Highlighter .
$ this ->setElementDecorators(array( 'ViewHelper' , array( 'decorator' => array( 'br' => 'HtmlTag' ), 'options' => array( 'tag' => 'span' , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'tdOpen' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::PREPEND)), array( 'decorator' => array( 'tdClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'closeOnly' => true , 'placement' => Zend_Form_Decorator_Abstract::APPEND)), array( 'decorator' => array( 'label' => 'Label' ), 'options' => array( 'separator' => '*' )), 'Errors' , array( 'decorator' => array( 'mainCell' => 'HtmlTag' ), 'options' => array( 'tag' => 'td' , 'class' => 'tregleft' )), array( 'decorator' => array( 'mainRowClose' => 'HtmlTag' ), 'options' => array( 'tag' => 'tr' )) )); $usernameFieldLabel = $ this ->user_name->getDecorator( 'label' ); $defaultSeparator = $usernameFieldLabel->getOption( 'separator' ); $usernameFieldLabel->setOption( 'separator' , $defaultSeparator. '

"_".'
);
* This source code was highlighted with Source Code Highlighter .


Of the disadvantages:And simply, not every code, even using hacks, will be able to be displayed like this with the help of decorators. Everything would be much simpler if there was a decorator to which other decorators could be added.

Solution to the problem



Googling, I did not find anything normal and decided to write my own group decorator.

Here is what happened:

  1. <? php
  2. require_once 'Zend / Form / Decorator / Abstract.php' ;
  3. class Zend_Form_Decorator_GroupDecorator extends Zend_Form_Decorator_Abstract {
  4. / **
  5. * Items (decorators) to group
  6. * @var array
  7. * /
  8. protected $ _items = null ;
  9. / **
  10. * Temporary form to perform decorators operations
  11. * @var Zend_Form_Element
  12. * /
  13. private $ _temporaryDecoratorsContainer = null ;
  14. / **
  15. * Constructor
  16. *
  17. * @param array | Zend_Config $ options
  18. * @return void
  19. * /
  20. public function __construct ($ options = null ) {
  21. parent :: __ construct ($ options);
  22. $ this -> _ temporaryDecoratorsContainer = new Zend_Form_Element ( '_temporaryDecoratorsContainer' , array ( 'DisableLoadDefaultDecorators' => true ));
  23. $ this -> getItems ();
  24. }
  25. / **
  26. * Set items to use
  27. *
  28. * @param array $ items
  29. * @return Zend_Form_Decorator_GroupDecorator
  30. * /
  31. public function setItems ($ items) {
  32. $ this -> _ items = $ this -> _ temporaryDecoratorsContainer-> clearDecorators () -> addDecorators ($ items) -> getDecorators ();
  33. return $ this ;
  34. }
  35. / **
  36. * Get tag
  37. *
  38. * If no items are registered, either through setItems () or as an option, uses empty array.
  39. *
  40. * @return array
  41. * /
  42. public function getItems () {
  43. if ( null === $ this -> _ items) {
  44. if ( null === ($ items = $ this -> getOption ( 'items' ))) {
  45. $ this -> setItems (array ());
  46. } else {
  47. $ this -> setItems ($ items);
  48. $ this -> removeOption ( 'items' );
  49. }
  50. }
  51. return $ this -> _ items;
  52. }
  53. public function addDecorator ($ decorator, $ options = null ) {
  54. $ this -> _ temporaryDecoratorsContainer-> addDecorator ($ decorator, $ options);
  55. return $ this ;
  56. }
  57. public function clearDecorators () {
  58. $ this -> _ temporaryDecoratorsContainer-> clearDecorators ();
  59. $ this -> _ items = array ();
  60. }
  61. public function getDecorator ($ index = null ) {
  62. if ( null === $ index) {
  63. return $ this -> _ items;
  64. }
  65. if (is_numeric ($ index)) {
  66. $ _items = array_values ​​($ this -> _ items);
  67. return ($ index <count ($ _ items))? $ _ items [$ index]: null ;
  68. }
  69. if (is_string ($ index)) {
  70. return (array_key_exists ($ index, $ this -> _ items))? $ this -> _ items [$ index]: null ;
  71. }
  72. return null ;
  73. }
  74. public function insertDecoratorBefore ($ index, $ decorator, $ options = null ) {
  75. $ _decoratorsToAdd = $ this -> _ temporaryDecoratorsContainer-> clearDecorators () -> addDecorator ($ decorator, $ options) -> getDecorators ();
  76. if (is_string ($ index)) {
  77. $ index = array_search ($ index, array_keys ($ this -> _ items));
  78. }
  79. if ( false ! == $ index) {
  80. $ first = ($ index> 0)? array_slice ($ this -> _ items, 0, $ index, true ): array ();
  81. $ last = ($ index <count ($ this -> _ items))? array_slice ($ this -> _ items, $ index, null , true ): array ();
  82. $ this -> _ items = array_merge ($ first, (array) $ _ decoratorsToAdd, $ last);
  83. }
  84. return $ this ;
  85. }
  86. / **
  87. * Render content wrapped in a group of decorators
  88. *
  89. * @param string $ content
  90. * @return string
  91. * /
  92. public function render ($ content) {
  93. $ placement = $ this -> getPlacement ();
  94. $ items = $ this -> getItems ();
  95. $ _content = '' ;
  96. foreach ($ items as $ _decorator) {
  97. if ($ _decorator instanceOf Zend_Form_Decorator_Interface) {
  98. $ _decorator-> setElement ($ this -> getElement ());
  99. $ _content = $ _decorator-> render ($ _ content);
  100. }
  101. else {
  102. require_once 'Zend / Form / Decorator / Exception.php' ;
  103. throw new Zend_Form_Decorator_Exception ( 'Invalid decorator' . $ _decorator. 'provided; must be string or Zend_Form_Decorator_Interface' );
  104. }
  105. }
  106. switch ($ placement) {
  107. case self :: APPEND:
  108. return $ content. $ _content;
  109. break ;
  110. case self :: PREPEND:
  111. return $ _content. $ content;
  112. break ;
  113. default :
  114. return $ _content. $ content. $ _ content;
  115. break ;
  116. }
  117. }
  118. }
  119. ?>
* This source code was highlighted with Source Code Highlighter .


This decorator can:Now the above example of creating a form element will look like this:

  1. <? php
  2. class Form_MemberRegister extends Zend_Form {
  3. public function init () {
  4. $ this -> setDisableLoadDefaultDecorators ( true );
  5. $ this -> addDecorator ( 'FormElements' )
  6. -> addDecorator (array ( 'table' => 'HtmlTag' ), array ( 'tag' => 'table' , 'class' => 'treg' ))
  7. -> addDecorator ( 'Form' );
  8. $ this -> addElement ( 'text' , 'user_name' , array ( 'label' => 'Login:' ));
  9. $ this -> addElement ( 'password' , 'password' , array ( 'label' => 'Password:' ));
  10. $ this -> addElement ( 'password' , 'password2' , array ( 'label' => 'Repeat password:' ));
  11. $ this -> addElement ( 'text' , 'email' , array ( 'label' => 'E-mail:' ));
  12. $ this -> setElementDecorators (array (
  13. array ( 'decorator' => array ( 'labelGroup' => 'GroupDecorator' ), 'options' => array ( 'items' => array (
  14. array ( 'decorator' => 'Text' , 'options' => array ( 'text' => '*' )),
  15. array ( 'decorator' => array ( 'span' => 'HtmlTag' ), 'options' => array ( 'tag' => 'span' , 'class' => 'red' ))
  16. array ( 'decorator' => 'Label' , 'options' => array ( 'placement' => Zend_Form_Decorator_Abstract :: PREPEND)),
  17. array ( 'decorator' => array ( 'labelCell' => 'HtmlTag' ), 'options' => array ( 'tag' => 'td' , 'class' => 'tregleft' ))
  18. ))),
  19. array ( 'decorator' => array ( 'elementGroup' => 'GroupDecorator' ), 'options' => array ( 'items' => array (
  20. 'ViewHelper' ,
  21. array ( 'decorator' => array ( 'elementCell' => 'HtmlTag' ), 'options' => array ( 'tag' => 'td' ))
  22. )), 'placement' => Zend_Form_Decorator_Abstract :: APPEND),
  23. array ( 'decorator' => array ( 'mainRowClose' => 'HtmlTag' ), 'options' => array ( 'tag' => 'tr' ))
  24. ))
  25. / **
  26. * @var Zend_Form_Decorator_GroupDecorator
  27. * /
  28. $ usernameFieldLabel = $ this -> user_name-> getDecorator ( 'labelGroup' );
  29. $ usernameFieldLabel-> insertDecoratorBefore ( 'labelCell' , array ( 'usernameNotes' => $ this -> _ getNotesDecorator ($ this -> user_name, 'Login can consist only of Latin letters and the sign "_".' ))));
  30. / **
  31. * @var Zend_Form_Decorator_GroupDecorator
  32. * /
  33. $ emailFieldDecorator = $ this -> email-> getDecorator ( 'elementGroup' );
  34. $ emailFieldDecorator-> insertDecoratorBefore ( 'elementCell' , array ( 'emailNotes' => $ this -> _ getNotesDecorator ($ this -> email, ' Enter only existing and working e-mail. At this address you will be sent a link to confirm registration. ' )));
  35. }
  36. protected function _getNotesDecorator ($ element, $ notesText = '' ) {
  37. $ _d = new Zend_Form_Decorator_GroupDecorator (array ( 'items' => array (
  38. array ( 'decorator' => array ( 'notesText' => 'Text' ), 'options' => array ( 'text' => $ notesText)),
  39. array ( 'decorator' => array ( 'notesTag' => 'HtmlTag' ), 'options' => array ( 'tag' => 'small' )),
  40. array (
  41. 'decorator' => array ( 'br' => 'HtmlTag' ),
  42. 'options' => array ( 'tag' => 'br' , 'openOnly' => true , 'placement' => Zend_Form_Decorator_Abstract :: PREPEND)
  43. )
  44. )));
  45. return $ _d-> setElement ($ element);
  46. }
  47. }
  48. ?>
* This source code was highlighted with Source Code Highlighter .


I apologize in advance if the post was too long.

If there is another, more elegant solution to the problem, let me know - I will sprinkle ashes on my head :)

PS: For opponents of tabular typesetting, I want to note that this is a post about programming, I am not a typesetter - I just needed to display the specified template.


')

Source: https://habr.com/ru/post/42748/



All Articles