Custom linktypes

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 TYPO3CMSLinkvalidatorLinktypeLinktypeInterface.

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

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

Vendor\Extension\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 TYPO3CMSLinkvalidatorLinktypeAbstractLinktype it is sufficient to set the $identifier class property.

For custom naming of a linktype, the additional interface TYPO3CMSLinkvalidatorLinktypeLabelledLinktypeInterface. can be implemented, which is also part of the default AbstractLinktype implementation. The method getReadableName() is used to return the custom localized name of a linktype.

Example

Add new linktype

You can find the following example in the extension t3docs/examples.

Extend TYPO3CMSLinkvalidatorLinktypeAbstractLinktype to create a custom linktype:

EXT:examples/Classes/LinkValidator/LinkType/ExampleLinkType.php
<?php

/*
 * This file is part of the TYPO3 CMS project. [...]
 */ 

namespace T3docs\Examples\LinkValidator\LinkType;

use TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype;

/**
 * This class provides Check Example Links plugin implementation
 */
class ExampleLinkType extends AbstractLinktype
{
    protected string $identifier = 'example';

    public function checkLink($url, $softRefEntry, $reference): bool
    {
        $isValidUrl = false;
        // TODO: Implement checkLink() method.
        return $isValidUrl;
    }

    public function getErrorMessage($errorParams): string
    {
        $lang = $this->getLanguageService();
        return match ($errorParams['errno'] ?? 0) {
            404 => $lang->sL('LLL:EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf:list.report.pagenotfound404'),
            // fall back to generic error message
            default => sprintf(
                $lang->sL('LLL:EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf:list.report.externalerror'),
                $errorParams['errno'],
            ),
        };
    }
}
Copied!

Activate the new linktype in the page tsconfig:

EXT:examples/Configuration/TsConfig/Page/Extension/Linkvalidator.tsconfig
mod.linkvalidator {
   # specify link types to be crawled
   linktypes = db,file,external,example
}
Copied!

The extension that provides the linktype must have a Configuration/Services.yaml file that contains either:

EXT:examples/Configuration/Services.yaml
services:
   _defaults:
      autoconfigure: true
Copied!

Or if autoconfiguration is not desired for some reason:

EXT:examples/Configuration/Services.yaml
services:
   T3docs\Examples\LinkValidator\LinkType\ExampleLinkType:
      tags:
         -  name: linkvalidator.linktype
Copied!

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":

EXT:my_extension/Classes/Linktype/ExternalLinktype.php
namespace MyVendor\NyExtension\Linktype\ExternalLinktype;

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:

EXT: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:

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

Migration from TYPO3 11 LTS and below

Remove $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] from your ext_localconf.php file.

If autoconfigure is not enabled in your Configuration/Services.(yaml|php), add the tag linkvalidator.linktype manually to your linktype service.

Additionally, make sure to either implement public function getIdentifier(): string or, in case your linktype extends AbstractLinktype, to set the $identifier class property.