-print l('Red theme', $_GET['q'], array('query' => array('theme' => 'red')));
+print l('Red theme', $_GET['q'], array(), 'theme=red');
@@ -118,4 +119,3 @@ This project has been sponsored by:
Specialized in consulting and planning of Drupal powered sites, UNLEASHED
MIND offers installation, development, theming, customization, and hosting
to get you started. Visit http://www.unleashedmind.com for more information.
-
diff --git a/src/EventSubscriber/InitSubscriber.php b/src/EventSubscriber/InitSubscriber.php
new file mode 100644
index 0000000..c9f233a
--- /dev/null
+++ b/src/EventSubscriber/InitSubscriber.php
@@ -0,0 +1,45 @@
+ ['onEvent', 0]];
+ }
+
+ /**
+ * Switch theme.
+ */
+ public function onEvent() {
+ // If there is a HTTP GET parameter 'theme', assign it as new theme.
+ $theme = \Drupal::service('request_stack')->getCurrentRequest()->query->get('theme');
+ if (isset($theme)) {
+ // Manually validate the value.
+ // @todo Consider switching the form's method to GET.
+ $themes = Switchtheme::switchThemeOptions();
+ if (isset($themes[$theme])) {
+ $form_state = new FormState();
+ $values['theme'] = $theme;
+ $form_state->setValues($values);
+ \Drupal::formBuilder()->submitForm('Drupal\switchtheme\Form\SwitchthemeSwitchForm', $form_state);
+ }
+ }
+ }
+
+}
diff --git a/src/Form/SwitchthemeAdminSettings.php b/src/Form/SwitchthemeAdminSettings.php
new file mode 100644
index 0000000..d6051f6
--- /dev/null
+++ b/src/Form/SwitchthemeAdminSettings.php
@@ -0,0 +1,78 @@
+config('switchtheme.settings');
+ $settings = $config->get();
+
+ $options = Switchtheme::switchThemeOptions();
+ foreach ($options as $name => $label) {
+ $form['switchtheme_' . $name] = array(
+ '#type' => 'textfield',
+ '#title' => $label,
+ '#default_value' => !empty($settings['switchtheme_' . $name]) ? $settings['switchtheme_' . $name] : '',
+ );
+ }
+
+ return parent::buildForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {
+ parent::validateForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ $config = $this->config('switchtheme.settings');
+
+ foreach (Element::children($form) as $variable) {
+ $config->set($variable, $form_state->getValue($form[$variable]['#parents']));
+ }
+ $config->save();
+
+ if (method_exists($this, '_submitForm')) {
+ $this->_submitForm($form, $form_state);
+ }
+
+ parent::submitForm($form, $form_state);
+ }
+
+}
diff --git a/src/Form/SwitchthemeSwitchForm.php b/src/Form/SwitchthemeSwitchForm.php
new file mode 100644
index 0000000..83e42f0
--- /dev/null
+++ b/src/Form/SwitchthemeSwitchForm.php
@@ -0,0 +1,94 @@
+ 'container',
+ '#attributes' => array('class' => array('container-inline')),
+ );
+ $form['widget']['theme'] = array(
+ '#type' => 'select',
+ '#title' => t('Change the way this site looks'),
+ '#title_display' => 'attribute',
+ '#options' => $options,
+ '#required' => TRUE,
+ );
+ // Only if no custom theme could be determined, check whether we
+ // can preselect the current theme.
+ if (!isset($form['widget']['theme']['#default_value']) && isset($options[$theme_key])) {
+ $form['widget']['theme']['#default_value'] = $theme_key;
+ }
+
+ $form['widget']['actions'] = array('#type' => 'actions');
+ $form['widget']['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Switch'),
+ '#id' => 'switchtheme-submit',
+ );
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {
+ parent::validateForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ $user = \Drupal::currentUser();
+
+ // Save the setting for authenticated users, if the "select different theme"
+ // permission has been granted.
+ if ($user->id() > 0 && \Drupal::currentUser()->hasPermission('select different theme')) {
+ $account = User::load($user->id());
+ $account->theme = $form_state->getValue('theme');
+ $account->save();
+ }
+
+ // Otherwise save the setting in the user's session.
+ elseif (\Drupal::currentUser()->hasPermission('switch theme')) {
+ $_SESSION['custom_theme'] = $form_state->getValue('theme');
+ }
+ }
+
+}
diff --git a/src/Plugin/Block/SwitchthemeBlock.php b/src/Plugin/Block/SwitchthemeBlock.php
new file mode 100644
index 0000000..ac60816
--- /dev/null
+++ b/src/Plugin/Block/SwitchthemeBlock.php
@@ -0,0 +1,40 @@
+hasPermission('switch theme')) {
+ $content = \Drupal::formBuilder()->getForm('Drupal\switchtheme\Form\SwitchthemeSwitchForm');
+ }
+
+ return array(
+ '#children' => \Drupal::service('renderer')->render($content),
+ '#cache' => array(
+ 'max-age' => 0,
+ ),
+ );
+ }
+
+}
diff --git a/src/Plugin/Block/SwitchthemeRandomBlock.php b/src/Plugin/Block/SwitchthemeRandomBlock.php
new file mode 100644
index 0000000..9618596
--- /dev/null
+++ b/src/Plugin/Block/SwitchthemeRandomBlock.php
@@ -0,0 +1,41 @@
+hasPermission('switch theme')) {
+ $content = Switchtheme::switchThemeDisplayRandomBlock();
+ }
+
+ return array(
+ '#children' => \Drupal::service('renderer')->render($content),
+ '#cache' => array(
+ 'max-age' => 0,
+ ),
+ );
+ }
+
+}
diff --git a/src/Switchtheme.php b/src/Switchtheme.php
new file mode 100644
index 0000000..eda2bba
--- /dev/null
+++ b/src/Switchtheme.php
@@ -0,0 +1,79 @@
+listInfo();
+ foreach ($themes as $theme_name => $theme) {
+ if (!empty($theme->info['hidden'])) {
+ continue;
+ }
+ if (\Drupal::service('access_check.theme')->checkAccess($theme_name)) {
+ $options[$theme_name] = $theme->info['name'];
+ }
+ }
+ return $options;
+ }
+
+ /**
+ * Returns switchtheme_options() with customized theme labels.
+ */
+ public static function switchThemeSelect() {
+ $options = array();
+ $config = \Drupal::config('switchtheme.settings');
+ $settings = $config->get();
+ foreach (Switchtheme::switchThemeOptions() as $name => $label) {
+ $options[$name] = !empty($settings['switchtheme_' . $name]) ? $settings['switchtheme_' . $name] : $label;
+ }
+ asort($options);
+ return $options;
+ }
+
+ /**
+ * Renders a random theme with screenshot to switch to.
+ */
+ public static function switchThemeDisplayRandomBlock() {
+ $theme_handler = \Drupal::service('theme_handler');
+ $themes = $theme_handler->listInfo();
+ shuffle($themes);
+ foreach ($themes as $key => $theme) {
+ if ($theme->status && !empty($theme->info['screenshot'])) {
+ // Return the first theme with a screenshot.
+ $image = array(
+ '#theme' => 'image',
+ '#uri' => $theme->info['screenshot'],
+ '#alt' => t('Preview of @theme', array('@theme' => $theme->getName())),
+ );
+ $query = Url::fromRoute('' . t('The Switchtheme module provides blocks to allow users to switch themes on the fly. You can define custom labels to display for each enabled theme. It also allows the theme to be changed based on the visitor browser (requires Browscap module).', array( - '@blocks-url' => url('admin/structure/block'), + '@blocks-url' => Url::fromRoute('block.admin_display'), '@browscap-url' => 'http://drupal.org/project/browscap', )) . '
'; return $output; - case 'admin/config/user-interface/switchtheme': - case 'admin/config/user-interface/switchtheme/themes': + case 'switchtheme.settings_form': return t('Set a label for each enabled theme. This is what will be displayed to the user in the selection box.'); } } - -/** - * Implements hook_permission(). - */ -function switchtheme_permission() { - return array( - 'administer switch' => array( - 'title' => t('Administer SwitchTheme'), - ), - 'switch theme' => array( - 'title' => t('Switch themes'), - ), - 'select different theme' => array( - 'title' => t('Permanently use a custom theme'), - ), - ); -} - -/** - * Implements hook_menu(). - */ -function switchtheme_menu() { - $items['admin/config/user-interface/switchtheme'] = array( - 'title' => 'Switchtheme', - 'description' => 'Configure theme selection settings.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('switchtheme_admin_settings'), - 'access arguments' => array('administer switch'), - 'file' => 'switchtheme.admin.inc', - ); - $items['admin/config/user-interface/switchtheme/themes'] = array( - 'title' => 'Themes', - 'description' => 'Configure theme selection options of the Switchtheme block.', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - if (module_exists('browscap')) { - $items['admin/config/user-interface/switchtheme/browser'] = array( - 'title' => 'Browsers', - 'description' => 'Configure automatic theme selection for visitors.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('switchtheme_admin_browser_settings'), - 'access arguments' => array('administer switch'), - 'file' => 'switchtheme.admin.inc', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, - ); - } - return $items; -} - -/** - * Implements hook_init(). - */ -function switchtheme_init() { - // Skip maintenance mode and maintenance pages. - // @see menu_get_custom_theme() - if (_menu_site_is_offline(TRUE) || defined('MAINTENANCE_MODE')) { - return; - } - - // If there is a HTTP GET parameter 'theme', assign it as new theme. - if (isset($_GET['theme'])) { - // Manually validate the value. - // @todo Consider switching the form's method to GET. - $themes = switchtheme_options(); - if (isset($themes[$_GET['theme']])) { - $form = array(); - $form_state['values']['theme'] = $_GET['theme']; - switchtheme_switch_form_submit($form, $form_state); - } - } -} - -/** - * Implements hook_custom_theme(). - * - * @param $return_single - * Boolean whether to return the first determined custom theme (TRUE) or all - * determined values (FALSE). Defaults to TRUE. - */ -function switchtheme_custom_theme($return_single = TRUE) { - global $user; - - $custom_theme = array(); - - // The HTTP GET parameter 'theme' always has precedence. - if (isset($_GET['theme'])) { - $custom_theme['get'] = $_GET['theme']; - } - // Check whether the user session contains a custom theme. - if (isset($_SESSION['custom_theme'])) { - $custom_theme['session'] = $_SESSION['custom_theme']; - } - // Check whether the current user has a custom theme assigned. - if (!empty($user->theme)) { - $custom_theme['user'] = $user->theme; - } - // Lastly, check whether a theme can be automatically selected. - if (module_exists('browscap') && variable_get('switchtheme_browser_enabled', FALSE)) { - $browser = browscap_get_browser(); - if (isset($browser['parent'])) { - $parent = trim($browser['parent']); - $browser_theme = variable_get('switchtheme_browser_' . md5($parent), 'default'); - if ($browser_theme != 'default') { - $custom_theme['browser'] = $browser_theme; - } - } - } - - if ($return_single) { - // reset() would return FALSE if $custom_theme is empty. - return (!empty($custom_theme) ? reset($custom_theme) : NULL); - } - return $custom_theme; -} - -/** - * Implements hook_block_info() - */ -function switchtheme_block_info() { - $blocks['switch_form'] = array( - 'info' => t('Switch theme'), - 'cache' => DRUPAL_NO_CACHE, - ); - $blocks['switch_random'] = array( - 'info' => t('Random theme'), - 'cache' => DRUPAL_NO_CACHE, - ); - return $blocks; -} - -/** - * Implements hook_block_view() - */ -function switchtheme_block_view($delta = '') { - if (user_access('switch theme')) { - switch ($delta) { - case 'switch_form': - $block['subject'] = t('Theme'); - $block['content'] = drupal_get_form('switchtheme_switch_form'); - return $block; - - case 'switch_random': - $block['subject'] = t('Random theme'); - $block['content'] = switchtheme_display_random_block(); - return $block; - } - } -} - -/** - * Renders a random theme with screenshot to switch to. - */ -function switchtheme_display_random_block() { - $themes = list_themes(); - shuffle($themes); - foreach ($themes as $key => $theme) { - if ($theme->status && !empty($theme->info['screenshot'])) { - // Return the first theme with a screenshot. - $build['theme'] = array( - '#type' => 'link', - '#title' => theme('image', array( - 'path' => $theme->info['screenshot'], - 'alt' => t('Preview of @theme', array('@theme' => $theme->name)), - )), - '#href' => $_GET['q'], - '#options' => array( - 'query' => array( - 'theme' => $theme->name, - ), - 'html' => TRUE, - ), - ); - return $build; - } - } -} - -/** - * Form constructor for theme switcher form. - */ -function switchtheme_switch_form($form, &$form_state) { - global $user, $theme_key; - - $options = switchtheme_select(); - // Nothing to switch if there is only one theme. - if (count($options) < 2) { - $form['#access'] = FALSE; - return $form; - } - - $form['widget'] = array( - '#type' => 'container', - '#attributes' => array('class' => array('container-inline')), - ); - $form['widget']['theme'] = array( - '#type' => 'select', - '#title' => t('Change the way this site looks'), - '#title_display' => 'attribute', - '#options' => $options, - '#required' => TRUE, - ); - // The current page may be displayed in a theme that is not available to - // Switchtheme (e.g., a disabled admin theme). And even if the current theme - // is available to Switchtheme, it might not be the theme the current user - // previously selected. So in order to not confuse the user, we need to figure - // out the proper, last set theme for the #default_value. - foreach (switchtheme_custom_theme(FALSE) as $name) { - if (isset($options[$name])) { - $form['widget']['theme']['#default_value'] = $name; - break; - } - } - // Only if no custom theme could be determined, check whether we can preselect - // the current theme. - if (!isset($form['widget']['theme']['#default_value']) && isset($options[$theme_key])) { - $form['widget']['theme']['#default_value'] = $theme_key; - } - - $form['widget']['actions'] = array('#type' => 'actions'); - $form['widget']['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Switch'), - '#id' => 'switchtheme-submit', - ); - return $form; -} - -/** - * Form submission handler for switchtheme_switch_form(). - * - * We do not validate the input here, because that is done in init_theme() - * already. - */ -function switchtheme_switch_form_submit($form, &$form_state) { - global $user; - - // Save the setting for authenticated users, if the "select different theme" - // permission has been granted. - if ($user->uid > 0 && user_access('select different theme')) { - $account = user_load($user->uid); - user_save($account, array( - 'theme' => $form_state['values']['theme'], - )); - } - // Otherwise save the setting in the user's session. - elseif (user_access('switch theme')) { - $_SESSION['custom_theme'] = $form_state['values']['theme']; - } -} - -/** - * Returns an #options list of enabled themes. - */ -function switchtheme_options() { - $options = array(); - $themes = list_themes(); - foreach ($themes as $name => $theme) { - if ($theme->status) { - $options[$name] = $theme->info['name']; - } - } - return $options; -} - -/** - * Returns switchtheme_options() with customized theme labels. - */ -function switchtheme_select() { - $options = array(); - foreach (switchtheme_options() as $name => $label) { - $options[$name] = variable_get('switchtheme_' . $name, $label); - } - asort($options); - return $options; -} - diff --git a/switchtheme.permissions.yml b/switchtheme.permissions.yml new file mode 100644 index 0000000..dec67d6 --- /dev/null +++ b/switchtheme.permissions.yml @@ -0,0 +1,6 @@ +administer switch: + title: 'Administer SwitchTheme' +switch theme: + title: 'Switch themes' +select different theme: + title: 'Permanently use a custom theme' diff --git a/switchtheme.routing.yml b/switchtheme.routing.yml new file mode 100644 index 0000000..a68718c --- /dev/null +++ b/switchtheme.routing.yml @@ -0,0 +1,8 @@ +switchtheme.settings_form: + path: /admin/config/user-interface/switchtheme + defaults: + _form: \Drupal\switchtheme\Form\SwitchthemeAdminSettings + _title: 'Switchtheme' + _description: 'Configure theme selection settings.' + requirements: + _permission: 'administer switch' diff --git a/switchtheme.services.yml b/switchtheme.services.yml new file mode 100644 index 0000000..6ea003f --- /dev/null +++ b/switchtheme.services.yml @@ -0,0 +1,10 @@ +services: + theme.negotiator.switchtheme: + class: Drupal\switchtheme\Theme\SwitchthemeNegotiator + tags: + - { name: theme_negotiator, priority: 0 } + init_subscriber: + class: Drupal\switchtheme\EventSubscriber\InitSubscriber + tags: + - + name: event_subscriber