You are here

mobile_switch.module in Mobile Switch 6

Same filename and directory in other branches
  1. 7.2 mobile_switch.module
  2. 7 mobile_switch.module

Simple theme switch for mobile devices, detected by browscap.

File

mobile_switch.module
View source
<?php

/**
 * @file
 * Simple theme switch for mobile devices, detected by browscap.
 */

/**
 * Implementation of hook_boot().
 *
 * Alter specific entries in the 'variable' table:
 *   - theme_default: If mobile mobile device the value are changed
 *                    to the configured mobile theme.
 * Insert new entries in the 'variable' table:
 *   - mobile_switch_ismobiledevice: The default value is FALSE. If the
 *                                   browscap value 'ismobiledevice' are 1
 *                                   the value is TRUE.
 *   - mobile_switch_ismobiletheme: The default value is FALSE. If used mobile
 *                                  theme the value is TRUE.
 *   - theme_mobile: The default value is FALSE. If used mobile theme the value
 *                   is the machine name of the used theme.
 */
function mobile_switch_boot() {
  global $conf;

  // Initialize the new variables here (as fallback) if configured the
  // 'Mobile theme' setting  with the option 'Do not use'.
  $conf['mobile_switch_ismobiledevice'] = FALSE;
  $conf['mobile_switch_ismobiletheme'] = FALSE;
  $conf['theme_mobile'] = FALSE;

  // Preserve the configuration variables.
  $conf['mobile_switch_theme_default'] = variable_get('theme_default', 'garland');
  $conf['mobile_switch_theme_mobile'] = variable_get('mobile_switch_mobile_theme', 'none');

  // Use the mobile theme on admin pages.
  $get['admin_usage'] = (bool) variable_get('mobile_switch_admin_usage', FALSE);
  if (variable_get('mobile_switch_mobile_theme', 'none') === 'none') {
    return;
  }
  if (isset($conf['site_offline'])) {
    if ((bool) $conf['site_offline'] === TRUE) {
      return;
    }
  }
  if (isset($_REQUEST['q'])) {
    if (stristr($_REQUEST['q'], 'admin') && $get['admin_usage'] === FALSE) {
      return;
    }
  }
  $get['deskbrowser'] = (bool) variable_get('mobile_switch_deskbrowser', FALSE);
  $get['developer'] = (bool) variable_get('mobile_switch_developer', FALSE);
  $get['theme_default'] = variable_get('theme_default', 'garland');
  $get['browser'] = mobile_switch_browscap_get_browser($get['developer']);
  if ((bool) variable_get('mobile_switch_prevent_devices', FALSE) === TRUE) {
    if ((bool) $get['browser']['prevent_device'] === TRUE) {
      return;
    }
  }
  if ((bool) $get['browser']['ismobiledevice'] === TRUE || (bool) $get['browser']['ismobiledevice'] === FALSE && $get['developer'] === TRUE && $get['deskbrowser'] === TRUE || $get['deskbrowser'] === TRUE) {
    $conf['theme_default'] = $conf['theme_mobile'] = $conf['mobile_switch_theme_mobile'];
    $conf['mobile_switch_ismobiletheme'] = TRUE;

    // Use mobile theme on admin pages.
    if (isset($_REQUEST['q'])) {
      if (stristr($_REQUEST['q'], 'admin') && $get['admin_usage'] === TRUE) {
        $conf['admin_theme'] = $conf['mobile_switch_theme_mobile'];
      }
    }
  }
  if ((bool) $get['browser']['ismobiledevice'] === TRUE) {
    $conf['mobile_switch_ismobiledevice'] = TRUE;
  }
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
  drupal_alter('mobile_switch_boot', $conf, $get);
}

/**
 * Implementation of hook_menu().
 */
