1.20.x update.fetch.inc _update_process_fetch_task(array $project)

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 into the {cache_update} table in an entry just for that project.

Parameters

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

Return value

TRUE if we fetched parsable XML, otherwise FALSE.:

File

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

Code

function _update_process_fetch_task(array $project) {
  global $base_url;
  $config = config('update.settings');
  $fail = &backdrop_static(__FUNCTION__, array());
  // This can be in the middle of a long-running batch, so REQUEST_TIME won't
  // necessarily be valid.
  $now = 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 from the cache.
    if (($cache = _update_cache_get('fetch_failures')) && ($cache->expire > $now)) {
      $fail = $cache->data;
    }
  }

  $max_fetch_attempts = $config->get('update_max_attempts');

  $success = FALSE;
  $response = NULL;
  $response_code = NULL;
  $available = array();
  $site_key = backdrop_hmac_base64($base_url, backdrop_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) {
    $response = backdrop_http_request($url);
    $response_code = (int) $response->code;
    if (isset($response->error)) {
      watchdog('update', 'HTTP request to @url failed with error: @error.', array('@url' => $url, '@error' => $response->error));
    }
    elseif (!isset($response->error) && isset($response->data)) {
      $data = $response->data;
    }
  }

  if ($response_code === 200 && !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;
    }
  }
  elseif ($response_code === 501) {
    $available['project_status'] = 'not-implemented';
  }
  else {
    $available['project_status'] = 'not-fetched';
    if (empty($fail[$fetch_url_base])) {
      $fail[$fetch_url_base] = 1;
    }
    else {
      $fail[$fetch_url_base]++;
    }
  }

  $frequency = $config->get('update_interval_days');
  $cid = 'available_releases::' . $project_name;
  _update_cache_set($cid, $available, $now + (60 * 60 * 24 * $frequency));

  // Stash the $fail data back in the DB for the next 5 minutes.
  _update_cache_set('fetch_failures', $fail, $now + (60 * 5));

  // Whether this worked or not, we did just (try to) check for updates.
  state_set('update_last_check', $now);

  // Now that we processed the fetch task for this project, clear out the
  // record in {cache_update} for this task so we're willing to fetch again.
  _update_cache_clear('fetch_task::' . $project_name);

  return $success;
}