Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 7 additions & 38 deletions Neos.FluidAdaptor/Classes/Core/Cache/CacheAdaptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,7 @@ class CacheAdaptor implements FluidCacheInterface
*/
protected $flowCache;

/**
* Gets an entry from the cache or NULL if the
* entry does not exist.
*
* @param string $name
* @return string
*/
public function get($name)
public function get(string $name): mixed
{
if ($this->flowCache->has($name)) {
$this->flowCache->requireOnce($name);
Expand All @@ -43,45 +36,21 @@ public function get($name)
return $this->flowCache->getWrapped($name);
}

/**
* Set or updates an entry identified by $name
* into the cache.
*
* @param string $name
* @param string $value
*/
public function set($name, $value)
public function set(string $name, mixed $value): void
{
// we need to strip the first line with the php header as the flow cache adds that again.
$this->flowCache->set($name, substr($value, strpos($value, "\n") + 1));
}

/**
* Flushes the cache either by entry or flushes
* the entire cache if no entry is provided.
*
* @param string|null $name
* @return bool|null
*/
public function flush($name = null)
public function flush(?string $name = null): void
{
if ($name !== null) {
return $this->flowCache->remove($name);
} else {
if ($name === null) {
$this->flowCache->flush();
return null;
return;
}
$this->flowCache->remove($name);
}

/**
* Get an instance of FluidCacheWarmerInterface which
* can warm up template files that would normally be
* cached on-the-fly to this FluidCacheInterface
* implementaion.
*
* @return FluidCacheWarmerInterface
*/
public function getCacheWarmer()
public function getCacheWarmer(): FluidCacheWarmerInterface
{
return new StandardCacheWarmer();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* source code.
*/

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Routing\Router;
use Neos\Flow\Package\FlowPackageKey;
use Neos\FluidAdaptor\Core\Parser\SyntaxTree\ResourceUriNode;
use TYPO3Fluid\Fluid\Core\Parser\InterceptorInterface;
Expand Down Expand Up @@ -40,7 +42,7 @@ class ResourceInterceptor implements InterceptorInterface
*
* @var string
*/
const PATTERN_SPLIT_AT_RESOURCE_URIS = '!
private const PATTERN_SPLIT_AT_RESOURCE_URIS = '!
(
(?:[^"\'(\s]+/ # URL part: A string with no quotes, no opening parentheses and no whitespace
)* # a URL consists of multiple URL parts
Expand All @@ -55,15 +57,21 @@ class ResourceInterceptor implements InterceptorInterface
* @var string
* @see \Neos\Flow\Package\FlowPackageKey::PATTERN
*/
const PATTERN_MATCH_RESOURCE_URI = '!(?:../)*(?:(?P<Package>[A-Za-z0-9]+\.(?:[A-Za-z0-9][\.a-z0-9]*)+)/Resources/)?Public/(?P<Path>[^"]+)!';
private const PATTERN_MATCH_RESOURCE_URI = '!(?:../)*(?:(?P<Package>[A-Za-z0-9]+\.(?:[A-Za-z0-9][\.a-z0-9]*)+)/Resources/)?Public/(?P<Path>[^"]+)!';

/**
* The default package key to use when rendering resource links without a
* package key in the source URL.
*
* @var string
*/
protected $defaultPackageKey;
protected string $defaultPackageKey = '';

/**
* @Flow\Inject
* @var Router
*/
protected Router $router;

/**
* Set the default package key to use for resource URIs.
Expand All @@ -72,7 +80,7 @@ class ResourceInterceptor implements InterceptorInterface
* @return void
* @throws \InvalidArgumentException
*/
public function setDefaultPackageKey($defaultPackageKey)
public function setDefaultPackageKey(string $defaultPackageKey): void
{
if (!FlowPackageKey::isPackageKeyValid($defaultPackageKey)) {
throw new \InvalidArgumentException('The given argument was not a valid package key.', 1277287099);
Expand All @@ -89,12 +97,9 @@ public function setDefaultPackageKey($defaultPackageKey)
* @param ParsingState $parsingState the current parsing state. Not needed in this interceptor.
* @return NodeInterface the modified node
*/
public function process(NodeInterface $node, $interceptorPosition, ParsingState $parsingState)
public function process(NodeInterface $node, $interceptorPosition, ParsingState $parsingState): NodeInterface
{
if (!$node instanceof TextNode) {
return $node;
}
if (strpos($node->getText(), 'Public/') === false) {
if (!$node instanceof TextNode || !str_contains($node->getText(), 'Public/')) {
return $node;
}
$textParts = preg_split(self::PATTERN_SPLIT_AT_RESOURCE_URIS, $node->getText(), -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
Expand All @@ -106,14 +111,13 @@ public function process(NodeInterface $node, $interceptorPosition, ParsingState
'path' => new TextNode($matches['Path'])
];

if ($this->defaultPackageKey !== null) {
$arguments['package'] = new TextNode($this->defaultPackageKey);
}
$packageKey = $this->defaultPackageKey;

if (isset($matches['Package']) && FlowPackageKey::isPackageKeyValid($matches['Package'])) {
$arguments['package'] = new TextNode($matches['Package']);
$packageKey = $matches['Package'];
}

$resourceUriNode = new ResourceUriNode($arguments);
$resourceUriNode = new ResourceUriNode($matches['Path'], $packageKey);
$node->addChildNode($resourceUriNode);
} else {
$textNode = new TextNode($part);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,73 @@
* source code.
*/

use Neos\Flow\I18n\Service;
use Neos\Flow\ResourceManagement\Exception;
use Neos\Flow\ResourceManagement\ResourceManager;
use Neos\FluidAdaptor\Core\Parser\Interceptor\ResourceInterceptor;
use Neos\FluidAdaptor\Core\ViewHelper\ViewHelperResolver;
use Neos\FluidAdaptor\ViewHelpers\Uri\ResourceViewHelper;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\NodeInterface;
use Neos\FluidAdaptor\Core\Rendering\RenderingContext;
use Neos\FluidAdaptor\Core\ViewHelper\Exception\InvalidVariableException;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\AbstractNode;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

/**
* A special ViewHelperNode that works via injections and is created by the ResourceInterceptor
*
* @see ResourceInterceptor
*/
class ResourceUriNode extends ViewHelperNode
class ResourceUriNode extends AbstractNode
{
/**
* @var array<NodeInterface>
* @var ResourceManager|null
*/
protected $arguments = [];
protected ?ResourceManager $resourceManager;

/**
* @var ViewHelperResolver
*/
protected $viewHelperResolver;
protected ?Service $i18nService;

/**
* @var string
*/
protected $viewHelperClassName = ResourceViewHelper::class;
public function injectResourceManager(ResourceManager $resourceManager): void
{
$this->resourceManager = $resourceManager;
}

/**
* @param ViewHelperResolver $viewHelperResolver
*/
public function injectViewHelperResolver(ViewHelperResolver $viewHelperResolver)
public function injectService(Service $i18nService): void
{
$this->viewHelperResolver = $viewHelperResolver;
$this->uninitializedViewHelper = $this->viewHelperResolver->createViewHelperInstanceFromClassName($this->viewHelperClassName);
/** @phpstan-ignore-next-line we use internal api */
$this->uninitializedViewHelper->setViewHelperNode($this);
$this->argumentDefinitions = $this->viewHelperResolver->getArgumentDefinitionsForViewHelper($this->uninitializedViewHelper);
$this->i18nService = $i18nService;
}

public function __construct(
public readonly string $path,
public readonly string $package
) {
}

/**
* Constructor.
*
* @param NodeInterface[] $arguments Arguments of view helper - each value is a RootNode.
* @param RenderingContextInterface $renderingContext
* @return string
* @throws InvalidVariableException
*/
public function __construct(array $arguments)
public function evaluate(RenderingContextInterface $renderingContext): string
{
$this->arguments = $arguments;
$package = $this->package;
$path = $this->path;
if ($package === '') {
/** @var RenderingContext $renderingContext */
$package = $renderingContext->getControllerContext()?->getRequest()?->getControllerPackageKey();
}
if (str_starts_with($path, 'resource://')) {
try {
[$package, $path] = $this->resourceManager->getPackageAndPathByPublicPath($path);
} catch (Exception $e) {
throw new InvalidVariableException(sprintf('The specified path "%s" does not point to a public resource.', $path), 1386458851, $e);
}
}

$resourcePath = 'resource://' . $package . '/Public/' . $this->path;
$localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath);
$matches = [];
if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) {
[$_, $package, $path] = $matches;
}

return $this->resourceManager->getPublicPackageResourceUri($package, $path);
}
}
4 changes: 2 additions & 2 deletions Neos.FluidAdaptor/Classes/Core/Parser/TemplateParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ class TemplateParser extends \TYPO3Fluid\Fluid\Core\Parser\TemplateParser
/**
* @return boolean
*/
public function isEscapingEnabled()
public function isEscapingEnabled(): bool
{
return $this->escapingEnabled;
}

/**
* @param boolean $escapingEnabled
*/
public function setEscapingEnabled($escapingEnabled)
public function setEscapingEnabled($escapingEnabled): void
{
$this->escapingEnabled = $escapingEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@ class NamespaceDetectionTemplateProcessor extends FluidNamespaceDetectionTemplat
* Pre-process the template source before it is
* returned to the TemplateParser or passed to
* the next TemplateProcessorInterface instance.
*
* @param string $templateSource
* @return string
*/
public function preProcessSource($templateSource)
public function preProcessSource(string $templateSource): string
{
$templateSource = $this->protectCDataSectionsFromParser($templateSource);
$templateSource = $this->registerNamespacesFromTemplateSource($templateSource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ interface FlowAwareRenderingContextInterface
/**
* @return ObjectManagerInterface
*/
public function getObjectManager();
public function getObjectManager(): ObjectManagerInterface;

/**
* @return ControllerContext
*/
public function getControllerContext();
public function getControllerContext(): ControllerContext;
}
Loading