function mobile_switch_menu() {
  $items = array();
  $items['admin/settings/mobile-switch'] = array(
    'title' => 'Mobile Switch',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'mobile_switch_settings_form',
    ),
    'access callback' => 'mobile_switch_administer',
    'description' => 'Enable or disable automatic theme changing for mobile devices.',
    'file' => 'includes/mobile_switch.admin.inc',
  );
  $items['admin/settings/mobile-switch/basic-settings'] = array(
    'title' => 'Basic settings',
    'description' => 'Adjust the basic settings.',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/settings/mobile-switch/advanced'] = array(
    'title' => 'Advanced',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'mobile_switch_advanced_settings_form',
    ),
    'access callback' => 'mobile_switch_administer',
    'file' => 'includes/mobile_switch.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -8,
  );
  $items['admin/settings/mobile-switch/development'] = array(
    'title' => 'Development',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'mobile_switch_development_settings_form',
    ),
    'access callback' => 'mobile_switch_administer',
    'file' => 'includes/mobile_switch.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -6,
  );
  return $items;
}

/**
 * Access callback.
 *
 * @see mobile_switch_menu()
 * @see mobile_switch_preprocess_page()
 */
function mobile_switch_administer() {
  global $user;
  if (user_access('administer site configuration', $user)) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implementation of hook_form_alter().
 */
function mobile_switch_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'system_themes_form':
      $mobile_theme = variable_get('mobile_switch_mobile_theme', 'none');
      $themes = mobile_switch_get_themes();

      // Provide JS function to disable the mobile theme checkbox
      // on the themes administration list page.
      drupal_add_js(array(
        'mobileSwitch' => array(
          'mobileTheme' => $mobile_theme,
        ),
      ), 'setting');
      drupal_add_js(drupal_get_path('module', 'mobile_switch') . '/js/mobile_switch.admin.js', 'module', 'footer');
      if ($mobile_theme !== 'none' && isset($themes[$mobile_theme])) {
        if (isset($form[$mobile_theme])) {

          // Prepare the mobile theme description.
          $mobile_theme_description = '<em>';
          $mobile_theme_description .= $form[$mobile_theme]['info']['#value']['description'];
          $mobile_theme_description .= '<br />' . t('(default mobile theme by !mobile-switch)', array(
            '!mobile-switch' => l(t('Mobile Switch'), 'admin/settings/mobile-switch', array(
              'attributes' => array(
                'title' => t('Administer Mobile Switch'),
              ),
            )),
          ));
          $mobile_theme_description .= '</em>';
          $form[$mobile_theme]['info']['#value']['description'] = $mobile_theme_description;
        }
      }

      // Alter default theme description.
      $theme_default = $form['theme_default']['#default_value'];
      $theme_default_description = '<em>';
      $theme_default_description .= $form[$theme_default]['info']['#value']['description'];
      $theme_default_description .= '</em>';
      $form[$theme_default]['info']['#value']['description'] = $theme_default_description;
      $form['#submit'][] = 'mobile_switch_system_themes_form_submit';
      break;
  }
}

/**
 * Form submission handler for system_themes_form().
 *
 * Make sure when using the "Reset to defaults" function on the
 * theme administration list page that the mobile theme be disabled.
 *
 * @see mobile_switch_form_alter()
 */
function mobile_switch_system_themes_form_submit($form, &$form_state) {
  if ($form_state['clicked_button']['#id'] === 'edit-reset') {
    variable_set('mobile_switch_mobile_theme', 'none');
    drupal_set_message(t('The mobile theme has been disabled.'), 'status');
  }
}

/**
 * Display a user agent message or browscap details.
 */
function mobile_switch_preprocess_page(&$variables) {
  if (variable_get('mobile_switch_display_useragent', 0)) {
    if (mobile_switch_administer()) {
      $browser = browscap_get_browser(NULL, TRUE);
      $message = t('!mobile-switch information from browscap. User agent', array(
        '!mobile-switch' => l(t('Mobile Switch'), 'admin/settings/mobile-switch/development'),
      )) . ':<br />';
      $message .= $browser['useragent'];
      drupal_set_message(filter_xss_admin($message));
    }
  }
  if (variable_get('mobile_switch_display_browscapinfo', 0)) {
    if (mobile_switch_administer()) {
      $browser = browscap_get_browser(NULL, TRUE);
      $message = t('!mobile-switch information; browscap details', array(
        '!mobile-switch' => l(t('Mobile Switch'), 'admin/settings/mobile-switch/development'),
      )) . ':<br />';
      $message .= _mobile_switch_get_browscap_details($browser);
      drupal_set_message($message);
    }
  }
}

