diff --git a/core/modules/update/src/Form/UpdateForm.php b/core/modules/update/src/Form/UpdateForm.php deleted file mode 100644 index 8f416c1..0000000 --- a/core/modules/update/src/Form/UpdateForm.php +++ /dev/null @@ -1,84 +0,0 @@ -getForm('update_manager_install_form', 'report'); - } - - /** - * Wraps update_manager_update_form(). - * - * @todo Remove update_manager_update_form(). - */ - public function reportUpdate() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_update_form', 'report'); - } - - /** - * Wraps update_manager_install_form(). - * - * @todo Remove update_manager_install_form(). - */ - public function moduleInstall() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_install_form', 'module'); - } - - /** - * Wraps update_manager_update_form(). - * - * @todo Remove update_manager_update_form(). - */ - public function moduleUpdate() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_update_form', 'module'); - } - - /** - * Wraps update_manager_install_form(). - * - * @todo Remove update_manager_install_form(). - */ - public function themeInstall() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_install_form', 'theme'); - } - - /** - * Wraps update_manager_update_form(). - * - * @todo Remove update_manager_update_form(). - */ - public function themeUpdate() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_update_form', 'theme'); - } - - /** - * Wraps update_manager_update_ready_form(). - * - * @todo Remove update_manager_update_ready_form(). - */ - public function confirmUpdates() { - module_load_include('manager.inc', 'update'); - return \Drupal::formBuilder()->getForm('update_manager_update_ready_form'); - } - -} diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php new file mode 100644 index 0000000..e44cd0d --- /dev/null +++ b/core/modules/update/src/Form/UpdateManagerInstall.php @@ -0,0 +1,222 @@ +moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'update_manager_install_form'; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('module_handler') + ); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); + if (!_update_manager_check_backends($form, 'install')) { + return $form; + } + + $form['help_text'] = array( + '#prefix' => '
', + '#markup' => $this->t('You can find modules and themes on drupal.org. The following file extensions are supported: %extensions.', array( + '@module_url' => 'http://drupal.org/project/modules', + '@theme_url' => 'http://drupal.org/project/themes', + '@drupal_org_url' => 'http://drupal.org', + '%extensions' => archiver_get_extensions(), + )), + '#suffix' => '
', + ); + + $form['project_url'] = array( + '#type' => 'url', + '#title' => $this->t('Install from a URL'), + '#description' => $this->t('For example: %url', array('%url' => 'http://ftp.drupal.org/files/projects/name.tar.gz')), + ); + + $form['information'] = array( + '#prefix' => '', + '#markup' => $this->t('Or'), + '#suffix' => '', + ); + + $form['project_upload'] = array( + '#type' => 'file', + '#title' => $this->t('Upload a module or theme archive to install'), + '#description' => $this->t('For example: %filename from your local computer', array('%filename' => 'name.tar.gz')), + ); + + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Install'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + $uploaded_file = $this->getRequest()->files->get('files[project_upload]', NULL, TRUE); + if (!($form_state['values']['project_url'] XOR !empty($uploaded_file))) { + $this->setFormError('project_url', $form_state, $this->t('You must either provide a URL or upload an archive file to install.')); + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $local_cache = NULL; + if ($form_state['values']['project_url']) { + $local_cache = update_manager_file_get($form_state['values']['project_url']); + if (!$local_cache) { + drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', array('%url' => $form_state['values']['project_url'])), 'error'); + return; + } + } + elseif ($_FILES['files']['name']['project_upload']) { + $validators = array('file_validate_extensions' => array(archiver_get_extensions())); + if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) { + // Failed to upload the file. file_save_upload() calls + // drupal_set_message() on failure. + return; + } + $local_cache = $finfo->getFileUri(); + } + + $directory = _update_manager_extract_directory(); + try { + $archive = update_manager_archive_extract($local_cache, $directory); + } + catch (\Exception $e) { + drupal_set_message($e->getMessage(), 'error'); + return; + } + + $files = $archive->listContents(); + if (!$files) { + drupal_set_message($this->t('Provided archive contains no files.'), 'error'); + return; + } + + // Unfortunately, we can only use the directory name to determine the + // project name. Some archivers list the first file as the directory (i.e., + // MODULE/) and others list an actual file (i.e., MODULE/README.TXT). + $project = strtok($files[0], '/\\'); + + $archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', array($project, $local_cache, $directory)); + if (!empty($archive_errors)) { + drupal_set_message(array_shift($archive_errors), 'error'); + // @todo: Fix me in D8: We need a way to set multiple errors on the same + // form element and have all of them appear! + if (!empty($archive_errors)) { + foreach ($archive_errors as $error) { + drupal_set_message($error, 'error'); + } + } + return; + } + + // Make sure the Updater registry is loaded. + drupal_get_updaters(); + + $project_location = $directory . '/' . $project; + try { + $updater = Updater::factory($project_location); + } + catch (\Exception $e) { + drupal_set_message($e->getMessage(), 'error'); + return; + } + + try { + $project_title = Updater::getProjectTitle($project_location); + } + catch (\Exception $e) { + drupal_set_message($e->getMessage(), 'error'); + return; + } + + if (!$project_title) { + drupal_set_message($this->t('Unable to determine %project name.', array('%project' => $project)), 'error'); + } + + if ($updater->isInstalled()) { + drupal_set_message($this->t('%project is already installed.', array('%project' => $project_title)), 'error'); + return; + } + + $project_real_location = drupal_realpath($project_location); + $arguments = array( + 'project' => $project, + 'updater_name' => get_class($updater), + 'local_url' => $project_real_location, + ); + + // If the owner of the directory we extracted is the same as the owner of + // our configuration directory (e.g. sites/default) where we're trying to + // install the code, there's no need to prompt for FTP/SSH credentials. + // Instead, we instantiate a Drupal\Core\FileTransfer\Local and invoke + // update_authorize_run_install() directly. + if (fileowner($project_real_location) == fileowner(conf_path())) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); + $filetransfer = new Local(DRUPAL_ROOT); + call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments)); + } + + // Otherwise, go through the regular workflow to prompt for FTP/SSH + // credentials and invoke update_authorize_run_install() indirectly with + // whatever FileTransfer object authorize.php creates for us. + else { + system_authorized_init('update_authorize_run_install', drupal_get_path('module', 'update') . '/update.authorize.inc', $arguments, $this->t('Update manager')); + $form_state['redirect'] = system_authorized_get_url(); + } + } + +} diff --git a/core/modules/update/src/Form/UpdateManagerUpdate.php b/core/modules/update/src/Form/UpdateManagerUpdate.php new file mode 100644 index 0000000..fd2cfb2 --- /dev/null +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php @@ -0,0 +1,331 @@ +moduleHandler = $module_handler; + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'update_manager_update_form'; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('module_handler'), + $container->get('state') + ); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); + + $last_markup = array( + '#theme' => 'update_last_check', + '#last' => $this->state->get('update.last_check') ?: 0, + ); + $form['last_check'] = array( + '#markup' => drupal_render($last_markup), + ); + + if (!_update_manager_check_backends($form, 'update')) { + return $form; + } + + $available = update_get_available(TRUE); + if (empty($available)) { + $form['message'] = array( + '#markup' => $this->t('There was a problem getting update information. Try again later.'), + ); + return $form; + } + + $form['#attached']['library'][] = 'update/drupal.update.admin'; + + // This will be a nested array. The first key is the kind of project, which + // can be either 'enabled', 'disabled', 'manual' (projects which require + // manual updates, such as core). Then, each subarray is an array of + // projects of that type, indexed by project short name, and containing an + // array of data for cells in that project's row in the appropriate table. + $projects = array(); + + // This stores the actual download link we're going to update from for each + // project in the form, regardless of if it's enabled or disabled. + $form['project_downloads'] = array('#tree' => TRUE); + $this->moduleHandler->loadInclude('update', 'inc', 'update.compare'); + $project_data = update_calculate_project_data($available); + foreach ($project_data as $name => $project) { + // Filter out projects which are up to date already. + if ($project['status'] == UPDATE_CURRENT) { + continue; + } + // The project name to display can vary based on the info we have. + if (!empty($project['title'])) { + if (!empty($project['link'])) { + $project_name = l($project['title'], $project['link']); + } + else { + $project_name = String::checkPlain($project['title']); + } + } + elseif (!empty($project['info']['name'])) { + $project_name = String::checkPlain($project['info']['name']); + } + else { + $project_name = String::checkPlain($name); + } + if ($project['project_type'] == 'theme' || $project['project_type'] == 'theme-disabled') { + $project_name .= ' ' . $this->t('(Theme)'); + } + + if (empty($project['recommended'])) { + // If we don't know what to recommend they upgrade to, we should skip + // the project entirely. + continue; + } + + $recommended_release = $project['releases'][$project['recommended']]; + $recommended_version = $recommended_release['version'] . ' ' . l($this->t('(Release notes)'), $recommended_release['release_link'], array('attributes' => array('title' => $this->t('Release notes for @project_title', array('@project_title' => $project['title']))))); + if ($recommended_release['version_major'] != $project['existing_major']) { + $recommended_version .= '' . $this->t('Updates of Drupal core are not supported at this time.') . '
'; + $form['manual_updates'] = array( + '#type' => 'table', + '#header' => $headers, + '#rows' => $projects['manual'], + '#prefix' => $prefix, + '#weight' => 120, + ); + } + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + if (!empty($form_state['values']['projects'])) { + $enabled = array_filter($form_state['values']['projects']); + } + if (!empty($form_state['values']['disabled_projects'])) { + $disabled = array_filter($form_state['values']['disabled_projects']); + } + if (empty($enabled) && empty($disabled)) { + $this->setFormError('projects', $form_state, $this->t('You must select at least one project to update.')); + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); + $projects = array(); + foreach (array('projects', 'disabled_projects') as $type) { + if (!empty($form_state['values'][$type])) { + $projects = array_merge($projects, array_keys(array_filter($form_state['values'][$type]))); + } + } + $operations = array(); + foreach ($projects as $project) { + $operations[] = array( + 'update_manager_batch_project_get', + array( + $project, + $form_state['values']['project_downloads'][$project], + ), + ); + } + $batch = array( + 'title' => $this->t('Downloading updates'), + 'init_message' => $this->t('Preparing to download selected updates'), + 'operations' => $operations, + 'finished' => 'update_manager_download_batch_finished', + 'file' => drupal_get_path('module', 'update') . '/update.manager.inc', + ); + batch_set($batch); + } + +} diff --git a/core/modules/update/src/Form/UpdateReady.php b/core/modules/update/src/Form/UpdateReady.php new file mode 100644 index 0000000..57155f0 --- /dev/null +++ b/core/modules/update/src/Form/UpdateReady.php @@ -0,0 +1,148 @@ +moduleHandler = $module_handler; + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'update_manager_update_ready_form'; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('module_handler'), + $container->get('state') + ); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); + if (!_update_manager_check_backends($form, 'update')) { + return $form; + } + + $form['backup'] = array( + '#prefix' => '', + '#markup' => $this->t('Back up your database and site before you continue. Learn how.', array('@backup_url' => url('http://drupal.org/node/22281'))), + '#suffix' => '', + ); + + $form['maintenance_mode'] = array( + '#title' => $this->t('Perform updates with site in maintenance mode (strongly recommended)'), + '#type' => 'checkbox', + '#default_value' => TRUE, + ); + + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Continue'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + // Store maintenance_mode setting so we can restore it when done. + $_SESSION['maintenance_mode'] = $this->state->get('system.maintenance_mode'); + if ($form_state['values']['maintenance_mode'] == TRUE) { + $this->state->set('system.maintenance_mode', TRUE); + } + + if (!empty($_SESSION['update_manager_update_projects'])) { + // Make sure the Updater registry is loaded. + drupal_get_updaters(); + + $updates = array(); + $directory = _update_manager_extract_directory(); + + $projects = $_SESSION['update_manager_update_projects']; + unset($_SESSION['update_manager_update_projects']); + + $project_real_location = NULL; + foreach ($projects as $project => $url) { + $project_location = $directory . '/' . $project; + $updater = Updater::factory($project_location); + $project_real_location = drupal_realpath($project_location); + $updates[] = array( + 'project' => $project, + 'updater_name' => get_class($updater), + 'local_url' => $project_real_location, + ); + } + + // If the owner of the last directory we extracted is the same as the + // owner of our configuration directory (e.g. sites/default) where we're + // trying to install the code, there's no need to prompt for FTP/SSH + // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local + // and invoke update_authorize_run_update() directly. + if (fileowner($project_real_location) == fileowner(conf_path())) { + $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); + $filetransfer = new Local(DRUPAL_ROOT); + update_authorize_run_update($filetransfer, $updates); + } + // Otherwise, go through the regular workflow to prompt for FTP/SSH + // credentials and invoke update_authorize_run_update() indirectly with + // whatever FileTransfer object authorize.php creates for us. + else { + system_authorized_init('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates), $this->t('Update manager')); + $form_state['redirect'] = system_authorized_get_url(); + } + } + } + +} diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc index f52d679..1faf7fd 100644 --- a/core/modules/update/update.manager.inc +++ b/core/modules/update/update.manager.inc @@ -36,315 +36,9 @@ * root. */ -use Drupal\Component\Utility\String; -use Drupal\Core\Updater\Updater; -use Drupal\Core\FileTransfer\Local; use Symfony\Component\HttpFoundation\RedirectResponse; /** - * Form constructor for the update form of the Update Manager module. - * - * This presents a table with all projects that have available updates with - * checkboxes to select which ones to upgrade. - * - * @param $context - * String representing the context from which we're trying to update. - * Allowed values are 'module', 'theme', and 'report'. - * - * @see update_manager_update_form_validate() - * @see update_manager_update_form_submit() - * @see update_menu() - * - * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. Use - * \Drupal\update\Form\UpdateForm::reportUpdate() or - * \Drupal\update\Form\UpdateForm::moduleUpdate(). - */ -function update_manager_update_form($form, $form_state = array(), $context) { - if (!_update_manager_check_backends($form, 'update')) { - return $form; - } - - $form['#theme'] = 'update_manager_update_form'; - - $available = update_get_available(TRUE); - if (empty($available)) { - $form['message'] = array( - '#markup' => t('There was a problem getting update information. Try again later.'), - ); - return $form; - } - - $form['#attached']['library'][] = 'update/drupal.update.admin'; - - // This will be a nested array. The first key is the kind of project, which - // can be either 'enabled', 'disabled', 'manual' (projects which require - // manual updates, such as core). Then, each subarray is an array of - // projects of that type, indexed by project short name, and containing an - // array of data for cells in that project's row in the appropriate table. - $projects = array(); - - // This stores the actual download link we're going to update from for each - // project in the form, regardless of if it's enabled or disabled. - $form['project_downloads'] = array('#tree' => TRUE); - - module_load_include('inc', 'update', 'update.compare'); - $project_data = update_calculate_project_data($available); - foreach ($project_data as $name => $project) { - // Filter out projects which are up to date already. - if ($project['status'] == UPDATE_CURRENT) { - continue; - } - // The project name to display can vary based on the info we have. - if (!empty($project['title'])) { - if (!empty($project['link'])) { - $project_name = l($project['title'], $project['link']); - } - else { - $project_name = String::checkPlain($project['title']); - } - } - elseif (!empty($project['info']['name'])) { - $project_name = String::checkPlain($project['info']['name']); - } - else { - $project_name = String::checkPlain($name); - } - if ($project['project_type'] == 'theme' || $project['project_type'] == 'theme-disabled') { - $project_name .= ' ' . t('(Theme)'); - } - - if (empty($project['recommended'])) { - // If we don't know what to recommend they upgrade to, we should skip - // the project entirely. - continue; - } - - $recommended_release = $project['releases'][$project['recommended']]; - $recommended_version = $recommended_release['version'] . ' ' . l(t('(Release notes)'), $recommended_release['release_link'], array('attributes' => array('title' => t('Release notes for @project_title', array('@project_title' => $project['title']))))); - if ($recommended_release['version_major'] != $project['existing_major']) { - $recommended_version .= '' . t('Updates of Drupal core are not supported at this time.') . '
'; - $form['manual_updates'] = array( - '#type' => 'table', - '#header' => $headers, - '#rows' => $projects['manual'], - '#prefix' => $prefix, - '#weight' => 120, - ); - } - - return $form; -} - -/** - * Returns HTML for the first page in the process of updating projects. - * - * @param $variables - * An associative array containing: - * - form: A render element representing the form. - * - * @ingroup themeable - */ -function theme_update_manager_update_form($variables) { - $form = $variables['form']; - $last = \Drupal::state()->get('update.last_check') ?: 0; - $update_last_check = array( - '#theme' => 'update_last_check', - '#last' => $last, - ); - $output = drupal_render($update_last_check); - $output .= drupal_render_children($form); - return $output; -} - -/** - * Form validation handler for update_manager_update_form(). - * - * Ensures that at least one project is selected. - * - * @see update_manager_update_form_submit() - */ -function update_manager_update_form_validate($form, &$form_state) { - if (!empty($form_state['values']['projects'])) { - $enabled = array_filter($form_state['values']['projects']); - } - if (!empty($form_state['values']['disabled_projects'])) { - $disabled = array_filter($form_state['values']['disabled_projects']); - } - if (empty($enabled) && empty($disabled)) { - form_set_error('projects', $form_state, t('You must select at least one project to update.')); - } -} - -/** - * Form submission handler for update_manager_update_form(). - * - * Sets up a batch that downloads, extracts, and verifies the selected releases. - * - * @see update_manager_update_form_validate() - */ -function update_manager_update_form_submit($form, &$form_state) { - $projects = array(); - foreach (array('projects', 'disabled_projects') as $type) { - if (!empty($form_state['values'][$type])) { - $projects = array_merge($projects, array_keys(array_filter($form_state['values'][$type]))); - } - } - $operations = array(); - foreach ($projects as $project) { - $operations[] = array( - 'update_manager_batch_project_get', - array( - $project, - $form_state['values']['project_downloads'][$project], - ), - ); - } - $batch = array( - 'title' => t('Downloading updates'), - 'init_message' => t('Preparing to download selected updates'), - 'operations' => $operations, - 'finished' => 'update_manager_download_batch_finished', - 'file' => drupal_get_path('module', 'update') . '/update.manager.inc', - ); - batch_set($batch); -} - -/** * Batch callback: Performs actions when the download batch is completed. * * @param $success @@ -374,170 +68,6 @@ function update_manager_download_batch_finished($success, $results) { } /** - * Form constructor for the update ready form. - * - * Build the form when the site is ready to update (after downloading). - * - * This form is an intermediary step in the automated update workflow. It is - * presented to the site administrator after all the required updates have been - * downloaded and verified. The point of this page is to encourage the user to - * backup their site, give them the opportunity to put the site offline, and - * then ask them to confirm that the update should continue. After this step, - * the user is redirected to authorize.php to enter their file transfer - * credentials and attempt to complete the update. - * - * @see update_manager_update_ready_form_submit() - * @see update_menu() - */ -function update_manager_update_ready_form($form, &$form_state) { - if (!_update_manager_check_backends($form, 'update')) { - return $form; - } - - $form['backup'] = array( - '#prefix' => '', - '#markup' => t('Back up your database and site before you continue. Learn how.', array('@backup_url' => url('http://drupal.org/node/22281'))), - '#suffix' => '', - ); - - $form['maintenance_mode'] = array( - '#title' => t('Perform updates with site in maintenance mode (strongly recommended)'), - '#type' => 'checkbox', - '#default_value' => TRUE, - ); - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Continue'), - ); - - return $form; -} - -/** - * Form submission handler for update_manager_update_ready_form(). - * - * If the site administrator requested that the site is put offline during the - * update, do so now. Otherwise, pull information about all the required updates - * out of the SESSION, figure out what Drupal\Core\Updater\Updater class is - * needed for each one, generate an array of update operations to perform, and - * hand it all off to system_authorized_init(), then redirect to authorize.php. - * - * @see update_authorize_run_update() - * @see system_authorized_init() - * @see system_authorized_get_url() - */ -function update_manager_update_ready_form_submit($form, &$form_state) { - // Store maintenance_mode setting so we can restore it when done. - $_SESSION['maintenance_mode'] = \Drupal::state()->get('system.maintenance_mode'); - if ($form_state['values']['maintenance_mode'] == TRUE) { - \Drupal::state()->set('system.maintenance_mode', TRUE); - } - - if (!empty($_SESSION['update_manager_update_projects'])) { - // Make sure the Updater registry is loaded. - drupal_get_updaters(); - - $updates = array(); - $directory = _update_manager_extract_directory(); - - $projects = $_SESSION['update_manager_update_projects']; - unset($_SESSION['update_manager_update_projects']); - - foreach ($projects as $project => $url) { - $project_location = $directory . '/' . $project; - $updater = Updater::factory($project_location); - $project_real_location = drupal_realpath($project_location); - $updates[] = array( - 'project' => $project, - 'updater_name' => get_class($updater), - 'local_url' => $project_real_location, - ); - } - - // If the owner of the last directory we extracted is the same as the - // owner of our configuration directory (e.g. sites/default) where we're - // trying to install the code, there's no need to prompt for FTP/SSH - // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local and - // invoke update_authorize_run_update() directly. - if (fileowner($project_real_location) == fileowner(conf_path())) { - module_load_include('inc', 'update', 'update.authorize'); - $filetransfer = new Local(DRUPAL_ROOT); - update_authorize_run_update($filetransfer, $updates); - } - // Otherwise, go through the regular workflow to prompt for FTP/SSH - // credentials and invoke update_authorize_run_update() indirectly with - // whatever FileTransfer object authorize.php creates for us. - else { - system_authorized_init('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates), t('Update manager')); - $form_state['redirect'] = system_authorized_get_url(); - } - } -} - -/** - * Form constructor for the install form of the Update Manager module. - * - * This presents a place to enter a URL or upload an archive file to use to - * install a new module or theme. - * - * @param $context - * String representing the context from which we're trying to install. - * Allowed values are 'module', 'theme', and 'report'. - * - * @see update_manager_install_form_validate() - * @see update_manager_install_form_submit() - * @see update_menu() - * - * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. Use - * \Drupal\update\Form\UpdateForm::reportInstall() or - * \Drupal\update\Form\UpdateForm::moduleInstall(). - */ -function update_manager_install_form($form, &$form_state, $context) { - if (!_update_manager_check_backends($form, 'install')) { - return $form; - } - - $form['help_text'] = array( - '#prefix' => '', - '#markup' => t('You can find modules and themes on drupal.org. The following file extensions are supported: %extensions.', array( - '@module_url' => 'http://drupal.org/project/modules', - '@theme_url' => 'http://drupal.org/project/themes', - '@drupal_org_url' => 'http://drupal.org', - '%extensions' => archiver_get_extensions(), - )), - '#suffix' => '
', - ); - - $form['project_url'] = array( - '#type' => 'url', - '#title' => t('Install from a URL'), - '#description' => t('For example: %url', array('%url' => 'http://ftp.drupal.org/files/projects/name.tar.gz')), - ); - - $form['information'] = array( - '#prefix' => '', - '#markup' => t('Or'), - '#suffix' => '', - ); - - $form['project_upload'] = array( - '#type' => 'file', - '#title' => t('Upload a module or theme archive to install'), - '#description' => t('For example: %filename from your local computer', array('%filename' => 'name.tar.gz')), - ); - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Install'), - ); - - return $form; -} - -/** * Checks for file transfer backends and prepares a form fragment about them. * * @param array $form @@ -605,142 +135,6 @@ function _update_manager_check_backends(&$form, $operation) { } /** - * Form validation handler for update_manager_install_form(). - * - * @see update_manager_install_form_submit() - */ -function update_manager_install_form_validate($form, &$form_state) { - $uploaded_file = \Drupal::request()->files->get('files[project_upload]', NULL, TRUE); - if (!($form_state['values']['project_url'] XOR !empty($uploaded_file))) { - form_set_error('project_url', $form_state, t('You must either provide a URL or upload an archive file to install.')); - } -} - -/** - * Form submission handler for update_manager_install_form(). - * - * Either downloads the file specified in the URL to a temporary cache, or - * uploads the file attached to the form, then attempts to extract the archive - * into a temporary location and verify it. Instantiate the appropriate - * Drupal\Core\Updater\Updater class for this project and make sure it is not - * already installed in the live webroot. If everything is successful, setup an - * operation to run via authorize.php which will copy the extracted files from - * the temporary location into the live site. - * - * @see update_manager_install_form_validate() - * @see update_authorize_run_install() - * @see system_authorized_init() - * @see system_authorized_get_url() - */ -function update_manager_install_form_submit($form, &$form_state) { - if ($form_state['values']['project_url']) { - $field = 'project_url'; - $local_cache = update_manager_file_get($form_state['values']['project_url']); - if (!$local_cache) { - drupal_set_message(t('Unable to retrieve Drupal project from %url.', array('%url' => $form_state['values']['project_url'])), 'error'); - return; - } - } - elseif ($_FILES['files']['name']['project_upload']) { - $validators = array('file_validate_extensions' => array(archiver_get_extensions())); - $field = 'project_upload'; - if (!($finfo = file_save_upload($field, $validators, NULL, 0, FILE_EXISTS_REPLACE))) { - // Failed to upload the file. file_save_upload() calls - // drupal_set_message() on failure. - return; - } - $local_cache = $finfo->getFileUri(); - } - - $directory = _update_manager_extract_directory(); - try { - $archive = update_manager_archive_extract($local_cache, $directory); - } - catch (Exception $e) { - drupal_set_message($e->getMessage(), 'error'); - return; - } - - $files = $archive->listContents(); - if (!$files) { - drupal_set_message(t('Provided archive contains no files.'), 'error'); - return; - } - - // Unfortunately, we can only use the directory name to determine the project - // name. Some archivers list the first file as the directory (i.e., MODULE/) - // and others list an actual file (i.e., MODULE/README.TXT). - $project = strtok($files[0], '/\\'); - - $archive_errors = update_manager_archive_verify($project, $local_cache, $directory); - if (!empty($archive_errors)) { - drupal_set_message(array_shift($archive_errors), 'error'); - // @todo: Fix me in D8: We need a way to set multiple errors on the same - // form element and have all of them appear! - if (!empty($archive_errors)) { - foreach ($archive_errors as $error) { - drupal_set_message($error, 'error'); - } - } - return; - } - - // Make sure the Updater registry is loaded. - drupal_get_updaters(); - - $project_location = $directory . '/' . $project; - try { - $updater = Updater::factory($project_location); - } - catch (Exception $e) { - drupal_set_message($e->getMessage(), 'error'); - return; - } - - try { - $project_title = Updater::getProjectTitle($project_location); - } - catch (Exception $e) { - drupal_set_message($e->getMessage(), 'error'); - return; - } - - if (!$project_title) { - drupal_set_message(t('Unable to determine %project name.', array('%project' => $project)), 'error'); - } - - if ($updater->isInstalled()) { - drupal_set_message(t('%project is already installed.', array('%project' => $project_title)), 'error'); - return; - } - - $project_real_location = drupal_realpath($project_location); - $arguments = array( - 'project' => $project, - 'updater_name' => get_class($updater), - 'local_url' => $project_real_location, - ); - - // If the owner of the directory we extracted is the same as the - // owner of our configuration directory (e.g. sites/default) where we're - // trying to install the code, there's no need to prompt for FTP/SSH - // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local and - // invoke update_authorize_run_install() directly. - if (fileowner($project_real_location) == fileowner(conf_path())) { - module_load_include('inc', 'update', 'update.authorize'); - $filetransfer = new Local(DRUPAL_ROOT); - call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments)); - } - // Otherwise, go through the regular workflow to prompt for FTP/SSH - // credentials and invoke update_authorize_run_install() indirectly with - // whatever FileTransfer object authorize.php creates for us. - else { - system_authorized_init('update_authorize_run_install', drupal_get_path('module', 'update') . '/update.authorize.inc', $arguments, t('Update manager')); - $form_state['redirect'] = system_authorized_get_url(); - } -} - -/** * Unpacks a downloaded archive file. * * @param string $file @@ -903,8 +297,6 @@ function update_manager_batch_project_get($project, $url, &$context) { * @return * TRUE if local file transfers are allowed on this server, or FALSE if not. * - * @see update_manager_update_ready_form_submit() - * @see update_manager_install_form_submit() * @see install_check_requirements() */ function update_manager_local_transfers_allowed() { diff --git a/core/modules/update/update.module b/core/modules/update/update.module index 1dbfcf9..06f2dd6 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -172,10 +172,6 @@ function update_manager_access() { */ function update_theme() { return array( - 'update_manager_update_form' => array( - 'render element' => 'form', - 'file' => 'update.manager.inc', - ), 'update_last_check' => array( 'variables' => array('last' => 0), 'template' => 'update-last-check', diff --git a/core/modules/update/update.routing.yml b/core/modules/update/update.routing.yml index 2ed1b68..d3cf59a 100644 --- a/core/modules/update/update.routing.yml +++ b/core/modules/update/update.routing.yml @@ -25,7 +25,7 @@ update.manual_status: update.report_install: path: '/admin/reports/updates/install' defaults: - _content: '\Drupal\update\Form\UpdateForm::reportInstall' + _form: '\Drupal\update\Form\UpdateManagerInstall' _title: 'Install' options: _access_mode: 'ALL' @@ -36,7 +36,7 @@ update.report_install: update.report_update: path: '/admin/reports/updates/update' defaults: - _content: '\Drupal\update\Form\UpdateForm::reportUpdate' + _form: '\Drupal\update\Form\UpdateManagerUpdate' _title: 'Update' options: _access_mode: 'ALL' @@ -47,7 +47,7 @@ update.report_update: update.module_install: path: '/admin/modules/install' defaults: - _content: '\Drupal\update\Form\UpdateForm::moduleInstall' + _form: '\Drupal\update\Form\UpdateManagerInstall' _title: 'Install new module' options: _access_mode: 'ALL' @@ -58,7 +58,7 @@ update.module_install: update.module_update: path: '/admin/modules/update' defaults: - _content: '\Drupal\update\Form\UpdateForm::moduleUpdate' + _form: '\Drupal\update\Form\UpdateManagerUpdate' _title: 'Update' options: _access_mode: 'ALL' @@ -69,7 +69,7 @@ update.module_update: update.theme_install: path: '/admin/theme/install' defaults: - _content: '\Drupal\update\Form\UpdateForm::themeInstall' + _form: '\Drupal\update\Form\UpdateManagerInstall' _title: 'Install new theme' options: _access_mode: 'ALL' @@ -80,7 +80,7 @@ update.theme_install: update.theme_update: path: '/admin/theme/update' defaults: - _content: '\Drupal\update\Form\UpdateForm::themeUpdate' + _form: '\Drupal\update\Form\UpdateManagerUpdate' _title: 'Update' options: _access_mode: 'ALL' @@ -91,7 +91,7 @@ update.theme_update: update.confirmation_page: path: '/admin/update/ready' defaults: - _content: '\Drupal\update\Form\UpdateForm::confirmUpdates' + _form: '\Drupal\update\Form\UpdateReady' _title: 'Ready to update' options: _access_mode: 'ALL'