77 lines
2.0 KiB
PHP
77 lines
2.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun3d\LanguageUrlStoreResolver\Model;
|
|
|
|
class HtmlLinkProcessor
|
|
{
|
|
/**
|
|
* @var UrlPathConverter
|
|
*/
|
|
private $urlPathConverter;
|
|
|
|
/**
|
|
* @param UrlPathConverter $urlPathConverter
|
|
*/
|
|
public function __construct(UrlPathConverter $urlPathConverter)
|
|
{
|
|
$this->urlPathConverter = $urlPathConverter;
|
|
}
|
|
|
|
/**
|
|
* Convert internal anchor URLs in complete page HTML.
|
|
*
|
|
* @param string $html
|
|
* @param string $language
|
|
* @return string
|
|
*/
|
|
public function process(string $html, string $language): string
|
|
{
|
|
if (stripos($html, '<a') === false) {
|
|
return $html;
|
|
}
|
|
|
|
$result = preg_replace_callback(
|
|
'~(<a\b[^>]*\bhref\s*=\s*)(["\'])(.*?)\2~is',
|
|
function (array $matches) use ($language): string {
|
|
$href = $matches[3];
|
|
$normalizedHref = trim($href);
|
|
|
|
if (!$this->isConvertibleHref($normalizedHref)) {
|
|
return $matches[0];
|
|
}
|
|
|
|
$convertedHref = $this->urlPathConverter->toLanguageUrl($normalizedHref, $language);
|
|
if ($convertedHref === $normalizedHref) {
|
|
return $matches[0];
|
|
}
|
|
|
|
return $matches[1] . $matches[2] . $convertedHref . $matches[2];
|
|
},
|
|
$html
|
|
);
|
|
|
|
return is_string($result) ? $result : $html;
|
|
}
|
|
|
|
/**
|
|
* Check whether an href represents a navigational HTTP URL.
|
|
*
|
|
* @param string $href
|
|
* @return bool
|
|
*/
|
|
private function isConvertibleHref(string $href): bool
|
|
{
|
|
if ($href === '' || $href[0] === '#' || $href[0] === '?') {
|
|
return false;
|
|
}
|
|
|
|
if (strpos($href, '{{') !== false || strpos($href, '${') !== false) {
|
|
return false;
|
|
}
|
|
|
|
return !preg_match('~^[a-z][a-z0-9+.-]*:~i', $href)
|
|
|| preg_match('~^https?:~i', $href) === 1;
|
|
}
|
|
}
|