';
- /** wrapper for horizontal elements that have to be wrapped AGAIN and uses the
- * horizontal_attributes class */
- protected static string $horizontalCheckboxWrapper = '
%s
';
- protected static string $wrapper = '
%s%s%s
';
- protected Helper\FormHelp $helpText;
-
- public function __invoke(): self
- {
- return $this;
- }
-
- public function render(BaseInterface $element, string $markup, string $errorString): string
- {
- if ($element instanceof ElementInterface) {
- // do we have errors? if so let'em know
- if ($errorString !== '') {
- $element->setAttribute('class', 'is-invalid');
- }
- // ok lets sort out what mode were in
- if ($element instanceof ModeAwareInterface) {
- if ($element instanceof Element\Checkbox) {
- $markup = sprintf(
- self::$checkboxWrapper,
- $markup
- );
- if ($element->getMode() === ModeAwareInterface::HORIZONTAL_MODE) {
- // todo throw an exception if this is not set, we gotta have it for horizontal checkboxes
- $markup = sprintf(
- self::$horizontalCheckboxWrapper,
- $this->createAttributesString($element->getHorizontalAttributes()),
- $markup
- );
- }
- }
- }
- // todo: #5 validation messages are not showing for mode: horizontal
- $markup = sprintf(
- self::$wrapper,
- $this->createAttributesString($element->getBootstrapAttributes()),
- $markup,
- $this->getHelpTextHelper()->render($element),
- $errorString
- );
- // return it ready or not
- return $markup;
- } elseif ($element instanceof BaseInterface) {
- return $markup;
- }
- // we should never get here, stops phpstan from complaining
- throw new InvalidElementException(
- sprintf(
- 'Expected Element implementing one of
- Limatus\\Form\\ElementInterface,
- Limatus\\Form\\NestedElementInterface,
- Laminas\\Form\\ElementInterface received %s',
- class_implements($element)
- )
- );
- }
-
- protected function getHelpTextHelper(): Helper\FormHelp
- {
- if ($this->view !== null && method_exists($this->view, 'plugin')) {
- $this->helpText = $this->view->plugin('formHelp');
- return $this->helpText;
- }
-
- $this->helpText = new Helper\FormHelp();
- return $this->helpText;
- }
-}
diff --git a/src/Form/View/Helper/FormCheckbox.php b/src/Form/View/Helper/FormCheckbox.php
deleted file mode 100644
index 191fd98..0000000
--- a/src/Form/View/Helper/FormCheckbox.php
+++ /dev/null
@@ -1,83 +0,0 @@
- element from the provided $element
- *
- * @throws Exception\InvalidArgumentException
- * @throws Exception\DomainException
- */
- public function render(ElementInterface $element): string
- {
- if (! $element instanceof Element\Checkbox) {
- throw new Exception\InvalidArgumentException(sprintf(
- 'Requires $element to one of ' . Element\Checkbox::class . ' or ' . Element\Checkbox::class . ' recieved: %s',
- $element::class
- ));
- }
-
- $name = $element->getName();
- if ($name === null || $name === '') {
- throw new Exception\DomainException(sprintf(
- '%s requires that the element has an assigned name; none discovered',
- __METHOD__
- ));
- }
-
- // force an id so the label will not wrap
- if (! $element->hasAttribute('id')) {
- $element->setAttribute('id', $name);
- }
-
- $attributes = $element->getAttributes();
- $attributes['name'] = $name;
- $attributes['type'] = $this->getInputType();
- $attributes['value'] = $element->getCheckedValue();
- $closingBracket = $this->getInlineClosingBracket();
-
- if ($element->isChecked()) {
- $attributes['checked'] = 'checked';
- }
-
- $rendered = sprintf(
- 'createAttributesString($attributes),
- $closingBracket
- );
-
- if ($element->useHiddenElement()) {
- $hiddenAttributes = [
- 'disabled' => $attributes['disabled'] ?? false,
- 'name' => $attributes['name'],
- 'value' => $element->getUncheckedValue(),
- ];
-
- $rendered = sprintf(
- 'createAttributesString($hiddenAttributes),
- $closingBracket
- ) . $rendered;
- }
-
- return $rendered;
- }
-
- /**
- * Return input type
- */
- protected function getInputType(): string
- {
- return 'checkbox';
- }
-}
diff --git a/src/Form/View/Helper/FormCollection.php b/src/Form/View/Helper/FormCollection.php
deleted file mode 100644
index e4322d3..0000000
--- a/src/Form/View/Helper/FormCollection.php
+++ /dev/null
@@ -1,394 +0,0 @@
-
- */
- protected $validTagAttributes = [
- 'name' => true,
- ];
-
- /**
- * If set to true, collections are automatically wrapped around a fieldset
- */
- protected bool $shouldWrap = true;
-
- /**
- * This is the default wrapper that the collection is wrapped into
- */
- protected string $wrapper = '';
-
- /**
- * This is the wrapper that $mode === horizontal wraps into
- */
- protected string $horizontalWrapper = '';
-
- /**
- * This is the default label-wrapper
- *
- * @var string
- */
- protected $labelWrapper = '';
-
- /**
- * This is the horizontal mode label wrapper
- */
- protected string $horizontalLabelWrapper = '';
-
- /**
- * Where shall the template-data be inserted into
- *
- * @var string
- */
- protected $templateWrapper = '';
-
- /**
- * horizontal mode template wrapper
- */
- protected string $horizontalTemplateWrapper = '';
-
- /**
- * The name of the default view helper that is used to render sub elements.
- *
- * @var string
- */
- protected $defaultElementHelper = 'formrow';
-
- /**
- * The view helper used to render sub elements.
- *
- * @var null|HelperInterface
- */
- protected $elementHelper;
-
- /**
- * The view helper used to render sub fieldsets.
- *
- * @var null|HelperInterface
- */
- protected $fieldsetHelper;
-
- private array $doctypesAllowedToHaveNameAttribute = [
- Doctype::HTML5 => true,
- Doctype::XHTML5 => true,
- ];
-
- /**
- * Invoke helper as function
- *
- * Proxies to {@link render()}.
- *
- * @template T as null|ElementInterface
- * @psalm-param T $element
- * @psalm-return (T is null ? self : string)
- * @return string|FormCollection
- */
- public function __invoke(?ElementInterface $element = null, bool $wrap = true)
- {
- if (! $element) {
- return $this;
- }
- $this->setShouldWrap($wrap);
-
- return $this->render($element);
- }
-
- /**
- * Render a collection by iterating through all fieldsets and elements
- */
- public function render(ElementInterface $element): string
- {
- $renderer = $this->getView();
- if ($renderer !== null && ! method_exists($renderer, 'plugin')) {
- // Bail early if renderer is not pluggable
- return '';
- }
-
- $markup = '';
- $templateMarkup = '';
- $elementHelper = $this->getElementHelper();
- assert(is_callable($elementHelper));
- $fieldsetHelper = $this->getFieldsetHelper();
- assert(is_callable($fieldsetHelper));
-
- if ($element instanceof CollectionElement && $element->shouldCreateTemplate()) {
- $templateMarkup = $this->renderTemplate($element);
- }
- // Limatus, may be to get into this workflow for nested fieldsets
- foreach ($element->getIterator() as $elementOrFieldset) {
- if ($elementOrFieldset instanceof FieldsetInterface) {
- $markup .= $fieldsetHelper(element: $elementOrFieldset, wrap: $this->shouldWrap());
- } elseif ($elementOrFieldset instanceof ElementInterface) {
- $markup .= $elementHelper(element: $elementOrFieldset);
- }
- }
-
- // Every collection is wrapped by a fieldset if needed
- if ($this->shouldWrap) {
- $attributes = $element->getAttributes();
- if (! isset($this->doctypesAllowedToHaveNameAttribute[$this->getDoctype()])) {
- unset($attributes['name']);
- }
- $attributesString = $attributes !== [] ? ' ' . $this->createAttributesString($attributes) : '';
-
- $label = $element->getLabel();
- $legend = '';
-
- if (! empty($label)) {
- if (null !== ($translator = $this->getTranslator())) {
- $label = $translator->translate(
- $label,
- $this->getTranslatorTextDomain()
- );
- }
-
- if (! $element instanceof LabelAwareInterface || ! $element->getLabelOption('disable_html_escape')) {
- $escapeHtmlHelper = $this->getEscapeHtmlHelper();
- $label = $escapeHtmlHelper($label);
- }
-
- $legend = sprintf(
- $this->labelWrapper,
- $label
- );
- }
-
- $markup = sprintf(
- $this->wrapper,
- $markup,
- $legend,
- $templateMarkup,
- $attributesString
- );
- } else {
- $markup .= $templateMarkup;
- }
-
- return $markup;
- }
-
- /**
- * Only render a template
- */
- public function renderTemplate(CollectionElement $collection): string
- {
- $elementHelper = $this->getElementHelper();
- assert(is_callable($elementHelper));
- $escapeHtmlAttribHelper = $this->getEscapeHtmlAttrHelper();
- $fieldsetHelper = $this->getFieldsetHelper();
- assert(is_callable($fieldsetHelper));
-
- $templateMarkup = '';
-
- $elementOrFieldset = $collection->getTemplateElement();
-
- if ($elementOrFieldset instanceof FieldsetInterface) {
- $templateMarkup .= $fieldsetHelper($elementOrFieldset, $this->shouldWrap());
- } elseif ($elementOrFieldset instanceof ElementInterface) {
- $templateMarkup .= $elementHelper($elementOrFieldset);
- }
-
- return sprintf(
- $this->getTemplateWrapper(),
- $escapeHtmlAttribHelper($templateMarkup)
- );
- }
-
- /**
- * If set to true, collections are automatically wrapped around a fieldset
- *
- * @return $this
- */
- public function setShouldWrap(bool $wrap)
- {
- $this->shouldWrap = $wrap;
- return $this;
- }
-
- /**
- * Get wrapped
- */
- public function shouldWrap(): bool
- {
- return $this->shouldWrap;
- }
-
- /**
- * Sets the name of the view helper that should be used to render sub elements.
- *
- * @param string $defaultSubHelper The name of the view helper to set.
- * @return $this
- */
- public function setDefaultElementHelper(string $defaultSubHelper)
- {
- $this->defaultElementHelper = $defaultSubHelper;
- return $this;
- }
-
- /**
- * Gets the name of the view helper that should be used to render sub elements.
- */
- public function getDefaultElementHelper(): string
- {
- return $this->defaultElementHelper;
- }
-
- /**
- * Sets the element helper that should be used by this collection.
- *
- * @param HelperInterface $elementHelper The element helper to use.
- * @return $this
- */
- public function setElementHelper(HelperInterface $elementHelper)
- {
- $this->elementHelper = $elementHelper;
- return $this;
- }
-
- /**
- * Retrieve the element helper.
- *
- * @throws RuntimeException
- */
- protected function getElementHelper(): HelperInterface
- {
- if ($this->elementHelper) {
- return $this->elementHelper;
- }
-
- if ($this->view !== null && method_exists($this->view, 'plugin')) {
- $this->elementHelper = $this->view->plugin($this->getDefaultElementHelper());
- }
-
- if (! $this->elementHelper instanceof HelperInterface) {
- throw new RuntimeException(
- 'Invalid element helper set in FormCollection. The helper must be an '
- . 'instance of Laminas\View\Helper\HelperInterface.'
- );
- }
-
- return $this->elementHelper;
- }
-
- /**
- * Sets the fieldset helper that should be used by this collection.
- *
- * @param HelperInterface $fieldsetHelper The fieldset helper to use.
- * @return $this
- */
- public function setFieldsetHelper(HelperInterface $fieldsetHelper)
- {
- $this->fieldsetHelper = $fieldsetHelper;
- return $this;
- }
-
- /**
- * Retrieve the fieldset helper.
- */
- protected function getFieldsetHelper(): HelperInterface
- {
- if ($this->fieldsetHelper) {
- return $this->fieldsetHelper;
- }
-
- return $this;
- }
-
- /**
- * Get the wrapper for the collection
- */
- public function getWrapper(): string
- {
- return $this->wrapper;
- }
-
- /**
- * Set the wrapper for this collection
- *
- * The string given will be passed through sprintf with the following three
- * replacements:
- *
- * 1. The content of the collection
- * 2. The label of the collection. If no label is given this will be an empty
- * string
- * 3. The template span-tag. This might also be an empty string
- *
- * The preset default is
- *
- * @return $this
- */
- public function setWrapper(string $wrapper)
- {
- $this->wrapper = $wrapper;
-
- return $this;
- }
-
- /**
- * Set the label-wrapper
- * The string will be passed through sprintf with the label as single
- * parameter
- * This defaults to ''
- *
- * @return $this
- */
- public function setLabelWrapper(string $labelWrapper)
- {
- $this->labelWrapper = $labelWrapper;
-
- return $this;
- }
-
- /**
- * Get the wrapper for the label
- */
- public function getLabelWrapper(): string
- {
- return $this->labelWrapper;
- }
-
- /**
- * Ge the wrapper for the template
- */
- public function getTemplateWrapper(): string
- {
- return $this->templateWrapper;
- }
-
- /**
- * Set the string where the template will be inserted into
- *
- * This string will be passed through sprintf and has the template as single
- * parameter
- *
- * THis defaults to ''
- *
- * @return $this
- */
- public function setTemplateWrapper(string $templateWrapper)
- {
- $this->templateWrapper = $templateWrapper;
-
- return $this;
- }
-}
diff --git a/src/Form/View/Helper/FormCollectionDelegator.php b/src/Form/View/Helper/FormCollectionDelegator.php
new file mode 100644
index 0000000..38cc318
--- /dev/null
+++ b/src/Form/View/Helper/FormCollectionDelegator.php
@@ -0,0 +1,109 @@
+%2$s%1$s%3$s';
+
+ /**
+ * This is the default label-wrapper
+ *
+ * @var string
+ */
+ protected $labelWrapper = 'legend';
+
+ /**
+ * Where shall the template-data be inserted into
+ *
+ * @var string
+ */
+ protected $templateWrapper = '';
+
+ /**
+ * Render a collection by iterating through all fieldsets and elements
+ */
+ public function render(ElementInterface $element): string
+ {
+ /** @var Fieldset|CollectionElement $element */
+
+ $renderer = $this->getView();
+ if ($renderer !== null && ! method_exists($renderer, 'plugin')) {
+ // Bail early if renderer is not pluggable
+ return '';
+ }
+
+ $markup = '';
+ $templateMarkup = '';
+ $elementHelper = $this->getElementHelper();
+ assert(is_callable($elementHelper));
+
+ $fieldsetHelper = $this->getFieldsetHelper();
+ assert(is_callable($fieldsetHelper));
+
+ if ($element instanceof CollectionElement && $element->shouldCreateTemplate()) {
+ $templateMarkup = $this->renderTemplate($element);
+ }
+
+ foreach ($element->getIterator() as $elementOrFieldset) {
+ if ($elementOrFieldset instanceof FieldsetInterface) {
+ $markup .= $fieldsetHelper($elementOrFieldset, $this->shouldWrap());
+ } elseif ($elementOrFieldset instanceof ElementInterface) {
+ $markup .= $elementHelper($elementOrFieldset);
+ }
+ }
+
+ if (! $this->shouldWrap) {
+ return $markup . $templateMarkup;
+ }
+
+ // Every collection is wrapped by a fieldset if needed
+ $attributes = $element->getAttributes();
+ if (! $this->getDoctypeHelper()->isHtml5()) {
+ unset(
+ $attributes['name'],
+ $attributes['disabled'],
+ $attributes['form']
+ );
+ }
+
+ $label = $element->getLabel();
+ $legend = '';
+
+ $event = new RenderEvent(Events::RenderCollection->value, $this);
+ $event->setMarkup($markup);
+
+ if (! empty($label)) {
+ $label = $this->translateLabel($label);
+ $label = $this->escapeLabel($element, $label);
+
+ $event->setParam('label', $label);
+ }
+
+ $event->setElement($element);
+
+ $result = $this->getEventManager()->triggerEvent($event);
+ if (! empty($result->last())) {
+ // return the modified markup
+ return $result->last();
+ }
+ }
+}
diff --git a/src/Form/View/Helper/FormCollectionDelegatorFactory.php b/src/Form/View/Helper/FormCollectionDelegatorFactory.php
new file mode 100644
index 0000000..024515b
--- /dev/null
+++ b/src/Form/View/Helper/FormCollectionDelegatorFactory.php
@@ -0,0 +1,27 @@
+get(EventManagerInterface::class);
+ $delegator = new FormCollectionDelegator();
+ $delegator->setEventManager($em);
+ $listener = $container->get(RenderListenerInterface::class);
+ $listener->attach($em);
+ return $delegator;
+ }
+}
diff --git a/src/Form/View/Helper/FormDelegator.php b/src/Form/View/Helper/FormDelegator.php
new file mode 100644
index 0000000..a927292
--- /dev/null
+++ b/src/Form/View/Helper/FormDelegator.php
@@ -0,0 +1,89 @@
+ true,
+ 'action' => true,
+ 'autocomplete' => true,
+ 'enctype' => true,
+ 'method' => true,
+ 'name' => true,
+ 'novalidate' => true,
+ 'target' => true,
+ // start htmx
+ 'post' => true,
+ 'get' => true,
+ 'put' => true,
+ 'trigger' => true,
+ 'swap' => true,
+ 'sync' => true,
+ ];
+
+ /**
+ * Render a form from the provided $form,
+ * @param Form $form
+ */
+ public function render(FormInterface $form): string
+ {
+ if (method_exists($form, 'prepare')) {
+ $form->prepare();
+ }
+
+ $formContent = '';
+
+ $renderer = $this->getView();
+ assert($renderer instanceof PhpRenderer);
+ // what LayoutMode should this helper use?,
+ $event = new RenderEvent(Events::PreRenderForm->value, $this);
+ $event->setAttributes($form->getAttributes())
+ ->setOptions($form->getOptions())
+ ->setElement($form);
+
+ $this->getEventManager()->triggerEvent($event);
+
+ foreach ($form as $element) {
+ if ($element instanceof FieldsetInterface) {
+ $formContent .= $renderer->formCollection($element);
+ } else {
+ $formContent .= $renderer->formRow($element);
+ }
+ }
+
+ return $this->openTag($form) . $formContent . $this->closeTag();
+ }
+}
diff --git a/src/Form/View/Helper/FormDelegatorFactory.php b/src/Form/View/Helper/FormDelegatorFactory.php
new file mode 100644
index 0000000..8a5d8fa
--- /dev/null
+++ b/src/Form/View/Helper/FormDelegatorFactory.php
@@ -0,0 +1,28 @@
+get(EventManagerInterface::class);
+ $delegator = new FormDelegator();
+ $delegator->setEventManager($em);
+ $listener = $container->get(RenderListenerInterface::class);
+ $listener->attach($em, 1000);
+ return $delegator;
+ }
+}
diff --git a/src/Form/View/Helper/FormElement.php b/src/Form/View/Helper/FormElement.php
deleted file mode 100644
index 3c5eb14..0000000
--- a/src/Form/View/Helper/FormElement.php
+++ /dev/null
@@ -1,196 +0,0 @@
- 'formbutton',
- Element\Captcha::class => 'formcaptcha',
- Element\Csrf::class => 'formhidden',
- Element\Collection::class => 'formcollection',
- Element\DateTimeSelect::class => 'formdatetimeselect',
- Element\DateSelect::class => 'formdateselect',
- Element\MonthSelect::class => 'formmonthselect',
- ];
-
- /**
- * Type map to view helper
- *
- * @var array
- */
- protected $typeMap = [
- 'checkbox' => 'formcheckbox',
- 'color' => 'formcolor',
- 'date' => 'formdate',
- 'datetime' => 'formdatetime',
- 'datetime-local' => 'formdatetimelocal',
- 'email' => 'formemail',
- 'file' => 'formfile',
- 'hidden' => 'formhidden',
- 'image' => 'formimage',
- 'month' => 'formmonth',
- 'multi_checkbox' => 'formmulticheckbox',
- 'number' => 'formnumber',
- 'password' => 'formpassword',
- 'radio' => 'formradio',
- 'range' => 'formrange',
- 'reset' => 'formreset',
- 'search' => 'formsearch',
- 'select' => 'formselect',
- 'submit' => 'formsubmit',
- 'tel' => 'formtel',
- 'text' => 'formtext',
- 'textarea' => 'formtextarea',
- 'time' => 'formtime',
- 'url' => 'formurl',
- 'week' => 'formweek',
- ];
-
- /**
- * Default helper name
- *
- * @var string
- */
- protected $defaultHelper = self::DEFAULT_HELPER;
-
- /**
- * Invoke helper as function
- *
- * Proxies to {@link render()}.
- *
- * @template T as null|ElementInterface
- * @psalm-param T $element
- * @psalm-return (T is null ? self : string)
- * @return string|self
- */
- public function __invoke(?ElementInterface $element = null)
- {
- if (! $element) {
- return $this;
- }
- return $this->render($element);
- }
-
- /**
- * Render an element
- *
- * Introspects the element type and attributes to determine which
- * helper to utilize when rendering.
- */
- public function render(ElementInterface $element): string
- {
- $renderer = $this->getView();
- if ($renderer === null || ! method_exists($renderer, 'plugin')) {
- // Bail early if renderer is not pluggable
- return '';
- }
-
- $renderedInstance = $this->renderInstance($element);
-
- if ($renderedInstance !== null) {
- return $renderedInstance;
- }
-
- $renderedType = $this->renderType($element);
-
- if ($renderedType !== null) {
- return $renderedType;
- }
-
- return $this->renderHelper($this->defaultHelper, $element);
- }
-
- /**
- * Set default helper name
- *
- * @return $this
- */
- public function setDefaultHelper(string $name)
- {
- $this->defaultHelper = $name;
-
- return $this;
- }
-
- /**
- * Add form element type to plugin map
- *
- * @return $this
- */
- public function addType(string $type, string $plugin)
- {
- $this->typeMap[$type] = $plugin;
-
- return $this;
- }
-
- /**
- * Add instance class to plugin map
- *
- * @return $this
- */
- public function addClass(string $class, string $plugin)
- {
- $this->classMap[$class] = $plugin;
-
- return $this;
- }
-
- /**
- * Render element by helper name
- */
- protected function renderHelper(string $name, ElementInterface $element): string
- {
- $renderer = $this->getView();
- assert($renderer instanceof PhpRenderer);
- $helper = $renderer->plugin($name);
- assert(is_callable($helper));
- return $helper($element);
- }
-
- /**
- * Render element by instance map
- */
- protected function renderInstance(ElementInterface $element): ?string
- {
- foreach ($this->classMap as $class => $pluginName) {
- if ($element instanceof $class) {
- return $this->renderHelper($pluginName, $element);
- }
- }
-
- return null;
- }
-
- /**
- * Render element by type map
- */
- protected function renderType(ElementInterface $element): ?string
- {
- $type = $element->getAttribute('type');
-
- if (isset($this->typeMap[$type])) {
- return $this->renderHelper($this->typeMap[$type], $element);
- }
-
- return null;
- }
-}
diff --git a/src/Form/View/Helper/FormElementDelegator.php b/src/Form/View/Helper/FormElementDelegator.php
new file mode 100644
index 0000000..cf65209
--- /dev/null
+++ b/src/Form/View/Helper/FormElementDelegator.php
@@ -0,0 +1,34 @@
+getView();
+ if ($renderer === null || ! method_exists($renderer, 'plugin')) {
+ // Bail early if renderer is not pluggable
+ return '';
+ }
+ // return the standard laminas-form rendering
+ return parent::render($element);
+ }
+}
diff --git a/src/Form/View/Helper/FormElementDelegatorFactory.php b/src/Form/View/Helper/FormElementDelegatorFactory.php
new file mode 100644
index 0000000..715828e
--- /dev/null
+++ b/src/Form/View/Helper/FormElementDelegatorFactory.php
@@ -0,0 +1,28 @@
+get(EventManagerInterface::class);
+ $delegator = new FormElementDelegator();
+ $delegator->setEventManager($em);
+ $listener = $container->get(RenderListenerInterface::class);
+ $listener->attach($em);
+ return $delegator;
+ }
+}
diff --git a/src/Form/View/Helper/FormGridCollection.php b/src/Form/View/Helper/FormGridCollection.php
deleted file mode 100644
index 2a55f6b..0000000
--- a/src/Form/View/Helper/FormGridCollection.php
+++ /dev/null
@@ -1,394 +0,0 @@
-
- */
- protected $validTagAttributes = [];
-
- /**
- * If set to true, collections are automatically wrapped around a fieldset
- */
- protected bool $shouldWrap = true;
-
- /**
- * This is the default wrapper that the collection is wrapped into
- */
- protected string $wrapper = '
%2$s%1$s%3$s
';
-
- /**
- * This is the default label-wrapper
- *
- * @var string
- */
- protected $labelWrapper = '';
-
- /**
- * Where shall the template-data be inserted into
- *
- * @var string
- */
- protected $templateWrapper = '';
-
- /**
- * horizontal mode template wrapper
- */
- protected string $horizontalTemplateWrapper = '';
-
- /**
- * The name of the default view helper that is used to render sub elements.
- *
- * @var string
- */
- protected $defaultElementHelper = 'formrow';
-
- /**
- * The view helper used to render sub elements.
- *
- * @var null|HelperInterface
- */
- protected $elementHelper;
-
- /**
- * The view helper used to render sub fieldsets.
- *
- * @var null|HelperInterface
- */
- protected $fieldsetHelper;
-
- private array $doctypesAllowedToHaveNameAttribute = [
- Doctype::HTML5 => true,
- Doctype::XHTML5 => true,
- ];
-
- /**
- * Invoke helper as function
- *
- * Proxies to {@link render()}.
- *
- * @template T as null|ElementInterface
- * @psalm-param T $element
- * @psalm-return (T is null ? self : string)
- * @return string|FormCollection
- */
- public function __invoke(?ElementInterface $element = null, bool $wrap = true)
- {
- if (! $element) {
- return $this;
- }
- $this->setShouldWrap($wrap);
-
- return $this->render($element);
- }
-
- /**
- * Render a collection by iterating through all fieldsets and elements
- */
- public function render(ElementInterface $element): string
- {
- $renderer = $this->getView();
- if ($renderer !== null && ! method_exists($renderer, 'plugin')) {
- // Bail early if renderer is not pluggable
- return '';
- }
-
- $markup = '';
- $templateMarkup = '';
- $elementHelper = $this->getElementHelper();
- assert(is_callable($elementHelper));
- $gridsetHelper = $this->getGridsetHelper();
- assert(is_callable($gridsetHelper));
- $fieldsetHelper = $this->getFieldsetHelper();
- assert(is_callable($fieldsetHelper));
-
- if ($element instanceof CollectionElement && $element->shouldCreateTemplate()) {
- $templateMarkup = $this->renderTemplate($element);
- }
-
- foreach ($element->getIterator() as $elementOrFieldset) {
- if ($elementOrFieldset instanceof GridsetInterface) {
- $markup .= $gridsetHelper(element: $elementOrFieldset, wrap: $this->shouldWrap());
- } elseif ($elementOrFieldset instanceof FieldsetInterface) {
- $markup .= $fieldsetHelper(element: $elementOrFieldset, wrap: $this->shouldWrap());
- } elseif ($elementOrFieldset instanceof ElementInterface) {
- $markup .= $elementHelper(element: $elementOrFieldset);
- }
- }
-
- // Every collection is wrapped by a row
- if ($this->shouldWrap) {
- $attributes = $element->getAttributes();
- if (! isset($this->doctypesAllowedToHaveNameAttribute[$this->getDoctype()])) {
- unset($attributes['name']);
- }
- $attributesString = $attributes !== [] ? ' ' . $this->createAttributesString($attributes) : '';
-
- $label = $element->getLabel();
- $legend = '';
-
- if (! empty($label)) {
- if (null !== ($translator = $this->getTranslator())) {
- $label = $translator->translate(
- $label,
- $this->getTranslatorTextDomain()
- );
- }
-
- if (! $element instanceof LabelAwareInterface || ! $element->getLabelOption('disable_html_escape')) {
- $escapeHtmlHelper = $this->getEscapeHtmlHelper();
- $label = $escapeHtmlHelper($label);
- }
-
- $legend = sprintf(
- $this->labelWrapper,
- $label
- );
- }
-
- $markup = sprintf(
- $this->wrapper,
- $markup,
- $legend,
- $templateMarkup,
- $attributesString
- );
- } else {
- $markup .= $templateMarkup;
- }
-
- return $markup;
- }
-
- /**
- * Only render a template
- */
- public function renderTemplate(CollectionElement $collection): string
- {
- $elementHelper = $this->getElementHelper();
- assert(is_callable($elementHelper));
- $escapeHtmlAttribHelper = $this->getEscapeHtmlAttrHelper();
- $fieldsetHelper = $this->getFieldsetHelper();
- assert(is_callable($fieldsetHelper));
-
- $templateMarkup = '';
-
- $elementOrFieldset = $collection->getTemplateElement();
-
- if ($elementOrFieldset instanceof FieldsetInterface) {
- $templateMarkup .= $fieldsetHelper($elementOrFieldset, $this->shouldWrap());
- } elseif ($elementOrFieldset instanceof ElementInterface) {
- $templateMarkup .= $elementHelper($elementOrFieldset);
- }
-
- return sprintf(
- $this->getTemplateWrapper(),
- $escapeHtmlAttribHelper($templateMarkup)
- );
- }
-
- /**
- * If set to true, collections are automatically wrapped around a fieldset
- *
- * @return $this
- */
- public function setShouldWrap(bool $wrap)
- {
- $this->shouldWrap = $wrap;
- return $this;
- }
-
- /**
- * Get wrapped
- */
- public function shouldWrap(): bool
- {
- return $this->shouldWrap;
- }
-
- public function getGridSetHelper(): HelperInterface
- {
- if ($this->view !== null && method_exists($this->view, 'plugin')) {
- return $this->view->plugin('formGridCollection');
- }
- return new $this();
- }
-
- /**
- * Sets the name of the view helper that should be used to render sub elements.
- *
- * @param string $defaultSubHelper The name of the view helper to set.
- * @return $this
- */
- public function setDefaultElementHelper(string $defaultSubHelper)
- {
- $this->defaultElementHelper = $defaultSubHelper;
- return $this;
- }
-
- /**
- * Gets the name of the view helper that should be used to render sub elements.
- */
- public function getDefaultElementHelper(): string
- {
- return $this->defaultElementHelper;
- }
-
- /**
- * Sets the element helper that should be used by this collection.
- *
- * @param HelperInterface $elementHelper The element helper to use.
- * @return $this
- */
- public function setElementHelper(HelperInterface $elementHelper)
- {
- $this->elementHelper = $elementHelper;
- return $this;
- }
-
- /**
- * Retrieve the element helper.
- *
- * @throws RuntimeException
- */
- protected function getElementHelper(): HelperInterface
- {
- if ($this->elementHelper) {
- return $this->elementHelper;
- }
-
- if ($this->view !== null && method_exists($this->view, 'plugin')) {
- $this->elementHelper = $this->view->plugin($this->getDefaultElementHelper());
- }
-
- if (! $this->elementHelper instanceof HelperInterface) {
- throw new RuntimeException(
- 'Invalid element helper set in FormCollection. The helper must be an '
- . 'instance of Laminas\View\Helper\HelperInterface.'
- );
- }
-
- return $this->elementHelper;
- }
-
- /**
- * Sets the fieldset helper that should be used by this collection.
- *
- * @param HelperInterface $fieldsetHelper The fieldset helper to use.
- * @return $this
- */
- public function setFieldsetHelper(HelperInterface $fieldsetHelper)
- {
- $this->fieldsetHelper = $fieldsetHelper;
- return $this;
- }
-
- /**
- * Retrieve the fieldset helper.
- */
- protected function getFieldsetHelper(): HelperInterface
- {
- if ($this->fieldsetHelper) {
- return $this->fieldsetHelper;
- }
-
- return $this;
- }
-
- /**
- * Get the wrapper for the collection
- */
- public function getWrapper(): string
- {
- return $this->wrapper;
- }
-
- /**
- * Set the wrapper for this collection
- *
- * The string given will be passed through sprintf with the following three
- * replacements:
- *
- * 1. The content of the collection
- * 2. The label of the collection. If no label is given this will be an empty
- * string
- * 3. The template span-tag. This might also be an empty string
- *
- * The preset default is
- *
- * @return $this
- */
- public function setWrapper(string $wrapper)
- {
- $this->wrapper = $wrapper;
-
- return $this;
- }
-
- /**
- * Set the label-wrapper
- * The string will be passed through sprintf with the label as single
- * parameter
- * This defaults to ''
- *
- * @return $this
- */
- public function setLabelWrapper(string $labelWrapper)
- {
- $this->labelWrapper = $labelWrapper;
-
- return $this;
- }
-
- /**
- * Get the wrapper for the label
- */
- public function getLabelWrapper(): string
- {
- return $this->labelWrapper;
- }
-
- /**
- * Ge the wrapper for the template
- */
- public function getTemplateWrapper(): string
- {
- return $this->templateWrapper;
- }
-
- /**
- * Set the string where the template will be inserted into
- *
- * This string will be passed through sprintf and has the template as single
- * parameter
- *
- * THis defaults to ''
- *
- * @return $this
- */
- public function setTemplateWrapper(string $templateWrapper)
- {
- $this->templateWrapper = $templateWrapper;
- return $this;
- }
-}
diff --git a/src/Form/View/Helper/FormHorizontalElement.php b/src/Form/View/Helper/FormHorizontalElement.php
deleted file mode 100644
index 6eab63f..0000000
--- a/src/Form/View/Helper/FormHorizontalElement.php
+++ /dev/null
@@ -1,21 +0,0 @@
-%s';
-
- public function __invoke(?string $markup = null): string|self
- {
- $this->setView($this->view);
- if ($markup !== null) {
- return sprintf($markup, self::$rowWrapper);
- }
- return $this;
- }
-}
diff --git a/src/Form/View/Helper/FormInput.php b/src/Form/View/Helper/FormInput.php
deleted file mode 100644
index 75c5316..0000000
--- a/src/Form/View/Helper/FormInput.php
+++ /dev/null
@@ -1,186 +0,0 @@
- true,
- 'accept' => true,
- 'alt' => true,
- 'autocomplete' => true,
- 'autofocus' => true,
- 'checked' => true,
- 'dirname' => true,
- 'disabled' => true,
- 'form' => true,
- 'formaction' => true,
- 'formenctype' => true,
- 'formmethod' => true,
- 'formnovalidate' => true,
- 'formtarget' => true,
- 'height' => true,
- 'list' => true,
- 'max' => true,
- 'maxlength' => true,
- 'min' => true,
- 'multiple' => true,
- 'pattern' => true,
- 'placeholder' => true,
- 'readonly' => true,
- 'required' => true,
- 'size' => true,
- 'src' => true,
- 'step' => true,
- 'type' => true,
- 'value' => true,
- 'width' => true,
- ];
- /**
- * Valid values for the input type
- *
- * @var array
- */
- protected $validTypes = [
- 'text' => true,
- 'button' => true,
- 'checkbox' => true,
- 'file' => true,
- 'hidden' => true,
- 'image' => true,
- 'password' => true,
- 'radio' => true,
- 'reset' => true,
- 'select' => true,
- 'submit' => true,
- 'color' => true,
- 'date' => true,
- 'datetime' => true,
- 'datetime-local' => true,
- 'email' => true,
- 'month' => true,
- 'number' => true,
- 'range' => true,
- 'search' => true,
- 'tel' => true,
- 'time' => true,
- 'url' => true,
- 'week' => true,
- ];
-
- protected static string $horizontalWrapper = '