Commit 14840bf9 authored by Nikita Hovratov's avatar Nikita Hovratov Committed by Benni Mack
Browse files

[BUGFIX] Skip non-existing soft reference parser keys

Declaring non-existing soft reference parser keys in TCA is ignored
again and won't throw an exception anymore. For informational purposes
this will be logged instead.

Resolves: #95012
Releases: master
Change-Id: Ifbc7927365f7c6a402e6ad99417f82cda0aa51d4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70795

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Torben Hansen's avatarTorben Hansen <derhansen@gmail.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Torben Hansen's avatarTorben Hansen <derhansen@gmail.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 8cc94d14
......@@ -17,6 +17,7 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\DataHandling\SoftReference;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
......@@ -27,10 +28,12 @@ class SoftReferenceParserFactory
{
protected array $softReferenceParsers = [];
protected FrontendInterface $runtimeCache;
protected LoggerInterface $logger;
public function __construct(FrontendInterface $runtimeCache)
public function __construct(FrontendInterface $runtimeCache, LoggerInterface $logger)
{
$this->runtimeCache = $runtimeCache;
$this->logger = $logger;
// TODO remove in TYPO3 v12.0
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'] ?? [] as $parserKey => $className) {
......@@ -103,6 +106,12 @@ class SoftReferenceParserFactory
if (!is_array($parameters)) {
$parameters = $forcedParameters ?? [];
}
if (!$this->hasSoftReferenceParser($parserKey)) {
$this->logger->warning('No soft reference parser exists for the key "{parserKey}".', ['parserKey' => $parserKey]);
continue;
}
$parser = $this->getSoftReferenceParser($parserKey);
$parser->setParserKey($parserKey, $parameters);
......@@ -110,6 +119,15 @@ class SoftReferenceParserFactory
}
}
/**
* @param string $softReferenceParserKey
* @return bool
*/
public function hasSoftReferenceParser(string $softReferenceParserKey): bool
{
return isset($this->softReferenceParsers[$softReferenceParserKey]);
}
/**
* Get a Soft Reference Parser by the given soft reference key.
* Implementation must be registered in Configuration/Services.yaml
......@@ -132,7 +150,7 @@ class SoftReferenceParserFactory
);
}
if (!isset($this->softReferenceParsers[$softReferenceParserKey])) {
if (!$this->hasSoftReferenceParser($softReferenceParserKey)) {
throw new \OutOfRangeException(
sprintf('No soft reference parser found for "%s".', $softReferenceParserKey),
1627899342
......
......@@ -19,6 +19,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\DataHandling\SoftReference;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\DataHandling\SoftReference\EmailSoftReferenceParser;
use TYPO3\CMS\Core\DataHandling\SoftReference\ExtensionPathSoftReferenceParser;
......@@ -44,8 +45,9 @@ abstract class AbstractSoftReferenceParserTest extends UnitTestCase
{
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$runtimeCache = $this->prophesize(FrontendInterface::class);
$logger = $this->prophesize(LoggerInterface::class);
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal());
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal(), $logger->reveal());
$softReferenceParserFactory->addParser(new SubstituteSoftReferenceParser(), 'substitute');
$softReferenceParserFactory->addParser(new NotifySoftReferenceParser(), 'notify');
$softReferenceParserFactory->addParser(new TypolinkSoftReferenceParser($eventDispatcher->reveal()), 'typolink');
......
......@@ -17,8 +17,10 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Tests\Unit\Database;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Database\SoftReferenceIndex;
use TYPO3\CMS\Core\DataHandling\SoftReference\NotifySoftReferenceParser;
......@@ -44,8 +46,11 @@ class SoftReferenceIndexTest extends UnitTestCase
{
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$runtimeCache = $this->prophesize(FrontendInterface::class);
$runtimeCache->get(Argument::any())->willReturn(false);
$runtimeCache->set(Argument::cetera())->willReturn(null);
$logger = $this->prophesize(LoggerInterface::class);
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal());
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal(), $logger->reveal());
$softReferenceParserFactory->addParser(new TypolinkSoftReferenceParser($eventDispatcher->reveal()), 'typolink');
$softReferenceParserFactory->addParser(new TypolinkTagSoftReferenceParser(), 'typolink_tag');
......@@ -490,9 +495,22 @@ class SoftReferenceIndexTest extends UnitTestCase
],
];
$runtimeCache = $this->prophesize(FrontendInterface::class);
$logger = $this->prophesize(LoggerInterface::class);
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal());
$softReferenceParserFactory = new SoftReferenceParserFactory($runtimeCache->reveal(), $logger->reveal());
self::assertIsObject($softReferenceParserFactory->getSoftReferenceParser('substitute'));
}
/**
* This simply shouldn't throw an exception.
* @test
*/
public function declaringNonExistingParserKeysWillNotThrowAnException()
{
$softReferenceParserFactory = $this->createSoftReferenceParserFactory();
foreach ($softReferenceParserFactory->getParsersBySoftRefParserList('idonotexist,typolink_tag') as $softReferenceParser) {
// Do nothing
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment