decode(''), true); // Add optional rel support as sixth TypoLink part. if (array_key_exists('rel', $typoLinkParts) || array_key_exists('download', $typoLinkParts)) { $reverseSortedParameters = ['rel' => '', ...$reverseSortedParameters]; } // Add optional download support as seventh TypoLink part. if (array_key_exists('download', $typoLinkParts)) { $reverseSortedParameters = ['download' => '', ...$reverseSortedParameters]; } $aValueWasSet = false; foreach ($reverseSortedParameters as $key => &$value) { $value = $typoLinkParts[$key] ?? ''; // escape special character \ and " $value = str_replace(['\\', '"'], ['\\\\', '\\"'], $value); // enclose with quotes if a string contains the delimiter if (str_contains($value, self::DELIMITER)) { $value = '"' . $value . '"'; } // fill with - if another values has already been set if ($value === '' && $aValueWasSet) { $value = self::EMPTY_VALUE_SYMBOL; } if ($value !== '') { $aValueWasSet = true; } } $reverseSortedParameters = $this->eventDispatcher->dispatch( new BeforeTypoLinkEncodedEvent( parameters: $reverseSortedParameters, typoLinkParts: $typoLinkParts, delimiter: self::DELIMITER, emptyValueSymbol: self::EMPTY_VALUE_SYMBOL ) )->getParameters(); return trim(implode(self::DELIMITER, array_reverse($reverseSortedParameters, true))); } /** * Decodes a TypoLink string into its parts * * @param string $typoLink The properly encoded TypoLink string * @return array{url: string, target: string, class: string, title: string, additionalParams: string, rel?: string, download?: string} */ public function decode(string $typoLink): array { $typoLink = trim($typoLink); if ($typoLink !== '') { $parts = str_replace(['\\\\', '\\"'], ['\\', '"'], str_getcsv($typoLink, self::DELIMITER, '"', '\\')); } else { $parts = []; } // The order of the entries is crucial!! $typoLinkParts = [ 'url' => isset($parts[0]) ? trim($parts[0]) : '', 'target' => isset($parts[1]) && $parts[1] !== self::EMPTY_VALUE_SYMBOL ? trim($parts[1]) : '', 'class' => isset($parts[2]) && $parts[2] !== self::EMPTY_VALUE_SYMBOL ? trim($parts[2]) : '', 'title' => isset($parts[3]) && $parts[3] !== self::EMPTY_VALUE_SYMBOL ? trim($parts[3]) : '', 'additionalParams' => isset($parts[4]) && $parts[4] !== self::EMPTY_VALUE_SYMBOL ? trim($parts[4]) : '', ]; if (isset($parts[5]) && $parts[5] !== self::EMPTY_VALUE_SYMBOL) { $typoLinkParts['rel'] = trim($parts[5]); } if (isset($parts[6]) && $parts[6] !== self::EMPTY_VALUE_SYMBOL) { $typoLinkParts['download'] = trim($parts[6]); } return $this->eventDispatcher->dispatch( new AfterTypoLinkDecodedEvent( typoLinkParts: $typoLinkParts, typoLink: $typoLink, delimiter: self::DELIMITER, emptyValueSymbol: self::EMPTY_VALUE_SYMBOL ) )->getTypoLinkParts(); } }