TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inspired by and partially taken from the Neos.Form package (www.neos.io)
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Form\Domain\Model\FormElements;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Form\Domain\Exception\IdentifierNotValidException;
|
||||
use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotFoundException;
|
||||
use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotValidException;
|
||||
use TYPO3\CMS\Form\Domain\Model\Exception\FormDefinitionConsistencyException;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\AbstractCompositeRenderable;
|
||||
|
||||
/**
|
||||
* A base class for "section-like" form parts like "Page" or "Section" (which
|
||||
* is rendered as "Fieldset")
|
||||
*
|
||||
* This class contains multiple FormElements ({@link FormElementInterface}).
|
||||
*
|
||||
* Please see {@link FormDefinition} for an in-depth explanation.
|
||||
*
|
||||
* **This class is NOT meant to be sub classed by developers.**
|
||||
* Scope: frontend
|
||||
*/
|
||||
abstract class AbstractSection extends AbstractCompositeRenderable
|
||||
{
|
||||
/**
|
||||
* @var FormElementInterface[]
|
||||
*/
|
||||
protected $renderables = [];
|
||||
|
||||
/**
|
||||
* Constructor. Needs the identifier and type of this element
|
||||
*
|
||||
* @param string $identifier The Section identifier
|
||||
* @param string $type The Section type
|
||||
* @throws IdentifierNotValidException if the identifier was no non-empty string
|
||||
*/
|
||||
public function __construct(string $identifier, string $type)
|
||||
{
|
||||
if ($identifier === '') {
|
||||
throw new IdentifierNotValidException('The given identifier was empty.', 1477082501);
|
||||
}
|
||||
|
||||
$this->identifier = $identifier;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child Form Elements
|
||||
*
|
||||
* @return FormElementInterface[] The Page's elements
|
||||
*/
|
||||
public function getElements(): array
|
||||
{
|
||||
return $this->renderables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child Form Elements
|
||||
*
|
||||
* @return FormElementInterface[] The Page's elements
|
||||
*/
|
||||
public function getElementsRecursively(): array
|
||||
{
|
||||
return $this->getRenderablesRecursively();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new form element at the end of the section
|
||||
*
|
||||
* @param FormElementInterface $formElement The form element to add
|
||||
* @throws FormDefinitionConsistencyException if FormElement is already added to a section
|
||||
*/
|
||||
public function addElement(FormElementInterface $formElement)
|
||||
{
|
||||
$this->addRenderable($formElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a form element with the given $identifier and attach it to this section/page.
|
||||
*
|
||||
* - Create Form Element object based on the given $typeName
|
||||
* - set defaults inside the Form Element (based on the parent form's field defaults)
|
||||
* - attach Form Element to this Section/Page
|
||||
* - return the newly created Form Element object
|
||||
*
|
||||
*
|
||||
* @param string $identifier Identifier of the new form element
|
||||
* @param string $typeName type of the new form element
|
||||
* @return FormElementInterface the newly created form element
|
||||
* @throws TypeDefinitionNotFoundException
|
||||
* @throws TypeDefinitionNotValidException
|
||||
*/
|
||||
public function createElement(string $identifier, string $typeName): FormElementInterface
|
||||
{
|
||||
$formDefinition = $this->getRootForm();
|
||||
|
||||
$typeDefinitions = $formDefinition->getTypeDefinitions();
|
||||
if (isset($typeDefinitions[$typeName])) {
|
||||
$typeDefinition = $typeDefinitions[$typeName];
|
||||
} else {
|
||||
$renderingOptions = $formDefinition->getRenderingOptions();
|
||||
$skipUnknownElements = isset($renderingOptions['skipUnknownElements']) && $renderingOptions['skipUnknownElements'] === true;
|
||||
if (!$skipUnknownElements) {
|
||||
throw new TypeDefinitionNotFoundException(sprintf('Type "%s" not found. Probably some configuration is missing.', $typeName), 1382364019);
|
||||
}
|
||||
|
||||
$element = GeneralUtility::makeInstance(UnknownFormElement::class, $identifier, $typeName);
|
||||
$this->addElement($element);
|
||||
return $element;
|
||||
}
|
||||
|
||||
if (!isset($typeDefinition['implementationClassName'])) {
|
||||
throw new TypeDefinitionNotFoundException(sprintf('The "implementationClassName" was not set in type definition "%s".', $typeName), 1325689855);
|
||||
}
|
||||
|
||||
$implementationClassName = $typeDefinition['implementationClassName'];
|
||||
$element = GeneralUtility::makeInstance($implementationClassName, $identifier, $typeName);
|
||||
if (!$element instanceof FormElementInterface) {
|
||||
throw new TypeDefinitionNotValidException(sprintf('The "implementationClassName" for element "%s" ("%s") does not implement the FormElementInterface.', $identifier, $implementationClassName), 1327318156);
|
||||
}
|
||||
unset($typeDefinition['implementationClassName']);
|
||||
|
||||
$this->addElement($element);
|
||||
$element->setOptions($typeDefinition);
|
||||
|
||||
$element->initializeFormElement();
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move FormElement $element before $referenceElement.
|
||||
*
|
||||
* Both $element and $referenceElement must be direct descendants of this Section/Page.
|
||||
*
|
||||
* @param FormElementInterface $elementToMove
|
||||
* @param FormElementInterface $referenceElement
|
||||
*/
|
||||
public function moveElementBefore(FormElementInterface $elementToMove, FormElementInterface $referenceElement)
|
||||
{
|
||||
$this->moveRenderableBefore($elementToMove, $referenceElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move FormElement $element after $referenceElement
|
||||
*
|
||||
* Both $element and $referenceElement must be direct descendants of this Section/Page.
|
||||
*
|
||||
* @param FormElementInterface $elementToMove
|
||||
* @param FormElementInterface $referenceElement
|
||||
*/
|
||||
public function moveElementAfter(FormElementInterface $elementToMove, FormElementInterface $referenceElement)
|
||||
{
|
||||
$this->moveRenderableAfter($elementToMove, $referenceElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove $elementToRemove from this Section/Page
|
||||
*/
|
||||
public function removeElement(FormElementInterface $elementToRemove)
|
||||
{
|
||||
$this->removeRenderable($elementToRemove);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user