Implementation of a custom linktype for the link validator 

The LinkValidator uses so called "linktypes" to check for different types of links, for example internal or external links.

All "linktypes" have to implement the \TYPO3\CMS\Linkvalidator\Linktype\LinktypeInterface .

Classes implementing the LinktypeInterface are automatically registered, if autoconfigure is enabled in packages/my_extension/Configuration/Services.yaml.

Alternatively, one can manually tag a custom link type with the linkvalidator.linktype tag:

packages/my_extension/Configuration/Services.yaml
# Other definitions

MyVendor\MyExtension\Linktype\MyCustomLinktype:
  tags:
    - name: linkvalidator.linktype
Copied!

Due to the autoconfiguration, the identifier has to be provided by the class directly, using the method getIdentifier() .

When extending \TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype it is sufficient to set the $identifier class property.

For custom naming of a linktype, the additional interface \TYPO3\CMS\Linkvalidator\Linktype\LabelledLinktypeInterface . can be implemented, which is also part of the default AbstractLinktype implementation.

The method LabelledLinktypeInterface->getReadableName() is used to return the custom localized name of a linktype.

Example 

Override the ExternalLinktype class 

A new custom class should replace \TYPO3\CMS\Linkvalidator\Linktype\ExternalLinktype . The class inherits existing functionality from ExternalLinktype , but will be registered with the identifier "custom_external":

packages/my_extension/Classes/Linktype/ExternalLinktype.php
<?php

namespace MyVendor\NyExtension\Linktype\ExternalLinktype;

use TYPO3\CMS\Linkvalidator\LinkAnalyzer;
use TYPO3\CMS\Linkvalidator\Linktype\ExternalLinktype as LinkvalidatorExternalLinkType;

// This class inherits from ExternalLinktype,
// so it is only necessary to override some methods.
class ExternalLinktype extends LinkvalidatorExternalLinkType
{
    // This class must use a different identifier because "external" is already used.
    protected string $identifier = 'custom_external';

    public function checkLink(
        string $origUrl,
        array $softRefEntry,
        LinkAnalyzer $reference
    ): bool {
        // do additional stuff here or after parent::checkLink
        // ...
        return parent::checkLink($origUrl, $softRefEntry, $reference);
    }

    public function fetchType(array $value, string $type, string $key): string
    {
        preg_match_all(
            '/((?:http|https))(?::\\/\\/)(?:[^\\s<>]+)/i',
            (string)$value['tokenValue'],
            $urls,
            PREG_PATTERN_ORDER
        );
        if (!empty($urls[0][0])) {
            $type = $this->getIdentifier();
        }
        return $type;
    }
}
Copied!

Use the new linktype:

packages/my_extension/Configuration/page.tsconfig
mod.linkvalidator.linktypes = db,file,custom_external
Copied!

Since the identifier changes, the configuration should be copied to mod.linkvalidator.linktypesConfig.custom_external , so that it will be passed to the linktype, for example:

packages/my_extension/Configuration/page.tsconfig
mod.linkvalidator.linktypesConfig.custom_external < mod.linkvalidator.linktypesConfig.external
Copied!