View source
<?php
declare (strict_types=1);
namespace Drupal\cdn;
use Drupal\Component\Assertion\Inspector;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ConfigValueException;
class CdnSettings {
protected $rawSettings;
protected $lookupTable;
public function __construct(ConfigFactoryInterface $config_factory) {
$this->rawSettings = $config_factory
->get('cdn.settings');
$this->lookupTable = NULL;
}
public function isEnabled() : bool {
return $this->rawSettings
->get('status') === TRUE;
}
public function farfutureIsEnabled() : bool {
return $this->rawSettings
->get('farfuture.status') === TRUE;
}
public function getScheme() : string {
return $this->rawSettings
->get('scheme');
}
public function getLookupTable() : array {
if ($this->lookupTable === NULL) {
$this->lookupTable = $this
->buildLookupTable($this->rawSettings
->get('mapping'));
}
return $this->lookupTable;
}
public function getDomains() : array {
$flattened = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this
->getLookupTable())), FALSE);
$unique_domains = array_unique(array_filter($flattened));
return $unique_domains;
}
public function getStreamWrappers() : array {
$stream_wrappers = $this->rawSettings
->get('stream_wrappers');
assert(Inspector::assertAllStrings($stream_wrappers), 'Please run update.php!');
return $stream_wrappers;
}
protected function buildLookupTable(array $mapping) : array {
assert(!\Drupal::hasContainer() || \Drupal::service('config.typed')
->get('cdn.settings')
->validate()
->count() === 0, 'There are validation errors for the "cdn.settings" configuration.');
$lookup_table = [];
if ($mapping['type'] === 'simple') {
$domain = $mapping['domain'];
if (empty($mapping['conditions'])) {
$lookup_table['*'] = $domain;
}
else {
if (empty($mapping['conditions']['extensions'])) {
$lookup_table['*'] = $domain;
}
else {
foreach ($mapping['conditions']['extensions'] as $extension) {
$lookup_table[$extension] = $domain;
}
}
if (isset($mapping['conditions']['not'])) {
assert(!isset($mapping['conditions']['extensions']), 'It does not make sense to provide an \'extensions\' condition as well as a negated \'extensions\' condition.');
if (!empty($mapping['conditions']['not']['extensions'])) {
foreach ($mapping['conditions']['not']['extensions'] as $not_extension) {
$lookup_table[$not_extension] = FALSE;
}
}
}
}
}
elseif ($mapping['type'] === 'complex') {
$fallback_domain = NULL;
if (isset($mapping['fallback_domain'])) {
$fallback_domain = $mapping['fallback_domain'];
$lookup_table['*'] = $fallback_domain;
}
for ($i = 0; $i < count($mapping['domains']); $i++) {
$nested_mapping = $mapping['domains'][$i];
assert(!empty($nested_mapping['conditions']), 'The nested mapping ' . $i . ' includes no conditions, which is not allowed for complex mappings.');
assert(!isset($nested_mapping['conditions']['not']), 'The nested mapping ' . $i . ' includes negated conditions, which is not allowed for complex mappings: the fallback_domain already serves this purpose.');
$lookup_table += $this
->buildLookupTable($nested_mapping);
}
}
elseif ($mapping['type'] === 'auto-balanced') {
if (empty($mapping['conditions']) || empty($mapping['conditions']['extensions'])) {
throw new ConfigValueException('It does not make sense to apply auto-balancing to all files, regardless of extension.');
}
$domains = $mapping['domains'];
foreach ($mapping['conditions']['extensions'] as $extension) {
$lookup_table[$extension] = $domains;
}
}
else {
throw new ConfigValueException('Unknown CDN mapping type specified.');
}
return $lookup_table;
}
public function getCdnDomain($uri) {
$file_extension = mb_strtolower(pathinfo($uri, PATHINFO_EXTENSION));
$lookup_table = $this
->getLookupTable();
if (isset($lookup_table[$file_extension])) {
$key = $file_extension;
}
elseif (isset($lookup_table['*'])) {
$key = '*';
}
else {
return FALSE;
}
$result = $lookup_table[$key];
if ($result === FALSE) {
return FALSE;
}
elseif (is_array($result)) {
$filename = basename($uri);
$hash = hexdec(substr(md5($filename), 0, 5));
$cdn_domain = $result[$hash % count($result)];
}
else {
$cdn_domain = $result;
}
return $cdn_domain;
}
}