getTheme($form, $form_state);
if (!$theme) {
return;
}
// Creates the necessary groups (vertical tabs) for a Bootstrap based theme.
$this->createGroups($form, $form_state);
// Iterate over all setting plugins and add them to the form.
foreach ($theme->getSettingPlugin() as $setting) {
$setting->alterForm($form->getArray(), $form_state);
}
}
/**
* Sets up the vertical tab groupings.
*
* @param \Drupal\bootstrap\Utility\Element $form
* The Element object that comprises the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
protected function createGroups(Element $form, FormStateInterface $form_state) {
// Vertical tabs for global settings provided by core or contrib modules.
if (!isset($form['global'])) {
$form['global'] = [
'#type' => 'vertical_tabs',
'#weight' => -9,
'#prefix' => '
' . t('Override Global Settings') . '
',
];
}
// Iterate over existing children and move appropriate ones to global group.
foreach ($form->children() as $child) {
if ($child->isType(['details', 'fieldset']) && !$child->hasProperty('group')) {
$child->setProperty('type', 'details');
$child->setProperty('group', 'global');
}
}
// Provide the necessary default groups.
$form['bootstrap'] = [
'#type' => 'vertical_tabs',
'#attached' => ['library' => ['bootstrap/theme-settings']],
'#prefix' => '' . t('Bootstrap Settings') . '
',
'#weight' => -10,
];
$groups = [
'general' => t('General'),
'components' => t('Components'),
'javascript' => t('JavaScript'),
'advanced' => t('Advanced'),
];
foreach ($groups as $group => $title) {
$form[$group] = [
'#type' => 'details',
'#title' => $title,
'#group' => 'bootstrap',
];
}
}
/**
* Retrieves the currently selected theme on the settings form.
*
* @param \Drupal\bootstrap\Utility\Element $form
* The Element object that comprises the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return \Drupal\bootstrap\Theme|FALSE
* The currently selected theme object or FALSE if not a Bootstrap theme.
*/
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;
// Do not continue if the theme is not Bootstrap specific.
if (!$theme || !$theme->isBootstrap()) {
unset($form['#submit'][0]);
unset($form['#validate'][0]);
}
return $theme;
}
/**
* {@inheritdoc}
*/
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();
// Iterate over all setting plugins and manually save them since core's
// process is severely limiting and somewhat broken.
foreach ($theme->getSettingPlugin() as $name => $setting) {
// Allow the setting to participate in the form submission process.
// Must call the "submitForm" method in case any setting actually uses it.
// It should, in turn, invoke "submitFormElement", if the setting that
// overrides it is implemented properly.
$setting->submitForm($form->getArray(), $form_state);
// Retrieve the submitted value.
$value = $form_state->getValue($name);
// Determine if the setting has a new value that overrides the original.
// Ignore the schemas "setting" because it's handled by UpdateManager.
if ($name !== 'schemas' && $settings->overridesValue($name, $value)) {
// Set the new value.
$settings->set($name, $value);
// Retrieve the cache tags for the setting.
$cache_tags = array_unique(array_merge($setting->getCacheTags()));
// Flag the save.
$save = TRUE;
}
// Remove value from the form state object so core doesn't re-save it.
$form_state->unsetValue($name);
}
// Save the settings, if needed.
if ($save) {
$settings->save();
// Invalidate necessary cache tags.
if ($cache_tags) {
\Drupal::service('cache_tags.invalidator')->invalidateTags($cache_tags);
}
// Clear our internal theme cache so it can be rebuilt properly.
$theme->getCache('settings')->deleteAll();
}
}
/**
* {@inheritdoc}
*/
public static function validateFormElement(Element $form, FormStateInterface $form_state) {
$theme = self::getTheme($form, $form_state);
if (!$theme) {
return;
}
// Iterate over all setting plugins and allow them to participate.
foreach ($theme->getSettingPlugin() as $setting) {
// Allow the setting to participate in the form validation process.
// Must call the "validateForm" method in case any setting actually uses it.
// It should, in turn, invoke "validateFormElement", if the setting that
// overrides it is implemented properly.
$setting->validateForm($form->getArray(), $form_state);
}
}
}