Make compatible with TYPO3 13.0

This commit is contained in:
Sebastian Fischer 2024-04-28 18:49:46 +02:00
parent 9a9b4a7bcb
commit f7c940a828
29 changed files with 432 additions and 731 deletions

View File

@ -36,10 +36,10 @@ class ContentElementCommand extends Command
parent::__construct(); parent::__construct();
} }
protected function configure() protected function configure(): void
{ {
$this $this
->setAliases(['kc-sitepackage']) ->setAliases(['ce'])
->addOption( ->addOption(
'pageId', 'pageId',
'-p', '-p',

View File

@ -12,8 +12,6 @@ namespace Evoweb\EwBase\Configuration;
* of the License, or any later version. * of the License, or any later version.
*/ */
use Mfc\OAuth2\ResourceServer\GitLab;
use Mfc\OAuth2\ResourceServer\Registry;
use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -22,24 +20,6 @@ class AdditionalConfiguration
{ {
protected string $extensionKey = 'ew_base'; protected string $extensionKey = 'ew_base';
protected array $oauthOptions = [
'enabled' => true, // Enable/Disable the provider
'arguments' => [
'appId' => '',
'appSecret' => '',
'projectName' => '',
'gitlabServer' => 'https://github.com',
// User level at which the user will be given admin permissions
'gitlabAdminUserLevel' => 30,
// Groups to assign to the User (comma separated list possible)
'gitlabDefaultGroups' => 1,
// UserConfig db and/or file mount from groups
'gitlabUserOption' => 3,
// Blocks users with flag external from access the backend
'blockExternalUser' => false,
],
];
protected array $developConfig = [ protected array $developConfig = [
'BE' => [ 'BE' => [
'debug' => true, 'debug' => true,
@ -169,19 +149,6 @@ class AdditionalConfiguration
} }
} }
public function addGitlabLogin(array $options = []): void
{
if (!empty($options)) {
$this->oauthOptions['arguments']['gitlabAdminUserLevel'] = GitLab::USER_LEVEL_DEVELOPER;
Registry::addServer(
'gitlab',
'Login mit GitLab',
GitLab::class,
$this->arrayMergeRecursive($this->oauthOptions, $options)
);
}
}
protected function arrayMergeRecursive(array $array1, array $array2): array protected function arrayMergeRecursive(array $array1, array $array2): array
{ {
$merged = $array1; $merged = $array1;

View File

@ -2,7 +2,7 @@
namespace Evoweb\EwBase\EventListener; namespace Evoweb\EwBase\EventListener;
use TYPO3\CMS\Backend\ViEvoweb\Event\IsContentUsedOnPageLayoutEvent; use TYPO3\CMS\Backend\View\Event\IsContentUsedOnPageLayoutEvent;
class IsContentUsedOnPageLayout class IsContentUsedOnPageLayout
{ {
@ -15,7 +15,7 @@ class IsContentUsedOnPageLayout
{ {
$found = false; $found = false;
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['ContentUsedStrings'] ?? [] as $search) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['ContentUsedStrings'] ?? [] as $search) {
if (strpos($cType, $search) !== false) { if (str_contains($cType, $search)) {
$found = true; $found = true;
break; break;
} }

View File

@ -15,8 +15,12 @@ namespace Evoweb\EwBase\Form\Element;
* LICENSE.txt file that was distributed with this source code. * LICENSE.txt file that was distributed with this source code.
*/ */
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement; use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
use TYPO3\CMS\Backend\Form\NodeFactory; use TYPO3\CMS\Backend\Form\Event\ModifyImageManipulationPreviewUrlEvent;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\View\BackendViewFactory;
use TYPO3\CMS\Core\Crypto\HashService;
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area; use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection; use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
use TYPO3\CMS\Core\Imaging\ImageManipulation\InvalidConfigurationException; use TYPO3\CMS\Core\Imaging\ImageManipulation\InvalidConfigurationException;
@ -27,15 +31,13 @@ use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\StringUtility; use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3Fluid\Fluid\ViEvoweb\TemplateView;
use TYPO3Fluid\Fluid\ViEvoweb\ViewInterface;
class PickColorFromImage extends AbstractFormElement class PickColorFromImage extends AbstractFormElement
{ {
private string $wizardRouteName = 'ajax_wizard_image_manipulation';
/** /**
* Default element configuration * Default element configuration
*
* @var array
*/ */
protected static array $defaultConfig = [ protected static array $defaultConfig = [
'imageField' => 'image', 'imageField' => 'image',
@ -110,53 +112,31 @@ class PickColorFromImage extends AbstractFormElement
], ],
]; ];
protected ViewInterface $templateView; public function __construct(
private readonly BackendViewFactory $backendViewFactory,
public function __construct(NodeFactory $nodeFactory, array $data) private readonly UriBuilder $uriBuilder,
{ private readonly EventDispatcherInterface $eventDispatcher,
parent::__construct($nodeFactory, $data); private readonly ResourceFactory $resourceFactory,
// Would be great, if we could inject the view here, but since the constructor is in the interface, we can't private readonly HashService $hashService,
// @todo: It's unfortunate we're using Typo3Fluid TemplateView directly here. We can't ) {}
// inject BackendViewFactory here since __construct() is polluted by NodeInterface.
// Remove __construct() from NodeInterface to have DI, then use BackendViewFactory here.
$view = GeneralUtility::makeInstance(TemplateView::class);
$templatePaths = $view->getRenderingContext()->getTemplatePaths();
$templatePaths
->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Templates')]);
$templatePaths
->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Partials')]);
$this->templateView = $view;
}
/**
* @throws InvalidConfigurationException
*/
public function render(): array public function render(): array
{ {
$resultArray = $this->initializeResultArray(); $resultArray = $this->initializeResultArray();
$parameterArray = $this->data['parameterArray']; $parameterArray = $this->data['parameterArray'];
$config = $this->populateConfiguration($parameterArray['fieldConf']['config']); $config = $this->populateConfiguration($parameterArray['fieldConf']['config']);
$fieldId = StringUtility::getUniqueId('formengine-color-');
$file = $this->getFileObject($this->data['databaseRow'], $config['imageField']); $file = $this->getFile($this->data['databaseRow'], $config['imageField']);
if (!$file) { if (!$file) {
$languageService = $this->getLanguageService();
$label = $languageService->sL(
'LLL:EXT:ew_base/Resources/Private/Language/locallang_db.xlf:imageField.empty'
);
$fieldLabel = $this->data['processedTca']['columns'][$config['imageField']]['label'];
$resultArray['html'] = '
<div class="form-control-wrap">
<div class="form-wizards-wrap">
<div class="form-wizards-element">
<typo3-formengine-element-pick-color recordFieldId="' . htmlspecialchars($fieldId) . '">
' . sprintf($label, '<strong>' . $fieldLabel . '</strong>') . '
</typo3-formengine-element-pick-color>
</div>
</div>
</div>
';
// Early return in case we do not find a file // Early return in case we do not find a file
return $resultArray; return $resultArray;
} }
$config = $this->processConfiguration($config, $parameterArray['itemFormElValue'], $file);
$fieldInformationResult = $this->renderFieldInformation(); $fieldInformationResult = $this->renderFieldInformation();
$fieldInformationHtml = $fieldInformationResult['html']; $fieldInformationHtml = $fieldInformationResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
@ -169,14 +149,6 @@ class PickColorFromImage extends AbstractFormElement
$fieldWizardHtml = $fieldWizardResult['html']; $fieldWizardHtml = $fieldWizardResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
$width = $this->formMaxWidth(
MathUtility::forceIntegerInRange(
$config['size'] ?? $this->defaultInputWidth,
$this->minimumInputWidth,
$this->maxInputWidth
)
);
$arguments = [ $arguments = [
'fieldInformation' => $fieldInformationHtml, 'fieldInformation' => $fieldInformationHtml,
'fieldControl' => $fieldControlHtml, 'fieldControl' => $fieldControlHtml,
@ -195,10 +167,15 @@ class PickColorFromImage extends AbstractFormElement
'validation' => '[]', 'validation' => '[]',
], ],
'config' => $config, 'config' => $config,
'width' => $width, 'wizardUri' => $this->getWizardUri(),
'wizardPayload' => json_encode($this->getWizardPayload($config['cropVariants'], $file)),
'previewUrl' => $this->eventDispatcher->dispatch(
new ModifyImageManipulationPreviewUrlEvent($this->data['databaseRow'], $config, $file)
)->getPreviewUrl(),
]; ];
if ($arguments['isAllowedFileExtension']) { if ($arguments['isAllowedFileExtension']) {
$fieldId = StringUtility::getUniqueId('formengine-color-');
$resultArray['stylesheetFiles'][] = $resultArray['stylesheetFiles'][] =
'EXT:ew_base/Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css'; 'EXT:ew_base/Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css';
$resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create( $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create(
@ -214,14 +191,14 @@ class PickColorFromImage extends AbstractFormElement
$arguments['formEngine']['validation'] = $this->getValidationDataAsJsonString(['required' => true]); $arguments['formEngine']['validation'] = $this->getValidationDataAsJsonString(['required' => true]);
} }
} }
$view = $this->backendViewFactory->create($this->data['request']);
$this->templateView->assignMultiple($arguments); $view->assignMultiple($arguments);
$resultArray['html'] = $this->templateView->render('Form/ImageManipulationElement'); $resultArray['html'] = $view->render('Form/ImageManipulationElement');
return $resultArray; return $resultArray;
} }
protected function getFileObject(array $row, string $fieldName): ?File protected function getFile(array $row, string $fieldName): ?File
{ {
$file = null; $file = null;
$fileUid = !empty($row[$fieldName]) ? $row[$fieldName] : null; $fileUid = !empty($row[$fieldName]) ? $row[$fieldName] : null;
@ -230,21 +207,26 @@ class PickColorFromImage extends AbstractFormElement
} }
if (MathUtility::canBeInterpretedAsInteger($fileUid)) { if (MathUtility::canBeInterpretedAsInteger($fileUid)) {
try { try {
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class); $file = $this->resourceFactory->getFileObject($fileUid);
$fileReference = $resourceFactory->getFileReferenceObject($fileUid);
$file = $fileReference->getOriginalFile();
} catch (FileDoesNotExistException | \InvalidArgumentException) { } catch (FileDoesNotExistException | \InvalidArgumentException) {
} }
} }
return $file; return $file;
} }
/**
* @throws InvalidConfigurationException
*/
protected function populateConfiguration(array $baseConfiguration): array protected function populateConfiguration(array $baseConfiguration): array
{ {
$defaultConfig = self::$defaultConfig; $defaultConfig = self::$defaultConfig;
// If ratios are set do not add default options
if (isset($baseConfiguration['cropVariants'])) {
unset($defaultConfig['cropVariants']);
}
$config = array_replace_recursive($defaultConfig, $baseConfiguration); $config = array_replace_recursive($defaultConfig, $baseConfiguration);
$imageConfig = $this->data['processedTca']['columns'][$config['imageField']];
$config['cropVariants'] = $imageConfig['config']['cropVariants'] ?? $defaultConfig['cropVariants'];
if (!is_array($config['cropVariants'])) { if (!is_array($config['cropVariants'])) {
throw new InvalidConfigurationException('Crop variants configuration must be an array', 1485377267); throw new InvalidConfigurationException('Crop variants configuration must be an array', 1485377267);
@ -282,8 +264,8 @@ class PickColorFromImage extends AbstractFormElement
$config['cropVariants'] = $cropVariants; $config['cropVariants'] = $cropVariants;
// By default, we allow all image extensions that can be handled by the GFX functionality
$config['allowedExtensions'] ??= $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']; $config['allowedExtensions'] ??= $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
return $config; return $config;
} }
@ -301,4 +283,22 @@ class PickColorFromImage extends AbstractFormElement
); );
return $config; return $config;
} }
protected function getWizardUri(): string
{
return (string)$this->uriBuilder->buildUriFromRoute($this->wizardRouteName);
}
protected function getWizardPayload(array $cropVariants, File $image): array
{
$uriArguments = [];
$arguments = [
'cropVariants' => $cropVariants,
'image' => $image->getUid(),
];
$uriArguments['arguments'] = json_encode($arguments);
$uriArguments['signature'] = $this->hashService->hmac((string)($uriArguments['arguments']), $this->wizardRouteName);
return $uriArguments;
}
} }

View File

@ -0,0 +1,304 @@
<?php
declare(strict_types=1);
namespace Evoweb\EwBase\Form\Element;
/*
* This file is developed by evoWeb.
*
* 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.
*/
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
use TYPO3\CMS\Backend\Form\NodeFactory;
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
use TYPO3\CMS\Core\Imaging\ImageManipulation\InvalidConfigurationException;
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3Fluid\Fluid\View\TemplateView;
use TYPO3Fluid\Fluid\View\ViewInterface;
class PickColorFromImagePre13 extends AbstractFormElement
{
/**
* Default element configuration
*
* @var array
*/
protected static array $defaultConfig = [
'imageField' => 'image',
'cropVariants' => [
'default' => [
'title' =>
'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.crop_variant.default',
'allowedAspectRatios' => [
'16:9' => [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.16_9',
'value' => 16 / 9,
],
'3:2' => [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.3_2',
'value' => 3 / 2,
],
'4:3' => [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.4_3',
'value' => 4 / 3,
],
'1:1' => [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.1_1',
'value' => 1.0,
],
'NaN' => [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.free',
'value' => 0.0,
],
],
'selectedRatio' => 'NaN',
'cropArea' => [
'x' => 0.0,
'y' => 0.0,
'width' => 1.0,
'height' => 1.0,
],
],
],
];
/**
* Default field information enabled for this element.
*
* @var array
*/
protected $defaultFieldInformation = [
'tcaDescription' => [
'renderType' => 'tcaDescription',
],
];
/**
* Default field wizards enabled for this element.
*
* @var array
*/
protected $defaultFieldWizard = [
'localizationStateSelector' => [
'renderType' => 'localizationStateSelector',
],
'otherLanguageContent' => [
'renderType' => 'otherLanguageContent',
'after' => [
'localizationStateSelector',
],
],
'defaultLanguageDifferences' => [
'renderType' => 'defaultLanguageDifferences',
'after' => [
'otherLanguageContent',
],
],
];
protected ViewInterface $templateView;
public function __construct(NodeFactory $nodeFactory, array $data)
{
parent::__construct($nodeFactory, $data);
// Would be great, if we could inject the view here, but since the constructor is in the interface, we can't
// @todo: It's unfortunate we're using Typo3Fluid TemplateView directly here. We can't
// inject BackendViewFactory here since __construct() is polluted by NodeInterface.
// Remove __construct() from NodeInterface to have DI, then use BackendViewFactory here.
$view = GeneralUtility::makeInstance(TemplateView::class);
$templatePaths = $view->getRenderingContext()->getTemplatePaths();
$templatePaths
->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Templates')]);
$templatePaths
->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Partials')]);
$this->templateView = $view;
}
public function render(): array
{
$resultArray = $this->initializeResultArray();
$parameterArray = $this->data['parameterArray'];
$config = $this->populateConfiguration($parameterArray['fieldConf']['config']);
$fieldId = StringUtility::getUniqueId('formengine-color-');
$file = $this->getFileObject($this->data['databaseRow'], $config['imageField']);
if (!$file) {
$languageService = $this->getLanguageService();
$label = $languageService->sL(
'LLL:EXT:ew_base/Resources/Private/Language/locallang_db.xlf:imageField.empty'
);
$fieldLabel = $this->data['processedTca']['columns'][$config['imageField']]['label'];
$resultArray['html'] = '
<div class="form-control-wrap">
<div class="form-wizards-wrap">
<div class="form-wizards-element">
<typo3-formengine-element-pick-color recordFieldId="' . htmlspecialchars($fieldId) . '">
' . sprintf($label, '<strong>' . $fieldLabel . '</strong>') . '
</typo3-formengine-element-pick-color>
</div>
</div>
</div>
';
// Early return in case we do not find a file
return $resultArray;
}
$fieldInformationResult = $this->renderFieldInformation();
$fieldInformationHtml = $fieldInformationResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
$fieldControlResult = $this->renderFieldControl();
$fieldControlHtml = $fieldControlResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
$fieldWizardResult = $this->renderFieldWizard();
$fieldWizardHtml = $fieldWizardResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
$width = $this->formMaxWidth(
MathUtility::forceIntegerInRange(
$config['size'] ?? $this->defaultInputWidth,
$this->minimumInputWidth,
$this->maxInputWidth
)
);
$arguments = [
'fieldInformation' => $fieldInformationHtml,
'fieldControl' => $fieldControlHtml,
'fieldWizard' => $fieldWizardHtml,
'isAllowedFileExtension' => in_array(
strtolower($file->getExtension()),
GeneralUtility::trimExplode(',', strtolower($config['allowedExtensions'])),
true
),
'image' => $file,
'formEngine' => [
'field' => [
'value' => $parameterArray['itemFormElValue'],
'name' => $parameterArray['itemFormElName'],
],
'validation' => '[]',
],
'config' => $config,
'width' => $width,
];
if ($arguments['isAllowedFileExtension']) {
$resultArray['stylesheetFiles'][] =
'EXT:ew_base/Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css';
$resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create(
'@evoweb/ew-base/form-engine/element/pick-color-from-image.js',
'PickColorFromImage'
)->instance(
$fieldId,
$parameterArray['itemFormElValue'],
($parameterArray['fieldConf']['config']['readOnly'] ?? false)
);
$arguments['formEngine']['field']['id'] = $fieldId;
if ($config['required'] ?? false) {
$arguments['formEngine']['validation'] = $this->getValidationDataAsJsonString(['required' => true]);
}
}
$this->templateView->assignMultiple($arguments);
$resultArray['html'] = $this->templateView->render('Form/ImageManipulationElement');
return $resultArray;
}
protected function getFileObject(array $row, string $fieldName): ?File
{
$file = null;
$fileUid = !empty($row[$fieldName]) ? $row[$fieldName] : null;
if (is_array($fileUid) && isset($fileUid[0]['uid'])) {
$fileUid = $fileUid[0]['uid'];
}
if (MathUtility::canBeInterpretedAsInteger($fileUid)) {
try {
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
$fileReference = $resourceFactory->getFileReferenceObject($fileUid);
$file = $fileReference->getOriginalFile();
} catch (FileDoesNotExistException | \InvalidArgumentException) {
}
}
return $file;
}
protected function populateConfiguration(array $baseConfiguration): array
{
$defaultConfig = self::$defaultConfig;
$config = array_replace_recursive($defaultConfig, $baseConfiguration);
$imageConfig = $this->data['processedTca']['columns'][$config['imageField']];
$config['cropVariants'] = $imageConfig['config']['cropVariants'] ?? $defaultConfig['cropVariants'];
if (!is_array($config['cropVariants'])) {
throw new InvalidConfigurationException('Crop variants configuration must be an array', 1485377267);
}
$cropVariants = [];
foreach ($config['cropVariants'] as $id => $cropVariant) {
// Filter allowed aspect ratios
$cropVariant['allowedAspectRatios'] = array_filter(
$cropVariant['allowedAspectRatios'] ?? [],
static function ($aspectRatio) {
return !(bool)($aspectRatio['disabled'] ?? false);
}
);
// Ignore disabled crop variants
if (!empty($cropVariant['disabled'])) {
continue;
}
if (empty($cropVariant['allowedAspectRatios'])) {
throw new InvalidConfigurationException(
'Crop variants configuration ' . $id . ' contains no allowed aspect ratios',
1620147893
);
}
// Enforce a crop area (default is full image)
if (empty($cropVariant['cropArea'])) {
$cropVariant['cropArea'] = Area::createEmpty()->asArray();
}
$cropVariants[$id] = $cropVariant;
}
$config['cropVariants'] = $cropVariants;
$config['allowedExtensions'] ??= $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
return $config;
}
protected function processConfiguration(array $config, string &$elementValue, File $file): array
{
$cropVariantCollection = CropVariantCollection::create($elementValue, $config['cropVariants']);
if (empty($config['readOnly']) && !empty($file->getProperty('width'))) {
$cropVariantCollection = $cropVariantCollection->applyRatioRestrictionToSelectedCropArea($file);
$elementValue = (string)$cropVariantCollection;
}
$config['cropVariants'] = $cropVariantCollection->asArray();
$config['allowedExtensions'] = implode(
', ',
GeneralUtility::trimExplode(',', $config['allowedExtensions'], true)
);
return $config;
}
}

View File

@ -14,8 +14,6 @@ class UsercentricsDatabaseEditRow extends SiteDatabaseEditRow
/** /**
* First level of ['customData']['siteData'] to ['databaseRow'] * First level of ['customData']['siteData'] to ['databaseRow']
* *
* @param array $result
* @return array
* @throws \RuntimeException * @throws \RuntimeException
*/ */
public function addData(array $result): array public function addData(array $result): array
@ -24,23 +22,19 @@ class UsercentricsDatabaseEditRow extends SiteDatabaseEditRow
return $result; return $result;
} }
$tableName = $result['tableName'];
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class, $this->siteConfiguration); $siteFinder = GeneralUtility::makeInstance(SiteFinder::class, $this->siteConfiguration);
if (in_array($tableName, ['site_usercentrics'], true)) {
$rootPageId = (int)($result['inlineTopMostParentUid'] ?? $result['inlineParentUid']); $rootPageId = (int)($result['inlineTopMostParentUid'] ?? $result['inlineParentUid']);
try { try {
$rowData = $this->getRawConfigurationForSiteWithRootPageId($siteFinder, $rootPageId); $rowData = $this->getRawConfigurationForSiteWithRootPageId($siteFinder, $rootPageId);
$parentFieldName = $result['inlineParentFieldName']; $parentFieldName = $result['inlineParentFieldName'];
if (!isset($rowData[$parentFieldName])) { if (!isset($rowData[$parentFieldName])) {
throw new \RuntimeException('Field "' . $parentFieldName . '" not found', 1520886092); throw new \RuntimeException('Field "' . $parentFieldName . '" not found', 1520886092);
}
$rowData = $rowData[$parentFieldName][$result['vanillaUid']];
$result['databaseRow']['uid'] = $result['vanillaUid'];
} catch (SiteNotFoundException $e) {
$rowData = [];
} }
} else { $rowData = $rowData[$parentFieldName][$result['vanillaUid']];
return $result; $result['databaseRow']['uid'] = $result['vanillaUid'];
} catch (SiteNotFoundException) {
$rowData = [];
} }
foreach ($rowData as $fieldName => $value) { foreach ($rowData as $fieldName => $value) {

View File

@ -40,7 +40,7 @@ class UsercentricsTcaInline extends SiteTcaInline
continue; continue;
} }
$childTableName = $fieldConfig['config']['foreign_table'] ?? ''; $childTableName = $fieldConfig['config']['foreign_table'] ?? '';
if (!in_array($childTableName, ['site_usercentrics'], true)) { if ($childTableName !== 'site_usercentrics') {
continue; continue;
} }
$result['processedTca']['columns'][$fieldName]['children'] = []; $result['processedTca']['columns'][$fieldName]['children'] = [];

