‪TYPO3CMS  11.5
LinkAnalyzerResult.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 
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 
38 {
42  protected ‪$linkAnalyzer;
43 
47  protected ‪$brokenLinkRepository;
48 
52  protected ‪$pagesRepository;
53 
57  protected ‪$connectionPool;
58 
62  protected ‪$brokenLinks = [];
63 
67  protected ‪$newBrokenLinkCounts = [];
68 
72  protected ‪$oldBrokenLinkCounts = [];
73 
77  protected ‪$differentToLastResult = false;
78 
84  protected $localizedPages = [];
85 
86  public function __construct(
91  ) {
96  }
97 
111  public function ‪getResultForTask(
112  int $page,
113  int $depth,
114  array $pageRow,
115  array $modTSconfig,
116  array $searchFields = [],
117  array $linkTypes = [],
118  string $languages = ''
119  ): self {
120  $rootLineHidden = $this->‪pagesRepository->doesRootLineContainHiddenPages($pageRow);
121  $checkHidden = $modTSconfig['checkhidden'] === 1;
122 
123  if ($rootLineHidden && !$checkHidden) {
124  return $this;
125  }
126 
127  $pageIds = $this->‪pagesRepository->getAllSubpagesForPage(
128  $page,
129  $depth,
130  '',
131  $checkHidden
132  );
133 
134  if ($pageRow['hidden'] === 0 || $checkHidden) {
135  $pageIds[] = $page;
136  }
137 
138  if (empty($pageIds)) {
139  return $this;
140  }
141 
142  $languageIds = ‪GeneralUtility::intExplode(',', $languages, true);
143  $pageTranslations = $this->‪pagesRepository->getTranslationForPage(
144  $page,
145  '',
146  $checkHidden,
147  $languageIds
148  );
149 
150  $pageIds = array_merge($pageIds, $pageTranslations);
151 
152  $this->‪linkAnalyzer->init($searchFields, $pageIds, $modTSconfig);
153  $this->oldBrokenLinkCounts = $this->‪linkAnalyzer->getLinkCounts();
154 
155  $this->‪linkAnalyzer->getLinkStatistics($linkTypes, $checkHidden);
156  $this->newBrokenLinkCounts = $this->‪linkAnalyzer->getLinkCounts();
157 
158  $this->brokenLinks = $this->‪brokenLinkRepository->getAllBrokenLinksForPages(
159  $pageIds,
160  $linkTypes,
161  $searchFields,
162  $languageIds
163  );
164 
165  $this
166  ->processLinkCounts($linkTypes)
167  ->processBrokenLinks();
168 
169  return $this;
170  }
171 
172  public function ‪setBrokenLinks(array ‪$brokenLinks): void
173  {
174  $this->brokenLinks = ‪$brokenLinks;
175  }
176 
177  public function ‪getBrokenLinks(): array
178  {
179  return ‪$this->brokenLinks;
180  }
181 
182  public function ‪setNewBrokenLinkCounts(array ‪$newBrokenLinkCounts): void
183  {
184  $this->newBrokenLinkCounts = ‪$newBrokenLinkCounts;
185  }
186 
187  public function ‪getNewBrokenLinkCounts(): array
188  {
190  }
191 
192  public function ‪setOldBrokenLinkCounts(array ‪$oldBrokenLinkCounts): void
193  {
194  $this->oldBrokenLinkCounts = ‪$oldBrokenLinkCounts;
195  }
196 
197  public function ‪getOldBrokenLinkCounts(): array
198  {
200  }
201 
202  public function ‪getTotalBrokenLinksCount(): int
203  {
204  return $this->newBrokenLinkCounts['total'] ?? 0;
205  }
206 
207  public function ‪isDifferentToLastResult(): bool
208  {
210  }
211 
218  protected function ‪processLinkCounts(array $linkTypes): self
219  {
220  foreach ($linkTypes as $linkType) {
221  if (!isset($this->newBrokenLinkCounts[$linkType])) {
222  $this->newBrokenLinkCounts[$linkType] = 0;
223  }
224  if (!isset($this->oldBrokenLinkCounts[$linkType])) {
225  $this->oldBrokenLinkCounts[$linkType] = 0;
226  }
227  if ($this->newBrokenLinkCounts[$linkType] !== $this->oldBrokenLinkCounts[$linkType]) {
228  $this->differentToLastResult = true;
229  }
230  }
231 
232  return $this;
233  }
234 
242  protected function ‪processBrokenLinks(): self
243  {
244  foreach ($this->brokenLinks as $key => &$brokenLink) {
245  $fullRecord = BackendUtility::getRecord($brokenLink['table_name'], $brokenLink['record_uid']);
246 
247  if ($fullRecord !== null) {
248  $brokenLink['full_record'] = $fullRecord;
249  $brokenLink['record_title'] = BackendUtility::getRecordTitle($brokenLink['table_name'], $fullRecord);
250  }
251 
252  $brokenLink['real_pid'] = ((int)($brokenLink['language'] ?? 0) > 0 && (string)($brokenLink['table_name'] ?? '') !== 'pages')
253  ? $this->‪getLocalizedPageId((int)$brokenLink['record_pid'], (int)$brokenLink['language'])
254  : $brokenLink['record_pid'];
255  $pageRecord = BackendUtility::getRecord('pages', $brokenLink['real_pid']);
256 
257  try {
258  $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId((int)$brokenLink['real_pid']);
259  $languageCode = $site->getLanguageById((int)$brokenLink['language'])->getTwoLetterIsoCode() ?: 'default';
260  } catch (‪SiteNotFoundException | \InvalidArgumentException $e) {
261  $languageCode = 'default';
262  }
263  if ($pageRecord !== null) {
264  $brokenLink['page_record'] = $pageRecord;
265  }
266 
267  $brokenLink['record_type'] = $this->‪getLanguageService()->‪sL(‪$GLOBALS['TCA'][$brokenLink['table_name']]['ctrl']['title'] ?? '');
268  $brokenLink['target'] = (((string)($brokenLink['link_type'] ?? '') === 'db') ? 'id:' : '') . $brokenLink['url'];
269  $brokenLink['language_code'] = $languageCode;
270  }
271 
272  return $this;
273  }
274 
282  protected function ‪getLocalizedPageId(int $parentId, int $languageId): int
283  {
284  $identifier = $parentId . '-' . $languageId;
285 
286  if ((bool)($this->localizedPages[$identifier] ?? false)) {
287  return $this->localizedPages[$identifier];
288  }
289 
290  $queryBuilder = $this->‪connectionPool->getQueryBuilderForTable('pages');
291  $queryBuilder
292  ->getRestrictions()
293  ->removeAll()
294  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
295 
296  $localizedPageId = (int)$queryBuilder
297  ->select('uid')
298  ->from('pages')
299  ->where(
300  $queryBuilder->expr()->eq(
301  ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
302  $queryBuilder->createNamedParameter($parentId, ‪Connection::PARAM_INT)
303  ),
304  $queryBuilder->expr()->eq(
305  ‪$GLOBALS['TCA']['pages']['ctrl']['languageField'],
306  $queryBuilder->createNamedParameter($languageId, ‪Connection::PARAM_INT)
307  )
308  )
309  ->setMaxResults(1)
310  ->executeQuery()
311  ->fetchOne();
312 
313  if ($localizedPageId) {
314  $this->localizedPages[$identifier] = $localizedPageId;
315  return $localizedPageId;
316  }
317 
318  return $parentId;
319  }
320 
324  protected function ‪getLanguageService(): ‪LanguageService
325  {
326  return ‪$GLOBALS['LANG'];
327  }
328 }
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Linkvalidator\Repository\PagesRepository
Definition: PagesRepository.php:33
‪TYPO3\CMS\Core\Exception\SiteNotFoundException
Definition: SiteNotFoundException.php:25
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:161
‪TYPO3\CMS\Linkvalidator\Result
Definition: LinkAnalyzerResult.php:18
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static int[] intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:927
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50