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

[!!!][TASK] Remove legacy SoftReferenceIndex

The old implementation and all backwards
compatibility layers for SoftReferenceIndex have
been dropped.

Resolves: #96145
Related: #94687
Releases: main
Change-Id: Ifa3bacbf3a7dc1ffad5acca852f1a2c25ac87b40
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72381

Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 22282deb
......@@ -38,8 +38,6 @@ use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction;
use TYPO3\CMS\Core\Database\RelationHandler;
use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory;
use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Imaging\Icon;
......@@ -2940,58 +2938,6 @@ class BackendUtility
return [$TScID, $cPid];
}
/**
* Returns soft-reference parser for the softRef processing type
* Usage: $softRefObj = BackendUtility::softRefParserObj('[parser key]');
*
* @param string $spKey softRef parser key
* @return mixed If available, returns Soft link parser object, otherwise false.
* @internal should only be used from within TYPO3 Core
* @deprecated will be removed in TYPO3 v12.0. Use SoftReferenceParserFactory->getSoftReferenceParser instead.
*/
public static function softRefParserObj($spKey)
{
trigger_error(
'BackendUtility::softRefParserObj will be removed in TYPO3 v12.0, use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory->getSoftReferenceParser instead.',
E_USER_DEPRECATED
);
$className = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'][$spKey] ?? false;
$obj = null;
if ($className) {
$obj = GeneralUtility::makeInstance($className);
}
if (!$obj) {
try {
$obj = GeneralUtility::makeInstance(SoftReferenceParserFactory::class)->getSoftReferenceParser($spKey);
} catch (\OutOfBoundsException|\InvalidArgumentException $e) {
return false;
}
}
// Build a wrapper to call the API with the legacy findRef() call.
if ($obj) {
if ($obj instanceof SoftReferenceParserInterface && !method_exists($obj, 'findRef')) {
// Build a temporary class acting as a wrapper to call findRef() with the new API.
return new class($obj) {
private SoftReferenceParserInterface $parser;
public function __construct(SoftReferenceParserInterface $obj)
{
$this->parser = $obj;
}
public function findRef($table, $field, $uid, $content, $parserKey, $spParams, $structurePath)
{
$this->parser->setParserKey($parserKey, $spParams);
return $this->parser->parse($table, $field, $uid, $content, $structurePath)->toNullableArray();
}
};
}
return $obj;
}
return false;
}
/**
* Gets an instance of the runtime cache.
*
......@@ -3002,49 +2948,6 @@ class BackendUtility
return GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
}
/**
* Returns array of soft parser references
*
* @param string $parserList softRef parser list
* @return array|bool Array where the parser key is the key and the value is the parameter string, FALSE if no parsers were found
* @throws \InvalidArgumentException
* @internal should only be used from within TYPO3 Core
* @deprecated will be removed in TYPO3 v12.0. Use SoftReferenceParserFactory->getParsersBySoftRefParserList instead.
*/
public static function explodeSoftRefParserList($parserList)
{
trigger_error(
'BackendUtility::explodeSoftRefParserList will be removed in TYPO3 v12.0, use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory->getParsersBySoftRefParserList instead.',
E_USER_DEPRECATED
);
// Return immediately if list is blank:
if ((string)$parserList === '') {
return false;
}
$runtimeCache = self::getRuntimeCache();
$cacheId = 'backend-softRefList-' . md5($parserList);
$parserListCache = $runtimeCache->get($cacheId);
if ($parserListCache !== false) {
return $parserListCache;
}
// Otherwise parse the list:
$keyList = GeneralUtility::trimExplode(',', $parserList, true);
$output = [];
foreach ($keyList as $val) {
$reg = [];
if (preg_match('/^([[:alnum:]_-]+)\\[(.*)\\]$/', $val, $reg)) {
$output[$reg[1]] = GeneralUtility::trimExplode(';', $reg[2], true);
} else {
$output[$val] = '';
}
}
$runtimeCache->set($cacheId, $output);
return $output;
}
/**
* Returns TRUE if $modName is set and is found as a main- or submodule in $TBE_MODULES array
*
......
......@@ -56,13 +56,4 @@ abstract class AbstractSoftReferenceParser implements SoftReferenceParserInterfa
{
$this->tokenID_basePrefix = implode(':', [$table, $uid, $field, $structurePath, $this->getParserKey()]);
}
/**
* @internal will be removed in favor of ->parse() in TYPO3 v12.0.
*/
public function findRef(string $table, string $field, int $uid, string $content, string $spKey, array $spParams, string $structurePath = '')
{
$this->setParserKey($spKey, $spParams);
return $this->parse($table, $field, $uid, $content, $structurePath)->toNullableArray();
}
}
......@@ -44,14 +44,6 @@ class ExtensionPathSoftReferenceParser implements SoftReferenceParserInterface
);
}
/**
* @internal will be removed in favor of ->parse() in TYPO3 v12.0.
*/
public function findRef(string $table, string $field, int $uid, string $content, string $spKey, array $spParams, string $structurePath = '')
{
return $this->parse($table, $field, $uid, $content, $structurePath)->toNullableArray();
}
/**
* @param string $parserKey The softref parser key.
* @param array $parameters Parameters of the softlink parser. Basically this is the content inside optional []-brackets after the softref keys. Parameters are exploded by ";
......
......@@ -52,12 +52,4 @@ class NotifySoftReferenceParser implements SoftReferenceParserInterface
]
);
}
/**
* @internal will be removed in favor of ->parse() in TYPO3 v12.0.
*/
public function findRef(string $table, string $field, int $uid, string $content, string $spKey, array $spParams, string $structurePath = '')
{
return $this->parse($table, $field, $uid, $content, $structurePath)->toNullableArray();
}
}
......@@ -34,19 +34,6 @@ class SoftReferenceParserFactory
{
$this->runtimeCache = $runtimeCache;
$this->logger = $logger;
// TODO remove in TYPO3 v12.0
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'] ?? [] as $parserKey => $className) {
trigger_error(
sprintf(
'The soft reference parser %s for the key "%s" is registered in the global array $GLOBALS[TYPO3_CONF_VARS][SC_OPTIONS][GLOBAL][softRefParser]. This way of registration will stop working in TYPO3 v12.0. Register the class in Configuration/Services.yaml instead.',
$className,
$parserKey
),
E_USER_DEPRECATED
);
$this->softReferenceParsers[$parserKey] = GeneralUtility::makeInstance($className);
}
}
/**
......@@ -157,61 +144,7 @@ class SoftReferenceParserFactory
);
}
$softReferenceParser = $this->softReferenceParsers[$softReferenceParserKey];
// @todo in v12 soft reference parsers, not implementing SoftReferenceParserInterface should throw an exception
if ($softReferenceParser instanceof SoftReferenceParserInterface) {
return $softReferenceParser;
}
// @todo everything below is deprecated and will be removed in v12
trigger_error(
sprintf('The class %s does not implement %s. The compatibility layer will be dropped in TYPO3 v12.0.', get_class($softReferenceParser), SoftReferenceParserInterface::class),
E_USER_DEPRECATED
);
if (!method_exists($softReferenceParser, 'findRef')) {
throw new \RuntimeException(
sprintf('The class %s must implement the findRef method.', get_class($softReferenceParser)),
1627899708
);
}
// Build a temporary class acting as a wrapper to call findRef() with the new API.
/** @var object $softReferenceParser */
return new class($softReferenceParser, $softReferenceParserKey) implements SoftReferenceParserInterface {
private object $parser;
private string $parserKey;
private array $parameters = [];
public function __construct(object $softReferenceParser, $parserKey)
{
$this->parser = $softReferenceParser;
$this->parserKey = $parserKey;
}
public function setParserKey(string $parserKey, array $parameters): void
{
$this->parserKey = $parserKey;
$this->parameters = $parameters;
}
public function getParserKey(): string
{
return $this->parserKey;
}
public function parse(
string $table,
string $field,
int $uid,
string $content,
string $structurePath = ''
): SoftReferenceParserResult {
$result = $this->parser->findRef($table, $field, $uid, $content, $this->parserKey, $this->parameters, $structurePath);
if (is_array($result)) {
return SoftReferenceParserResult::create($result['content'] ?? '', $result['elements'] ?? []);
}
return SoftReferenceParserResult::createWithoutMatches();
}
};
return $this->softReferenceParsers[$softReferenceParserKey];
}
/**
......
......@@ -83,22 +83,4 @@ final class SoftReferenceParserResult
{
return $this->elements;
}
/**
* @internal This method is added for backwards-compatibility of TYPO3 v11, and not part of the official TYPO3 Core API.
*/
public function toNullableArray(): ?array
{
if (!$this->hasMatched()) {
return null;
}
$result = [];
if ($this->hasContent()) {
$result['content'] = $this->content;
}
$result['elements'] = $this->elements;
return $result;
}
}
......@@ -19,7 +19,6 @@ namespace TYPO3\CMS\Core\DataHandling\SoftReference;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
use TYPO3\CMS\Core\DataHandling\Event\AppendLinkHandlerElementsEvent;
use TYPO3\CMS\Core\LinkHandling\Exception\UnknownLinkHandlerException;
use TYPO3\CMS\Core\LinkHandling\LinkService;
......@@ -35,13 +34,6 @@ use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
*/
class TypolinkSoftReferenceParser extends AbstractSoftReferenceParser
{
use PublicMethodDeprecationTrait;
private $deprecatedPublicMethods = [
'getTypoLinkParts' => 'getTypoLinkParts() is for internal usage only. It is implicitly called by the parse() method. Calling getTypoLinkParts() will throw and error in v12.',
'setTypoLinkPartsElement' => 'setTypoLinkPartsElement() is for internal usage only. It is implicitly called by the parse() method. Calling setTypoLinkPartsElement() will throw an error in v12.',
];
protected EventDispatcherInterface $eventDispatcher;
public function __construct(EventDispatcherInterface $eventDispatcher)
......
<?php
/*
* 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\Core\Database;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory;
use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserResult;
use TYPO3\CMS\Core\DataHandling\SoftReference\TypolinkSoftReferenceParser;
use TYPO3\CMS\Core\SingletonInterface;
/**
* Class for processing of the default soft reference types for CMS:
*
* - 'substitute' : A full field value targeted for manual substitution (for import /export features)
* - 'notify' : Just report if a value is found, nothing more.
* - 'typolink' : references to page id or file, possibly with anchor/target, possibly commaseparated list.
* - 'typolink_tag' : As typolink, but searching for <link> tag to encapsulate it.
* - 'email' : Email highlight
* - 'url' : URL highlights (with a scheme)
* @deprecated will be removed in TYPO3 v12.0 in favor of SoftReferenceParserInterface
*/
class SoftReferenceIndex extends TypolinkSoftReferenceParser implements SingletonInterface
{
public string $tokenID_basePrefix;
protected SoftReferenceParserFactory $softReferenceParserFactory;
public function __construct(
EventDispatcherInterface $eventDispatcher,
SoftReferenceParserFactory $softReferenceParserFactory
) {
parent::__construct($eventDispatcher);
$this->softReferenceParserFactory = $softReferenceParserFactory;
trigger_error(
'SoftReferenceIndex will be removed in TYPO3 v12.0, use appropriate TYPO3\CMS\Core\DataHandling\SoftReference\* class instead.',
E_USER_DEPRECATED
);
}
/**
* @deprecated since v11, will be removed in v12
*/
public function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath = '')
{
$this->parserKey = (string)$spKey;
$this->setTokenIdBasePrefix($table, (string)$uid, $field, $structurePath);
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser($spKey);
$softReferenceParser->setParserKey($spKey, $spParams);
return $softReferenceParser->parse($table, $field, $uid, $content, $structurePath)->toNullableArray();
}
public function parse(string $table, string $field, int $uid, string $content, string $structurePath = ''): SoftReferenceParserResult
{
// does nothing
return SoftReferenceParserResult::createWithoutMatches();
}
public function setParserKey(string $parserKey, array $parameters): void
{
// does nothing
}
/**
* TypoLink value processing.
* Will process input value as a TypoLink value.
*
* @param string $content The input content to analyze
* @param array $spParams Parameters set for the softref parser key in TCA/columns. value "linkList" will split the string by comma before processing.
* @return array|null Result array on positive matches, see description above. Otherwise null
* @see \TYPO3\CMS\Frontend\ContentObject::typolink()
* @see getTypoLinkParts()
*/
public function findRef_typolink($content, $spParams)
{
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser('typolink');
$softReferenceParser->setParserKey('typolink', (array)$spParams);
return $softReferenceParser->parse('', '', '', $content)->toNullableArray();
}
/**
* TypoLink tag processing.
* Will search for <link ...> and <a> tags in the content string and process any found.
*
* @param string $content The input content to analyze
* @return array|null Result array on positive matches, see description above. Otherwise null
* @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::typolink()
* @see getTypoLinkParts()
*/
public function findRef_typolink_tag($content)
{
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser('typolink_tag');
$softReferenceParser->setParserKey('typolink_tag', []);
return $softReferenceParser->parse('', '', '', $content)->toNullableArray();
}
/**
* Finding email addresses in content and making them substitutable.
*
* @param string $content The input content to analyze
* @param array $spParams Parameters set for the softref parser key in TCA/columns
* @return array|null Result array on positive matches, see description above. Otherwise null
*/
public function findRef_email($content, $spParams)
{
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser('email');
$softReferenceParser->setParserKey('email', (array)$spParams);
return $softReferenceParser->parse('', '', '', $content)->toNullableArray();
}
/**
* Finding URLs in content
*
* @param string $content The input content to analyze
* @param array $spParams Parameters set for the softref parser key in TCA/columns
* @return array|null Result array on positive matches, see description above. Otherwise null
*/
public function findRef_url($content, $spParams)
{
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser('url');
$softReferenceParser->setParserKey('url', (array)$spParams);
return $softReferenceParser->parse('', '', '', $content)->toNullableArray();
}
/**
* Finding reference to files from extensions in content, but only to notify about their existence. No substitution
*
* @param string $content The input content to analyze
* @return array|null Result array on positive matches, see description above. Otherwise null
*/
public function findRef_extension_fileref($content)
{
$softReferenceParser = $this->softReferenceParserFactory->getSoftReferenceParser('ext_fileref');
$softReferenceParser->setParserKey('ext_fileref', []);
return $softReferenceParser->parse('', '', '', $content)->toNullableArray();
}
}
......@@ -15,6 +15,7 @@ The following PHP classes that have previously been marked as deprecated for v11
- :php:`\TYPO3\CMS\Core\Cache\Backend\WincacheBackend`
- :php:`\TYPO3\CMS\Core\Database\QueryGenerator`
- :php:`\TYPO3\CMS\Core\Database\QueryView`
- :php:`\TYPO3\CMS\Core\Database\SoftReferenceIndex`
- :php:`\TYPO3\CMS\Core\Service\AbstractService`
- :php:`\TYPO3\CMS\Extbase\Domain\Model\BackendUser`
- :php:`\TYPO3\CMS\Extbase\Domain\Model\BackendUserGroup`
......@@ -44,8 +45,10 @@ The following PHP class methods that have previously been marked as deprecated f
The following PHP static class methods that have previously been marked as deprecated for v11 and were now removed:
- :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::fixVersioningPid()`
- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::stdAuthCode()`
- :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::softRefParserObj()`
- :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::explodeSoftRefParserList()`
- :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::viewOnClick`
- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::stdAuthCode()`
The following methods changed signature according to previous deprecations in v11 at the end of the argument list:
......@@ -61,7 +64,8 @@ The following public class properties have been dropped:
The following class methods visibility have been changed to protected:
- :php:`\Full\Class\Name->methodName`
- :php:`\TYPO3\CMS\Core\DataHandling\SoftReference\TypolinkSoftReferenceParser->getTypoLinkParts`
- :php:`\TYPO3\CMS\Core\DataHandling\SoftReference\TypolinkSoftReferenceParser->setTypoLinkPartsElement`
The following class methods visibility have been changed to private:
......
......@@ -26,28 +26,26 @@ class EmailSoftReferenceParserTest extends AbstractSoftReferenceParserTest
return [
'Simple email address found' => [
'foo@bar.baz',
[
'content' => 'foo@bar.baz',
'elements' => [
2 => [
'matchString' => 'foo@bar.baz',
],
'content' => 'foo@bar.baz',
'elements' => [
2 => [
'matchString' => 'foo@bar.baz',
],
],
'hasMatched' => true,
],
'Multiple email addresses found' => [
'This is my first email: foo@bar.baz and this is my second email: foo-_2@bar.baz',
[
'content' => 'This is my first email: foo@bar.baz and this is my second email: foo-_2@bar.baz',
'elements' => [
2 => [
'matchString' => 'foo@bar.baz',
],
5 => [
'matchString' => 'foo-_2@bar.baz',
],
'content' => 'This is my first email: foo@bar.baz and this is my second email: foo-_2@bar.baz',
'elements' => [
2 => [
'matchString' => 'foo@bar.baz',
],
5 => [
'matchString' => 'foo-_2@bar.baz',
],
],
'hasMatched' => true,
],
'Invalid emails are ignored' => [
'abc-@mail.com
......@@ -58,21 +56,22 @@ class EmailSoftReferenceParserTest extends AbstractSoftReferenceParserTest
abc.def@mail#archive.com
abc.def@mail
abc.def@mail..com',
null,
'content' => '',
'elements' => [],
'hasMatched' => false,
],
'E-Mails in html match' => [
'<a href="mailto:foo@bar.de">foo@bar.baz</a>',
[
'content' => '<a href="mailto:foo@bar.de">foo@bar.baz</a>',
'elements' => [
2 => [
'matchString' => 'foo@bar.de',
],
5 => [
'matchString' => 'foo@bar.baz',
],
'content' => '<a href="mailto:foo@bar.de">foo@bar.baz</a>',
'elements' => [
2 => [
'matchString' => 'foo@bar.de',
],
5 => [
'matchString' => 'foo@bar.baz',
],
],
'hasMatched' => true,
],
];
}
......@@ -81,11 +80,13 @@ class EmailSoftReferenceParserTest extends AbstractSoftReferenceParserTest
* @test
* @dataProvider emailSoftReferenceParserTestDataProvider
*/
public function emailSoftReferenceParserTest(string $content, ?array $expected): void
public function emailSoftReferenceParserTest(string $content, string $expectedContent, array $expectedElements, bool $expectedHasMatched): void
{
$subject = $this->getParserByKey('email');
$result = $subject->parse('be_users', 'email', 1, $content)->toNullableArray();
self::assertSame($expected, $result);
$result = $subject->parse('be_users', 'email', 1, $content);
self::assertSame($expectedContent, $result->getContent());
self::assertSame($expectedElements, $result->getMatchedElements());
self::assertSame($expectedHasMatched, $result->hasMatched());
}
/**
......@@ -96,10 +97,11 @@ class EmailSoftReferenceParserTest extends AbstractSoftReferenceParserTest
$content = 'My email is: foo@bar.baz';
$subject = $this->getParserByKey('email');
$subject->setParserKey('email', ['subst']);
$result = $subject->parse('be_users', 'email', 1, $content)->toNullableArray();
self::assertArrayHasKey('subst', $result['elements'][2]);
self::assertArrayHasKey('tokenID', $result['elements'][2]['subst']);
unset($result['elements'][2]['subst']['tokenID']);
$result = $subject->parse('be_users', 'email', 1, $content);
$matchedElements = $result->getMatchedElements();
self::assertArrayHasKey('subst', $matchedElements[2]);
self::assertArrayHasKey('tokenID', $matchedElements[2]['subst']);
unset($matchedElements[2]['subst']['tokenID']);
$expected = [
2 => [
......@@ -110,6 +112,6 @@ class EmailSoftReferenceParserTest extends AbstractSoftReferenceParserTest
],
],