View File

@ -1,106 +0,0 @@
<?php
declare(strict_types=1);
namespace Evoweb\EwBase\Updates;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
/**
* Migrate parent child elements to container elements
*/
#[UpgradeWizard('parentChildToContainer')]
class ParentChildToContainerMigration implements UpgradeWizardInterface
{
private const TABLE_NAME = 'tt_content';
protected LoggerInterface $logger;
public function __construct(
protected ParentChildToContainerService $service,
protected LogManager $logManager,
) {
$this->logger = $logManager->getLogger(self::class);
}
public function getTitle(): string
{
return 'Migrate parent/child to container';
}
public function getDescription(): string
{
return 'Migrates content elements that are type parent/child to corresponding container elements';
}
public function getPrerequisites(): array
{
return [
DatabaseUpdatedPrerequisite::class
];
}
public function updateNecessary(): bool
{
return $this->hasRecordsToUpdate();
}
public function executeUpdate(): bool
{
$updateSuccessful = true;
try {
$this->service->migrate();
} catch (\Exception $exception) {
$this->logger->log(LogLevel::ERROR, $exception->getMessage());
$updateSuccessful = false;
}
return $updateSuccessful;
}
protected function hasRecordsToUpdate(): bool
{
$queryBuilder = $this->getPreparedQueryBuilder();
$tableColumns = $queryBuilder
->getConnection()
->createSchemaManager()
->listTableColumns(self::TABLE_NAME);
return isset($tableColumns['parent'])
&& $queryBuilder
->count('uid')
->executeQuery()
->fetchOne() > 0;
}
protected function getPreparedQueryBuilder(): QueryBuilder
{
$queryBuilder = $this->getConnectionPool()->getQueryBuilderForTable(self::TABLE_NAME);
$queryBuilder->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
$queryBuilder
->from(self::TABLE_NAME)
->where(
// check if there are still records that have parent instead of tx_container_parent
$queryBuilder->expr()->gt('parent', 0)
);
return $queryBuilder;
}
protected function getConnectionPool(): ConnectionPool
{
return GeneralUtility::makeInstance(ConnectionPool::class);
}
}

