- 8.x-3.x src/Plugin/Provider/ProviderBase.php
- 7.x-3.x includes/cdn/ProviderBase.php
Namespace
Drupal\bootstrap\Plugin\Provider
- <?php
-
- namespace Drupal\bootstrap\Plugin\Provider;
-
- use Drupal\bootstrap\Bootstrap;
- use Drupal\bootstrap\Plugin\PluginBase;
- use Drupal\bootstrap\Plugin\ProviderManager;
- use Drupal\bootstrap\Utility\Crypt;
- use Drupal\bootstrap\Utility\Unicode;
- use Drupal\Component\Serialization\Json;
- use Drupal\Component\Utility\NestedArray;
-
- * CDN Provider base class.
- *
- * @ingroup plugins_provider
- */
- class ProviderBase extends PluginBase implements ProviderInterface {
-
-
- * The currently set assets.
- *
- * @var array
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- protected $assets = [];
-
-
- * The cache backend used for storing various permanent CDN Provider data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
- */
- protected $keyValue;
-
-
- * The cache backend used for storing various expirable CDN Provider data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
- */
- protected $keyValueExpirable;
-
-
- * The cache TTL values, in seconds, keyed by type.
- *
- * @var int[]
- *
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderInterface
- */
- protected $cacheTtl = [];
-
-
- * The currently set CDN assets, keyed by a hash identifier.
- *
- * @var \Drupal\bootstrap\Plugin\Provider\CdnAssets[]
- */
- protected $cdnAssets;
-
-
- * A list of currently set Exception objects.
- *
- * @var \Drupal\bootstrap\Plugin\Provider\ProviderException[]
- */
- protected $cdnExceptions = [];
-
-
- * The versions supplied by the CDN Provider.
- *
- * @var array
- */
- protected $versions;
-
-
- * The themes supplied by the CDN Provider, keyed by version.
- *
- * @var array[]
- */
- protected $themes = [];
-
-
- * Adds a new CDN Provider exception.
- *
- * @param \Throwable $exception
- * The exception message.
- */
- protected function addCdnException(\Throwable $exception) {
- $this->cdnExceptions[] = new ProviderException($this, $exception->getMessage(), $exception->getCode(), $exception);
- }
-
-
- * {@inheritdoc}
- *
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderBase::getCdnAssetsCacheData()
- */
- public function alterFrameworkLibrary(array &$framework) {
-
-
-
-
-
-
-
- $data = $this->getCdnAssetsCacheData();
- $hash = Crypt::generateBase64HashIdentifier($data);
-
-
- $framework = $this->cacheGet('library', $hash, [], function () use ($framework, $data) {
- $version = isset($data['version']) ? $data['version'] : NULL;
- $theme = isset($data['theme']) ? $data['theme'] : NULL;
- $assets = $this->getCdnAssets($version, $theme)->toLibraryArray($data['min']);
-
-
- if (empty($assets)) {
- return $framework;
- }
-
-
- if (isset($data['version'])) {
- $framework['version'] = $data['version'];
- }
-
-
- $styles = [];
- if ($this->theme->getSetting('cdn_styles', TRUE)) {
- $stylesProvider = ProviderManager::load($this->theme, 'drupal_bootstrap_styles');
- $styles = $stylesProvider->getCdnAssets($version, $theme)->toLibraryArray($data['min']);
- }
-
-
- return NestedArray::mergeDeepArray([$assets, $styles, $framework], TRUE);
- });
- }
-
-
- * Retrieves a value from the CDN Provider cache.
- *
- * @param string $type
- * The type of cache item to retrieve.
- * @param string $key
- * Optional. A specific key of the item to retrieve. Note: this can be in
- * the form of dot notation if the value is nested in an array. If not
- * provided, the entire contents of $name will be returned.
- * @param mixed $default
- * Optional. The default value to return if $key is not set.
- * @param callable $builder
- * Optional. If provided, a builder will be invoked when there is no cache
- * currently set. The return value of the build will be used to set the
- * cached value, provided there are no CDN Provider exceptions generated.
- * If there are, but you still need the cache to be set, reset them prior
- * to returning from the builder callback.
- *
- * @return mixed
- * The cached value if it's set or the value supplied to $default if not.
- */
- protected function cacheGet($type, $key = NULL, $default = NULL, callable $builder = NULL) {
- $ttl = $this->getCacheTtl($type);
- $never = $ttl === static::TTL_NEVER;
- $forever = $ttl === static::TTL_FOREVER;
- $cache = $forever ? $this->getKeyValue() : $this->getKeyValueExpirable();
-
- $data = $cache->get($type, []);
-
- if (!isset($key)) {
- return $data;
- }
-
- $parts = Unicode::splitDelimiter($key);
- $value = NestedArray::getValue($data, $parts, $key_exists);
-
-
- if (!$key_exists && $builder) {
- $value = $builder($default);
- if (!isset($value)) {
- $value = $default;
- }
- NestedArray::setValue($data, $parts, $value);
-
-
- if (!$this->cdnExceptions && !$never) {
- if ($forever) {
- $cache->set($type, $data);
- }
- else {
- $cache->setWithExpire($type, $data, $ttl);
- }
- }
-
- return $value;
- }
-
- return $key_exists ? $value : $default;
- }
-
-
- * Discovers the assets supported by the CDN Provider.
- *
- * CDN Providers should sub-class this method to make requests and/or process
- * any necessary data.
- *
- * @param string $version
- * The version of assets to return.
- * @param string $theme
- * A specific set of themed assets to return, if any.
- *
- * @return \Drupal\bootstrap\Plugin\Provider\CdnAssets
- * A CdnAssets object.
- */
- protected function discoverCdnAssets($version, $theme = NULL) {
- $assets = [];
-
-
- $data = $this->getAssets();
- foreach (['css', 'js'] as $type) {
- if (isset($data[$type])) {
- foreach ($data[$type] as $file) {
- $assets[] = new CdnAsset($file, NULL, $version);
- }
- }
- if (isset($data['min'][$type])) {
- foreach ($data['min'][$type] as $file) {
- $assets[] = new CdnAsset($file, NULL, $version);
- }
- }
- }
-
- return new CdnAssets($assets);
- }
-
-
- * Discovers the themes supported by the CDN Provider.
- *
- * CDN Providers should sub-class this method to make requests and/or process
- * any necessary data.
- *
- * @param string $version
- * A specific version of themes to retrieve.
- *
- * @return array|false
- * An associative array of theme data, similar to what is returned in
- * \Drupal\bootstrap\Plugin\Provider\ProviderBase::discoverCdnAssets(), but
- * keyed by the theme name.
- */
- protected function discoverCdnThemes($version) {
- return [];
- }
-
-
- * Discovers the versions supported by the CDN Provider.
- *
- * CDN Providers should sub-class this method to make requests and/or process
- * any necessary data.
- *
- * @return array|false
- * An associative array of versions, also keyed by the version.
- */
- protected function discoverCdnVersions() {
- return [];
- }
-
-
- * {@inheritdoc}
- */
- public function getCacheTtl($type) {
- if (!isset($this->cacheTtl[$type])) {
- $this->cacheTtl[$type] = (int) $this->theme->getSetting("cdn_cache_ttl_$type", static::TTL_NEVER);
-
- if ($this->cacheTtl[$type] === static::TTL_FOREVER) {
- $this->cacheTtl[$type] = static::TTL_ONE_YEAR * 10;
- }
- }
- return $this->cacheTtl[$type];
- }
-
-
- * Retrieves the unique cache identifier for the CDN Provider.
- *
- * @return string
- * The CDN Provider cache identifier.
- */
- protected function getCacheId() {
- return "theme:{$this->theme->getName()}:cdn:{$this->getPluginId()}";
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnAssets($version = NULL, $theme = NULL) {
- if (!isset($this->cdnAssets)) {
- $this->cdnAssets = $this->cacheGet('assets');
- }
-
- $data = $this->getCdnAssetsCacheData($version, $theme);
- $hash = Crypt::generateBase64HashIdentifier($data);
- if (!isset($this->cdnAssets[$hash])) {
- $this->cdnAssets[$hash] = $this->cacheGet('assets', $hash, [], function () use ($data) {
- return $this->discoverCdnAssets($data['version'], $data['theme']);
- });
- }
-
- return $this->cdnAssets[$hash];
- }
-
-
- * Retrieves the data used to create a hash for CDN Assets.
- *
- * @param string $version
- * Optional. A specific version to use.
- * @param string $theme
- * Optional. A specific theme to use.
- *
- * @return array
- * An array of components that will be serialized and hashed.
- *
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderBase::getCdnAssets()
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderBase::alterFrameworkLibrary()
- */
- protected function getCdnAssetsCacheData($version = NULL, $theme = NULL) {
- if (!isset($version) && $this->supportsVersions()) {
- $version = $this->getCdnVersion();
- }
- if (!isset($theme) && $this->supportsThemes()) {
- $theme = $this->getCdnTheme();
- }
- return [
- 'ttl' => $this->getCacheTtl(static::CACHE_LIBRARY),
- 'min' => [
- 'css' => !!\Drupal::config('system.performance')->get('css.preprocess'),
- 'js' => !!\Drupal::config('system.performance')->get('js.preprocess'),
- ],
- 'provider' => $this->pluginId,
- 'version' => $version,
- 'theme' => $theme,
- ];
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnExceptions($reset = TRUE) {
- $exceptions = $this->cdnExceptions;
- if ($reset) {
- $this->cdnExceptions = [];
- }
- return $exceptions;
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnTheme() {
- return $this->supportsThemes() ? $this->theme->getSetting('cdn_theme', 'bootstrap') : NULL;
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnThemes($version = NULL) {
-
- if (!$this->supportsThemes()) {
- return [];
- }
-
- $data = $this->getCdnThemesCacheData($version);
- $hash = Crypt::generateBase64HashIdentifier($data);
- if (!isset($this->themes[$hash])) {
- $this->themes[$hash] = $this->cacheGet('themes', $hash, [], function () use ($data) {
- return $this->discoverCdnThemes($data['version']);
- });
- }
-
- return $this->themes[$hash];
- }
-
-
- * Retrieves the data used to create a hash for CDN Themes.
- *
- * @param string $version
- * Optional. A specific version to use. If not set, the
- * currently set CDN version of the active theme will be used.
- *
- * @return array
- * An array of components that will be serialized and hashed.
- *
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderBase::getCdnThemes()
- */
- protected function getCdnThemesCacheData($version = NULL) {
- if (!isset($version) && $this->supportsVersions()) {
- $version = $this->getCdnVersion();
- }
- return [
- 'ttl' => $this->getCacheTtl(static::CACHE_THEMES),
- 'provider' => $this->pluginId,
- 'version' => $version,
- ];
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnVersion() {
- return $this->supportsVersions() ? $this->theme->getSetting('cdn_version', Bootstrap::FRAMEWORK_VERSION) : NULL;
- }
-
-
- * {@inheritdoc}
- */
- public function getCdnVersions() {
-
- if (!$this->supportsVersions()) {
- return [];
- }
-
- if (!isset($this->versions)) {
- $hash = Crypt::generateBase64HashIdentifier($this->getCdnVersionsCacheData());
- $this->versions = $this->cacheGet('versions', $hash, [], function () {
- return $this->discoverCdnVersions();
- });
- }
- return $this->versions;
- }
-
-
- * Retrieves the data used to create a hash for CDN Versions.
- *
- * @return array
- * An array of components that will be serialized and hashed.
- *
- * @see \Drupal\bootstrap\Plugin\Provider\ProviderBase::getCdnVersions()
- */
- protected function getCdnVersionsCacheData() {
- return [
- 'ttl' => $this->getCacheTtl(static::CACHE_THEMES),
- 'provider' => $this->pluginId,
- ];
- }
-
-
- * {@inheritdoc}
- */
- public function getDescription() {
- return $this->pluginDefinition['description'];
- }
-
-
- * Retrieves a permanent key/value storage instance.
- *
- * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface
- * A permanent key/value storage instance.
- */
- protected function getKeyValue() {
- if (!isset($this->keyValue)) {
- $this->keyValue = \Drupal::keyValue($this->getCacheId());
- }
- return $this->keyValue;
- }
-
-
- * Retrieves a expirable key/value storage instance.
- *
- * @return \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
- * An expirable key/value storage instance.
- */
- protected function getKeyValueExpirable() {
- if (!isset($this->keyValueExpirable)) {
- $this->keyValueExpirable = \Drupal::keyValueExpirable($this->getCacheId());
- }
- return $this->keyValueExpirable;
- }
-
-
- * {@inheritdoc}
- */
- public function getLabel() {
- return $this->pluginDefinition['label'] ?: $this->getPluginId();
- }
-
-
- * {@inheritdoc}
- */
- public function getThemes() {
- return $this->pluginDefinition['themes'];
- }
-
-
- * {@inheritdoc}
- */
- public function getVersions() {
- return $this->pluginDefinition['versions'];
- }
-
-
- * Allows providers a way to map a version to a different version.
- *
- * @param string $version
- * The version to map.
- *
- * @return string
- * The mapped version.
- */
- protected function mapVersion($version) {
- return $version;
- }
-
-
- * Initiates an HTTP request.
- *
- * @param string $url
- * The URL to retrieve.
- * @param array $options
- * The options to pass to the HTTP client.
- *
- * @return \Drupal\bootstrap\SerializedResponse
- * A SerializedResponse object.
- */
- protected function request($url, array $options = []) {
- $response = Bootstrap::request($url, $options, $exception);
- if ($exception) {
- $this->addCdnException($exception);
- }
- return $response;
- }
-
-
- * {@inheritdoc}
- */
- public function resetCache() {
- $this->getKeyValue()->deleteAll();
- $this->getKeyValueExpirable()->deleteAll();
-
-
- if ($this->theme->getCdnProvider()->getPluginId() === $this->pluginId) {
-
- $invalidator = \Drupal::service('cache_tags.invalidator');
- $invalidator->invalidateTags(['library_info']);
- }
- }
-
-
- * Sets CDN Provider exceptions, replacing any existing exceptions.
- *
- * @param \Throwable[] $exceptions
- * The Exceptions to set.
- *
- * @return static
- */
- protected function setCdnExceptions(array $exceptions) {
- $this->cdnExceptions = [];
- foreach ($exceptions as $exception) {
- $this->addCdnException($exception);
- }
- return $this;
- }
-
-
- * {@inheritdoc}
- */
- public function supportsThemes() {
- return TRUE;
- }
-
-
- * {@inheritdoc}
- */
- public function supportsVersions() {
- return TRUE;
- }
-
-
- * {@inheritdoc}
- */
- public function trackCdnExceptions(callable $callable) {
-
- $existing = $this->getCdnExceptions();
-
-
- $callable($this);
-
-
- $new = $this->getCdnExceptions();
-
-
- $this->setCdnExceptions(array_merge($existing, $new));
-
-
- return $new;
- }
-
-
- *
- * Deprecated methods
- *
- ***************************************************************************/
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function getApi() {
- Bootstrap::deprecated();
- return $this->pluginDefinition['api'];
- }
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function getAssets($types = NULL) {
- Bootstrap::deprecated();
- return $this->assets;
- }
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function hasError() {
- Bootstrap::deprecated();
- return $this->pluginDefinition['error'];
- }
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function isImported() {
- Bootstrap::deprecated();
- return $this->pluginDefinition['imported'];
- }
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function processDefinition(array &$definition, $plugin_id) {
-
-
- Bootstrap::deprecated(FALSE);
-
-
- if ($api = $this->getApi()) {
- $provider_path = ProviderManager::FILE_PATH;
-
-
- $options = 1 | 2;
- if ($fileSystem = Bootstrap::fileSystem('prepareDirectory')) {
- $fileSystem->prepareDirectory($provider_path, $options);
- }
- else {
- file_prepare_directory($provider_path, $options);
- }
-
-
- if (file_exists("$provider_path/$plugin_id.json") && ($imported_data = file_get_contents("$provider_path/$plugin_id.json"))) {
- $definition['imported'] = TRUE;
- try {
- $json = Json::decode($imported_data);
- }
- catch (\Exception $e) {
-
- }
- }
-
-
- else {
- $json = Bootstrap::request($api)->getData();
- }
-
- if (!isset($json)) {
- $json = [];
- $definition['error'] = TRUE;
- }
-
- $this->processApi($json, $definition);
- }
- }
-
-
- * {@inheritdoc}
- *
- * @deprecated in 8.x-3.18, will be removed in a future release.
- */
- public function processApi(array $json, array &$definition) {
- Bootstrap::deprecated();
- }
-
- }
Classes