Validate links of a custom link handler (t3://...)
The link validator does not scan the content itself. It evaluates the result of
the soft reference parsers configured in the TCA of a field, for example
typolink_ for
tt_ and
typolink
for link
fields like
tt_.
Both parsers know the core link types such as pages, files, URLs and records.
For all other link types, for example a custom link handler providing links like
t3://, they dispatch the PSR-14 event
\TYPO3\.
To validate such links, two parts are needed:
- An event listener which turns the link into an entry for the link validator.
- A linktype which checks the entry.
No custom soft reference parser and no change of the TCA are required, as long
as the field already uses
typolink_ or
typolink
.
Event listener
The listener returns an element whose
subst
array describes the link. The
type
is matched by the linktype, the
token is passed to
Linktype as the URL to check.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\DataHandling\Event\AppendLinkHandlerElementsEvent;
#[AsEventListener]
final class AppendShopLinkElements
{
public function __invoke(AppendLinkHandlerElementsEvent $event): void
{
$linkParts = $event->getLinkParts();
// Link details of "t3://shop?..." as built by the link handler
if (($linkParts['type'] ?? '') !== 'shop') {
return;
}
$tokenId = $event->getTokenId();
$event->addElements([
$tokenId . ':' . $event->getIdx() => [
'matchString' => $event->getContent(),
'subst' => [
'type' => 'shop',
'tokenID' => $tokenId,
'tokenValue' => (string)($linkParts['identifier'] ?? ''),
],
],
]);
}
}
Calling
add marks the event as resolved. Links without a
resolved event are skipped by
typolink_ and reported as
"Couldn't decide typolink mode." by
typolink
.
Linktype
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Linktype;
use TYPO3\CMS\Linkvalidator\LinkAnalyzer;
use TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype;
final class ShopLinktype extends AbstractLinktype
{
protected string $identifier = 'shop';
public function checkLink(string $url, array $softRefEntry, LinkAnalyzer $reference): bool
{
// $url is the "tokenValue" set in the event listener
return $this->productExists($url);
}
private function productExists(string $identifier): bool
{
// Ask your shop API or database
return true;
}
}
The default
Abstract selects the linktype if the
type
of the entry equals the identifier of the linktype, here shop.
Register and activate the linktype as described in
Implementation of a custom linktype for the link validator:
mod.linkvalidator.linktypes = db,file,external,shop
Fields without the typolink soft reference parsers
If a field does not use
typolink_ or
typolink
, add one of them
to the
softref
option of the field in the TCA, for example:
$GLOBALS['TCA']['tt_content']['columns']['my_field']['config']['softref'] = 'typolink';