diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ecfb99042..06c5ded33 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -79,3 +79,5 @@ parameters: - web/core/modules/locale/locale.batch.inc - web/core/modules/locale/locale.bulk.inc - web/modules/contrib/config_translation_po/config_translation_po.bulk.inc + # Drupal\dpl_webmaster\Form\InstallOrUpdateModule uses this. + - web/core/modules/update/update.authorize.inc diff --git a/web/modules/custom/dpl_webmaster/src/Form/InstallOrUpdateModule.php b/web/modules/custom/dpl_webmaster/src/Form/InstallOrUpdateModule.php index c211948d9..85d7df566 100644 --- a/web/modules/custom/dpl_webmaster/src/Form/InstallOrUpdateModule.php +++ b/web/modules/custom/dpl_webmaster/src/Form/InstallOrUpdateModule.php @@ -198,6 +198,11 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { // MODULE/) and others list an actual file (i.e., MODULE/README.TXT). $project = strtok($files[0], '/\\'); + if (!$project) { + $this->messenger()->addError($this->t('Could not determine module name from archive')); + return; + } + $archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', [$project, $local_cache, $directory]); if (!empty($archive_errors)) { $this->messenger()->addError(array_shift($archive_errors)); @@ -240,15 +245,11 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { return; } - // This is where we diverge from UpdateManagerInstall. It simply errors out, - // we set a session variable to tell /admin/update/ready which module to - // update and redirect to it instead. It'll pick up the files for the module - // as we've already extracted it in the directory where it expects to find - // it. + // This is where we diverge from UpdateManagerInstall and pass over control + // to update.php. It'll pick up the files for the module as we've already + // extracted it in the directory where it expects to find it. if ($updater->isInstalled()) { - // Tell UpdateReady form which projects to update. - $this->session->set('update_manager_update_projects', [$project => $project]); - $form_state->setRedirect('update.confirmation_page'); + $this->updateProject([$project], $form_state); return; } @@ -291,4 +292,41 @@ public function submitForm(array &$form, FormStateInterface $form_state): void { } } + /** + * Copy uploaded module into place run updates. + * + * @param string[] $projects + * List of projects to update. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * Form state to set redirect on. + */ + protected function updateProject(array $projects, FormStateInterface $form_state): void { + // Most of this has been lifted from UpdateReady::submitForm(). + drupal_get_updaters(); + + $updates = []; + $directory = _update_manager_extract_directory(); + + $project_real_location = NULL; + foreach ($projects as $project) { + $project_location = $directory . '/' . $project; + $updater = Updater::factory($project_location, $this->root); + $project_real_location = $this->fileSystem->realpath($project_location); + $updates[] = [ + 'project' => $project, + 'updater_name' => get_class($updater), + 'local_url' => $project_real_location, + ]; + } + + // Contrary to UpdateReady::submitForm(), we don't check file owners or + // support FTP method. + $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); + $filetransfer = new Local($this->root, $this->fileSystem); + $response = update_authorize_run_update($filetransfer, $updates); + if ($response instanceof Response) { + $form_state->setResponse($response); + } + } + }