Created
July 28, 2014 14:58
-
-
Save aertmann/730d49d81dc2264d324d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace MOC\...\ViewHelpers\Form; | |
/** | |
* The form checkbox select view helper | |
* | |
* @scope prototype | |
*/ | |
class CheckboxSelectViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper { | |
/** | |
* @var mixed | |
*/ | |
protected $selectedValue = NULL; | |
/** | |
* Initialize arguments. | |
* | |
* @return void | |
* @api | |
*/ | |
public function initializeArguments() { | |
parent::initializeArguments(); | |
$this->registerUniversalTagAttributes(); | |
$this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads'); | |
$this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', TRUE); | |
$this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.'); | |
$this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.'); | |
$this->registerArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, FALSE); | |
$this->registerArgument('selectAllByDefault', 'boolean', 'If specified options are selected if none was set before.', FALSE, FALSE); | |
$this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error'); | |
} | |
/** | |
* Render the checkboxes. | |
* | |
* @return string rendered checkboxes. | |
* @api | |
*/ | |
public function render() { | |
$options = $this->getOptions(); | |
if (empty($options)) { | |
$options = array('' => ''); | |
} | |
$this->setErrorClassAttribute(); | |
$content = ''; | |
// Register field name for each checkbox for the token generation. | |
$content .= $this->renderHiddenFieldForEmptyValue(); | |
foreach ($options as $option) { | |
$this->registerFieldNameForFormTokenGeneration($option); | |
} | |
$content .= $this->renderCheckboxes($options); | |
return $content; | |
} | |
/** | |
* Render the checkboxes. | |
* | |
* @param array $options the options for the form. | |
* @return string rendered checkboxes. | |
*/ | |
protected function renderCheckboxes($options) { | |
$output = ''; | |
foreach ($options as $value => $label) { | |
$isSelected = $this->isSelected($value); | |
$output .= $this->renderCheckbox($value, $label, $isSelected) . chr(10); | |
} | |
return $output; | |
} | |
/** | |
* Get the options. | |
* | |
* @return array an associative array of options, key will be the value of the checkbox | |
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception | |
*/ | |
protected function getOptions() { | |
if (!is_array($this->arguments['options']) && !$this->arguments['options'] instanceof \Traversable) { | |
return array(); | |
} | |
$options = array(); | |
$optionsArgument = $this->arguments['options']; | |
foreach ($optionsArgument as $key => $value) { | |
if (is_object($value)) { | |
if ($this->hasArgument('optionValueField')) { | |
$key = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionValueField']); | |
if (is_object($key)) { | |
if (method_exists($key, '__toString')) { | |
$key = (string) $key; | |
} else { | |
throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('Identifying value for object of class "' . get_class($value) . '" was an object.', 1247827428); | |
} | |
} | |
} elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) { | |
$key = $this->persistenceManager->getBackend()->getIdentifierByObject($value); | |
} elseif (method_exists($value, '__toString')) { | |
$key = (string) $value; | |
} else { | |
throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('No identifying value for object of class "' . get_class($value) . '" found.', 1247826696); | |
} | |
if ($this->hasArgument('optionLabelField')) { | |
$value = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $this->arguments['optionLabelField']); | |
if (is_object($value)) { | |
if (method_exists($value, '__toString')) { | |
$value = (string) $value; | |
} else { | |
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); | |
} | |
} | |
} elseif (method_exists($value, '__toString')) { | |
$value = (string) $value; | |
} elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) { | |
$value = $this->persistenceManager->getBackend()->getIdentifierByObject($value); | |
} | |
} | |
$options[$key] = $value; | |
} | |
if ($this->arguments['sortByOptionLabel']) { | |
asort($options); | |
} | |
return $options; | |
} | |
/** | |
* Check if the value is selected. | |
* | |
* @param mixed $value Value to check for | |
* @return boolean TRUE if the value should be marked a s selected; FALSE otherwise | |
*/ | |
protected function isSelected($value) { | |
$selectedValue = $this->getSelectedValue(); | |
if ($value === $selectedValue || (string) $value === $selectedValue) { | |
return TRUE; | |
} | |
if (is_null($selectedValue) && $this->arguments['selectAllByDefault'] === TRUE) { | |
return TRUE; | |
} elseif (is_array($selectedValue) && in_array($value, $selectedValue)) { | |
return TRUE; | |
} | |
return FALSE; | |
} | |
/** | |
* Retrieves the selected value(s) | |
* | |
* @return mixed value string or an array of strings | |
*/ | |
protected function getSelectedValue() { | |
$value = $this->getValue(); | |
if (!is_array($value) && !$value instanceof \Traversable) { | |
return $this->getOptionValueScalar($value); | |
} | |
$selectedValues = array(); | |
foreach ($value as $selectedValueElement) { | |
$selectedValues[] = $this->getOptionValueScalar($selectedValueElement); | |
} | |
return $selectedValues; | |
} | |
/** | |
* Get the option value for an object | |
* | |
* @param mixed $valueElement | |
* @return string | |
*/ | |
protected function getOptionValueScalar($valueElement) { | |
if (is_object($valueElement)) { | |
if ($this->hasArgument('optionValueField')) { | |
return \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($valueElement, $this->arguments['optionValueField']); | |
} else { | |
if ($this->persistenceManager->getBackend()->getIdentifierByObject($valueElement) !== NULL) { | |
return $this->persistenceManager->getBackend()->getIdentifierByObject($valueElement); | |
} else { | |
return (string) $valueElement; | |
} | |
} | |
} | |
return $valueElement; | |
} | |
/** | |
* Render one checkbox | |
* | |
* @param string $value value attribute of the checkbox (will be escaped) | |
* @param string $label content of the checkbox (will be escaped) | |
* @param boolean $isSelected specifies whether or not to add selected attribute | |
* @return string the rendered checkbox | |
*/ | |
protected function renderCheckbox($value, $label, $isSelected) { | |
$output = '<label class="checkbox"><input type="checkbox" name="' . $this->getName() . '" value="' . htmlspecialchars($value) . '"'; | |
if ($isSelected) { | |
$output .= ' checked="checked"'; | |
} | |
$output .= '>' . htmlspecialchars($label) . '</label>'; | |
return $output; | |
} | |
/** | |
* Get the name of this form element. | |
* Either returns arguments['name'], or the correct name for Object Access. | |
* | |
* In case property is something like bla.blubb (hierarchical), then [bla][blubb] is generated. | |
* | |
* @return string Name | |
*/ | |
protected function getName() { | |
$name = $this->getNameWithoutPrefix() . '[]'; | |
return $this->prefixFieldName($name); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment