Advertisement
Guest User

Untitled

a guest
May 21st, 2012
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.96 KB | None | 0 0
  1. <?php
  2. namespace TYPO3\Fluid\ViewHelpers\Form;
  3.  
  4. /* *
  5. * This script belongs to the FLOW3 package "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. * */
  13.  
  14. /**
  15. * Modified by Michel Albers 21.05.2012
  16. * Added prepend and append arguments
  17. */
  18.  
  19. /**
  20. * This view helper generates a <select> dropdown list for the use with a form.
  21. *
  22. * = Basic usage =
  23. *
  24. * The most straightforward way is to supply an associative array as the "options" parameter.
  25. * The array key is used as option key, and the value is used as human-readable name.
  26. *
  27. * <code title="Basic usage">
  28. * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" />
  29. * </code>
  30. *
  31. * = Pre-select a value =
  32. *
  33. * To pre-select a value, set "value" to the option key which should be selected.
  34. * <code title="Default value">
  35. * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" value="visa" />
  36. * </code>
  37. * Generates a dropdown box like above, except that "VISA Card" is selected.
  38. *
  39. * If the select box is a multi-select box (multiple="true"), then "value" can be an array as well.
  40. *
  41. * = Usage on domain objects =
  42. *
  43. * If you want to output domain objects, you can just pass them as array into the "options" parameter.
  44. * To define what domain object value should be used as option key, use the "optionValueField" variable. Same goes for optionLabelField.
  45. * If neither is given, the Identifier (UUID/uid) and the __toString() method are tried as fallbacks.
  46. *
  47. * If the optionValueField variable is set, the getter named after that value is used to retrieve the option key.
  48. * If the optionLabelField variable is set, the getter named after that value is used to retrieve the option value.
  49. *
  50. * <code title="Domain objects">
  51. * <f:form.select name="users" options="{userArray}" optionValueField="id" optionLabelField="firstName" />
  52. * </code>
  53. * In the above example, the userArray is an array of "User" domain objects, with no array key specified.
  54. *
  55. * 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.
  56. *
  57. * The "value" property now expects a domain object, and tests for object equivalence.
  58. *
  59. * @api
  60. */
  61. class TbselectViewHelper extends \TYPO3\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper {
  62.  
  63. /**
  64. * @var string
  65. */
  66. protected $tagName = 'select';
  67.  
  68. /**
  69. * @var mixed
  70. */
  71. protected $selectedValue = NULL;
  72.  
  73. /**
  74. * Initialize arguments.
  75. *
  76. * @return void
  77. * @api
  78. */
  79. public function initializeArguments() {
  80. parent::initializeArguments();
  81. $this->registerUniversalTagAttributes();
  82. $this->registerTagAttribute('multiple', 'string', 'if set, multiple select field');
  83. $this->registerTagAttribute('size', 'string', 'Size of input field');
  84. $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
  85. $this->registerArgument('prepend','array','Values before options list',FALSE);
  86. $this->registerArgument('append','array','Values after options list',FALSE);
  87. $this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', TRUE);
  88. $this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.');
  89. $this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.');
  90. $this->registerArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, FALSE);
  91. $this->registerArgument('selectAllByDefault', 'boolean', 'If specified options are selected if none was set before.', FALSE, FALSE);
  92. $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
  93. }
  94.  
  95. /**
  96. * Render the tag.
  97. *
  98. * @return string rendered tag.
  99. * @api
  100. */
  101. public function render() {
  102. $name = $this->getName();
  103. if ($this->hasArgument('multiple')) {
  104. $name .= '[]';
  105. }
  106.  
  107. $this->tag->addAttribute('name', $name);
  108.  
  109. $options = $this->getOptions();
  110. if (empty($options)) {
  111. $options = array('' => '');
  112. }
  113. $this->tag->setContent($this->renderOptionTags($options));
  114.  
  115. $this->setErrorClassAttribute();
  116.  
  117. $content = '';
  118.  
  119. // register field name for token generation.
  120. // in case it is a multi-select, we need to register the field name
  121. // as often as there are elements in the box
  122. if ($this->hasArgument('multiple') && $this->arguments['multiple'] !== '') {
  123. $content .= $this->renderHiddenFieldForEmptyValue();
  124. for ($i=0; $i<count($options); $i++) {
  125. $this->registerFieldNameForFormTokenGeneration($name);
  126. }
  127. } else {
  128. $this->registerFieldNameForFormTokenGeneration($name);
  129. }
  130.  
  131. $content .= $this->tag->render();
  132. return $content;
  133. }
  134.  
  135. /**
  136. * Render the option tags.
  137. *
  138. * @param array $options the options for the form.
  139. * @return string rendered tags.
  140. */
  141. protected function renderOptionTags($options) {
  142. $output = '';
  143.  
  144. foreach ($options as $value => $label) {
  145. $isSelected = $this->isSelected($value);
  146. $output.= $this->renderOptionTag($value, $label, $isSelected) . chr(10);
  147. }
  148. return $output;
  149. }
  150.  
  151. /**
  152. * Render the option tags.
  153. *
  154. * @return array an associative array of options, key will be the value of the option tag
  155. */
  156. protected function getOptions() {
  157. if (!is_array($this->arguments['options']) && !($this->arguments['options'] instanceof \Traversable)) {
  158. return array();
  159. }
  160. $options = array();
  161. $optionsArgument = $this->arguments['options'];
  162. foreach ($optionsArgument as $key => $value) {
  163. if (is_object($value)) {
  164.  
  165. if ($this->hasArgument('optionValueField')) {
  166. $key = \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionValueField']);
  167. if (is_object($key)) {
  168. if (method_exists($key, '__toString')) {
  169. $key = (string)$key;
  170. } else {
  171. throw new \TYPO3\Fluid\Core\ViewHelper\Exception('Identifying value for object of class "' . get_class($value) . '" was an object.' , 1247827428);
  172. }
  173. }
  174. } elseif ($this->persistenceManager->getIdentifierByObject($value) !== NULL) {
  175. $key = $this->persistenceManager->getIdentifierByObject($value);
  176. } elseif (method_exists($value, '__toString')) {
  177. $key = (string)$value;
  178. } else {
  179. throw new \TYPO3\Fluid\Core\ViewHelper\Exception('No identifying value for object of class "' . get_class($value) . '" found.' , 1247826696);
  180. }
  181.  
  182. if ($this->hasArgument('optionLabelField')) {
  183. $value = \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionLabelField']);
  184. if (is_object($value)) {
  185. if (method_exists($value, '__toString')) {
  186. $value = (string)$value;
  187. } else {
  188. throw new \TYPO3\Fluid\Core\ViewHelper\Exception('Label value for object of class "' . get_class($value) . '" was an object without a __toString() method.' , 1247827553);
  189. }
  190. }
  191. } elseif (method_exists($value, '__toString')) {
  192. $value = (string)$value;
  193. } elseif ($this->persistenceManager->getIdentifierByObject($value) !== NULL) {
  194. $value = $this->persistenceManager->getIdentifierByObject($value);
  195. }
  196. }
  197. $options[$key] = $value;
  198. }
  199. if ($this->arguments['sortByOptionLabel']) {
  200. asort($options);
  201. }
  202.  
  203. /* Prepend and Append */
  204. if(!empty($this->arguments['prepend'])) {
  205. $options = array_merge($this->parsePrependAppend($this->arguments['prepend']),$options);
  206. }
  207.  
  208. if(!empty($this->arguments['append'])) {
  209. $options = array_merge($options,$this->parsePrependAppend($this->arguments['append']));
  210. }
  211.  
  212. return $options;
  213. }
  214.  
  215. /**
  216. * Parse the prepend / append arrays
  217. * @return array
  218. */
  219. protected function parsePrependAppend($array) {
  220. foreach($array as $key => $option) {
  221. if($option == "NULL") {
  222. $array[$key] = "";
  223. }
  224. }
  225. return $array;
  226. }
  227.  
  228. /**
  229. * Render the option tags.
  230. *
  231. * @param mixed $value Value to check for
  232. * @return boolean TRUE if the value should be marked a s selected; FALSE otherwise
  233. */
  234. protected function isSelected($value) {
  235. $selectedValue = $this->getSelectedValue();
  236. if ($value === $selectedValue || (string)$value === $selectedValue) {
  237. return TRUE;
  238. }
  239. if ($this->hasArgument('multiple')) {
  240. if (is_null($selectedValue) && $this->arguments['selectAllByDefault'] === TRUE) {
  241. return TRUE;
  242. } elseif (is_array($selectedValue) && in_array($value, $selectedValue)) {
  243. return TRUE;
  244. }
  245. }
  246. return FALSE;
  247. }
  248.  
  249. /**
  250. * Retrieves the selected value(s)
  251. *
  252. * @return mixed value string or an array of strings
  253. */
  254. protected function getSelectedValue() {
  255. $value = $this->getValue();
  256. if (!is_array($value) && !($value instanceof \Traversable)) {
  257. return $this->getOptionValueScalar($value);
  258. }
  259. $selectedValues = array();
  260. foreach($value as $selectedValueElement) {
  261. $selectedValues[] = $this->getOptionValueScalar($selectedValueElement);
  262. }
  263. return $selectedValues;
  264. }
  265.  
  266. /**
  267. * Get the option value for an object
  268. *
  269. * @param mixed $valueElement
  270. * @return string
  271. */
  272. protected function getOptionValueScalar($valueElement) {
  273. if (is_object($valueElement)) {
  274. if ($this->hasArgument('optionValueField')) {
  275. return \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($valueElement, $this->arguments['optionValueField']);
  276. } else if ($this->persistenceManager->getIdentifierByObject($valueElement) !== NULL){
  277. return $this->persistenceManager->getIdentifierByObject($valueElement);
  278. } else {
  279. return (string)$valueElement;
  280. }
  281. } else {
  282. return $valueElement;
  283. }
  284. }
  285.  
  286. /**
  287. * Render one option tag
  288. *
  289. * @param string $value value attribute of the option tag (will be escaped)
  290. * @param string $label content of the option tag (will be escaped)
  291. * @param boolean $isSelected specifies wheter or not to add selected attribute
  292. * @return string the rendered option tag
  293. */
  294. protected function renderOptionTag($value, $label, $isSelected) {
  295. $output = '<option value="' . htmlspecialchars($value) . '"';
  296. if ($isSelected) {
  297. $output= ' selected="selected"';
  298. }
  299. $output.= '>' . htmlspecialchars($label) . '</option>';
  300.  
  301. return $output;
  302. }
  303. }
  304.  
  305. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement