PageRenderTime 62ms CodeModel.GetById 18ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 1ms

/library/Zend/Form/Element.php

http://digitalus-cms.googlecode.com/
PHP | 2243 lines | 1245 code | 220 blank | 778 comment | 196 complexity | 4f105e042163df7bd8bd74d98fc97e6e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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/** @see Zend_Filter */
  22require_once 'Zend/Filter.php';
  23
  24/** @see Zend_Form */
  25require_once 'Zend/Form.php';
  26
  27/** @see Zend_Validate_Interface */
  28require_once 'Zend/Validate/Interface.php';
  29
  30/** @see Zend_Validate_Abstract */
  31require_once 'Zend/Validate/Abstract.php';
  32
  33/**
  34 * Zend_Form_Element
  35 *
  36 * @category   Zend
  37 * @package    Zend_Form
  38 * @subpackage Element
  39 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  40 * @license    http://framework.zend.com/license/new-bsd     New BSD License
  41 * @version    $Id: Element.php 21894 2010-04-16 19:41:12Z matthew $
  42 */
  43class Zend_Form_Element implements Zend_Validate_Interface
  44{
  45    /**
  46     * Element Constants
  47     */
  48    const DECORATOR = 'DECORATOR';
  49    const FILTER    = 'FILTER';
  50    const VALIDATE  = 'VALIDATE';
  51
  52    /**
  53     * Default view helper to use
  54     * @var string
  55     */
  56    public $helper = 'formText';
  57
  58    /**
  59     * 'Allow empty' flag
  60     * @var bool
  61     */
  62    protected $_allowEmpty = true;
  63
  64    /**
  65     * Flag indicating whether or not to insert NotEmpty validator when element is required
  66     * @var bool
  67     */
  68    protected $_autoInsertNotEmptyValidator = true;
  69
  70    /**
  71     * Array to which element belongs
  72     * @var string
  73     */
  74    protected $_belongsTo;
  75
  76    /**
  77     * Element decorators
  78     * @var array
  79     */
  80    protected $_decorators = array();
  81
  82    /**
  83     * Element description
  84     * @var string
  85     */
  86    protected $_description;
  87
  88    /**
  89     * Should we disable loading the default decorators?
  90     * @var bool
  91     */
  92    protected $_disableLoadDefaultDecorators = false;
  93
  94    /**
  95     * Custom error messages
  96     * @var array
  97     */
  98    protected $_errorMessages = array();
  99
 100    /**
 101     * Validation errors
 102     * @var array
 103     */
 104    protected $_errors = array();
 105
 106    /**
 107     * Separator to use when concatenating aggregate error messages (for
 108     * elements having array values)
 109     * @var string
 110     */
 111    protected $_errorMessageSeparator = '; ';
 112
 113    /**
 114     * Element filters
 115     * @var array
 116     */
 117    protected $_filters = array();
 118
 119    /**
 120     * Ignore flag (used when retrieving values at form level)
 121     * @var bool
 122     */
 123    protected $_ignore = false;
 124
 125    /**
 126     * Does the element represent an array?
 127     * @var bool
 128     */
 129    protected $_isArray = false;
 130
 131    /**
 132     * Is the error marked as in an invalid state?
 133     * @var bool
 134     */
 135    protected $_isError = false;
 136
 137    /**
 138     * Has the element been manually marked as invalid?
 139     * @var bool
 140     */
 141    protected $_isErrorForced = false;
 142
 143    /**
 144     * Element label
 145     * @var string
 146     */
 147    protected $_label;
 148
 149    /**
 150     * Plugin loaders for filter and validator chains
 151     * @var array
 152     */
 153    protected $_loaders = array();
 154
 155    /**
 156     * Formatted validation error messages
 157     * @var array
 158     */
 159    protected $_messages = array();
 160
 161    /**
 162     * Element name
 163     * @var string
 164     */
 165    protected $_name;
 166
 167    /**
 168     * Order of element
 169     * @var int
 170     */
 171    protected $_order;
 172
 173    /**
 174     * Required flag
 175     * @var bool
 176     */
 177    protected $_required = false;
 178
 179    /**
 180     * @var Zend_Translate
 181     */
 182    protected $_translator;
 183
 184    /**
 185     * Is translation disabled?
 186     * @var bool
 187     */
 188    protected $_translatorDisabled = false;
 189
 190    /**
 191     * Element type
 192     * @var string
 193     */
 194    protected $_type;
 195
 196    /**
 197     * Array of initialized validators
 198     * @var array Validators
 199     */
 200    protected $_validators = array();
 201
 202    /**
 203     * Array of un-initialized validators
 204     * @var array
 205     */
 206    protected $_validatorRules = array();
 207
 208    /**
 209     * Element value
 210     * @var mixed
 211     */
 212    protected $_value;
 213
 214    /**
 215     * @var Zend_View_Interface
 216     */
 217    protected $_view;
 218
 219    /**
 220     * Is a specific decorator being rendered via the magic renderDecorator()?
 221     *
 222     * This is to allow execution of logic inside the render() methods of child
 223     * elements during the magic call while skipping the parent render() method.
 224     *
 225     * @var bool
 226     */
 227    protected $_isPartialRendering = false;
 228
 229    /**
 230     * Constructor
 231     *
 232     * $spec may be:
 233     * - string: name of element
 234     * - array: options with which to configure element
 235     * - Zend_Config: Zend_Config with options for configuring element
 236     *
 237     * @param  string|array|Zend_Config $spec
 238     * @param  array|Zend_Config $options
 239     * @return void
 240     * @throws Zend_Form_Exception if no element name after initialization
 241     */
 242    public function __construct($spec, $options = null)
 243    {
 244        if (is_string($spec)) {
 245            $this->setName($spec);
 246        } elseif (is_array($spec)) {
 247            $this->setOptions($spec);
 248        } elseif ($spec instanceof Zend_Config) {
 249            $this->setConfig($spec);
 250        }
 251
 252        if (is_string($spec) && is_array($options)) {
 253            $this->setOptions($options);
 254        } elseif (is_string($spec) && ($options instanceof Zend_Config)) {
 255            $this->setConfig($options);
 256        }
 257
 258        if (null === $this->getName()) {
 259            require_once 'Zend/Form/Exception.php';
 260            throw new Zend_Form_Exception('Zend_Form_Element requires each element to have a name');
 261        }
 262
 263        /**
 264         * Extensions
 265         */
 266        $this->init();
 267
 268        /**
 269         * Register ViewHelper decorator by default
 270         */
 271        $this->loadDefaultDecorators();
 272    }
 273
 274    /**
 275     * Initialize object; used by extending classes
 276     *
 277     * @return void
 278     */
 279    public function init()
 280    {
 281    }
 282
 283    /**
 284     * Set flag to disable loading default decorators
 285     *
 286     * @param  bool $flag
 287     * @return Zend_Form_Element
 288     */
 289    public function setDisableLoadDefaultDecorators($flag)
 290    {
 291        $this->_disableLoadDefaultDecorators = (bool) $flag;
 292        return $this;
 293    }
 294
 295    /**
 296     * Should we load the default decorators?
 297     *
 298     * @return bool
 299     */
 300    public function loadDefaultDecoratorsIsDisabled()
 301    {
 302        return $this->_disableLoadDefaultDecorators;
 303    }
 304
 305    /**
 306     * Load default decorators
 307     *
 308     * @return void
 309     */
 310    public function loadDefaultDecorators()
 311    {
 312        if ($this->loadDefaultDecoratorsIsDisabled()) {
 313            return;
 314        }
 315
 316        $decorators = $this->getDecorators();
 317        if (empty($decorators)) {
 318            $this->addDecorator('ViewHelper')
 319                ->addDecorator('Errors')
 320                ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
 321                ->addDecorator('HtmlTag', array('tag' => 'dd',
 322                                                'id'  => $this->getName() . '-element'))
 323                ->addDecorator('Label', array('tag' => 'dt'));
 324        }
 325    }
 326
 327    /**
 328     * Set object state from options array
 329     *
 330     * @param  array $options
 331     * @return Zend_Form_Element
 332     */
 333    public function setOptions(array $options)
 334    {
 335        if (isset($options['prefixPath'])) {
 336            $this->addPrefixPaths($options['prefixPath']);
 337            unset($options['prefixPath']);
 338        }
 339
 340        if (isset($options['disableTranslator'])) {
 341            $this->setDisableTranslator($options['disableTranslator']);
 342            unset($options['disableTranslator']);
 343        }
 344
 345        unset($options['options']);
 346        unset($options['config']);
 347
 348        foreach ($options as $key => $value) {
 349            $method = 'set' . ucfirst($key);
 350
 351            if (in_array($method, array('setTranslator', 'setPluginLoader', 'setView'))) {
 352                if (!is_object($value)) {
 353                    continue;
 354                }
 355            }
 356
 357            if (method_exists($this, $method)) {
 358                // Setter exists; use it
 359                $this->$method($value);
 360            } else {
 361                // Assume it's metadata
 362                $this->setAttrib($key, $value);
 363            }
 364        }
 365        return $this;
 366    }
 367
 368    /**
 369     * Set object state from Zend_Config object
 370     *
 371     * @param  Zend_Config $config
 372     * @return Zend_Form_Element
 373     */
 374    public function setConfig(Zend_Config $config)
 375    {
 376        return $this->setOptions($config->toArray());
 377    }
 378
 379
 380    // Localization:
 381
 382    /**
 383     * Set translator object for localization
 384     *
 385     * @param  Zend_Translate|null $translator
 386     * @return Zend_Form_Element
 387     */
 388    public function setTranslator($translator = null)
 389    {
 390        if (null === $translator) {
 391            $this->_translator = null;
 392        } elseif ($translator instanceof Zend_Translate_Adapter) {
 393            $this->_translator = $translator;
 394        } elseif ($translator instanceof Zend_Translate) {
 395            $this->_translator = $translator->getAdapter();
 396        } else {
 397            require_once 'Zend/Form/Exception.php';
 398            throw new Zend_Form_Exception('Invalid translator specified');
 399        }
 400        return $this;
 401    }
 402
 403    /**
 404     * Retrieve localization translator object
 405     *
 406     * @return Zend_Translate_Adapter|null
 407     */
 408    public function getTranslator()
 409    {
 410        if ($this->translatorIsDisabled()) {
 411            return null;
 412        }
 413
 414        if (null === $this->_translator) {
 415            return Zend_Form::getDefaultTranslator();
 416        }
 417        return $this->_translator;
 418    }
 419
 420    /**
 421     * Does this element have its own specific translator?
 422     *
 423     * @return bool
 424     */
 425    public function hasTranslator()
 426    {
 427        return (bool)$this->_translator;
 428    }
 429
 430    /**
 431     * Indicate whether or not translation should be disabled
 432     *
 433     * @param  bool $flag
 434     * @return Zend_Form_Element
 435     */
 436    public function setDisableTranslator($flag)
 437    {
 438        $this->_translatorDisabled = (bool) $flag;
 439        return $this;
 440    }
 441
 442    /**
 443     * Is translation disabled?
 444     *
 445     * @return bool
 446     */
 447    public function translatorIsDisabled()
 448    {
 449        return $this->_translatorDisabled;
 450    }
 451
 452    // Metadata
 453
 454    /**
 455     * Filter a name to only allow valid variable characters
 456     *
 457     * @param  string $value
 458     * @param  bool $allowBrackets
 459     * @return string
 460     */
 461    public function filterName($value, $allowBrackets = false)
 462    {
 463        $charset = '^a-zA-Z0-9_\x7f-\xff';
 464        if ($allowBrackets) {
 465            $charset .= '\[\]';
 466        }
 467        return preg_replace('/[' . $charset . ']/', '', (string) $value);
 468    }
 469
 470    /**
 471     * Set element name
 472     *
 473     * @param  string $name
 474     * @return Zend_Form_Element
 475     */
 476    public function setName($name)
 477    {
 478        $name = $this->filterName($name);
 479        if ('' === $name) {
 480            require_once 'Zend/Form/Exception.php';
 481            throw new Zend_Form_Exception('Invalid name provided; must contain only valid variable characters and be non-empty');
 482        }
 483
 484        $this->_name = $name;
 485        return $this;
 486    }
 487
 488    /**
 489     * Return element name
 490     *
 491     * @return string
 492     */
 493    public function getName()
 494    {
 495        return $this->_name;
 496    }
 497
 498    /**
 499     * Get fully qualified name
 500     *
 501     * Places name as subitem of array and/or appends brackets.
 502     *
 503     * @return string
 504     */
 505    public function getFullyQualifiedName()
 506    {
 507        $name = $this->getName();
 508
 509        if (null !== ($belongsTo = $this->getBelongsTo())) {
 510            $name = $belongsTo . '[' . $name . ']';
 511        }
 512
 513        if ($this->isArray()) {
 514            $name .= '[]';
 515        }
 516
 517        return $name;
 518    }
 519
 520    /**
 521     * Get element id
 522     *
 523     * @return string
 524     */
 525    public function getId()
 526    {
 527        if (isset($this->id)) {
 528            return $this->id;
 529        }
 530
 531        $id = $this->getFullyQualifiedName();
 532
 533        // Bail early if no array notation detected
 534        if (!strstr($id, '[')) {
 535            return $id;
 536        }
 537
 538        // Strip array notation
 539        if ('[]' == substr($id, -2)) {
 540            $id = substr($id, 0, strlen($id) - 2);
 541        }
 542        $id = str_replace('][', '-', $id);
 543        $id = str_replace(array(']', '['), '-', $id);
 544        $id = trim($id, '-');
 545
 546        return $id;
 547    }
 548
 549    /**
 550     * Set element value
 551     *
 552     * @param  mixed $value
 553     * @return Zend_Form_Element
 554     */
 555    public function setValue($value)
 556    {
 557        $this->_value = $value;
 558        return $this;
 559    }
 560
 561    /**
 562     * Filter a value
 563     *
 564     * @param  string $value
 565     * @param  string $key
 566     * @return void
 567     */
 568    protected function _filterValue(&$value, &$key)
 569    {
 570        foreach ($this->getFilters() as $filter) {
 571            $value = $filter->filter($value);
 572        }
 573    }
 574
 575    /**
 576     * Retrieve filtered element value
 577     *
 578     * @return mixed
 579     */
 580    public function getValue()
 581    {
 582        $valueFiltered = $this->_value;
 583
 584        if ($this->isArray() && is_array($valueFiltered)) {
 585            array_walk_recursive($valueFiltered, array($this, '_filterValue'));
 586        } else {
 587            $this->_filterValue($valueFiltered, $valueFiltered);
 588        }
 589
 590        return $valueFiltered;
 591    }
 592
 593    /**
 594     * Retrieve unfiltered element value
 595     *
 596     * @return mixed
 597     */
 598    public function getUnfilteredValue()
 599    {
 600        return $this->_value;
 601    }
 602
 603    /**
 604     * Set element label
 605     *
 606     * @param  string $label
 607     * @return Zend_Form_Element
 608     */
 609    public function setLabel($label)
 610    {
 611        $this->_label = (string) $label;
 612        return $this;
 613    }
 614
 615    /**
 616     * Retrieve element label
 617     *
 618     * @return string
 619     */
 620    public function getLabel()
 621    {
 622        $translator = $this->getTranslator();
 623        if (null !== $translator) {
 624            return $translator->translate($this->_label);
 625        }
 626
 627        return $this->_label;
 628    }
 629
 630    /**
 631     * Set element order
 632     *
 633     * @param  int $order
 634     * @return Zend_Form_Element
 635     */
 636    public function setOrder($order)
 637    {
 638        $this->_order = (int) $order;
 639        return $this;
 640    }
 641
 642    /**
 643     * Retrieve element order
 644     *
 645     * @return int
 646     */
 647    public function getOrder()
 648    {
 649        return $this->_order;
 650    }
 651
 652    /**
 653     * Set required flag
 654     *
 655     * @param  bool $flag Default value is true
 656     * @return Zend_Form_Element
 657     */
 658    public function setRequired($flag = true)
 659    {
 660        $this->_required = (bool) $flag;
 661        return $this;
 662    }
 663
 664    /**
 665     * Is the element required?
 666     *
 667     * @return bool
 668     */
 669    public function isRequired()
 670    {
 671        return $this->_required;
 672    }
 673
 674    /**
 675     * Set flag indicating whether a NotEmpty validator should be inserted when element is required
 676     *
 677     * @param  bool $flag
 678     * @return Zend_Form_Element
 679     */
 680    public function setAutoInsertNotEmptyValidator($flag)
 681    {
 682        $this->_autoInsertNotEmptyValidator = (bool) $flag;
 683        return $this;
 684    }
 685
 686    /**
 687     * Get flag indicating whether a NotEmpty validator should be inserted when element is required
 688     *
 689     * @return bool
 690     */
 691    public function autoInsertNotEmptyValidator()
 692    {
 693        return $this->_autoInsertNotEmptyValidator;
 694    }
 695
 696    /**
 697     * Set element description
 698     *
 699     * @param  string $description
 700     * @return Zend_Form_Element
 701     */
 702    public function setDescription($description)
 703    {
 704        $this->_description = (string) $description;
 705        return $this;
 706    }
 707
 708    /**
 709     * Retrieve element description
 710     *
 711     * @return string
 712     */
 713    public function getDescription()
 714    {
 715        return $this->_description;
 716    }
 717
 718    /**
 719     * Set 'allow empty' flag
 720     *
 721     * When the allow empty flag is enabled and the required flag is false, the
 722     * element will validate with empty values.
 723     *
 724     * @param  bool $flag
 725     * @return Zend_Form_Element
 726     */
 727    public function setAllowEmpty($flag)
 728    {
 729        $this->_allowEmpty = (bool) $flag;
 730        return $this;
 731    }
 732
 733    /**
 734     * Get 'allow empty' flag
 735     *
 736     * @return bool
 737     */
 738    public function getAllowEmpty()
 739    {
 740        return $this->_allowEmpty;
 741    }
 742
 743    /**
 744     * Set ignore flag (used when retrieving values at form level)
 745     *
 746     * @param  bool $flag
 747     * @return Zend_Form_Element
 748     */
 749    public function setIgnore($flag)
 750    {
 751        $this->_ignore = (bool) $flag;
 752        return $this;
 753    }
 754
 755    /**
 756     * Get ignore flag (used when retrieving values at form level)
 757     *
 758     * @return bool
 759     */
 760    public function getIgnore()
 761    {
 762        return $this->_ignore;
 763    }
 764
 765    /**
 766     * Set flag indicating if element represents an array
 767     *
 768     * @param  bool $flag
 769     * @return Zend_Form_Element
 770     */
 771    public function setIsArray($flag)
 772    {
 773        $this->_isArray = (bool) $flag;
 774        return $this;
 775    }
 776
 777    /**
 778     * Is the element representing an array?
 779     *
 780     * @return bool
 781     */
 782    public function isArray()
 783    {
 784        return $this->_isArray;
 785    }
 786
 787    /**
 788     * Set array to which element belongs
 789     *
 790     * @param  string $array
 791     * @return Zend_Form_Element
 792     */
 793    public function setBelongsTo($array)
 794    {
 795        $array = $this->filterName($array, true);
 796        if (!empty($array)) {
 797            $this->_belongsTo = $array;
 798        }
 799
 800        return $this;
 801    }
 802
 803    /**
 804     * Return array name to which element belongs
 805     *
 806     * @return string
 807     */
 808    public function getBelongsTo()
 809    {
 810        return $this->_belongsTo;
 811    }
 812
 813    /**
 814     * Return element type
 815     *
 816     * @return string
 817     */
 818    public function getType()
 819    {
 820        if (null === $this->_type) {
 821            $this->_type = get_class($this);
 822        }
 823
 824        return $this->_type;
 825    }
 826
 827    /**
 828     * Set element attribute
 829     *
 830     * @param  string $name
 831     * @param  mixed $value
 832     * @return Zend_Form_Element
 833     * @throws Zend_Form_Exception for invalid $name values
 834     */
 835    public function setAttrib($name, $value)
 836    {
 837        $name = (string) $name;
 838        if ('_' == $name[0]) {
 839            require_once 'Zend/Form/Exception.php';
 840            throw new Zend_Form_Exception(sprintf('Invalid attribute "%s"; must not contain a leading underscore', $name));
 841        }
 842
 843        if (null === $value) {
 844            unset($this->$name);
 845        } else {
 846            $this->$name = $value;
 847        }
 848
 849        return $this;
 850    }
 851
 852    /**
 853     * Set multiple attributes at once
 854     *
 855     * @param  array $attribs
 856     * @return Zend_Form_Element
 857     */
 858    public function setAttribs(array $attribs)
 859    {
 860        foreach ($attribs as $key => $value) {
 861            $this->setAttrib($key, $value);
 862        }
 863
 864        return $this;
 865    }
 866
 867    /**
 868     * Retrieve element attribute
 869     *
 870     * @param  string $name
 871     * @return string
 872     */
 873    public function getAttrib($name)
 874    {
 875        $name = (string) $name;
 876        if (isset($this->$name)) {
 877            return $this->$name;
 878        }
 879
 880        return null;
 881    }
 882
 883    /**
 884     * Return all attributes
 885     *
 886     * @return array
 887     */
 888    public function getAttribs()
 889    {
 890        $attribs = get_object_vars($this);
 891        foreach ($attribs as $key => $value) {
 892            if ('_' == substr($key, 0, 1)) {
 893                unset($attribs[$key]);
 894            }
 895        }
 896
 897        return $attribs;
 898    }
 899
 900    /**
 901     * Overloading: retrieve object property
 902     *
 903     * Prevents access to properties beginning with '_'.
 904     *
 905     * @param  string $key
 906     * @return mixed
 907     */
 908    public function __get($key)
 909    {
 910        if ('_' == $key[0]) {
 911            require_once 'Zend/Form/Exception.php';
 912            throw new Zend_Form_Exception(sprintf('Cannot retrieve value for protected/private property "%s"', $key));
 913        }
 914
 915        if (!isset($this->$key)) {
 916            return null;
 917        }
 918
 919        return $this->$key;
 920    }
 921
 922    /**
 923     * Overloading: set object property
 924     *
 925     * @param  string $key
 926     * @param  mixed $value
 927     * @return voide
 928     */
 929    public function __set($key, $value)
 930    {
 931        $this->setAttrib($key, $value);
 932    }
 933
 934    /**
 935     * Overloading: allow rendering specific decorators
 936     *
 937     * Call renderDecoratorName() to render a specific decorator.
 938     *
 939     * @param  string $method
 940     * @param  array $args
 941     * @return string
 942     * @throws Zend_Form_Exception for invalid decorator or invalid method call
 943     */
 944    public function __call($method, $args)
 945    {
 946        if ('render' == substr($method, 0, 6)) {
 947            $this->_isPartialRendering = true;
 948            $this->render();
 949            $this->_isPartialRendering = false;
 950            $decoratorName = substr($method, 6);
 951            if (false !== ($decorator = $this->getDecorator($decoratorName))) {
 952                $decorator->setElement($this);
 953                $seed = '';
 954                if (0 < count($args)) {
 955                    $seed = array_shift($args);
 956                }
 957                return $decorator->render($seed);
 958            }
 959
 960            require_once 'Zend/Form/Element/Exception.php';
 961            throw new Zend_Form_Element_Exception(sprintf('Decorator by name %s does not exist', $decoratorName));
 962        }
 963
 964        require_once 'Zend/Form/Element/Exception.php';
 965        throw new Zend_Form_Element_Exception(sprintf('Method %s does not exist', $method));
 966    }
 967
 968    // Loaders
 969
 970    /**
 971     * Set plugin loader to use for validator or filter chain
 972     *
 973     * @param  Zend_Loader_PluginLoader_Interface $loader
 974     * @param  string $type 'decorator', 'filter', or 'validate'
 975     * @return Zend_Form_Element
 976     * @throws Zend_Form_Exception on invalid type
 977     */
 978    public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type)
 979    {
 980        $type = strtoupper($type);
 981        switch ($type) {
 982            case self::DECORATOR:
 983            case self::FILTER:
 984            case self::VALIDATE:
 985                $this->_loaders[$type] = $loader;
 986                return $this;
 987            default:
 988                require_once 'Zend/Form/Exception.php';
 989                throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to setPluginLoader()', $type));
 990        }
 991    }
 992
 993    /**
 994     * Retrieve plugin loader for validator or filter chain
 995     *
 996     * Instantiates with default rules if none available for that type. Use
 997     * 'decorator', 'filter', or 'validate' for $type.
 998     *
 999     * @param  string $type
1000     * @return Zend_Loader_PluginLoader
1001     * @throws Zend_Loader_Exception on invalid type.
1002     */
1003    public function getPluginLoader($type)
1004    {
1005        $type = strtoupper($type);
1006        switch ($type) {
1007            case self::FILTER:
1008            case self::VALIDATE:
1009                $prefixSegment = ucfirst(strtolower($type));
1010                $pathSegment   = $prefixSegment;
1011            case self::DECORATOR:
1012                if (!isset($prefixSegment)) {
1013                    $prefixSegment = 'Form_Decorator';
1014                    $pathSegment   = 'Form/Decorator';
1015                }
1016                if (!isset($this->_loaders[$type])) {
1017                    require_once 'Zend/Loader/PluginLoader.php';
1018                    $this->_loaders[$type] = new Zend_Loader_PluginLoader(
1019                        array('Zend_' . $prefixSegment . '_' => 'Zend/' . $pathSegment . '/')
1020                    );
1021                }
1022                return $this->_loaders[$type];
1023            default:
1024                require_once 'Zend/Form/Exception.php';
1025                throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
1026        }
1027    }
1028
1029    /**
1030     * Add prefix path for plugin loader
1031     *
1032     * If no $type specified, assumes it is a base path for both filters and
1033     * validators, and sets each according to the following rules:
1034     * - decorators: $prefix = $prefix . '_Decorator'
1035     * - filters: $prefix = $prefix . '_Filter'
1036     * - validators: $prefix = $prefix . '_Validate'
1037     *
1038     * Otherwise, the path prefix is set on the appropriate plugin loader.
1039     *
1040     * @param  string $prefix
1041     * @param  string $path
1042     * @param  string $type
1043     * @return Zend_Form_Element
1044     * @throws Zend_Form_Exception for invalid type
1045     */
1046    public function addPrefixPath($prefix, $path, $type = null)
1047    {
1048        $type = strtoupper($type);
1049        switch ($type) {
1050            case self::DECORATOR:
1051            case self::FILTER:
1052            case self::VALIDATE:
1053                $loader = $this->getPluginLoader($type);
1054                $loader->addPrefixPath($prefix, $path);
1055                return $this;
1056            case null:
1057                $prefix = rtrim($prefix, '_');
1058                $path   = rtrim($path, DIRECTORY_SEPARATOR);
1059                foreach (array(self::DECORATOR, self::FILTER, self::VALIDATE) as $type) {
1060                    $cType        = ucfirst(strtolower($type));
1061                    $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
1062                    $pluginPrefix = $prefix . '_' . $cType;
1063                    $loader       = $this->getPluginLoader($type);
1064                    $loader->addPrefixPath($pluginPrefix, $pluginPath);
1065                }
1066                return $this;
1067            default:
1068                require_once 'Zend/Form/Exception.php';
1069                throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
1070        }
1071    }
1072
1073    /**
1074     * Add many prefix paths at once
1075     *
1076     * @param  array $spec
1077     * @return Zend_Form_Element
1078     */
1079    public function addPrefixPaths(array $spec)
1080    {
1081        if (isset($spec['prefix']) && isset($spec['path'])) {
1082            return $this->addPrefixPath($spec['prefix'], $spec['path']);
1083        }
1084        foreach ($spec as $type => $paths) {
1085            if (is_numeric($type) && is_array($paths)) {
1086                $type = null;
1087                if (isset($paths['prefix']) && isset($paths['path'])) {
1088                    if (isset($paths['type'])) {
1089                        $type = $paths['type'];
1090                    }
1091                    $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
1092                }
1093            } elseif (!is_numeric($type)) {
1094                if (!isset($paths['prefix']) || !isset($paths['path'])) {
1095                    foreach ($paths as $prefix => $spec) {
1096                        if (is_array($spec)) {
1097                            foreach ($spec as $path) {
1098                                if (!is_string($path)) {
1099                                    continue;
1100                                }
1101                                $this->addPrefixPath($prefix, $path, $type);
1102                            }
1103                        } elseif (is_string($spec)) {
1104                            $this->addPrefixPath($prefix, $spec, $type);
1105                        }
1106                    }
1107                } else {
1108                    $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
1109                }
1110            }
1111        }
1112        return $this;
1113    }
1114
1115    // Validation
1116
1117    /**
1118     * Add validator to validation chain
1119     *
1120     * Note: will overwrite existing validators if they are of the same class.
1121     *
1122     * @param  string|Zend_Validate_Interface $validator
1123     * @param  bool $breakChainOnFailure
1124     * @param  array $options
1125     * @return Zend_Form_Element
1126     * @throws Zend_Form_Exception if invalid validator type
1127     */
1128    public function addValidator($validator, $breakChainOnFailure = false, $options = array())
1129    {
1130        if ($validator instanceof Zend_Validate_Interface) {
1131            $name = get_class($validator);
1132
1133            if (!isset($validator->zfBreakChainOnFailure)) {
1134                $validator->zfBreakChainOnFailure = $breakChainOnFailure;
1135            }
1136        } elseif (is_string($validator)) {
1137            $name      = $validator;
1138            $validator = array(
1139                'validator' => $validator,
1140                'breakChainOnFailure' => $breakChainOnFailure,
1141                'options'             => $options,
1142            );
1143        } else {
1144            require_once 'Zend/Form/Exception.php';
1145            throw new Zend_Form_Exception('Invalid validator provided to addValidator; must be string or Zend_Validate_Interface');
1146        }
1147
1148
1149        $this->_validators[$name] = $validator;
1150
1151        return $this;
1152    }
1153
1154    /**
1155     * Add multiple validators
1156     *
1157     * @param  array $validators
1158     * @return Zend_Form_Element
1159     */
1160    public function addValidators(array $validators)
1161    {
1162        foreach ($validators as $validatorInfo) {
1163            if (is_string($validatorInfo)) {
1164                $this->addValidator($validatorInfo);
1165            } elseif ($validatorInfo instanceof Zend_Validate_Interface) {
1166                $this->addValidator($validatorInfo);
1167            } elseif (is_array($validatorInfo)) {
1168                $argc                = count($validatorInfo);
1169                $breakChainOnFailure = false;
1170                $options             = array();
1171                if (isset($validatorInfo['validator'])) {
1172                    $validator = $validatorInfo['validator'];
1173                    if (isset($validatorInfo['breakChainOnFailure'])) {
1174                        $breakChainOnFailure = $validatorInfo['breakChainOnFailure'];
1175                    }
1176                    if (isset($validatorInfo['options'])) {
1177                        $options = $validatorInfo['options'];
1178                    }
1179                    $this->addValidator($validator, $breakChainOnFailure, $options);
1180                } else {
1181                    switch (true) {
1182                        case (0 == $argc):
1183                            break;
1184                        case (1 <= $argc):
1185                            $validator  = array_shift($validatorInfo);
1186                        case (2 <= $argc):
1187                            $breakChainOnFailure = array_shift($validatorInfo);
1188                        case (3 <= $argc):
1189                            $options = array_shift($validatorInfo);
1190                        default:
1191                            $this->addValidator($validator, $breakChainOnFailure, $options);
1192                            break;
1193                    }
1194                }
1195            } else {
1196                require_once 'Zend/Form/Exception.php';
1197                throw new Zend_Form_Exception('Invalid validator passed to addValidators()');
1198            }
1199        }
1200
1201        return $this;
1202    }
1203
1204    /**
1205     * Set multiple validators, overwriting previous validators
1206     *
1207     * @param  array $validators
1208     * @return Zend_Form_Element
1209     */
1210    public function setValidators(array $validators)
1211    {
1212        $this->clearValidators();
1213        return $this->addValidators($validators);
1214    }
1215
1216    /**
1217     * Retrieve a single validator by name
1218     *
1219     * @param  string $name
1220     * @return Zend_Validate_Interface|false False if not found, validator otherwise
1221     */
1222    public function getValidator($name)
1223    {
1224        if (!isset($this->_validators[$name])) {
1225            $len = strlen($name);
1226            foreach ($this->_validators as $localName => $validator) {
1227                if ($len > strlen($localName)) {
1228                    continue;
1229                }
1230                if (0 === substr_compare($localName, $name, -$len, $len, true)) {
1231                    if (is_array($validator)) {
1232                        return $this->_loadValidator($validator);
1233                    }
1234                    return $validator;
1235                }
1236            }
1237            return false;
1238        }
1239
1240        if (is_array($this->_validators[$name])) {
1241            return $this->_loadValidator($this->_validators[$name]);
1242        }
1243
1244        return $this->_validators[$name];
1245    }
1246
1247    /**
1248     * Retrieve all validators
1249     *
1250     * @return array
1251     */
1252    public function getValidators()
1253    {
1254        $validators = array();
1255        foreach ($this->_validators as $key => $value) {
1256            if ($value instanceof Zend_Validate_Interface) {
1257                $validators[$key] = $value;
1258                continue;
1259            }
1260            $validator = $this->_loadValidator($value);
1261            $validators[get_class($validator)] = $validator;
1262        }
1263        return $validators;
1264    }
1265
1266    /**
1267     * Remove a single validator by name
1268     *
1269     * @param  string $name
1270     * @return bool
1271     */
1272    public function removeValidator($name)
1273    {
1274        if (isset($this->_validators[$name])) {
1275            unset($this->_validators[$name]);
1276        } else {
1277            $len = strlen($name);
1278            foreach (array_keys($this->_validators) as $validator) {
1279                if ($len > strlen($validator)) {
1280                    continue;
1281                }
1282                if (0 === substr_compare($validator, $name, -$len, $len, true)) {
1283                    unset($this->_validators[$validator]);
1284                    break;
1285                }
1286            }
1287        }
1288
1289        return $this;
1290    }
1291
1292    /**
1293     * Clear all validators
1294     *
1295     * @return Zend_Form_Element
1296     */
1297    public function clearValidators()
1298    {
1299        $this->_validators = array();
1300        return $this;
1301    }
1302
1303    /**
1304     * Validate element value
1305     *
1306     * If a translation adapter is registered, any error messages will be
1307     * translated according to the current locale, using the given error code;
1308     * if no matching translation is found, the original message will be
1309     * utilized.
1310     *
1311     * Note: The *filtered* value is validated.
1312     *
1313     * @param  mixed $value
1314     * @param  mixed $context
1315     * @return boolean
1316     */
1317    public function isValid($value, $context = null)
1318    {
1319        $this->setValue($value);
1320        $value = $this->getValue();
1321
1322        if ((('' === $value) || (null === $value))
1323            && !$this->isRequired()
1324            && $this->getAllowEmpty()
1325        ) {
1326            return true;
1327        }
1328
1329        if ($this->isRequired()
1330            && $this->autoInsertNotEmptyValidator()
1331            && !$this->getValidator('NotEmpty'))
1332        {
1333            $validators = $this->getValidators();
1334            $notEmpty   = array('validator' => 'NotEmpty', 'breakChainOnFailure' => true);
1335            array_unshift($validators, $notEmpty);
1336            $this->setValidators($validators);
1337        }
1338
1339        // Find the correct translator. Zend_Validate_Abstract::getDefaultTranslator()
1340        // will get either the static translator attached to Zend_Validate_Abstract
1341        // or the 'Zend_Translate' from Zend_Registry.
1342        if (Zend_Validate_Abstract::hasDefaultTranslator() &&
1343            !Zend_Form::hasDefaultTranslator())
1344        {
1345            $translator = Zend_Validate_Abstract::getDefaultTranslator();
1346            if ($this->hasTranslator()) {
1347                // only pick up this element's translator if it was attached directly.
1348                $translator = $this->getTranslator();
1349            }
1350        } else {
1351            $translator = $this->getTranslator();
1352        }
1353
1354        $this->_messages = array();
1355        $this->_errors   = array();
1356        $result          = true;
1357        $isArray         = $this->isArray();
1358        foreach ($this->getValidators() as $key => $validator) {
1359            if (method_exists($validator, 'setTranslator')) {
1360                if (method_exists($validator, 'hasTranslator')) {
1361                    if (!$validator->hasTranslator()) {
1362                        $validator->setTranslator($translator);
1363                    }
1364                } else {
1365                    $validator->setTranslator($translator);
1366                }
1367            }
1368
1369            if (method_exists($validator, 'setDisableTranslator')) {
1370                $validator->setDisableTranslator($this->translatorIsDisabled());
1371            }
1372
1373            if ($isArray && is_array($value)) {
1374                $messages = array();
1375                $errors   = array();
1376                foreach ($value as $val) {
1377                    if (!$validator->isValid($val, $context)) {
1378                        $result = false;
1379                        if ($this->_hasErrorMessages()) {
1380                            $messages = $this->_getErrorMessages();
1381                            $errors   = $messages;
1382                        } else {
1383                            $messages = array_merge($messages, $validator->getMessages());
1384                            $errors   = array_merge($errors,   $validator->getErrors());
1385                        }
1386                    }
1387                }
1388                if ($result) {
1389                    continue;
1390                }
1391            } elseif ($validator->isValid($value, $context)) {
1392                continue;
1393            } else {
1394                $result = false;
1395                if ($this->_hasErrorMessages()) {
1396                    $messages = $this->_getErrorMessages();
1397                    $errors   = $messages;
1398                } else {
1399                    $messages = $validator->getMessages();
1400                    $errors   = array_keys($messages);
1401                }
1402            }
1403
1404            $result          = false;
1405            $this->_messages = array_merge($this->_messages, $messages);
1406            $this->_errors   = array_merge($this->_errors,   $errors);
1407
1408            if ($validator->zfBreakChainOnFailure) {
1409                break;
1410            }
1411        }
1412
1413        // If element manually flagged as invalid, return false
1414        if ($this->_isErrorForced) {
1415            return false;
1416        }
1417
1418        return $result;
1419    }
1420
1421    /**
1422     * Add a custom error message to return in the event of failed validation
1423     *
1424     * @param  string $message
1425     * @return Zend_Form_Element
1426     */
1427    public function addErrorMessage($message)
1428    {
1429        $this->_errorMessages[] = (string) $message;
1430        return $this;
1431    }
1432
1433    /**
1434     * Add multiple custom error messages to return in the event of failed validation
1435     *
1436     * @param  array $messages
1437     * @return Zend_Form_Element
1438     */
1439    public function addErrorMessages(array $messages)
1440    {
1441        foreach ($messages as $message) {
1442            $this->addErrorMessage($message);
1443        }
1444        return $this;
1445    }
1446
1447    /**
1448     * Same as addErrorMessages(), but clears custom error message stack first
1449     *
1450     * @param  array $messages
1451     * @return Zend_Form_Element
1452     */
1453    public function setErrorMessages(array $messages)
1454    {
1455        $this->clearErrorMessages();
1456        return $this->addErrorMessages($messages);
1457    }
1458
1459    /**
1460     * Retrieve custom error messages
1461     *
1462     * @return array
1463     */
1464    public function getErrorMessages()
1465    {
1466        return $this->_errorMessages;
1467    }
1468
1469    /**
1470     * Clear custom error messages stack
1471     *
1472     * @return Zend_Form_Element
1473     */
1474    public function clearErrorMessages()
1475    {
1476        $this->_errorMessages = array();
1477        return $this;
1478    }
1479
1480    /**
1481     * Get errorMessageSeparator
1482     *
1483     * @return string
1484     */
1485    public function getErrorMessageSeparator()
1486    {
1487        return $this->_errorMessageSeparator;
1488    }
1489
1490    /**
1491     * Set errorMessageSeparator
1492     *
1493     * @param  string $separator
1494     * @return Zend_Form_Element
1495     */
1496    public function setErrorMessageSeparator($separator)
1497    {
1498        $this->_errorMessageSeparator = $separator;
1499        return $this;
1500    }
1501
1502    /**
1503     * Mark the element as being in a failed validation state
1504     *
1505     * @return Zend_Form_Element
1506     */
1507    public function markAsError()
1508    {
1509        $messages       = $this->getMessages();
1510        $customMessages = $this->_getErrorMessages();
1511        $messages       = $messages + $customMessages;
1512        if (empty($messages)) {
1513            $this->_isError = true;
1514        } else {
1515            $this->_messages = $messages;
1516        }
1517        $this->_isErrorForced = true;
1518        return $this;
1519    }
1520
1521    /**
1522     * Add an error message and mark element as failed validation
1523     *
1524     * @param  string $message
1525     * @return Zend_Form_Element
1526     */
1527    public function addError($message)
1528    {
1529        $this->addErrorMessage($message);
1530        $this->markAsError();
1531        return $this;
1532    }
1533
1534    /**
1535     * Add multiple error messages and flag element as failed validation
1536     *
1537     * @param  array $messages
1538     * @return Zend_Form_Element
1539     */
1540    public function addErrors(array $messages)
1541    {
1542        foreach ($messages as $message) {
1543            $this->addError($message);
1544        }
1545        return $this;
1546    }
1547
1548    /**
1549     * Overwrite any previously set error messages and flag as failed validation
1550     *
1551     * @param  array $messages
1552     * @return Zend_Form_Element
1553     */
1554    public function setErrors(array $messages)
1555    {
1556        $this->clearErrorMessages();
1557        return $this->addErrors($messages);
1558    }
1559
1560    /**
1561     * Are there errors registered?
1562     *
1563     * @return bool
1564     */
1565    public function hasErrors()
1566    {
1567        return (!empty($this->_messages) || $this->_isError);
1568    }
1569
1570    /**
1571     * Retrieve validator chain errors
1572     *
1573     * @return array
1574     */
1575    public function getErrors()
1576    {
1577        return $this->_errors;
1578    }
1579
1580    /**
1581     * Retrieve error messages
1582     *
1583     * @return array
1584     */
1585    public function getMessages()
1586    {
1587        return $this->_messages;
1588    }
1589
1590
1591    // Filtering
1592
1593    /**
1594     * Add a filter to the element
1595     *
1596     * @param  string|Zend_Filter_Interface $filter
1597     * @return Zend_Form_Element
1598     */
1599    public function addFilter($filter, $options = array())
1600    {
1601        if ($filter instanceof Zend_Filter_Interface) {
1602            $name = get_class($filter);
1603        } elseif (is_string($filter)) {
1604            $name = $filter;
1605            $filter = array(
1606                'filter'  => $filter,
1607                'options' => $options,
1608            );
1609            $this->_filters[$name] = $filter;
1610        } else {
1611            require_once 'Zend/Form/Exception.php';
1612            throw new Zend_Form_Exception('Invalid filter provided to addFilter; must be string or Zend_Filter_Interface');
1613        }
1614
1615        $this->_filters[$name] = $filter;
1616
1617        return $this;
1618    }
1619
1620    /**
1621     * Add filters to element
1622     *
1623     * @param  array $filters
1624     * @return Zend_Form_Element
1625     */
1626    public function addFilters(array $filters)
1627    {
1628        foreach ($filters as $filterInfo) {
1629            if (is_string($filterInfo)) {
1630                $this->addFilter($filterInfo);
1631            } elseif ($filterInfo instanceof Zend_Filter_Interface) {
1632                $this->addFilter($filterInfo);
1633            } elseif (is_array($filterInfo)) {
1634                $argc                = count($filterInfo);
1635                $options             = array();
1636                if (isset($filterInfo['filter'])) {
1637                    $filter = $filterInfo['filter'];
1638                    if (isset($filterInfo['options'])) {
1639                        $options = $filterInfo['options'];
1640                    }
1641                    $this->addFilter($filter, $options);
1642                } else {
1643                    switch (true) {
1644                        case (0 == $argc):
1645                            break;
1646                        case (1 <= $argc):
1647                            $filter  = array_shift($filterInfo);
1648                        case (2 <= $argc):
1649                            $options = array_shift($filterInfo);
1650                        default:
1651                            $this->addFilter($filter, $options);
1652                            break;
1653                    }
1654                }
1655            } else {
1656                require_once 'Zend/Form/Exception.php';
1657                throw new Zend_Form_Exception('Invalid filter passed to addFilters()');
1658            }
1659        }
1660
1661        return $this;
1662    }
1663
1664    /**
1665     * Add filters to element, overwriting any already existing
1666     *
1667     * @param  array $filters
1668     * @return Zend_Form_Element
1669     */
1670    public function setFilters(array $filters)
1671    {
1672        $this->clearFilters();
1673        return $this->addFilters($filters);
1674    }
1675
1676    /**
1677     * Retrieve a single filter by name
1678     *
1679     * @param  string $name
1680     * @return Zend_Filter_Interface
1681     */
1682    public function getFilter($name)
1683    {
1684        if (!isset($this->_filters[$name])) {
1685            $len = strlen($name);
1686            foreach ($this->_filters as $localName => $filter) {
1687                if ($len > strlen($localName)) {
1688                    continue;
1689                }
1690
1691                if (0 === substr_compare($localName, $name, -$len, $len, true)) {
1692                    if (is_array($filter)) {
1693                        return $this->_loadFilter($filter);
1694                    }
1695                    return $filter;
1696                }
1697            }
1698            return false;
1699        }
1700
1701        if (is_array($this->_filters[$name])) {
1702            return $this->_loadFilter($this->_filters[$name]);
1703        }
1704
1705        return $this->_filters[$name];
1706    }
1707
1708    /**
1709     * Get all filters
1710     *
1711     * @return array
1712     */
1713    public function getFilters()
1714    {
1715        $filters = array();
1716        foreach ($this->_filters as $key => $value) {
1717            if ($value instanceof Zend_Filter_Interface) {
1718                $filters[$key] = $value;
1719                continue;
1720            }
1721            $filter = $this->_loadFilter($value);
1722            $filters[get_class($filter)] = $filter;
1723        }
1724        return $filters;
1725    }
1726
1727    /**
1728     * Remove a filter by name
1729     *
1730     * @param  string $name
1731     * @return Zend_Form_Element
1732     */
1733    public function removeFilter($name)
1734    {
1735        if (isset($this->_filters[$name])) {
1736            unset($this->_filters[$name]);
1737        } else {
1738            $len = strlen($name);
1739            foreach (array_keys($this->_filters) as $filter) {
1740                if ($len > strlen($filter)) {
1741                    continue;
1742                }
1743                if (0 === substr_compare($filter, $name, -$len, $len, true)) {
1744                    unset($this->_filters[$filter]);
1745                    break;
1746                }
1747            }
1748        }
1749
1750        return $this;
1751    }
1752
1753    /**
1754     * Clear all filters
1755     *
1756     * @return Zend_Form_Element
1757     */
1758    public function clearFilters()
1759    {
1760        $this->_filters = array();
1761        return $this;
1762    }
1763
1764    // Rendering
1765
1766    /**
1767     * Set view object
1768     *
1769     * @param  Zend_View_Interface $view
1770     * @return Zend_Form_Element
1771     */
1772    public function setView(Zend_View_Interface $view = null)
1773    {
1774        $this->_view = $view;
1775        return $this;
1776    }
1777
1778    /**
1779     * Retrieve view object
1780     *
1781     * Retrieves from ViewRenderer if none previously set.
1782     *
1783     * @return null|Zend_View_Interface
1784     */
1785    public function getView()
1786    {
1787        if (null === $this->_view) {
1788            require_once 'Zend/Controller/Action/HelperBroker.php';
1789            $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
1790            $this->setView($viewRenderer->view);
1791        }
1792        return $this->_view;
1793    }
1794
1795    /**
1796     * Instantiate a decorator based on class name or class name fragment
1797     *
1798     * @param  string $name
1799     * @param  null|array $options
1800     * @return Zend_Form_Decorator_Interface
1801     */
1802    protected function _getDecorator($name, $options)
1803    {
1804        $class = $this->getPluginLoader(self::DECORATOR)->load($name);
1805        if (null === $options) {
1806            $decorator = new $class;
1807        } else {
1808            $decorator = new $class($options);
1809        }
1810
1811        return $decorator;
1812    }
1813
1814    /**
1815     * Add a decorator for rendering the element
1816     *
1817     * @param  string|Zend_Form_Decorator_Interface $decorator
1818     * @param  array|Zend_Config $options Options with which to initialize decorator
1819     * @return Zend_Form_Element
1820     */
1821    public function addDecorator($decorator, $options = null)
1822    {
1823        if ($decorator instanceof Zend_Form_Decorator_Interface) {
1824            $name = get_class($decorator);
1825        } elseif (is_string($decorator)) {
1826            $name      = $decorator;
1827            $decorator = array(
1828                'decorator' => $name,
1829                'options'   => $options,
1830            );
1831        } elseif (is_array($decorator)) {
1832            foreach ($decorator as $name => $spec) {
1833                break;
1834            }
1835            if (is_numeric($name)) {
1836                require_once 'Zend/Form/Exception.php';
1837                throw new Zend_Form_Exception('Invalid alias provided to addDecorator; must be alphanumeric string');
1838            }
1839            if (is_string($spec)) {
1840                $decorator = array(
1841                    'decorator' => $spec,
1842                    'options'   => $options,
1843                );
1844            } elseif ($spec instanceof Zend_Form_Decorator_Interface) {
1845                $decorator = $spec;
1846            }
1847        } else {
1848            require_once 'Zend/Form/Exception.php';
1849            throw new Zend_Form_Exception('Invalid decorator provided to addDecorator; must be string or Zend_Form_Decorator_Interface');
1850        }
1851
1852        $this->_decorators[$name] = $decorator;
1853
1854        return $this;
1855    }
1856
1857    /**
1858     * Add many decorators at once
1859     *
1860     * @param  array $decorators
1861     * @return Zend_Form_Element
1862     */
1863    public function addDecorators(array $decorators)
1864    {
1865        foreach ($decorators as $deco…

Large files files are truncated, but you can click here to view the full file