UpdateFetcher.php 3.19 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\update\UpdateFetcher.
 */

namespace Drupal\update;

10
use Drupal\Core\Config\ConfigFactoryInterface;
11
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
12 13
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
14 15 16 17

/**
 * Fetches project information from remote locations.
 */
18
class UpdateFetcher implements UpdateFetcherInterface {
19

20 21
  use DependencySerializationTrait;

22 23 24 25 26 27 28 29 30 31 32 33
  /**
   * URL to check for updates, if a given project doesn't define its own.
   */
  const UPDATE_DEFAULT_URL = 'http://updates.drupal.org/release-history';

  /**
   * The fetch url configured in the update settings.
   *
   * @var string
   */
  protected $fetchUrl;

34 35 36 37 38 39 40
  /**
   * The update settings
   *
   * @var \Drupal\Core\Config\Config
   */
  protected $updateSettings;

41 42 43
  /**
   * The HTTP client to fetch the feed data with.
   *
44
   * @var \GuzzleHttp\ClientInterface
45 46 47 48 49 50
   */
  protected $httpClient;

  /**
   * Constructs a UpdateFetcher.
   *
51
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
52
   *   The config factory.
53
   * @param \GuzzleHttp\ClientInterface $http_client
54 55
   *   A Guzzle client object.
   */
56
  public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client) {
57 58
    $this->fetchUrl = $config_factory->get('update.settings')->get('fetch.url');
    $this->httpClient = $http_client;
59
    $this->updateSettings = $config_factory->get('update.settings');
60 61 62
  }

  /**
63
   * {@inheritdoc}
64 65 66 67 68
   */
  public function fetchProjectData(array $project, $site_key = '') {
    $url = $this->buildFetchUrl($project, $site_key);
    $data = '';
    try {
69
      $data = (string) $this->httpClient
70
        ->get($url, array('headers' => array('Accept' => 'text/xml')))
71
        ->getBody();
72 73 74 75 76 77 78 79
    }
    catch (RequestException $exception) {
      watchdog_exception('update', $exception);
    }
    return $data;
  }

  /**
80
   * {@inheritdoc}
81 82 83 84 85 86
   */
  public function buildFetchUrl(array $project, $site_key = '') {
    $name = $project['name'];
    $url = $this->getFetchBaseUrl($project);
    $url .= '/' . $name . '/' . \Drupal::CORE_COMPATIBILITY;

87
    // Only append usage information if we have a site key and the project is
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    // enabled. We do not want to record usage statistics for disabled projects.
    if (!empty($site_key) && (strpos($project['project_type'], 'disabled') === FALSE)) {
      // Append the site key.
      $url .= (strpos($url, '?') !== FALSE) ? '&' : '?';
      $url .= 'site_key=';
      $url .= rawurlencode($site_key);

      // Append the version.
      if (!empty($project['info']['version'])) {
        $url .= '&version=';
        $url .= rawurlencode($project['info']['version']);
      }

      // Append the list of modules or themes enabled.
      $list = array_keys($project['includes']);
      $url .= '&list=';
      $url .= rawurlencode(implode(',', $list));
    }
    return $url;
  }

  /**
110
   * {@inheritdoc}
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
   */
  public function getFetchBaseUrl($project) {
    if (isset($project['info']['project status url'])) {
      $url = $project['info']['project status url'];
    }
    else {
      $url = $this->fetchUrl;
      if (empty($url)) {
        $url = static::UPDATE_DEFAULT_URL;
      }
    }
    return $url;
  }

}