web/enmi/Zend/Form/DisplayGroup.php
changeset 19 1c2f13fd785c
parent 0 4eba9c11703f
equal deleted inserted replaced
18:bd595ad770fc 19:1c2f13fd785c
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Form
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  */
       
    20 
       
    21 /**
       
    22  * Zend_Form_DisplayGroup
       
    23  *
       
    24  * @category   Zend
       
    25  * @package    Zend_Form
       
    26  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    27  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    28  * @version    $Id: DisplayGroup.php 22930 2010-09-09 18:45:18Z matthew $
       
    29  */
       
    30 class Zend_Form_DisplayGroup implements Iterator,Countable
       
    31 {
       
    32     /**
       
    33      * Group attributes
       
    34      * @var array
       
    35      */
       
    36     protected $_attribs = array();
       
    37 
       
    38     /**
       
    39      * Display group decorators
       
    40      * @var array
       
    41      */
       
    42     protected $_decorators = array();
       
    43 
       
    44     /**
       
    45      * Description
       
    46      * @var string
       
    47      */
       
    48     protected $_description;
       
    49 
       
    50     /**
       
    51      * Should we disable loading the default decorators?
       
    52      * @var bool
       
    53      */
       
    54     protected $_disableLoadDefaultDecorators = false;
       
    55 
       
    56     /**
       
    57      * Element order
       
    58      * @var array
       
    59      */
       
    60     protected $_elementOrder = array();
       
    61 
       
    62     /**
       
    63      * Elements
       
    64      * @var array
       
    65      */
       
    66     protected $_elements = array();
       
    67 
       
    68     /**
       
    69      * Form object to which the display group is currently registered
       
    70      * 
       
    71      * @var Zend_Form
       
    72      */
       
    73     protected $_form;
       
    74 
       
    75     /**
       
    76      * Whether or not a new element has been added to the group
       
    77      * @var bool
       
    78      */
       
    79     protected $_groupUpdated = false;
       
    80 
       
    81     /**
       
    82      * Plugin loader for decorators
       
    83      * @var Zend_Loader_PluginLoader
       
    84      */
       
    85     protected $_loader;
       
    86 
       
    87     /**
       
    88      * Group name
       
    89      * @var string
       
    90      */
       
    91     protected $_name;
       
    92 
       
    93     /**
       
    94      * Group order
       
    95      * @var int
       
    96      */
       
    97     protected $_order;
       
    98 
       
    99     /**
       
   100      * @var Zend_Translate
       
   101      */
       
   102     protected $_translator;
       
   103 
       
   104     /**
       
   105      * Is translation disabled?
       
   106      * @var bool
       
   107      */
       
   108     protected $_translatorDisabled = false;
       
   109 
       
   110     /**
       
   111      * @var Zend_View_Interface
       
   112      */
       
   113     protected $_view;
       
   114 
       
   115     /**
       
   116      * Constructor
       
   117      *
       
   118      * @param  string $name
       
   119      * @param  Zend_Loader_PluginLoader $loader
       
   120      * @param  array|Zend_Config $options
       
   121      * @return void
       
   122      */
       
   123     public function __construct($name, Zend_Loader_PluginLoader $loader, $options = null)
       
   124     {
       
   125         $this->setName($name);
       
   126 
       
   127         $this->setPluginLoader($loader);
       
   128 
       
   129         if (is_array($options)) {
       
   130             $this->setOptions($options);
       
   131         } elseif ($options instanceof Zend_Config) {
       
   132             $this->setConfig($options);
       
   133         }
       
   134 
       
   135         // Extensions...
       
   136         $this->init();
       
   137 
       
   138         $this->loadDefaultDecorators();
       
   139     }
       
   140 
       
   141     /**
       
   142      * Initialize object; used by extending classes
       
   143      *
       
   144      * @return void
       
   145      */
       
   146     public function init()
       
   147     {
       
   148     }
       
   149 
       
   150     /**
       
   151      * Set options
       
   152      *
       
   153      * @param  array $options
       
   154      * @return Zend_Form_DisplayGroup
       
   155      */
       
   156     public function setOptions(array $options)
       
   157     {
       
   158         $forbidden = array(
       
   159             'Options', 'Config', 'PluginLoader', 'View',
       
   160             'Translator', 'Attrib'
       
   161         );
       
   162         foreach ($options as $key => $value) {
       
   163             $normalized = ucfirst($key);
       
   164 
       
   165             if (in_array($normalized, $forbidden)) {
       
   166                 continue;
       
   167             }
       
   168 
       
   169             $method = 'set' . $normalized;
       
   170             if (method_exists($this, $method)) {
       
   171                 $this->$method($value);
       
   172             } else {
       
   173                 $this->setAttrib($key, $value);
       
   174             }
       
   175         }
       
   176         return $this;
       
   177     }
       
   178 
       
   179     /**
       
   180      * Set options from config object
       
   181      *
       
   182      * @param  Zend_Config $config
       
   183      * @return Zend_Form_DisplayGroup
       
   184      */
       
   185     public function setConfig(Zend_Config $config)
       
   186     {
       
   187         return $this->setOptions($config->toArray());
       
   188     }
       
   189 
       
   190     /**
       
   191      * Set group attribute
       
   192      *
       
   193      * @param  string $key
       
   194      * @param  mixed $value
       
   195      * @return Zend_Form_DisplayGroup
       
   196      */
       
   197     public function setAttrib($key, $value)
       
   198     {
       
   199         $key = (string) $key;
       
   200         $this->_attribs[$key] = $value;
       
   201         return $this;
       
   202     }
       
   203 
       
   204     /**
       
   205      * Add multiple form attributes at once
       
   206      *
       
   207      * @param  array $attribs
       
   208      * @return Zend_Form_DisplayGroup
       
   209      */
       
   210     public function addAttribs(array $attribs)
       
   211     {
       
   212         foreach ($attribs as $key => $value) {
       
   213             $this->setAttrib($key, $value);
       
   214         }
       
   215         return $this;
       
   216     }
       
   217 
       
   218     /**
       
   219      * Set multiple form attributes at once
       
   220      *
       
   221      * Overwrites any previously set attributes.
       
   222      *
       
   223      * @param  array $attribs
       
   224      * @return Zend_Form_DisplayGroup
       
   225      */
       
   226     public function setAttribs(array $attribs)
       
   227     {
       
   228         $this->clearAttribs();
       
   229         return $this->addAttribs($attribs);
       
   230     }
       
   231 
       
   232     /**
       
   233      * Retrieve a single form attribute
       
   234      *
       
   235      * @param  string $key
       
   236      * @return mixed
       
   237      */
       
   238     public function getAttrib($key)
       
   239     {
       
   240         $key = (string) $key;
       
   241         if (!isset($this->_attribs[$key])) {
       
   242             return null;
       
   243         }
       
   244 
       
   245         return $this->_attribs[$key];
       
   246     }
       
   247 
       
   248     /**
       
   249      * Retrieve all form attributes/metadata
       
   250      *
       
   251      * @return array
       
   252      */
       
   253     public function getAttribs()
       
   254     {
       
   255         return $this->_attribs;
       
   256     }
       
   257 
       
   258     /**
       
   259      * Remove attribute
       
   260      *
       
   261      * @param  string $key
       
   262      * @return bool
       
   263      */
       
   264     public function removeAttrib($key)
       
   265     {
       
   266         if (array_key_exists($key, $this->_attribs)) {
       
   267             unset($this->_attribs[$key]);
       
   268             return true;
       
   269         }
       
   270 
       
   271         return false;
       
   272     }
       
   273 
       
   274     /**
       
   275      * Clear all form attributes
       
   276      *
       
   277      * @return Zend_Form
       
   278      */
       
   279     public function clearAttribs()
       
   280     {
       
   281         $this->_attribs = array();
       
   282         return $this;
       
   283     }
       
   284 
       
   285     /**
       
   286      * Set form object to which the display group is attached
       
   287      * 
       
   288      * @param  Zend_Form $form 
       
   289      * @return Zend_Form_DisplayGroup
       
   290      */
       
   291     public function setForm(Zend_Form $form)
       
   292     {
       
   293         $this->_form = $form;
       
   294 
       
   295         // Ensure any elements attached prior to setting the form are now 
       
   296         // removed from iteration by the form
       
   297         foreach ($this->getElements() as $element) {
       
   298             $form->removeFromIteration($element->getName());
       
   299         }
       
   300 
       
   301         return $this;
       
   302     }
       
   303 
       
   304     /**
       
   305      * Get form object to which the group is attached
       
   306      * 
       
   307      * @return Zend_Form|null
       
   308      */
       
   309     public function getForm()
       
   310     {
       
   311         return $this->_form;
       
   312     }
       
   313 
       
   314     /**
       
   315      * Filter a name to only allow valid variable characters
       
   316      *
       
   317      * @param  string $value
       
   318      * @return string
       
   319      */
       
   320     public function filterName($value)
       
   321     {
       
   322         return preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '', (string) $value);
       
   323     }
       
   324 
       
   325     /**
       
   326      * Set group name
       
   327      *
       
   328      * @param  string $name
       
   329      * @return Zend_Form_DisplayGroup
       
   330      */
       
   331     public function setName($name)
       
   332     {
       
   333         $name = $this->filtername($name);
       
   334         if (('0' !== $name) && empty($name)) {
       
   335             require_once 'Zend/Form/Exception.php';
       
   336             throw new Zend_Form_Exception('Invalid name provided; must contain only valid variable characters and be non-empty');
       
   337         }
       
   338 
       
   339         $this->_name = $name;
       
   340         return $this;
       
   341     }
       
   342 
       
   343     /**
       
   344      * Retrieve group name
       
   345      *
       
   346      * @return string
       
   347      */
       
   348     public function getName()
       
   349     {
       
   350         return $this->_name;
       
   351     }
       
   352 
       
   353     /**
       
   354      * Get fully qualified name
       
   355      *
       
   356      * Places name as subitem of array and/or appends brackets.
       
   357      *
       
   358      * @return string
       
   359      */
       
   360     public function getFullyQualifiedName()
       
   361     {
       
   362         return $this->getName();
       
   363     }
       
   364 
       
   365     /**
       
   366      * Get element id
       
   367      *
       
   368      * @return string
       
   369      */
       
   370     public function getId()
       
   371     {
       
   372         if (isset($this->id)) {
       
   373             return $this->id;
       
   374         }
       
   375 
       
   376         $id = $this->getFullyQualifiedName();
       
   377 
       
   378         // Bail early if no array notation detected
       
   379         if (!strstr($id, '[')) {
       
   380             return $id;
       
   381         }
       
   382 
       
   383         // Strip array notation
       
   384         if ('[]' == substr($id, -2)) {
       
   385             $id = substr($id, 0, strlen($id) - 2);
       
   386         }
       
   387         $id = str_replace('][', '-', $id);
       
   388         $id = str_replace(array(']', '['), '-', $id);
       
   389         $id = trim($id, '-');
       
   390 
       
   391         return $id;
       
   392     }
       
   393 
       
   394     /**
       
   395      * Set group legend
       
   396      *
       
   397      * @param  string $legend
       
   398      * @return Zend_Form_DisplayGroup
       
   399      */
       
   400     public function setLegend($legend)
       
   401     {
       
   402         return $this->setAttrib('legend', (string) $legend);
       
   403     }
       
   404 
       
   405     /**
       
   406      * Retrieve group legend
       
   407      *
       
   408      * @return string
       
   409      */
       
   410     public function getLegend()
       
   411     {
       
   412         return $this->getAttrib('legend');
       
   413     }
       
   414 
       
   415     /**
       
   416      * Set description
       
   417      *
       
   418      * @param  string $value
       
   419      * @return Zend_Form_DisplayGroup
       
   420      */
       
   421     public function setDescription($value)
       
   422     {
       
   423         $this->_description = (string) $value;
       
   424         return $this;
       
   425     }
       
   426 
       
   427     /**
       
   428      * Get description
       
   429      *
       
   430      * @return string
       
   431      */
       
   432     public function getDescription()
       
   433     {
       
   434         return $this->_description;
       
   435     }
       
   436 
       
   437     /**
       
   438      * Set group order
       
   439      *
       
   440      * @param  int $order
       
   441      * @return Zend_Form_Element
       
   442      */
       
   443     public function setOrder($order)
       
   444     {
       
   445         $this->_order = (int) $order;
       
   446         return $this;
       
   447     }
       
   448 
       
   449     /**
       
   450      * Retrieve group order
       
   451      *
       
   452      * @return int
       
   453      */
       
   454     public function getOrder()
       
   455     {
       
   456         return $this->_order;
       
   457     }
       
   458 
       
   459     // Elements
       
   460 
       
   461     /**
       
   462      * Add element to stack
       
   463      *
       
   464      * @param  Zend_Form_Element $element
       
   465      * @return Zend_Form_DisplayGroup
       
   466      */
       
   467     public function addElement(Zend_Form_Element $element)
       
   468     {
       
   469         $this->_elements[$element->getName()] = $element;
       
   470         $this->_groupUpdated = true;
       
   471 
       
   472         // Display group will now handle display of element
       
   473         if (null !== ($form = $this->getForm())) {
       
   474             $form->removeFromIteration($element->getName());
       
   475         }
       
   476 
       
   477         return $this;
       
   478     }
       
   479 
       
   480     /**
       
   481      * Add multiple elements at once
       
   482      *
       
   483      * @param  array $elements
       
   484      * @return Zend_Form_DisplayGroup
       
   485      * @throws Zend_Form_Exception if any element is not a Zend_Form_Element
       
   486      */
       
   487     public function addElements(array $elements)
       
   488     {
       
   489         foreach ($elements as $element) {
       
   490             if (!$element instanceof Zend_Form_Element) {
       
   491                 require_once 'Zend/Form/Exception.php';
       
   492                 throw new Zend_Form_Exception('elements passed via array to addElements() must be Zend_Form_Elements only');
       
   493             }
       
   494             $this->addElement($element);
       
   495         }
       
   496         return $this;
       
   497     }
       
   498 
       
   499     /**
       
   500      * Set multiple elements at once (overwrites)
       
   501      *
       
   502      * @param  array $elements
       
   503      * @return Zend_Form_DisplayGroup
       
   504      */
       
   505     public function setElements(array $elements)
       
   506     {
       
   507         $this->clearElements();
       
   508         return $this->addElements($elements);
       
   509     }
       
   510 
       
   511     /**
       
   512      * Retrieve element
       
   513      *
       
   514      * @param  string $name
       
   515      * @return Zend_Form_Element|null
       
   516      */
       
   517     public function getElement($name)
       
   518     {
       
   519         $name = (string) $name;
       
   520         if (isset($this->_elements[$name])) {
       
   521             return $this->_elements[$name];
       
   522         }
       
   523 
       
   524         return null;
       
   525     }
       
   526 
       
   527     /**
       
   528      * Retrieve elements
       
   529      * @return array
       
   530      */
       
   531     public function getElements()
       
   532     {
       
   533         return $this->_elements;
       
   534     }
       
   535 
       
   536     /**
       
   537      * Remove a single element
       
   538      *
       
   539      * @param  string $name
       
   540      * @return boolean
       
   541      */
       
   542     public function removeElement($name)
       
   543     {
       
   544         $name = (string) $name;
       
   545         if (array_key_exists($name, $this->_elements)) {
       
   546             unset($this->_elements[$name]);
       
   547             $this->_groupUpdated = true;
       
   548             return true;
       
   549         }
       
   550 
       
   551         return false;
       
   552     }
       
   553 
       
   554     /**
       
   555      * Remove all elements
       
   556      *
       
   557      * @return Zend_Form_DisplayGroup
       
   558      */
       
   559     public function clearElements()
       
   560     {
       
   561         $this->_elements = array();
       
   562         $this->_groupUpdated = true;
       
   563         return $this;
       
   564     }
       
   565 
       
   566     // Plugin loader (for decorators)
       
   567 
       
   568     /**
       
   569      * Set plugin loader
       
   570      *
       
   571      * @param  Zend_Loader_PluginLoader $loader
       
   572      * @return Zend_Form_DisplayGroup
       
   573      */
       
   574     public function setPluginLoader(Zend_Loader_PluginLoader $loader)
       
   575     {
       
   576         $this->_loader = $loader;
       
   577         return $this;
       
   578     }
       
   579 
       
   580     /**
       
   581      * Retrieve plugin loader
       
   582      *
       
   583      * @return Zend_Loader_PluginLoader
       
   584      */
       
   585     public function getPluginLoader()
       
   586     {
       
   587         return $this->_loader;
       
   588     }
       
   589 
       
   590     /**
       
   591      * Add a prefix path for the plugin loader
       
   592      *
       
   593      * @param  string $prefix
       
   594      * @param  string $path
       
   595      * @return Zend_Form_DisplayGroup
       
   596      */
       
   597     public function addPrefixPath($prefix, $path)
       
   598     {
       
   599         $this->getPluginLoader()->addPrefixPath($prefix, $path);
       
   600         return $this;
       
   601     }
       
   602 
       
   603     /**
       
   604      * Add several prefix paths at once
       
   605      *
       
   606      * @param  array $spec
       
   607      * @return Zend_Form_DisplayGroup
       
   608      */
       
   609     public function addPrefixPaths(array $spec)
       
   610     {
       
   611         if (isset($spec['prefix']) && isset($spec['path'])) {
       
   612             return $this->addPrefixPath($spec['prefix'], $spec['path']);
       
   613         }
       
   614         foreach ($spec as $prefix => $paths) {
       
   615             if (is_numeric($prefix) && is_array($paths)) {
       
   616                 $prefix = null;
       
   617                 if (isset($paths['prefix']) && isset($paths['path'])) {
       
   618                     $this->addPrefixPath($paths['prefix'], $paths['path']);
       
   619                 }
       
   620             } elseif (!is_numeric($prefix)) {
       
   621                 if (is_string($paths)) {
       
   622                     $this->addPrefixPath($prefix, $paths);
       
   623                 } elseif (is_array($paths)) {
       
   624                     foreach ($paths as $path) {
       
   625                         $this->addPrefixPath($prefix, $path);
       
   626                     }
       
   627                 }
       
   628             }
       
   629         }
       
   630         return $this;
       
   631     }
       
   632 
       
   633     // Decorators
       
   634 
       
   635     /**
       
   636      * Set flag to disable loading default decorators
       
   637      *
       
   638      * @param  bool $flag
       
   639      * @return Zend_Form_Element
       
   640      */
       
   641     public function setDisableLoadDefaultDecorators($flag)
       
   642     {
       
   643         $this->_disableLoadDefaultDecorators = (bool) $flag;
       
   644         return $this;
       
   645     }
       
   646 
       
   647     /**
       
   648      * Should we load the default decorators?
       
   649      *
       
   650      * @return bool
       
   651      */
       
   652     public function loadDefaultDecoratorsIsDisabled()
       
   653     {
       
   654         return $this->_disableLoadDefaultDecorators;
       
   655     }
       
   656 
       
   657     /**
       
   658      * Load default decorators
       
   659      *
       
   660      * @return void
       
   661      */
       
   662     public function loadDefaultDecorators()
       
   663     {
       
   664         if ($this->loadDefaultDecoratorsIsDisabled()) {
       
   665             return $this;
       
   666         }
       
   667 
       
   668         $decorators = $this->getDecorators();
       
   669         if (empty($decorators)) {
       
   670             $this->addDecorator('FormElements')
       
   671                  ->addDecorator('HtmlTag', array('tag' => 'dl'))
       
   672                  ->addDecorator('Fieldset')
       
   673                  ->addDecorator('DtDdWrapper');
       
   674         }
       
   675         return $this;
       
   676     }
       
   677 
       
   678     /**
       
   679      * Instantiate a decorator based on class name or class name fragment
       
   680      *
       
   681      * @param  string $name
       
   682      * @param  null|array $options
       
   683      * @return Zend_Form_Decorator_Interface
       
   684      */
       
   685     protected function _getDecorator($name, $options = null)
       
   686     {
       
   687         $class = $this->getPluginLoader()->load($name);
       
   688         if (null === $options) {
       
   689             $decorator = new $class;
       
   690         } else {
       
   691             $decorator = new $class($options);
       
   692         }
       
   693 
       
   694         return $decorator;
       
   695     }
       
   696 
       
   697     /**
       
   698      * Add a decorator for rendering the group
       
   699      *
       
   700      * @param  string|Zend_Form_Decorator_Interface $decorator
       
   701      * @param  array|Zend_Config $options Options with which to initialize decorator
       
   702      * @return Zend_Form_DisplayGroup
       
   703      */
       
   704     public function addDecorator($decorator, $options = null)
       
   705     {
       
   706         if ($decorator instanceof Zend_Form_Decorator_Interface) {
       
   707             $name = get_class($decorator);
       
   708         } elseif (is_string($decorator)) {
       
   709             $name      = $decorator;
       
   710             $decorator = array(
       
   711                 'decorator' => $name,
       
   712                 'options'   => $options,
       
   713             );
       
   714         } elseif (is_array($decorator)) {
       
   715             foreach ($decorator as $name => $spec) {
       
   716                 break;
       
   717             }
       
   718             if (is_numeric($name)) {
       
   719                 require_once 'Zend/Form/Exception.php';
       
   720                 throw new Zend_Form_Exception('Invalid alias provided to addDecorator; must be alphanumeric string');
       
   721             }
       
   722             if (is_string($spec)) {
       
   723                 $decorator = array(
       
   724                     'decorator' => $spec,
       
   725                     'options'   => $options,
       
   726                 );
       
   727             } elseif ($spec instanceof Zend_Form_Decorator_Interface) {
       
   728                 $decorator = $spec;
       
   729             }
       
   730         } else {
       
   731             require_once 'Zend/Form/Exception.php';
       
   732             throw new Zend_Form_Exception('Invalid decorator provided to addDecorator; must be string or Zend_Form_Decorator_Interface');
       
   733         }
       
   734 
       
   735         $this->_decorators[$name] = $decorator;
       
   736 
       
   737         return $this;
       
   738     }
       
   739 
       
   740     /**
       
   741      * Add many decorators at once
       
   742      *
       
   743      * @param  array $decorators
       
   744      * @return Zend_Form_DisplayGroup
       
   745      */
       
   746     public function addDecorators(array $decorators)
       
   747     {
       
   748         foreach ($decorators as $decoratorName => $decoratorInfo) {
       
   749             if (is_string($decoratorInfo) ||
       
   750                 $decoratorInfo instanceof Zend_Form_Decorator_Interface) {
       
   751                 if (!is_numeric($decoratorName)) {
       
   752                     $this->addDecorator(array($decoratorName => $decoratorInfo));
       
   753                 } else {
       
   754                     $this->addDecorator($decoratorInfo);
       
   755                 }
       
   756             } elseif (is_array($decoratorInfo)) {
       
   757                 $argc    = count($decoratorInfo);
       
   758                 $options = array();
       
   759                 if (isset($decoratorInfo['decorator'])) {
       
   760                     $decorator = $decoratorInfo['decorator'];
       
   761                     if (isset($decoratorInfo['options'])) {
       
   762                         $options = $decoratorInfo['options'];
       
   763                     }
       
   764                     $this->addDecorator($decorator, $options);
       
   765                 } else {
       
   766                     switch (true) {
       
   767                         case (0 == $argc):
       
   768                             break;
       
   769                         case (1 <= $argc):
       
   770                             $decorator  = array_shift($decoratorInfo);
       
   771                         case (2 <= $argc):
       
   772                             $options = array_shift($decoratorInfo);
       
   773                         default:
       
   774                             $this->addDecorator($decorator, $options);
       
   775                             break;
       
   776                     }
       
   777                 }
       
   778             } else {
       
   779                 require_once 'Zend/Form/Exception.php';
       
   780                 throw new Zend_Form_Exception('Invalid decorator passed to addDecorators()');
       
   781             }
       
   782         }
       
   783 
       
   784         return $this;
       
   785     }
       
   786 
       
   787     /**
       
   788      * Overwrite all decorators
       
   789      *
       
   790      * @param  array $decorators
       
   791      * @return Zend_Form_DisplayGroup
       
   792      */
       
   793     public function setDecorators(array $decorators)
       
   794     {
       
   795         $this->clearDecorators();
       
   796         return $this->addDecorators($decorators);
       
   797     }
       
   798 
       
   799     /**
       
   800      * Retrieve a registered decorator
       
   801      *
       
   802      * @param  string $name
       
   803      * @return false|Zend_Form_Decorator_Abstract
       
   804      */
       
   805     public function getDecorator($name)
       
   806     {
       
   807         if (!isset($this->_decorators[$name])) {
       
   808             $len = strlen($name);
       
   809             foreach ($this->_decorators as $localName => $decorator) {
       
   810                 if ($len > strlen($localName)) {
       
   811                     continue;
       
   812                 }
       
   813 
       
   814                 if (0 === substr_compare($localName, $name, -$len, $len, true)) {
       
   815                     if (is_array($decorator)) {
       
   816                         return $this->_loadDecorator($decorator, $localName);
       
   817                     }
       
   818                     return $decorator;
       
   819                 }
       
   820             }
       
   821             return false;
       
   822         }
       
   823 
       
   824         if (is_array($this->_decorators[$name])) {
       
   825             return $this->_loadDecorator($this->_decorators[$name], $name);
       
   826         }
       
   827 
       
   828         return $this->_decorators[$name];
       
   829     }
       
   830 
       
   831     /**
       
   832      * Retrieve all decorators
       
   833      *
       
   834      * @return array
       
   835      */
       
   836     public function getDecorators()
       
   837     {
       
   838         foreach ($this->_decorators as $key => $value) {
       
   839             if (is_array($value)) {
       
   840                 $this->_loadDecorator($value, $key);
       
   841             }
       
   842         }
       
   843         return $this->_decorators;
       
   844     }
       
   845 
       
   846     /**
       
   847      * Remove a single decorator
       
   848      *
       
   849      * @param  string $name
       
   850      * @return bool
       
   851      */
       
   852     public function removeDecorator($name)
       
   853     {
       
   854         $decorator = $this->getDecorator($name);
       
   855         if ($decorator) {
       
   856             if (array_key_exists($name, $this->_decorators)) {
       
   857                 unset($this->_decorators[$name]);
       
   858             } else {
       
   859                 $class = get_class($decorator);
       
   860                 unset($this->_decorators[$class]);
       
   861             }
       
   862             return true;
       
   863         }
       
   864 
       
   865         return false;
       
   866     }
       
   867 
       
   868     /**
       
   869      * Clear all decorators
       
   870      *
       
   871      * @return Zend_Form_DisplayGroup
       
   872      */
       
   873     public function clearDecorators()
       
   874     {
       
   875         $this->_decorators = array();
       
   876         return $this;
       
   877     }
       
   878 
       
   879     /**
       
   880      * Set view
       
   881      *
       
   882      * @param  Zend_View_Interface $view
       
   883      * @return Zend_Form_DisplayGroup
       
   884      */
       
   885     public function setView(Zend_View_Interface $view = null)
       
   886     {
       
   887         $this->_view = $view;
       
   888         return $this;
       
   889     }
       
   890 
       
   891     /**
       
   892      * Retrieve view
       
   893      *
       
   894      * @return Zend_View_Interface
       
   895      */
       
   896     public function getView()
       
   897     {
       
   898         if (null === $this->_view) {
       
   899             require_once 'Zend/Controller/Action/HelperBroker.php';
       
   900             $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
       
   901             $this->setView($viewRenderer->view);
       
   902         }
       
   903 
       
   904         return $this->_view;
       
   905     }
       
   906 
       
   907     /**
       
   908      * Render display group
       
   909      *
       
   910      * @return string
       
   911      */
       
   912     public function render(Zend_View_Interface $view = null)
       
   913     {
       
   914         if (null !== $view) {
       
   915             $this->setView($view);
       
   916         }
       
   917         $content = '';
       
   918         foreach ($this->getDecorators() as $decorator) {
       
   919             $decorator->setElement($this);
       
   920             $content = $decorator->render($content);
       
   921         }
       
   922         return $content;
       
   923     }
       
   924 
       
   925     /**
       
   926      * String representation of group
       
   927      *
       
   928      * @return string
       
   929      */
       
   930     public function __toString()
       
   931     {
       
   932         try {
       
   933             $return = $this->render();
       
   934             return $return;
       
   935         } catch (Exception $e) {
       
   936             trigger_error($e->getMessage(), E_USER_WARNING);
       
   937             return '';
       
   938         }
       
   939     }
       
   940 
       
   941     /**
       
   942      * Set translator object
       
   943      *
       
   944      * @param  Zend_Translate|Zend_Translate_Adapter|null $translator
       
   945      * @return Zend_Form_DisplayGroup
       
   946      */
       
   947     public function setTranslator($translator = null)
       
   948     {
       
   949         if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
       
   950             $this->_translator = $translator;
       
   951         } elseif ($translator instanceof Zend_Translate) {
       
   952             $this->_translator = $translator->getAdapter();
       
   953         } else {
       
   954             require_once 'Zend/Form/Exception.php';
       
   955             throw new Zend_Form_Exception('Invalid translator specified');
       
   956         }
       
   957         return $this;
       
   958     }
       
   959 
       
   960     /**
       
   961      * Retrieve translator object
       
   962      *
       
   963      * @return Zend_Translate_Adapter|null
       
   964      */
       
   965     public function getTranslator()
       
   966     {
       
   967         if ($this->translatorIsDisabled()) {
       
   968             return null;
       
   969         }
       
   970 
       
   971         if (null === $this->_translator) {
       
   972             require_once 'Zend/Form.php';
       
   973             return Zend_Form::getDefaultTranslator();
       
   974         }
       
   975 
       
   976         return $this->_translator;
       
   977     }
       
   978 
       
   979     /**
       
   980      * Indicate whether or not translation should be disabled
       
   981      *
       
   982      * @param  bool $flag
       
   983      * @return Zend_Form_DisplayGroup
       
   984      */
       
   985     public function setDisableTranslator($flag)
       
   986     {
       
   987         $this->_translatorDisabled = (bool) $flag;
       
   988         return $this;
       
   989     }
       
   990 
       
   991     /**
       
   992      * Is translation disabled?
       
   993      *
       
   994      * @return bool
       
   995      */
       
   996     public function translatorIsDisabled()
       
   997     {
       
   998         return $this->_translatorDisabled;
       
   999     }
       
  1000 
       
  1001     /**
       
  1002      * Overloading: allow rendering specific decorators
       
  1003      *
       
  1004      * Call renderDecoratorName() to render a specific decorator.
       
  1005      *
       
  1006      * @param  string $method
       
  1007      * @param  array $args
       
  1008      * @return string
       
  1009      * @throws Zend_Form_Exception for invalid decorator or invalid method call
       
  1010      */
       
  1011     public function __call($method, $args)
       
  1012     {
       
  1013         if ('render' == substr($method, 0, 6)) {
       
  1014             $decoratorName = substr($method, 6);
       
  1015             if (false !== ($decorator = $this->getDecorator($decoratorName))) {
       
  1016                 $decorator->setElement($this);
       
  1017                 $seed = '';
       
  1018                 if (0 < count($args)) {
       
  1019                     $seed = array_shift($args);
       
  1020                 }
       
  1021                 return $decorator->render($seed);
       
  1022             }
       
  1023 
       
  1024             require_once 'Zend/Form/Exception.php';
       
  1025             throw new Zend_Form_Exception(sprintf('Decorator by name %s does not exist', $decoratorName));
       
  1026         }
       
  1027 
       
  1028         require_once 'Zend/Form/Exception.php';
       
  1029         throw new Zend_Form_Exception(sprintf('Method %s does not exist', $method));
       
  1030     }
       
  1031 
       
  1032     // Interfaces: Iterator, Countable
       
  1033 
       
  1034     /**
       
  1035      * Current element
       
  1036      *
       
  1037      * @return Zend_Form_Element
       
  1038      */
       
  1039     public function current()
       
  1040     {
       
  1041         $this->_sort();
       
  1042         current($this->_elementOrder);
       
  1043         $key = key($this->_elementOrder);
       
  1044         return $this->getElement($key);
       
  1045     }
       
  1046 
       
  1047     /**
       
  1048      * Current element
       
  1049      *
       
  1050      * @return string
       
  1051      */
       
  1052     public function key()
       
  1053     {
       
  1054         $this->_sort();
       
  1055         return key($this->_elementOrder);
       
  1056     }
       
  1057 
       
  1058     /**
       
  1059      * Move pointer to next element
       
  1060      *
       
  1061      * @return void
       
  1062      */
       
  1063     public function next()
       
  1064     {
       
  1065         $this->_sort();
       
  1066         next($this->_elementOrder);
       
  1067     }
       
  1068 
       
  1069     /**
       
  1070      * Move pointer to beginning of element loop
       
  1071      *
       
  1072      * @return void
       
  1073      */
       
  1074     public function rewind()
       
  1075     {
       
  1076         $this->_sort();
       
  1077         reset($this->_elementOrder);
       
  1078     }
       
  1079 
       
  1080     /**
       
  1081      * Determine if current element/subform/display group is valid
       
  1082      *
       
  1083      * @return bool
       
  1084      */
       
  1085     public function valid()
       
  1086     {
       
  1087         $this->_sort();
       
  1088         return (current($this->_elementOrder) !== false);
       
  1089     }
       
  1090 
       
  1091     /**
       
  1092      * Count of elements/subforms that are iterable
       
  1093      *
       
  1094      * @return int
       
  1095      */
       
  1096     public function count()
       
  1097     {
       
  1098         return count($this->_elements);
       
  1099     }
       
  1100 
       
  1101     /**
       
  1102      * Sort items according to their order
       
  1103      *
       
  1104      * @return void
       
  1105      */
       
  1106     protected function _sort()
       
  1107     {
       
  1108         if ($this->_groupUpdated || !is_array($this->_elementOrder)) {
       
  1109             $elementOrder = array();
       
  1110             foreach ($this->getElements() as $key => $element) {
       
  1111                 $elementOrder[$key] = $element->getOrder();
       
  1112             }
       
  1113 
       
  1114             $items = array();
       
  1115             $index = 0;
       
  1116             foreach ($elementOrder as $key => $order) {
       
  1117                 if (null === $order) {
       
  1118                     while (array_search($index, $elementOrder, true)) {
       
  1119                         ++$index;
       
  1120                     }
       
  1121                     $items[$index] = $key;
       
  1122                     ++$index;
       
  1123                 } else {
       
  1124                     $items[$order] = $key;
       
  1125                 }
       
  1126             }
       
  1127 
       
  1128             $items = array_flip($items);
       
  1129             asort($items);
       
  1130             $this->_elementOrder = $items;
       
  1131             $this->_groupUpdated = false;
       
  1132         }
       
  1133     }
       
  1134 
       
  1135     /**
       
  1136      * Lazy-load a decorator
       
  1137      *
       
  1138      * @param  array $decorator Decorator type and options
       
  1139      * @param  mixed $name Decorator name or alias
       
  1140      * @return Zend_Form_Decorator_Interface
       
  1141      */
       
  1142     protected function _loadDecorator(array $decorator, $name)
       
  1143     {
       
  1144         $sameName = false;
       
  1145         if ($name == $decorator['decorator']) {
       
  1146             $sameName = true;
       
  1147         }
       
  1148 
       
  1149         $instance = $this->_getDecorator($decorator['decorator'], $decorator['options']);
       
  1150         if ($sameName) {
       
  1151             $newName            = get_class($instance);
       
  1152             $decoratorNames     = array_keys($this->_decorators);
       
  1153             $order              = array_flip($decoratorNames);
       
  1154             $order[$newName]    = $order[$name];
       
  1155             $decoratorsExchange = array();
       
  1156             unset($order[$name]);
       
  1157             asort($order);
       
  1158             foreach ($order as $key => $index) {
       
  1159                 if ($key == $newName) {
       
  1160                     $decoratorsExchange[$key] = $instance;
       
  1161                     continue;
       
  1162                 }
       
  1163                 $decoratorsExchange[$key] = $this->_decorators[$key];
       
  1164             }
       
  1165             $this->_decorators = $decoratorsExchange;
       
  1166         } else {
       
  1167             $this->_decorators[$name] = $instance;
       
  1168         }
       
  1169 
       
  1170         return $instance;
       
  1171     }
       
  1172 }