Chris@0: moduleHandler = $module_handler; Chris@0: $this->state = $state; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getFormId() { Chris@0: return 'update_manager_update_form'; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function create(ContainerInterface $container) { Chris@0: return new static( Chris@0: $container->get('module_handler'), Chris@0: $container->get('state') Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function buildForm(array $form, FormStateInterface $form_state) { Chris@0: $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); Chris@0: Chris@0: $last_markup = [ Chris@0: '#theme' => 'update_last_check', Chris@0: '#last' => $this->state->get('update.last_check') ?: 0, Chris@0: ]; Chris@0: $form['last_check'] = [ Chris@0: '#markup' => \Drupal::service('renderer')->render($last_markup), Chris@0: ]; Chris@0: Chris@0: if (!_update_manager_check_backends($form, 'update')) { Chris@0: return $form; Chris@0: } Chris@0: Chris@0: $available = update_get_available(TRUE); Chris@0: if (empty($available)) { Chris@0: $form['message'] = [ Chris@0: '#markup' => $this->t('There was a problem getting update information. Try again later.'), Chris@0: ]; Chris@0: return $form; Chris@0: } Chris@0: Chris@0: $form['#attached']['library'][] = 'update/drupal.update.admin'; Chris@0: Chris@0: // This will be a nested array. The first key is the kind of project, which Chris@0: // can be either 'enabled', 'disabled', 'manual' (projects which require Chris@0: // manual updates, such as core). Then, each subarray is an array of Chris@0: // projects of that type, indexed by project short name, and containing an Chris@0: // array of data for cells in that project's row in the appropriate table. Chris@0: $projects = []; Chris@0: Chris@0: // This stores the actual download link we're going to update from for each Chris@0: // project in the form, regardless of if it's enabled or disabled. Chris@0: $form['project_downloads'] = ['#tree' => TRUE]; Chris@0: $this->moduleHandler->loadInclude('update', 'inc', 'update.compare'); Chris@0: $project_data = update_calculate_project_data($available); Chris@0: foreach ($project_data as $name => $project) { Chris@0: // Filter out projects which are up to date already. Chris@0: if ($project['status'] == UPDATE_CURRENT) { Chris@0: continue; Chris@0: } Chris@0: // The project name to display can vary based on the info we have. Chris@0: if (!empty($project['title'])) { Chris@0: if (!empty($project['link'])) { Chris@0: $project_name = $this->l($project['title'], Url::fromUri($project['link'])); Chris@0: } Chris@0: else { Chris@0: $project_name = $project['title']; Chris@0: } Chris@0: } Chris@0: elseif (!empty($project['info']['name'])) { Chris@0: $project_name = $project['info']['name']; Chris@0: } Chris@0: else { Chris@0: $project_name = $name; Chris@0: } Chris@0: if ($project['project_type'] == 'theme' || $project['project_type'] == 'theme-disabled') { Chris@0: $project_name .= ' ' . $this->t('(Theme)'); Chris@0: } Chris@0: Chris@0: if (empty($project['recommended'])) { Chris@0: // If we don't know what to recommend they upgrade to, we should skip Chris@0: // the project entirely. Chris@0: continue; Chris@0: } Chris@0: Chris@0: $recommended_release = $project['releases'][$project['recommended']]; Chris@0: $recommended_version = '{{ release_version }} ({{ release_notes }})'; Chris@0: if ($recommended_release['version_major'] != $project['existing_major']) { Chris@0: $recommended_version .= '
' . $this->t('Automatic updates of Drupal core are not supported at this time.') . '
'; Chris@0: $form['manual_updates'] = [ Chris@0: '#type' => 'table', Chris@0: '#header' => $headers, Chris@0: '#rows' => $projects['manual'], Chris@0: '#prefix' => $prefix, Chris@0: '#weight' => 120, Chris@0: ]; Chris@0: } Chris@0: Chris@0: return $form; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function validateForm(array &$form, FormStateInterface $form_state) { Chris@0: if (!$form_state->isValueEmpty('projects')) { Chris@0: $enabled = array_filter($form_state->getValue('projects')); Chris@0: } Chris@0: if (!$form_state->isValueEmpty('disabled_projects')) { Chris@0: $disabled = array_filter($form_state->getValue('disabled_projects')); Chris@0: } Chris@0: if (empty($enabled) && empty($disabled)) { Chris@0: $form_state->setErrorByName('projects', $this->t('You must select at least one project to update.')); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function submitForm(array &$form, FormStateInterface $form_state) { Chris@0: $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); Chris@0: $projects = []; Chris@0: foreach (['projects', 'disabled_projects'] as $type) { Chris@0: if (!$form_state->isValueEmpty($type)) { Chris@0: $projects = array_merge($projects, array_keys(array_filter($form_state->getValue($type)))); Chris@0: } Chris@0: } Chris@0: $operations = []; Chris@0: foreach ($projects as $project) { Chris@0: $operations[] = [ Chris@0: 'update_manager_batch_project_get', Chris@0: [ Chris@0: $project, Chris@0: $form_state->getValue(['project_downloads', $project]), Chris@0: ], Chris@0: ]; Chris@0: } Chris@0: $batch = [ Chris@0: 'title' => $this->t('Downloading updates'), Chris@0: 'init_message' => $this->t('Preparing to download selected updates'), Chris@0: 'operations' => $operations, Chris@0: 'finished' => 'update_manager_download_batch_finished', Chris@0: 'file' => drupal_get_path('module', 'update') . '/update.manager.inc', Chris@0: ]; Chris@0: batch_set($batch); Chris@0: } Chris@0: Chris@0: }