output = new StreamOutput($stream, Output::VERBOSITY_NORMAL, false); } /** * @return array List of wizards marked as done in registry */ public function listOfWizardsDone(): array { $wizardsDoneInRegistry = []; foreach ($this->upgradeWizardRegistry->getUpgradeWizards() as $identifier => $serviceName) { if ($this->registry->get('installUpdate', $serviceName, false)) { $wizardsDoneInRegistry[] = [ 'class' => $serviceName, 'identifier' => $identifier, // @todo fetching the service to get the title should be improved 'title' => $this->upgradeWizardRegistry->getUpgradeWizard($identifier)->getTitle(), ]; } } return $wizardsDoneInRegistry; } /** * @return array List of row updaters marked as done in registry * @throws \RuntimeException */ public function listOfRowUpdatersDone(): array { $rowUpdatersDoneClassNames = $this->registry->get('installUpdateRows', 'rowUpdatersDone', []); $rowUpdatersDone = []; foreach ($rowUpdatersDoneClassNames as $rowUpdaterClassName) { // Silently skip non-existing DatabaseRowsUpdateWizards if (!class_exists($rowUpdaterClassName)) { continue; } $rowUpdater = GeneralUtility::makeInstance($rowUpdaterClassName); if (!$rowUpdater instanceof RowUpdaterInterface) { throw new \RuntimeException( 'Row updater must implement RowUpdaterInterface', 1484152906 ); } $rowUpdatersDone[] = [ 'class' => $rowUpdaterClassName, 'identifier' => $rowUpdaterClassName, 'title' => $rowUpdater->getTitle(), ]; } return $rowUpdatersDone; } /** * Mark one wizard as undone. This can be a "casual" wizard * or a single "row updater". * * @param string $identifier Wizard or RowUpdater identifier * @return bool True if wizard has been marked as undone * @throws \RuntimeException */ public function markWizardUndone(string $identifier): bool { $this->assertIdentifierIsValid($identifier); $aWizardHasBeenMarkedUndone = false; foreach ($this->listOfWizardsDone() as $wizard) { if ($wizard['identifier'] === $identifier) { $aWizardHasBeenMarkedUndone = true; $this->registry->set('installUpdate', $wizard['class'], 0); } } if (!$aWizardHasBeenMarkedUndone) { $rowUpdatersDoneList = $this->listOfRowUpdatersDone(); $registryArray = $this->registry->get('installUpdateRows', 'rowUpdatersDone', []); foreach ($rowUpdatersDoneList as $rowUpdater) { if ($rowUpdater['identifier'] === $identifier) { $aWizardHasBeenMarkedUndone = true; foreach ($registryArray as $rowUpdaterMarkedAsDonePosition => $rowUpdaterMarkedAsDone) { if ($rowUpdaterMarkedAsDone === $rowUpdater['class']) { unset($registryArray[$rowUpdaterMarkedAsDonePosition]); break; } } $this->registry->set('installUpdateRows', 'rowUpdatersDone', $registryArray); } } } return $aWizardHasBeenMarkedUndone; } /** * Get list of registered upgrade wizards not marked done. * * @return array List of upgrade wizards in correct order with detail information */ public function getUpgradeWizardsList(): array { $wizards = []; foreach (array_keys($this->upgradeWizardRegistry->getUpgradeWizards()) as $identifier) { if ($this->isWizardDone($identifier)) { continue; } $wizards[] = $this->getWizardInformationByIdentifier($identifier); } return $wizards; } public function getWizardInformationByIdentifier(string $identifier): array { $this->assertIdentifierIsValid($identifier); if (is_subclass_of($identifier, RowUpdaterInterface::class)) { return [ 'class' => $identifier, 'identifier' => $identifier, 'title' => $identifier, 'shouldRenderWizard' => false, 'explanation' => '', ]; } $wizard = $this->upgradeWizardRegistry->getUpgradeWizard($identifier); if ($wizard instanceof ChattyInterface) { $wizard->setOutput($this->output); } return [ 'class' => $wizard::class, 'identifier' => $identifier, 'title' => $wizard->getTitle(), 'shouldRenderWizard' => $wizard->updateNecessary(), 'explanation' => $wizard->getDescription(), ]; } /** * Execute the "get user input" step of a wizard * * @throws \RuntimeException */ public function getWizardUserInput(string $identifier): array { $this->assertIdentifierIsValid($identifier); $wizard = $this->upgradeWizardRegistry->getUpgradeWizard($identifier); $wizardHtml = ''; if ($wizard instanceof ConfirmableInterface) { $markup = []; $radioAttributes = [ 'type' => 'radio', 'class' => 'btn-check', 'name' => 'install[values][' . $identifier . '][install]', 'value' => '0', ]; $markup[] = '
' . nl2br(htmlspecialchars($wizard->getConfirmation()->getMessage())) . '
'; $markup[] = '