Deprecation: #94687 - Deprecate SoftReferenceIndex

See forge#94687

Description

The TYPO3\CMS\Core\Database\SoftReferenceIndex class combined all core soft reference parser implementations into one class. Each and every parser had its own method residing in one class. It is now possible to define a dedicated class for each parser, as a result SoftReferenceIndex is not needed anymore and has been therefore marked as deprecated.

The related method \TYPO3\CMS\Backend\Utility\BackendUtility::softRefParserObj() was used to get the according soft reference parser object and was basically a factory method. This logic has been moved into TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory. BackendUtility::softRefParserObj has been marked as internal in TYPO3 v11 already. To ease migration, the old static method is still in place and triggers a PHP E_USER_DEPRECATED error when called.

Another tightly coupled method \TYPO3\CMS\Backend\Utility\BackendUtility::explodeSoftRefParserList(), which was used to parse the comma separated list of soft reference parsers and return them as an array, has now also been marked as deprecated. It was mostly used for internal purposes. The corresponding logic now resides in the getParsersBySoftRefParserList method of TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory.

All soft reference parsers are now required to implement the TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface. Not doing so will trigger a PHP E_USER_DEPRECATED error. In TYPO3 v12 this will throw an exception.

Impact

The following class is marked as deprecated. Instantiating this class will trigger a PHP E_USER_DEPRECATED error.

  • TYPO3\CMS\Core\Database\SoftReferenceIndex

The following methods are marked as deprecated. Calling these methods will trigger a PHP E_USER_DEPRECATED error.

  • \TYPO3\CMS\Backend\Utility\BackendUtility::softRefParserObj()

  • \TYPO3\CMS\Backend\Utility\BackendUtility::explodeSoftRefParserList()

Soft reference parsers must implement TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface. Otherwise a PHP E_USER_DEPRECATED error will be triggered and an exception will be thrown in TYPO3 v12.

Affected Installations

  • All installations registering user-defined soft reference parsers not implementing TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface.

  • All installations calling any of the above-mentioned methods.

  • All installations, which are using TYPO3\CMS\Core\Database\SoftReferenceIndex directly.

Migration

Among other methods TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface ensures the method parse is implemented. The previously used method name findRef() can be simply renamed to parse(). The first 4 parameters $table, $field, $uid and $content stay the same, as well as the seventh (now fifth) and last parameter $structurePath. The remaining two parameters $spKey (now $parserKey) and $spParams (now $parameters) have to be set by the setParserKey() method, in case they are needed. The key can be retrieved by using the getParserKey() method.

The return type has been changed to an instance of TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserResult. It provides as static factory method simply called create(). It expects the content part of the old array as the first parameter and the elements part as the second. If there are no matches, one can simply call SoftReferenceParserResult::createWithoutMatches().

If needed, one could also extend TYPO3\CMS\Core\DataHandling\SoftReference\AbstractSoftReferenceParser. This abstract class comes with the helper method makeTokenID() (originally in TYPO3\CMS\Core\Database\SoftReferenceIndex) and a new method setTokenIdBasePrefix, which sets the concatenated string for the property tokenID_basePrefix.

Example before:

class MySoftReferenceParser implements SingletonInterface
{
    public function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath = '')
    {
        ...

        if (!empty($elements)) {
            $resultArray = [
                'content' => $content,
                'elements' => $elements
            ];
            return $resultArray;
        }

        return null;
    }
}

Example after:

class MySoftReferenceParser implements SoftReferenceParserInterface
{
    protected string $parserKey = '';
    protected array $parameters = [];

    public function parse(string $table, string $field, int $uid, string $content, string $structurePath = ''): SoftReferenceParserResult
    {
        ...

        if (!empty($elements)) {
            return SoftReferenceParserResult::create(
                $content,
                $elements
            );
        }
        return SoftReferenceParserResult::createWithoutMatches();
    }

    /**
     * @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 ";
     */
    public function setParserKey(string $parserKey, array $parameters): void
    {
        $this->parserKey = $parserKey;
        $this->parameters = $parameters;
    }

    public function getParserKey(): string
    {
        return $this->parserKey;
    }
}

Instead of calling BackendUtility::softRefParserObj() one should now create an instance of TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory. This factory has a method: getSoftReferenceParser(), which expects the soft reference key as first argument (just like the BackendUtility method).

Example before:

$softRefObj = BackendUtility::softRefParserObj('typolink');

Example after:

$softReferenceParserFactory = GeneralUtility::makeInstance(SoftReferenceParserFactory::class);
$softReferenceParser = $softReferenceParserFactory->getSoftReferenceParser('typolink');

The method BackendUtility::explodeSoftRefParserList() should be replaced by instantiating TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory and calling getParsersBySoftRefParserList(). This method expects the $parserList as first argument, same as in the BackendUtility The second argument is a fallback configuration array for softref parsers. This method returns an iterable of TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserInterface.

Example before:

$softRefs = BackendUtility::explodeSoftRefParserList($conf['softref']);

foreach ($softRefs as $spKey => $spParams) {
    $softRefObj = BackendUtility::softRefParserObj($spKey);
    $resultArray = $softRefObj->findRef($table, $field, $idRecord, $valueField, $spKey, $softRefParams);
}

Example after:

foreach ($softReferenceParserFactory->getParsersBySoftRefParserList($conf['softref'], $softRefParams) as $softReferenceParser) {
    $parserResult = $softReferenceParser->parse($table, $field, $idRecord, $valueField);
}