[ZF-10089] Zend_Log
[zend/radio.git] / library / Zend / Form / Element.php
blob16487d3c956f9c897b590cad5f5545400165f2e6
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
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.
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
21 /** @see Zend_Filter */
22 require_once 'Zend/Filter.php';
24 /** @see Zend_Form */
25 require_once 'Zend/Form.php';
27 /** @see Zend_Validate_Interface */
28 require_once 'Zend/Validate/Interface.php';
30 /** @see Zend_Validate_Abstract */
31 require_once 'Zend/Validate/Abstract.php';
33 /**
34 * Zend_Form_Element
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$
43 class Zend_Form_Element implements Zend_Validate_Interface
45 /**
46 * Element Constants
48 const DECORATOR = 'DECORATOR';
49 const FILTER = 'FILTER';
50 const VALIDATE = 'VALIDATE';
52 /**
53 * Default view helper to use
54 * @var string
56 public $helper = 'formText';
58 /**
59 * 'Allow empty' flag
60 * @var bool
62 protected $_allowEmpty = true;
64 /**
65 * Flag indicating whether or not to insert NotEmpty validator when element is required
66 * @var bool
68 protected $_autoInsertNotEmptyValidator = true;
70 /**
71 * Array to which element belongs
72 * @var string
74 protected $_belongsTo;
76 /**
77 * Element decorators
78 * @var array
80 protected $_decorators = array();
82 /**
83 * Element description
84 * @var string
86 protected $_description;
88 /**
89 * Should we disable loading the default decorators?
90 * @var bool
92 protected $_disableLoadDefaultDecorators = false;
94 /**
95 * Custom error messages
96 * @var array
98 protected $_errorMessages = array();
101 * Validation errors
102 * @var array
104 protected $_errors = array();
107 * Separator to use when concatenating aggregate error messages (for
108 * elements having array values)
109 * @var string
111 protected $_errorMessageSeparator = '; ';
114 * Element filters
115 * @var array
117 protected $_filters = array();
120 * Ignore flag (used when retrieving values at form level)
121 * @var bool
123 protected $_ignore = false;
126 * Does the element represent an array?
127 * @var bool
129 protected $_isArray = false;
132 * Is the error marked as in an invalid state?
133 * @var bool
135 protected $_isError = false;
138 * Has the element been manually marked as invalid?
139 * @var bool
141 protected $_isErrorForced = false;
144 * Element label
145 * @var string
147 protected $_label;
150 * Plugin loaders for filter and validator chains
151 * @var array
153 protected $_loaders = array();
156 * Formatted validation error messages
157 * @var array
159 protected $_messages = array();
162 * Element name
163 * @var string
165 protected $_name;
168 * Order of element
169 * @var int
171 protected $_order;
174 * Required flag
175 * @var bool
177 protected $_required = false;
180 * @var Zend_Translate
182 protected $_translator;
185 * Is translation disabled?
186 * @var bool
188 protected $_translatorDisabled = false;
191 * Element type
192 * @var string
194 protected $_type;
197 * Array of initialized validators
198 * @var array Validators
200 protected $_validators = array();
203 * Array of un-initialized validators
204 * @var array
206 protected $_validatorRules = array();
209 * Element value
210 * @var mixed
212 protected $_value;
215 * @var Zend_View_Interface
217 protected $_view;
220 * Is a specific decorator being rendered via the magic renderDecorator()?
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.
225 * @var bool
227 protected $_isPartialRendering = false;
230 * Constructor
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
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
242 public function __construct($spec, $options = null)
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);
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);
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');
264 * Extensions
266 $this->init();
269 * Register ViewHelper decorator by default
271 $this->loadDefaultDecorators();
275 * Initialize object; used by extending classes
277 * @return void
279 public function init()
284 * Set flag to disable loading default decorators
286 * @param bool $flag
287 * @return Zend_Form_Element
289 public function setDisableLoadDefaultDecorators($flag)
291 $this->_disableLoadDefaultDecorators = (bool) $flag;
292 return $this;
296 * Should we load the default decorators?
298 * @return bool
300 public function loadDefaultDecoratorsIsDisabled()
302 return $this->_disableLoadDefaultDecorators;
306 * Load default decorators
308 * @return Zend_Form_Element
310 public function loadDefaultDecorators()
312 if ($this->loadDefaultDecoratorsIsDisabled()) {
313 return $this;
316 $decorators = $this->getDecorators();
317 if (empty($decorators)) {
318 $getId = create_function('$decorator',
319 'return $decorator->getElement()->getId()
320 . "-element";');
321 $this->addDecorator('ViewHelper')
322 ->addDecorator('Errors')
323 ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
324 ->addDecorator('HtmlTag', array('tag' => 'dd',
325 'id' => array('callback' => $getId)))
326 ->addDecorator('Label', array('tag' => 'dt'));
328 return $this;
332 * Set object state from options array
334 * @param array $options
335 * @return Zend_Form_Element
337 public function setOptions(array $options)
339 if (isset($options['prefixPath'])) {
340 $this->addPrefixPaths($options['prefixPath']);
341 unset($options['prefixPath']);
344 if (isset($options['disableTranslator'])) {
345 $this->setDisableTranslator($options['disableTranslator']);
346 unset($options['disableTranslator']);
349 unset($options['options']);
350 unset($options['config']);
352 foreach ($options as $key => $value) {
353 $method = 'set' . ucfirst($key);
355 if (in_array($method, array('setTranslator', 'setPluginLoader', 'setView'))) {
356 if (!is_object($value)) {
357 continue;
361 if (method_exists($this, $method)) {
362 // Setter exists; use it
363 $this->$method($value);
364 } else {
365 // Assume it's metadata
366 $this->setAttrib($key, $value);
369 return $this;
373 * Set object state from Zend_Config object
375 * @param Zend_Config $config
376 * @return Zend_Form_Element
378 public function setConfig(Zend_Config $config)
380 return $this->setOptions($config->toArray());
384 // Localization:
387 * Set translator object for localization
389 * @param Zend_Translate|null $translator
390 * @return Zend_Form_Element
392 public function setTranslator($translator = null)
394 if (null === $translator) {
395 $this->_translator = null;
396 } elseif ($translator instanceof Zend_Translate_Adapter) {
397 $this->_translator = $translator;
398 } elseif ($translator instanceof Zend_Translate) {
399 $this->_translator = $translator->getAdapter();
400 } else {
401 require_once 'Zend/Form/Exception.php';
402 throw new Zend_Form_Exception('Invalid translator specified');
404 return $this;
408 * Retrieve localization translator object
410 * @return Zend_Translate_Adapter|null
412 public function getTranslator()
414 if ($this->translatorIsDisabled()) {
415 return null;
418 if (null === $this->_translator) {
419 return Zend_Form::getDefaultTranslator();
421 return $this->_translator;
425 * Does this element have its own specific translator?
427 * @return bool
429 public function hasTranslator()
431 return (bool)$this->_translator;
435 * Indicate whether or not translation should be disabled
437 * @param bool $flag
438 * @return Zend_Form_Element
440 public function setDisableTranslator($flag)
442 $this->_translatorDisabled = (bool) $flag;
443 return $this;
447 * Is translation disabled?
449 * @return bool
451 public function translatorIsDisabled()
453 return $this->_translatorDisabled;
456 // Metadata
459 * Filter a name to only allow valid variable characters
461 * @param string $value
462 * @param bool $allowBrackets
463 * @return string
465 public function filterName($value, $allowBrackets = false)
467 $charset = '^a-zA-Z0-9_\x7f-\xff';
468 if ($allowBrackets) {
469 $charset .= '\[\]';
471 return preg_replace('/[' . $charset . ']/', '', (string) $value);
475 * Set element name
477 * @param string $name
478 * @return Zend_Form_Element
480 public function setName($name)
482 $name = $this->filterName($name);
483 if ('' === $name) {
484 require_once 'Zend/Form/Exception.php';
485 throw new Zend_Form_Exception('Invalid name provided; must contain only valid variable characters and be non-empty');
488 $this->_name = $name;
489 return $this;
493 * Return element name
495 * @return string
497 public function getName()
499 return $this->_name;
503 * Get fully qualified name
505 * Places name as subitem of array and/or appends brackets.
507 * @return string
509 public function getFullyQualifiedName()
511 $name = $this->getName();
513 if (null !== ($belongsTo = $this->getBelongsTo())) {
514 $name = $belongsTo . '[' . $name . ']';
517 if ($this->isArray()) {
518 $name .= '[]';
521 return $name;
525 * Get element id
527 * @return string
529 public function getId()
531 if (isset($this->id)) {
532 return $this->id;
535 $id = $this->getFullyQualifiedName();
537 // Bail early if no array notation detected
538 if (!strstr($id, '[')) {
539 return $id;
542 // Strip array notation
543 if ('[]' == substr($id, -2)) {
544 $id = substr($id, 0, strlen($id) - 2);
546 $id = str_replace('][', '-', $id);
547 $id = str_replace(array(']', '['), '-', $id);
548 $id = trim($id, '-');
550 return $id;
554 * Set element value
556 * @param mixed $value
557 * @return Zend_Form_Element
559 public function setValue($value)
561 $this->_value = $value;
562 return $this;
566 * Filter a value
568 * @param string $value
569 * @param string $key
570 * @return void
572 protected function _filterValue(&$value, &$key)
574 foreach ($this->getFilters() as $filter) {
575 $value = $filter->filter($value);
580 * Retrieve filtered element value
582 * @return mixed
584 public function getValue()
586 $valueFiltered = $this->_value;
588 if ($this->isArray() && is_array($valueFiltered)) {
589 array_walk_recursive($valueFiltered, array($this, '_filterValue'));
590 } else {
591 $this->_filterValue($valueFiltered, $valueFiltered);
594 return $valueFiltered;
598 * Retrieve unfiltered element value
600 * @return mixed
602 public function getUnfilteredValue()
604 return $this->_value;
608 * Set element label
610 * @param string $label
611 * @return Zend_Form_Element
613 public function setLabel($label)
615 $this->_label = (string) $label;
616 return $this;
620 * Retrieve element label
622 * @return string
624 public function getLabel()
626 $translator = $this->getTranslator();
627 if (null !== $translator) {
628 return $translator->translate($this->_label);
631 return $this->_label;
635 * Set element order
637 * @param int $order
638 * @return Zend_Form_Element
640 public function setOrder($order)
642 $this->_order = (int) $order;
643 return $this;
647 * Retrieve element order
649 * @return int
651 public function getOrder()
653 return $this->_order;
657 * Set required flag
659 * @param bool $flag Default value is true
660 * @return Zend_Form_Element
662 public function setRequired($flag = true)
664 $this->_required = (bool) $flag;
665 return $this;
669 * Is the element required?
671 * @return bool
673 public function isRequired()
675 return $this->_required;
679 * Set flag indicating whether a NotEmpty validator should be inserted when element is required
681 * @param bool $flag
682 * @return Zend_Form_Element
684 public function setAutoInsertNotEmptyValidator($flag)
686 $this->_autoInsertNotEmptyValidator = (bool) $flag;
687 return $this;
691 * Get flag indicating whether a NotEmpty validator should be inserted when element is required
693 * @return bool
695 public function autoInsertNotEmptyValidator()
697 return $this->_autoInsertNotEmptyValidator;
701 * Set element description
703 * @param string $description
704 * @return Zend_Form_Element
706 public function setDescription($description)
708 $this->_description = (string) $description;
709 return $this;
713 * Retrieve element description
715 * @return string
717 public function getDescription()
719 return $this->_description;
723 * Set 'allow empty' flag
725 * When the allow empty flag is enabled and the required flag is false, the
726 * element will validate with empty values.
728 * @param bool $flag
729 * @return Zend_Form_Element
731 public function setAllowEmpty($flag)
733 $this->_allowEmpty = (bool) $flag;
734 return $this;
738 * Get 'allow empty' flag
740 * @return bool
742 public function getAllowEmpty()
744 return $this->_allowEmpty;
748 * Set ignore flag (used when retrieving values at form level)
750 * @param bool $flag
751 * @return Zend_Form_Element
753 public function setIgnore($flag)
755 $this->_ignore = (bool) $flag;
756 return $this;
760 * Get ignore flag (used when retrieving values at form level)
762 * @return bool
764 public function getIgnore()
766 return $this->_ignore;
770 * Set flag indicating if element represents an array
772 * @param bool $flag
773 * @return Zend_Form_Element
775 public function setIsArray($flag)
777 $this->_isArray = (bool) $flag;
778 return $this;
782 * Is the element representing an array?
784 * @return bool
786 public function isArray()
788 return $this->_isArray;
792 * Set array to which element belongs
794 * @param string $array
795 * @return Zend_Form_Element
797 public function setBelongsTo($array)
799 $array = $this->filterName($array, true);
800 if (!empty($array)) {
801 $this->_belongsTo = $array;
804 return $this;
808 * Return array name to which element belongs
810 * @return string
812 public function getBelongsTo()
814 return $this->_belongsTo;
818 * Return element type
820 * @return string
822 public function getType()
824 if (null === $this->_type) {
825 $this->_type = get_class($this);
828 return $this->_type;
832 * Set element attribute
834 * @param string $name
835 * @param mixed $value
836 * @return Zend_Form_Element
837 * @throws Zend_Form_Exception for invalid $name values
839 public function setAttrib($name, $value)
841 $name = (string) $name;
842 if ('_' == $name[0]) {
843 require_once 'Zend/Form/Exception.php';
844 throw new Zend_Form_Exception(sprintf('Invalid attribute "%s"; must not contain a leading underscore', $name));
847 if (null === $value) {
848 unset($this->$name);
849 } else {
850 $this->$name = $value;
853 return $this;
857 * Set multiple attributes at once
859 * @param array $attribs
860 * @return Zend_Form_Element
862 public function setAttribs(array $attribs)
864 foreach ($attribs as $key => $value) {
865 $this->setAttrib($key, $value);
868 return $this;
872 * Retrieve element attribute
874 * @param string $name
875 * @return string
877 public function getAttrib($name)
879 $name = (string) $name;
880 if (isset($this->$name)) {
881 return $this->$name;
884 return null;
888 * Return all attributes
890 * @return array
892 public function getAttribs()
894 $attribs = get_object_vars($this);
895 foreach ($attribs as $key => $value) {
896 if ('_' == substr($key, 0, 1)) {
897 unset($attribs[$key]);
901 return $attribs;
905 * Overloading: retrieve object property
907 * Prevents access to properties beginning with '_'.
909 * @param string $key
910 * @return mixed
912 public function __get($key)
914 if ('_' == $key[0]) {
915 require_once 'Zend/Form/Exception.php';
916 throw new Zend_Form_Exception(sprintf('Cannot retrieve value for protected/private property "%s"', $key));
919 if (!isset($this->$key)) {
920 return null;
923 return $this->$key;
927 * Overloading: set object property
929 * @param string $key
930 * @param mixed $value
931 * @return voide
933 public function __set($key, $value)
935 $this->setAttrib($key, $value);
939 * Overloading: allow rendering specific decorators
941 * Call renderDecoratorName() to render a specific decorator.
943 * @param string $method
944 * @param array $args
945 * @return string
946 * @throws Zend_Form_Exception for invalid decorator or invalid method call
948 public function __call($method, $args)
950 if ('render' == substr($method, 0, 6)) {
951 $this->_isPartialRendering = true;
952 $this->render();
953 $this->_isPartialRendering = false;
954 $decoratorName = substr($method, 6);
955 if (false !== ($decorator = $this->getDecorator($decoratorName))) {
956 $decorator->setElement($this);
957 $seed = '';
958 if (0 < count($args)) {
959 $seed = array_shift($args);
961 return $decorator->render($seed);
964 require_once 'Zend/Form/Element/Exception.php';
965 throw new Zend_Form_Element_Exception(sprintf('Decorator by name %s does not exist', $decoratorName));
968 require_once 'Zend/Form/Element/Exception.php';
969 throw new Zend_Form_Element_Exception(sprintf('Method %s does not exist', $method));
972 // Loaders
975 * Set plugin loader to use for validator or filter chain
977 * @param Zend_Loader_PluginLoader_Interface $loader
978 * @param string $type 'decorator', 'filter', or 'validate'
979 * @return Zend_Form_Element
980 * @throws Zend_Form_Exception on invalid type
982 public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type)
984 $type = strtoupper($type);
985 switch ($type) {
986 case self::DECORATOR:
987 case self::FILTER:
988 case self::VALIDATE:
989 $this->_loaders[$type] = $loader;
990 return $this;
991 default:
992 require_once 'Zend/Form/Exception.php';
993 throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to setPluginLoader()', $type));
998 * Retrieve plugin loader for validator or filter chain
1000 * Instantiates with default rules if none available for that type. Use
1001 * 'decorator', 'filter', or 'validate' for $type.
1003 * @param string $type
1004 * @return Zend_Loader_PluginLoader
1005 * @throws Zend_Loader_Exception on invalid type.
1007 public function getPluginLoader($type)
1009 $type = strtoupper($type);
1010 switch ($type) {
1011 case self::FILTER:
1012 case self::VALIDATE:
1013 $prefixSegment = ucfirst(strtolower($type));
1014 $pathSegment = $prefixSegment;
1015 case self::DECORATOR:
1016 if (!isset($prefixSegment)) {
1017 $prefixSegment = 'Form_Decorator';
1018 $pathSegment = 'Form/Decorator';
1020 if (!isset($this->_loaders[$type])) {
1021 require_once 'Zend/Loader/PluginLoader.php';
1022 $this->_loaders[$type] = new Zend_Loader_PluginLoader(
1023 array('Zend_' . $prefixSegment . '_' => 'Zend/' . $pathSegment . '/')
1026 return $this->_loaders[$type];
1027 default:
1028 require_once 'Zend/Form/Exception.php';
1029 throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
1034 * Add prefix path for plugin loader
1036 * If no $type specified, assumes it is a base path for both filters and
1037 * validators, and sets each according to the following rules:
1038 * - decorators: $prefix = $prefix . '_Decorator'
1039 * - filters: $prefix = $prefix . '_Filter'
1040 * - validators: $prefix = $prefix . '_Validate'
1042 * Otherwise, the path prefix is set on the appropriate plugin loader.
1044 * @param string $prefix
1045 * @param string $path
1046 * @param string $type
1047 * @return Zend_Form_Element
1048 * @throws Zend_Form_Exception for invalid type
1050 public function addPrefixPath($prefix, $path, $type = null)
1052 $type = strtoupper($type);
1053 switch ($type) {
1054 case self::DECORATOR:
1055 case self::FILTER:
1056 case self::VALIDATE:
1057 $loader = $this->getPluginLoader($type);
1058 $loader->addPrefixPath($prefix, $path);
1059 return $this;
1060 case null:
1061 $prefix = rtrim($prefix, '_');
1062 $path = rtrim($path, DIRECTORY_SEPARATOR);
1063 foreach (array(self::DECORATOR, self::FILTER, self::VALIDATE) as $type) {
1064 $cType = ucfirst(strtolower($type));
1065 $pluginPath = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
1066 $pluginPrefix = $prefix . '_' . $cType;
1067 $loader = $this->getPluginLoader($type);
1068 $loader->addPrefixPath($pluginPrefix, $pluginPath);
1070 return $this;
1071 default:
1072 require_once 'Zend/Form/Exception.php';
1073 throw new Zend_Form_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
1078 * Add many prefix paths at once
1080 * @param array $spec
1081 * @return Zend_Form_Element
1083 public function addPrefixPaths(array $spec)
1085 if (isset($spec['prefix']) && isset($spec['path'])) {
1086 return $this->addPrefixPath($spec['prefix'], $spec['path']);
1088 foreach ($spec as $type => $paths) {
1089 if (is_numeric($type) && is_array($paths)) {
1090 $type = null;
1091 if (isset($paths['prefix']) && isset($paths['path'])) {
1092 if (isset($paths['type'])) {
1093 $type = $paths['type'];
1095 $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
1097 } elseif (!is_numeric($type)) {
1098 if (!isset($paths['prefix']) || !isset($paths['path'])) {
1099 foreach ($paths as $prefix => $spec) {
1100 if (is_array($spec)) {
1101 foreach ($spec as $path) {
1102 if (!is_string($path)) {
1103 continue;
1105 $this->addPrefixPath($prefix, $path, $type);
1107 } elseif (is_string($spec)) {
1108 $this->addPrefixPath($prefix, $spec, $type);
1111 } else {
1112 $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
1116 return $this;
1119 // Validation
1122 * Add validator to validation chain
1124 * Note: will overwrite existing validators if they are of the same class.
1126 * @param string|Zend_Validate_Interface $validator
1127 * @param bool $breakChainOnFailure
1128 * @param array $options
1129 * @return Zend_Form_Element
1130 * @throws Zend_Form_Exception if invalid validator type
1132 public function addValidator($validator, $breakChainOnFailure = false, $options = array())
1134 if ($validator instanceof Zend_Validate_Interface) {
1135 $name = get_class($validator);
1137 if (!isset($validator->zfBreakChainOnFailure)) {
1138 $validator->zfBreakChainOnFailure = $breakChainOnFailure;
1140 } elseif (is_string($validator)) {
1141 $name = $validator;
1142 $validator = array(
1143 'validator' => $validator,
1144 'breakChainOnFailure' => $breakChainOnFailure,
1145 'options' => $options,
1147 } else {
1148 require_once 'Zend/Form/Exception.php';
1149 throw new Zend_Form_Exception('Invalid validator provided to addValidator; must be string or Zend_Validate_Interface');
1153 $this->_validators[$name] = $validator;
1155 return $this;
1159 * Add multiple validators
1161 * @param array $validators
1162 * @return Zend_Form_Element
1164 public function addValidators(array $validators)
1166 foreach ($validators as $validatorInfo) {
1167 if (is_string($validatorInfo)) {
1168 $this->addValidator($validatorInfo);
1169 } elseif ($validatorInfo instanceof Zend_Validate_Interface) {
1170 $this->addValidator($validatorInfo);
1171 } elseif (is_array($validatorInfo)) {
1172 $argc = count($validatorInfo);
1173 $breakChainOnFailure = false;
1174 $options = array();
1175 if (isset($validatorInfo['validator'])) {
1176 $validator = $validatorInfo['validator'];
1177 if (isset($validatorInfo['breakChainOnFailure'])) {
1178 $breakChainOnFailure = $validatorInfo['breakChainOnFailure'];
1180 if (isset($validatorInfo['options'])) {
1181 $options = $validatorInfo['options'];
1183 $this->addValidator($validator, $breakChainOnFailure, $options);
1184 } else {
1185 switch (true) {
1186 case (0 == $argc):
1187 break;
1188 case (1 <= $argc):
1189 $validator = array_shift($validatorInfo);
1190 case (2 <= $argc):
1191 $breakChainOnFailure = array_shift($validatorInfo);
1192 case (3 <= $argc):
1193 $options = array_shift($validatorInfo);
1194 default:
1195 $this->addValidator($validator, $breakChainOnFailure, $options);
1196 break;
1199 } else {
1200 require_once 'Zend/Form/Exception.php';
1201 throw new Zend_Form_Exception('Invalid validator passed to addValidators()');
1205 return $this;
1209 * Set multiple validators, overwriting previous validators
1211 * @param array $validators
1212 * @return Zend_Form_Element
1214 public function setValidators(array $validators)
1216 $this->clearValidators();
1217 return $this->addValidators($validators);
1221 * Retrieve a single validator by name
1223 * @param string $name
1224 * @return Zend_Validate_Interface|false False if not found, validator otherwise
1226 public function getValidator($name)
1228 if (!isset($this->_validators[$name])) {
1229 $len = strlen($name);
1230 foreach ($this->_validators as $localName => $validator) {
1231 if ($len > strlen($localName)) {
1232 continue;
1234 if (0 === substr_compare($localName, $name, -$len, $len, true)) {
1235 if (is_array($validator)) {
1236 return $this->_loadValidator($validator);
1238 return $validator;
1241 return false;
1244 if (is_array($this->_validators[$name])) {
1245 return $this->_loadValidator($this->_validators[$name]);
1248 return $this->_validators[$name];
1252 * Retrieve all validators
1254 * @return array
1256 public function getValidators()
1258 $validators = array();
1259 foreach ($this->_validators as $key => $value) {
1260 if ($value instanceof Zend_Validate_Interface) {
1261 $validators[$key] = $value;
1262 continue;
1264 $validator = $this->_loadValidator($value);
1265 $validators[get_class($validator)] = $validator;
1267 return $validators;
1271 * Remove a single validator by name
1273 * @param string $name
1274 * @return bool
1276 public function removeValidator($name)
1278 if (isset($this->_validators[$name])) {
1279 unset($this->_validators[$name]);
1280 } else {
1281 $len = strlen($name);
1282 foreach (array_keys($this->_validators) as $validator) {
1283 if ($len > strlen($validator)) {
1284 continue;
1286 if (0 === substr_compare($validator, $name, -$len, $len, true)) {
1287 unset($this->_validators[$validator]);
1288 break;
1293 return $this;
1297 * Clear all validators
1299 * @return Zend_Form_Element
1301 public function clearValidators()
1303 $this->_validators = array();
1304 return $this;
1308 * Validate element value
1310 * If a translation adapter is registered, any error messages will be
1311 * translated according to the current locale, using the given error code;
1312 * if no matching translation is found, the original message will be
1313 * utilized.
1315 * Note: The *filtered* value is validated.
1317 * @param mixed $value
1318 * @param mixed $context
1319 * @return boolean
1321 public function isValid($value, $context = null)
1323 $this->setValue($value);
1324 $value = $this->getValue();
1326 if ((('' === $value) || (null === $value))
1327 && !$this->isRequired()
1328 && $this->getAllowEmpty()
1330 return true;
1333 if ($this->isRequired()
1334 && $this->autoInsertNotEmptyValidator()
1335 && !$this->getValidator('NotEmpty'))
1337 $validators = $this->getValidators();
1338 $notEmpty = array('validator' => 'NotEmpty', 'breakChainOnFailure' => true);
1339 array_unshift($validators, $notEmpty);
1340 $this->setValidators($validators);
1343 // Find the correct translator. Zend_Validate_Abstract::getDefaultTranslator()
1344 // will get either the static translator attached to Zend_Validate_Abstract
1345 // or the 'Zend_Translate' from Zend_Registry.
1346 if (Zend_Validate_Abstract::hasDefaultTranslator() &&
1347 !Zend_Form::hasDefaultTranslator())
1349 $translator = Zend_Validate_Abstract::getDefaultTranslator();
1350 if ($this->hasTranslator()) {
1351 // only pick up this element's translator if it was attached directly.
1352 $translator = $this->getTranslator();
1354 } else {
1355 $translator = $this->getTranslator();
1358 $this->_messages = array();
1359 $this->_errors = array();
1360 $result = true;
1361 $isArray = $this->isArray();
1362 foreach ($this->getValidators() as $key => $validator) {
1363 if (method_exists($validator, 'setTranslator')) {
1364 if (method_exists($validator, 'hasTranslator')) {
1365 if (!$validator->hasTranslator()) {
1366 $validator->setTranslator($translator);
1368 } else {
1369 $validator->setTranslator($translator);
1373 if (method_exists($validator, 'setDisableTranslator')) {
1374 $validator->setDisableTranslator($this->translatorIsDisabled());
1377 if ($isArray && is_array($value)) {
1378 $messages = array();
1379 $errors = array();
1380 foreach ($value as $val) {
1381 if (!$validator->isValid($val, $context)) {
1382 $result = false;
1383 if ($this->_hasErrorMessages()) {
1384 $messages = $this->_getErrorMessages();
1385 $errors = $messages;
1386 } else {
1387 $messages = array_merge($messages, $validator->getMessages());
1388 $errors = array_merge($errors, $validator->getErrors());
1392 if ($result) {
1393 continue;
1395 } elseif ($validator->isValid($value, $context)) {
1396 continue;
1397 } else {
1398 $result = false;
1399 if ($this->_hasErrorMessages()) {
1400 $messages = $this->_getErrorMessages();
1401 $errors = $messages;
1402 } else {
1403 $messages = $validator->getMessages();
1404 $errors = array_keys($messages);
1408 $result = false;
1409 $this->_messages = array_merge($this->_messages, $messages);
1410 $this->_errors = array_merge($this->_errors, $errors);
1412 if ($validator->zfBreakChainOnFailure) {
1413 break;
1417 // If element manually flagged as invalid, return false
1418 if ($this->_isErrorForced) {
1419 return false;
1422 return $result;
1426 * Add a custom error message to return in the event of failed validation
1428 * @param string $message
1429 * @return Zend_Form_Element
1431 public function addErrorMessage($message)
1433 $this->_errorMessages[] = (string) $message;
1434 return $this;
1438 * Add multiple custom error messages to return in the event of failed validation
1440 * @param array $messages
1441 * @return Zend_Form_Element
1443 public function addErrorMessages(array $messages)
1445 foreach ($messages as $message) {
1446 $this->addErrorMessage($message);
1448 return $this;
1452 * Same as addErrorMessages(), but clears custom error message stack first
1454 * @param array $messages
1455 * @return Zend_Form_Element
1457 public function setErrorMessages(array $messages)
1459 $this->clearErrorMessages();
1460 return $this->addErrorMessages($messages);
1464 * Retrieve custom error messages
1466 * @return array
1468 public function getErrorMessages()
1470 return $this->_errorMessages;
1474 * Clear custom error messages stack
1476 * @return Zend_Form_Element
1478 public function clearErrorMessages()
1480 $this->_errorMessages = array();
1481 return $this;
1485 * Get errorMessageSeparator
1487 * @return string
1489 public function getErrorMessageSeparator()
1491 return $this->_errorMessageSeparator;
1495 * Set errorMessageSeparator
1497 * @param string $separator
1498 * @return Zend_Form_Element
1500 public function setErrorMessageSeparator($separator)
1502 $this->_errorMessageSeparator = $separator;
1503 return $this;
1507 * Mark the element as being in a failed validation state
1509 * @return Zend_Form_Element
1511 public function markAsError()
1513 $messages = $this->getMessages();
1514 $customMessages = $this->_getErrorMessages();
1515 $messages = $messages + $customMessages;
1516 if (empty($messages)) {
1517 $this->_isError = true;
1518 } else {
1519 $this->_messages = $messages;
1521 $this->_isErrorForced = true;
1522 return $this;
1526 * Add an error message and mark element as failed validation
1528 * @param string $message
1529 * @return Zend_Form_Element
1531 public function addError($message)
1533 $this->addErrorMessage($message);
1534 $this->markAsError();
1535 return $this;
1539 * Add multiple error messages and flag element as failed validation
1541 * @param array $messages
1542 * @return Zend_Form_Element
1544 public function addErrors(array $messages)
1546 foreach ($messages as $message) {
1547 $this->addError($message);
1549 return $this;
1553 * Overwrite any previously set error messages and flag as failed validation
1555 * @param array $messages
1556 * @return Zend_Form_Element
1558 public function setErrors(array $messages)
1560 $this->clearErrorMessages();
1561 return $this->addErrors($messages);
1565 * Are there errors registered?
1567 * @return bool
1569 public function hasErrors()
1571 return (!empty($this->_messages) || $this->_isError);
1575 * Retrieve validator chain errors
1577 * @return array
1579 public function getErrors()
1581 return $this->_errors;
1585 * Retrieve error messages
1587 * @return array
1589 public function getMessages()
1591 return $this->_messages;
1595 // Filtering
1598 * Add a filter to the element
1600 * @param string|Zend_Filter_Interface $filter
1601 * @return Zend_Form_Element
1603 public function addFilter($filter, $options = array())
1605 if ($filter instanceof Zend_Filter_Interface) {
1606 $name = get_class($filter);
1607 } elseif (is_string($filter)) {
1608 $name = $filter;
1609 $filter = array(
1610 'filter' => $filter,
1611 'options' => $options,
1613 $this->_filters[$name] = $filter;
1614 } else {
1615 require_once 'Zend/Form/Exception.php';
1616 throw new Zend_Form_Exception('Invalid filter provided to addFilter; must be string or Zend_Filter_Interface');
1619 $this->_filters[$name] = $filter;
1621 return $this;
1625 * Add filters to element
1627 * @param array $filters
1628 * @return Zend_Form_Element
1630 public function addFilters(array $filters)
1632 foreach ($filters as $filterInfo) {
1633 if (is_string($filterInfo)) {
1634 $this->addFilter($filterInfo);
1635 } elseif ($filterInfo instanceof Zend_Filter_Interface) {
1636 $this->addFilter($filterInfo);
1637 } elseif (is_array($filterInfo)) {
1638 $argc = count($filterInfo);
1639 $options = array();
1640 if (isset($filterInfo['filter'])) {
1641 $filter = $filterInfo['filter'];
1642 if (isset($filterInfo['options'])) {
1643 $options = $filterInfo['options'];
1645 $this->addFilter($filter, $options);
1646 } else {
1647 switch (true) {
1648 case (0 == $argc):
1649 break;
1650 case (1 <= $argc):
1651 $filter = array_shift($filterInfo);
1652 case (2 <= $argc):
1653 $options = array_shift($filterInfo);
1654 default:
1655 $this->addFilter($filter, $options);
1656 break;
1659 } else {
1660 require_once 'Zend/Form/Exception.php';
1661 throw new Zend_Form_Exception('Invalid filter passed to addFilters()');
1665 return $this;
1669 * Add filters to element, overwriting any already existing
1671 * @param array $filters
1672 * @return Zend_Form_Element
1674 public function setFilters(array $filters)
1676 $this->clearFilters();
1677 return $this->addFilters($filters);
1681 * Retrieve a single filter by name
1683 * @param string $name
1684 * @return Zend_Filter_Interface
1686 public function getFilter($name)
1688 if (!isset($this->_filters[$name])) {
1689 $len = strlen($name);
1690 foreach ($this->_filters as $localName => $filter) {
1691 if ($len > strlen($localName)) {
1692 continue;
1695 if (0 === substr_compare($localName, $name, -$len, $len, true)) {
1696 if (is_array($filter)) {
1697 return $this->_loadFilter($filter);
1699 return $filter;
1702 return false;
1705 if (is_array($this->_filters[$name])) {
1706 return $this->_loadFilter($this->_filters[$name]);
1709 return $this->_filters[$name];
1713 * Get all filters
1715 * @return array
1717 public function getFilters()
1719 $filters = array();
1720 foreach ($this->_filters as $key => $value) {
1721 if ($value instanceof Zend_Filter_Interface) {
1722 $filters[$key] = $value;
1723 continue;
1725 $filter = $this->_loadFilter($value);
1726 $filters[get_class($filter)] = $filter;
1728 return $filters;
1732 * Remove a filter by name
1734 * @param string $name
1735 * @return Zend_Form_Element
1737 public function removeFilter($name)
1739 if (isset($this->_filters[$name])) {
1740 unset($this->_filters[$name]);
1741 } else {
1742 $len = strlen($name);
1743 foreach (array_keys($this->_filters) as $filter) {
1744 if ($len > strlen($filter)) {
1745 continue;
1747 if (0 === substr_compare($filter, $name, -$len, $len, true)) {
1748 unset($this->_filters[$filter]);
1749 break;
1754 return $this;
1758 * Clear all filters
1760 * @return Zend_Form_Element
1762 public function clearFilters()
1764 $this->_filters = array();
1765 return $this;
1768 // Rendering
1771 * Set view object
1773 * @param Zend_View_Interface $view
1774 * @return Zend_Form_Element
1776 public function setView(Zend_View_Interface $view = null)
1778 $this->_view = $view;
1779 return $this;
1783 * Retrieve view object
1785 * Retrieves from ViewRenderer if none previously set.
1787 * @return null|Zend_View_Interface
1789 public function getView()
1791 if (null === $this->_view) {
1792 require_once 'Zend/Controller/Action/HelperBroker.php';
1793 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
1794 $this->setView($viewRenderer->view);
1796 return $this->_view;
1800 * Instantiate a decorator based on class name or class name fragment
1802 * @param string $name
1803 * @param null|array $options
1804 * @return Zend_Form_Decorator_Interface
1806 protected function _getDecorator($name, $options)
1808 $class = $this->getPluginLoader(self::DECORATOR)->load($name);
1809 if (null === $options) {
1810 $decorator = new $class;
1811 } else {
1812 $decorator = new $class($options);
1815 return $decorator;
1819 * Add a decorator for rendering the element
1821 * @param string|Zend_Form_Decorator_Interface $decorator
1822 * @param array|Zend_Config $options Options with which to initialize decorator
1823 * @return Zend_Form_Element
1825 public function addDecorator($decorator, $options = null)
1827 if ($decorator instanceof Zend_Form_Decorator_Interface) {
1828 $name = get_class($decorator);
1829 } elseif (is_string($decorator)) {
1830 $name = $decorator;
1831 $decorator = array(
1832 'decorator' => $name,
1833 'options' => $options,
1835 } elseif (is_array($decorator)) {
1836 foreach ($decorator as $name => $spec) {
1837 break;
1839 if (is_numeric($name)) {
1840 require_once 'Zend/Form/Exception.php';
1841 throw new Zend_Form_Exception('Invalid alias provided to addDecorator; must be alphanumeric string');
1843 if (is_string($spec)) {
1844 $decorator = array(
1845 'decorator' => $spec,
1846 'options' => $options,
1848 } elseif ($spec instanceof Zend_Form_Decorator_Interface) {
1849 $decorator = $spec;
1851 } else {
1852 require_once 'Zend/Form/Exception.php';
1853 throw new Zend_Form_Exception('Invalid decorator provided to addDecorator; must be string or Zend_Form_Decorator_Interface');
1856 $this->_decorators[$name] = $decorator;
1858 return $this;
1862 * Add many decorators at once
1864 * @param array $decorators
1865 * @return Zend_Form_Element
1867 public function addDecorators(array $decorators)
1869 foreach ($decorators as $decoratorName => $decoratorInfo) {
1870 if (is_string($decoratorInfo) ||
1871 $decoratorInfo instanceof Zend_Form_Decorator_Interface) {
1872 if (!is_numeric($decoratorName)) {
1873 $this->addDecorator(array($decoratorName => $decoratorInfo));
1874 } else {
1875 $this->addDecorator($decoratorInfo);
1877 } elseif (is_array($decoratorInfo)) {
1878 $argc = count($decoratorInfo);
1879 $options = array();
1880 if (isset($decoratorInfo['decorator'])) {
1881 $decorator = $decoratorInfo['decorator'];
1882 if (isset($decoratorInfo['options'])) {
1883 $options = $decoratorInfo['options'];
1885 $this->addDecorator($decorator, $options);
1886 } else {
1887 switch (true) {
1888 case (0 == $argc):
1889 break;
1890 case (1 <= $argc):
1891 $decorator = array_shift($decoratorInfo);
1892 case (2 <= $argc):
1893 $options = array_shift($decoratorInfo);
1894 default:
1895 $this->addDecorator($decorator, $options);
1896 break;
1899 } else {
1900 require_once 'Zend/Form/Exception.php';
1901 throw new Zend_Form_Exception('Invalid decorator passed to addDecorators()');
1905 return $this;
1909 * Overwrite all decorators
1911 * @param array $decorators
1912 * @return Zend_Form_Element
1914 public function setDecorators(array $decorators)
1916 $this->clearDecorators();
1917 return $this->addDecorators($decorators);
1921 * Retrieve a registered decorator
1923 * @param string $name
1924 * @return false|Zend_Form_Decorator_Abstract
1926 public function getDecorator($name)
1928 if (!isset($this->_decorators[$name])) {
1929 $len = strlen($name);
1930 foreach ($this->_decorators as $localName => $decorator) {
1931 if ($len > strlen($localName)) {
1932 continue;
1935 if (0 === substr_compare($localName, $name, -$len, $len, true)) {
1936 if (is_array($decorator)) {
1937 return $this->_loadDecorator($decorator, $localName);
1939 return $decorator;
1942 return false;
1945 if (is_array($this->_decorators[$name])) {
1946 return $this->_loadDecorator($this->_decorators[$name], $name);
1949 return $this->_decorators[$name];
1953 * Retrieve all decorators
1955 * @return array
1957 public function getDecorators()
1959 foreach ($this->_decorators as $key => $value) {
1960 if (is_array($value)) {
1961 $this->_loadDecorator($value, $key);
1964 return $this->_decorators;
1968 * Remove a single decorator
1970 * @param string $name
1971 * @return Zend_Form_Element
1973 public function removeDecorator($name)
1975 if (isset($this->_decorators[$name])) {
1976 unset($this->_decorators[$name]);
1977 } else {
1978 $len = strlen($name);
1979 foreach (array_keys($this->_decorators) as $decorator) {
1980 if ($len > strlen($decorator)) {
1981 continue;
1983 if (0 === substr_compare($decorator, $name, -$len, $len, true)) {
1984 unset($this->_decorators[$decorator]);
1985 break;
1990 return $this;
1994 * Clear all decorators
1996 * @return Zend_Form_Element
1998 public function clearDecorators()
2000 $this->_decorators = array();
2001 return $this;
2005 * Render form element
2007 * @param Zend_View_Interface $view
2008 * @return string
2010 public function render(Zend_View_Interface $view = null)
2012 if ($this->_isPartialRendering) {
2013 return '';
2016 if (null !== $view) {
2017 $this->setView($view);
2020 $content = '';
2021 foreach ($this->getDecorators() as $decorator) {
2022 $decorator->setElement($this);
2023 $content = $decorator->render($content);
2025 return $content;
2029 * String representation of form element
2031 * Proxies to {@link render()}.
2033 * @return string
2035 public function __toString()
2037 try {
2038 $return = $this->render();
2039 return $return;
2040 } catch (Exception $e) {
2041 trigger_error($e->getMessage(), E_USER_WARNING);
2042 return '';
2047 * Lazy-load a filter
2049 * @param array $filter
2050 * @return Zend_Filter_Interface
2052 protected function _loadFilter(array $filter)
2054 $origName = $filter['filter'];
2055 $name = $this->getPluginLoader(self::FILTER)->load($filter['filter']);
2057 if (array_key_exists($name, $this->_filters)) {
2058 require_once 'Zend/Form/Exception.php';
2059 throw new Zend_Form_Exception(sprintf('Filter instance already exists for filter "%s"', $origName));
2062 if (empty($filter['options'])) {
2063 $instance = new $name;
2064 } else {
2065 $r = new ReflectionClass($name);
2066 if ($r->hasMethod('__construct')) {
2067 $instance = $r->newInstanceArgs((array) $filter['options']);
2068 } else {
2069 $instance = $r->newInstance();
2073 if ($origName != $name) {
2074 $filterNames = array_keys($this->_filters);
2075 $order = array_flip($filterNames);
2076 $order[$name] = $order[$origName];
2077 $filtersExchange = array();
2078 unset($order[$origName]);
2079 asort($order);
2080 foreach ($order as $key => $index) {
2081 if ($key == $name) {
2082 $filtersExchange[$key] = $instance;
2083 continue;
2085 $filtersExchange[$key] = $this->_filters[$key];
2087 $this->_filters = $filtersExchange;
2088 } else {
2089 $this->_filters[$name] = $instance;
2092 return $instance;
2096 * Lazy-load a validator
2098 * @param array $validator Validator definition
2099 * @return Zend_Validate_Interface
2101 protected function _loadValidator(array $validator)
2103 $origName = $validator['validator'];
2104 $name = $this->getPluginLoader(self::VALIDATE)->load($validator['validator']);
2106 if (array_key_exists($name, $this->_validators)) {
2107 require_once 'Zend/Form/Exception.php';
2108 throw new Zend_Form_Exception(sprintf('Validator instance already exists for validator "%s"', $origName));
2111 $messages = false;
2112 if (isset($validator['options']) && array_key_exists('messages', (array)$validator['options'])) {
2113 $messages = $validator['options']['messages'];
2114 unset($validator['options']['messages']);
2117 if (empty($validator['options'])) {
2118 $instance = new $name;
2119 } else {
2120 $r = new ReflectionClass($name);
2121 if ($r->hasMethod('__construct')) {
2122 $numeric = false;
2123 if (is_array($validator['options'])) {
2124 $keys = array_keys($validator['options']);
2125 foreach($keys as $key) {
2126 if (is_numeric($key)) {
2127 $numeric = true;
2128 break;
2133 if ($numeric) {
2134 $instance = $r->newInstanceArgs((array) $validator['options']);
2135 } else {
2136 $instance = $r->newInstance($validator['options']);
2138 } else {
2139 $instance = $r->newInstance();
2143 if ($messages) {
2144 if (is_array($messages)) {
2145 $instance->setMessages($messages);
2146 } elseif (is_string($messages)) {
2147 $instance->setMessage($messages);
2150 $instance->zfBreakChainOnFailure = $validator['breakChainOnFailure'];
2152 if ($origName != $name) {
2153 $validatorNames = array_keys($this->_validators);
2154 $order = array_flip($validatorNames);
2155 $order[$name] = $order[$origName];
2156 $validatorsExchange = array();
2157 unset($order[$origName]);
2158 asort($order);
2159 foreach ($order as $key => $index) {
2160 if ($key == $name) {
2161 $validatorsExchange[$key] = $instance;
2162 continue;
2164 $validatorsExchange[$key] = $this->_validators[$key];
2166 $this->_validators = $validatorsExchange;
2167 } else {
2168 $this->_validators[$name] = $instance;
2171 return $instance;
2175 * Lazy-load a decorator
2177 * @param array $decorator Decorator type and options
2178 * @param mixed $name Decorator name or alias
2179 * @return Zend_Form_Decorator_Interface
2181 protected function _loadDecorator(array $decorator, $name)
2183 $sameName = false;
2184 if ($name == $decorator['decorator']) {
2185 $sameName = true;
2188 $instance = $this->_getDecorator($decorator['decorator'], $decorator['options']);
2189 if ($sameName) {
2190 $newName = get_class($instance);
2191 $decoratorNames = array_keys($this->_decorators);
2192 $order = array_flip($decoratorNames);
2193 $order[$newName] = $order[$name];
2194 $decoratorsExchange = array();
2195 unset($order[$name]);
2196 asort($order);
2197 foreach ($order as $key => $index) {
2198 if ($key == $newName) {
2199 $decoratorsExchange[$key] = $instance;
2200 continue;
2202 $decoratorsExchange[$key] = $this->_decorators[$key];
2204 $this->_decorators = $decoratorsExchange;
2205 } else {
2206 $this->_decorators[$name] = $instance;
2209 return $instance;
2213 * Retrieve error messages and perform translation and value substitution
2215 * @return array
2217 protected function _getErrorMessages()
2219 $translator = $this->getTranslator();
2220 $messages = $this->getErrorMessages();
2221 $value = $this->getValue();
2222 foreach ($messages as $key => $message) {
2223 if (null !== $translator) {
2224 $message = $translator->translate($message);
2226 if (($this->isArray() || is_array($value))
2227 && !empty($value)
2229 $aggregateMessages = array();
2230 foreach ($value as $val) {
2231 $aggregateMessages[] = str_replace('%value%', $val, $message);
2233 $messages[$key] = implode($this->getErrorMessageSeparator(), $aggregateMessages);
2234 } else {
2235 $messages[$key] = str_replace('%value%', $value, $message);
2238 return $messages;
2242 * Are there custom error messages registered?
2244 * @return bool
2246 protected function _hasErrorMessages()
2248 return !empty($this->_errorMessages);