‪TYPO3CMS  10.4
LegacyLinkNotationConverter.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
27 
35 {
36 
40  protected ‪$resourceFactory;
41 
59  public function ‪resolve(string $linkParameter): array
60  {
61  $a = [];
62  if (stripos(rawurldecode(trim($linkParameter)), 'phar://') === 0) {
63  throw new \RuntimeException(
64  'phar scheme not allowed as soft reference target',
65  1530030673
66  );
67  }
68 
69  $result = [];
70 
71  // Resolve FAL-api "file:UID-of-sys_file-record" and "file:combined-identifier"
72  if (stripos($linkParameter, 'file:') === 0) {
73  $result = $this->‪getFileOrFolderObjectFromMixedIdentifier(substr($linkParameter, 5));
74  } elseif (GeneralUtility::validEmail((string)parse_url($linkParameter, PHP_URL_PATH))) {
75  $result['type'] = ‪LinkService::TYPE_EMAIL;
76  $result['email'] = $linkParameter;
77  } elseif (strpos($linkParameter, 'tel:') === 0) {
78  $result['type'] = ‪LinkService::TYPE_TELEPHONE;
79  $result['telephone'] = $linkParameter;
80  } elseif (strpos($linkParameter, ':') !== false) {
81  // Check for link-handler keyword
82  [$linkHandlerKeyword, $linkHandlerValue] = explode(':', $linkParameter, 2);
83  $result['type'] = strtolower(trim($linkHandlerKeyword));
84  $result['url'] = $linkParameter;
85  $result['value'] = $linkHandlerValue;
86  if ($result['type'] === ‪LinkService::TYPE_RECORD) {
87  [$a['identifier'], $tableAndUid] = explode(':', $linkHandlerValue, 2);
88  $tableAndUid = explode(':', $tableAndUid);
89  if (count($tableAndUid) > 1) {
90  $a['table'] = $tableAndUid[0];
91  $a['uid'] = $tableAndUid[1];
92  } else {
93  // this case can happen if there is the very old linkhandler syntax, which was only record:<table>:<uid>
94  $a['table'] = $a['identifier'];
95  $a['uid'] = $tableAndUid[0];
96  }
97  $result = array_merge($result, $a);
98  }
99  } else {
100  // special handling without a scheme
101  $isLocalFile = 0;
102  $fileChar = (int)strpos($linkParameter, '/');
103  $urlChar = (int)strpos($linkParameter, '.');
104 
105  $isIdOrAlias = ‪MathUtility::canBeInterpretedAsInteger($linkParameter);
106  $matches = [];
107  // capture old RTE links relative to TYPO3_mainDir
108  if (preg_match('#../(?:index\\.php)?\\?id=([^&]+)#', $linkParameter, $matches)) {
109  $linkParameter = $matches[1];
110  $isIdOrAlias = true;
111  }
112  $containsSlash = false;
113  if (!$isIdOrAlias) {
114  // Detects if a file is found in site-root and if so it will be treated like a normal file.
115  [$rootFileDat] = explode('?', rawurldecode($linkParameter));
116  $containsSlash = strpos($rootFileDat, '/') !== false;
117  $pathInfo = pathinfo($rootFileDat);
118  $fileExtension = strtolower($pathInfo['extension'] ?? '');
119  if (!$containsSlash
120  && trim($rootFileDat)
121  && (
122  @is_file(‪Environment::getPublicPath() . '/' . $rootFileDat)
123  || $fileExtension === 'php'
124  || $fileExtension === 'html'
125  || $fileExtension === 'htm'
126  )
127  ) {
128  $isLocalFile = 1;
129  } elseif ($containsSlash) {
130  // Adding this so realurl directories are linked right (non-existing).
131  $isLocalFile = 2;
132  }
133  }
134 
135  // url (external): If doubleSlash or if a '.' comes before a '/'.
136  if (!$isIdOrAlias && $isLocalFile !== 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar)) {
137  $result['type'] = ‪LinkService::TYPE_URL;
138  $result['url'] = 'http://' . $linkParameter;
139  // file (internal) or folder
140  } elseif ($containsSlash || $isLocalFile) {
141  $result = $this->‪getFileOrFolderObjectFromMixedIdentifier($linkParameter);
142  } else {
143  // Integer or alias (alias is without slashes or periods or commas, that is
144  // 'nospace,alphanum_x,lower,unique' according to definition in $GLOBALS['TCA']!)
145  $result = $this->‪resolvePageRelatedParameters($linkParameter);
146  }
147  }
148 
149  return $result;
150  }
151 
159  protected function ‪resolvePageRelatedParameters(string $data): array
160  {
161  $result = ['type' => ‪LinkService::TYPE_PAGE];
162  if (strpos($data, '#') !== false) {
163  [$data, $result['fragment']] = explode('#', $data, 2);
164  }
165  // check for additional parameters
166  if (strpos($data, '?') !== false) {
167  [$data, $result['parameters']] = explode('?', $data, 2);
168  } elseif (strpos($data, '&') !== false) {
169  [$data, $result['parameters']] = explode('&', $data, 2);
170  }
171  if (empty($data)) {
172  $result['pageuid'] = 'current';
173  } elseif ($data[0] === '#') {
174  $result['pageuid'] = 'current';
175  $result['fragment'] = substr($data, 1);
176  } elseif (strpos($data, ',') !== false) {
177  $data = rtrim($data, ',');
178  [$result['pageuid'], $result['pagetype']] = explode(',', $data, 2);
179  } elseif (strpos($data, '/') !== false) {
180  $data = explode('/', trim($data, '/'));
181  $result['pageuid'] = array_shift($data);
182  foreach ($data as $k => $item) {
183  if ($data[$k] % 2 === 0 && !empty($data[$k + 1])) {
184  $result['page' . $data[$k]] = $data[$k + 1];
185  }
186  }
187  } else {
188  $result['pageuid'] = $data;
189  }
190  return $result;
191  }
192 
200  protected function ‪getFileOrFolderObjectFromMixedIdentifier(string $mixedIdentifier): array
201  {
202  $result = [];
203  try {
204  $fileIdentifier = $mixedIdentifier;
205  $fragment = null;
206  if (strpos($fileIdentifier, '#') !== false) {
207  [$fileIdentifier, $fragment] = explode('#', $fileIdentifier, 2);
208  }
209  $fileOrFolderObject = $this->‪getResourceFactory()->‪retrieveFileOrFolderObject($fileIdentifier);
210  // Link to a folder or file
211  if ($fileOrFolderObject instanceof ‪File) {
212  $result['type'] = ‪LinkService::TYPE_FILE;
213  $result['file'] = $fileOrFolderObject;
214  if ($fragment) {
215  $result['fragment'] = $fragment;
216  }
217  } elseif ($fileOrFolderObject instanceof ‪Folder) {
218  $result['type'] = ‪LinkService::TYPE_FOLDER;
219  $result['folder'] = $fileOrFolderObject;
220  if ($fragment) {
221  $result['fragment'] = $fragment;
222  }
223  } else {
224  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
225  $result['file'] = $mixedIdentifier;
226  }
227  } catch (\RuntimeException $e) {
228  // Element wasn't found
229  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
230  $result['file'] = $mixedIdentifier;
231  } catch (‪ResourceDoesNotExistException $e) {
232  // Resource was not found
233  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
234  $result['file'] = $mixedIdentifier;
235  }
236 
237  return $result;
238  }
239 
245  protected function ‪getResourceFactory(): ‪ResourceFactory
246  {
247  if (!$this->resourceFactory) {
248  $this->resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
249  }
251  }
252 }
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:180
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
Definition: ResourceDoesNotExistException.php:24
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:482