View File

@ -1,168 +0,0 @@
<?php
declare(strict_types=1);
namespace Evoweb\EwBase\Updates;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Service\FlexFormService;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentColPosOffset'] = 0;
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentMigrationMapping'] = [
'downloads' => [ 'CType' => 'container-downloads' ],
];
*/
class ParentChildToContainerService
{
private const TABLE_NAME = 'tt_content';
protected int $colPosOffset = 0;
protected array $configuration = [];
public function __construct(
protected ConnectionPool $connectionPool,
protected DataHandler $dataHandler,
protected FlexFormService $flexFormService,
) {
$config =& $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base'];
$this->colPosOffset = $config['childParentColPosOffset'] ?? 0;
$this->configuration = $config['childParentMigrationMapping'] ?? [];
}
public function migrate(): void
{
$this->initializeDataHandler();
$this->migrateConfiguredContainer();
}
protected function initializeDataHandler(): void
{
$backendUser = GeneralUtility::makeInstance(BackendUserAuthentication::class);
$backendUser->user = [
'uid' => 0,
'admin' => 1,
];
$this->dataHandler->start([], [], $backendUser);
}
protected function migrateConfiguredContainer(): void
{
array_walk($this->configuration, function($config, $key) {
$parents = $this->getParentsByCType((string)$key);
foreach ($parents as $parent) {
$this->processParentMigration($parent, $config);
}
});
}
protected function processParentMigration(array $parent, array $config): void
{
$children = $this->getChildren($parent['uid']);
foreach ($children as $child) {
$this->processChildMigration($child, $parent);
}
$this->updateElement(
$parent['uid'],
[
'CType' => $this->getCType($parent, $config),
'children' => 0,
]
);
}
protected function processChildMigration(array $child, array $parent): void
{
$this->updateElement(
$child['uid'],
[
'tx_container_parent' => $parent['uid'],
'colPos' => $child['colPos'] + $this->colPosOffset,
'parent' => 0,
]
);
}
protected function getCType(array $container, array $config): string
{
if (is_array($config['CType'])) {
$value = ArrayUtility::getValueByPath($container, $config['CType']['search']);
$result = $config['CType']['matches'][$value] ?? null;
} else {
$result = $config['CType'] ?? null;
}
if (empty($result)) {
throw new \Exception('CType must always be set');
}
return $result;
}
protected function updateElement(int $uid, array $changes): void
{
$this->connectionPool
->getConnectionForTable(self::TABLE_NAME)
->update(self::TABLE_NAME, $changes, ['uid' => $uid]);
}
protected function getChildren(int $parentUid): array
{
$queryBuilder = $this->getQueryBuilderForTable();
return $queryBuilder
->select('*')
->where(
$queryBuilder->expr()->eq(
'parent',
$queryBuilder->createNamedParameter($parentUid, \PDO::PARAM_INT)
)
)
->orderBy('sorting')
->executeQuery()
->fetchAllAssociative();
}
protected function getParentsByCType(string $cType): array
{
$queryBuilder = $this->getQueryBuilderForTable();
$expr = $queryBuilder->expr();
return $queryBuilder
->select('*')
->where(
$expr->eq('CType', $queryBuilder->createNamedParameter($cType))
)
->orderBy('sorting')
->executeQuery()
->fetchAllAssociative();
}
protected function getQueryBuilderForTable(string $table = 'tt_content'): QueryBuilder
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
$queryBuilder->from($table);
return $queryBuilder;
}
}

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Evoweb\EwBase\User; namespace Evoweb\EwBase\User;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Core\Utility\PathUtility;
/** /**
@ -18,8 +17,6 @@ class AssetPath
{ {
public function getAbsolutePublicPath(string $content, array $conf): string public function getAbsolutePublicPath(string $content, array $conf): string
{ {
return $content return PathUtility::getAbsoluteWebPath($conf['file']);
. GeneralUtility::getIndpEnv('TYPO3_SITE_URL')
. ltrim(PathUtility::getPublicResourceWebPath($conf['file']), '/');
} }
} }

View File

@ -26,7 +26,7 @@ class AddViewHelper extends AbstractViewHelper
*/ */
protected $escapeOutput = false; protected $escapeOutput = false;
public function initializeArguments() public function initializeArguments(): void
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('array', 'array', 'Array to add value to'); $this->registerArgument('array', 'array', 'Array to add value to');
@ -34,18 +34,11 @@ class AddViewHelper extends AbstractViewHelper
$this->registerArgument('value', 'mixed', 'Value to add'); $this->registerArgument('value', 'mixed', 'Value to add');
} }
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return array
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): array {
$array = $arguments['array'] ?: []; $array = $arguments['array'] ?: [];
$key = $arguments['key']; $key = $arguments['key'];
$value = !is_null($arguments['value']) ? $arguments['value'] : $renderChildrenClosure(); $value = !is_null($arguments['value']) ? $arguments['value'] : $renderChildrenClosure();

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Evoweb\EwBase\ViewHelpers\Iterator; namespace Evoweb\EwBase\ViewHelpers\Array;
/* /*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later. * This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
@ -30,7 +30,7 @@ class ExplodeViewHelper extends AbstractViewHelper
protected static string $method = 'explode'; protected static string $method = 'explode';
public function initializeArguments() public function initializeArguments(): void
{ {
$this->registerArgument( $this->registerArgument(
'as', 'as',
@ -48,16 +48,11 @@ class ExplodeViewHelper extends AbstractViewHelper
); );
} }
/**
* Render method
*
* @return string|array
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): mixed {
$content = $arguments['content'] ?? $renderChildrenClosure(); $content = $arguments['content'] ?? $renderChildrenClosure();
$glue = static::resolveGlue($arguments); $glue = static::resolveGlue($arguments);
$content = call_user_func_array(static::$method, [$glue, $content]); $content = call_user_func_array(static::$method, [$glue, $content]);

View File

@ -30,10 +30,7 @@ class ThumbnailViewHelper extends AbstractViewHelper
{ {
use CompileWithRenderStatic; use CompileWithRenderStatic;
/** public function initializeArguments(): void
* Initializes the arguments
*/
public function initializeArguments()
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('row', 'array', 'content data', true); $this->registerArgument('row', 'array', 'content data', true);
@ -41,20 +38,11 @@ class ThumbnailViewHelper extends AbstractViewHelper
$this->registerArgument('fieldName', 'string', 'field name', true); $this->registerArgument('fieldName', 'string', 'field name', true);
} }
/**
* Render a constant
*
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string Value of constant
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): string {
$row = $arguments['row']; $row = $arguments['row'];
$tableName = $arguments['tableName']; $tableName = $arguments['tableName'];
$fieldName = $arguments['fieldName']; $fieldName = $arguments['fieldName'];

View File

@ -19,21 +19,14 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
*/ */
class InArrayViewHelper extends AbstractConditionViewHelper class InArrayViewHelper extends AbstractConditionViewHelper
{ {
/** public function initializeArguments(): void
* Initialize arguments
*/
public function initializeArguments()
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('haystack', 'array', 'haystack', true); $this->registerArgument('haystack', 'array', 'haystack', true);
$this->registerArgument('needle', 'mixed', 'needle', true); $this->registerArgument('needle', 'mixed', 'needle', true);
} }
/** protected static function evaluateCondition($arguments = null): bool
* @param array $arguments
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{ {
$array = $arguments['haystack']->toArray(); $array = $arguments['haystack']->toArray();
return in_array($arguments['needle'], $array); return in_array($arguments['needle'], $array);

View File

@ -19,22 +19,15 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
*/ */
class StringContainsViewHelper extends AbstractConditionViewHelper class StringContainsViewHelper extends AbstractConditionViewHelper
{ {
/** public function initializeArguments(): void
* Initialize arguments
*/
public function initializeArguments()
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('haystack', 'string', 'haystack', true); $this->registerArgument('haystack', 'string', 'haystack', true);
$this->registerArgument('needle', 'string', 'need', true); $this->registerArgument('needle', 'string', 'need', true);
} }
/** protected static function evaluateCondition($arguments = null): bool
* @param array $arguments
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{ {
return false !== strpos($arguments['haystack'], $arguments['needle']); return str_contains($arguments['haystack'], $arguments['needle']);
} }
} }

View File

@ -14,11 +14,7 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
class DevelopmentViewHelper extends AbstractConditionViewHelper class DevelopmentViewHelper extends AbstractConditionViewHelper
{ {
/** protected static function evaluateCondition($arguments = null): bool
* @param array $arguments
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{ {
return Environment::getContext()->isDevelopment(); return Environment::getContext()->isDevelopment();
} }

View File

@ -14,11 +14,7 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
class ProductionViewHelper extends AbstractConditionViewHelper class ProductionViewHelper extends AbstractConditionViewHelper
{ {
/** protected static function evaluateCondition($arguments = null): bool
* @param array $arguments
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{ {
return Environment::getContext()->isProduction(); return Environment::getContext()->isProduction();
} }

View File

@ -14,11 +14,7 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
class StagingViewHelper extends AbstractConditionViewHelper class StagingViewHelper extends AbstractConditionViewHelper
{ {
/** protected static function evaluateCondition($arguments = null): bool
* @param array $arguments
* @return bool
*/
protected static function evaluateCondition($arguments = null)
{ {
return 'Production/Staging' === (string)Environment::getContext(); return 'Production/Staging' === (string)Environment::getContext();
} }

