PageRenderTime 78ms CodeModel.GetById 30ms app.highlight 37ms RepoModel.GetById 0ms app.codeStats 1ms

/Zend/Form/Element.php

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

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