class SystemThemeSettings extends FormBase implements FormInterface {
public function alterFormElement(Element $form, FormStateInterface $form_state, $form_id = NULL) {
$theme = $this->getTheme($form, $form_state);
if (!$theme) {
return;
}
$this->createGroups($form, $form_state);
foreach ($theme->getSettingPlugin() as $setting) {
if (!$setting->autoCreateFormElement()) {
continue;
}
$setting->alterForm($form->getArray(), $form_state);
}
}
protected function createGroups(Element $form, FormStateInterface $form_state) {
if (!isset($form['global'])) {
$form['global'] = [
'#type' => 'vertical_tabs',
'#weight' => -9,
'#prefix' => '<h2><small>' . t('Override Global Settings') . '</small></h2>',
];
}
foreach ($form->children() as $child) {
if ($child->isType(['details', 'fieldset']) && !$child->hasProperty('group')) {
$child->setProperty('type', 'details');
$child->setProperty('group', 'global');
}
}
$form['bootstrap'] = [
'#type' => 'vertical_tabs',
'#attached' => ['library' => ['bootstrap/theme-settings']],
'#prefix' => '<h2><small>' . t('Bootstrap Settings') . '</small></h2>',
'#weight' => -10,
];
$groups = [
'general' => t('General'),
'components' => t('Components'),
'javascript' => t('JavaScript'),
'cdn' => t('CDN'),
'advanced' => t('Advanced'),
];
foreach ($groups as $group => $title) {
$form[$group] = [
'#type' => 'details',
'#title' => $title,
'#group' => 'bootstrap',
];
if ($group === 'advanced') {
$cache = \Drupal::keyValueExpirable('theme:' . $this->theme->getName() . ':http');
$count = count($cache->getAll());
$form[$group]['reset_http_request_cache'] = [
'#type' => 'item',
'#title' => $this->t('Cached HTTP requests: @count', ['@count' => $count]),
'#weight' => 100,
'#smart_description' => FALSE,
'#description' => $this->t('All external HTTP requests initiated by this theme are subject to caching. Cacheability is determined automatically based on a manually passed TTL value by the initiator or if there is a "max-age" response header present. These cached requests will persist through cache rebuilds and will only be requested again once they have expired. If you believe there is some request not being properly retrieved, you can manually reset this cache here.'),
'#description_display' => 'before',
'#prefix' => '<div id="reset-http-request-cache">',
'#suffix' => '</div>',
];
$form[$group]['reset_http_request_cache']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Reset HTTP Request Cache'),
'#description' => $this->t('Note: this will not reset any cached CDN data; see "Advanced Cache" in the "CDN" section.'),
'#prefix' => '<div>',
'#suffix' => '</div>',
'#submit' => [
[get_class($this), 'submitResetHttpRequestCache'],
],
'#ajax' => [
'callback' => [get_class($this), 'ajaxResetHttpRequestCache'],
'wrapper' => 'reset-http-request-cache',
],
];
}
}
}
public static function submitResetHttpRequestCache(array $form, FormStateInterface $form_state) {
$form_state->setRebuild();
$theme = SystemThemeSettings::getTheme(Element::create($form), $form_state);
$cache = \Drupal::keyValueExpirable('theme:' . $theme->getName() . ':http');
$cache->deleteAll();
}
public static function ajaxResetHttpRequestCache(array $form, FormStateInterface $form_state) {
return $form['advanced']['reset_http_request_cache'];
}
public static function getTheme(Element $form, FormStateInterface $form_state) {
$build_info = $form_state->getBuildInfo();
$theme = isset($build_info['args'][0]) ? Bootstrap::getTheme($build_info['args'][0]) : FALSE;
if (!$theme || !$theme->isBootstrap()) {
unset($form['#submit'][0]);
unset($form['#validate'][0]);
}
return $theme;
}
public static function submitFormElement(Element $form, FormStateInterface $form_state) {
$theme = self::getTheme($form, $form_state);
if (!$theme) {
return;
}
$cache_tags = [];
$save = FALSE;
$settings = $theme->settings();
$rebuild_cdn_assets = FALSE;
foreach ($theme->getSettingPlugin() as $name => $setting) {
if ($setting instanceof DeprecatedSettingInterface) {
$form_state->unsetValue($name);
continue;
}
$setting->submitForm($form->getArray(), $form_state);
$value = $form_state->getValue($name);
$definition = $setting->getPluginDefinition();
if (isset($definition['type']) && $definition['type'] === 'textarea' && is_string($value)) {
$value = implode("\n", array_filter(array_map('trim', preg_split("/\r\n|\n/", $value))));
}
if ($name !== 'schemas' && $settings->overridesValue($name, $value)) {
$settings->set($name, $value);
$cache_tags = array_unique(array_merge($setting->getCacheTags()));
if (strpos($name, 'cdn') === 0) {
$rebuild_cdn_assets = TRUE;
}
$save = TRUE;
}
$form_state->unsetValue($name);
}
if ($save) {
if ($rebuild_cdn_assets) {
$settings->clear('cdn_cache');
}
$settings->save();
if ($cache_tags) {
\Drupal::service('cache_tags.invalidator')->invalidateTags($cache_tags);
}
$theme->getCache('settings')->deleteAll();
}
}
public static function validateFormElement(Element $form, FormStateInterface $form_state) {
$theme = self::getTheme($form, $form_state);
if (!$theme) {
return;
}
foreach ($theme->getSettingPlugin() as $setting) {
$setting->validateForm($form->getArray(), $form_state);
}
}
}