View File

@ -1,77 +0,0 @@
<?php
namespace Evoweb\EwBase\ViewHelpers;
/*
* This file is developed by evoWeb.
*
* 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.
*/
use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* = Examples =
*
* <code title="Simple Loop">
* <ewb:fixFlexformForExtbase data="{data}">....</ewb:fixFlexformForExtbase>
* </code>
* <output>
* fixed flexform data for extbase controller
* </output>
*
* @api
*/
class FixFlexformForExtbaseViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* @var boolean
*/
protected $escapeOutput = false;
public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument('data', 'array', 'The data array of content element', true);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return array
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$templateVariableContainer = $renderingContext->getVariableProvider();
/** @var FlexFormTools $flexFormTools */
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
$data = $arguments['data'];
if (is_array($data['pi_flexform'])) {
$data['pi_flexform'] = $flexFormTools->flexArray2Xml($data['pi_flexform']);
}
$templateVariableContainer->add('data', $data);
$output = $renderChildrenClosure();
$templateVariableContainer->remove('data');
return $output;
}
}

View File

@ -1,80 +0,0 @@
<?php
namespace Evoweb\EwBase\ViewHelpers;
/*
* This file is developed by evoWeb.
*
* 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.
*/
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;
/**
* = Examples =
*
* <code title="Simple Loop">
* <ewb:flexForm data="{data}">....</ewb:flexForm>
* </code>
* <output>
* fixed flexform data for extbase controller
* </output>
*
* @api
*/
class FlexFormViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* @var boolean
*/
protected $escapeOutput = false;
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('data', 'array', 'Array to get flex form data from', true);
$this->registerArgument('fieldName', 'string', 'Field name', false, 'pi_flexform');
$this->registerArgument('as', 'string', 'Name of the variable to assign', false, 'flexFormData');
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return array
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$data = [];
if (is_array($arguments['data'])) {
if (isset($arguments['data'][$arguments['fieldName']])) {
$data = is_array($arguments['data'][$arguments['fieldName']]) ?
$arguments['data'][$arguments['fieldName']] :
GeneralUtility::xml2array($arguments['data'][$arguments['fieldName']]);
$data = $data['data'] ?? $data;
}
}
$templateVariableContainer = $renderingContext->getVariableProvider();
$templateVariableContainer->add($arguments['as'], $data);
$content = $renderChildrenClosure();
$templateVariableContainer->remove($arguments['as']);
return $content;
}
}

