engine_type = $type; $this->engine = $engine; $this->engine_config = $config; } /** * {@inheritdoc} */ function lastCheck() { $last_check = \Drupal::state()->get('update.last_check') ?: 0; return $last_check; } /** * {@inheritdoc} */ function refresh() { update_refresh(); } /** * Perform adjustments before running get status. * * - Enforce check-disabled option on update module. */ function beforeGetStatus(&$projects, $check_disabled) { // If check-disabled option was provided, alter Drupal settings temporarily. // There's no other way to hook into this. if (!is_null($check_disabled)) { $config = \Drupal::config('update.settings'); $this->update_check_disabled = $config->get('check.disabled_extensions'); $config->set('check.disabled_extensions', (bool)$check_disabled); } } /** * Get update information for all installed projects. * * @return * Array of update status information. */ function getStatus($projects, $check_disabled) { $this->beforeGetStatus($projects, $check_disabled); $available = $this->getAvailableReleases(); $update_info = $this->calculateUpdateStatus($available, $projects); $this->afterGetStatus($update_info, $projects, $check_disabled); return $update_info; } /** * Perform adjustments after running get status. * * - Restore check-disabled setting in update module. * - Adjust project type for disabled projects. */ function afterGetStatus(&$update_info, $projects, $check_disabled) { // Restore Drupal settings. if (!is_null($check_disabled)) { \Drupal::config('update.settings')->set('check.disabled_extensions', $this->update_check_disabled); unset($this->update_check_disabled); } // update.module sets a different project type // for disabled projects. Here we normalize it. if ($check_disabled) { foreach ($update_info as $key => $project) { if (in_array($project['project_type'], array('module-disabled', 'theme-disabled'))) { $update_info[$key]['project_type'] = substr($project['project_type'], 0, strpos($project['project_type'], '-')); } } } } /** * Obtains release info for all installed projects via update.module. * * @see update_get_available(). * @see \Drupal\update\Controller\UpdateController::updateStatusManually() */ protected function getAvailableReleases() { // Force to invalidate some caches that are only cleared // when visiting update status report page. This allow to detect changes in // .info.yml files. \Drupal::keyValueExpirable('update')->deleteMultiple(array('update_project_projects', 'update_project_data')); // From update_get_available(): Iterate all projects and create a fetch task // for those we have no information or is obsolete. $available = \Drupal::keyValueExpirable('update_available_releases')->getAll(); $update_projects = \Drupal::service('update.manager')->getProjects(); foreach ($update_projects as $key => $project) { if (empty($available[$key])) { \Drupal::service('update.processor')->createFetchTask($project); continue; } if ($project['info']['_info_file_ctime'] > $available[$key]['last_fetch']) { $available[$key]['fetch_status'] = UPDATE_FETCH_PENDING; } if (empty($available[$key]['releases'])) { $available[$key]['fetch_status'] = UPDATE_FETCH_PENDING; } if (!empty($available[$key]['fetch_status']) && $available[$key]['fetch_status'] == UPDATE_FETCH_PENDING) { \Drupal::service('update.processor')->createFetchTask($project); } } // Set a batch to process all pending tasks. $batch = array( 'operations' => array( array(array(\Drupal::service('update.manager'), 'fetchDataBatch'), array()), ), 'finished' => 'update_fetch_data_finished', 'file' => drupal_get_path('module', 'update') . '/update.fetch.inc', ); batch_set($batch); drush_backend_batch_process(); // Clear any error set by a failed update fetch task. This avoid rollbacks. drush_clear_error(); return \Drupal::keyValueExpirable('update_available_releases')->getAll(); } /** * Calculates update status for all projects via update.module. */ protected function calculateUpdateStatus($available, $projects) { module_load_include('inc', 'update', 'update.compare'); $data = update_calculate_project_data($available); foreach ($data as $project_name => $project) { // Discard custom projects. if ($project['status'] == UPDATE_UNKNOWN) { unset($data[$project_name]); continue; } // Discard projects with unknown installation path. if ($project_name != 'drupal' && !isset($projects[$project_name]['path'])) { unset($data[$project_name]); continue; } // Add some info from the project to $data. $data[$project_name] += array( 'path' => isset($projects[$project_name]['path']) ? $projects[$project_name]['path'] : '', 'label' => $projects[$project_name]['label'], ); // Store all releases, not just the ones selected by update.module. // We use it to allow the user to update to a specific version. if (isset($available[$project_name]['releases'])) { $data[$project_name]['releases'] = $available[$project_name]['releases']; } } return $data; } }