setLabelPosition($labelPosition); } return $this->render($element); } /** * Render a form element from the provided $element * * @throws Exception\InvalidArgumentException */ public function render(ElementInterface $element): string { if (! $element instanceof MultiCheckboxElement) { throw new Exception\InvalidArgumentException(sprintf( '%s requires that the element is of type Laminas\Form\Element\MultiCheckbox', __METHOD__ )); } $name = static::getName($element); $options = $element->getValueOptions(); $attributes = $element->getAttributes(); $attributes['name'] = $name; $attributes['type'] = $this->getInputType(); $selectedOptions = (array) $element->getValue(); $rendered = $this->renderOptions($element, $options, $selectedOptions, $attributes); // Render hidden element if ($element->useHiddenElement()) { $rendered = $this->renderHiddenElement($element) . $rendered; } return $rendered; } /** * Render options * * @param array $options * @param array $selectedOptions * @param array $attributes */ protected function renderOptions( MultiCheckboxElement $element, array $options, array $selectedOptions, array $attributes ): string { $escapeHtmlHelper = $this->getEscapeHtmlHelper(); $labelHelper = $this->getLabelHelper(); $labelClose = $labelHelper->closeTag(); $labelPosition = $this->getLabelPosition(); $globalLabelAttributes = []; $closingBracket = $this->getInlineClosingBracket(); if ($element instanceof LabelAwareInterface) { $globalLabelAttributes = $element->getLabelAttributes(); } if (empty($globalLabelAttributes)) { $globalLabelAttributes = $this->labelAttributes; } $combinedMarkup = []; $count = 0; foreach ($options as $key => $optionSpec) { $count++; if ($count > 1 && array_key_exists('id', $attributes)) { unset($attributes['id']); } $value = ''; $label = ''; $inputAttributes = $attributes; $labelAttributes = $globalLabelAttributes; $selected = isset($inputAttributes['selected']) && $inputAttributes['type'] !== 'radio' && $inputAttributes['selected']; $disabled = isset($inputAttributes['disabled']) && $inputAttributes['disabled']; if (is_scalar($optionSpec)) { $optionSpec = [ 'label' => $optionSpec, 'value' => $key, ]; } if (isset($optionSpec['value'])) { $value = $optionSpec['value']; } if (isset($optionSpec['label'])) { $label = $optionSpec['label']; } if (isset($optionSpec['selected'])) { $selected = $optionSpec['selected']; } if (isset($optionSpec['disabled'])) { $disabled = $optionSpec['disabled']; } if (isset($optionSpec['label_attributes'])) { $labelAttributes = isset($labelAttributes) ? array_merge($labelAttributes, $optionSpec['label_attributes']) : $optionSpec['label_attributes']; } if (isset($optionSpec['attributes'])) { $inputAttributes = array_merge($inputAttributes, $optionSpec['attributes']); } if (in_array($value, $selectedOptions)) { $selected = true; } $inputAttributes['value'] = $value; $inputAttributes['checked'] = $selected; $inputAttributes['disabled'] = $disabled; $input = sprintf( 'createAttributesString($inputAttributes), $closingBracket ); if (null !== ($translator = $this->getTranslator())) { $label = $translator->translate( $label, $this->getTranslatorTextDomain() ); } if (! $element instanceof LabelAwareInterface || ! $element->getLabelOption('disable_html_escape')) { $label = $escapeHtmlHelper($label); } $labelOpen = $labelHelper->openTag($labelAttributes); $template = $labelOpen . '%s%s' . $labelClose; switch ($labelPosition) { case self::LABEL_PREPEND: $markup = sprintf($template, $label, $input); break; case self::LABEL_APPEND: default: $markup = sprintf($template, $input, $label); break; } $combinedMarkup[] = $markup; } return implode($this->getSeparator(), $combinedMarkup); } /** * Render a hidden element for empty/unchecked value */ protected function renderHiddenElement(MultiCheckboxElement $element): string { $closingBracket = $this->getInlineClosingBracket(); $uncheckedValue = $element->getUncheckedValue() ?: $this->uncheckedValue; $hiddenAttributes = [ 'name' => $element->getName(), 'value' => $uncheckedValue, ]; return sprintf( 'createAttributesString($hiddenAttributes), $closingBracket ); } /** * Sets the attributes applied to option label. * * @param array|null $attributes * @return $this */ public function setLabelAttributes(?array $attributes) { $this->labelAttributes = $attributes; return $this; } /** * Returns the attributes applied to each option label. * * @return array|null */ public function getLabelAttributes(): ?array { return $this->labelAttributes; } /** * Set value for labelPosition * * @throws Exception\InvalidArgumentException * @return $this */ public function setLabelPosition(string $labelPosition) { $labelPosition = strtolower($labelPosition); if (! in_array($labelPosition, [self::LABEL_APPEND, self::LABEL_PREPEND])) { throw new Exception\InvalidArgumentException(sprintf( '%s expects either %s::LABEL_APPEND or %s::LABEL_PREPEND; received "%s"', __METHOD__, self::class, self::class, $labelPosition )); } $this->labelPosition = $labelPosition; return $this; } /** * Get position of label */ public function getLabelPosition(): string { return $this->labelPosition; } /** * Set separator string for checkbox elements * * @return $this */ public function setSeparator(string $separator) { $this->separator = $separator; return $this; } /** * Get separator for checkbox elements */ public function getSeparator(): string { return $this->separator; } /** * Sets the option for prefixing the element with a hidden element * for the unset value. * * @return $this */ public function setUseHiddenElement(bool $useHiddenElement) { $this->useHiddenElement = $useHiddenElement; return $this; } /** * Returns the option for prefixing the element with a hidden element * for the unset value. */ public function getUseHiddenElement(): bool { return $this->useHiddenElement; } /** * Sets the unchecked value used when "UseHiddenElement" is turned on. * * @return $this */ public function setUncheckedValue(string $value) { $this->uncheckedValue = $value; return $this; } /** * Returns the unchecked value used when "UseHiddenElement" is turned on. */ public function getUncheckedValue(): string { return $this->uncheckedValue; } /** * Return input type */ protected function getInputType(): string { return 'checkbox'; } /** * Get element name * * @throws Exception\DomainException */ protected static function getName(ElementInterface $element): string { $name = $element->getName(); if ($name === null || $name === '') { throw new Exception\DomainException(sprintf( '%s requires that the element has an assigned name; none discovered', __METHOD__ )); } return $name . '[]'; } /** * Retrieve the FormInput helper */ protected function getInputHelper(): FormInput { if (null !== $this->inputHelper) { return $this->inputHelper; } if (method_exists($this->view, 'plugin')) { $this->inputHelper = $this->view->plugin('form_input'); } if (! $this->inputHelper instanceof FormInput) { $this->inputHelper = new FormInput(); } return $this->inputHelper; } /** * Retrieve the FormLabel helper */ protected function getLabelHelper(): FormLabel { if ($this->labelHelper) { return $this->labelHelper; } if (method_exists($this->view, 'plugin')) { $this->labelHelper = $this->view->plugin('form_label'); } if (! $this->labelHelper instanceof FormLabel) { $this->labelHelper = new FormLabel(); } return $this->labelHelper; } }