class ThemeSettings extends Config {
protected $defaults;
protected $deprecated;
protected $theme;
protected $settings;
public function __construct(Theme $theme) {
parent::__construct($theme->getName() . '.settings', \Drupal::service('config.storage'), \Drupal::service('event_dispatcher'), \Drupal::service('config.typed'));
$this->theme = $theme;
$this->settings = $theme->getSettingPlugin();
$deprecated = array_filter($this->settings, function($setting) {
return $setting instanceof DeprecatedSettingInterface;
});
$this->deprecated = [];
foreach ($deprecated as $deprecatedName => $deprecatedSetting) {
if (!is_null($deprecatedSetting)) {
$key = $deprecatedSetting->getDeprecatedReplacementSetting()->getPluginId();
if (!isset($this->deprecated[$key])) {
$this->deprecated[$key] = [];
}
$this->deprecated[$key][$deprecatedName] = $deprecatedSetting;
}
}
$cache = $theme->getCache('settings');
if ($defaults = $cache->get('defaults')) {
$this->defaults = $defaults;
$this->initWithData($cache->get('data', []));
return;
}
$this->defaults = \Drupal::config('system.theme.global')->get();
foreach ($this->settings as $name => $deprecatedSetting) {
if ($deprecatedSetting instanceof DeprecatedSettingInterface) {
continue;
}
$this->defaults[$name] = $deprecatedSetting->getDefaultValue();
}
$ancestry = $theme->getAncestry();
$active_theme = array_pop($ancestry);
foreach ($ancestry as $ancestor) {
$this->defaults = NestedArray::mergeDeepArray([$this->defaults, $this->getThemeConfig($ancestor)], TRUE);
}
$this->initWithData($this->getThemeConfig($active_theme, TRUE));
$cache->set('data', $this->data);
$cache->set('defaults', $this->defaults);
}
public function getCacheTags() {
return ['rendered'];
}
public function get($key = '') {
if (empty($key)) {
return NestedArray::mergeDeepArray([$this->defaults, $this->data], TRUE);
}
else {
$value = parent::get($key);
if (!isset($value)) {
$value = $this->getDeprecatedValue($key);
}
if (!isset($value)) {
$value = $this->getOriginal($key);
}
}
return $value;
}
protected function getDeprecatedValue($key) {
$value = NULL;
if (!isset($this->settings[$key]) || empty($this->deprecated[$key])) {
return $value;
}
$setting = $this->settings[$key];
$deprecatedSettings = $this->deprecated[$key];
$values = [];
foreach (array_keys($deprecatedSettings) as $deprecatedName) {
$deprecatedValue = $this->get($deprecatedName);
if (isset($deprecatedValue)) {
$values[$deprecatedName] = $deprecatedValue;
}
}
if (!$values) {
return $value;
}
$value = $setting->processDeprecatedValues($values, $deprecatedSettings);
if (isset($value)) {
if (count($values) > 1) {
Bootstrap::deprecated(NULL, NULL, t('The following theme settings have been deprecated and should no longer be used: "%deprecated". The values have been converted automatically for use with the supported theme setting "%name" instead. The configuration for the site should be exported to accommodate this change.', [
'%deprecated' => implode('", "', array_keys($deprecatedSettings)),
'%name' => $key,
]));
}
else {
Bootstrap::deprecated(NULL, NULL, t('The following theme setting has been deprecated and should no longer be used: "%deprecated". The value has been converted automatically for use with the supported theme setting "%name" instead. The configuration for the site should be exported to accommodate this change.', [
'%deprecated' => array_keys($deprecatedSettings) [0],
'%name' => $key,
]));
}
$this->set($key, $value);
foreach (array_keys($values) as $setting) {
$this->clear($setting);
}
$this->save();
}
return $value;
}
public function getOriginal($key = '', $apply_overrides = TRUE) {
$original_data = $this->defaults;
if ($apply_overrides) {
if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
$original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE);
}
if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
$original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE);
}
}
if (empty($key)) {
return $original_data;
}
else {
$parts = explode('.', $key);
if (count($parts) == 1) {
return isset($original_data[$key]) ? $original_data[$key] : NULL;
}
else {
$value = NestedArray::getValue($original_data, $parts, $key_exists);
return $key_exists ? $value : NULL;
}
}
}
public function getThemeConfig(Theme $theme, $active_theme = FALSE) {
$config = new CoreThemeSettings($theme->getName());
try {
if ($theme_settings = \Drupal::config($theme->getName() . '.settings')->get()) {
if (!$active_theme) {
unset($theme_settings['schemas']);
}
$config->merge($theme_settings);
}
}
catch (StorageException $e) {
}
$info = $theme->getInfo();
if (!empty($info['features'])) {
foreach (_system_default_theme_features() as $feature) {
if (!in_array($feature, $info['features'])) {
$config->set('features.' . $feature, NULL);
}
}
}
if ($config->get('features.logo')) {
$logo_url = FALSE;
foreach (['svg', 'png', 'jpg'] as $type) {
if (file_exists($theme->getPath() . "/logo.$type")) {
$logo_url = file_create_url($theme->getPath() . "/logo.$type");
break;
}
}
if ($config->get('logo.use_default') && $logo_url) {
$config->set('logo.url', $logo_url);
}
elseif (($logo_path = $config->get('logo.path')) && file_exists($logo_path)) {
$config->set('logo.url', file_create_url($logo_path));
}
}
if ($config->get('features.favicon')) {
$favicon_url = $theme->getPath() . '/favicon.ico';
if ($config->get('favicon.use_default') && file_exists($favicon_url)) {
$config->set('favicon.url', file_create_url($favicon_url));
}
elseif ($favicon_path = $config->get('favicon.path')) {
$config->set('favicon.url', file_create_url($favicon_path));
}
}
$data = $config->get();
$diff = DiffArray::diffAssocRecursive($data, $this->defaults);
foreach (['favicon', 'features', 'logo'] as $key) {
$arrays = [];
$arrays[] = isset($this->defaults[$key]) ? $this->defaults[$key] : [];
$arrays[] = isset($data[$key]) ? $data[$key] : [];
$diff[$key] = NestedArray::mergeDeepArray($arrays, TRUE);
}
return $diff;
}
public function overridesValue($name, $value) {
$current_value = $this->get($name);
if ($value === [] && $current_value !== []) {
return TRUE;
}
return !!DiffArray::diffAssocRecursive([$name => $value], [$name => $current_value]);
}
public function save($has_trusted_data = FALSE) {
parent::save($has_trusted_data);
$this->theme->getCache('settings')->deleteAll();
return $this;
}
}