/**
 * Wrapper for browscap_get_browser().
 *
 * Extend the browscap device detection with additional device types.
 *
 * @param bool $emulator_check
 *   Boolean value to use mobile browser emulators.
 *
 * @see mobile_switch_boot()
 */
function mobile_switch_browscap_get_browser($emulator_check = FALSE) {
  static $browser;
  if (!isset($browser)) {

    // Fix a peculiarity of Broscap module branch 2+.
    // Browscap module is not loaded during bootstrap.
    if (!function_exists('browscap_get_browser')) {
      drupal_load('module', 'browscap');
    }
    $browser = browscap_get_browser(NULL, TRUE);

    // Mobile device emulators.
    if ($emulator_check === TRUE) {
      $emulator_strings = variable_get('mobile_switch_emulator_strings', "Fennec\nAndroid\nTablet\nMobi");
      $emulator_strings = str_replace(array(
        "\r\n",
        "\n",
        "\r",
      ), '|', $emulator_strings);
      if (preg_match("/{$emulator_strings}/i", $browser['useragent'])) {
        $browser['ismobiledevice'] = TRUE;
      }
    }

    // Mobile device prevention.
    $browser['prevent_device'] = FALSE;
    $prevent_devices = (bool) variable_get('mobile_switch_prevent_devices', FALSE);
    $prevent_devices_strings = variable_get('mobile_switch_prevent_devices_strings', '');
    if ($prevent_devices === TRUE && !empty($prevent_devices_strings)) {
      $prevent_devices_strings = str_replace(array(
        "\r\n",
        "\n",
        "\r",
      ), '|', $prevent_devices_strings);
      $strings_arr = explode("|", $prevent_devices_strings);
      foreach ($strings_arr as $val) {
        $found = stristr($browser['useragent'], $val);
        if (!empty($found)) {
          $browser['prevent_device'] = TRUE;
        }
      }
    }

    // Fix a peculiarity of Broscap module branch 2+.
    if ($browser['ismobiledevice'] === 'false') {
      $browser['ismobiledevice'] = FALSE;
    }
    if ($browser['ismobiledevice'] === 'true') {
      $browser['ismobiledevice'] = TRUE;
    }
  }
  return $browser;
}

/**
 * Helper function to determine the active themes.
 *
 * @see mobile_switch_settings_form()
 * @see mobile_switch.admin.inc
 */
function mobile_switch_get_themes() {
  $themes = array();
  foreach (list_themes() as $name => $value) {
    if ($value->status == 0) {
      continue;
    }
    $themes[$name] = preg_replace('/_/', ' ', ucfirst($value->name));
  }
  return $themes;
}

/**
 * Helper function to get browscap details.
 *
 * @param $browser
 *  Associative array from browscap.
 *
 * @return string
 *   HTML table contains browscap details.
 *
 * @see mobile_switch_preprocess_page()
 */
function _mobile_switch_get_browscap_details($browser) {
  $rows = array();
  foreach ($browser as $key => $value) {
    $rows[] = array(
      $key,
      filter_xss_admin($value),
    );
  }
  return theme('table', array(
    '',
    '',
  ), $rows, array(
    'id' => 'mobile-switch-browscap-details',
  ));
}

Functions

Namesort descending Description
mobile_switch_administer Access callback.
mobile_switch_boot Implementation of hook_boot().
mobile_switch_browscap_get_browser Wrapper for browscap_get_browser().
mobile_switch_form_alter Implementation of hook_form_alter().
mobile_switch_get_themes Helper function to determine the active themes.
mobile_switch_menu Implementation of hook_menu().
mobile_switch_preprocess_page Display a user agent message or browscap details.
mobile_switch_system_themes_form_submit Form submission handler for system_themes_form().
_mobile_switch_get_browscap_details Helper function to get browscap details.