From a97cc7367e51fb0f192a459659e343c280588a7b Mon Sep 17 00:00:00 2001
From: Sybille Peters <sypets@gmx.de>
Date: Sun, 11 Feb 2024 12:33:34 +0100
Subject: [PATCH] [DOCS] Document how to replace a linktype

Since the linktypes are automatically registered in Linkvalidator,
it is no longer quite as easy to replace the "external" linktype.
You cannot register another linktype using the same identifier
"external", so a different identifier must be used.

A minimal example is added to the developer section in the
documentation.

Resolves: #101673
Related: #96935
Releases: main, 12.4
Change-Id: I9afa1a77fe56675dff2dbc1bacc3635b1b9b36c6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/82849
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../Documentation/Configuration/Index.rst     |  2 +-
 .../Development/LinkTypeImplementation.rst    | 68 +++++++++++++++++++
 .../Documentation/KnownProblems/Index.rst     |  2 +-
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/typo3/sysext/linkvalidator/Documentation/Configuration/Index.rst b/typo3/sysext/linkvalidator/Documentation/Configuration/Index.rst
index 7e23dfd40fed..f50335342e32 100644
--- a/typo3/sysext/linkvalidator/Documentation/Configuration/Index.rst
+++ b/typo3/sysext/linkvalidator/Documentation/Configuration/Index.rst
@@ -132,7 +132,7 @@ linktypes
          db,file,external
 
 
-
+.. _linktypes-config:
 .. _linktypes-config-external:
 
 linktypesConfig.external.httpAgentName
diff --git a/typo3/sysext/linkvalidator/Documentation/Development/LinkTypeImplementation.rst b/typo3/sysext/linkvalidator/Documentation/Development/LinkTypeImplementation.rst
index 30ce37bc435a..c2361fc615f6 100644
--- a/typo3/sysext/linkvalidator/Documentation/Development/LinkTypeImplementation.rst
+++ b/typo3/sysext/linkvalidator/Documentation/Development/LinkTypeImplementation.rst
@@ -34,6 +34,9 @@ it is sufficient to set the :php:`$identifier` class property.
 Example
 =======
 
+Add new linktype
+----------------
+
 You can find the following example in the extension
 `t3docs/examples <https://github.com/TYPO3-Documentation/t3docs-examples>`__.
 
@@ -66,6 +69,71 @@ Or if autoconfiguration is not desired for some reason:
           tags:
              -  name: linkvalidator.linktype
 
+.. _linktype-implementation-override-external:
+
+Override the ExternalLinktype class
+-----------------------------------
+
+A new custom class should replace
+:php:`\TYPO3\CMS\Linkvalidator\Linktype\ExternalLinktype`. The class inherits
+existing functionality from :php:`ExternalLinktype`, but will be registered with
+the identifier "custom_external":
+
+..  code-block:: php
+    :caption: 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;
+        }
+    }
+
+Use the new linktype:
+
+..  code-block:: typoscript
+    :caption: EXT:my_extension/Configuration/page.tsconfig
+
+    mod.linkvalidator.linktypes = db,file,custom_external
+
+Since the identifier changes, the configuration should be copied to
+:typoscript:`mod.linkvalidator.linktypesConfig.custom_external`, so that it will be
+passed to the linktype, for example:
+
+..  code-block:: typoscript
+    :caption: EXT:my_extension/Configuration/page.tsconfig
+
+    mod.linkvalidator.linktypesConfig.custom_external < mod.linkvalidator.linktypesConfig.external
+
 Migration from TYPO3 11 LTS and below
 =====================================
 
diff --git a/typo3/sysext/linkvalidator/Documentation/KnownProblems/Index.rst b/typo3/sysext/linkvalidator/Documentation/KnownProblems/Index.rst
index 73637ad1eaad..b6333fbe22a3 100644
--- a/typo3/sysext/linkvalidator/Documentation/KnownProblems/Index.rst
+++ b/typo3/sysext/linkvalidator/Documentation/KnownProblems/Index.rst
@@ -22,7 +22,7 @@ There are (at least) 2 possible counter-measures:
 #. Turn off external link checking entirely
    by removing `external` from Page TSconfig :ref:`linktypes`
 
-#. :ref:`Override the ExternalLinktype class <linktype-implementation>`
+#. :ref:`linktype-implementation-override-external`
    (in your own extension), to check only specific URLs or exclude specific
    URLs or handle only specific error types as errors.
 
-- 
GitLab