diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 03c0aa4..e856376 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,7 @@ +// $Id: CHANGELOG.txt,v 1.14 2011/01/07 23:41:22 sun Exp $ Switchtheme 7.x-1.x, xxxx-xx-xx ------------------------------- -#871692 by sun: Fixed custom theme labels not applied on output. -#402348 by gilgabar, sun: Fixed form validation errors with block caching. Switchtheme 7.x-1.0, 2010-01-07 @@ -12,7 +11,6 @@ Switchtheme 7.x-1.0, 2010-01-07 Switchtheme 6.x-1.x, xxxx-xx-xx ------------------------------- -#986520 by RockSoup: Fixed bogus customization code in README.txt. #455796 by sun: Fixed query string allows to select disabled themes. #417120 by dereine: Fixed random theme block displays disabled themes. @@ -45,5 +43,3 @@ Switchtheme 5.x-1.1, 2006-12-29 Switchtheme 5.x-1.0, 2006-11-15 ------------------------------- Initial release of Switchtheme for Drupal 5.x. - - diff --git a/README.txt b/README.txt index cd91916..a43fea4 100644 --- a/README.txt +++ b/README.txt @@ -1,3 +1,4 @@ +/* $Id: README.txt,v 1.9 2011/01/07 23:41:22 sun Exp $ */ -- SUMMARY -- @@ -101,7 +102,7 @@ the font size of their pages. which allow users to switch to pre-defined themes. For example, using Drupal's l() function in page.tpl.php (without code tags): -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('', [], ['absolute' => TRUE]); + $build['theme'] = array( + '#type' => 'link', + '#title' => \Drupal::service('renderer')->render($image), + '#url' => $query, + '#options' => array( + 'query' => array( + 'theme' => $theme->getName(), + ), + 'html' => TRUE, + ), + ); + return $build; + } + } + } + +} diff --git a/src/Theme/SwitchthemeNegotiator.php b/src/Theme/SwitchthemeNegotiator.php new file mode 100644 index 0000000..6e1aa59 --- /dev/null +++ b/src/Theme/SwitchthemeNegotiator.php @@ -0,0 +1,57 @@ +getCurrentRequest()->query->get('theme'); + $themes = Switchtheme::switchThemeOptions(); + + if (!empty($theme)) { + $set_theme = $theme; + } + // Check whether the user session contains a custom theme. + if (isset($_SESSION['custom_theme'])) { + $set_theme = $_SESSION['custom_theme']; + } + // Check whether the current user has a custom theme assigned. + $user = User::load($account->id()); + if (!empty($user->theme)) { + $set_theme = $user->theme; + } + + if (isset($themes[$set_theme])) { + return $set_theme; + } + + } + +} diff --git a/switchtheme.admin.inc b/switchtheme.admin.inc deleted file mode 100644 index d052bf8..0000000 --- a/switchtheme.admin.inc +++ /dev/null @@ -1,59 +0,0 @@ - $label) { - $form['switchtheme']['switchtheme_' . $name] = array( - '#type' => 'textfield', - '#title' => $label, - '#default_value' => variable_get('switchtheme_' . $name, $label), - ); - } - return system_settings_form($form); -} - -/** - * Form constructor for browser settings. - */ -function switchtheme_admin_browser_settings($form, &$form_state) { - $form['switchtheme_browser_enabled'] = array( - '#type' => 'checkbox', - '#title' => t('Switch theme based on the browser of the visitor'), - '#default_value' => variable_get('switchtheme_browser_enabled', FALSE), - ); - - $themes = array('default' => t('Default')); - $themes += switchtheme_options(); - $useragents = array(); - $result = db_query('SELECT data FROM {browscap}')->fetchCol(); - foreach ($result as $data) { - $data = unserialize($data); - if (isset($data['parent'])) { - $useragents[trim($data['parent'])][] = isset($data['platform']) ? $data['platform'] : ''; - } - } - $form['switchtheme_browser'] = array( - '#type' => 'fieldset', - '#title' => t('Browsers'), - '#collapsible' => FALSE, - '#collapsed' => FALSE, - ); - foreach ($useragents as $parent => $platforms) { - $form['switchtheme_browser']['switchtheme_browser_' . md5($parent)] = array( - '#type' => 'select', - '#title' => $parent, - '#options' => $themes, - '#default_value' => variable_get('switchtheme_browser_' . md5($parent), 'default'), - ); - } - return system_settings_form($form); -} - diff --git a/switchtheme.info b/switchtheme.info deleted file mode 100644 index f70e4b3..0000000 --- a/switchtheme.info +++ /dev/null @@ -1,5 +0,0 @@ -name = Switchtheme -description = Allows switching the theme in various means. -core = 7.x -package = User interface -configure = admin/config/user-interface/switchtheme diff --git a/switchtheme.info.yml b/switchtheme.info.yml new file mode 100644 index 0000000..3ea92ca --- /dev/null +++ b/switchtheme.info.yml @@ -0,0 +1,6 @@ +name: Switchtheme +description: 'Allows switching the theme in various means.' +core: 8.x +configure: switchtheme.settings_form +package: User interface +type: module diff --git a/switchtheme.install b/switchtheme.install deleted file mode 100644 index 02fd816..0000000 --- a/switchtheme.install +++ /dev/null @@ -1,15 +0,0 @@ -condition('name', 'switchtheme_%', 'LIKE') - ->execute; -} diff --git a/switchtheme.links.menu.yml b/switchtheme.links.menu.yml new file mode 100644 index 0000000..458d12a --- /dev/null +++ b/switchtheme.links.menu.yml @@ -0,0 +1,5 @@ +switchtheme.settings_form: + route_name: switchtheme.settings_form + title: 'Switchtheme settings' + description: 'Configure theme selection settings.' + parent: system.admin_config_ui diff --git a/switchtheme.module b/switchtheme.module index 3248889..a3100a2 100644 --- a/switchtheme.module +++ b/switchtheme.module @@ -5,300 +5,24 @@ * Adds a block with a user theme switcher. */ +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Url; + /** * Implements hook_help(). */ -function switchtheme_help($path, $arg) { - switch ($path) { - case 'admin/help#switchtheme': +function switchtheme_help($route_name, RouteMatchInterface $route_match) { + switch ($route_name) { + case 'help.page.switchtheme': $output = ''; $output .= '

' . t('About') . '

'; $output .= '

' . 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