1<?php 2 3declare(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 18namespace TYPO3\CMS\Install\Command; 19 20use Symfony\Component\Console\Command\Command; 21use Symfony\Component\Console\Input\InputInterface; 22use Symfony\Component\Console\Input\InputOption; 23use Symfony\Component\Console\Output\OutputInterface; 24use Symfony\Component\Console\Style\SymfonyStyle; 25use TYPO3\CMS\Core\Authentication\CommandLineUserAuthentication; 26use TYPO3\CMS\Core\Core\Bootstrap; 27use TYPO3\CMS\Core\Utility\GeneralUtility; 28use TYPO3\CMS\Install\Service\LateBootService; 29use TYPO3\CMS\Install\Service\UpgradeWizardsService; 30use TYPO3\CMS\Install\Updates\ChattyInterface; 31use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; 32 33/** 34 * Upgrade wizard command for listing wizards 35 * 36 * @internal 37 */ 38class UpgradeWizardListCommand extends Command 39{ 40 /** 41 * @var LateBootService 42 */ 43 private $lateBootService; 44 45 /** 46 * @var UpgradeWizardsService 47 */ 48 private $upgradeWizardsService; 49 50 /** 51 * @var OutputInterface|\Symfony\Component\Console\Style\StyleInterface 52 */ 53 private $output; 54 55 /** 56 * @var InputInterface 57 */ 58 private $input; 59 60 public function __construct( 61 string $name, 62 LateBootService $lateBootService, 63 UpgradeWizardsService $upgradeWizardsService 64 ) { 65 $this->lateBootService = $lateBootService; 66 $this->upgradeWizardsService = $upgradeWizardsService; 67 parent::__construct($name); 68 } 69 70 /** 71 * Bootstrap running of upgradeWizards 72 */ 73 protected function bootstrap(): void 74 { 75 $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(); 76 Bootstrap::initializeBackendUser(CommandLineUserAuthentication::class); 77 Bootstrap::initializeBackendAuthentication(); 78 } 79 80 /** 81 * Configure the command by defining the name, options and arguments 82 */ 83 protected function configure() 84 { 85 $this->setDescription('List available upgrade wizards.') 86 ->addOption( 87 'all', 88 'a', 89 InputOption::VALUE_NONE, 90 'Include wizards already done.' 91 ); 92 } 93 94 /** 95 * List available upgrade wizards. If -all is given, already done wizards are listed, too. 96 * 97 * @param InputInterface $input 98 * @param \Symfony\Component\Console\Output\OutputInterface $output 99 * @return int 100 */ 101 protected function execute(InputInterface $input, OutputInterface $output) 102 { 103 $this->output = new SymfonyStyle($input, $output); 104 $this->input = $input; 105 $this->bootstrap(); 106 107 $result = 0; 108 $wizards = []; 109 $all = $input->getOption('all'); 110 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $wizardToExecute) { 111 $upgradeWizard = $this->getWizard($wizardToExecute, $identifier, (bool)$all); 112 if ($upgradeWizard !== null) { 113 $wizardInfo = [ 114 'identifier' => $upgradeWizard->getIdentifier(), 115 'title' => $upgradeWizard->getTitle(), 116 'description' => wordwrap($upgradeWizard->getDescription()), 117 ]; 118 if ($all === true) { 119 $wizardInfo['status'] = $this->upgradeWizardsService->isWizardDone($identifier) ? 'DONE' : 'AVAILABLE'; 120 } 121 $wizards[] = $wizardInfo; 122 } 123 } 124 if (empty($wizards)) { 125 $this->output->success('No wizards available.'); 126 } else { 127 if ($all === true) { 128 $this->output->table(['Identifier', 'Title', 'Description', 'Status'], $wizards); 129 } else { 130 $this->output->table(['Identifier', 'Title', 'Description'], $wizards); 131 } 132 } 133 return $result; 134 } 135 136 /** 137 * Get Wizard instance by class name and identifier 138 * Returns null if wizard is already done 139 * 140 * @param string $className 141 * @param string $identifier 142 * @param bool $all 143 * @return \TYPO3\CMS\Install\Updates\UpgradeWizardInterface|null 144 */ 145 protected function getWizard(string $className, string $identifier, $all = false): ?UpgradeWizardInterface 146 { 147 // already done 148 if (!$all && $this->upgradeWizardsService->isWizardDone($identifier)) { 149 return null; 150 } 151 152 $wizardInstance = GeneralUtility::makeInstance($className); 153 if ($wizardInstance instanceof ChattyInterface) { 154 $wizardInstance->setOutput($this->output); 155 } 156 157 if (!($wizardInstance instanceof UpgradeWizardInterface)) { 158 return null; 159 } 160 161 return !$all ? $wizardInstance->updateNecessary() ? $wizardInstance : null : $wizardInstance; 162 } 163} 164