diff --git a/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php b/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php index 9d06c66..aaede46 100644 --- a/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php +++ b/core/modules/link/src/Plugin/migrate/process/d6/FieldLink.php @@ -53,16 +53,102 @@ protected function canonicalizeUri($uri) { return $uri; } - // If the URL starts with 'www.' without scheme, add 'http://' prefix. - if (strpos($uri, 'www.') === 0) { - $uri = 'http://' . $uri; - return $uri; - } - // Remove the component of the URL. if (strpos($uri, '') === 0) { $uri = substr($uri, strlen('')); } + else { + // @TODO Complete letters. + $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", [ + "æ", // æ + "Æ", // Æ + "À", // À + "à", // à + "Á", // Á + "á", // á + "Â", //  + "â", // â + "å", // å + "Å", // Å + "ä", // ä + "Ä", // Ä + "Ç", // Ç + "ç", // ç + "Ð", // Ð + "ð", // ð + "È", // È + "è", // è + "É", // É + "é", // é + "Ê", // Ê + "ê", // ê + "Ë", // Ë + "ë", // ë + "Î", // Î + "î", // î + "Ï", // Ï + "ï", // ï + "ø", // ø + "Ø", // Ø + "ö", // ö + "Ö", // Ö + "Ô", // Ô + "ô", // ô + "Õ", // Õ + "õ", // õ + "Œ", // Œ + "œ", // œ + "ü", // ü + "Ü", // Ü + "Ù", // Ù + "ù", // ù + "Û", // Û + "û", // û + "Ÿ", // Ÿ + "ÿ", // ÿ + "Ñ", // Ñ + "ñ", // ñ + "þ", // þ + "Þ", // Þ + "ý", // ý + "Ý", // Ý + "¿", // ¿ + ]), ENT_QUOTES, 'UTF-8'); + + $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", [ + "ß", // ß + ]), ENT_QUOTES, 'UTF-8'); + + // Pattern specific to internal links. + $internal_pattern = "/^(?:[a-z0-9" . $LINK_ICHARS . "_\-+\[\] ]+)"; + + $directories = "(?:\/[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'#!():;*@\[\]]*)*"; + // Yes, four backslashes == a single backslash. + $query = "(?:\/?\?([?a-z0-9" . $LINK_ICHARS . "+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))"; + $anchor = "(?:#[a-z0-9" . $LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)"; + + // The rest of the path for a standard URL. + $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i'; + + if (!preg_match($internal_pattern . $end, $uri)) { + $allowed_protocols = ['http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal']; + $LINK_DOMAINS = 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local'; + + // Starting a parenthesis group with (?: means that it is grouped, but is not captured + $protocol = '((?:' . implode("|", $allowed_protocols) . '):\/\/)'; + $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w" . $LINK_ICHARS . "\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)"; + $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*(' . $LINK_DOMAINS . '|[a-z]{2}))?)'; + $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})'; + $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})'; + $port = '(?::([0-9]{1,5}))'; + + // Pattern specific to external links. + $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?'; + if (preg_match($external_pattern . $end, $uri)) { + return 'http://' . $uri; + } + } + } // Add the internal: scheme and ensure a leading slash. return 'internal:/' . ltrim($uri, '/'); diff --git a/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php index c933fcd..5815390 100644 --- a/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php +++ b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/FieldLinkTest.php @@ -58,6 +58,10 @@ public function canonicalizeUriDataProvider() { 'www.yahoo.com', 'http://www.yahoo.com', ], + 'Absolute URL without protocol prefix nor www' => [ + 'yahoo.com', + 'http://yahoo.com', + ], ]; }