function _update_process_fetch_task

Processes a task to fetch available update data for a single project.

Once the release history XML data is downloaded, it is parsed and saved in an entry just for that project.

Parameters

$project: Associative array of information about the project to fetch data for.

Return value

TRUE if we fetched parsable XML, otherwise FALSE.

2 calls to _update_process_fetch_task()
update_fetch_data_batch in drupal/core/modules/update/update.fetch.inc
Batch callback: Processes a step in batch for fetching available update data.
_update_fetch_data in drupal/core/modules/update/update.fetch.inc
Attempts to drain the queue of tasks for release history data to fetch.

File

drupal/core/modules/update/update.fetch.inc, line 132
Code required only when fetching information about available updates.

Code

function _update_process_fetch_task($project) {
  global $base_url;
  $update_config = config('update.settings');
  $fail =& drupal_static(__FUNCTION__, array());

  // This can be in the middle of a long-running batch, so REQUEST_TIME won't
  // necessarily be valid.
  $request_time_difference = time() - REQUEST_TIME;
  if (empty($fail)) {

    // If we have valid data about release history XML servers that we have
    // failed to fetch from on previous attempts, load that.
    $fail = Drupal::keyValueExpirable('update')
      ->get('fetch_failures');
  }
  $max_fetch_attempts = $update_config
    ->get('fetch.max_attempts');
  $success = FALSE;
  $available = array();
  $site_key = Crypt::hmacBase64($base_url, drupal_get_private_key());
  $url = _update_build_fetch_url($project, $site_key);
  $fetch_url_base = _update_get_fetch_url_base($project);
  $project_name = $project['name'];
  if (empty($fail[$fetch_url_base]) || $fail[$fetch_url_base] < $max_fetch_attempts) {
    try {
      $data = Drupal::httpClient()
        ->get($url, array(
        'Accept' => 'text/xml',
      ))
        ->send()
        ->getBody(TRUE);
    } catch (RequestException $exception) {
      watchdog_exception('update', $exception);
    }
  }
  if (!empty($data)) {
    $available = update_parse_xml($data);

    // @todo: Purge release data we don't need (http://drupal.org/node/238950).
    if (!empty($available)) {

      // Only if we fetched and parsed something sane do we return success.
      $success = TRUE;
    }
  }
  else {
    $available['project_status'] = 'not-fetched';
    if (empty($fail[$fetch_url_base])) {
      $fail[$fetch_url_base] = 1;
    }
    else {
      $fail[$fetch_url_base]++;
    }
  }
  $frequency = $update_config
    ->get('check.interval_days');
  $available['last_fetch'] = REQUEST_TIME + $request_time_difference;
  Drupal::keyValueExpirable('update_available_releases')
    ->setWithExpire($project_name, $available, $request_time_difference + 60 * 60 * 24 * $frequency);

  // Stash the $fail data back in the DB for the next 5 minutes.
  Drupal::keyValueExpirable('update')
    ->setWithExpire('fetch_failures', $fail, $request_time_difference + 60 * 5);

  // Whether this worked or not, we did just (try to) check for updates.
  Drupal::state()
    ->set('update.last_check', REQUEST_TIME + $request_time_difference);

  // Now that we processed the fetch task for this project, clear out the
  // record for this task so we're willing to fetch again.
  drupal_container()
    ->get('keyvalue')
    ->get('update_fetch_task')
    ->delete($project_name);
  return $success;
}