TYPO3 CMS  TYPO3_6-2
SelectViewHelper.php
Go to the documentation of this file.
1 <?php
3 
4 /* *
5  * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * The TYPO3 project - inspiring people to share! *
12  * */
59 
63  protected $tagName = 'select';
64 
68  protected $selectedValue = NULL;
69 
76  public function initializeArguments() {
77  parent::initializeArguments();
79  $this->registerTagAttribute('multiple', 'string', 'if set, multiple select field');
80  $this->registerTagAttribute('size', 'string', 'Size of input field');
81  $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
82  $this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', TRUE);
83  $this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.');
84  $this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.');
85  $this->registerArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, FALSE);
86  $this->registerArgument('selectAllByDefault', 'boolean', 'If specified options are selected if none was set before.', FALSE, FALSE);
87  $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
88  $this->registerArgument('prependOptionLabel', 'string', 'If specified, will provide an option at first position with the specified label.');
89  $this->registerArgument('prependOptionValue', 'string', 'If specified, will provide an option at first position with the specified value.');
90  }
91 
98  public function render() {
99  $name = $this->getName();
100  if ($this->hasArgument('multiple')) {
101  $name .= '[]';
102  }
103  $this->tag->addAttribute('name', $name);
104  $options = $this->getOptions();
105  if (empty($options)) {
106  $options = array('' => '');
107  }
108  $this->tag->setContent($this->renderOptionTags($options));
109  $this->setErrorClassAttribute();
110  $content = '';
111  // register field name for token generation.
112  // in case it is a multi-select, we need to register the field name
113  // as often as there are elements in the box
114  if ($this->hasArgument('multiple') && $this->arguments['multiple'] !== '') {
115  $content .= $this->renderHiddenFieldForEmptyValue();
116  for ($i = 0; $i < count($options); $i++) {
118  }
119  } else {
121  }
122  $content .= $this->tag->render();
123  return $content;
124  }
125 
132  protected function renderOptionTags($options) {
133  $output = '';
134  if ($this->hasArgument('prependOptionLabel')) {
135  $value = $this->hasArgument('prependOptionValue') ? $this->arguments['prependOptionValue'] : '';
136  $label = $this->arguments['prependOptionLabel'];
137  $output .= $this->renderOptionTag($value, $label, FALSE) . chr(10);
138  }
139  foreach ($options as $value => $label) {
140  $isSelected = $this->isSelected($value);
141  $output .= $this->renderOptionTag($value, $label, $isSelected) . chr(10);
142  }
143  return $output;
144  }
145 
151  protected function getOptions() {
152  if (!is_array($this->arguments['options']) && !$this->arguments['options'] instanceof \Traversable) {
153  return array();
154  }
155  $options = array();
156  $optionsArgument = $this->arguments['options'];
157  foreach ($optionsArgument as $key => $value) {
158  if (is_object($value)) {
159  if ($this->hasArgument('optionValueField')) {
160  $key = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionValueField']);
161  if (is_object($key)) {
162  if (method_exists($key, '__toString')) {
163  $key = (string) $key;
164  } else {
165  throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('Identifying value for object of class "' . get_class($value) . '" was an object.', 1247827428);
166  }
167  }
168  // TODO: use $this->persistenceManager->isNewObject() once it is implemented
169  } elseif ($this->persistenceManager->getIdentifierByObject($value) !== NULL) {
170  $key = $this->persistenceManager->getIdentifierByObject($value);
171  } elseif (method_exists($value, '__toString')) {
172  $key = (string) $value;
173  } else {
174  throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('No identifying value for object of class "' . get_class($value) . '" found.', 1247826696);
175  }
176  if ($this->hasArgument('optionLabelField')) {
177  $value = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionLabelField']);
178  if (is_object($value)) {
179  if (method_exists($value, '__toString')) {
180  $value = (string) $value;
181  } else {
182  throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('Label value for object of class "' . get_class($value) . '" was an object without a __toString() method.', 1247827553);
183  }
184  }
185  } elseif (method_exists($value, '__toString')) {
186  $value = (string) $value;
187  // TODO: use $this->persistenceManager->isNewObject() once it is implemented
188  } elseif ($this->persistenceManager->getIdentifierByObject($value) !== NULL) {
189  $value = $this->persistenceManager->getIdentifierByObject($value);
190  }
191  }
192  $options[$key] = $value;
193  }
194  if ($this->arguments['sortByOptionLabel']) {
195  asort($options, SORT_LOCALE_STRING);
196  }
197  return $options;
198  }
199 
206  protected function isSelected($value) {
207  $selectedValue = $this->getSelectedValue();
208  if ($value === $selectedValue || (string) $value === $selectedValue) {
209  return TRUE;
210  }
211  if ($this->hasArgument('multiple')) {
212  if (is_null($selectedValue) && $this->arguments['selectAllByDefault'] === TRUE) {
213  return TRUE;
214  } elseif (is_array($selectedValue) && in_array($value, $selectedValue)) {
215  return TRUE;
216  }
217  }
218  return FALSE;
219  }
220 
226  protected function getSelectedValue() {
227  $value = $this->getValue();
228  if (!is_array($value) && !$value instanceof \Traversable) {
229  return $this->getOptionValueScalar($value);
230  }
231  $selectedValues = array();
232  foreach ($value as $selectedValueElement) {
233  $selectedValues[] = $this->getOptionValueScalar($selectedValueElement);
234  }
235  return $selectedValues;
236  }
237 
244  protected function getOptionValueScalar($valueElement) {
245  if (is_object($valueElement)) {
246  if ($this->hasArgument('optionValueField')) {
247  return \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($valueElement, $this->arguments['optionValueField']);
248  } else {
249  // TODO: use $this->persistenceManager->isNewObject() once it is implemented
250  if ($this->persistenceManager->getIdentifierByObject($valueElement) !== NULL) {
251  return $this->persistenceManager->getIdentifierByObject($valueElement);
252  } else {
253  return (string) $valueElement;
254  }
255  }
256  } else {
257  return $valueElement;
258  }
259  }
260 
269  protected function renderOptionTag($value, $label, $isSelected) {
270  $output = '<option value="' . htmlspecialchars($value) . '"';
271  if ($isSelected) {
272  $output .= ' selected="selected"';
273  }
274  $output .= '>' . htmlspecialchars($label) . '</option>';
275  return $output;
276  }
277 }
registerTagAttribute($name, $type, $description, $required=FALSE, $default=NULL)
registerArgument($name, $type, $description, $required=FALSE, $defaultValue=NULL)
static getPropertyPath($subject, $propertyPath)