‪TYPO3CMS  10.4
InternalLinktype.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
20 
25 {
29  const ‪DELETED = 'deleted';
30 
34  const ‪HIDDEN = 'hidden';
35 
39  const ‪MOVED = 'moved';
40 
44  const ‪NOTEXISTING = 'notExisting';
45 
51  protected ‪$responsePage = true;
52 
58  protected ‪$responseContent = true;
59 
68  public function ‪checkLink($url, $softRefEntry, $reference)
69  {
70  $page = null;
71  $anchor = '';
72  $this->responseContent = true;
73  // Might already contain values - empty it
74  unset($this->errorParams);
75  // Only check pages records. Content elements will also be checked
76  // as we extract the anchor in the next step.
77  [$table] = explode(':', $softRefEntry['substr']['recordRef']);
78  if (!in_array($table, ['pages', 'tt_content'], true)) {
79  return true;
80  }
81  // Defines the linked page and anchor (if any).
82  if (strpos($url, '#c') !== false) {
83  $parts = explode('#c', $url);
84  $page = $parts[0];
85  $anchor = $parts[1];
86  } elseif (
87  $table === 'tt_content'
88  && strpos($softRefEntry['row'][$softRefEntry['field']], 't3://') === 0
89  ) {
90  $parsedTypoLinkUrl = @parse_url($softRefEntry['row'][$softRefEntry['field']]);
91  if ($parsedTypoLinkUrl['host'] === 'page') {
92  parse_str($parsedTypoLinkUrl['query'], $query);
93  if (isset($query['uid'])) {
94  $page = (int)$query['uid'];
95  $anchor = (int)$url;
96  }
97  }
98  } else {
99  $page = $url;
100  }
101  // Check if the linked page is OK
102  $this->responsePage = $this->‪checkPage((int)$page);
103  // Check if the linked content element is OK
104  if ($anchor) {
105  // Check if the content element is OK
106  $this->responseContent = $this->‪checkContent((int)$page, (int)$anchor);
107  }
108  if (
109  (is_array($this->errorParams['page']) && !$this->responsePage)
110  || (is_array($this->errorParams['content']) && !$this->responseContent)
111  ) {
112  $this->‪setErrorParams($this->errorParams);
113  }
114 
115  return $this->responsePage && ‪$this->responseContent;
116  }
117 
124  protected function ‪checkPage($page)
125  {
126  // Get page ID on which the content element in fact is located
127  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
128  $queryBuilder->getRestrictions()->removeAll();
129  $row = $queryBuilder
130  ->select('uid', 'title', 'deleted', 'hidden', 'starttime', 'endtime')
131  ->from('pages')
132  ->where(
133  $queryBuilder->expr()->eq(
134  'uid',
135  $queryBuilder->createNamedParameter($page, \PDO::PARAM_INT)
136  )
137  )
138  ->execute()
139  ->fetch();
140  $this->responsePage = true;
141  if ($row) {
142  if ($row['deleted'] == '1') {
143  $this->errorParams['errorType']['page'] = ‪self::DELETED;
144  $this->errorParams['page']['title'] = $row['title'];
145  $this->errorParams['page']['uid'] = $row['uid'];
146  $this->responsePage = false;
147  } elseif ($row['hidden'] == '1'
148  || ‪$GLOBALS['EXEC_TIME'] < (int)$row['starttime']
149  || $row['endtime'] && (int)$row['endtime'] < ‪$GLOBALS['EXEC_TIME']
150  ) {
151  $this->errorParams['errorType']['page'] = ‪self::HIDDEN;
152  $this->errorParams['page']['title'] = $row['title'];
153  $this->errorParams['page']['uid'] = $row['uid'];
154  $this->responsePage = false;
155  }
156  } else {
157  $this->errorParams['errorType']['page'] = ‪self::NOTEXISTING;
158  $this->errorParams['page']['uid'] = (int)$page;
159  $this->responsePage = false;
160  }
161  return ‪$this->responsePage;
162  }
163 
171  protected function ‪checkContent($page, $anchor)
172  {
173  // Get page ID on which the content element in fact is located
174  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
175  $queryBuilder->getRestrictions()->removeAll();
176  $row = $queryBuilder
177  ->select('uid', 'pid', 'header', 'deleted', 'hidden', 'starttime', 'endtime')
178  ->from('tt_content')
179  ->where(
180  $queryBuilder->expr()->eq(
181  'uid',
182  $queryBuilder->createNamedParameter($anchor, \PDO::PARAM_INT)
183  )
184  )
185  ->execute()
186  ->fetch();
187  $this->responseContent = true;
188  // this content element exists
189  if ($row) {
190  $page = (int)$page;
191  // page ID on which this CE is in fact located.
192  $correctPageID = (int)$row['pid'];
193  // Check if the element is on the linked page
194  // (The element might have been moved to another page)
195  if ($correctPageID !== $page) {
196  $this->errorParams['errorType']['content'] = ‪self::MOVED;
197  $this->errorParams['content']['uid'] = (int)$anchor;
198  $this->errorParams['content']['wrongPage'] = $page;
199  $this->errorParams['content']['rightPage'] = $correctPageID;
200  $this->responseContent = false;
201  } else {
202  // The element is located on the page to which the link is pointing
203  if ($row['deleted'] == '1') {
204  $this->errorParams['errorType']['content'] = ‪self::DELETED;
205  $this->errorParams['content']['title'] = $row['header'];
206  $this->errorParams['content']['uid'] = $row['uid'];
207  $this->responseContent = false;
208  } elseif ($row['hidden'] == '1' || ‪$GLOBALS['EXEC_TIME'] < (int)$row['starttime'] || $row['endtime'] && (int)$row['endtime'] < ‪$GLOBALS['EXEC_TIME']) {
209  $this->errorParams['errorType']['content'] = ‪self::HIDDEN;
210  $this->errorParams['content']['title'] = $row['header'];
211  $this->errorParams['content']['uid'] = $row['uid'];
212  $this->responseContent = false;
213  }
214  }
215  } else {
216  // The content element does not exist
217  $this->errorParams['errorType']['content'] = ‪self::NOTEXISTING;
218  $this->errorParams['content']['uid'] = (int)$anchor;
219  $this->responseContent = false;
220  }
222  }
223 
230  public function ‪getErrorMessage(‪$errorParams)
231  {
232  $errorPage = null;
233  $errorContent = null;
234  $lang = $this->‪getLanguageService();
235  $errorType = ‪$errorParams['errorType'];
236  if (is_array(‪$errorParams['page'])) {
237  switch ($errorType['page']) {
238  case ‪self::DELETED:
239  $errorPage = str_replace(
240  [
241  '###title###',
242  '###uid###'
243  ],
244  [
245  ‪$errorParams['page']['title'],
246  ‪$errorParams['page']['uid']
247  ],
248  $lang->getLL('list.report.pagedeleted')
249  );
250  break;
251  case ‪self::HIDDEN:
252  $errorPage = str_replace(
253  [
254  '###title###',
255  '###uid###'
256  ],
257  [
258  ‪$errorParams['page']['title'],
259  ‪$errorParams['page']['uid']
260  ],
261  $lang->getLL('list.report.pagenotvisible')
262  );
263  break;
264  default:
265  $errorPage = str_replace(
266  '###uid###',
267  ‪$errorParams['page']['uid'],
268  $lang->getLL('list.report.pagenotexisting')
269  );
270  }
271  }
272  if (is_array(‪$errorParams['content'])) {
273  switch ($errorType['content']) {
274  case ‪self::DELETED:
275  $errorContent = str_replace(
276  [
277  '###title###',
278  '###uid###'
279  ],
280  [
281  ‪$errorParams['content']['title'],
282  ‪$errorParams['content']['uid']
283  ],
284  $lang->getLL('list.report.contentdeleted')
285  );
286  break;
287  case ‪self::HIDDEN:
288  $errorContent = str_replace(
289  [
290  '###title###',
291  '###uid###'
292  ],
293  [
294  ‪$errorParams['content']['title'],
295  ‪$errorParams['content']['uid']
296  ],
297  $lang->getLL('list.report.contentnotvisible')
298  );
299  break;
300  case ‪self::MOVED:
301  $errorContent = str_replace(
302  [
303  '###title###',
304  '###uid###',
305  '###wrongpage###',
306  '###rightpage###'
307  ],
308  [
309  ‪$errorParams['content']['title'],
310  ‪$errorParams['content']['uid'],
311  ‪$errorParams['content']['wrongPage'],
312  ‪$errorParams['content']['rightPage']
313  ],
314  $lang->getLL('list.report.contentmoved')
315  );
316  break;
317  default:
318  $errorContent = str_replace('###uid###', ‪$errorParams['content']['uid'], $lang->getLL('list.report.contentnotexisting'));
319  }
320  }
321  if (isset($errorPage) && isset($errorContent)) {
322  $response = $errorPage . LF . $errorContent;
323  } elseif (isset($errorPage)) {
324  $response = $errorPage;
325  } elseif (isset($errorContent)) {
326  $response = $errorContent;
327  } else {
328  // This should not happen
329  $response = $lang->getLL('list.report.noinformation');
330  }
331  return $response;
332  }
333 
340  public function ‪getBrokenUrl($row)
341  {
342  $domain = rtrim(GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), '/');
343  return $domain . '/index.php?id=' . $row['url'];
344  }
345 }
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\checkLink
‪bool checkLink($url, $softRefEntry, $reference)
Definition: InternalLinktype.php:66
‪TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype\$errorParams
‪array $errorParams
Definition: AbstractLinktype.php:29
‪TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype\getLanguageService
‪LanguageService getLanguageService()
Definition: AbstractLinktype.php:92
‪TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype
Definition: AbstractLinktype.php:24
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\MOVED
‪const MOVED
Definition: InternalLinktype.php:39
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\$responseContent
‪bool $responseContent
Definition: InternalLinktype.php:56
‪TYPO3\CMS\Linkvalidator\Linktype
Definition: AbstractLinktype.php:16
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype
Definition: InternalLinktype.php:25
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\getBrokenUrl
‪string getBrokenUrl($row)
Definition: InternalLinktype.php:338
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\DELETED
‪const DELETED
Definition: InternalLinktype.php:29
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\checkPage
‪bool checkPage($page)
Definition: InternalLinktype.php:122
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\HIDDEN
‪const HIDDEN
Definition: InternalLinktype.php:34
‪TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype\setErrorParams
‪setErrorParams($value)
Definition: AbstractLinktype.php:63
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\checkContent
‪bool checkContent($page, $anchor)
Definition: InternalLinktype.php:169
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\NOTEXISTING
‪const NOTEXISTING
Definition: InternalLinktype.php:44
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\getErrorMessage
‪string getErrorMessage($errorParams)
Definition: InternalLinktype.php:228
‪TYPO3\CMS\Linkvalidator\Linktype\InternalLinktype\$responsePage
‪bool $responsePage
Definition: InternalLinktype.php:50