‪TYPO3CMS  9.5
LegacyLinkNotationConverter.php
Go to the documentation of this file.
1 <?php
2 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 
25 
33 {
34 
38  protected ‪$resourceFactory;
39 
57  public function ‪resolve(string $linkParameter): array
58  {
59  if (stripos(rawurldecode(trim($linkParameter)), 'phar://') === 0) {
60  throw new \RuntimeException(
61  'phar scheme not allowed as soft reference target',
62  1530030673
63  );
64  }
65 
66  $result = [];
67 
68  // Resolve FAL-api "file:UID-of-sys_file-record" and "file:combined-identifier"
69  if (stripos($linkParameter, 'file:') === 0) {
70  $result = $this->‪getFileOrFolderObjectFromMixedIdentifier(substr($linkParameter, 5));
71  } elseif (GeneralUtility::validEmail(parse_url($linkParameter, PHP_URL_PATH))) {
72  $result['type'] = ‪LinkService::TYPE_EMAIL;
73  $result['email'] = $linkParameter;
74  } elseif (strpos($linkParameter, ':') !== false) {
75  // Check for link-handler keyword
76  list($linkHandlerKeyword, $linkHandlerValue) = explode(':', $linkParameter, 2);
77  $result['type'] = strtolower(trim($linkHandlerKeyword));
78  $result['url'] = $linkParameter;
79  $result['value'] = $linkHandlerValue;
80  if ($result['type'] === ‪LinkService::TYPE_RECORD) {
81  list($a['identifier'], $tableAndUid) = explode(':', $linkHandlerValue, 2);
82  $tableAndUid = explode(':', $tableAndUid);
83  if (count($tableAndUid) > 1) {
84  $a['table'] = $tableAndUid[0];
85  $a['uid'] = $tableAndUid[1];
86  } else {
87  // this case can happen if there is the very old linkhandler syntax, which was only record:<table>:<uid>
88  $a['table'] = $a['identifier'];
89  $a['uid'] = $tableAndUid[0];
90  }
91  $result = array_merge($result, $a);
92  }
93  } else {
94  // special handling without a scheme
95  $isLocalFile = 0;
96  $fileChar = (int)strpos($linkParameter, '/');
97  $urlChar = (int)strpos($linkParameter, '.');
98 
99  $isIdOrAlias = ‪MathUtility::canBeInterpretedAsInteger($linkParameter);
100  $matches = [];
101  // capture old RTE links relative to TYPO3_mainDir
102  if (preg_match('#../(?:index\\.php)?\\?id=([^&]+)#', $linkParameter, $matches)) {
103  $linkParameter = $matches[1];
104  $isIdOrAlias = true;
105  }
106  $containsSlash = false;
107  if (!$isIdOrAlias) {
108  // Detects if a file is found in site-root and if so it will be treated like a normal file.
109  list($rootFileDat) = explode('?', rawurldecode($linkParameter));
110  $containsSlash = strpos($rootFileDat, '/') !== false;
111  $pathInfo = pathinfo($rootFileDat);
112  $fileExtension = strtolower($pathInfo['extension'] ?? '');
113  if (!$containsSlash
114  && trim($rootFileDat)
115  && (
116  @is_file(‪Environment::getPublicPath() . '/' . $rootFileDat)
117  || $fileExtension === 'php'
118  || $fileExtension === 'html'
119  || $fileExtension === 'htm'
120  )
121  ) {
122  $isLocalFile = 1;
123  } elseif ($containsSlash) {
124  // Adding this so realurl directories are linked right (non-existing).
125  $isLocalFile = 2;
126  }
127  }
128 
129  // url (external): If doubleSlash or if a '.' comes before a '/'.
130  if (!$isIdOrAlias && $isLocalFile !== 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar)) {
131  $result['type'] = ‪LinkService::TYPE_URL;
132  $result['url'] = 'http://' . $linkParameter;
133  // file (internal) or folder
134  } elseif ($containsSlash || $isLocalFile) {
135  $result = $this->‪getFileOrFolderObjectFromMixedIdentifier($linkParameter);
136  } else {
137  // Integer or alias (alias is without slashes or periods or commas, that is
138  // 'nospace,alphanum_x,lower,unique' according to definition in $GLOBALS['TCA']!)
139  $result = $this->‪resolvePageRelatedParameters($linkParameter);
140  }
141  }
142 
143  return $result;
144  }
145 
153  protected function ‪resolvePageRelatedParameters(string $data): array
154  {
155  $result = ['type' => ‪LinkService::TYPE_PAGE];
156  if (strpos($data, '#') !== false) {
157  list($data, $result['fragment']) = explode('#', $data, 2);
158  }
159  // check for additional parameters
160  if (strpos($data, '?') !== false) {
161  list($data, $result['parameters']) = explode('?', $data, 2);
162  } elseif (strpos($data, '&') !== false) {
163  list($data, $result['parameters']) = explode('&', $data, 2);
164  }
165  if (empty($data)) {
166  $result['pageuid'] = 'current';
167  } elseif ($data[0] === '#') {
168  $result['pageuid'] = 'current';
169  $result['fragment'] = substr($data, 1);
170  } elseif (strpos($data, ',') !== false) {
171  $data = rtrim($data, ',');
172  list($result['pageuid'], $result['pagetype']) = explode(',', $data, 2);
173  } elseif (strpos($data, '/') !== false) {
174  $data = explode('/', trim($data, '/'));
175  $result['pageuid'] = array_shift($data);
176  foreach ($data as $k => $item) {
177  if ($data[$k] % 2 === 0 && !empty($data[$k + 1])) {
178  $result['page' . $data[$k]] = $data[$k + 1];
179  }
180  }
181  } else {
182  $result['pageuid'] = $data;
183  }
184 
185  // expect an alias
186  if (!‪MathUtility::canBeInterpretedAsInteger($result['pageuid']) && $result['pageuid'] !== 'current') {
187  $result['pagealias'] = $result['pageuid'];
188  unset($result['pageuid']);
189  }
190 
191  return $result;
192  }
193 
201  protected function ‪getFileOrFolderObjectFromMixedIdentifier(string $mixedIdentifier): array
202  {
203  $result = [];
204  try {
205  $fileIdentifier = $mixedIdentifier;
206  $fragment = null;
207  if (strpos($fileIdentifier, '#') !== false) {
208  [$fileIdentifier, $fragment] = explode('#', $fileIdentifier, 2);
209  }
210  $fileOrFolderObject = $this->‪getResourceFactory()->‪retrieveFileOrFolderObject($fileIdentifier);
211  // Link to a folder or file
212  if ($fileOrFolderObject instanceof ‪File) {
213  $result['type'] = ‪LinkService::TYPE_FILE;
214  $result['file'] = $fileOrFolderObject;
215  if ($fragment) {
216  $result['fragment'] = $fragment;
217  }
218  } elseif ($fileOrFolderObject instanceof ‪Folder) {
219  $result['type'] = ‪LinkService::TYPE_FOLDER;
220  $result['folder'] = $fileOrFolderObject;
221  if ($fragment) {
222  $result['fragment'] = $fragment;
223  }
224  } else {
225  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
226  $result['file'] = $mixedIdentifier;
227  }
228  } catch (\RuntimeException $e) {
229  // Element wasn't found
230  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
231  $result['file'] = $mixedIdentifier;
232  } catch (‪ResourceDoesNotExistException $e) {
233  // Resource was not found
234  $result['type'] = ‪LinkService::TYPE_UNKNOWN;
235  $result['file'] = $mixedIdentifier;
236  }
237 
238  return $result;
239  }
240 
246  protected function ‪getResourceFactory(): ‪ResourceFactory
247  {
248  if (!$this->resourceFactory) {
249  $this->resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
250  }
252  }
253 }
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:153
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:34
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:33
‪TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
Definition: ResourceDoesNotExistException.php:21
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:23
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:491