2 declare(strict_types = 1);
18 use Psr\Log\LoggerInterface;
54 (?\'tag\'<link\\s++(?\'typolink\'[^>]+)>)
55 (?\'content\'(?:[^<]++|<(?!/link>))*+)
59 (?\'tag\'<link\\s++(?\'typolink\'(?:[^&]++|&(?!gt;))++)>)
60 (?\'content\'(?:[^&]++|&(?!lt;/link>))*+)
77 return 'Scan for old "<link>" syntax in richtext and text fields and update to "<a href>"';
88 if (!is_array(
$GLOBALS[
'TCA'][$tableName])) {
89 throw new \RuntimeException(
90 'Globals TCA of ' . $tableName .
' must be an array',
95 if (in_array($tableName, $this->blackListedTables,
true)) {
98 $tcaOfTable =
$GLOBALS[
'TCA'][$tableName];
99 if (!is_array($tcaOfTable[
'columns'])) {
102 foreach ($tcaOfTable[
'columns'] as $fieldName => $fieldConfiguration) {
103 if (isset($fieldConfiguration[
'config'][
'type'])
104 && in_array($fieldConfiguration[
'config'][
'type'], [
'input',
'text',
'flex'],
true)
107 if (!is_array($this->tableFieldListToConsider[$tableName])) {
108 $this->tableFieldListToConsider[$tableName] = [];
110 $this->tableFieldListToConsider[$tableName][] = $fieldName;
125 if (!is_array($this->tableFieldListToConsider)) {
126 throw new \RuntimeException(
127 'Parent should not call me with a table name I do not consider relevant for update',
131 $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
132 $fieldsToScan = $this->tableFieldListToConsider[$tableName];
133 foreach ($fieldsToScan as $fieldName) {
138 $GLOBALS[
'TCA'][$tableName][
'columns'][$fieldName][
'config'][
'type'] ===
'flex'
156 $content = $row[$fieldName];
157 if (is_string($content)
159 && (stripos($content,
'<link') !==
false || stripos($content,
'<link') !==
false)
161 $result = preg_replace_callback(
162 $this->regularExpressions[$isFlexformField ?
'flex' :
'default'],
163 function ($matches) use ($isFlexformField) {
164 $typoLink = $isFlexformField ? htmlspecialchars_decode($matches[
'typolink']) : $matches[
'typolink'];
165 $typoLinkParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($typoLink);
166 $anchorTagAttributes = [
167 'target' => $typoLinkParts[
'target'],
168 'class' => $typoLinkParts[
'class'],
169 'title' => $typoLinkParts[
'title'],
172 $link = $typoLinkParts[
'url'];
173 if (!empty($typoLinkParts[
'additionalParams'])) {
174 $link .= (strpos($link,
'?') ===
false ?
'?' :
'&') . ltrim($typoLinkParts[
'additionalParams'],
'&');
178 $linkService = GeneralUtility::makeInstance(LinkService::class);
180 $linkParts = $linkService->resolve($link);
181 $anchorTagAttributes[
'href'] = $linkService->asString($linkParts);
182 $newLink =
'<a ' . GeneralUtility::implodeAttributes($anchorTagAttributes,
true) .
'>' .
183 ($isFlexformField ? htmlspecialchars_decode($matches[
'content']) : $matches[
'content']) .
185 if ($isFlexformField) {
186 $newLink = htmlspecialchars($newLink);
188 }
catch (UnknownLinkHandlerException $e) {
189 $newLink = $matches[0];
190 }
catch (UnknownUrnException $e) {
191 $newLink = $matches[0];
198 if ($result !==
null) {
201 $this->logger->error(
'Converting links failed due to PCRE error', [
202 'table' => $tableName,
203 'field' => $fieldName,
204 'uid' => $row[
'uid'] ??
null,
205 'errorCode' => preg_last_error()