UpdateFetcher.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Drupal\update;
  3. use Drupal\Core\Config\ConfigFactoryInterface;
  4. use Drupal\Core\DependencyInjection\DependencySerializationTrait;
  5. use GuzzleHttp\ClientInterface;
  6. use GuzzleHttp\Exception\RequestException;
  7. /**
  8. * Fetches project information from remote locations.
  9. */
  10. class UpdateFetcher implements UpdateFetcherInterface {
  11. use DependencySerializationTrait;
  12. /**
  13. * URL to check for updates, if a given project doesn't define its own.
  14. */
  15. const UPDATE_DEFAULT_URL = 'http://updates.drupal.org/release-history';
  16. /**
  17. * The fetch url configured in the update settings.
  18. *
  19. * @var string
  20. */
  21. protected $fetchUrl;
  22. /**
  23. * The update settings
  24. *
  25. * @var \Drupal\Core\Config\Config
  26. */
  27. protected $updateSettings;
  28. /**
  29. * The HTTP client to fetch the feed data with.
  30. *
  31. * @var \GuzzleHttp\ClientInterface
  32. */
  33. protected $httpClient;
  34. /**
  35. * Constructs a UpdateFetcher.
  36. *
  37. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
  38. * The config factory.
  39. * @param \GuzzleHttp\ClientInterface $http_client
  40. * A Guzzle client object.
  41. */
  42. public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client) {
  43. $this->fetchUrl = $config_factory->get('update.settings')->get('fetch.url');
  44. $this->httpClient = $http_client;
  45. $this->updateSettings = $config_factory->get('update.settings');
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function fetchProjectData(array $project, $site_key = '') {
  51. $url = $this->buildFetchUrl($project, $site_key);
  52. $data = '';
  53. try {
  54. $data = (string) $this->httpClient
  55. ->get($url, ['headers' => ['Accept' => 'text/xml']])
  56. ->getBody();
  57. }
  58. catch (RequestException $exception) {
  59. watchdog_exception('update', $exception);
  60. }
  61. return $data;
  62. }
  63. /**
  64. * {@inheritdoc}
  65. */
  66. public function buildFetchUrl(array $project, $site_key = '') {
  67. $name = $project['name'];
  68. $url = $this->getFetchBaseUrl($project);
  69. $url .= '/' . $name . '/' . \Drupal::CORE_COMPATIBILITY;
  70. // Only append usage information if we have a site key and the project is
  71. // enabled. We do not want to record usage statistics for disabled projects.
  72. if (!empty($site_key) && (strpos($project['project_type'], 'disabled') === FALSE)) {
  73. // Append the site key.
  74. $url .= (strpos($url, '?') !== FALSE) ? '&' : '?';
  75. $url .= 'site_key=';
  76. $url .= rawurlencode($site_key);
  77. // Append the version.
  78. if (!empty($project['info']['version'])) {
  79. $url .= '&version=';
  80. $url .= rawurlencode($project['info']['version']);
  81. }
  82. // Append the list of modules or themes enabled.
  83. $list = array_keys($project['includes']);
  84. $url .= '&list=';
  85. $url .= rawurlencode(implode(',', $list));
  86. }
  87. return $url;
  88. }
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function getFetchBaseUrl($project) {
  93. if (isset($project['info']['project status url'])) {
  94. $url = $project['info']['project status url'];
  95. }
  96. else {
  97. $url = $this->fetchUrl;
  98. if (empty($url)) {
  99. $url = static::UPDATE_DEFAULT_URL;
  100. }
  101. }
  102. return $url;
  103. }
  104. }