|
TYPO3 API
SVNRelease
|
00001 <?php 00002 00003 /* * 00004 * This script belongs to the FLOW3 package "Fluid". * 00005 * * 00006 * It is free software; you can redistribute it and/or modify it under * 00007 * the terms of the GNU Lesser General Public License as published by the * 00008 * Free Software Foundation, either version 3 of the License, or (at your * 00009 * option) any later version. * 00010 * * 00011 * This script is distributed in the hope that it will be useful, but * 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- * 00013 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00014 * General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with the script. * 00018 * If not, see http://www.gnu.org/licenses/lgpl.html * 00019 * * 00020 * The TYPO3 project - inspiring people to share! * 00021 * */ 00022 00023 /** 00024 * This view helper generates a <select> dropdown list for the use with a form. 00025 * 00026 * = Basic usage = 00027 * 00028 * The most straightforward way is to supply an associative array as the "options" parameter. 00029 * The array key is used as option key, and the value is used as human-readable name. 00030 * 00031 * <code title="Basic usage"> 00032 * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" /> 00033 * </code> 00034 * 00035 * = Pre-select a value = 00036 * 00037 * To pre-select a value, set "value" to the option key which should be selected. 00038 * <code title="Default value"> 00039 * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" value="visa" /> 00040 * </code> 00041 * Generates a dropdown box like above, except that "VISA Card" is selected. 00042 * 00043 * If the select box is a multi-select box (multiple="true"), then "value" can be an array as well. 00044 * 00045 * = Usage on domain objects = 00046 * 00047 * If you want to output domain objects, you can just pass them as array into the "options" parameter. 00048 * To define what domain object value should be used as option key, use the "optionValueField" variable. Same goes for optionLabelField. 00049 * If neither is given, the Identifier (UID/uid) and the __toString() method are tried as fallbacks. 00050 * 00051 * If the optionValueField variable is set, the getter named after that value is used to retrieve the option key. 00052 * If the optionLabelField variable is set, the getter named after that value is used to retrieve the option value. 00053 * 00054 * <code title="Domain objects"> 00055 * <f:form.select name="users" options="{userArray}" optionValueField="id" optionLabelField="firstName" /> 00056 * </code> 00057 * In the above example, the userArray is an array of "User" domain objects, with no array key specified. 00058 * 00059 * So, in the above example, the method $user->getId() is called to retrieve the key, and $user->getFirstName() to retrieve the displayed value of each entry. 00060 * 00061 * The "value" property now expects a domain object, and tests for object equivalence. 00062 * 00063 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later 00064 * @api 00065 */ 00066 class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper { 00067 00068 /** 00069 * @var string 00070 */ 00071 protected $tagName = 'select'; 00072 00073 /** 00074 * @var mixed the selected value 00075 */ 00076 protected $selectedValue = NULL; 00077 00078 /** 00079 * Initialize arguments. 00080 * 00081 * @return void 00082 * @author Sebastian Kurfürst <sebastian@typo3.org> 00083 * @api 00084 */ 00085 public function initializeArguments() { 00086 parent::initializeArguments(); 00087 $this->registerUniversalTagAttributes(); 00088 $this->registerTagAttribute('multiple', 'string', 'if set, multiple select field'); 00089 $this->registerTagAttribute('size', 'string', 'Size of input field'); 00090 $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads'); 00091 $this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', TRUE); 00092 $this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.'); 00093 $this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.'); 00094 $this->registerArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, FALSE); 00095 $this->registerArgument('selectAllByDefault', 'boolean', 'If specified options are selected if none was set before.', FALSE, FALSE); 00096 $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error'); 00097 } 00098 00099 /** 00100 * Render the tag. 00101 * 00102 * @return string rendered tag. 00103 * @author Sebastian Kurfürst <sebastian@typo3.org> 00104 * @author Bastian Waidelich <bastian@typo3.org> 00105 * @api 00106 */ 00107 public function render() { 00108 $name = $this->getName(); 00109 if ($this->arguments->hasArgument('multiple')) { 00110 $name .= '[]'; 00111 } 00112 00113 $this->tag->addAttribute('name', $name); 00114 00115 $options = $this->getOptions(); 00116 if (empty($options)) { 00117 $options = array('' => ''); 00118 } 00119 $this->tag->setContent($this->renderOptionTags($options)); 00120 00121 $this->setErrorClassAttribute(); 00122 00123 $content = ''; 00124 00125 // register field name for token generation. 00126 // in case it is a multi-select, we need to register the field name 00127 // as often as there are elements in the box 00128 if ($this->arguments->hasArgument('multiple') && $this->arguments['multiple'] !== '') { 00129 $content .= $this->renderHiddenFieldForEmptyValue(); 00130 for ($i=0; $i<count($options); $i++) { 00131 $this->registerFieldNameForFormTokenGeneration($name); 00132 } 00133 } else { 00134 $this->registerFieldNameForFormTokenGeneration($name); 00135 } 00136 00137 $content .= $this->tag->render(); 00138 return $content; 00139 } 00140 00141 /** 00142 * Render the option tags. 00143 * 00144 * @param array $options the options for the form. 00145 * @return string rendered tags. 00146 * @author Bastian Waidelich <bastian@typo3.org> 00147 */ 00148 protected function renderOptionTags($options) { 00149 $output = ''; 00150 00151 foreach ($options as $value => $label) { 00152 $isSelected = $this->isSelected($value); 00153 $output.= $this->renderOptionTag($value, $label, $isSelected) . chr(10); 00154 } 00155 return $output; 00156 } 00157 00158 /** 00159 * Render the option tags. 00160 * 00161 * @return array an associative array of options, key will be the value of the option tag 00162 * @author Bastian Waidelich <bastian@typo3.org> 00163 * @author Karsten Dambekalns <karsten@typo3.org> 00164 */ 00165 protected function getOptions() { 00166 if (!is_array($this->arguments['options']) && !($this->arguments['options'] instanceof Traversable)) { 00167 return array(); 00168 } 00169 $options = array(); 00170 $optionsArgument = $this->arguments['options']; 00171 foreach ($optionsArgument as $key => $value) { 00172 if (is_object($value)) { 00173 00174 if ($this->arguments->hasArgument('optionValueField')) { 00175 $key = Tx_Extbase_Reflection_ObjectAccess::getProperty($value, $this->arguments['optionValueField']); 00176 if (is_object($key)) { 00177 if (method_exists($key, '__toString')) { 00178 $key = (string)$key; 00179 } else { 00180 throw new Tx_Fluid_Core_ViewHelper_Exception('Identifying value for object of class "' . get_class($value) . '" was an object.' , 1247827428); 00181 } 00182 } 00183 } elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) { 00184 $key = $this->persistenceManager->getBackend()->getIdentifierByObject($value); 00185 } elseif (method_exists($value, '__toString')) { 00186 $key = (string)$value; 00187 } else { 00188 throw new Tx_Fluid_Core_ViewHelper_Exception('No identifying value for object of class "' . get_class($value) . '" found.' , 1247826696); 00189 } 00190 00191 if ($this->arguments->hasArgument('optionLabelField')) { 00192 $value = Tx_Extbase_Reflection_ObjectAccess::getProperty($value, $this->arguments['optionLabelField']); 00193 if (is_object($value)) { 00194 if (method_exists($value, '__toString')) { 00195 $value = (string)$value; 00196 } else { 00197 throw new Tx_Fluid_Core_ViewHelper_Exception('Label value for object of class "' . get_class($value) . '" was an object without a __toString() method.' , 1247827553); 00198 } 00199 } 00200 } elseif (method_exists($value, '__toString')) { 00201 $value = (string)$value; 00202 } elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) { 00203 $value = $this->persistenceManager->getBackend()->getIdentifierByObject($value); 00204 } 00205 } 00206 $options[$key] = $value; 00207 } 00208 if ($this->arguments['sortByOptionLabel']) { 00209 asort($options); 00210 } 00211 return $options; 00212 } 00213 00214 /** 00215 * Render the option tags. 00216 * 00217 * @return boolean TRUE if the value should be marked a s selected; FALSE otherwise 00218 * @author Bastian Waidelich <bastian@typo3.org> 00219 * @author Jochen Rau <jochen.rau@typoplanet.de> 00220 */ 00221 protected function isSelected($value) { 00222 $selectedValue = $this->getSelectedValue(); 00223 if ($value === $selectedValue || (string)$value === $selectedValue) { 00224 return TRUE; 00225 } 00226 if ($this->arguments->hasArgument('multiple')) { 00227 if (is_null($selectedValue) && $this->arguments['selectAllByDefault'] === TRUE) { 00228 return TRUE; 00229 } elseif (is_array($selectedValue) && in_array($value, $selectedValue)) { 00230 return TRUE; 00231 } 00232 } 00233 return FALSE; 00234 } 00235 00236 /** 00237 * Retrieves the selected value(s) 00238 * 00239 * @return mixed value string or an array of strings 00240 * @author Bastian Waidelich <bastian@typo3.org> 00241 */ 00242 protected function getSelectedValue() { 00243 $value = $this->getValue(); 00244 if (!$this->arguments->hasArgument('optionValueField')) { 00245 return $value; 00246 } 00247 if (!is_array($value) && !($value instanceof Iterator)) { 00248 if (is_object($value)) { 00249 return Tx_Extbase_Reflection_ObjectAccess::getProperty($value, $this->arguments['optionValueField']); 00250 } else { 00251 return $value; 00252 } 00253 } 00254 $selectedValues = array(); 00255 foreach($value as $selectedValueElement) { 00256 if (is_object($selectedValueElement)) { 00257 $selectedValues[] = Tx_Extbase_Reflection_ObjectAccess::getProperty($selectedValueElement, $this->arguments['optionValueField']); 00258 } else { 00259 $selectedValues[] = $selectedValueElement; 00260 } 00261 } 00262 return $selectedValues; 00263 } 00264 00265 /** 00266 * Render one option tag 00267 * 00268 * @param string $value value attribute of the option tag (will be escaped) 00269 * @param string $label content of the option tag (will be escaped) 00270 * @param boolean $isSelected specifies wheter or not to add selected attribute 00271 * @return string the rendered option tag 00272 * @author Bastian Waidelich <bastian@typo3.org> 00273 */ 00274 protected function renderOptionTag($value, $label, $isSelected) { 00275 $output = '<option value="' . htmlspecialchars($value) . '"'; 00276 if ($isSelected) { 00277 $output.= ' selected="selected"'; 00278 } 00279 $output.= '>' . htmlspecialchars($label) . '</option>'; 00280 00281 return $output; 00282 } 00283 } 00284 00285 ?>
1.8.0