/
HtmlLinkMultisite.php
executable file
·121 lines (98 loc) · 3.35 KB
/
HtmlLinkMultisite.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
namespace Pushword\Core\Component\EntityFilter\Filter;
use Doctrine\ORM\EntityManagerInterface;
use Pushword\Core\AutowiringTrait\RequiredApps;
use Pushword\Core\AutowiringTrait\RequiredAppTrait;
use Pushword\Core\AutowiringTrait\RequiredTwigTrait;
use Pushword\Core\Repository\Repository;
use Pushword\Core\Router\Router;
use Pushword\Core\Router\RouterInterface;
use Pushword\Core\Twig\LinkTwigTrait;
final class HtmlLinkMultisite extends AbstractFilter
{
use LinkTwigTrait;
use RequiredApps;
use RequiredAppTrait;
use RequiredTwigTrait;
private EntityManagerInterface $entityManager;
public function setEntityManager(EntityManagerInterface $entityManager): void
{
$this->entityManager = $entityManager;
}
private RouterInterface $router;
public function setRouter(RouterInterface $router): void
{
$this->router = $router;
}
/**
* @var string
*/
public const HTML_REGEX = '/href=((?P<hrefQuote>\'|")(?P<href1>(?:(?!(?P=hrefQuote)).)*)(?P=hrefQuote)|(?P<href2>[^"\'>][^> \r\n\t\f\v]*))/iJ';
/** @var string */
public const HTML_REGEX_HREF_KEY = 'href';
public function apply(mixed $propertyValue): string
{
$propertyValue = $this->string($propertyValue);
if (! $this->router instanceof Router) {
return $propertyValue;
}
if (! $this->router->mayUseCustomPath()) {
return $propertyValue;
}
return $this->convertLinks($propertyValue);
}
public function convertLinks(string $body): string
{
\Safe\preg_match_all(self::HTML_REGEX, $body, $matches);
if (! isset($matches[1])) {
return $body;
}
return $this->replaceLinks($body, $matches);
}
/**
* @param array<(string|int), array<int, string>> $matches
*/
private function replaceLinks(string $body, array $matches): string
{
$nbrMatch = \count($matches[0]);
for ($k = 0; $k < $nbrMatch; ++$k) {
$currentHref = $this->getHrefValue($matches, $k);
$newHref = $this->getHref($currentHref);
if ($newHref !== $currentHref) {
$body = str_replace(
$matches[0][$k],
'href='.($matches['hrefQuote'][$k] ?? '"').$newHref.($matches['hrefQuote'][$k] ?? '"'),
$body
);
}
}
return $body;
}
private function getHref(string $href): string
{
if (! str_starts_with($href, '/')) {
return $href;
}
if (($currentPage = $this->apps->getCurrentPage()) === null) {
return $href;
}
$newHref = substr($href, 1);
if (($page = Repository::getPageRepository($this->entityManager, $currentPage::class)
->findOneBy(['slug' => $newHref, 'host' => $currentPage->getHost()])) !== null) {
return $this->router->generate($page);
}
return $href;
}
/**
* @param array<(string|int), array<int, string>> $matches
*/
private function getHrefValue(array $matches, int $k): string
{
for ($i = 1; $i <= 2; ++$i) {
if ('' !== $matches[self::HTML_REGEX_HREF_KEY.$i][$k]) {
return $matches[self::HTML_REGEX_HREF_KEY.$i][$k];
}
}
throw new \Exception();
}
}