Skip to content

Instantly share code, notes, and snippets.

@aertmann
Created July 28, 2014 14:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aertmann/730d49d81dc2264d324d to your computer and use it in GitHub Desktop.
Save aertmann/730d49d81dc2264d324d to your computer and use it in GitHub Desktop.
<?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