class AutomaticUpdatesPsa in Automatic Updates 8
Class AutomaticUpdatesPsa.
Hierarchy
- class \Drupal\automatic_updates\Services\AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface uses DependencySerializationTrait, StringTranslationTrait
Expanded class hierarchy of AutomaticUpdatesPsa
1 string reference to 'AutomaticUpdatesPsa'
1 service uses AutomaticUpdatesPsa
File
- src/
Services/ AutomaticUpdatesPsa.php, line 20
Namespace
Drupal\automatic_updates\ServicesView source
class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
use StringTranslationTrait;
use DependencySerializationTrait;
/**
* This module's configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $config;
/**
* The http client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* The cache backend.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* The module extension list.
*
* @var \Drupal\Core\Extension\ExtensionList
*/
protected $module;
/**
* The profile extension list.
*
* @var \Drupal\Core\Extension\ExtensionList
*/
protected $profile;
/**
* The theme extension list.
*
* @var \Drupal\Core\Extension\ExtensionList
*/
protected $theme;
/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* AutomaticUpdatesPsa constructor.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
* @param \GuzzleHttp\Client $client
* The HTTP client.
* @param \Drupal\Core\Extension\ExtensionList $module
* The module extension list.
* @param \Drupal\Core\Extension\ExtensionList $profile
* The profile extension list.
* @param \Drupal\Core\Extension\ExtensionList $theme
* The theme extension list.
* @param \Psr\Log\LoggerInterface $logger
* The logger.
*/
public function __construct(ConfigFactoryInterface $config_factory, CacheBackendInterface $cache, TimeInterface $time, Client $client, ExtensionList $module, ExtensionList $profile, ExtensionList $theme, LoggerInterface $logger) {
$this->config = $config_factory
->get('automatic_updates.settings');
$this->cache = $cache;
$this->time = $time;
$this->httpClient = $client;
$this->module = $module;
$this->profile = $profile;
$this->theme = $theme;
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function getPublicServiceMessages() {
$messages = [];
if (!$this->config
->get('enable_psa')) {
return $messages;
}
if ($cache = $this->cache
->get('automatic_updates_psa')) {
$response = $cache->data;
}
else {
$psa_endpoint = $this->config
->get('psa_endpoint');
try {
$response = $this->httpClient
->get($psa_endpoint)
->getBody()
->getContents();
$this->cache
->set('automatic_updates_psa', $response, $this->time
->getCurrentTime() + $this->config
->get('check_frequency'));
} catch (TransferException $exception) {
$this->logger
->error($exception
->getMessage());
return [
$this
->t('Drupal PSA endpoint :url is unreachable.', [
':url' => $psa_endpoint,
]),
];
}
}
try {
$json_payload = json_decode($response, FALSE);
if ($json_payload !== NULL) {
foreach ($json_payload as $json) {
if ($json->is_psa && ($json->type === 'core' || $this
->isValidExtension($json->type, $json->project))) {
$messages[] = $this
->message($json->title, $json->link);
}
elseif ($json->type === 'core') {
$this
->parseConstraints($messages, $json, \Drupal::VERSION);
}
elseif ($this
->isValidExtension($json->type, $json->project)) {
$this
->contribParser($messages, $json);
}
}
}
else {
$this->logger
->error('Drupal PSA JSON is malformed: @response', [
'@response' => $response,
]);
$messages[] = $this
->t('Drupal PSA JSON is malformed.');
}
} catch (\UnexpectedValueException $exception) {
$this->logger
->error($exception
->getMessage());
$messages[] = $this
->t('Drupal PSA endpoint service is malformed.');
}
return $messages;
}
/**
* Determine if extension exists and has a version string.
*
* @param string $extension_type
* The extension type i.e. module, theme, profile.
* @param string $project_name
* The project.
*
* @return bool
* TRUE if extension exists, else FALSE.
*/
protected function isValidExtension($extension_type, $project_name) {
if (!property_exists($this, $extension_type)) {
$this->logger
->error('Extension list of type "%extension" does not exist.', [
'%extension' => $extension_type,
]);
return FALSE;
}
return $this->{$extension_type}
->exists($project_name) && !empty($this->{$extension_type}
->getAllAvailableInfo()[$project_name]['version']);
}
/**
* Parse contrib project JSON version strings.
*
* @param array $messages
* The messages array.
* @param object $json
* The JSON object.
*/
protected function contribParser(array &$messages, $json) {
$extension_version = $this->{$json->type}
->getAllAvailableInfo()[$json->project]['version'];
$json->insecure = array_filter(array_map(static function ($version) {
$version_array = explode('-', $version, 2);
if ($version_array && $version_array[0] === \Drupal::CORE_COMPATIBILITY) {
return isset($version_array[1]) ? $version_array[1] : NULL;
}
if (count($version_array) === 1) {
return $version_array[0];
}
if (count($version_array) === 2 && $version_array[1] === 'dev') {
return $version;
}
}, $json->insecure));
$version_array = explode('-', $extension_version, 2);
$extension_version = isset($version_array[1]) && $version_array[1] !== 'dev' ? $version_array[1] : $extension_version;
$this
->parseConstraints($messages, $json, $extension_version);
}
/**
* Compare versions and add a message, if appropriate.
*
* @param array $messages
* The messages array.
* @param object $json
* The JSON object.
* @param string $current_version
* The current extension version.
*
* @throws \UnexpectedValueException
*/
protected function parseConstraints(array &$messages, $json, $current_version) {
$version_string = implode('||', $json->insecure);
if (empty($version_string)) {
return;
}
$parser = new VersionParser();
$psa_constraint = $parser
->parseConstraints($version_string);
$contrib_constraint = $parser
->parseConstraints($current_version);
if ($psa_constraint
->matches($contrib_constraint)) {
$messages[] = $this
->message($json->title, $json->link);
}
}
/**
* Return a message.
*
* @param string $title
* The title.
* @param string $link
* The link.
*
* @return \Drupal\Component\Render\FormattableMarkup
* The PSA or SA message.
*/
protected function message($title, $link) {
return new FormattableMarkup('<a href=":url">:message</a>', [
':message' => $title,
':url' => $link,
]);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AutomaticUpdatesPsa:: |
protected | property | The cache backend. | |
AutomaticUpdatesPsa:: |
protected | property | This module's configuration. | |
AutomaticUpdatesPsa:: |
protected | property | The http client. | |
AutomaticUpdatesPsa:: |
protected | property | The logger. | |
AutomaticUpdatesPsa:: |
protected | property | The module extension list. | |
AutomaticUpdatesPsa:: |
protected | property | The profile extension list. | |
AutomaticUpdatesPsa:: |
protected | property | The theme extension list. | |
AutomaticUpdatesPsa:: |
protected | property | The time service. | |
AutomaticUpdatesPsa:: |
protected | function | Parse contrib project JSON version strings. | |
AutomaticUpdatesPsa:: |
public | function |
Get public service messages. Overrides AutomaticUpdatesPsaInterface:: |
|
AutomaticUpdatesPsa:: |
protected | function | Determine if extension exists and has a version string. | |
AutomaticUpdatesPsa:: |
protected | function | Return a message. | |
AutomaticUpdatesPsa:: |
protected | function | Compare versions and add a message, if appropriate. | |
AutomaticUpdatesPsa:: |
public | function | AutomaticUpdatesPsa constructor. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |