first commit
This commit is contained in:
commit
1218dd1517
12716 files changed
+989233
No files matched your search
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers\Be;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Backend\View\PageLayoutView;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Used by the form editor.
|
||||
* Render a content element preview like the page module
|
||||
*
|
||||
* Scope: backend
|
||||
* @internal
|
||||
*/
|
||||
class RenderContentElementPreviewViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* As this ViewHelper renders HTML, the output must not be escaped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('contentElementUid', 'int', 'The uid of a content element');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
* @internal
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
$content = '';
|
||||
$contentElementUid = $arguments['contentElementUid'];
|
||||
$contentRecord = BackendUtility::getRecord('tt_content', $contentElementUid);
|
||||
if (!empty($contentRecord)) {
|
||||
$pageLayoutView = GeneralUtility::makeInstance(PageLayoutView::class);
|
||||
$content = $pageLayoutView->tt_content_drawItem($contentRecord);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
|
||||
use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper;
|
||||
|
||||
/**
|
||||
* Display a jQuery date picker.
|
||||
*
|
||||
* Note: Requires jQuery UI to be included on the page.
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class DatePickerViewHelper extends AbstractFormFieldViewHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'input';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Property\PropertyMapper
|
||||
*/
|
||||
protected $propertyMapper;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
|
||||
* @internal
|
||||
*/
|
||||
public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper)
|
||||
{
|
||||
$this->propertyMapper = $propertyMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerTagAttribute('size', 'int', 'The size of the input field');
|
||||
$this->registerTagAttribute('placeholder', 'string', 'Specifies a short hint that describes the expected value of an input element');
|
||||
$this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this ViewHelper', false, 'f3-form-error');
|
||||
$this->registerArgument('initialDate', 'string', 'Initial date (@see http://www.php.net/manual/en/datetime.formats.php for supported formats)');
|
||||
$this->registerArgument('enableDatePicker', 'bool', 'Enable the Datepicker', false, true);
|
||||
$this->registerArgument('previewMode', 'bool', 'Preview mde flag', true, false);
|
||||
$this->registerArgument('dateFormat', 'string', 'The date format', false, 'Y-m-d');
|
||||
$this->registerUniversalTagAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the text field, hidden field and required javascript
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$enableDatePicker = $this->arguments['enableDatePicker'];
|
||||
$dateFormat = $this->arguments['dateFormat'];
|
||||
$previewMode = (bool)$this->arguments['previewMode'];
|
||||
$placeholder = $this->arguments['additionalAttributes']['placeholder'] ?? $this->arguments['placeholder'];
|
||||
|
||||
$name = $this->getName();
|
||||
$this->registerFieldNameForFormTokenGeneration($name);
|
||||
|
||||
$this->tag->addAttribute('type', 'text');
|
||||
$this->tag->addAttribute('name', $name . '[date]');
|
||||
|
||||
if ($this->hasArgument('id')) {
|
||||
$id = $this->arguments['id'];
|
||||
} else {
|
||||
$id = 'field' . md5(uniqid());
|
||||
}
|
||||
|
||||
if (empty($placeholder)) {
|
||||
$this->tag->addAttribute('placeholder', $dateFormat);
|
||||
}
|
||||
|
||||
if ($enableDatePicker) {
|
||||
$this->tag->addAttribute('readonly', 'readonly');
|
||||
if (!$previewMode) {
|
||||
$datePickerDateFormat = $this->convertDateFormatToDatePickerFormat($dateFormat);
|
||||
$this->renderInlineJavascript($id, $datePickerDateFormat);
|
||||
}
|
||||
}
|
||||
$date = $this->getSelectedDate();
|
||||
if ($date !== null) {
|
||||
$this->tag->addAttribute('value', $date->format($dateFormat));
|
||||
}
|
||||
|
||||
$this->tag->addAttribute('id', $id);
|
||||
|
||||
$this->setErrorClassAttribute();
|
||||
$content = '';
|
||||
$content .= $this->tag->render();
|
||||
$content .= '<input type="hidden" name="' . htmlspecialchars($name) . '[dateFormat]" value="' . htmlspecialchars($dateFormat) . '" />';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
protected function getSelectedDate()
|
||||
{
|
||||
/** @var FormRuntime $formRuntime */
|
||||
$formRuntime = $this->renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(RenderRenderableViewHelper::class, 'formRuntime');
|
||||
|
||||
$formState = $formRuntime->getFormState();
|
||||
|
||||
$date = $formRuntime[$this->arguments['property']];
|
||||
if ($date instanceof \DateTime) {
|
||||
return $date;
|
||||
}
|
||||
if ($date !== null) {
|
||||
$date = $this->propertyMapper->convert($date, 'DateTime');
|
||||
if (!$date instanceof \DateTime) {
|
||||
return null;
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
if ($this->hasArgument('initialDate')) {
|
||||
return new \DateTime($this->arguments['initialDate']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dateFormat
|
||||
* @return string
|
||||
*/
|
||||
protected function convertDateFormatToDatePickerFormat(string $dateFormat): string
|
||||
{
|
||||
$replacements = [
|
||||
'd' => 'dd',
|
||||
'D' => 'D',
|
||||
'j' => 'o',
|
||||
'l' => 'DD',
|
||||
|
||||
'F' => 'MM',
|
||||
'm' => 'mm',
|
||||
'M' => 'M',
|
||||
'n' => 'm',
|
||||
|
||||
'Y' => 'yy',
|
||||
'y' => 'y'
|
||||
];
|
||||
return strtr($dateFormat, $replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uniqueIdentifier
|
||||
* @param string $datePickerDateFormat
|
||||
*/
|
||||
protected function renderInlineJavascript(string $uniqueIdentifier, string $datePickerDateFormat)
|
||||
{
|
||||
$this->getPageRenderer()->addJsFooterInlineCode(
|
||||
'ext_form_datepicker-' . $uniqueIdentifier,
|
||||
'if ("undefined" !== typeof $) {
|
||||
$(function() {
|
||||
$("#' . $uniqueIdentifier . '").datepicker({
|
||||
dateFormat: "' . $datePickerDateFormat . '"
|
||||
}).on("keydown", function(e) {
|
||||
// By using "backspace" or "delete", you can clear the datepicker again.
|
||||
if(e.keyCode == 8 || e.keyCode == 46) {
|
||||
e.preventDefault();
|
||||
$.datepicker._clearDate(this);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PageRenderer
|
||||
*/
|
||||
protected function getPageRenderer(): PageRenderer
|
||||
{
|
||||
return GeneralUtility::makeInstance(PageRenderer::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
|
||||
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
|
||||
use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper;
|
||||
|
||||
/**
|
||||
* Displays two select-boxes for hour and minute selection.
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class TimePickerViewHelper extends AbstractFormFieldViewHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'select';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Property\PropertyMapper
|
||||
*/
|
||||
protected $propertyMapper;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
|
||||
* @internal
|
||||
*/
|
||||
public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper)
|
||||
{
|
||||
$this->propertyMapper = $propertyMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerTagAttribute('size', 'int', 'The size of the select field');
|
||||
$this->registerTagAttribute('placeholder', 'string', 'Specifies a short hint that describes the expected value of an input element');
|
||||
$this->registerTagAttribute('disabled', 'string', 'Specifies that the select element should be disabled when the page loads');
|
||||
$this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this ViewHelper', false, 'f3-form-error');
|
||||
$this->registerArgument('initialDate', 'string', 'Initial time (@see http://www.php.net/manual/en/datetime.formats.php for supported formats)');
|
||||
$this->registerArgument('timeType', 'string', '"hour" or "minute"');
|
||||
$this->registerUniversalTagAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the select fields for hour & minute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$name = $this->getName();
|
||||
$this->registerFieldNameForFormTokenGeneration($name);
|
||||
$this->tag->addAttribute('name', $name . '[hour]');
|
||||
|
||||
$date = $this->getSelectedDate();
|
||||
$this->setErrorClassAttribute();
|
||||
|
||||
$content = '';
|
||||
|
||||
if ($this->arguments['timeType'] === 'hour') {
|
||||
$content .= $this->buildHourSelector($date);
|
||||
} else {
|
||||
$content .= $this->buildMinuteSelector($date);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
protected function getSelectedDate()
|
||||
{
|
||||
/** @var FormRuntime $formRuntime */
|
||||
$formRuntime = $this->renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(RenderRenderableViewHelper::class, 'formRuntime');
|
||||
|
||||
$date = $formRuntime[$this->arguments['property']];
|
||||
if ($date instanceof \DateTime) {
|
||||
return $date;
|
||||
}
|
||||
if ($date !== null) {
|
||||
$date = $this->propertyMapper->convert($date, 'DateTime');
|
||||
if (!$date instanceof \DateTime) {
|
||||
return null;
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
if ($this->hasArgument('initialDate')) {
|
||||
return new \DateTime($this->arguments['initialDate']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $date
|
||||
* @return string
|
||||
*/
|
||||
protected function buildHourSelector(\DateTime $date = null): string
|
||||
{
|
||||
$value = $date !== null ? $date->format('H') : null;
|
||||
$hourSelector = clone $this->tag;
|
||||
$hourSelector->addAttribute('name', sprintf('%s[hour]', $this->getName()));
|
||||
$options = '';
|
||||
foreach (range(0, 23) as $hour) {
|
||||
$hour = str_pad((string)$hour, 2, '0', STR_PAD_LEFT);
|
||||
$selected = $hour === $value ? ' selected="selected"' : '';
|
||||
$options .= '<option value="' . htmlspecialchars($hour) . '" ' . $selected . '>' . htmlspecialchars($hour) . '</option>';
|
||||
}
|
||||
$hourSelector->setContent($options);
|
||||
return $hourSelector->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $date
|
||||
* @return string
|
||||
*/
|
||||
protected function buildMinuteSelector(\DateTime $date = null): string
|
||||
{
|
||||
$value = $date !== null ? $date->format('i') : null;
|
||||
$minuteSelector = clone $this->tag;
|
||||
if ($this->hasArgument('id')) {
|
||||
$minuteSelector->addAttribute('id', $this->arguments['id'] . '-minute');
|
||||
}
|
||||
$minuteSelector->addAttribute('name', sprintf('%s[minute]', $this->getName()));
|
||||
$options = '';
|
||||
foreach (range(0, 59) as $minute) {
|
||||
$minute = str_pad((string)$minute, 2, '0', STR_PAD_LEFT);
|
||||
$selected = $minute === $value ? ' selected="selected"' : '';
|
||||
$options .= '<option value="' . htmlspecialchars($minute) . '"' . $selected . '>' . htmlspecialchars($minute) . '</option>';
|
||||
}
|
||||
$minuteSelector->setContent($options);
|
||||
return $minuteSelector->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers\Form;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
|
||||
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\Form\UploadViewHelper;
|
||||
|
||||
/**
|
||||
* This ViewHelper makes the specified Image object available for its
|
||||
* childNodes.
|
||||
* In case the form is redisplayed because of validation errors, a previously
|
||||
* uploaded image will be correctly used.
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class UploadedResourceViewHelper extends UploadViewHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @var HashService
|
||||
*/
|
||||
protected $hashService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Property\PropertyMapper
|
||||
*/
|
||||
protected $propertyMapper;
|
||||
|
||||
/**
|
||||
* @param HashService $hashService
|
||||
* @internal
|
||||
*/
|
||||
public function injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
|
||||
{
|
||||
$this->hashService = $hashService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
|
||||
* @internal
|
||||
*/
|
||||
public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper)
|
||||
{
|
||||
$this->propertyMapper = $propertyMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('as', 'string', '');
|
||||
$this->registerArgument('accept', 'array', 'Values for the accept attribute', false, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$output = '';
|
||||
|
||||
$as = $this->arguments['as'];
|
||||
$accept = $this->arguments['accept'];
|
||||
$resource = $this->getUploadedResource();
|
||||
|
||||
if (!empty($accept)) {
|
||||
$this->tag->addAttribute('accept', implode(',', $accept));
|
||||
}
|
||||
|
||||
if ($resource !== null) {
|
||||
$resourcePointerIdAttribute = '';
|
||||
if ($this->hasArgument('id')) {
|
||||
$resourcePointerIdAttribute = ' id="' . htmlspecialchars($this->arguments['id']) . '-file-reference"';
|
||||
}
|
||||
$resourcePointerValue = $resource->getUid();
|
||||
if ($resourcePointerValue === null) {
|
||||
// Newly created file reference which is not persisted yet.
|
||||
// Use the file UID instead, but prefix it with "file:" to communicate this to the type converter
|
||||
$resourcePointerValue = 'file:' . $resource->getOriginalResource()->getOriginalFile()->getUid();
|
||||
}
|
||||
$output .= '<input type="hidden" name="' . htmlspecialchars($this->getName()) . '[submittedFile][resourcePointer]" value="' . htmlspecialchars($this->hashService->appendHmac((string)$resourcePointerValue)) . '"' . $resourcePointerIdAttribute . ' />';
|
||||
|
||||
$this->templateVariableContainer->add($as, $resource);
|
||||
$output .= $this->renderChildren();
|
||||
$this->templateVariableContainer->remove($as);
|
||||
}
|
||||
|
||||
$output .= parent::render();
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a previously uploaded resource.
|
||||
* Return NULL if errors occurred during property mapping for this property.
|
||||
*
|
||||
* @return FileReference|null
|
||||
*/
|
||||
protected function getUploadedResource()
|
||||
{
|
||||
if ($this->getMappingResultsForProperty()->hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
$resource = $this->getValueAttribute();
|
||||
if ($resource instanceof FileReference) {
|
||||
return $resource;
|
||||
}
|
||||
return $this->propertyMapper->convert($resource, FileReference::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper as FluidFormViewHelper;
|
||||
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
|
||||
|
||||
/**
|
||||
* Custom form ViewHelper that renders the form state instead of referrer fields
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class FormViewHelper extends FluidFormViewHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* Renders hidden form fields for referrer information about
|
||||
* the current request.
|
||||
*
|
||||
* @return string Hidden fields with referrer information
|
||||
*/
|
||||
protected function renderHiddenReferrerFields()
|
||||
{
|
||||
$formRuntime = $this->getFormRuntime();
|
||||
$prefix = $this->prefixFieldName($this->getFormObjectName());
|
||||
|
||||
$markup = $this->createHiddenInputElement(
|
||||
$prefix . '[__state]',
|
||||
$this->hashService->appendHmac(
|
||||
base64_encode(serialize($formRuntime->getFormState()))
|
||||
)
|
||||
);
|
||||
|
||||
// ONLY assign `__session` if form is performing (uncached)
|
||||
if ($formRuntime->canProcessFormSubmission() && $formRuntime->getFormSession() !== null) {
|
||||
$markup .= $this->createHiddenInputElement(
|
||||
$prefix . '[__session]',
|
||||
$formRuntime->getFormSession()->getAuthenticatedIdentifier()
|
||||
);
|
||||
}
|
||||
return $markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function createHiddenInputElement(string $name, string $value): string
|
||||
{
|
||||
$tagBuilder = GeneralUtility::makeInstance(TagBuilder::class, 'input');
|
||||
$tagBuilder->addAttribute('type', 'hidden');
|
||||
$tagBuilder->addAttribute('name', $name);
|
||||
$tagBuilder->addAttribute('value', $value);
|
||||
return $tagBuilder->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* We do NOT return NULL as in this case, the Form ViewHelpers do not enter $objectAccessorMode.
|
||||
* However, we return the form identifier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFormObjectName()
|
||||
{
|
||||
return $this->getFormRuntime()->getFormDefinition()->getIdentifier();
|
||||
}
|
||||
|
||||
protected function getFormRuntime(): FormRuntime
|
||||
{
|
||||
return $this->arguments['object'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Form\Domain\Model\FormElements\GridContainerInterface;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Scope: frontend
|
||||
*/
|
||||
class GridColumnClassAutoConfigurationViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('element', RootRenderableInterface::class, 'A RootRenderableInterface instance', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$formElement = $arguments['element'];
|
||||
|
||||
$gridRowElement = $formElement->getParentRenderable();
|
||||
$gridContainerElement = $gridRowElement->getParentRenderable();
|
||||
$gridRowEChildElements = $gridRowElement->getElements();
|
||||
|
||||
if ($gridContainerElement instanceof GridContainerInterface) {
|
||||
$gridViewPortConfiguration = $gridContainerElement->getProperties()['gridColumnClassAutoConfiguration'];
|
||||
} else {
|
||||
$gridViewPortConfiguration = $gridRowElement->getProperties()['gridColumnClassAutoConfiguration'];
|
||||
}
|
||||
|
||||
if (empty($gridViewPortConfiguration)) {
|
||||
return '';
|
||||
}
|
||||
$gridSize = (int)$gridViewPortConfiguration['gridSize'];
|
||||
|
||||
$columnsToCalculate = [];
|
||||
$usedColumns = [];
|
||||
foreach ($gridRowEChildElements as $childElement) {
|
||||
if (empty($childElement->getProperties()['gridColumnClassAutoConfiguration'])) {
|
||||
foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
|
||||
$columnsToCalculate[$viewPortName]['elements']++;
|
||||
}
|
||||
} else {
|
||||
$gridColumnViewPortConfiguration = $childElement->getProperties()['gridColumnClassAutoConfiguration'];
|
||||
foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
|
||||
$configuration = $gridColumnViewPortConfiguration['viewPorts'][$viewPortName];
|
||||
if (
|
||||
isset($configuration['numbersOfColumnsToUse'])
|
||||
&& (int)$configuration['numbersOfColumnsToUse'] > 0
|
||||
) {
|
||||
$usedColumns[$viewPortName]['sum'] += (int)$configuration['numbersOfColumnsToUse'];
|
||||
if ($childElement->getIdentifier() === $formElement->getIdentifier()) {
|
||||
$usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] = (int)$configuration['numbersOfColumnsToUse'];
|
||||
if ($usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] > $gridSize) {
|
||||
$usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] = $gridSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$columnsToCalculate[$viewPortName]['elements']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$classes = [];
|
||||
foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
|
||||
if (isset($usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'])) {
|
||||
$numbersOfColumnsToUse = $usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'];
|
||||
} else {
|
||||
$restColumnsToDivide = $gridSize - $usedColumns[$viewPortName]['sum'];
|
||||
$restElements = (int)$columnsToCalculate[$viewPortName]['elements'];
|
||||
|
||||
if ($restColumnsToDivide < 1) {
|
||||
$restColumnsToDivide = $gridSize;
|
||||
}
|
||||
if ($restElements < 1) {
|
||||
$restElements = 1;
|
||||
}
|
||||
$numbersOfColumnsToUse = floor($restColumnsToDivide / $restElements);
|
||||
}
|
||||
|
||||
$classes[] = str_replace(
|
||||
'{@numbersOfColumnsToUse}',
|
||||
$numbersOfColumnsToUse,
|
||||
$configuration['classPattern']
|
||||
);
|
||||
}
|
||||
|
||||
return implode(' ', $classes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
|
||||
use TYPO3\CMS\Form\Domain\Model\FormElements\FormElementInterface;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Renders the values of a form
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class RenderAllFormValuesViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('renderable', RootRenderableInterface::class, 'A RootRenderableInterface instance', true);
|
||||
$this->registerArgument('as', 'string', 'The name within the template', false, 'formValue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array element by key.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string the rendered form values
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
$renderable = $arguments['renderable'];
|
||||
$as = $arguments['as'];
|
||||
|
||||
if (!$renderable->isEnabled()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($renderable instanceof CompositeRenderableInterface) {
|
||||
$elements = $renderable->getRenderablesRecursively();
|
||||
} else {
|
||||
$elements = [$renderable];
|
||||
}
|
||||
|
||||
$formRuntime = $renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(RenderRenderableViewHelper::class, 'formRuntime');
|
||||
|
||||
$output = '';
|
||||
foreach ($elements as $element) {
|
||||
$renderingOptions = $element->getRenderingOptions();
|
||||
|
||||
if (
|
||||
!$element instanceof FormElementInterface
|
||||
|| (isset($renderingOptions['_isCompositeFormElement']) && (bool)$renderingOptions['_isCompositeFormElement'] === true)
|
||||
|| !$element->isEnabled()
|
||||
|| self::hasDisabledParent($element)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
(isset($renderingOptions['_isHiddenFormElement']) && (bool)$renderingOptions['_isHiddenFormElement'] === true)
|
||||
|| (isset($renderingOptions['_isReadOnlyFormElement']) && (bool)$renderingOptions['_isReadOnlyFormElement'] === true)
|
||||
) {
|
||||
trigger_error(
|
||||
'Using the properties "renderingOptions._isHiddenFormElement" and "renderingOptions._isReadOnlyFormElement" will be removed in TYPO3 v10.0. Use variants instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $formRuntime[$element->getIdentifier()];
|
||||
|
||||
$formValue = [
|
||||
'element' => $element,
|
||||
'value' => $value,
|
||||
'processedValue' => self::processElementValue($element, $value, $renderChildrenClosure, $renderingContext),
|
||||
'isMultiValue' => is_array($value) || $value instanceof \Iterator
|
||||
];
|
||||
$renderingContext->getVariableProvider()->add($as, $formValue);
|
||||
$output .= $renderChildrenClosure();
|
||||
$renderingContext->getVariableProvider()->remove($as);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to a simple type (string or array) considering the underlying FormElement definition
|
||||
*
|
||||
* @param FormElementInterface $element
|
||||
* @param mixed $value
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
* @internal
|
||||
*/
|
||||
public static function processElementValue(
|
||||
FormElementInterface $element,
|
||||
$value,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$properties = $element->getProperties();
|
||||
if (isset($properties['options']) && is_array($properties['options'])) {
|
||||
$properties['options'] = TranslateElementPropertyViewHelper::renderStatic(
|
||||
['element' => $element, 'property' => 'options'],
|
||||
$renderChildrenClosure,
|
||||
$renderingContext
|
||||
);
|
||||
if (is_array($value)) {
|
||||
return self::mapValuesToOptions($value, $properties['options']);
|
||||
}
|
||||
return self::mapValueToOption($value, $properties['options']);
|
||||
}
|
||||
if (is_object($value)) {
|
||||
return self::processObject($element, $value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the given values (=keys) with the corresponding elements in $options
|
||||
* @see mapValueToOption()
|
||||
*
|
||||
* @param array $value
|
||||
* @param array $options
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
public static function mapValuesToOptions(array $value, array $options): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($value as $key) {
|
||||
$result[] = self::mapValueToOption($key, $options);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the given value (=key) with the corresponding element in $options
|
||||
* If the key does not exist in $options, it is returned without modification
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array $options
|
||||
* @return mixed
|
||||
* @internal
|
||||
*/
|
||||
public static function mapValueToOption($value, array $options)
|
||||
{
|
||||
return $options[$value] ?? $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given $object to a string representation considering the $element FormElement definition
|
||||
*
|
||||
* @param FormElementInterface $element
|
||||
* @param object $object
|
||||
* @return string
|
||||
* @internal
|
||||
*/
|
||||
public static function processObject(FormElementInterface $element, $object): string
|
||||
{
|
||||
$properties = $element->getProperties();
|
||||
if ($object instanceof \DateTime) {
|
||||
if (
|
||||
$element->getType() === 'DatePicker'
|
||||
&& isset($properties['dateFormat'])
|
||||
) {
|
||||
$dateFormat = $properties['dateFormat'];
|
||||
if (isset($properties['displayTimeSelector']) && $properties['displayTimeSelector'] === true) {
|
||||
$dateFormat .= ' H:i';
|
||||
}
|
||||
} elseif ($element->getType() === 'Date') {
|
||||
if (isset($properties['displayFormat'])) {
|
||||
$dateFormat = $properties['displayFormat'];
|
||||
} else {
|
||||
$dateFormat = 'Y-m-d';
|
||||
}
|
||||
} else {
|
||||
$dateFormat = \DateTime::W3C;
|
||||
}
|
||||
|
||||
return $object->format($dateFormat);
|
||||
}
|
||||
|
||||
if ($object instanceof File || $object instanceof FileReference) {
|
||||
if ($object instanceof FileReference) {
|
||||
$object = $object->getOriginalResource();
|
||||
}
|
||||
return $object->getName();
|
||||
}
|
||||
|
||||
if (method_exists($object, '__toString')) {
|
||||
return (string)$object;
|
||||
}
|
||||
return 'Object [' . get_class($object) . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RenderableInterface $renderable
|
||||
* @return bool
|
||||
* @internal
|
||||
*/
|
||||
public static function hasDisabledParent(RenderableInterface $renderable): bool
|
||||
{
|
||||
while ($renderable = $renderable->getParentRenderable()) {
|
||||
if ($renderable instanceof RenderableInterface && !$renderable->isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Render a renderable.
|
||||
*
|
||||
* Set the renderable into the \TYPO3\CMS\Form\Mvc\View\FormView
|
||||
* and return the rendered content.
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class RenderRenderableViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('renderable', RootRenderableInterface::class, 'A RenderableInterface instance', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
* @internal
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
|
||||
/** @var FormRuntime $formRuntime */
|
||||
$formRuntime = $renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(self::class, 'formRuntime');
|
||||
|
||||
$renderable = $arguments['renderable'];
|
||||
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'] ?? [] as $className) {
|
||||
$hookObj = GeneralUtility::makeInstance($className);
|
||||
if (method_exists($hookObj, 'beforeRendering')) {
|
||||
$hookObj->beforeRendering(
|
||||
$formRuntime,
|
||||
$renderable
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
if ($renderable instanceof FormRuntime || $renderable instanceof RenderableInterface && $renderable->isEnabled()) {
|
||||
$content = $renderChildrenClosure();
|
||||
}
|
||||
|
||||
// Wrap every renderable with a span with a identifier path data attribute if previewMode is active
|
||||
if (!empty($content)) {
|
||||
$renderingOptions = $formRuntime->getRenderingOptions();
|
||||
if (isset($renderingOptions['previewMode']) && $renderingOptions['previewMode'] === true) {
|
||||
$path = $renderable->getIdentifier();
|
||||
if ($renderable instanceof RenderableInterface) {
|
||||
while ($renderable = $renderable->getParentRenderable()) {
|
||||
$path = $renderable->getIdentifier() . '/' . $path;
|
||||
}
|
||||
}
|
||||
$content = '<span data-element-identifier-path="' . $path . '">' . $content . '</span>';
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It originated from the Neos.Form package (www.neos.io)
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\Response;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory;
|
||||
use TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Main Entry Point to render a Form into a Fluid Template
|
||||
*
|
||||
* Usage
|
||||
* =====
|
||||
*
|
||||
* Default::
|
||||
*
|
||||
* {namespace formvh=TYPO3\CMS\Form\ViewHelpers}
|
||||
* <formvh:render factoryClass="NameOfYourCustomFactoryClass" />
|
||||
*
|
||||
* The factory class must implement :php:`TYPO3\CMS\Form\Domain\Factory\FormFactoryInterface`.
|
||||
*
|
||||
* Scope: frontend
|
||||
*/
|
||||
class RenderViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize the arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('persistenceIdentifier', 'string', 'The persistence identifier for the form.', false, null);
|
||||
$this->registerArgument('factoryClass', 'string', 'The fully qualified class name of the factory', false, ArrayFormFactory::class);
|
||||
$this->registerArgument('prototypeName', 'string', 'Name of the prototype to use', false, null);
|
||||
$this->registerArgument('overrideConfiguration', 'array', 'factory specific configuration', false, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
$persistenceIdentifier = $arguments['persistenceIdentifier'];
|
||||
$factoryClass = $arguments['factoryClass'];
|
||||
$prototypeName = $arguments['prototypeName'];
|
||||
$overrideConfiguration = $arguments['overrideConfiguration'];
|
||||
|
||||
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
|
||||
if (!empty($persistenceIdentifier)) {
|
||||
$formPersistenceManager = $objectManager->get(FormPersistenceManagerInterface::class);
|
||||
$formConfiguration = $formPersistenceManager->load($persistenceIdentifier);
|
||||
ArrayUtility::mergeRecursiveWithOverrule(
|
||||
$formConfiguration,
|
||||
$overrideConfiguration
|
||||
);
|
||||
$overrideConfiguration = $formConfiguration;
|
||||
$overrideConfiguration['persistenceIdentifier'] = $persistenceIdentifier;
|
||||
}
|
||||
|
||||
if (empty($prototypeName)) {
|
||||
$prototypeName = $overrideConfiguration['prototypeName'] ?? 'standard';
|
||||
}
|
||||
|
||||
$factory = $objectManager->get($factoryClass);
|
||||
$formDefinition = $factory->build($overrideConfiguration, $prototypeName);
|
||||
$response = $renderingContext->getControllerContext()->getResponse() ?? $objectManager->get(Response::class);
|
||||
$form = $formDefinition->bind($renderingContext->getControllerContext()->getRequest(), $response);
|
||||
|
||||
// If the controller context does not contain a response object, this viewhelper is used in a
|
||||
// fluid template rendered by the FluidTemplateContentObject. Handle the StopActionException
|
||||
// as there is no extbase dispatcher involved that catches that. */
|
||||
if ($renderingContext->getControllerContext()->getResponse() === null) {
|
||||
try {
|
||||
return $form->render();
|
||||
} catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
|
||||
return $response->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
return $form->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Error\Error;
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
|
||||
use TYPO3\CMS\Form\Service\TranslationService;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Translate form element properites.
|
||||
*
|
||||
* Scope: frontend / backend
|
||||
*/
|
||||
class TranslateElementErrorViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('element', RootRenderableInterface::class, 'Form Element to translate', true);
|
||||
$this->registerArgument('error', Error::class, '', false, '');
|
||||
$this->registerArgument('code', 'integer', 'Error code - deprecated', false, '');
|
||||
$this->registerArgument('arguments', 'array', 'Error arguments - deprecated', false, null);
|
||||
$this->registerArgument('defaultValue', 'string', 'The default value - deprecated', false, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array element by key.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
$element = $arguments['element'];
|
||||
$error = $arguments['error'];
|
||||
|
||||
$code = $arguments['code'];
|
||||
$errorArguments = $arguments['arguments'];
|
||||
$defaultValue = $arguments['defaultValue'];
|
||||
|
||||
if ($error instanceof Error) {
|
||||
$code = $error->getCode();
|
||||
$errorArguments = $error->getArguments();
|
||||
$defaultValue = $error->__toString();
|
||||
} else {
|
||||
trigger_error(
|
||||
'TranslateElementErrorViewHelper arguments "code", "arguments" and "defaultValue" will be removed in TYPO3 v10.0. Use "error" instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
}
|
||||
|
||||
/** @var FormRuntime $formRuntime */
|
||||
$formRuntime = $renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(RenderRenderableViewHelper::class, 'formRuntime');
|
||||
|
||||
return TranslationService::getInstance()->translateFormElementError(
|
||||
$element,
|
||||
$code,
|
||||
$errorArguments,
|
||||
$defaultValue,
|
||||
$formRuntime
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Form\ViewHelpers;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
|
||||
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
|
||||
use TYPO3\CMS\Form\Service\TranslationService;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Translate form element properties.
|
||||
*
|
||||
* Scope: frontend / backend
|
||||
*/
|
||||
class TranslateElementPropertyViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('element', RootRenderableInterface::class, 'Form Element to translate', true);
|
||||
$this->registerArgument('property', 'mixed', 'Property to translate', false);
|
||||
$this->registerArgument('renderingOptionProperty', 'mixed', 'Property to translate', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array element by key.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string|array
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
static::assertArgumentTypes($arguments);
|
||||
|
||||
$element = $arguments['element'];
|
||||
|
||||
$property = null;
|
||||
if (!empty($arguments['property'])) {
|
||||
$property = $arguments['property'];
|
||||
} elseif (!empty($arguments['renderingOptionProperty'])) {
|
||||
$property = $arguments['renderingOptionProperty'];
|
||||
}
|
||||
|
||||
if (empty($property)) {
|
||||
$propertyParts = [];
|
||||
} elseif (is_array($property)) {
|
||||
$propertyParts = $property;
|
||||
} else {
|
||||
$propertyParts = [$property];
|
||||
}
|
||||
|
||||
/** @var FormRuntime $formRuntime */
|
||||
$formRuntime = $renderingContext
|
||||
->getViewHelperVariableContainer()
|
||||
->get(RenderRenderableViewHelper::class, 'formRuntime');
|
||||
|
||||
return TranslationService::getInstance()->translateFormElementValue($element, $propertyParts, $formRuntime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
*/
|
||||
protected static function assertArgumentTypes(array $arguments)
|
||||
{
|
||||
foreach (['property', 'renderingOptionProperty'] as $argumentName) {
|
||||
if (
|
||||
!isset($arguments[$argumentName])
|
||||
|| is_string($arguments[$argumentName])
|
||||
|| is_array($arguments[$argumentName])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Arguments "%s" either must be string or array',
|
||||
$argumentName
|
||||
),
|
||||
1504871830
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user