View File

@ -13,6 +13,9 @@ namespace Evoweb\EwBase\ViewHelpers;
* LICENSE.txt file that was distributed with this source code. * LICENSE.txt file that was distributed with this source code.
*/ */
use TYPO3\CMS\Core\Crypto\HashService;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
@ -26,33 +29,31 @@ class HashViewHelper extends AbstractViewHelper
*/ */
protected $escapeOutput = false; protected $escapeOutput = false;
public function initializeArguments() public function initializeArguments(): void
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('action', 'string', 'Target action'); $this->registerArgument('action', 'string', 'Target action');
$this->registerArgument('arguments', 'array', 'Arguments for the controller action, associative array'); $this->registerArgument('arguments', 'array', 'Arguments for the controller action, associative array');
} }
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): string {
$result = ''; $result = '';
if ( if (
$arguments['action'] !== null $arguments['action'] !== null
&& $arguments['arguments'] !== null && $arguments['arguments'] !== null
&& isset($arguments['arguments']['user']) && isset($arguments['arguments']['user'])
) { ) {
$result = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac( if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 13) {
$arguments['action'] . '::' . $arguments['arguments']['user'] $result = GeneralUtility::hmac($arguments['action'] . '::' . $arguments['arguments']['user']);
); } else {
/** @var HashService $hashService */
$hashService = GeneralUtility::makeInstance(HashService::class);
$result = $hashService->hmac($arguments['action'] . '::' . $arguments['arguments']['user'], '');
}
} }
return $result; return $result;

