|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Form |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 */ |
|
20 |
|
21 /** @see Zend_Filter */ |
|
22 require_once 'Zend/Filter.php'; |
|
23 |
|
24 /** @see Zend_Form */ |
|
25 require_once 'Zend/Form.php'; |
|
26 |
|
27 /** @see Zend_Validate_Interface */ |
|
28 require_once 'Zend/Validate/Interface.php'; |
|
29 |
|
30 /** @see Zend_Validate_Abstract */ |
|
31 require_once 'Zend/Validate/Abstract.php'; |
|
32 |
|
33 /** |
|
34 * Zend_Form_Element |
|
35 * |
|
36 * @category Zend |
|
37 * @package Zend_Form |
|
38 * @subpackage Element |
|
39 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
40 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
41 * @version $Id: Element.php 22464 2010-06-19 17:31:21Z alab $ |
|
42 */ |
|
43 class 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 $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')); |
|
327 } |
|
328 return $this; |
|
329 } |
|
330 |
|
331 /** |
|
332 * Set object state from options array |
|
333 * |
|
334 * @param array $options |
|
335 * @return Zend_Form_Element |
|
336 */ |
|
337 public function setOptions(array $options) |
|
338 { |
|
339 if (isset($options['prefixPath'])) { |
|
340 $this->addPrefixPaths($options['prefixPath']); |
|
341 unset($options['prefixPath']); |
|
342 } |
|
343 |
|
344 if (isset($options['disableTranslator'])) { |
|
345 $this->setDisableTranslator($options['disableTranslator']); |
|
346 unset($options['disableTranslator']); |
|
347 } |
|
348 |
|
349 unset($options['options']); |
|
350 unset($options['config']); |
|
351 |
|
352 foreach ($options as $key => $value) { |
|
353 $method = 'set' . ucfirst($key); |
|
354 |
|
355 if (in_array($method, array('setTranslator', 'setPluginLoader', 'setView'))) { |
|
356 if (!is_object($value)) { |
|
357 continue; |
|
358 } |
|
359 } |
|
360 |
|
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); |
|
367 } |
|
368 } |
|
369 return $this; |
|
370 } |
|
371 |
|
372 /** |
|
373 * Set object state from Zend_Config object |
|
374 * |
|
375 * @param Zend_Config $config |
|
376 * @return Zend_Form_Element |
|
377 */ |
|
378 public function setConfig(Zend_Config $config) |
|
379 { |
|
380 return $this->setOptions($config->toArray()); |
|
381 } |
|
382 |
|
383 |
|
384 // Localization: |
|
385 |
|
386 /** |
|
387 * Set translator object for localization |
|
388 * |
|
389 * @param Zend_Translate|null $translator |
|
390 * @return Zend_Form_Element |
|
391 */ |
|
392 public function setTranslator($translator = null) |
|
393 { |
|
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'); |
|
403 } |
|
404 return $this; |
|
405 } |
|
406 |
|
407 /** |
|
408 * Retrieve localization translator object |
|
409 * |
|
410 * @return Zend_Translate_Adapter|null |
|
411 */ |
|
412 public function getTranslator() |
|
413 { |
|
414 if ($this->translatorIsDisabled()) { |
|
415 return null; |
|
416 } |
|
417 |
|
418 if (null === $this->_translator) { |
|
419 return Zend_Form::getDefaultTranslator(); |
|
420 } |
|
421 return $this->_translator; |
|
422 } |
|
423 |
|
424 /** |
|
425 * Does this element have its own specific translator? |
|
426 * |
|
427 * @return bool |
|
428 */ |
|
429 public function hasTranslator() |
|
430 { |
|
431 return (bool)$this->_translator; |
|
432 } |
|
433 |
|
434 /** |
|
435 * Indicate whether or not translation should be disabled |
|
436 * |
|
437 * @param bool $flag |
|
438 * @return Zend_Form_Element |
|
439 */ |
|
440 public function setDisableTranslator($flag) |
|
441 { |
|
442 $this->_translatorDisabled = (bool) $flag; |
|
443 return $this; |
|
444 } |
|
445 |
|
446 /** |
|
447 * Is translation disabled? |
|
448 * |
|
449 * @return bool |
|
450 */ |
|
451 public function translatorIsDisabled() |
|
452 { |
|
453 return $this->_translatorDisabled; |
|
454 } |
|
455 |
|
456 // Metadata |
|
457 |
|
458 /** |
|
459 * Filter a name to only allow valid variable characters |
|
460 * |
|
461 * @param string $value |
|
462 * @param bool $allowBrackets |
|
463 * @return string |
|
464 */ |
|
465 public function filterName($value, $allowBrackets = false) |
|
466 { |
|
467 $charset = '^a-zA-Z0-9_\x7f-\xff'; |
|
468 if ($allowBrackets) { |
|
469 $charset .= '\[\]'; |
|
470 } |
|
471 return preg_replace('/[' . $charset . ']/', '', (string) $value); |
|
472 } |
|
473 |
|
474 /** |
|
475 * Set element name |
|
476 * |
|
477 * @param string $name |
|
478 * @return Zend_Form_Element |
|
479 */ |
|
480 public function setName($name) |
|
481 { |
|
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'); |
|
486 } |
|
487 |
|
488 $this->_name = $name; |
|
489 return $this; |
|
490 } |
|
491 |
|
492 /** |
|
493 * Return element name |
|
494 * |
|
495 * @return string |
|
496 */ |
|
497 public function getName() |
|
498 { |
|
499 return $this->_name; |
|
500 } |
|
501 |
|
502 /** |
|
503 * Get fully qualified name |
|
504 * |
|
505 * Places name as subitem of array and/or appends brackets. |
|
506 * |
|
507 * @return string |
|
508 */ |
|
509 public function getFullyQualifiedName() |
|
510 { |
|
511 $name = $this->getName(); |
|
512 |
|
513 if (null !== ($belongsTo = $this->getBelongsTo())) { |
|
514 $name = $belongsTo . '[' . $name . ']'; |
|
515 } |
|
516 |
|
517 if ($this->isArray()) { |
|
518 $name .= '[]'; |
|
519 } |
|
520 |
|
521 return $name; |
|
522 } |
|
523 |
|
524 /** |
|
525 * Get element id |
|
526 * |
|
527 * @return string |
|
528 */ |
|
529 public function getId() |
|
530 { |
|
531 if (isset($this->id)) { |
|
532 return $this->id; |
|
533 } |
|
534 |
|
535 $id = $this->getFullyQualifiedName(); |
|
536 |
|
537 // Bail early if no array notation detected |
|
538 if (!strstr($id, '[')) { |
|
539 return $id; |
|
540 } |
|
541 |
|
542 // Strip array notation |
|
543 if ('[]' == substr($id, -2)) { |
|
544 $id = substr($id, 0, strlen($id) - 2); |
|
545 } |
|
546 $id = str_replace('][', '-', $id); |
|
547 $id = str_replace(array(']', '['), '-', $id); |
|
548 $id = trim($id, '-'); |
|
549 |
|
550 return $id; |
|
551 } |
|
552 |
|
553 /** |
|
554 * Set element value |
|
555 * |
|
556 * @param mixed $value |
|
557 * @return Zend_Form_Element |
|
558 */ |
|
559 public function setValue($value) |
|
560 { |
|
561 $this->_value = $value; |
|
562 return $this; |
|
563 } |
|
564 |
|
565 /** |
|
566 * Filter a value |
|
567 * |
|
568 * @param string $value |
|
569 * @param string $key |
|
570 * @return void |
|
571 */ |
|
572 protected function _filterValue(&$value, &$key) |
|
573 { |
|
574 foreach ($this->getFilters() as $filter) { |
|
575 $value = $filter->filter($value); |
|
576 } |
|
577 } |
|
578 |
|
579 /** |
|
580 * Retrieve filtered element value |
|
581 * |
|
582 * @return mixed |
|
583 */ |
|
584 public function getValue() |
|
585 { |
|
586 $valueFiltered = $this->_value; |
|
587 |
|
588 if ($this->isArray() && is_array($valueFiltered)) { |
|
589 array_walk_recursive($valueFiltered, array($this, '_filterValue')); |
|
590 } else { |
|
591 $this->_filterValue($valueFiltered, $valueFiltered); |
|
592 } |
|
593 |
|
594 return $valueFiltered; |
|
595 } |
|
596 |
|
597 /** |
|
598 * Retrieve unfiltered element value |
|
599 * |
|
600 * @return mixed |
|
601 */ |
|
602 public function getUnfilteredValue() |
|
603 { |
|
604 return $this->_value; |
|
605 } |
|
606 |
|
607 /** |
|
608 * Set element label |
|
609 * |
|
610 * @param string $label |
|
611 * @return Zend_Form_Element |
|
612 */ |
|
613 public function setLabel($label) |
|
614 { |
|
615 $this->_label = (string) $label; |
|
616 return $this; |
|
617 } |
|
618 |
|
619 /** |
|
620 * Retrieve element label |
|
621 * |
|
622 * @return string |
|
623 */ |
|
624 public function getLabel() |
|
625 { |
|
626 $translator = $this->getTranslator(); |
|
627 if (null !== $translator) { |
|
628 return $translator->translate($this->_label); |
|
629 } |
|
630 |
|
631 return $this->_label; |
|
632 } |
|
633 |
|
634 /** |
|
635 * Set element order |
|
636 * |
|
637 * @param int $order |
|
638 * @return Zend_Form_Element |
|
639 */ |
|
640 public function setOrder($order) |
|
641 { |
|
642 $this->_order = (int) $order; |
|
643 return $this; |
|
644 } |
|
645 |
|
646 /** |
|
647 * Retrieve element order |
|
648 * |
|
649 * @return int |
|
650 */ |
|
651 public function getOrder() |
|
652 { |
|
653 return $this->_order; |
|
654 } |
|
655 |
|
656 /** |
|
657 * Set required flag |
|
658 * |
|
659 * @param bool $flag Default value is true |
|
660 * @return Zend_Form_Element |
|
661 */ |
|
662 public function setRequired($flag = true) |
|
663 { |
|
664 $this->_required = (bool) $flag; |
|
665 return $this; |
|
666 } |
|
667 |
|
668 /** |
|
669 * Is the element required? |
|
670 * |
|
671 * @return bool |
|
672 */ |
|
673 public function isRequired() |
|
674 { |
|
675 return $this->_required; |
|
676 } |
|
677 |
|
678 /** |
|
679 * Set flag indicating whether a NotEmpty validator should be inserted when element is required |
|
680 * |
|
681 * @param bool $flag |
|
682 * @return Zend_Form_Element |
|
683 */ |
|
684 public function setAutoInsertNotEmptyValidator($flag) |
|
685 { |
|
686 $this->_autoInsertNotEmptyValidator = (bool) $flag; |
|
687 return $this; |
|
688 } |
|
689 |
|
690 /** |
|
691 * Get flag indicating whether a NotEmpty validator should be inserted when element is required |
|
692 * |
|
693 * @return bool |
|
694 */ |
|
695 public function autoInsertNotEmptyValidator() |
|
696 { |
|
697 return $this->_autoInsertNotEmptyValidator; |
|
698 } |
|
699 |
|
700 /** |
|
701 * Set element description |
|
702 * |
|
703 * @param string $description |
|
704 * @return Zend_Form_Element |
|
705 */ |
|
706 public function setDescription($description) |
|
707 { |
|
708 $this->_description = (string) $description; |
|
709 return $this; |
|
710 } |
|
711 |
|
712 /** |
|
713 * Retrieve element description |
|
714 * |
|
715 * @return string |
|
716 */ |
|
717 public function getDescription() |
|
718 { |
|
719 return $this->_description; |
|
720 } |
|
721 |
|
722 /** |
|
723 * Set 'allow empty' flag |
|
724 * |
|
725 * When the allow empty flag is enabled and the required flag is false, the |
|
726 * element will validate with empty values. |
|
727 * |
|
728 * @param bool $flag |
|
729 * @return Zend_Form_Element |
|
730 */ |
|
731 public function setAllowEmpty($flag) |
|
732 { |
|
733 $this->_allowEmpty = (bool) $flag; |
|
734 return $this; |
|
735 } |
|
736 |
|
737 /** |
|
738 * Get 'allow empty' flag |
|
739 * |
|
740 * @return bool |
|
741 */ |
|
742 public function getAllowEmpty() |
|
743 { |
|
744 return $this->_allowEmpty; |
|
745 } |
|
746 |
|
747 /** |
|
748 * Set ignore flag (used when retrieving values at form level) |
|
749 * |
|
750 * @param bool $flag |
|
751 * @return Zend_Form_Element |
|
752 */ |
|
753 public function setIgnore($flag) |
|
754 { |
|
755 $this->_ignore = (bool) $flag; |
|
756 return $this; |
|
757 } |
|
758 |
|
759 /** |
|
760 * Get ignore flag (used when retrieving values at form level) |
|
761 * |
|
762 * @return bool |
|
763 */ |
|
764 public function getIgnore() |
|
765 { |
|
766 return $this->_ignore; |
|
767 } |
|
768 |
|
769 /** |
|
770 * Set flag indicating if element represents an array |
|
771 * |
|
772 * @param bool $flag |
|
773 * @return Zend_Form_Element |
|
774 */ |
|
775 public function setIsArray($flag) |
|
776 { |
|
777 $this->_isArray = (bool) $flag; |
|
778 return $this; |
|
779 } |
|
780 |
|
781 /** |
|
782 * Is the element representing an array? |
|
783 * |
|
784 * @return bool |
|
785 */ |
|
786 public function isArray() |
|
787 { |
|
788 return $this->_isArray; |
|
789 } |
|
790 |
|
791 /** |
|
792 * Set array to which element belongs |
|
793 * |
|
794 * @param string $array |
|
795 * @return Zend_Form_Element |
|
796 */ |
|
797 public function setBelongsTo($array) |
|
798 { |
|
799 $array = $this->filterName($array, true); |
|
800 if (!empty($array)) { |
|
801 $this->_belongsTo = $array; |
|
802 } |
|
803 |
|
804 return $this; |
|
805 } |
|
806 |
|
807 /** |
|
808 * Return array name to which element belongs |
|
809 * |
|
810 * @return string |
|
811 */ |
|
812 public function getBelongsTo() |
|
813 { |
|
814 return $this->_belongsTo; |
|
815 } |
|
816 |
|
817 /** |
|
818 * Return element type |
|
819 * |
|
820 * @return string |
|
821 */ |
|
822 public function getType() |
|
823 { |
|
824 if (null === $this->_type) { |
|
825 $this->_type = get_class($this); |
|
826 } |
|
827 |
|
828 return $this->_type; |
|
829 } |
|
830 |
|
831 /** |
|
832 * Set element attribute |
|
833 * |
|
834 * @param string $name |
|
835 * @param mixed $value |
|
836 * @return Zend_Form_Element |
|
837 * @throws Zend_Form_Exception for invalid $name values |
|
838 */ |
|
839 public function setAttrib($name, $value) |
|
840 { |
|
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)); |
|
845 } |
|
846 |
|
847 if (null === $value) { |
|
848 unset($this->$name); |
|
849 } else { |
|
850 $this->$name = $value; |
|
851 } |
|
852 |
|
853 return $this; |
|
854 } |
|
855 |
|
856 /** |
|
857 * Set multiple attributes at once |
|
858 * |
|
859 * @param array $attribs |
|
860 * @return Zend_Form_Element |
|
861 */ |
|
862 public function setAttribs(array $attribs) |
|
863 { |
|
864 foreach ($attribs as $key => $value) { |
|
865 $this->setAttrib($key, $value); |
|
866 } |
|
867 |
|
868 return $this; |
|
869 } |
|
870 |
|
871 /** |
|
872 * Retrieve element attribute |
|
873 * |
|
874 * @param string $name |
|
875 * @return string |
|
876 */ |
|
877 public function getAttrib($name) |
|
878 { |
|
879 $name = (string) $name; |
|
880 if (isset($this->$name)) { |
|
881 return $this->$name; |
|
882 } |
|
883 |
|
884 return null; |
|
885 } |
|
886 |
|
887 /** |
|
888 * Return all attributes |
|
889 * |
|
890 * @return array |
|
891 */ |
|
892 public function getAttribs() |
|
893 { |
|
894 $attribs = get_object_vars($this); |
|
895 foreach ($attribs as $key => $value) { |
|
896 if ('_' == substr($key, 0, 1)) { |
|
897 unset($attribs[$key]); |
|
898 } |
|
899 } |
|
900 |
|
901 return $attribs; |
|
902 } |
|
903 |
|
904 /** |
|
905 * Overloading: retrieve object property |
|
906 * |
|
907 * Prevents access to properties beginning with '_'. |
|
908 * |
|
909 * @param string $key |
|
910 * @return mixed |
|
911 */ |
|
912 public function __get($key) |
|
913 { |
|
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)); |
|
917 } |
|
918 |
|
919 if (!isset($this->$key)) { |
|
920 return null; |
|
921 } |
|
922 |
|
923 return $this->$key; |
|
924 } |
|
925 |
|
926 /** |
|
927 * Overloading: set object property |
|
928 * |
|
929 * @param string $key |
|
930 * @param mixed $value |
|
931 * @return voide |
|
932 */ |
|
933 public function __set($key, $value) |
|
934 { |
|
935 $this->setAttrib($key, $value); |
|
936 } |
|
937 |
|
938 /** |
|
939 * Overloading: allow rendering specific decorators |
|
940 * |
|
941 * Call renderDecoratorName() to render a specific decorator. |
|
942 * |
|
943 * @param string $method |
|
944 * @param array $args |
|
945 * @return string |
|
946 * @throws Zend_Form_Exception for invalid decorator or invalid method call |
|
947 */ |
|
948 public function __call($method, $args) |
|
949 { |
|
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); |
|
960 } |
|
961 return $decorator->render($seed); |
|
962 } |
|
963 |
|
964 require_once 'Zend/Form/Element/Exception.php'; |
|
965 throw new Zend_Form_Element_Exception(sprintf('Decorator by name %s does not exist', $decoratorName)); |
|
966 } |
|
967 |
|
968 require_once 'Zend/Form/Element/Exception.php'; |
|
969 throw new Zend_Form_Element_Exception(sprintf('Method %s does not exist', $method)); |
|
970 } |
|
971 |
|
972 // Loaders |
|
973 |
|
974 /** |
|
975 * Set plugin loader to use for validator or filter chain |
|
976 * |
|
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 |
|
981 */ |
|
982 public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type) |
|
983 { |
|
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)); |
|
994 } |
|
995 } |
|
996 |
|
997 /** |
|
998 * Retrieve plugin loader for validator or filter chain |
|
999 * |
|
1000 * Instantiates with default rules if none available for that type. Use |
|
1001 * 'decorator', 'filter', or 'validate' for $type. |
|
1002 * |
|
1003 * @param string $type |
|
1004 * @return Zend_Loader_PluginLoader |
|
1005 * @throws Zend_Loader_Exception on invalid type. |
|
1006 */ |
|
1007 public function getPluginLoader($type) |
|
1008 { |
|
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'; |
|
1019 } |
|
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 . '/') |
|
1024 ); |
|
1025 } |
|
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)); |
|
1030 } |
|
1031 } |
|
1032 |
|
1033 /** |
|
1034 * Add prefix path for plugin loader |
|
1035 * |
|
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' |
|
1041 * |
|
1042 * Otherwise, the path prefix is set on the appropriate plugin loader. |
|
1043 * |
|
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 |
|
1049 */ |
|
1050 public function addPrefixPath($prefix, $path, $type = null) |
|
1051 { |
|
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); |
|
1069 } |
|
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)); |
|
1074 } |
|
1075 } |
|
1076 |
|
1077 /** |
|
1078 * Add many prefix paths at once |
|
1079 * |
|
1080 * @param array $spec |
|
1081 * @return Zend_Form_Element |
|
1082 */ |
|
1083 public function addPrefixPaths(array $spec) |
|
1084 { |
|
1085 if (isset($spec['prefix']) && isset($spec['path'])) { |
|
1086 return $this->addPrefixPath($spec['prefix'], $spec['path']); |
|
1087 } |
|
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']; |
|
1094 } |
|
1095 $this->addPrefixPath($paths['prefix'], $paths['path'], $type); |
|
1096 } |
|
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; |
|
1104 } |
|
1105 $this->addPrefixPath($prefix, $path, $type); |
|
1106 } |
|
1107 } elseif (is_string($spec)) { |
|
1108 $this->addPrefixPath($prefix, $spec, $type); |
|
1109 } |
|
1110 } |
|
1111 } else { |
|
1112 $this->addPrefixPath($paths['prefix'], $paths['path'], $type); |
|
1113 } |
|
1114 } |
|
1115 } |
|
1116 return $this; |
|
1117 } |
|
1118 |
|
1119 // Validation |
|
1120 |
|
1121 /** |
|
1122 * Add validator to validation chain |
|
1123 * |
|
1124 * Note: will overwrite existing validators if they are of the same class. |
|
1125 * |
|
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 |
|
1131 */ |
|
1132 public function addValidator($validator, $breakChainOnFailure = false, $options = array()) |
|
1133 { |
|
1134 if ($validator instanceof Zend_Validate_Interface) { |
|
1135 $name = get_class($validator); |
|
1136 |
|
1137 if (!isset($validator->zfBreakChainOnFailure)) { |
|
1138 $validator->zfBreakChainOnFailure = $breakChainOnFailure; |
|
1139 } |
|
1140 } elseif (is_string($validator)) { |
|
1141 $name = $validator; |
|
1142 $validator = array( |
|
1143 'validator' => $validator, |
|
1144 'breakChainOnFailure' => $breakChainOnFailure, |
|
1145 'options' => $options, |
|
1146 ); |
|
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'); |
|
1150 } |
|
1151 |
|
1152 |
|
1153 $this->_validators[$name] = $validator; |
|
1154 |
|
1155 return $this; |
|
1156 } |
|
1157 |
|
1158 /** |
|
1159 * Add multiple validators |
|
1160 * |
|
1161 * @param array $validators |
|
1162 * @return Zend_Form_Element |
|
1163 */ |
|
1164 public function addValidators(array $validators) |
|
1165 { |
|
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']; |
|
1179 } |
|
1180 if (isset($validatorInfo['options'])) { |
|
1181 $options = $validatorInfo['options']; |
|
1182 } |
|
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; |
|
1197 } |
|
1198 } |
|
1199 } else { |
|
1200 require_once 'Zend/Form/Exception.php'; |
|
1201 throw new Zend_Form_Exception('Invalid validator passed to addValidators()'); |
|
1202 } |
|
1203 } |
|
1204 |
|
1205 return $this; |
|
1206 } |
|
1207 |
|
1208 /** |
|
1209 * Set multiple validators, overwriting previous validators |
|
1210 * |
|
1211 * @param array $validators |
|
1212 * @return Zend_Form_Element |
|
1213 */ |
|
1214 public function setValidators(array $validators) |
|
1215 { |
|
1216 $this->clearValidators(); |
|
1217 return $this->addValidators($validators); |
|
1218 } |
|
1219 |
|
1220 /** |
|
1221 * Retrieve a single validator by name |
|
1222 * |
|
1223 * @param string $name |
|
1224 * @return Zend_Validate_Interface|false False if not found, validator otherwise |
|
1225 */ |
|
1226 public function getValidator($name) |
|
1227 { |
|
1228 if (!isset($this->_validators[$name])) { |
|
1229 $len = strlen($name); |
|
1230 foreach ($this->_validators as $localName => $validator) { |
|
1231 if ($len > strlen($localName)) { |
|
1232 continue; |
|
1233 } |
|
1234 if (0 === substr_compare($localName, $name, -$len, $len, true)) { |
|
1235 if (is_array($validator)) { |
|
1236 return $this->_loadValidator($validator); |
|
1237 } |
|
1238 return $validator; |
|
1239 } |
|
1240 } |
|
1241 return false; |
|
1242 } |
|
1243 |
|
1244 if (is_array($this->_validators[$name])) { |
|
1245 return $this->_loadValidator($this->_validators[$name]); |
|
1246 } |
|
1247 |
|
1248 return $this->_validators[$name]; |
|
1249 } |
|
1250 |
|
1251 /** |
|
1252 * Retrieve all validators |
|
1253 * |
|
1254 * @return array |
|
1255 */ |
|
1256 public function getValidators() |
|
1257 { |
|
1258 $validators = array(); |
|
1259 foreach ($this->_validators as $key => $value) { |
|
1260 if ($value instanceof Zend_Validate_Interface) { |
|
1261 $validators[$key] = $value; |
|
1262 continue; |
|
1263 } |
|
1264 $validator = $this->_loadValidator($value); |
|
1265 $validators[get_class($validator)] = $validator; |
|
1266 } |
|
1267 return $validators; |
|
1268 } |
|
1269 |
|
1270 /** |
|
1271 * Remove a single validator by name |
|
1272 * |
|
1273 * @param string $name |
|
1274 * @return bool |
|
1275 */ |
|
1276 public function removeValidator($name) |
|
1277 { |
|
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; |
|
1285 } |
|
1286 if (0 === substr_compare($validator, $name, -$len, $len, true)) { |
|
1287 unset($this->_validators[$validator]); |
|
1288 break; |
|
1289 } |
|
1290 } |
|
1291 } |
|
1292 |
|
1293 return $this; |
|
1294 } |
|
1295 |
|
1296 /** |
|
1297 * Clear all validators |
|
1298 * |
|
1299 * @return Zend_Form_Element |
|
1300 */ |
|
1301 public function clearValidators() |
|
1302 { |
|
1303 $this->_validators = array(); |
|
1304 return $this; |
|
1305 } |
|
1306 |
|
1307 /** |
|
1308 * Validate element value |
|
1309 * |
|
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. |
|
1314 * |
|
1315 * Note: The *filtered* value is validated. |
|
1316 * |
|
1317 * @param mixed $value |
|
1318 * @param mixed $context |
|
1319 * @return boolean |
|
1320 */ |
|
1321 public function isValid($value, $context = null) |
|
1322 { |
|
1323 $this->setValue($value); |
|
1324 $value = $this->getValue(); |
|
1325 |
|
1326 if ((('' === $value) || (null === $value)) |
|
1327 && !$this->isRequired() |
|
1328 && $this->getAllowEmpty() |
|
1329 ) { |
|
1330 return true; |
|
1331 } |
|
1332 |
|
1333 if ($this->isRequired() |
|
1334 && $this->autoInsertNotEmptyValidator() |
|
1335 && !$this->getValidator('NotEmpty')) |
|
1336 { |
|
1337 $validators = $this->getValidators(); |
|
1338 $notEmpty = array('validator' => 'NotEmpty', 'breakChainOnFailure' => true); |
|
1339 array_unshift($validators, $notEmpty); |
|
1340 $this->setValidators($validators); |
|
1341 } |
|
1342 |
|
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()) |
|
1348 { |
|
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(); |
|
1353 } |
|
1354 } else { |
|
1355 $translator = $this->getTranslator(); |
|
1356 } |
|
1357 |
|
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); |
|
1367 } |
|
1368 } else { |
|
1369 $validator->setTranslator($translator); |
|
1370 } |
|
1371 } |
|
1372 |
|
1373 if (method_exists($validator, 'setDisableTranslator')) { |
|
1374 $validator->setDisableTranslator($this->translatorIsDisabled()); |
|
1375 } |
|
1376 |
|
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()); |
|
1389 } |
|
1390 } |
|
1391 } |
|
1392 if ($result) { |
|
1393 continue; |
|
1394 } |
|
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); |
|
1405 } |
|
1406 } |
|
1407 |
|
1408 $result = false; |
|
1409 $this->_messages = array_merge($this->_messages, $messages); |
|
1410 $this->_errors = array_merge($this->_errors, $errors); |
|
1411 |
|
1412 if ($validator->zfBreakChainOnFailure) { |
|
1413 break; |
|
1414 } |
|
1415 } |
|
1416 |
|
1417 // If element manually flagged as invalid, return false |
|
1418 if ($this->_isErrorForced) { |
|
1419 return false; |
|
1420 } |
|
1421 |
|
1422 return $result; |
|
1423 } |
|
1424 |
|
1425 /** |
|
1426 * Add a custom error message to return in the event of failed validation |
|
1427 * |
|
1428 * @param string $message |
|
1429 * @return Zend_Form_Element |
|
1430 */ |
|
1431 public function addErrorMessage($message) |
|
1432 { |
|
1433 $this->_errorMessages[] = (string) $message; |
|
1434 return $this; |
|
1435 } |
|
1436 |
|
1437 /** |
|
1438 * Add multiple custom error messages to return in the event of failed validation |
|
1439 * |
|
1440 * @param array $messages |
|
1441 * @return Zend_Form_Element |
|
1442 */ |
|
1443 public function addErrorMessages(array $messages) |
|
1444 { |
|
1445 foreach ($messages as $message) { |
|
1446 $this->addErrorMessage($message); |
|
1447 } |
|
1448 return $this; |
|
1449 } |
|
1450 |
|
1451 /** |
|
1452 * Same as addErrorMessages(), but clears custom error message stack first |
|
1453 * |
|
1454 * @param array $messages |
|
1455 * @return Zend_Form_Element |
|
1456 */ |
|
1457 public function setErrorMessages(array $messages) |
|
1458 { |
|
1459 $this->clearErrorMessages(); |
|
1460 return $this->addErrorMessages($messages); |
|
1461 } |
|
1462 |
|
1463 /** |
|
1464 * Retrieve custom error messages |
|
1465 * |
|
1466 * @return array |
|
1467 */ |
|
1468 public function getErrorMessages() |
|
1469 { |
|
1470 return $this->_errorMessages; |
|
1471 } |
|
1472 |
|
1473 /** |
|
1474 * Clear custom error messages stack |
|
1475 * |
|
1476 * @return Zend_Form_Element |
|
1477 */ |
|
1478 public function clearErrorMessages() |
|
1479 { |
|
1480 $this->_errorMessages = array(); |
|
1481 return $this; |
|
1482 } |
|
1483 |
|
1484 /** |
|
1485 * Get errorMessageSeparator |
|
1486 * |
|
1487 * @return string |
|
1488 */ |
|
1489 public function getErrorMessageSeparator() |
|
1490 { |
|
1491 return $this->_errorMessageSeparator; |
|
1492 } |
|
1493 |
|
1494 /** |
|
1495 * Set errorMessageSeparator |
|
1496 * |
|
1497 * @param string $separator |
|
1498 * @return Zend_Form_Element |
|
1499 */ |
|
1500 public function setErrorMessageSeparator($separator) |
|
1501 { |
|
1502 $this->_errorMessageSeparator = $separator; |
|
1503 return $this; |
|
1504 } |
|
1505 |
|
1506 /** |
|
1507 * Mark the element as being in a failed validation state |
|
1508 * |
|
1509 * @return Zend_Form_Element |
|
1510 */ |
|
1511 public function markAsError() |
|
1512 { |
|
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; |
|
1520 } |
|
1521 $this->_isErrorForced = true; |
|
1522 return $this; |
|
1523 } |
|
1524 |
|
1525 /** |
|
1526 * Add an error message and mark element as failed validation |
|
1527 * |
|
1528 * @param string $message |
|
1529 * @return Zend_Form_Element |
|
1530 */ |
|
1531 public function addError($message) |
|
1532 { |
|
1533 $this->addErrorMessage($message); |
|
1534 $this->markAsError(); |
|
1535 return $this; |
|
1536 } |
|
1537 |
|
1538 /** |
|
1539 * Add multiple error messages and flag element as failed validation |
|
1540 * |
|
1541 * @param array $messages |
|
1542 * @return Zend_Form_Element |
|
1543 */ |
|
1544 public function addErrors(array $messages) |
|
1545 { |
|
1546 foreach ($messages as $message) { |
|
1547 $this->addError($message); |
|
1548 } |
|
1549 return $this; |
|
1550 } |
|
1551 |
|
1552 /** |
|
1553 * Overwrite any previously set error messages and flag as failed validation |
|
1554 * |
|
1555 * @param array $messages |
|
1556 * @return Zend_Form_Element |
|
1557 */ |
|
1558 public function setErrors(array $messages) |
|
1559 { |
|
1560 $this->clearErrorMessages(); |
|
1561 return $this->addErrors($messages); |
|
1562 } |
|
1563 |
|
1564 /** |
|
1565 * Are there errors registered? |
|
1566 * |
|
1567 * @return bool |
|
1568 */ |
|
1569 public function hasErrors() |
|
1570 { |
|
1571 return (!empty($this->_messages) || $this->_isError); |
|
1572 } |
|
1573 |
|
1574 /** |
|
1575 * Retrieve validator chain errors |
|
1576 * |
|
1577 * @return array |
|
1578 */ |
|
1579 public function getErrors() |
|
1580 { |
|
1581 return $this->_errors; |
|
1582 } |
|
1583 |
|
1584 /** |
|
1585 * Retrieve error messages |
|
1586 * |
|
1587 * @return array |
|
1588 */ |
|
1589 public function getMessages() |
|
1590 { |
|
1591 return $this->_messages; |
|
1592 } |
|
1593 |
|
1594 |
|
1595 // Filtering |
|
1596 |
|
1597 /** |
|
1598 * Add a filter to the element |
|
1599 * |
|
1600 * @param string|Zend_Filter_Interface $filter |
|
1601 * @return Zend_Form_Element |
|
1602 */ |
|
1603 public function addFilter($filter, $options = array()) |
|
1604 { |
|
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, |
|
1612 ); |
|
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'); |
|
1617 } |
|
1618 |
|
1619 $this->_filters[$name] = $filter; |
|
1620 |
|
1621 return $this; |
|
1622 } |
|
1623 |
|
1624 /** |
|
1625 * Add filters to element |
|
1626 * |
|
1627 * @param array $filters |
|
1628 * @return Zend_Form_Element |
|
1629 */ |
|
1630 public function addFilters(array $filters) |
|
1631 { |
|
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']; |
|
1644 } |
|
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; |
|
1657 } |
|
1658 } |
|
1659 } else { |
|
1660 require_once 'Zend/Form/Exception.php'; |
|
1661 throw new Zend_Form_Exception('Invalid filter passed to addFilters()'); |
|
1662 } |
|
1663 } |
|
1664 |
|
1665 return $this; |
|
1666 } |
|
1667 |
|
1668 /** |
|
1669 * Add filters to element, overwriting any already existing |
|
1670 * |
|
1671 * @param array $filters |
|
1672 * @return Zend_Form_Element |
|
1673 */ |
|
1674 public function setFilters(array $filters) |
|
1675 { |
|
1676 $this->clearFilters(); |
|
1677 return $this->addFilters($filters); |
|
1678 } |
|
1679 |
|
1680 /** |
|
1681 * Retrieve a single filter by name |
|
1682 * |
|
1683 * @param string $name |
|
1684 * @return Zend_Filter_Interface |
|
1685 */ |
|
1686 public function getFilter($name) |
|
1687 { |
|
1688 if (!isset($this->_filters[$name])) { |
|
1689 $len = strlen($name); |
|
1690 foreach ($this->_filters as $localName => $filter) { |
|
1691 if ($len > strlen($localName)) { |
|
1692 continue; |
|
1693 } |
|
1694 |
|
1695 if (0 === substr_compare($localName, $name, -$len, $len, true)) { |
|
1696 if (is_array($filter)) { |
|
1697 return $this->_loadFilter($filter); |
|
1698 } |
|
1699 return $filter; |
|
1700 } |
|
1701 } |
|
1702 return false; |
|
1703 } |
|
1704 |
|
1705 if (is_array($this->_filters[$name])) { |
|
1706 return $this->_loadFilter($this->_filters[$name]); |
|
1707 } |
|
1708 |
|
1709 return $this->_filters[$name]; |
|
1710 } |
|
1711 |
|
1712 /** |
|
1713 * Get all filters |
|
1714 * |
|
1715 * @return array |
|
1716 */ |
|
1717 public function getFilters() |
|
1718 { |
|
1719 $filters = array(); |
|
1720 foreach ($this->_filters as $key => $value) { |
|
1721 if ($value instanceof Zend_Filter_Interface) { |
|
1722 $filters[$key] = $value; |
|
1723 continue; |
|
1724 } |
|
1725 $filter = $this->_loadFilter($value); |
|
1726 $filters[get_class($filter)] = $filter; |
|
1727 } |
|
1728 return $filters; |
|
1729 } |
|
1730 |
|
1731 /** |
|
1732 * Remove a filter by name |
|
1733 * |
|
1734 * @param string $name |
|
1735 * @return Zend_Form_Element |
|
1736 */ |
|
1737 public function removeFilter($name) |
|
1738 { |
|
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; |
|
1746 } |
|
1747 if (0 === substr_compare($filter, $name, -$len, $len, true)) { |
|
1748 unset($this->_filters[$filter]); |
|
1749 break; |
|
1750 } |
|
1751 } |
|
1752 } |
|
1753 |
|
1754 return $this; |
|
1755 } |
|
1756 |
|
1757 /** |
|
1758 * Clear all filters |
|
1759 * |
|
1760 * @return Zend_Form_Element |
|
1761 */ |
|
1762 public function clearFilters() |
|
1763 { |
|
1764 $this->_filters = array(); |
|
1765 return $this; |
|
1766 } |
|
1767 |
|
1768 // Rendering |
|
1769 |
|
1770 /** |
|
1771 * Set view object |
|
1772 * |
|
1773 * @param Zend_View_Interface $view |
|
1774 * @return Zend_Form_Element |
|
1775 */ |
|
1776 public function setView(Zend_View_Interface $view = null) |
|
1777 { |
|
1778 $this->_view = $view; |
|
1779 return $this; |
|
1780 } |
|
1781 |
|
1782 /** |
|
1783 * Retrieve view object |
|
1784 * |
|
1785 * Retrieves from ViewRenderer if none previously set. |
|
1786 * |
|
1787 * @return null|Zend_View_Interface |
|
1788 */ |
|
1789 public function getView() |
|
1790 { |
|
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); |
|
1795 } |
|
1796 return $this->_view; |
|
1797 } |
|
1798 |
|
1799 /** |
|
1800 * Instantiate a decorator based on class name or class name fragment |
|
1801 * |
|
1802 * @param string $name |
|
1803 * @param null|array $options |
|
1804 * @return Zend_Form_Decorator_Interface |
|
1805 */ |
|
1806 protected function _getDecorator($name, $options) |
|
1807 { |
|
1808 $class = $this->getPluginLoader(self::DECORATOR)->load($name); |
|
1809 if (null === $options) { |
|
1810 $decorator = new $class; |
|
1811 } else { |
|
1812 $decorator = new $class($options); |
|
1813 } |
|
1814 |
|
1815 return $decorator; |
|
1816 } |
|
1817 |
|
1818 /** |
|
1819 * Add a decorator for rendering the element |
|
1820 * |
|
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 |
|
1824 */ |
|
1825 public function addDecorator($decorator, $options = null) |
|
1826 { |
|
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, |
|
1834 ); |
|
1835 } elseif (is_array($decorator)) { |
|
1836 foreach ($decorator as $name => $spec) { |
|
1837 break; |
|
1838 } |
|
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'); |
|
1842 } |
|
1843 if (is_string($spec)) { |
|
1844 $decorator = array( |
|
1845 'decorator' => $spec, |
|
1846 'options' => $options, |
|
1847 ); |
|
1848 } elseif ($spec instanceof Zend_Form_Decorator_Interface) { |
|
1849 $decorator = $spec; |
|
1850 } |
|
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'); |
|
1854 } |
|
1855 |
|
1856 $this->_decorators[$name] = $decorator; |
|
1857 |
|
1858 return $this; |
|
1859 } |
|
1860 |
|
1861 /** |
|
1862 * Add many decorators at once |
|
1863 * |
|
1864 * @param array $decorators |
|
1865 * @return Zend_Form_Element |
|
1866 */ |
|
1867 public function addDecorators(array $decorators) |
|
1868 { |
|
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); |
|
1876 } |
|
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']; |
|
1884 } |
|
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; |
|
1897 } |
|
1898 } |
|
1899 } else { |
|
1900 require_once 'Zend/Form/Exception.php'; |
|
1901 throw new Zend_Form_Exception('Invalid decorator passed to addDecorators()'); |
|
1902 } |
|
1903 } |
|
1904 |
|
1905 return $this; |
|
1906 } |
|
1907 |
|
1908 /** |
|
1909 * Overwrite all decorators |
|
1910 * |
|
1911 * @param array $decorators |
|
1912 * @return Zend_Form_Element |
|
1913 */ |
|
1914 public function setDecorators(array $decorators) |
|
1915 { |
|
1916 $this->clearDecorators(); |
|
1917 return $this->addDecorators($decorators); |
|
1918 } |
|
1919 |
|
1920 /** |
|
1921 * Retrieve a registered decorator |
|
1922 * |
|
1923 * @param string $name |
|
1924 * @return false|Zend_Form_Decorator_Abstract |
|
1925 */ |
|
1926 public function getDecorator($name) |
|
1927 { |
|
1928 if (!isset($this->_decorators[$name])) { |
|
1929 $len = strlen($name); |
|
1930 foreach ($this->_decorators as $localName => $decorator) { |
|
1931 if ($len > strlen($localName)) { |
|
1932 continue; |
|
1933 } |
|
1934 |
|
1935 if (0 === substr_compare($localName, $name, -$len, $len, true)) { |
|
1936 if (is_array($decorator)) { |
|
1937 return $this->_loadDecorator($decorator, $localName); |
|
1938 } |
|
1939 return $decorator; |
|
1940 } |
|
1941 } |
|
1942 return false; |
|
1943 } |
|
1944 |
|
1945 if (is_array($this->_decorators[$name])) { |
|
1946 return $this->_loadDecorator($this->_decorators[$name], $name); |
|
1947 } |
|
1948 |
|
1949 return $this->_decorators[$name]; |
|
1950 } |
|
1951 |
|
1952 /** |
|
1953 * Retrieve all decorators |
|
1954 * |
|
1955 * @return array |
|
1956 */ |
|
1957 public function getDecorators() |
|
1958 { |
|
1959 foreach ($this->_decorators as $key => $value) { |
|
1960 if (is_array($value)) { |
|
1961 $this->_loadDecorator($value, $key); |
|
1962 } |
|
1963 } |
|
1964 return $this->_decorators; |
|
1965 } |
|
1966 |
|
1967 /** |
|
1968 * Remove a single decorator |
|
1969 * |
|
1970 * @param string $name |
|
1971 * @return Zend_Form_Element |
|
1972 */ |
|
1973 public function removeDecorator($name) |
|
1974 { |
|
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; |
|
1982 } |
|
1983 if (0 === substr_compare($decorator, $name, -$len, $len, true)) { |
|
1984 unset($this->_decorators[$decorator]); |
|
1985 break; |
|
1986 } |
|
1987 } |
|
1988 } |
|
1989 |
|
1990 return $this; |
|
1991 } |
|
1992 |
|
1993 /** |
|
1994 * Clear all decorators |
|
1995 * |
|
1996 * @return Zend_Form_Element |
|
1997 */ |
|
1998 public function clearDecorators() |
|
1999 { |
|
2000 $this->_decorators = array(); |
|
2001 return $this; |
|
2002 } |
|
2003 |
|
2004 /** |
|
2005 * Render form element |
|
2006 * |
|
2007 * @param Zend_View_Interface $view |
|
2008 * @return string |
|
2009 */ |
|
2010 public function render(Zend_View_Interface $view = null) |
|
2011 { |
|
2012 if ($this->_isPartialRendering) { |
|
2013 return ''; |
|
2014 } |
|
2015 |
|
2016 if (null !== $view) { |
|
2017 $this->setView($view); |
|
2018 } |
|
2019 |
|
2020 $content = ''; |
|
2021 foreach ($this->getDecorators() as $decorator) { |
|
2022 $decorator->setElement($this); |
|
2023 $content = $decorator->render($content); |
|
2024 } |
|
2025 return $content; |
|
2026 } |
|
2027 |
|
2028 /** |
|
2029 * String representation of form element |
|
2030 * |
|
2031 * Proxies to {@link render()}. |
|
2032 * |
|
2033 * @return string |
|
2034 */ |
|
2035 public function __toString() |
|
2036 { |
|
2037 try { |
|
2038 $return = $this->render(); |
|
2039 return $return; |
|
2040 } catch (Exception $e) { |
|
2041 trigger_error($e->getMessage(), E_USER_WARNING); |
|
2042 return ''; |
|
2043 } |
|
2044 } |
|
2045 |
|
2046 /** |
|
2047 * Lazy-load a filter |
|
2048 * |
|
2049 * @param array $filter |
|
2050 * @return Zend_Filter_Interface |
|
2051 */ |
|
2052 protected function _loadFilter(array $filter) |
|
2053 { |
|
2054 $origName = $filter['filter']; |
|
2055 $name = $this->getPluginLoader(self::FILTER)->load($filter['filter']); |
|
2056 |
|
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)); |
|
2060 } |
|
2061 |
|
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(); |
|
2070 } |
|
2071 } |
|
2072 |
|
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; |
|
2084 } |
|
2085 $filtersExchange[$key] = $this->_filters[$key]; |
|
2086 } |
|
2087 $this->_filters = $filtersExchange; |
|
2088 } else { |
|
2089 $this->_filters[$name] = $instance; |
|
2090 } |
|
2091 |
|
2092 return $instance; |
|
2093 } |
|
2094 |
|
2095 /** |
|
2096 * Lazy-load a validator |
|
2097 * |
|
2098 * @param array $validator Validator definition |
|
2099 * @return Zend_Validate_Interface |
|
2100 */ |
|
2101 protected function _loadValidator(array $validator) |
|
2102 { |
|
2103 $origName = $validator['validator']; |
|
2104 $name = $this->getPluginLoader(self::VALIDATE)->load($validator['validator']); |
|
2105 |
|
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)); |
|
2109 } |
|
2110 |
|
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']); |
|
2115 } |
|
2116 |
|
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; |
|
2129 } |
|
2130 } |
|
2131 } |
|
2132 |
|
2133 if ($numeric) { |
|
2134 $instance = $r->newInstanceArgs((array) $validator['options']); |
|
2135 } else { |
|
2136 $instance = $r->newInstance($validator['options']); |
|
2137 } |
|
2138 } else { |
|
2139 $instance = $r->newInstance(); |
|
2140 } |
|
2141 } |
|
2142 |
|
2143 if ($messages) { |
|
2144 if (is_array($messages)) { |
|
2145 $instance->setMessages($messages); |
|
2146 } elseif (is_string($messages)) { |
|
2147 $instance->setMessage($messages); |
|
2148 } |
|
2149 } |
|
2150 $instance->zfBreakChainOnFailure = $validator['breakChainOnFailure']; |
|
2151 |
|
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; |
|
2163 } |
|
2164 $validatorsExchange[$key] = $this->_validators[$key]; |
|
2165 } |
|
2166 $this->_validators = $validatorsExchange; |
|
2167 } else { |
|
2168 $this->_validators[$name] = $instance; |
|
2169 } |
|
2170 |
|
2171 return $instance; |
|
2172 } |
|
2173 |
|
2174 /** |
|
2175 * Lazy-load a decorator |
|
2176 * |
|
2177 * @param array $decorator Decorator type and options |
|
2178 * @param mixed $name Decorator name or alias |
|
2179 * @return Zend_Form_Decorator_Interface |
|
2180 */ |
|
2181 protected function _loadDecorator(array $decorator, $name) |
|
2182 { |
|
2183 $sameName = false; |
|
2184 if ($name == $decorator['decorator']) { |
|
2185 $sameName = true; |
|
2186 } |
|
2187 |
|
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; |
|
2201 } |
|
2202 $decoratorsExchange[$key] = $this->_decorators[$key]; |
|
2203 } |
|
2204 $this->_decorators = $decoratorsExchange; |
|
2205 } else { |
|
2206 $this->_decorators[$name] = $instance; |
|
2207 } |
|
2208 |
|
2209 return $instance; |
|
2210 } |
|
2211 |
|
2212 /** |
|
2213 * Retrieve error messages and perform translation and value substitution |
|
2214 * |
|
2215 * @return array |
|
2216 */ |
|
2217 protected function _getErrorMessages() |
|
2218 { |
|
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); |
|
2225 } |
|
2226 if (($this->isArray() || is_array($value)) |
|
2227 && !empty($value) |
|
2228 ) { |
|
2229 $aggregateMessages = array(); |
|
2230 foreach ($value as $val) { |
|
2231 $aggregateMessages[] = str_replace('%value%', $val, $message); |
|
2232 } |
|
2233 $messages[$key] = implode($this->getErrorMessageSeparator(), $aggregateMessages); |
|
2234 } else { |
|
2235 $messages[$key] = str_replace('%value%', $value, $message); |
|
2236 } |
|
2237 } |
|
2238 return $messages; |
|
2239 } |
|
2240 |
|
2241 /** |
|
2242 * Are there custom error messages registered? |
|
2243 * |
|
2244 * @return bool |
|
2245 */ |
|
2246 protected function _hasErrorMessages() |
|
2247 { |
|
2248 return !empty($this->_errorMessages); |
|
2249 } |
|
2250 } |