web/lib/Zend/Form.php
changeset 807 877f952ae2bd
parent 207 621fa6caec0c
child 1230 68c69c656a2c
equal deleted inserted replaced
805:5e7a0fedabdf 807:877f952ae2bd
    12  * obtain it through the world-wide-web, please send an email
    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.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_Form
    16  * @package    Zend_Form
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    17  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    19  */
    19  */
    20 
    20 
    21 /** @see Zend_Validate_Interface */
    21 /** @see Zend_Validate_Interface */
    22 require_once 'Zend/Validate/Interface.php';
    22 require_once 'Zend/Validate/Interface.php';
    24 /**
    24 /**
    25  * Zend_Form
    25  * Zend_Form
    26  *
    26  *
    27  * @category   Zend
    27  * @category   Zend
    28  * @package    Zend_Form
    28  * @package    Zend_Form
    29  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    29  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    30  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    30  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    31  * @version    $Id: Form.php 23429 2010-11-22 23:06:46Z bittarman $
    31  * @version    $Id: Form.php 25223 2013-01-17 14:44:54Z frosch $
    32  */
    32  */
    33 class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
    33 class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
    34 {
    34 {
    35     /**#@+
    35     /**#@+
    36      * Plugin loader type constants
    36      * Plugin loader type constants
   349         }
   349         }
   350 
   350 
   351         if (isset($options['attribs'])) {
   351         if (isset($options['attribs'])) {
   352             $this->addAttribs($options['attribs']);
   352             $this->addAttribs($options['attribs']);
   353             unset($options['attribs']);
   353             unset($options['attribs']);
       
   354         }
       
   355 
       
   356         if (isset($options['subForms'])) {
       
   357             $this->addSubForms($options['subForms']);
       
   358             unset($options['subForms']);
   354         }
   359         }
   355 
   360 
   356         $forbidden = array(
   361         $forbidden = array(
   357             'Options', 'Config', 'PluginLoader', 'SubForms', 'Translator',
   362             'Options', 'Config', 'PluginLoader', 'SubForms', 'Translator',
   358             'Attrib', 'Default',
   363             'Attrib', 'Default',
   493             case self::ELEMENT:
   498             case self::ELEMENT:
   494                 $loader = $this->getPluginLoader($type);
   499                 $loader = $this->getPluginLoader($type);
   495                 $loader->addPrefixPath($prefix, $path);
   500                 $loader->addPrefixPath($prefix, $path);
   496                 return $this;
   501                 return $this;
   497             case null:
   502             case null:
   498                 $prefix = rtrim($prefix, '_');
   503                 $nsSeparator = (false !== strpos($prefix, '\\'))?'\\':'_';
       
   504                 $prefix = rtrim($prefix, $nsSeparator);
   499                 $path   = rtrim($path, DIRECTORY_SEPARATOR);
   505                 $path   = rtrim($path, DIRECTORY_SEPARATOR);
   500                 foreach (array(self::DECORATOR, self::ELEMENT) as $type) {
   506                 foreach (array(self::DECORATOR, self::ELEMENT) as $type) {
   501                     $cType        = ucfirst(strtolower($type));
   507                     $cType        = ucfirst(strtolower($type));
   502                     $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
   508                     $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
   503                     $pluginPrefix = $prefix . '_' . $cType;
   509                     $pluginPrefix = $prefix . $nsSeparator . $cType;
   504                     $loader       = $this->getPluginLoader($type);
   510                     $loader       = $this->getPluginLoader($type);
   505                     $loader->addPrefixPath($pluginPrefix, $pluginPath);
   511                     $loader->addPrefixPath($pluginPrefix, $pluginPath);
   506                 }
   512                 }
   507                 return $this;
   513                 return $this;
   508             default:
   514             default:
  1011      * and any provided $options will be ignored.
  1017      * and any provided $options will be ignored.
  1012      *
  1018      *
  1013      * @param  string|Zend_Form_Element $element
  1019      * @param  string|Zend_Form_Element $element
  1014      * @param  string $name
  1020      * @param  string $name
  1015      * @param  array|Zend_Config $options
  1021      * @param  array|Zend_Config $options
       
  1022      * @throws Zend_Form_Exception on invalid element
  1016      * @return Zend_Form
  1023      * @return Zend_Form
  1017      */
  1024      */
  1018     public function addElement($element, $name = null, $options = null)
  1025     public function addElement($element, $name = null, $options = null)
  1019     {
  1026     {
  1020         if (is_string($element)) {
  1027         if (is_string($element)) {
  1021             if (null === $name) {
  1028             if (null === $name) {
  1022                 require_once 'Zend/Form/Exception.php';
  1029                 require_once 'Zend/Form/Exception.php';
  1023                 throw new Zend_Form_Exception('Elements specified by string must have an accompanying name');
  1030                 throw new Zend_Form_Exception(
  1024             }
  1031                     'Elements specified by string must have an accompanying name'
  1025 
  1032                 );
  1026             if (is_array($this->_elementDecorators)) {
       
  1027                 if (null === $options) {
       
  1028                     $options = array('decorators' => $this->_elementDecorators);
       
  1029                 } elseif ($options instanceof Zend_Config) {
       
  1030                     $options = $options->toArray();
       
  1031                 }
       
  1032                 if (is_array($options)
       
  1033                     && !array_key_exists('decorators', $options)
       
  1034                 ) {
       
  1035                     $options['decorators'] = $this->_elementDecorators;
       
  1036                 }
       
  1037             }
  1033             }
  1038 
  1034 
  1039             $this->_elements[$name] = $this->createElement($element, $name, $options);
  1035             $this->_elements[$name] = $this->createElement($element, $name, $options);
  1040         } elseif ($element instanceof Zend_Form_Element) {
  1036         } elseif ($element instanceof Zend_Form_Element) {
  1041             $prefixPaths              = array();
  1037             $prefixPaths              = array();
  1042             $prefixPaths['decorator'] = $this->getPluginLoader('decorator')->getPaths();
  1038             $prefixPaths['decorator'] = $this->getPluginLoader('decorator')->getPaths();
  1043             if (!empty($this->_elementPrefixPaths)) {
  1039             if (!empty($this->_elementPrefixPaths)) {
  1044                 $prefixPaths = array_merge($prefixPaths, $this->_elementPrefixPaths);
  1040                 $prefixPaths = array_merge($prefixPaths, $this->_elementPrefixPaths);
  1045             }
  1041             }
  1046 
  1042 
       
  1043             if (is_array($this->_elementDecorators)
       
  1044                 && 0 == count($element->getDecorators())
       
  1045             ) {
       
  1046                 $element->setDecorators($this->_elementDecorators);
       
  1047             }
       
  1048 
  1047             if (null === $name) {
  1049             if (null === $name) {
  1048                 $name = $element->getName();
  1050                 $name = $element->getName();
  1049             }
  1051             }
  1050 
  1052 
  1051             $this->_elements[$name] = $element;
  1053             $this->_elements[$name] = $element;
  1052             $this->_elements[$name]->addPrefixPaths($prefixPaths);
  1054             $this->_elements[$name]->addPrefixPaths($prefixPaths);
       
  1055         } else {
       
  1056             require_once 'Zend/Form/Exception.php';
       
  1057             throw new Zend_Form_Exception(
       
  1058                 'Element must be specified by string or Zend_Form_Element instance'
       
  1059             );
  1053         }
  1060         }
  1054 
  1061 
  1055         $this->_order[$name] = $this->_elements[$name]->getOrder();
  1062         $this->_order[$name] = $this->_elements[$name]->getOrder();
  1056         $this->_orderUpdated = true;
  1063         $this->_orderUpdated = true;
  1057         $this->_setElementsBelongTo($name);
  1064         $this->_setElementsBelongTo($name);
  1094             $options = $options->toArray();
  1101             $options = $options->toArray();
  1095         }
  1102         }
  1096 
  1103 
  1097         if ((null === $options) || !is_array($options)) {
  1104         if ((null === $options) || !is_array($options)) {
  1098             $options = array('prefixPath' => $prefixPaths);
  1105             $options = array('prefixPath' => $prefixPaths);
       
  1106 
       
  1107             if (is_array($this->_elementDecorators)) {
       
  1108                 $options['decorators'] = $this->_elementDecorators;
       
  1109             }
  1099         } elseif (is_array($options)) {
  1110         } elseif (is_array($options)) {
  1100             if (array_key_exists('prefixPath', $options)) {
  1111             if (array_key_exists('prefixPath', $options)) {
  1101                 $options['prefixPath'] = array_merge($prefixPaths, $options['prefixPath']);
  1112                 $options['prefixPath'] = array_merge($prefixPaths, $options['prefixPath']);
  1102             } else {
  1113             } else {
  1103                 $options['prefixPath'] = $prefixPaths;
  1114                 $options['prefixPath'] = $prefixPaths;
       
  1115             }
       
  1116 
       
  1117             if (is_array($this->_elementDecorators)
       
  1118                 && !array_key_exists('decorators', $options)
       
  1119             ) {
       
  1120                 $options['decorators'] = $this->_elementDecorators;
  1104             }
  1121             }
  1105         }
  1122         }
  1106 
  1123 
  1107         $class = $this->getPluginLoader(self::ELEMENT)->load($type);
  1124         $class = $this->getPluginLoader(self::ELEMENT)->load($type);
  1108         $element = new $class($name, $options);
  1125         $element = new $class($name, $options);
  1338      */
  1355      */
  1339     public function getValues($suppressArrayNotation = false)
  1356     public function getValues($suppressArrayNotation = false)
  1340     {
  1357     {
  1341         $values = array();
  1358         $values = array();
  1342         $eBelongTo = null;
  1359         $eBelongTo = null;
  1343         
  1360 
  1344         if ($this->isArray()) {
  1361         if ($this->isArray()) {
  1345             $eBelongTo = $this->getElementsBelongTo();
  1362             $eBelongTo = $this->getElementsBelongTo();
  1346         }
  1363         }
  1347         
  1364 
  1348         foreach ($this->getElements() as $key => $element) {
  1365         foreach ($this->getElements() as $key => $element) {
  1349             if (!$element->getIgnore()) {
  1366             if (!$element->getIgnore()) {
  1350                 $merge = array();
  1367                 $merge = array();
  1351                 if (($belongsTo = $element->getBelongsTo()) !== $eBelongTo) {
  1368                 if (($belongsTo = $element->getBelongsTo()) !== $eBelongTo) {
  1352                     if ('' !== (string)$belongsTo) {
  1369                     if ('' !== (string)$belongsTo) {
  1635      * @param  array $subForms
  1652      * @param  array $subForms
  1636      * @return Zend_Form
  1653      * @return Zend_Form
  1637      */
  1654      */
  1638     public function addSubForms(array $subForms)
  1655     public function addSubForms(array $subForms)
  1639     {
  1656     {
  1640         foreach ($subForms as $key => $spec) {
  1657         foreach ($subForms as $key => $spec) {          
  1641             $name = null;
  1658             $name = (string) $key;
  1642             if (!is_numeric($key)) {
       
  1643                 $name = $key;
       
  1644             }
       
  1645 
       
  1646             if ($spec instanceof Zend_Form) {
  1659             if ($spec instanceof Zend_Form) {
  1647                 $this->addSubForm($spec, $name);
  1660                 $this->addSubForm($spec, $name);
  1648                 continue;
  1661                 continue;
  1649             }
  1662             }
  1650 
  1663 
  1654                 switch ($argc) {
  1667                 switch ($argc) {
  1655                     case 0:
  1668                     case 0:
  1656                         continue;
  1669                         continue;
  1657                     case (1 <= $argc):
  1670                     case (1 <= $argc):
  1658                         $subForm = array_shift($spec);
  1671                         $subForm = array_shift($spec);
       
  1672 
       
  1673                         if (!$subForm instanceof Zend_Form) {
       
  1674                             $subForm = new Zend_Form_SubForm($subForm);
       
  1675                         }
  1659                     case (2 <= $argc):
  1676                     case (2 <= $argc):
  1660                         $name  = array_shift($spec);
  1677                         $name  = array_shift($spec);
  1661                     case (3 <= $argc):
  1678                     case (3 <= $argc):
  1662                         $order = array_shift($spec);
  1679                         $order = array_shift($spec);
  1663                     default:
  1680                     default:
  1784     public function addDisplayGroup(array $elements, $name, $options = null)
  1801     public function addDisplayGroup(array $elements, $name, $options = null)
  1785     {
  1802     {
  1786         $group = array();
  1803         $group = array();
  1787         foreach ($elements as $element) {
  1804         foreach ($elements as $element) {
  1788             if($element instanceof Zend_Form_Element) {
  1805             if($element instanceof Zend_Form_Element) {
  1789                 $element = $element->getId();
  1806                 $elementName = $element->getName();
       
  1807                 if (!isset($this->_elements[$elementName])) {
       
  1808                     $this->addElement($element);
       
  1809                 }
       
  1810                 $element = $elementName;
  1790             }
  1811             }
  1791 
  1812 
  1792             if (isset($this->_elements[$element])) {
  1813             if (isset($this->_elements[$element])) {
  1793                 $add = $this->getElement($element);
  1814                 $add = $this->getElement($element);
  1794                 if (null !== $add) {
  1815                 if (null !== $add) {
  2100 
  2121 
  2101     /**
  2122     /**
  2102      * Given an array, an optional arrayPath and a key this method
  2123      * Given an array, an optional arrayPath and a key this method
  2103      * dissolves the arrayPath and unsets the key within the array
  2124      * dissolves the arrayPath and unsets the key within the array
  2104      * if it exists.
  2125      * if it exists.
  2105      * 
  2126      *
  2106      * @param array $array 
  2127      * @param array $array
  2107      * @param string|null $arrayPath
  2128      * @param string|null $arrayPath
  2108      * @param string $key
  2129      * @param string $key
  2109      * @return array
  2130      * @return array
  2110      */
  2131      */
  2111     protected function _dissolveArrayUnsetKey($array, $arrayPath, $key)
  2132     protected function _dissolveArrayUnsetKey($array, $arrayPath, $key)
  2112     {
  2133     {
  2113         $unset =& $array;
  2134         $unset =& $array;
  2114         $path  = trim(strtr((string)$arrayPath, array('[' => '/', ']' => '')), '/');
  2135         $path  = trim(strtr((string)$arrayPath, array('[' => '/', ']' => '')), '/');
  2115         $segs  = ('' !== $path) ? explode('/', $path) : array();
  2136         $segs  = ('' !== $path) ? explode('/', $path) : array();
  2116         
  2137 
  2117         foreach ($segs as $seg) {
  2138         foreach ($segs as $seg) {
  2118             if (!array_key_exists($seg, (array)$unset)) {
  2139             if (!array_key_exists($seg, (array)$unset)) {
  2119                 return $array;
  2140                 return $array;
  2120             }
  2141             }
  2121             $unset =& $unset[$seg];
  2142             $unset =& $unset[$seg];
  2157      * Elements, SubForms and Elements from DisplayGroups as Values.
  2178      * Elements, SubForms and Elements from DisplayGroups as Values.
  2158      *
  2179      *
  2159      * Subitems are inserted based on their order Setting if set,
  2180      * Subitems are inserted based on their order Setting if set,
  2160      * otherwise they are appended, the resulting numerical index
  2181      * otherwise they are appended, the resulting numerical index
  2161      * may differ from the order value.
  2182      * may differ from the order value.
  2162      * 
  2183      *
  2163      * @access protected
  2184      * @access protected
  2164      * @return array 
  2185      * @return array
  2165      */
  2186      */
  2166     public function getElementsAndSubFormsOrdered()
  2187     public function getElementsAndSubFormsOrdered()
  2167     {
  2188     {
  2168         $ordered = array();
  2189         $ordered = array();
  2169         foreach ($this->_order as $name => $order) {
  2190         foreach ($this->_order as $name => $order) {
  2185         }
  2206         }
  2186         return $ordered;
  2207         return $ordered;
  2187     }
  2208     }
  2188 
  2209 
  2189     /**
  2210     /**
  2190      * This is a helper function until php 5.3 is widespreaded 
  2211      * This is a helper function until php 5.3 is widespreaded
  2191      * 
  2212      *
  2192      * @param array $into
  2213      * @param array $into
  2193      * @access protected
  2214      * @access protected
  2194      * @return void
  2215      * @return void
  2195      */
  2216      */
  2196     protected function _array_replace_recursive(array $into)
  2217     protected function _array_replace_recursive(array $into)
  2248                 $valid = $element->isValid($check[$key], $context) && $valid;
  2269                 $valid = $element->isValid($check[$key], $context) && $valid;
  2249                 $data = $this->_dissolveArrayUnsetKey($data, $belongsTo, $key);
  2270                 $data = $this->_dissolveArrayUnsetKey($data, $belongsTo, $key);
  2250             }
  2271             }
  2251         }
  2272         }
  2252         foreach ($this->getSubForms() as $key => $form) {
  2273         foreach ($this->getSubForms() as $key => $form) {
  2253             if (null !== $translator && !$form->hasTranslator()) {
  2274             if (null !== $translator && $this->hasTranslator()
       
  2275                     && !$form->hasTranslator()) {
  2254                 $form->setTranslator($translator);
  2276                 $form->setTranslator($translator);
  2255             }
  2277             }
  2256             if (isset($data[$key]) && !$form->isArray()) {
  2278             if (isset($data[$key]) && !$form->isArray()) {
  2257                 $valid = $form->isValid($data[$key]) && $valid;
  2279                 $valid = $form->isValid($data[$key]) && $valid;
  2258             } else {
  2280             } else {
  2455     }
  2477     }
  2456 
  2478 
  2457     /**
  2479     /**
  2458      * Are there errors in the form?
  2480      * Are there errors in the form?
  2459      *
  2481      *
       
  2482      * @deprecated since 1.11.1 - use hasErrors() instead
  2460      * @return bool
  2483      * @return bool
  2461      */
  2484      */
  2462     public function isErrors()
  2485     public function isErrors()
       
  2486     {
       
  2487         return $this->hasErrors();
       
  2488     }
       
  2489 
       
  2490     /**
       
  2491      * Are there errors in the form?
       
  2492      *
       
  2493      * @return bool
       
  2494      */
       
  2495     public function hasErrors()
  2463     {
  2496     {
  2464         return $this->_errorsExist;
  2497         return $this->_errorsExist;
  2465     }
  2498     }
  2466 
  2499 
  2467     /**
  2500     /**
  2478                 return $this->getElement($name)->getErrors();
  2511                 return $this->getElement($name)->getErrors();
  2479             } else if (isset($this->_subForms[$name])) {
  2512             } else if (isset($this->_subForms[$name])) {
  2480                 return $this->getSubForm($name)->getErrors(null, true);
  2513                 return $this->getSubForm($name)->getErrors(null, true);
  2481             }
  2514             }
  2482         }
  2515         }
  2483         
  2516 
  2484         foreach ($this->_elements as $key => $element) {
  2517         foreach ($this->_elements as $key => $element) {
  2485             $errors[$key] = $element->getErrors();
  2518             $errors[$key] = $element->getErrors();
  2486         }
  2519         }
  2487         foreach ($this->getSubForms() as $key => $subForm) {
  2520         foreach ($this->getSubForms() as $key => $subForm) {
  2488             $merge = array();
  2521             $merge = array();
  2566     }
  2599     }
  2567 
  2600 
  2568     /**
  2601     /**
  2569      * Retrieve translated custom error messages
  2602      * Retrieve translated custom error messages
  2570      * Proxies to {@link _getErrorMessages()}.
  2603      * Proxies to {@link _getErrorMessages()}.
  2571      * 
  2604      *
  2572      * @return array
  2605      * @return array
  2573      */
  2606      */
  2574     public function getCustomMessages()
  2607     public function getCustomMessages()
  2575     {
  2608     {
  2576         return $this->_getErrorMessages();
  2609         return $this->_getErrorMessages();
  2983             return self::getDefaultTranslator();
  3016             return self::getDefaultTranslator();
  2984         }
  3017         }
  2985 
  3018 
  2986         return $this->_translator;
  3019         return $this->_translator;
  2987     }
  3020     }
  2988     
  3021 
  2989     /**
  3022     /**
  2990      * Does this form have its own specific translator?
  3023      * Does this form have its own specific translator?
  2991      * 
  3024      *
  2992      * @return bool
  3025      * @return bool
  2993      */
  3026      */
  2994     public function hasTranslator()
  3027     public function hasTranslator()
  2995     {
  3028     {
  2996         return (bool)$this->_translator;
  3029         return (bool)$this->_translator;
  2997     }    
  3030     }
  2998 
  3031 
  2999     /**
  3032     /**
  3000      * Get global default translator object
  3033      * Get global default translator object
  3001      *
  3034      *
  3002      * @return null|Zend_Translate
  3035      * @return null|Zend_Translate
  3017         return self::$_translatorDefault;
  3050         return self::$_translatorDefault;
  3018     }
  3051     }
  3019 
  3052 
  3020     /**
  3053     /**
  3021      * Is there a default translation object set?
  3054      * Is there a default translation object set?
  3022      * 
  3055      *
  3023      * @return boolean
  3056      * @return boolean
  3024      */
  3057      */
  3025     public static function hasDefaultTranslator()
  3058     public static function hasDefaultTranslator()
  3026     { 
  3059     {
  3027         return (bool)self::$_translatorDefault;
  3060         return (bool)self::$_translatorDefault;
  3028     }
  3061     }
  3029     
  3062 
  3030     /**
  3063     /**
  3031      * Indicate whether or not translation should be disabled
  3064      * Indicate whether or not translation should be disabled
  3032      *
  3065      *
  3033      * @param  bool $flag
  3066      * @param  bool $flag
  3034      * @return Zend_Form
  3067      * @return Zend_Form
  3270     }
  3303     }
  3271 
  3304 
  3272     /**
  3305     /**
  3273      * Load the default decorators
  3306      * Load the default decorators
  3274      *
  3307      *
  3275      * @return void
  3308      * @return Zend_Form
  3276      */
  3309      */
  3277     public function loadDefaultDecorators()
  3310     public function loadDefaultDecorators()
  3278     {
  3311     {
  3279         if ($this->loadDefaultDecoratorsIsDisabled()) {
  3312         if ($this->loadDefaultDecoratorsIsDisabled()) {
  3280             return $this;
  3313             return $this;
  3289         return $this;
  3322         return $this;
  3290     }
  3323     }
  3291 
  3324 
  3292     /**
  3325     /**
  3293      * Remove an element from iteration
  3326      * Remove an element from iteration
  3294      * 
  3327      *
  3295      * @param  string $name Element/group/form name
  3328      * @param  string $name Element/group/form name
  3296      * @return void
  3329      * @return void
  3297      */
  3330      */
  3298     public function removeFromIteration($name)
  3331     public function removeFromIteration($name)
  3299     {
  3332     {