View File

@ -1,56 +0,0 @@
<?php
namespace Evoweb\EwBase\ViewHelpers\Iterator;
/*
* This file is developed by evoWeb.
*
* 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.
*/
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;
class AddViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* @var bool
*/
protected $escapeOutput = false;
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('array', 'array', 'Array to add value to');
$this->registerArgument('key', 'string', 'Key to add value by', true);
$this->registerArgument('value', 'mixed', 'Value to add');
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return array
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$array = $arguments['array'] ?: [];
$key = $arguments['key'];
$value = $arguments['value'] ?: $renderChildrenClosure();
return array_merge($array, [$key => $value]);
}
}

View File

@ -41,27 +41,23 @@ class PublicPathViewHelper extends AbstractViewHelper
*/ */
protected $escapeOutput = false; protected $escapeOutput = false;
protected static ?array $frontendGroupIds = null; public function initializeArguments(): void
public function initializeArguments()
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('path', 'string', 'Extension resource path', true); $this->registerArgument('path', 'string', 'Extension resource path', true);
} }
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return bool
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): string {
$path = (string)$arguments['path']; $path = (string)$arguments['path'];
return PathUtility::getPublicResourceWebPath($path); try {
$path = PathUtility::getPublicResourceWebPath($path);
} catch (\Exception) {
$path = '';
}
return $path;
} }
} }

