TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:20 +02:00
commit c7a46689ff
115 changed files with 11736 additions and 0 deletions
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Fluid\Core\ViewHelper;
use Psr\Container\ContainerInterface;
use TYPO3\CMS\Core\DependencyInjection\FailsafeContainer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInterface;
/**
* Class whose purpose is dedicated to resolving classes which
* can be used as ViewHelpers and ExpressionNodes in Fluid.
*
* This CMS-specific version of the ViewHelperResolver works
* almost exactly like the one from Fluid itself, with the main
* differences being that this one supports a legacy mode flag
* which when toggled on makes the Fluid parser behave exactly
* like it did in the legacy CMS Fluid package.
*
* In addition to modifying the behavior or the parser when
* legacy mode is requested, this ViewHelperResolver is also
* made capable of "mixing" two different ViewHelper namespaces
* to effectively create aliases for the Fluid core ViewHelpers
* to be loaded in the TYPO3\CMS\ViewHelpers scope as well.
*
* Default ViewHelper namespaces are read from the extension-level
* configuration file "Configuration/Fluid/Namespaces.php".
*
* Extending this array allows third party ViewHelper providers
* to automatically add or extend namespaces which then become
* available in every Fluid template file without having to
* register the namespace.
*
* @internal This is a helper class which is not considered part of TYPO3's Public API.
*/
class ViewHelperResolver extends \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperResolver
{
protected ContainerInterface $container;
/**
* ViewHelperResolver constructor
*
* @internal constructor, use `ViewHelperResolverFactory->create()` instead
*/
public function __construct(ContainerInterface $container, array $namespaces, array $resolverDelegates = [])
{
$this->container = $container;
$this->namespaces = $namespaces;
$this->resolverDelegates = $resolverDelegates;
}
/**
* @param string $viewHelperClassName
*/
public function createViewHelperInstanceFromClassName($viewHelperClassName): ViewHelperInterface
{
if ($this->container instanceof FailsafeContainer) {
// Install tool: makeInstance() resolves via the FailsafeContainer when the VH is
// registered there, else via `new`. VHs with required constructor arguments used by
// install-tool templates must be wired in install/Classes/ServiceProvider.php.
/** @var ViewHelperInterface $viewHelperInstance */
$viewHelperInstance = GeneralUtility::makeInstance($viewHelperClassName);
return $viewHelperInstance;
}
if ($this->container->has($viewHelperClassName)) {
/** @var ViewHelperInterface $viewHelperInstance */
$viewHelperInstance = $this->container->get($viewHelperClassName);
} else {
/** @var ViewHelperInterface $viewHelperInstance */
$viewHelperInstance = new $viewHelperClassName();
}
return $viewHelperInstance;
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Fluid\Core\ViewHelper;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
use TYPO3\CMS\Fluid\Core\Component\ComponentCollectionRegistry;
use TYPO3\CMS\Fluid\Core\Component\DeclarativeComponentCollection;
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperResolverDelegateInterface;
/**
* @internal May change / vanish any time
*/
#[Autoconfigure(public: true)]
final readonly class ViewHelperResolverDelegateRegistry
{
/**
* @var array<string, ViewHelperResolverDelegateInterface>
*/
private array $viewHelperResolverDelegates;
public function __construct(
ComponentCollectionRegistry $componentCollectionRegistry,
#[AutowireIterator('fluid.resolverdelegate', exclude: [DeclarativeComponentCollection::class], indexAttribute: 'identifier')]
iterable $resolverDelegates,
) {
$this->viewHelperResolverDelegates = array_replace(
iterator_to_array($resolverDelegates),
$componentCollectionRegistry->getAll(),
);
}
/**
* @return array<string, ViewHelperResolverDelegateInterface>
*/
public function getAll(): array
{
return $this->viewHelperResolverDelegates;
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Fluid\Core\ViewHelper;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Fluid\Event\ModifyNamespacesEvent;
/**
* Factory class registered in ServiceProvider to create a ViewHelperResolver.
*
* Note fluid is a failsafe mode aware extensions since its used in the install
* tool. We thus need a ServiceProvider.php to correctly instantiate / inject
* these class objects. This would be simple, but ViewHelperResolver has state,
* and the failsafe mode expects injected services to not have state.
*
* So, to retrieve a ViewHelperResolver instance, an instance of this factory
* is retrieved instead (which is a singleton), which then creates a 'fresh'
* instance of the ViewHelperResolver each time create() is called.
*
* @internal May change / vanish any time
*/
final readonly class ViewHelperResolverFactory implements ViewHelperResolverFactoryInterface
{
public function __construct(
private ContainerInterface $container,
private EventDispatcherInterface $eventDispatcher,
private ?ViewHelperResolverDelegateRegistry $viewHelperResolverDelegateRegistry,
private iterable $namespaces,
) {}
public function create(): ViewHelperResolver
{
$event = $this->eventDispatcher->dispatch(new ModifyNamespacesEvent((array)$this->namespaces));
return new ViewHelperResolver(
$this->container,
$event->getNamespaces(),
$this->viewHelperResolverDelegateRegistry instanceof ViewHelperResolverDelegateRegistry ? iterator_to_array($this->viewHelperResolverDelegateRegistry->getAll()) : [],
);
}
}
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Fluid\Core\ViewHelper;
/**
* @internal May change / vanish any time. This interface *may* be used to override implementation via
* ServiceProvider.php in an own extension. However, ServiceProvider.php itself is *not* API,
* so this interface isn't as well. Core *may* break this later again, but will still try not to,
* but this is not guaranteed.
*/
interface ViewHelperResolverFactoryInterface
{
public function create(): ViewHelperResolver;
}