5 * Contains \Drupal\Console\Command\Update\ExecuteCommand.
8 namespace Drupal\Console\Command\Update;
10 use Symfony\Component\Console\Input\InputInterface;
11 use Symfony\Component\Console\Input\InputArgument;
12 use Symfony\Component\Console\Output\OutputInterface;
13 use Drupal\Console\Core\Command\Command;
14 use Drupal\Core\State\StateInterface;
15 use Drupal\Core\Extension\ModuleHandler;
16 use Drupal\Core\Update\UpdateRegistry;
17 use Drupal\Console\Utils\Site;
18 use Drupal\Console\Extension\Manager;
19 use Drupal\Console\Core\Utils\ChainQueue;
21 class ExecuteCommand extends Command
36 protected $moduleHandler;
41 protected $postUpdateRegistry;
47 protected $extensionManager;
52 protected $chainQueue;
65 * EntitiesCommand constructor.
68 * @param StateInterface $state
69 * @param ModuleHandler $moduleHandler
70 * @param UpdateRegistry $postUpdateRegistry
71 * @param Manager $extensionManager
72 * @param ChainQueue $chainQueue
74 public function __construct(
76 StateInterface $state,
77 ModuleHandler $moduleHandler,
78 UpdateRegistry $postUpdateRegistry,
79 Manager $extensionManager,
80 ChainQueue $chainQueue
83 $this->state = $state;
84 $this->moduleHandler = $moduleHandler;
85 $this->postUpdateRegistry = $postUpdateRegistry;
86 $this->extensionManager = $extensionManager;
87 $this->chainQueue = $chainQueue;
88 parent::__construct();
94 protected function configure()
97 ->setName('update:execute')
98 ->setDescription($this->trans('commands.update.execute.description'))
101 InputArgument::OPTIONAL,
102 $this->trans('commands.common.options.module'),
107 InputArgument::OPTIONAL,
108 $this->trans('commands.update.execute.options.update-n'),
111 ->setAliases(['upex']);
117 protected function execute(InputInterface $input, OutputInterface $output)
119 $this->module = $input->getArgument('module');
120 $this->update_n = (int)$input->getArgument('update-n');
122 $this->site->loadLegacyFile('/core/includes/install.inc');
123 $this->site->loadLegacyFile('/core/includes/update.inc');
125 drupal_load_updates();
126 update_fix_compatibility();
128 $start = $this->getUpdates($this->module!=='all'?$this->module:null);
129 $updates = update_resolve_dependencies($start);
131 foreach ($updates as $function => $update) {
132 $dependencyMap[$function] = !empty($update['reverse_paths']) ? array_keys($update['reverse_paths']) : [];
135 if (!$this->checkUpdates($start, $updates)) {
136 if ($this->module === 'all') {
137 $this->getIo()->warning(
140 'commands.update.execute.messages.no-pending-updates'
145 $this->getIo()->warning(
148 'commands.update.execute.messages.no-module-updates'
158 $maintenanceMode = $this->state->get('system.maintenance_mode', false);
160 if (!$maintenanceMode) {
161 $this->getIo()->info($this->trans('commands.site.maintenance.description'));
162 $this->state->set('system.maintenance_mode', true);
170 // Post Updates are only safe to run after all schemas have been updated.
171 if (!$this->getUpdates()) {
172 $this->runPostUpdates();
174 } catch (\Exception $e) {
175 watchdog_exception('update', $e);
176 $this->getIo()->error($e->getMessage());
180 if (!$maintenanceMode) {
181 $this->state->set('system.maintenance_mode', false);
182 $this->getIo()->info($this->trans('commands.site.maintenance.messages.maintenance-off'));
185 if (!$this->getUpdates()) {
186 $this->chainQueue->addCommand('update:entities');
189 $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
195 * @param array $start
196 * @param array $updates
198 * @return bool true if the selected module/update number exists.
200 private function checkUpdates(
204 if (!$start || !$updates) {
208 if ($this->module !== 'all') {
209 $module = $this->module;
210 $hooks = array_keys($updates);
212 function ($v) use ($module) {
213 return (int)str_replace(
222 if ((int)min($hooks) > (int)$this->update_n) {
231 * @param array $updates
233 private function runUpdates(
236 $this->getIo()->info(
237 $this->trans('commands.update.execute.messages.executing-required-previous-updates')
240 foreach ($updates as $function => $update) {
241 if (!$update['allowed']) {
245 if ($this->module !== 'all' && $update['number'] > $this->update_n) {
249 $this->getIo()->comment(
251 $this->trans('commands.update.execute.messages.executing-update'),
257 $this->moduleHandler->loadInclude($update['module'], 'install');
259 $this->executeUpdate(
264 drupal_set_installed_schema_version(
274 private function runPostUpdates()
276 $postUpdates = $this->postUpdateRegistry->getPendingUpdateInformation();
277 foreach ($postUpdates as $module => $updates) {
278 foreach ($updates['pending'] as $updateName => $update) {
279 $this->getIo()->info(
281 $this->trans('commands.update.execute.messages.executing-update'),
292 drupal_flush_all_caches();
293 $this->executeUpdate(
297 $this->postUpdateRegistry->registerInvokedUpdates([$function]);
304 protected function getUpdates($module = null)
306 $start = $this->getUpdateList();
308 if (isset($start[$module])) {
310 $module => $start[$module]
320 // Copy of protected \Drupal\system\Controller\DbUpdateController::getModuleUpdates.
321 protected function getUpdateList()
324 $updates = update_get_update_list();
325 foreach ($updates as $module => $update) {
326 $start[$module] = $update['start'];
332 private function executeUpdate($function, &$context)
334 if (!$context || !array_key_exists('sandbox', $context)) {
335 $context['sandbox'] = [];
338 if (function_exists($function)) {
339 $function($context['sandbox']);