View File

@ -44,24 +44,18 @@ class ReplaceViewHelper extends AbstractViewHelper
{ {
use CompileWithContentArgumentAndRenderStatic; use CompileWithContentArgumentAndRenderStatic;
public function initializeArguments() public function initializeArguments(): void
{ {
$this->registerArgument('value', 'string', 'String to replace in'); $this->registerArgument('value', 'string', 'String to replace in');
$this->registerArgument('search', 'string', 'Search string'); $this->registerArgument('search', 'string', 'Search string');
$this->registerArgument('replace', 'string', 'Replace value'); $this->registerArgument('replace', 'string', 'Replace value');
} }
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return null
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): string {
$content = $arguments['value']; $content = $arguments['value'];
if ($content === null) { if ($content === null) {
$content = $renderChildrenClosure(); $content = $renderChildrenClosure();

View File

@ -18,6 +18,7 @@ use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Type\Icon\IconState; use TYPO3\CMS\Core\Type\Icon\IconState;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
/** /**
@ -61,7 +62,7 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
* </span> * </span>
* </span> * </span>
*/ */
class SvgViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper class SvgViewHelper extends AbstractViewHelper
{ {
use CompileWithRenderStatic; use CompileWithRenderStatic;
@ -76,24 +77,16 @@ class SvgViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper
{ {
$this->registerArgument('identifier', 'string', 'Identifier of the icon as registered in the Icon Registry.', true); $this->registerArgument('identifier', 'string', 'Identifier of the icon as registered in the Icon Registry.', true);
$this->registerArgument('size', 'string', 'Desired size of the icon. All values of the Icons.sizes enum are allowed, these are: "small", "default", "large" and "overlay".', false, Icon::SIZE_SMALL); $this->registerArgument('size', 'string', 'Desired size of the icon. All values of the Icons.sizes enum are allowed, these are: "small", "default", "large" and "overlay".', false, Icon::SIZE_SMALL);
$this->registerArgument('overlay', 'string', 'Identifier of an overlay icon as registered in the Icon Registry.', false); $this->registerArgument('overlay', 'string', 'Identifier of an overlay icon as registered in the Icon Registry.', false, '');
$this->registerArgument('state', 'string', 'Sets the state of the icon. All values of the Icons.states enum are allowed, these are: "default" and "disabled".', false, IconState::STATE_DEFAULT); $this->registerArgument('state', 'string', 'Sets the state of the icon. All values of the Icons.states enum are allowed, these are: "default" and "disabled".', false, IconState::STATE_DEFAULT);
$this->registerArgument('alternativeMarkupIdentifier', 'string', 'Alternative icon identifier. Takes precedence over the identifier if supported by the IconProvider.', false); $this->registerArgument('alternativeMarkupIdentifier', 'string', 'Alternative icon identifier. Takes precedence over the identifier if supported by the IconProvider.', false, '');
} }
/**
* Prints icon html for $identifier key
*
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): Icon {
$identifier = $arguments['identifier']; $identifier = $arguments['identifier'];
$size = $arguments['size']; $size = $arguments['size'];
$overlay = $arguments['overlay']; $overlay = $arguments['overlay'];

View File

@ -26,27 +26,20 @@ class TrimViewHelper extends AbstractViewHelper
*/ */
protected $escapeOutput = false; protected $escapeOutput = false;
public function initializeArguments() public function initializeArguments(): void
{ {
parent::initializeArguments(); parent::initializeArguments();
$this->registerArgument('content', 'string', 'Content to be trimmed'); $this->registerArgument('content', 'string', 'Content to be trimmed');
$this->registerArgument('characters', 'string', 'Characters to be removed', false); $this->registerArgument('characters', 'string', 'Characters to be removed');
} }
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string
*/
public static function renderStatic( public static function renderStatic(
array $arguments, array $arguments,
\Closure $renderChildrenClosure, \Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext RenderingContextInterface $renderingContext
) { ): string {
$content = $arguments['content'] ? $arguments['content'] : $renderChildrenClosure(); $content = $arguments['content'] ?: $renderChildrenClosure();
$characters = $arguments['characters'] ? $arguments['characters'] : null; $characters = $arguments['characters'] ?: null;
if ($characters !== null) { if ($characters !== null) {
$content = trim($content, $characters); $content = trim($content, $characters);

View File

@ -12,8 +12,6 @@ class SiteDatabaseEditRow extends BaseSiteDatabaseEditRow
/** /**
* First level of ['customData']['siteData'] to ['databaseRow'] * First level of ['customData']['siteData'] to ['databaseRow']
* *
* @param array $result
* @return array
* @throws \RuntimeException * @throws \RuntimeException
*/ */
public function addData(array $result): array public function addData(array $result): array

View File

@ -8,9 +8,6 @@ class SiteTcaInline extends BaseSiteTcaInline
{ {
/** /**
* Resolve inline fields * Resolve inline fields
*
* @param array $result
* @return array
*/ */
public function addData(array $result): array public function addData(array $result): array
{ {

View File

@ -3,6 +3,7 @@
defined('TYPO3') or die('access denied'); defined('TYPO3') or die('access denied');
use Evoweb\EwBase\Form\Element\PickColorFromImage; use Evoweb\EwBase\Form\Element\PickColorFromImage;
use Evoweb\EwBase\Form\Element\PickColorFromImagePre13;
use Evoweb\EwBase\Form\FormDataProvider\UsercentricsDatabaseEditRow; use Evoweb\EwBase\Form\FormDataProvider\UsercentricsDatabaseEditRow;
use Evoweb\EwBase\Form\FormDataProvider\UsercentricsTcaInline; use Evoweb\EwBase\Form\FormDataProvider\UsercentricsTcaInline;
use Evoweb\EwBase\Hooks\UsercentricsPostRenderHook; use Evoweb\EwBase\Hooks\UsercentricsPostRenderHook;
@ -12,6 +13,8 @@ use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseParentPageRow;
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow as BaseSiteDatabaseEditRow; use TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow as BaseSiteDatabaseEditRow;
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteTcaInline as BaseSiteTcaInline; use TYPO3\CMS\Backend\Form\FormDataProvider\SiteTcaInline as BaseSiteTcaInline;
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSiteLanguage; use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSiteLanguage;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Utility\GeneralUtility;
call_user_func(function () { call_user_func(function () {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['ewb'] = [ 'Evoweb\\EwBase\\ViewHelpers' ]; $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['ewb'] = [ 'Evoweb\\EwBase\\ViewHelpers' ];
@ -19,10 +22,11 @@ call_user_func(function () {
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'][] = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'][] =
UsercentricsPostRenderHook::class . '->executePostRenderHook'; UsercentricsPostRenderHook::class . '->executePostRenderHook';
$versionPre13 = (GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 13;
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1681197508] = [ $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1681197508] = [
'nodeName' => 'pick-color-from-image', 'nodeName' => 'pick-color-from-image',
'priority' => '70', 'priority' => '70',
'class' => PickColorFromImage::class, 'class' => $versionPre13 ? PickColorFromImagePre13::class : PickColorFromImage::class,
]; ];
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][BaseSiteDatabaseEditRow::class] = [ $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][BaseSiteDatabaseEditRow::class] = [