‪TYPO3CMS  ‪main
UpgradeController.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 PhpParser\NodeTraverser;
21 use PhpParser\NodeVisitor\NameResolver;
22 use PhpParser\ParserFactory;
23 use PhpParser\PhpVersion;
24 use Psr\Http\Message\ResponseInterface;
25 use Psr\Http\Message\ServerRequestInterface;
26 use Symfony\Component\Finder\Finder;
27 use Symfony\Component\Finder\SplFileInfo;
37 use TYPO3\CMS\Core\Package\PackageManager;
71 use TYPO3\CMS\Install\Service\CoreVersionService;
72 use TYPO3\CMS\Install\Service\DatabaseUpgradeWizardsService;
78 
84 {
88  protected ‪$coreUpdateService;
89 
94 
95  public function ‪__construct(
96  protected readonly PackageManager $packageManager,
97  private readonly ‪LateBootService $lateBootService,
98  private readonly DatabaseUpgradeWizardsService $databaseUpgradeWizardsService,
99  private readonly ‪FormProtectionFactory $formProtectionFactory
100  ) {}
101 
108  protected ‪$matchers = [
109  [
110  'class' => ArrayDimensionMatcher::class,
111  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php',
112  ],
113  [
114  'class' => ArrayGlobalMatcher::class,
115  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ArrayGlobalMatcher.php',
116  ],
117  [
118  'class' => ClassConstantMatcher::class,
119  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ClassConstantMatcher.php',
120  ],
121  [
122  'class' => ClassNameMatcher::class,
123  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php',
124  ],
125  [
126  'class' => ConstantMatcher::class,
127  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ConstantMatcher.php',
128  ],
129  [
130  'class' => ConstructorArgumentMatcher::class,
131  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ConstructorArgumentMatcher.php',
132  ],
133  [
134  'class' => PropertyAnnotationMatcher::class,
135  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/PropertyAnnotationMatcher.php',
136  ],
137  [
138  'class' => MethodAnnotationMatcher::class,
139  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php',
140  ],
141  [
142  'class' => FunctionCallMatcher::class,
143  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/FunctionCallMatcher.php',
144  ],
145  [
146  'class' => InterfaceMethodChangedMatcher::class,
147  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/InterfaceMethodChangedMatcher.php',
148  ],
149  [
150  'class' => MethodArgumentDroppedMatcher::class,
151  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedMatcher.php',
152  ],
153  [
154  'class' => MethodArgumentDroppedStaticMatcher::class,
155  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedStaticMatcher.php',
156  ],
157  [
158  'class' => MethodArgumentRequiredMatcher::class,
159  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodArgumentRequiredMatcher.php',
160  ],
161  [
162  'class' => MethodArgumentRequiredStaticMatcher::class,
163  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodArgumentRequiredStaticMatcher.php',
164  ],
165  [
166  'class' => MethodArgumentUnusedMatcher::class,
167  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodArgumentUnusedMatcher.php',
168  ],
169  [
170  'class' => MethodCallMatcher::class,
171  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php',
172  ],
173  [
174  'class' => MethodCallStaticMatcher::class,
175  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php',
176  ],
177  [
178  'class' => PropertyExistsStaticMatcher::class,
179  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/PropertyExistsStaticMatcher.php',
180  ],
181  [
182  'class' => PropertyProtectedMatcher::class,
183  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/PropertyProtectedMatcher.php',
184  ],
185  [
186  'class' => PropertyPublicMatcher::class,
187  'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php',
188  ],
189  ];
190 
194  public function ‪cardsAction(ServerRequestInterface $request): ResponseInterface
195  {
196  $view = $this->‪initializeView($request);
197  $hasExtensions = false;
198 
199  foreach ($this->packageManager->getAvailablePackages() as $package) {
200  if (!$package->getPackageMetaData()->isExtensionType() || $package->getPackageMetaData()->isFrameworkType()) {
201  continue;
202  }
203 
204  $hasExtensions = true;
205  break;
206  }
207 
208  $view->assign('hasExtensions', $hasExtensions);
209  return new JsonResponse([
210  'success' => true,
211  'html' => $view->render('Upgrade/Cards'),
212  ]);
213  }
214 
218  public function ‪coreUpdateActivateAction(ServerRequestInterface $request): ResponseInterface
219  {
220  $this->‪coreUpdateInitialize();
221  return new JsonResponse([
222  'success' => $this->coreUpdateService->activateVersion($this->coreUpdateGetVersionToHandle($request)),
223  'status' => $this->coreUpdateService->getMessages(),
224  ]);
225  }
226 
230  public function ‪coreUpdateCheckPreConditionsAction(ServerRequestInterface $request): ResponseInterface
231  {
232  $this->‪coreUpdateInitialize();
233  return new JsonResponse([
234  'success' => $this->coreUpdateService->checkPreConditions(
235  $this->coreUpdateGetVersionToHandle($request),
237  ),
238  'status' => $this->coreUpdateService->getMessages(),
239  ]);
240  }
241 
245  public function ‪coreUpdateDownloadAction(ServerRequestInterface $request): ResponseInterface
246  {
247  $this->‪coreUpdateInitialize();
248  return new JsonResponse([
249  'success' => $this->coreUpdateService->downloadVersion($this->coreUpdateGetVersionToHandle($request)),
250  'status' => $this->coreUpdateService->getMessages(),
251  ]);
252  }
253 
257  public function ‪coreUpdateGetDataAction(ServerRequestInterface $request): ResponseInterface
258  {
259  $view = $this->‪initializeView($request);
260  ‪$coreUpdateService = GeneralUtility::makeInstance(CoreUpdateService::class);
261  ‪$coreVersionService = GeneralUtility::makeInstance(CoreVersionService::class);
262 
263  $coreUpdateEnabled = ‪$coreUpdateService->‪isCoreUpdateEnabled();
264  $coreUpdateComposerMode = ‪Environment::isComposerMode();
265  $coreUpdateIsReleasedVersion = ‪$coreVersionService->isInstalledVersionAReleasedVersion();
266  $coreUpdateIsSymLinkedCore = is_link(‪Environment::getPublicPath() . '/typo3_src');
267  $isUpdatable = !$coreUpdateComposerMode && $coreUpdateEnabled && $coreUpdateIsReleasedVersion && $coreUpdateIsSymLinkedCore;
268 
269  $view->assignMultiple([
270  'coreIsUpdatable' => $isUpdatable,
271  'coreUpdateEnabled' => $coreUpdateEnabled,
272  'coreUpdateComposerMode' => $coreUpdateComposerMode,
273  'coreUpdateIsReleasedVersion' => $coreUpdateIsReleasedVersion,
274  'coreUpdateIsSymLinkedCore' => $coreUpdateIsSymLinkedCore,
275  ]);
276 
277  $buttons = [];
278  if ($isUpdatable) {
279  $buttons[] = [
280  'btnClass' => 'btn-warning t3js-coreUpdate-button t3js-coreUpdate-init',
281  'name' => 'coreUpdateCheckForUpdate',
282  'text' => 'Check for core updates',
283  ];
284  }
285 
286  return new JsonResponse([
287  'success' => true,
288  'html' => $view->render('Upgrade/CoreUpdate'),
289  'buttons' => $buttons,
290  ]);
291  }
292 
296  public function ‪coreUpdateIsUpdateAvailableAction(): ResponseInterface
297  {
298  $action = null;
299  $this->‪coreUpdateInitialize();
300  $messageQueue = new FlashMessageQueue('install');
301 
302  $messages = [];
303 
304  if ($this->coreVersionService->isInstalledVersionAReleasedVersion()) {
305  $versionMaintenanceWindow = $this->coreVersionService->getMaintenanceWindow();
306  $renderVersionInformation = false;
307 
308  if (!$versionMaintenanceWindow->isSupportedByCommunity() && !$versionMaintenanceWindow->isSupportedByElts()) {
309  $messages[] = [
310  'title' => 'Outdated version',
311  'message' => 'The currently installed TYPO3 version ' . $this->coreVersionService->getInstalledVersion() . ' does not receive any further updates, please consider upgrading to a supported version!',
312  'severity' => ContextualFeedbackSeverity::ERROR,
313  ];
314  $renderVersionInformation = true;
315  } else {
316  $currentVersion = $this->coreVersionService->getInstalledVersion();
317  $isCurrentVersionElts = $this->coreVersionService->isCurrentInstalledVersionElts();
318  $latestRelease = $this->coreVersionService->getYoungestPatchRelease();
319 
320  $availableReleases = [];
321  if ($this->coreVersionService->isPatchReleaseSuitableForUpdate($latestRelease)) {
322  $availableReleases[] = $latestRelease;
323 
324  if (!$latestRelease->isElts()) {
325  $action = ['title' => 'Update now to version ' . $latestRelease->getVersion(), 'action' => 'updateRegular'];
326  }
327  }
328  if (!$versionMaintenanceWindow->isSupportedByCommunity()) {
329  if ($latestRelease->isElts()) {
330  // Check if there's a public release left that's not installed yet
331  $latestCommunityDrivenRelease = $this->coreVersionService->getYoungestCommunityPatchRelease();
332  if ($this->coreVersionService->isPatchReleaseSuitableForUpdate($latestCommunityDrivenRelease)) {
333  $availableReleases[] = $latestCommunityDrivenRelease;
334  $action = ['title' => 'Update now to version ' . $latestCommunityDrivenRelease->getVersion(), 'action' => 'updateRegular'];
335  }
336  } elseif (!$isCurrentVersionElts) {
337  // Inform user about ELTS being available soon if:
338  // - regular support ran out
339  // - the current installed version is no ELTS
340  // - no ELTS update was released, yet
341  $messages[] = [
342  'title' => 'ELTS will be available soon',
343  'message' => sprintf('The currently installed TYPO3 version %s doesn\'t receive any community-driven updates anymore, consider subscribing to Extended Long Term Support (ELTS) releases. Please read the information below.', $currentVersion),
344  'severity' => ContextualFeedbackSeverity::WARNING,
345  ];
346  $renderVersionInformation = true;
347  }
348  }
349 
350  if ($availableReleases === []) {
351  $messages[] = [
352  'title' => 'Up to date',
353  'message' => 'There are no TYPO3 updates available.',
354  'severity' => ContextualFeedbackSeverity::NOTICE,
355  ];
356  } else {
357  foreach ($availableReleases as $availableRelease) {
358  $isUpdateSecurityRelevant = $this->coreVersionService->isUpdateSecurityRelevant($availableRelease);
359  $versionString = $availableRelease->getVersion();
360  if ($availableRelease->isElts()) {
361  $versionString .= ' ELTS';
362  }
363 
364  if ($isUpdateSecurityRelevant) {
365  $title = ($availableRelease->isElts() ? 'ELTS ' : '') . 'Security update available!';
366  $message = sprintf('The currently installed version is %s, update to security relevant released version %s is available.', $currentVersion, $versionString);
367  $severity = ContextualFeedbackSeverity::ERROR;
368  } else {
369  $title = ($availableRelease->isElts() ? 'ELTS ' : '') . 'Update available!';
370  $message = sprintf('Currently installed version is %s, update to regular released version %s is available.', $currentVersion, $versionString);
371  $severity = ContextualFeedbackSeverity::WARNING;
372  }
373 
374  if ($availableRelease->isElts()) {
375  if ($isCurrentVersionElts) {
376  $message .= ' Please visit my.typo3.org to download the release in your ELTS area.';
377  } else {
378  $message .= ' ' . sprintf('The currently installed TYPO3 version %s doesn\'t receive any community-driven updates anymore, consider subscribing to Extended Long Term Support (ELTS) releases. Please read the information below.', $currentVersion);
379  }
380 
381  $renderVersionInformation = true;
382  }
383 
384  $messages[] = [
385  'title' => $title,
386  'message' => $message,
387  'severity' => $severity,
388  ];
389  }
390  }
391  }
392 
393  if ($renderVersionInformation) {
394  $supportedMajorReleases = $this->coreVersionService->getSupportedMajorReleases();
395  $supportMessages = [];
396  if (!empty($supportedMajorReleases['community'])) {
397  $supportMessages[] = sprintf('Currently community-supported TYPO3 versions: %s (more information at https://get.typo3.org).', implode(', ', $supportedMajorReleases['community']));
398  }
399  if (!empty($supportedMajorReleases['elts'])) {
400  $supportMessages[] = sprintf('Currently supported TYPO3 ELTS versions: %s (more information at https://typo3.com/elts).', implode(', ', $supportedMajorReleases['elts']));
401  }
402 
403  $messages[] = [
404  'title' => 'TYPO3 Version information',
405  'message' => implode(' ', $supportMessages),
406  'severity' => ContextualFeedbackSeverity::INFO,
407  ];
408  }
409 
410  foreach ($messages as $message) {
411  $messageQueue->enqueue(new FlashMessage($message['message'], $message['title'], $message['severity']));
412  }
413  } else {
414  $messageQueue->enqueue(new FlashMessage(
415  '',
416  'Current version is a development version and can not be updated',
417  ContextualFeedbackSeverity::WARNING
418  ));
419  }
420  $responseData = [
421  'success' => true,
422  'status' => $messageQueue,
423  ];
424  if (isset($action)) {
425  $responseData['action'] = $action;
426  }
427  return new JsonResponse($responseData);
428  }
429 
433  public function ‪coreUpdateMoveAction(ServerRequestInterface $request): ResponseInterface
434  {
435  $this->‪coreUpdateInitialize();
436  return new JsonResponse([
437  'success' => $this->coreUpdateService->moveVersion($this->coreUpdateGetVersionToHandle($request)),
438  'status' => $this->coreUpdateService->getMessages(),
439  ]);
440  }
441 
445  public function ‪coreUpdateUnpackAction(ServerRequestInterface $request): ResponseInterface
446  {
447  $this->‪coreUpdateInitialize();
448  return new JsonResponse([
449  'success' => $this->coreUpdateService->unpackVersion($this->coreUpdateGetVersionToHandle($request)),
450  'status' => $this->coreUpdateService->getMessages(),
451  ]);
452  }
453 
457  public function ‪coreUpdateVerifyChecksumAction(ServerRequestInterface $request): ResponseInterface
458  {
459  $this->‪coreUpdateInitialize();
460  return new JsonResponse([
461  'success' => $this->coreUpdateService->verifyFileChecksum($this->coreUpdateGetVersionToHandle($request)),
462  'status' => $this->coreUpdateService->getMessages(),
463  ]);
464  }
465 
469  public function ‪extensionCompatTesterLoadedExtensionListAction(ServerRequestInterface $request): ResponseInterface
470  {
471  $formProtection = $this->formProtectionFactory->createFromRequest($request);
472  $view = $this->‪initializeView($request);
473  $view->assignMultiple([
474  'extensionCompatTesterLoadExtLocalconfToken' => $formProtection->generateToken('installTool', 'extensionCompatTesterLoadExtLocalconf'),
475  'extensionCompatTesterLoadExtTablesToken' => $formProtection->generateToken('installTool', 'extensionCompatTesterLoadExtTables'),
476  'extensionCompatTesterUninstallToken' => $formProtection->generateToken('installTool', 'extensionCompatTesterUninstallExtension'),
477  ]);
478 
479  return new JsonResponse([
480  'success' => true,
481  'html' => $view->render('Upgrade/ExtensionCompatTester'),
482  'buttons' => [
483  [
484  'btnClass' => 'btn-default disabled t3js-extensionCompatTester-check',
485  'text' => 'Check extensions',
486  ],
487  ],
488  ]);
489  }
490 
494  public function ‪extensionCompatTesterLoadExtLocalconfAction(ServerRequestInterface $request): ResponseInterface
495  {
496  $brokenExtensions = [];
497  $container = $this->lateBootService->getContainer();
498  $backup = $this->lateBootService->makeCurrent($container);
499 
500  foreach ($this->packageManager->getActivePackages() as $package) {
501  try {
503  } catch (\Throwable $e) {
504  $brokenExtensions[] = [
505  'name' => $package->getPackageKey(),
506  'isProtected' => $package->isProtected(),
507  ];
508  }
509  }
510 
511  $this->lateBootService->makeCurrent(null, $backup);
512 
513  return new JsonResponse([
514  'brokenExtensions' => $brokenExtensions,
515  ], empty($brokenExtensions) ? 200 : 500);
516  }
517 
521  public function ‪extensionCompatTesterLoadExtTablesAction(ServerRequestInterface $request): ResponseInterface
522  {
523  $brokenExtensions = [];
524  $container = $this->lateBootService->getContainer();
525  $backup = $this->lateBootService->makeCurrent($container);
526 
527  $activePackages = $this->packageManager->getActivePackages();
528  foreach ($activePackages as $package) {
529  // Load all ext_localconf files first
531  }
532  foreach ($activePackages as $package) {
533  try {
535  } catch (\Throwable $e) {
536  $brokenExtensions[] = [
537  'name' => $package->getPackageKey(),
538  'isProtected' => $package->isProtected(),
539  ];
540  }
541  }
542 
543  $this->lateBootService->makeCurrent(null, $backup);
544 
545  return new JsonResponse([
546  'brokenExtensions' => $brokenExtensions,
547  ], empty($brokenExtensions) ? 200 : 500);
548  }
549 
555  public function ‪extensionCompatTesterUninstallExtensionAction(ServerRequestInterface $request): ResponseInterface
556  {
557  $extension = $request->getParsedBody()['install']['extension'];
558  if (empty($extension)) {
559  throw new \RuntimeException(
560  'No extension given',
561  1505407269
562  );
563  }
564  $messageQueue = new FlashMessageQueue('install');
565  if (‪ExtensionManagementUtility::isLoaded($extension)) {
566  try {
568  GeneralUtility::makeInstance(ClearCacheService::class)->clearAll();
569  GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive();
570 
571  $messageQueue->enqueue(new FlashMessage(
572  'Extension "' . $extension . '" unloaded.',
573  '',
574  ContextualFeedbackSeverity::ERROR
575  ));
576  } catch (\Exception $e) {
577  $messageQueue->enqueue(new FlashMessage(
578  $e->getMessage(),
579  '',
580  ContextualFeedbackSeverity::ERROR
581  ));
582  }
583  }
584  return new JsonResponse([
585  'success' => true,
586  'status' => $messageQueue,
587  ]);
588  }
589 
593  public function ‪extensionScannerGetDataAction(ServerRequestInterface $request): ResponseInterface
594  {
595  $extensions = [];
596  foreach ($this->packageManager->getAvailablePackages() as $package) {
597  if (!$package->getPackageMetaData()->isExtensionType() || $package->getPackageMetaData()->isFrameworkType()) {
598  continue;
599  }
600 
601  $extensions[] = $package->getPackageKey();
602  }
603  sort($extensions);
604  $view = $this->‪initializeView($request);
605  $formProtection = $this->formProtectionFactory->createFromRequest($request);
606  $view->assignMultiple([
607  'extensionScannerExtensionList' => $extensions,
608  'extensionScannerFilesToken' => $formProtection->generateToken('installTool', 'extensionScannerFiles'),
609  'extensionScannerScanFileToken' => $formProtection->generateToken('installTool', 'extensionScannerScanFile'),
610  'extensionScannerMarkFullyScannedRestFilesToken' => $formProtection->generateToken('installTool', 'extensionScannerMarkFullyScannedRestFiles'),
611  ]);
612  return new JsonResponse([
613  'success' => true,
614  'html' => $view->render('Upgrade/ExtensionScanner'),
615  'buttons' => [
616  [
617  'btnClass' => 'btn-default t3js-extensionScanner-scan-all',
618  'text' => 'Scan all',
619  ],
620  ],
621  ]);
622  }
623 
627  public function ‪extensionScannerFilesAction(ServerRequestInterface $request): ResponseInterface
628  {
629  // Get and validate path
630  $extension = $request->getParsedBody()['install']['extension'];
631  $extensionBasePath = $this->packageManager->getPackage($extension)->getPackagePath();
632  if (empty($extension) || !GeneralUtility::isAllowedAbsPath($extensionBasePath)) {
633  throw new \RuntimeException(
634  'Path to extension ' . $extension . ' not allowed.',
635  1499777261
636  );
637  }
638  if (!is_dir($extensionBasePath)) {
639  throw new \RuntimeException(
640  'Extension path ' . $extensionBasePath . ' does not exist or is no directory.',
641  1499777330
642  );
643  }
644 
645  ‪$finder = new Finder();
646  $files = ‪$finder->files()->in($extensionBasePath)->name('*.php')->sortByName();
647  // A list of file names relative to extension directory
648  $relativeFileNames = [];
649  foreach ($files as $file) {
651  $relativeFileNames[] = GeneralUtility::fixWindowsFilePath($file->getRelativePathname());
652  }
653  return new JsonResponse([
654  'success' => true,
655  'files' => $relativeFileNames,
656  ]);
657  }
658 
665  public function ‪extensionScannerMarkFullyScannedRestFilesAction(ServerRequestInterface $request): ResponseInterface
666  {
667  $foundRestFileHashes = (array)($request->getParsedBody()['install']['hashes'] ?? []);
668  // First un-mark files marked as scanned-ok
669  $registry = new Registry();
670  $registry->removeAllByNamespace('extensionScannerNotAffected');
671  // Find all .rst files (except those from v8), see if they are tagged with "FullyScanned"
672  // and if their content is not in incoming "hashes" array, mark as "not affected"
673  $documentationFile = new DocumentationFile();
674  ‪$finder = new Finder();
675  $restFilesBasePath = ‪ExtensionManagementUtility::extPath('core') . 'Documentation/Changelog';
676  $restFiles = ‪$finder->files()->in($restFilesBasePath);
677  $fullyScannedRestFilesNotAffected = [];
678  foreach ($restFiles as $restFile) {
679  // Skip files in "8.x" directory
681  if (str_starts_with($restFile->getRelativePath(), '8')) {
682  continue;
683  }
684 
685  // Build array of file (hashes) not affected by current scan, if they are tagged as "FullyScanned"
686  $listEntries = $documentationFile->getListEntry(str_replace(
687  '\\',
688  '/',
689  (string)realpath($restFile->getPathname())
690  ));
691  $parsedRestFile = array_pop($listEntries);
692  if (!in_array($parsedRestFile['file_hash'], $foundRestFileHashes, true)
693  && in_array('FullyScanned', $parsedRestFile['tags'], true)
694  ) {
695  $fullyScannedRestFilesNotAffected[] = $parsedRestFile['file_hash'];
696  }
697  }
698  foreach ($fullyScannedRestFilesNotAffected as $fileHash) {
699  $registry->set('extensionScannerNotAffected', $fileHash, $fileHash);
700  }
701  return new JsonResponse([
702  'success' => true,
703  'markedAsNotAffected' => count($fullyScannedRestFilesNotAffected),
704  ]);
705  }
706 
710  public function ‪extensionScannerScanFileAction(ServerRequestInterface $request): ResponseInterface
711  {
712  // Get and validate path and file
713  $extension = $request->getParsedBody()['install']['extension'];
714  $extensionBasePath = $this->packageManager->getPackage($extension)->getPackagePath();
715  if (empty($extension) || !GeneralUtility::isAllowedAbsPath($extensionBasePath)) {
716  throw new \RuntimeException(
717  'Path to extension ' . $extension . ' not allowed.',
718  1499789246
719  );
720  }
721  if (!is_dir($extensionBasePath)) {
722  throw new \RuntimeException(
723  'Extension path ' . $extensionBasePath . ' does not exist or is no directory.',
724  1499789259
725  );
726  }
727  $file = $request->getParsedBody()['install']['file'];
728  $absoluteFilePath = $extensionBasePath . $file;
729  if (empty($file) || !GeneralUtility::isAllowedAbsPath($absoluteFilePath)) {
730  throw new \RuntimeException(
731  'Path to file ' . $file . ' of extension ' . $extension . ' not allowed.',
732  1499789384
733  );
734  }
735  if (!is_file($absoluteFilePath)) {
736  throw new \RuntimeException(
737  'File ' . $file . ' not found or is not a file.',
738  1499789433
739  );
740  }
741 
742  ‪$parser = (new ParserFactory())->createForVersion(PhpVersion::fromComponents(8, 2));
743  // Parse PHP file to AST and traverse tree calling visitors
744  $statements = ‪$parser->parse(file_get_contents($absoluteFilePath));
745 
746  // The built in NameResolver translates class names shortened with 'use' to fully qualified
747  // class names at all places. Incredibly useful for us and added as first visitor.
748  // IMPORTANT: first process completely to resolve fully qualified names of arguments
749  // (otherwise GeneratorClassesResolver will NOT get reliable results)
750  $traverser = new NodeTraverser();
751  $traverser->addVisitor(new NameResolver());
752  $statements = $traverser->traverse($statements);
753 
754  // IMPORTANT: second process to actually work on the pre-resolved statements
755  $traverser = new NodeTraverser();
756  // Understand GeneralUtility::makeInstance('My\\Package\\Foo\\Bar') as fqdn class name in first argument
757  $traverser->addVisitor(new GeneratorClassesResolver());
758  // Count ignored lines, effective code lines, ...
759  $statistics = new CodeStatistics();
760  $traverser->addVisitor($statistics);
761 
762  // Add all configured matcher classes
763  $matcherFactory = new MatcherFactory();
764  ‪$matchers = $matcherFactory->createAll($this->matchers);
765  foreach (‪$matchers as $matcher) {
766  $traverser->addVisitor($matcher);
767  }
768 
769  $traverser->traverse($statements);
770 
771  // Gather code matches
772  $matches = [[]];
773  foreach (‪$matchers as $matcher) {
775  $matches[] = $matcher->getMatches();
776  }
777  $matches = array_merge(...$matches);
778 
779  // Prepare match output
780  $restFilesBasePath = ‪ExtensionManagementUtility::extPath('core') . 'Documentation/Changelog';
781  $documentationFile = new DocumentationFile();
782  $preparedMatches = [];
783  foreach ($matches as $match) {
784  $preparedHit = [];
785  $preparedHit['uniqueId'] = ‪StringUtility::getUniqueId();
786  $preparedHit['message'] = $match['message'];
787  $preparedHit['line'] = $match['line'];
788  $preparedHit['indicator'] = $match['indicator'];
789  $preparedHit['lineContent'] = $this->‪extensionScannerGetLineFromFile($absoluteFilePath, $match['line']);
790  $preparedHit['restFiles'] = [];
791  foreach ($match['restFiles'] as $fileName) {
792  ‪$finder = new Finder();
793  $restFileLocation = ‪$finder->files()->in($restFilesBasePath)->name($fileName);
794  if ($restFileLocation->count() !== 1) {
795  throw new \RuntimeException(
796  'ResT file ' . $fileName . ' not found or multiple files found.',
797  1499803909
798  );
799  }
800  foreach ($restFileLocation as $restFile) {
802  $restFileLocation = $restFile->getPathname();
803  break;
804  }
805  $listEntries = $documentationFile->getListEntry(str_replace(
806  '\\',
807  '/',
808  (string)realpath($restFileLocation)
809  ));
810  $parsedRestFile = array_pop($listEntries);
811  $version = ‪GeneralUtility::trimExplode(DIRECTORY_SEPARATOR, $restFileLocation);
812  array_pop($version);
813  // something like "8.2" .. "8.7" .. "master"
814  $parsedRestFile['version'] = array_pop($version);
815  $parsedRestFile['uniqueId'] = ‪StringUtility::getUniqueId();
816  $preparedHit['restFiles'][] = $parsedRestFile;
817  }
818  $preparedMatches[] = $preparedHit;
819  }
820  return new JsonResponse([
821  'success' => true,
822  'matches' => $preparedMatches,
823  'isFileIgnored' => $statistics->isFileIgnored(),
824  'effectiveCodeLines' => $statistics->getNumberOfEffectiveCodeLines(),
825  'ignoredLines' => $statistics->getNumberOfIgnoredLines(),
826  ]);
827  }
828 
832  public function ‪tcaExtTablesCheckAction(ServerRequestInterface $request): ResponseInterface
833  {
834  $view = $this->‪initializeView($request);
835  $messageQueue = new FlashMessageQueue('install');
836  $loadTcaService = GeneralUtility::makeInstance(LoadTcaService::class);
837  $loadTcaService->loadExtensionTablesWithoutMigration();
838  $baseTca = ‪$GLOBALS['TCA'];
839  $container = $this->lateBootService->getContainer();
840  $backup = $this->lateBootService->makeCurrent($container);
841  foreach ($this->packageManager->getActivePackages() as $package) {
843 
844  $extensionKey = $package->getPackageKey();
845  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
846  if (@file_exists($extTablesPath)) {
847  $loadTcaService->loadSingleExtTablesFile($extensionKey);
848  $newTca = ‪$GLOBALS['TCA'];
849  if ($newTca !== $baseTca) {
850  $messageQueue->enqueue(new FlashMessage(
851  '',
852  $extensionKey,
853  ContextualFeedbackSeverity::NOTICE
854  ));
855  }
856  $baseTca = $newTca;
857  }
858  }
859  $this->lateBootService->makeCurrent(null, $backup);
860  return new JsonResponse([
861  'success' => true,
862  'status' => $messageQueue,
863  'html' => $view->render('Upgrade/TcaExtTablesCheck'),
864  'buttons' => [
865  [
866  'btnClass' => 'btn-default t3js-tcaExtTablesCheck-check',
867  'text' => 'Check loaded extensions',
868  ],
869  ],
870  ]);
871  }
872 
876  public function ‪tcaMigrationsCheckAction(ServerRequestInterface $request): ResponseInterface
877  {
878  $view = $this->‪initializeView($request);
879  $messageQueue = new FlashMessageQueue('install');
880  GeneralUtility::makeInstance(LoadTcaService::class)->loadExtensionTablesWithoutMigration();
881  $tcaMigration = GeneralUtility::makeInstance(TcaMigration::class);
882  ‪$GLOBALS['TCA'] = $tcaMigration->migrate(‪$GLOBALS['TCA']);
883  $tcaMessages = $tcaMigration->getMessages();
884  foreach ($tcaMessages as $tcaMessage) {
885  $messageQueue->enqueue(new FlashMessage(
886  '',
887  $tcaMessage,
888  ContextualFeedbackSeverity::NOTICE
889  ));
890  }
891  return new JsonResponse([
892  'success' => true,
893  'status' => $messageQueue,
894  'html' => $view->render('Upgrade/TcaMigrationsCheck'),
895  'buttons' => [
896  [
897  'btnClass' => 'btn-default t3js-tcaMigrationsCheck-check',
898  'text' => 'Check TCA Migrations',
899  ],
900  ],
901  ]);
902  }
903 
907  public function ‪upgradeDocsGetContentAction(ServerRequestInterface $request): ResponseInterface
908  {
909  $formProtection = $this->formProtectionFactory->createFromRequest($request);
910  $documentationDirectories = $this->‪getDocumentationDirectories();
911  $view = $this->‪initializeView($request);
912  $view->assignMultiple([
913  'upgradeDocsMarkReadToken' => $formProtection->generateToken('installTool', 'upgradeDocsMarkRead'),
914  'upgradeDocsUnmarkReadToken' => $formProtection->generateToken('installTool', 'upgradeDocsUnmarkRead'),
915  'upgradeDocsVersions' => $documentationDirectories,
916  ]);
917  return new JsonResponse([
918  'success' => true,
919  'html' => $view->render('Upgrade/UpgradeDocsGetContent'),
920  ]);
921  }
922 
926  public function ‪upgradeDocsGetChangelogForVersionAction(ServerRequestInterface $request): ResponseInterface
927  {
928  $version = $request->getQueryParams()['install']['version'] ?? '';
929  $this->‪assertValidVersion($version);
930 
931  $documentationFiles = $this->‪getDocumentationFiles($version);
932  $view = $this->‪initializeView($request);
933  $view->assignMultiple([
934  'upgradeDocsFiles' => $documentationFiles['normalFiles'],
935  'upgradeDocsReadFiles' => $documentationFiles['readFiles'],
936  'upgradeDocsNotAffectedFiles' => $documentationFiles['notAffectedFiles'],
937  ]);
938  return new JsonResponse([
939  'success' => true,
940  'html' => $view->render('Upgrade/UpgradeDocsGetChangelogForVersion'),
941  ]);
942  }
943 
947  public function ‪upgradeDocsMarkReadAction(ServerRequestInterface $request): ResponseInterface
948  {
949  $registry = new Registry();
950  $filePath = $request->getParsedBody()['install']['ignoreFile'];
951  $fileHash = md5_file($filePath);
952  $registry->set('upgradeAnalysisIgnoredFiles', $fileHash, $filePath);
953  return new JsonResponse([
954  'success' => true,
955  ]);
956  }
957 
961  public function ‪upgradeDocsUnmarkReadAction(ServerRequestInterface $request): ResponseInterface
962  {
963  $registry = new Registry();
964  $filePath = $request->getParsedBody()['install']['ignoreFile'];
965  $fileHash = md5_file($filePath);
966  $registry->remove('upgradeAnalysisIgnoredFiles', $fileHash);
967  return new JsonResponse([
968  'success' => true,
969  ]);
970  }
971 
975  public function ‪upgradeWizardsBlockingDatabaseAddsAction(): ResponseInterface
976  {
977  // ext_localconf, db and ext_tables must be loaded for the updates :(
978  $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
979  $adds = [];
980  $needsUpdate = false;
981  try {
982  $adds = $this->databaseUpgradeWizardsService->getBlockingDatabaseAdds();
983  $this->lateBootService->resetGlobalContainer();
984  if (!empty($adds)) {
985  $needsUpdate = true;
986  }
987  } catch (StatementException $exception) {
988  $needsUpdate = true;
989  }
990  return new JsonResponse([
991  'success' => true,
992  'needsUpdate' => $needsUpdate,
993  'adds' => $adds,
994  ]);
995  }
996 
1000  public function ‪upgradeWizardsBlockingDatabaseExecuteAction(): ResponseInterface
1001  {
1002  // ext_localconf, db and ext_tables must be loaded for the updates :(
1003  $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1004  ‪$errors = $this->databaseUpgradeWizardsService->addMissingTablesAndFields();
1005  $this->lateBootService->resetGlobalContainer();
1006  $messages = new FlashMessageQueue('install');
1007  // Discard empty values which indicate success
1008  ‪$errors = array_filter(‪$errors);
1009  $success = count(‪$errors) === 0;
1010  if ($success) {
1011  $messages->enqueue(new FlashMessage(
1012  '',
1013  'Added missing database fields and tables'
1014  ));
1015  } else {
1016  foreach (‪$errors as $query => $error) {
1017  $messages->enqueue(new FlashMessage(
1018  'Error: ' . $error,
1019  'Failed to execute: ' . $query,
1020  ContextualFeedbackSeverity::ERROR
1021  ));
1022  }
1023  }
1024  return new JsonResponse([
1025  'success' => $success,
1026  'status' => $messages,
1027  ]);
1028  }
1029 
1036  public function ‪upgradeWizardsBlockingDatabaseCharsetFixAction(): ResponseInterface
1037  {
1038  $this->databaseUpgradeWizardsService->setDatabaseCharsetUtf8();
1039  $messages = new FlashMessageQueue('install');
1040  $messages->enqueue(new FlashMessage(
1041  '',
1042  'Default connection database has been set to utf8'
1043  ));
1044  return new JsonResponse([
1045  'success' => true,
1046  'status' => $messages,
1047  ]);
1048  }
1049 
1056  public function ‪upgradeWizardsBlockingDatabaseCharsetTestAction(): ResponseInterface
1057  {
1058  $result = !$this->databaseUpgradeWizardsService->isDatabaseCharsetUtf8();
1059  return new JsonResponse([
1060  'success' => true,
1061  'needsUpdate' => $result,
1062  ]);
1063  }
1064 
1068  public function ‪upgradeWizardsDoneUpgradesAction(): ResponseInterface
1069  {
1070  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1071  $upgradeWizardsService = $container->get(UpgradeWizardsService::class);
1072  $wizardsDone = $upgradeWizardsService->listOfWizardsDone();
1073  $rowUpdatersDone = $upgradeWizardsService->listOfRowUpdatersDone();
1074  $this->lateBootService->resetGlobalContainer();
1075  $messages = new FlashMessageQueue('install');
1076  if (empty($wizardsDone) && empty($rowUpdatersDone)) {
1077  $messages->enqueue(new FlashMessage(
1078  '',
1079  'No wizards are marked as done'
1080  ));
1081  }
1082  return new JsonResponse([
1083  'success' => true,
1084  'status' => $messages,
1085  'wizardsDone' => $wizardsDone,
1086  'rowUpdatersDone' => $rowUpdatersDone,
1087  ]);
1088  }
1089 
1093  public function ‪upgradeWizardsExecuteAction(ServerRequestInterface $request): ResponseInterface
1094  {
1095  // ext_localconf, db and ext_tables must be loaded for the updates :(
1096  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1097  ‪$identifier = $request->getParsedBody()['install']['identifier'];
1098  $values = $request->getParsedBody()['install']['values'] ?? [];
1099  $messages = $container->get(UpgradeWizardsService::class)->executeWizard(‪$identifier, $values);
1100  $this->lateBootService->resetGlobalContainer();
1101  return new JsonResponse([
1102  'success' => true,
1103  'status' => $messages,
1104  ]);
1105  }
1106 
1110  public function ‪upgradeWizardsInputAction(ServerRequestInterface $request): ResponseInterface
1111  {
1112  // ext_localconf, db and ext_tables must be loaded for the updates :(
1113  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1114  ‪$identifier = $request->getParsedBody()['install']['identifier'];
1115  $result = $container->get(UpgradeWizardsService::class)->getWizardUserInput(‪$identifier);
1116  $this->lateBootService->resetGlobalContainer();
1117  return new JsonResponse([
1118  'success' => true,
1119  'status' => [],
1120  'userInput' => $result,
1121  ]);
1122  }
1123 
1127  public function ‪upgradeWizardsListAction(): ResponseInterface
1128  {
1129  // ext_localconf, db and ext_tables must be loaded for the updates :(
1130  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1131  $wizards = $container->get(UpgradeWizardsService::class)->getUpgradeWizardsList();
1132  $this->lateBootService->resetGlobalContainer();
1133  return new JsonResponse([
1134  'success' => true,
1135  'status' => [],
1136  'wizards' => $wizards,
1137  ]);
1138  }
1139 
1143  public function ‪upgradeWizardsMarkUndoneAction(ServerRequestInterface $request): ResponseInterface
1144  {
1145  $container = $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
1146  $upgradeWizardsService = $container->get(UpgradeWizardsService::class);
1147  $wizardToBeMarkedAsUndoneIdentifier = $request->getParsedBody()['install']['identifier'];
1148  $wizardToBeMarkedAsUndone = $upgradeWizardsService->getWizardInformationByIdentifier($wizardToBeMarkedAsUndoneIdentifier);
1149  $result = $upgradeWizardsService->markWizardUndone($wizardToBeMarkedAsUndoneIdentifier);
1150  $this->lateBootService->resetGlobalContainer();
1151  $messages = new FlashMessageQueue('install');
1152  if ($result) {
1153  $messages->enqueue(new FlashMessage(
1154  'The wizard "' . $wizardToBeMarkedAsUndone['title'] . '" has been marked as undone.',
1155  'Wizard marked as undone'
1156  ));
1157  } else {
1158  $messages->enqueue(new FlashMessage(
1159  'The wizard "' . $wizardToBeMarkedAsUndone['title'] . '" has not been marked as undone.',
1160  'Wizard has not been marked undone',
1161  ContextualFeedbackSeverity::ERROR
1162  ));
1163  }
1164  return new JsonResponse([
1165  'success' => true,
1166  'status' => $messages,
1167  ]);
1168  }
1169 
1173  public function ‪upgradeWizardsGetDataAction(ServerRequestInterface $request): ResponseInterface
1174  {
1175  $view = $this->‪initializeView($request);
1176  $formProtection = $this->formProtectionFactory->createFromRequest($request);
1177  $view->assignMultiple([
1178  'upgradeWizardsMarkUndoneToken' => $formProtection->generateToken('installTool', 'upgradeWizardsMarkUndone'),
1179  'upgradeWizardsInputToken' => $formProtection->generateToken('installTool', 'upgradeWizardsInput'),
1180  'upgradeWizardsExecuteToken' => $formProtection->generateToken('installTool', 'upgradeWizardsExecute'),
1181  ]);
1182  return new JsonResponse([
1183  'success' => true,
1184  'html' => $view->render('Upgrade/UpgradeWizards'),
1185  ]);
1186  }
1187 
1193  protected function ‪coreUpdateInitialize()
1194  {
1195  $this->coreUpdateService = GeneralUtility::makeInstance(CoreUpdateService::class);
1196  $this->coreVersionService = GeneralUtility::makeInstance(CoreVersionService::class);
1197  if (!$this->coreUpdateService->isCoreUpdateEnabled()) {
1198  throw new \RuntimeException(
1199  'Core Update disabled in this environment',
1200  1381609294
1201  );
1202  }
1203  // @todo: Does the core updater really depend on loaded ext_* files?
1204  $this->lateBootService->loadExtLocalconfDatabaseAndExtTables();
1205  }
1206 
1213  protected function ‪coreUpdateGetVersionToHandle(ServerRequestInterface $request): CoreRelease
1214  {
1215  $type = $request->getQueryParams()['install']['type'];
1216  if (!isset($type) || empty($type)) {
1217  throw new \RuntimeException(
1218  'Type must be set to either "regular" or "development"',
1219  1380975303
1220  );
1221  }
1222  return $this->coreVersionService->getYoungestCommunityPatchRelease();
1223  }
1224 
1229  protected function ‪extensionCompatTesterLoadExtLocalconfForExtension(PackageInterface $package)
1230  {
1231  $extLocalconfPath = $package->getPackagePath() . 'ext_localconf.php';
1232  if (@file_exists($extLocalconfPath)) {
1233  require $extLocalconfPath;
1234  }
1235  }
1236 
1241  protected function ‪extensionCompatTesterLoadExtTablesForExtension(PackageInterface $package)
1242  {
1243  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
1244  if (@file_exists($extTablesPath)) {
1245  require $extTablesPath;
1246  }
1247  }
1248 
1252  protected function ‪getDocumentationDirectories(): array
1253  {
1254  $documentationFileService = new DocumentationFile();
1255  $documentationDirectories = $documentationFileService->findDocumentationDirectories(
1256  str_replace('\\', '/', (string)realpath(‪ExtensionManagementUtility::extPath('core') . 'Documentation/Changelog'))
1257  );
1258  return array_reverse($documentationDirectories);
1259  }
1260 
1264  protected function ‪getDocumentationFiles(string $version): array
1265  {
1266  $documentationFileService = new DocumentationFile();
1267  $documentationFiles = $documentationFileService->findDocumentationFiles(
1268  str_replace('\\', '/', (string)realpath(‪ExtensionManagementUtility::extPath('core') . 'Documentation/Changelog/' . $version))
1269  );
1270 
1271  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_registry');
1272  $filesMarkedAsRead = $queryBuilder
1273  ->select('*')
1274  ->from('sys_registry')
1275  ->where(
1276  $queryBuilder->expr()->eq(
1277  'entry_namespace',
1278  $queryBuilder->createNamedParameter('upgradeAnalysisIgnoredFiles')
1279  )
1280  )
1281  ->executeQuery()
1282  ->fetchAllAssociative();
1283  $hashesMarkedAsRead = [];
1284  foreach ($filesMarkedAsRead as $file) {
1285  $hashesMarkedAsRead[] = $file['entry_key'];
1286  }
1287 
1288  $fileMarkedAsNotAffected = $queryBuilder
1289  ->select('*')
1290  ->from('sys_registry')
1291  ->where(
1292  $queryBuilder->expr()->eq(
1293  'entry_namespace',
1294  $queryBuilder->createNamedParameter('extensionScannerNotAffected')
1295  )
1296  )
1297  ->executeQuery()
1298  ->fetchAllAssociative();
1299  $hashesMarkedAsNotAffected = [];
1300  foreach ($fileMarkedAsNotAffected as $file) {
1301  $hashesMarkedAsNotAffected[] = $file['entry_key'];
1302  }
1303 
1304  $readFiles = [];
1305  $notAffectedFiles = [];
1306  foreach ($documentationFiles as $fileId => $fileData) {
1307  if (in_array($fileData['file_hash'], $hashesMarkedAsRead, true)) {
1308  $readFiles[$fileId] = $fileData;
1309  unset($documentationFiles[$fileId]);
1310  } elseif (in_array($fileData['file_hash'], $hashesMarkedAsNotAffected, true)) {
1311  $notAffectedFiles[$fileId] = $fileData;
1312  unset($documentationFiles[$fileId]);
1313  }
1314  }
1315 
1316  return [
1317  'normalFiles' => $documentationFiles,
1318  'readFiles' => $readFiles,
1319  'notAffectedFiles' => $notAffectedFiles,
1320  ];
1321  }
1322 
1330  protected function ‪extensionScannerGetLineFromFile(string $file, int $lineNumber): string
1331  {
1332  $fileContent = file($file, FILE_IGNORE_NEW_LINES);
1333  $line = '';
1334  if (isset($fileContent[$lineNumber - 1])) {
1335  $line = trim($fileContent[$lineNumber - 1]);
1336  }
1337  return $line;
1338  }
1339 
1345  protected function ‪assertValidVersion(string $version): void
1346  {
1347  if ($version !== 'master' && !preg_match('/^\d+.\d+(?:.(?:\d+|x))?$/', $version)) {
1348  throw new \InvalidArgumentException('Given version "' . $version . '" is invalid', 1537209128);
1349  }
1350  }
1351 }
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateActivateAction
‪coreUpdateActivateAction(ServerRequestInterface $request)
Definition: UpgradeController.php:215
‪TYPO3\CMS\Install\ExtensionScanner\Php\GeneratorClassesResolver
Definition: GeneratorClassesResolver.php:42
‪TYPO3\CMS\Install\Controller\UpgradeController\$coreVersionService
‪CoreVersionService $coreVersionService
Definition: UpgradeController.php:91
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionScannerMarkFullyScannedRestFilesAction
‪extensionScannerMarkFullyScannedRestFilesAction(ServerRequestInterface $request)
Definition: UpgradeController.php:662
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeDocsGetChangelogForVersionAction
‪upgradeDocsGetChangelogForVersionAction(ServerRequestInterface $request)
Definition: UpgradeController.php:923
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeDocsGetContentAction
‪upgradeDocsGetContentAction(ServerRequestInterface $request)
Definition: UpgradeController.php:904
‪TYPO3\CMS\Install\ExtensionScanner\Php\CodeStatistics
Definition: CodeStatistics.php:30
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionScannerGetDataAction
‪extensionScannerGetDataAction(ServerRequestInterface $request)
Definition: UpgradeController.php:590
‪$finder
‪if(PHP_SAPI !=='cli') $finder
Definition: header-comment.php:22
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodCallStaticMatcher
Definition: MethodCallStaticMatcher.php:38
‪TYPO3\CMS\Install\UpgradeAnalysis\DocumentationFile
Definition: DocumentationFile.php:33
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsMarkUndoneAction
‪upgradeWizardsMarkUndoneAction(ServerRequestInterface $request)
Definition: UpgradeController.php:1140
‪TYPO3\CMS\Core\Database\Schema\Exception\StatementException
Definition: StatementException.php:24
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateUnpackAction
‪coreUpdateUnpackAction(ServerRequestInterface $request)
Definition: UpgradeController.php:442
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsDoneUpgradesAction
‪upgradeWizardsDoneUpgradesAction()
Definition: UpgradeController.php:1065
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsExecuteAction
‪upgradeWizardsExecuteAction(ServerRequestInterface $request)
Definition: UpgradeController.php:1090
‪TYPO3\CMS\Install\Controller\UpgradeController
Definition: UpgradeController.php:84
‪TYPO3\CMS\Install\Controller\UpgradeController\cardsAction
‪cardsAction(ServerRequestInterface $request)
Definition: UpgradeController.php:191
‪TYPO3\CMS\Install\Controller\UpgradeController\$matchers
‪array $matchers
Definition: UpgradeController.php:105
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsBlockingDatabaseExecuteAction
‪upgradeWizardsBlockingDatabaseExecuteAction()
Definition: UpgradeController.php:997
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsBlockingDatabaseCharsetFixAction
‪upgradeWizardsBlockingDatabaseCharsetFixAction()
Definition: UpgradeController.php:1033
‪TYPO3\CMS\Core\Core\Environment\isComposerMode
‪static isComposerMode()
Definition: Environment.php:137
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsBlockingDatabaseAddsAction
‪upgradeWizardsBlockingDatabaseAddsAction()
Definition: UpgradeController.php:972
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Core\Package\PackageInterface\getPackagePath
‪string getPackagePath()
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeDocsMarkReadAction
‪upgradeDocsMarkReadAction(ServerRequestInterface $request)
Definition: UpgradeController.php:944
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateInitialize
‪coreUpdateInitialize()
Definition: UpgradeController.php:1190
‪$parser
‪$parser
Definition: annotationChecker.php:103
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateVerifyChecksumAction
‪coreUpdateVerifyChecksumAction(ServerRequestInterface $request)
Definition: UpgradeController.php:454
‪TYPO3\CMS\Install\CoreVersion\CoreRelease
Definition: CoreRelease.php:21
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsGetDataAction
‪upgradeWizardsGetDataAction(ServerRequestInterface $request)
Definition: UpgradeController.php:1170
‪TYPO3\CMS\Install\WebserverType
‪WebserverType
Definition: WebserverType.php:26
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionScannerGetLineFromFile
‪string extensionScannerGetLineFromFile(string $file, int $lineNumber)
Definition: UpgradeController.php:1327
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\PropertyExistsStaticMatcher
Definition: PropertyExistsStaticMatcher.php:29
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:55
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateGetDataAction
‪coreUpdateGetDataAction(ServerRequestInterface $request)
Definition: UpgradeController.php:254
‪TYPO3\CMS\Core\Package\PackageInterface
Definition: PackageInterface.php:24
‪TYPO3\CMS\Install\Controller\UpgradeController\tcaMigrationsCheckAction
‪tcaMigrationsCheckAction(ServerRequestInterface $request)
Definition: UpgradeController.php:873
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentRequiredMatcher
Definition: MethodArgumentRequiredMatcher.php:30
‪TYPO3\CMS\Install\Service\UpgradeWizardsService
Definition: UpgradeWizardsService.php:40
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsListAction
‪upgradeWizardsListAction()
Definition: UpgradeController.php:1124
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:32
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodAnnotationMatcher
Definition: MethodAnnotationMatcher.php:29
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ConstantMatcher
Definition: ConstantMatcher.php:30
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterLoadExtTablesAction
‪extensionCompatTesterLoadExtTablesAction(ServerRequestInterface $request)
Definition: UpgradeController.php:518
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\PropertyAnnotationMatcher
Definition: PropertyAnnotationMatcher.php:30
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterLoadExtTablesForExtension
‪extensionCompatTesterLoadExtTablesForExtension(PackageInterface $package)
Definition: UpgradeController.php:1238
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ClassNameMatcher
Definition: ClassNameMatcher.php:28
‪TYPO3\CMS\Install\Service\CoreUpdateService\isCoreUpdateEnabled
‪bool isCoreUpdateEnabled()
Definition: CoreUpdateService.php:78
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static extPath(string $key, string $script='')
Definition: ExtensionManagementUtility.php:82
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateCheckPreConditionsAction
‪coreUpdateCheckPreConditionsAction(ServerRequestInterface $request)
Definition: UpgradeController.php:227
‪TYPO3\CMS\Install\Exception
Definition: Exception.php:23
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\PropertyPublicMatcher
Definition: PropertyPublicMatcher.php:29
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodCallMatcher
Definition: MethodCallMatcher.php:30
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedMatcher
Definition: MethodArgumentDroppedMatcher.php:31
‪TYPO3\CMS\Install\Controller
Definition: AbstractController.php:18
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ArrayGlobalMatcher
Definition: ArrayGlobalMatcher.php:31
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateGetVersionToHandle
‪coreUpdateGetVersionToHandle(ServerRequestInterface $request)
Definition: UpgradeController.php:1210
‪TYPO3\CMS\Install\Controller\UpgradeController\assertValidVersion
‪assertValidVersion(string $version)
Definition: UpgradeController.php:1342
‪TYPO3\CMS\Install\ExtensionScanner\CodeScannerInterface
Definition: CodeScannerInterface.php:24
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionScannerScanFileAction
‪extensionScannerScanFileAction(ServerRequestInterface $request)
Definition: UpgradeController.php:707
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsInputAction
‪upgradeWizardsInputAction(ServerRequestInterface $request)
Definition: UpgradeController.php:1107
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentRequiredStaticMatcher
Definition: MethodArgumentRequiredStaticMatcher.php:31
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedStaticMatcher
Definition: MethodArgumentDroppedStaticMatcher.php:31
‪TYPO3\CMS\Install\Service\LateBootService
Definition: LateBootService.php:27
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeWizardsBlockingDatabaseCharsetTestAction
‪upgradeWizardsBlockingDatabaseCharsetTestAction()
Definition: UpgradeController.php:1053
‪TYPO3\CMS\Core\Service\OpcodeCacheService
Definition: OpcodeCacheService.php:27
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\FunctionCallMatcher
Definition: FunctionCallMatcher.php:30
‪TYPO3\CMS\Install\Controller\UpgradeController\getDocumentationFiles
‪getDocumentationFiles(string $version)
Definition: UpgradeController.php:1261
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterLoadedExtensionListAction
‪extensionCompatTesterLoadedExtensionListAction(ServerRequestInterface $request)
Definition: UpgradeController.php:466
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ConstructorArgumentMatcher
Definition: ConstructorArgumentMatcher.php:37
‪TYPO3\CMS\Install\ExtensionScanner\Php\MatcherFactory
Definition: MatcherFactory.php:29
‪TYPO3\CMS\Install\Service\LoadTcaService
Definition: LoadTcaService.php:27
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionScannerFilesAction
‪extensionScannerFilesAction(ServerRequestInterface $request)
Definition: UpgradeController.php:624
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ClassConstantMatcher
Definition: ClassConstantMatcher.php:31
‪TYPO3\CMS\Install\Controller\UpgradeController\upgradeDocsUnmarkReadAction
‪upgradeDocsUnmarkReadAction(ServerRequestInterface $request)
Definition: UpgradeController.php:958
‪TYPO3\CMS\Install\Controller\AbstractController\initializeView
‪initializeView(ServerRequestInterface $request)
Definition: AbstractController.php:39
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterLoadExtLocalconfForExtension
‪extensionCompatTesterLoadExtLocalconfForExtension(PackageInterface $package)
Definition: UpgradeController.php:1226
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateDownloadAction
‪coreUpdateDownloadAction(ServerRequestInterface $request)
Definition: UpgradeController.php:242
‪$errors
‪$errors
Definition: annotationChecker.php:116
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateIsUpdateAvailableAction
‪coreUpdateIsUpdateAvailableAction()
Definition: UpgradeController.php:293
‪TYPO3\CMS\Install\Service\CoreUpdateService
Definition: CoreUpdateService.php:42
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:43
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterLoadExtLocalconfAction
‪extensionCompatTesterLoadExtLocalconfAction(ServerRequestInterface $request)
Definition: UpgradeController.php:491
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentUnusedMatcher
Definition: MethodArgumentUnusedMatcher.php:33
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ArrayDimensionMatcher
Definition: ArrayDimensionMatcher.php:31
‪TYPO3\CMS\Install\Controller\AbstractController
Definition: AbstractController.php:35
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\unloadExtension
‪static unloadExtension(string $extensionKey)
Definition: ExtensionManagementUtility.php:1154
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Install\Controller\UpgradeController\extensionCompatTesterUninstallExtensionAction
‪extensionCompatTesterUninstallExtensionAction(ServerRequestInterface $request)
Definition: UpgradeController.php:552
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Install\Controller\UpgradeController\tcaExtTablesCheckAction
‪tcaExtTablesCheckAction(ServerRequestInterface $request)
Definition: UpgradeController.php:829
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Install\Controller\UpgradeController\coreUpdateMoveAction
‪coreUpdateMoveAction(ServerRequestInterface $request)
Definition: UpgradeController.php:430
‪TYPO3\CMS\Install\Controller\UpgradeController\__construct
‪__construct(protected readonly PackageManager $packageManager, private readonly LateBootService $lateBootService, private readonly DatabaseUpgradeWizardsService $databaseUpgradeWizardsService, private readonly FormProtectionFactory $formProtectionFactory)
Definition: UpgradeController.php:93
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:29
‪TYPO3\CMS\Install\Service\ClearCacheService
Definition: ClearCacheService.php:27
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\InterfaceMethodChangedMatcher
Definition: InterfaceMethodChangedMatcher.php:35
‪TYPO3\CMS\Install\Controller\UpgradeController\$coreUpdateService
‪CoreUpdateService $coreUpdateService
Definition: UpgradeController.php:87
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:817
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57
‪TYPO3\CMS\Core\Configuration\Tca\TcaMigration
Definition: TcaMigration.php:31
‪TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\PropertyProtectedMatcher
Definition: PropertyProtectedMatcher.php:30
‪TYPO3\CMS\Install\Controller\UpgradeController\getDocumentationDirectories
‪string[] getDocumentationDirectories()
Definition: UpgradeController.php:1249