You are here

mobile_tools.module in Mobile Tools 5

Mobile Tools provides a range of functionality assisting in creating a mobile drupal site . this functionality contains:

  • User Agent detection ('mobile' or 'desktop')
  • automatic redirection towards mobile site or user notification by means of a block message or drupal_set_message
  • Adding a mobile context to the permission system
  • Adding a mobile context to theming (= theme switching or seperate configuration for desktop and )

For more documentation and examples please go to http://drupal.org/node/459686

File

mobile_tools.module
View source
<?php

/**
 * @file
 * Mobile Tools provides a range of functionality assisting in creating a mobile drupal site . this functionality contains:
 * - User Agent detection ('mobile' or 'desktop')
 * - automatic redirection towards mobile site or user notification by means of a block message or drupal_set_message
 * - Adding a mobile context to the permission system
 * - Adding a mobile context to theming (= theme switching or seperate configuration for desktop and )     
 *  
 * For more documentation and examples please go to http://drupal.org/node/459686
 */

/* The default messages being displayed to the users . these can be overwritten in 
 * the configuration panel
 */
define('MOBILE_NOTIFICATION', 'Check out our mobile site at [mobile-url].');
define('DESKTOP_NOTIFICATION', 'Check out our desktop site at [desktop-url]');

/**
 * Implementation of hook_help($section).
 */
function mobile_tools_help($section) {
  switch ($section) {
    case 'admin/help#mobile_tools':
      $output .= '<p>' . t('The mobile tools module assembles a range of functionality helping out in making your Drupal site mobile. Visit the !documentation for more information') . '<p>';
  }
  return $output;
}

/**
 * Implementation of hook_perm().
 */
function mobile_tools_perm() {
  return array(
    'configure mobile tools',
  );
}

/**
 * Implementation of hook_menu().
 */
function mobile_tools_menu($may_cache) {
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/mobile-tools',
      'title' => t('Mobile Tools'),
      'description' => t('Configure the detection of the mobile client and the appropriate actions.'),
      'access' => user_access('configure mobile tools'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'mobile_tools_detection_configuration_form',
      ),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/settings/mobile-tools/device-detection',
      'title' => t('Notification / redirection'),
      'description' => 'Configure the detection of the mobile client and the appropriate actions (notifications or redirection)',
      'access' => user_access('configure mobile tools'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -4,
    );
    $items[] = array(
      'path' => 'admin/settings/mobile-tools/themes',
      'title' => t('Mobile theme'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'mobile_tools_themes_configuration_form',
      ),
      'access' => user_access('configure mobile tools'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 0,
    );
    $items[] = array(
      'path' => 'admin/settings/mobile-tools/roles',
      'title' => t('Mobile roles'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'mobile_tools_roles_configuration_form',
      ),
      'access' => user_access('configure mobile tools'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 0,
    );

    /*$items[] = array(
        'path' => 'admin/settings/mobile-tools/ready',
        'title' => t('ready.mobi'),
        'callback' => 'mobile_tools_ready_mobi',
        'callback arguments' => array('mobile_tools_roles_configuration_form'),
        'access' => user_access('configure mobile tools'),
        'type' => MENU_LOCAL_TASK,
        'weight' => 0,
      );*/
  }
  return $items;
}

/**
 * Implementation of hook_exit()
 */
function mobile_tools_exit() {

  //drupal_set_message($_SERVER['REQUEST_URI']);
  cache_clear_all(NULL, 'cache_page', TRUE);
}

/**
 *  Implementation of hook_boot().
 */
function mobile_tools_init() {
  cache_clear_all(NULL, 'cache_page', TRUE);
  global $conf;
  global $user;
  global $base_url;

  // Invoke the hook_is_mobile_device() and hook_is_mobile_site()
  $device_detection = variable_get('mobile-tools-device-detection', 'mobile_tools');
  if ($device_detection != 'mobile_tools') {
    drupal_load('module', $device_detection);
  }
  $site_detection = variable_get('mobile-tools-site-type-detection', 'mobile_tools');
  if ($site_detection != 'mobile_tools') {
    drupal_load('module', $site_detection);
  }
  $_SESSION['mobile-tools-mobile-device'] = module_invoke($device_detection, 'is_mobile_device');
  $_SESSION['mobile-tools-site-type'] = module_invoke($site_detection, 'is_mobile_site');
  if (variable_get('mobile_tools_enable_redirect', 0) == 1 && variable_get('mobile_tools_mobile_url', mobile_tools_create_mobile_url($base_url)) != variable_get('mobile_tools_desktop_url', $base_url)) {
    mobile_tools_detection_boot();

    // do the device detection, redirect or generate a notification
  }
  if (variable_get('mobile_tools_enable_theme', 0)) {
    mobile_tools_themes_init();

    // changes the theme
  }
  if (variable_get('mobile_tools_enable_roles', 0)) {
    mobile_tools_roles_init();

    // assigns the user the mobile role
  }
  if ($_SESSION['mobile-tools-site-type'] == 'mobile' || variable_get('mobile_tools_handling', '') == 'theme-switch' && $_SESSION['mobile-tools-mobile-device']['type'] == 'mobile') {
    variable_set('default_main_nodes', variable_get('default_nodes_main_mobile', 5));
  }
  else {
    variable_set('default_main_nodes', variable_get('default_nodes_main_original', 10));
  }
}

/**
 * Being called in the hook_init() implementation
 * This function is in charge of device detection, redirection or displaying a notification 
 */
function mobile_tools_detection_boot() {
  global $base_url;
  $handling = variable_get('mobile_tools_handling', 0);
  if ($_SESSION['mobile-tools-mobile-device']['type'] != $_SESSION['mobile-tools-site-type']) {
    switch ($handling) {
      case 'redirect':

        //redirect
        $destination = $_SESSION['mobile-tools-mobile-device']['type'] == 'mobile' ? variable_get('mobile_tools_mobile_url', mobile_tools_create_mobile_url($base_url)) : variable_get('mobile_tools_desktop_url', $base_url);
        mobile_tools_goto($destination);
        break;
    }
  }
}

/**
 *  Helper function returning the configurable message for the notification
 */
function _mobile_tools_message() {
  if ($_SESSION['mobile-tools-mobile-device']['type'] == 'mobile') {
    return token_replace(variable_get('mobile_notification', MOBILE_NOTIFICATION), 'mobile_tools');
  }
  else {
    return token_replace(variable_get('desktop_notification', DESKTOP_NOTIFICATION), 'mobile_tools');
  }
}

/**
 * Being called in the hook_init() implementation
 * This function is in charge of changing to the mobile theme 
 */
function mobile_tools_themes_init() {
  global $conf;
  if ($_SESSION['mobile-tools-site-type'] == 'mobile' && variable_get('mobile_tools_handling', '') != 'theme-switch' || variable_get('mobile_tools_handling', '') == 'theme-switch' && $_SESSION['mobile-tools-mobile-device']['type'] == 'mobile') {
    $group = $_SESSION['mobile-tools-mobile-device']['group'];
    $type = $_SESSION['mobile-tools-mobile-device']['type'];
    $mobile_detection_module = variable_get('mobile-tools-device-detection', 'mobile_tools');
    if (variable_get($mobile_detection_module . '_' . $group . '_enable', '') == 1) {
      $conf['theme_default'] = variable_get($mobile_detection_module . '_' . $group . '_theme', $conf['theme_default']);
    }
    else {
      $conf['theme_default'] = variable_get('mobile_tools_theme_name', $conf['theme_default']);
    }
  }
}

/**
 * Being called in the hook_init() implementation
 * This function is in charge of changing the user role 
 */
function mobile_tools_roles_init() {
  global $user;
  $roles = $user->roles;

  //count the number of mobile roles... must be bigger then 1
  $count = db_result(db_query("SELECT COUNT(*) as count FROM {mobile_tools_roles_relations}"));
  if ($count > 0) {
    foreach ($roles as $key => $value) {
      $role = mobile_tools_roles_info(array(
        'id' => $key,
      ));
      if ($role->type == 'desktop' && $role->has_sibling == 1 && $_SESSION['mobile-tools-site-type'] == 'mobile' || $_SESSION['mobile-tools-mobile-device']['type'] == 'mobile' && variable_get('mobile_tools_handling', FALSE) == 'theme-switch') {
        unset($user->roles[$key]);
        $user->roles[$role->sibling['id']] = $role->sibling['name'];
      }
    }
  }
}

/**
 * Implementation of hook_block()
 * Provides the blocks that can be used to show a message to the user to go to the
 * mobile or desktop version.  
 */
function mobile_tools_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      if (variable_get('mobile_tools_handling', 'notification') == 'notification' && variable_get('mobile_tools_enable_redirect', 0) == 1) {
        $blocks[0]['info'] = t('Mobile Tools block notification');
        return $blocks;
      }
      break;
    case 'view':
      if (variable_get('mobile_tools_handling', 'notification') == 'notification' && $_SESSION['mobile-tools-mobile-device']['type'] != $_SESSION['mobile-tools-site-type'] && variable_get('mobile_tools_enable_redirect', 0) == 1) {
        $block['title'] = '';
        $block['content'] = _mobile_tools_message();
        return $block;
      }
      break;
  }
}

/**
 * Configuration form for the mobile device detection, redirection and notification
 * 
 * @return
 *   The configuration form   
 */
function mobile_tools_detection_configuration_form() {
  global $base_url;
  $form['mobile_tools_configuration'] = array(
    '#type' => 'fieldset',
    '#title' => t('Configuration'),
    '#collapsible' => TRUE,
    '#description' => t('Configure the way Drupal detects the end user and how Mobile users are being redirected to your mobile site, or notified on the existence of a mobile site?'),
  );
  $form['mobile_tools_configuration']['mobile_tools_enable_redirect'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable device detection and further processing (redirection / notification / theme switching)'),
    '#description' => t('Enable or disable the notification and redirection functionality!'),
    '#default_value' => variable_get('mobile_tools_enable_redirect', 0),
  );
  $form['mobile_tools_configuration']['mobile_tools_handling'] = array(
    '#type' => 'radios',
    '#title' => t('Select the appropriate method'),
    '#default_value' => variable_get('mobile_tools_handling', 'notification'),
    '#options' => mobile_tools_detection_configuration_options('device handling'),
    '#description' => 'Choose one of these methodes!',
  );
  $form['mobile_tools_configuration']['mobile_tools_mobile_url'] = array(
    '#type' => 'textfield',
    '#title' => t('Mobile URL'),
    '#description' => t('Give the name of your mobile site. It is recommended to use the convention of m.domain .com or www.domain.mobi'),
    '#default_value' => variable_get('mobile_tools_mobile_url', mobile_tools_create_mobile_url($base_url)),
  );
  $form['mobile_tools_configuration']['mobile_tools_desktop_url'] = array(
    '#type' => 'textfield',
    '#title' => t('Desktop URL'),
    '#description' => t('Give the name of your regular website.'),
    '#collapsible' => TRUE,
    '#default_value' => variable_get('mobile_tools_desktop_url', $base_url),
  );
  $form['mobile_tools_notification'] = array(
    '#type' => 'fieldset',
    '#title' => t('Notification options'),
    '#collapsible' => TRUE,
    '#description' => t('Choose a text to be displayed to the visitors of your site and how many times the user gets the message. this will be used if you checked the "Display a notification" checkbox in the above configuration.'),
  );
  $form['mobile_tools_notification']['mobile_tools_times'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of impressions'),
    '#cols' => 2,
    '#default_value' => variable_get('mobile_tools_times', 0),
    '#description' => t('How many times do you want to show a notification (0 means always).'),
  );
  $form['mobile_tools_notification']['mobile_tools_notification_option'] = array(
    '#type' => 'radios',
    '#title' => t('When to display the notifications'),
    '#options' => array(
      t('Always'),
      t('Only when a mobile user looks at the desktop site, or a desktop users looks at the mobile site'),
    ),
    '#default_value' => 0,
  );
  $form['mobile_tools_notification']['mobile_notification'] = array(
    '#type' => 'textarea',
    '#rows' => 2,
    '#title' => t('On the desktop site'),
    '#default_value' => variable_get('mobile_notification', MOBILE_NOTIFICATION),
  );
  $form['mobile_tools_notification']['desktop_notification'] = array(
    '#type' => 'textarea',
    '#title' => t('On the mobile site'),
    '#rows' => 2,
    '#default_value' => variable_get('desktop_notification', DESKTOP_NOTIFICATION),
    '#suffix' => mobile_tools_notification_help(),
  );
  $form['frontpage'] = array(
    '#type' => 'fieldset',
    '#title' => t('Extra'),
    '#collapsible' => TRUE,
  );
  $form['frontpage']['default_nodes_main_mobile'] = array(
    '#type' => 'select',
    '#title' => t('Number of posts on main page for the mobile version'),
    '#default_value' => variable_get('default_nodes_main_mobile', 10),
    '#options' => array(
      1 => 1,
      2 => 2,
      3 => 3,
      4 => 4,
      5 => 5,
      6 => 6,
      7 => 7,
      8 => 8,
      9 => 9,
      10 => 10,
      15 => 15,
      20 => 20,
      25 => 25,
      30 => 30,
    ),
    '#description' => t('The default maximum number of posts to display per page on overview pages such as the main page (on Mobile).'),
  );
  $form['mobile_tools_detection'] = array(
    '#type' => 'fieldset',
    '#title' => t('External detection modules'),
    '#collapsible' => TRUE,
    '#description' => t('You can let other modules do the device detection or detect if your site is being mobilised.'),
  );
  $form['mobile_tools_detection']['mobile-tools-device-detection'] = array(
    '#type' => 'radios',
    '#title' => t('Device detection module'),
    '#default_value' => variable_get('mobile-tools-device-detection', 'mobile_tools'),
    '#options' => _mobile_tools_external('device-detection'),
    '#description' => t('Choose which module is in charge for detecting if the visiting device is a mobile device. The Mobile Tools provides a standard implementation. You can also use other modules'),
  );
  $form['mobile_tools_detection']['mobile-tools-site-type-detection'] = array(
    '#type' => 'radios',
    '#title' => t('Site type detection module'),
    '#default_value' => variable_get('mobile-tools-site-type-detection', 'mobile_tools'),
    '#options' => _mobile_tools_external('site-type-detection'),
    '#description' => 'This option is only used when your Drupal site is used for both the mobile as desktop version of the site.',
  );
  $form['mobile_tools_detection']['mobile-tools-device-capabilities'] = array(
    '#type' => 'radios',
    '#title' => t('Device capability detection'),
    '#default_value' => variable_get('mobile-tools-device-capabilities', 'wurfl'),
    '#options' => _mobile_tools_external('device-capability'),
    '#description' => t('The mobile tools module gives an abstract api in order to get capabilities of the mobile devices. These capability can be fetched by calling mobile_tools_devicecapability($capability). Capability can be for example "is_wireless_device". A full range of parameters can be found on !wurfl you need at least one capability module (like !wurfl2) to use this functionality', array(
      '!wurfl' => l('http://wurfl.sourceforge.net/help_doc.php', 'http://wurfl.sourceforge.net/help_doc.php'),
      '!wurfl2' => l('http://drupal.org/project/wurfl', 'http://drupal.org/project/wurfl'),
    )),
  );
  return system_settings_form($form);
}
function mobile_tools_notification_help() {
  $output .= '<div class="description">';
  $output .= 'Define your message that you want to display on your website to mobile users that are on your desktop site, or destkop users that are on your mobile site. Some tokens are available:';
  $output .= '<ul>';
  $output .= '<li>[mobile]: Displays the word Mobile. When the mobile user is on the mobile site, no hyperlink is attached to it. When the mobile user is on the desktop site, the word is clickable and brings the user to the mobbile site.';
  $output .= '<li>[desktop]: The desktop counterpart of [mobile]';
  $output .= '<li>[mobile-site-link]: Dislays the word "mobile" and contains always the link to the mobile site.';
  $output .= '<li>[desktop-site-link]: Displays the word "desktop" and contains always the link to the desktop site.';
  $output .= '<li>[mobile-url]: Displays the mobile url ';
  $output .= '<li>[desktop-url]: Displays the desktop url';
  $output .= '</ul>';
  $output .= 'A recommended message is: "Change site: [mobile] | [desktop]"';
  $output .= '</div>';
  return $output;
}

/**
 * Helper function to return the configuration options
 */
function mobile_tools_detection_configuration_options($configuration) {
  switch ($configuration) {
    case 'device handling':
      $options = array(
        'nothing' => t('Do nothing, just provide the $_SESSION[\'mobile_device\'] variable'),
        'redirect' => t('Automatic redirection to mobile or desktop site (requires a seperate mobile and desktop url!)'),
        'notification' => t('Display a block notification with link to mobile site (requires a seperate mobile and destkop url!)'),
        'theme-switch' => t('Switch the theme when a mobile user visits the site (only 1 url for both mobile and desktop url). Enable and configure the mobile theme !here', array(
          '!here' => l('here', 'admin/settings/mobile-tools/themes'),
        )),
      );
      break;
    case 'site type':
      $options = array(
        'mobile' => t('Only the mobile site'),
        'desktop' => t('only the deskop site'),
        'mobile-desktop' => t('for both mobile and desktop site'),
      );
      break;
  }
  return $options;
}

/**
 * Configuration form for configuring the mobile context in the permission system
 */
function mobile_tools_roles_configuration_form() {
  global $base_url;
  $form['mobile_tools_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Mobile Tools settings'),
    '#collapsible' => TRUE,
    '#description' => t('The Mobile Tools module allows the creation of a mobile version of each role . these mobile versions of each role will be assigned to the mobile user. In the !url configuration panel, you can assign permissions to the mobile user.', array(
      '!url' => l('permissions', 'admin/user/access'),
    )),
  );
  $form['mobile_tools_settings']['mobile_tools_enable_roles'] = array(
    '#type' => 'checkbox',
    '#title' => t('Activate mobile user roles'),
    '#description' => t('When activated, mobile users will get the mobile versions of their normal roles when the site is being mobilized.'),
    '#default_value' => variable_get('mobile_tools_enable_roles', 0),
  );
  $form['mobile_tools_roles'] = array(
    '#type' => 'fieldset',
    '#title' => t('Mobile roles'),
    '#collapsible' => TRUE,
    '#description' => t('Enable or disable the mobile version of each user role. When no mobile role is created, the user will
    keep it\'s normal role . the settings can also be configured in the !roles configuration section', array(
      '!roles' => l('roles', 'admin/user/roles'),
    )),
    '#suffix' => mobile_tools_roles_overview(),
  );
  $result = db_query("SELECT * FROM {role}");
  while ($item = db_fetch_object($result)) {
    $role = mobile_tools_roles_info(array(
      'id' => $item->rid,
    ));
    if ($role->type == 'desktop') {
      $form['mobile_tools_roles']['mobile_tools_role_' . $item->rid] = array(
        '#type' => 'checkbox',
        '#title' => $item->name,
        '#default_value' => $role->has_sibling ? TRUE : FALSE,
        '#description' => t('Enabling will create the %role role . the name can be changed aferwards in the !roles settings page', array(
          '%role' => $role->name . ' (Mobile)',
          '!roles' => l('roles', 'admin/user/roles'),
        )),
      );
    }
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}

/**
 * Implementation of hook_submit().
 */
function mobile_tools_roles_configuration_form_submit($form_id, $form_values) {
  variable_set('mobile_tools_enable_roles', $form_values['mobile_tools_enable_roles']);
  $query = "SELECT * FROM {role}";
  $result = db_query($query);
  while ($item = db_fetch_object($result)) {
    $role = mobile_tools_roles_info(array(
      'id' => $item->rid,
    ));
    if ($role->type == 'desktop') {
      $choice = $form_values['mobile_tools_role_' . $item->rid];
      if ($role->has_sibling == 1 && $choice == 0) {

        // DELETE
        mobile_tools_edit_mobile_role('delete', $role);
      }
      else {
        if ($role->has_sibling == 0 && $choice == 1) {
          mobile_tools_edit_mobile_role('add', $role);
        }
      }
    }
  }
}
function mobile_tools_roles_overview() {
  $query = "SELECT * FROM {mobile_tools_roles_relations}";
  $result = db_query($query);
  $rows = array();
  while ($item = db_fetch_object($result)) {
    $query = "SELECT * FROM {role} WHERE rid = %d";
    $result1 = db_query($query, $item->rid);
    $result2 = db_query($query, $item->mrid);
    $rows[] = array(
      db_fetch_object($result1)->name,
      db_fetch_object($result2)->name,
    );
  }
  $headers = array(
    "original role",
    "mobile role",
  );
  if (count($rows) == 0) {
    $output .= '<div class="message">No Mobile roles where assigned</div>';
  }
  else {
    $output .= theme('table', $headers, $rows);
    $output .= '<br>' . t('Configure the !permissions', array(
      '!permissions' => l('permissions', 'admin/user/access'),
    )) . '<br />';
  }
  return $output;
}

/**
 * Helper function to return the user roles
 */
function mobile_tools_user_roles() {

  //$roles = array('none');
  $roles = user_roles();
  $desktop_roles = array();
  foreach ($roles as $key => $value) {
    $role = mobile_tools_roles_info(array(
      'id' => $key,
    ));
    if ($role->type == 'desktop') {
      $desktop_roles[$key] = $value;
    }
  }
  return $desktop_roles;
}

/**
 * Configuration form for configuring the mobile context in the theming system
 */
function mobile_tools_themes_configuration_form() {
  $themes = mobile_tools_list_theme_names();
  $prefix = '';
  if (count($themes) == 0) {
    $warning = '<div class="message error">You must enable themes in order to use theme switching</div>';
  }
  $form['mobile_tools_theme_configuration'] = array(
    '#type' => 'fieldset',
    '#title' => t('Theming configuration'),
    '#collapsible' => TRUE,
    '#description' => t('You can assign a variation of your current theme to all mobile users . this allows you to configure your theme
      specific for mobile users. See !url for more information on this configuration.', array(
      '!url' => l('help', 'help'),
    )),
    '#suffix' => t('If enabled, !configure the settings of your mobile theme and manage the !blocks layout', array(
      '!configure' => l('configure', 'admin/build/themes'),
      '!blocks' => l('blocks', 'admin/build/block'),
    )) . '<br>',
    '#prefix' => $warning,
  );
  if (count($themes) > 0) {
    $form['mobile_tools_theme_configuration']['mobile_tools_enable_theme'] = array(
      '#type' => 'checkbox',
      '#title' => t('Enable the mobile theme'),
      '#default_value' => variable_get('mobile_tools_enable_theme', 0),
      '#description' => t('This option will only work if you have manually created a second *.info file in your theme directory.'),
    );
    $form['mobile_tools_theme_configuration']['mobile_tools_theme_name'] = array(
      '#type' => 'select',
      '#title' => t('Mobile theme'),
      '#default_value' => variable_get("mobile_tools_theme_name", FALSE),
      '#options' => $themes,
      '#description' => t('Select your mobile theme.'),
    );

    // for each group, checkbox and dropdown
    // Mobile
    $mobile_groups = module_invoke(variable_get('mobile-tools-device-detection', 'mobile_tools'), 'device_groups');
    $mobile_detection_module = variable_get('mobile-tools-device-detection', 'mobile_tools');
    foreach ($mobile_groups as $group) {
      $form['mobile_tools_theme_configuration'][$mobile_detection_module . '_' . $group] = array(
        '#type' => 'fieldset',
        '#title' => $group,
        '#collapsible' => TRUE,
      );
      $form['mobile_tools_theme_configuration'][$mobile_detection_module . '_' . $group][$mobile_detection_module . '_' . $group . '_enable'] = array(
        '#type' => 'checkbox',
        '#title' => t('Enable filter for this device group'),
        '#default_value' => variable_get($mobile_detection_module . '_' . $group . '_enable', ''),
        '#description' => t('Choose a theme for this device group'),
      );
      $form['mobile_tools_theme_configuration'][$mobile_detection_module . '_' . $group][$mobile_detection_module . '_' . $group . '_theme'] = array(
        '#type' => 'select',
        '#title' => t('Mobile theme'),
        '#default_value' => variable_get($mobile_detection_module . '_' . $group . '_theme', FALSE),
        '#options' => $themes,
        '#description' => t('Select your mobile theme. See <a href="">help</a> for information on the name'),
      );
    }
  }
  return system_settings_form($form);
}

/**
 * Function returning the available themes
 */
function mobile_tools_list_theme_names() {
  global $conf;
  $themes = list_themes();
  $list = array();
  foreach ($themes as $key => $value) {
    if ($value->status == 1) {
      $list[] = $key;
    }
  }
  if (count($list) == 0) {
    return array();
  }
  else {
    return array_combine($list, $list);
  }
}

/**
 *  Helper function to return the options for definition of the Drupal usage
 */
function mobile_tools_site_type_options() {
  $options = array(
    'mobile' => t('Only the mobile site'),
    'desktop' => t('only the deskop site'),
    'mobile-desktop' => t('for both mobile and desktop site'),
  );
  return $options;
}

/**
 *  Help function that retrieves the modules that implement the 
 *  hook_is_mobile_device() or hook_is_mobile_site() hooks. 
 */
function _mobile_tools_external($type) {
  switch ($type) {
    case 'device-detection':
      $modules = mobile_tools_get_module_names(module_implements('is_mobile_device'));
      break;
    case 'site-type-detection':
      $modules = mobile_tools_get_module_names(module_implements('is_mobile_site'));
      break;
    case 'device-capability':
      $modules = mobile_tools_get_module_names(module_implements('devicecapability'));
      break;
  }
  return $modules;
}

/**
 * Helper function to retrieve the name of the module that implements a hook
 * @param array of module names
 * @return array of module names keyed by module name
 */
function mobile_tools_get_module_names($module_names) {
  return array_combine($module_names, $module_names);
}

/**
 *  Implementation of the user_load function to assure that the right role is being assigned to the user.
 *  This is the same actions as in the hook_init() method 
 */
function mobile_tools_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'load':
      $user = $account;
      $roles = $user->roles;
      foreach ($roles as $key => $value) {
        $role = mobile_tools_roles_info(array(
          'id' => $key,
        ));
        if ($role->type == 'desktop' && $role->has_sibling == 1 && $_SESSION['mobile-tools-site-type'] == 'mobile') {
          unset($user->roles[$key]);
          $user->roles[$role->sibling['id']] = $role->sibling['name'];
        }
      }
      break;
  }
}

/**
 *  Implementation of hook_is_mobile_device()
 */
function mobile_tools_is_mobile_device() {
  $mobile_browser = array(
    'type' => 'desktop',
    'group' => '',
  );

  // set mobile browser as FALSE till we can prove otherwise
  $user_agent = $_SERVER['HTTP_USER_AGENT'];

  // get the user agent value - this should be cleaned to ensure no nefarious input gets executed
  $accept = $_SERVER['HTTP_ACCEPT'];

  // get the content accept value - this should be cleaned to ensure no nefarious input gets executed
  switch (TRUE) {
    case eregi('ipod', $user_agent):

      // we find the words iphone or ipod in the user agent
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => 'ipod',
      );

      // mobile browser is either TRUE or FALSE depending on the setting of iphone when calling the function
      break;

    // break out and skip the rest if we've had a match on the iphone or ipod
    case eregi('iphone', $user_agent):

      // we find the words iphone or ipod in the user agent
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => 'iphone',
      );
      break;
    case eregi('android', $user_agent):

      // we find android in the user agent
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => 'android',
      );

      // mobile browser is either TRUE or FALSE depending on the setting of android when calling the function
      break;

    // break out and skip the rest if we've had a match on android
    case eregi('opera mini', $user_agent):

      // we find opera mini in the user agent
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => 'opera mini',
      );

      // mobile browser is either TRUE or FALSE depending on the setting of opera when calling the function
      break;

    // break out and skip the rest if we've had a match on opera
    case eregi('blackberry', $user_agent):

      // we find blackberry in the user agent
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => 'blackberry',
      );

      // mobile browser is either TRUE or FALSE depending on the setting of blackberry when calling the function
      break;

    // break out and skip the rest if we've had a match on blackberry
    case preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|vodafone|o2|pocket|kindle|mobile|pda|psp|treo)/i', $user_agent):

      // check if any of the values listed create a match on the user agent - these are some of the most common terms used in agents to identify them as being mobile devices - the i at the end makes it case insensitive
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => '',
      );

      // set mobile browser to TRUE
      break;

    // break out and skip the rest if we've preg_match on the user agent returned TRUE
    case strpos($accept, 'text/vnd.wap.wml') > 0 || strpos($accept, 'application/vnd.wap.xhtml+xml') > 0:

      // is the device showing signs of support for text/vnd.wap.wml or application/vnd.wap.xhtml+xml
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => '',
      );

      // set mobile browser to TRUE
      break;

    // break out and skip the rest if we've had a match on the content accept headers
    case isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']):

      // is the device giving us a HTTP_X_WAP_PROFILE or HTTP_PROFILE header - only mobile devices would do this
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => '',
      );

      // set mobile browser to TRUE
      break;

    // break out and skip the final step if we've had a return TRUE on the mobile specfic headers
    case in_array(strtolower(substr($user_agent, 0, 4)), array(
      '1207' => '1207',
      '3gso' => '3gso',
      '4thp' => '4thp',
      '501i' => '501i',
      '502i' => '502i',
      '503i' => '503i',
      '504i' => '504i',
      '505i' => '505i',
      '506i' => '506i',
      '6310' => '6310',
      '6590' => '6590',
      '770s' => '770s',
      '802s' => '802s',
      'a wa' => 'a wa',
      'acer' => 'acer',
      'acs-' => 'acs-',
      'airn' => 'airn',
      'alav' => 'alav',
      'asus' => 'asus',
      'attw' => 'attw',
      'au-m' => 'au-m',
      'aur ' => 'aur ',
      'aus ' => 'aus ',
      'abac' => 'abac',
      'acoo' => 'acoo',
      'aiko' => 'aiko',
      'alco' => 'alco',
      'alca' => 'alca',
      'amoi' => 'amoi',
      'anex' => 'anex',
      'anny' => 'anny',
      'anyw' => 'anyw',
      'aptu' => 'aptu',
      'arch' => 'arch',
      'argo' => 'argo',
      'bell' => 'bell',
      'bird' => 'bird',
      'bw-n' => 'bw-n',
      'bw-u' => 'bw-u',
      'beck' => 'beck',
      'benq' => 'benq',
      'bilb' => 'bilb',
      'blac' => 'blac',
      'c55/' => 'c55/',
      'cdm-' => 'cdm-',
      'chtm' => 'chtm',
      'capi' => 'capi',
      'comp' => 'comp',
      'cond' => 'cond',
      'craw' => 'craw',
      'dall' => 'dall',
      'dbte' => 'dbte',
      'dc-s' => 'dc-s',
      'dica' => 'dica',
      'ds-d' => 'ds-d',
      'ds12' => 'ds12',
      'dait' => 'dait',
      'devi' => 'devi',
      'dmob' => 'dmob',
      'doco' => 'doco',
      'dopo' => 'dopo',
      'el49' => 'el49',
      'erk0' => 'erk0',
      'esl8' => 'esl8',
      'ez40' => 'ez40',
      'ez60' => 'ez60',
      'ez70' => 'ez70',
      'ezos' => 'ezos',
      'ezze' => 'ezze',
      'elai' => 'elai',
      'emul' => 'emul',
      'eric' => 'eric',
      'ezwa' => 'ezwa',
      'fake' => 'fake',
      'fly-' => 'fly-',
      'fly_' => 'fly_',
      'g-mo' => 'g-mo',
      'g1 u' => 'g1 u',
      'g560' => 'g560',
      'gf-5' => 'gf-5',
      'grun' => 'grun',
      'gene' => 'gene',
      'go.w' => 'go.w',
      'good' => 'good',
      'grad' => 'grad',
      'hcit' => 'hcit',
      'hd-m' => 'hd-m',
      'hd-p' => 'hd-p',
      'hd-t' => 'hd-t',
      'hei-' => 'hei-',
      'hp i' => 'hp i',
      'hpip' => 'hpip',
      'hs-c' => 'hs-c',
      'htc ' => 'htc ',
      'htc-' => 'htc-',
      'htca' => 'htca',
      'htcg' => 'htcg',
      'htcp' => 'htcp',
      'htcs' => 'htcs',
      'htct' => 'htct',
      'htc_' => 'htc_',
      'haie' => 'haie',
      'hita' => 'hita',
      'huaw' => 'huaw',
      'hutc' => 'hutc',
      'i-20' => 'i-20',
      'i-go' => 'i-go',
      'i-ma' => 'i-ma',
      'i230' => 'i230',
      'iac' => 'iac',
      'iac-' => 'iac-',
      'iac/' => 'iac/',
      'ig01' => 'ig01',
      'im1k' => 'im1k',
      'inno' => 'inno',
      'iris' => 'iris',
      'jata' => 'jata',
      'java' => 'java',
      'kddi' => 'kddi',
      'kgt' => 'kgt',
      'kgt/' => 'kgt/',
      'kpt ' => 'kpt ',
      'kwc-' => 'kwc-',
      'klon' => 'klon',
      'lexi' => 'lexi',
      'lg g' => 'lg g',
      'lg-a' => 'lg-a',
      'lg-b' => 'lg-b',
      'lg-c' => 'lg-c',
      'lg-d' => 'lg-d',
      'lg-f' => 'lg-f',
      'lg-g' => 'lg-g',
      'lg-k' => 'lg-k',
      'lg-l' => 'lg-l',
      'lg-m' => 'lg-m',
      'lg-o' => 'lg-o',
      'lg-p' => 'lg-p',
      'lg-s' => 'lg-s',
      'lg-t' => 'lg-t',
      'lg-u' => 'lg-u',
      'lg-w' => 'lg-w',
      'lg/k' => 'lg/k',
      'lg/l' => 'lg/l',
      'lg/u' => 'lg/u',
      'lg50' => 'lg50',
      'lg54' => 'lg54',
      'lge-' => 'lge-',
      'lge/' => 'lge/',
      'lynx' => 'lynx',
      'leno' => 'leno',
      'm1-w' => 'm1-w',
      'm3ga' => 'm3ga',
      'm50/' => 'm50/',
      'maui' => 'maui',
      'mc01' => 'mc01',
      'mc21' => 'mc21',
      'mcca' => 'mcca',
      'medi' => 'medi',
      'meri' => 'meri',
      'mio8' => 'mio8',
      'mioa' => 'mioa',
      'mo01' => 'mo01',
      'mo02' => 'mo02',
      'mode' => 'mode',
      'modo' => 'modo',
      'mot ' => 'mot ',
      'mot-' => 'mot-',
      'mt50' => 'mt50',
      'mtp1' => 'mtp1',
      'mtv ' => 'mtv ',
      'mate' => 'mate',
      'maxo' => 'maxo',
      'merc' => 'merc',
      'mits' => 'mits',
      'mobi' => 'mobi',
      'motv' => 'motv',
      'mozz' => 'mozz',
      'n100' => 'n100',
      'n101' => 'n101',
      'n102' => 'n102',
      'n202' => 'n202',
      'n203' => 'n203',
      'n300' => 'n300',
      'n302' => 'n302',
      'n500' => 'n500',
      'n502' => 'n502',
      'n505' => 'n505',
      'n700' => 'n700',
      'n701' => 'n701',
      'n710' => 'n710',
      'nec-' => 'nec-',
      'nem-' => 'nem-',
      'newg' => 'newg',
      'neon' => 'neon',
      'netf' => 'netf',
      'noki' => 'noki',
      'nzph' => 'nzph',
      'o2 x' => 'o2 x',
      'o2-x' => 'o2-x',
      'opwv' => 'opwv',
      'owg1' => 'owg1',
      'opti' => 'opti',
      'oran' => 'oran',
      'p800' => 'p800',
      'pand' => 'pand',
      'pg-1' => 'pg-1',
      'pg-2' => 'pg-2',
      'pg-3' => 'pg-3',
      'pg-6' => 'pg-6',
      'pg-8' => 'pg-8',
      'pg-c' => 'pg-c',
      'pg13' => 'pg13',
      'phil' => 'phil',
      'pn-2' => 'pn-2',
      'ppc;' => 'ppc;',
      'pt-g' => 'pt-g',
      'palm' => 'palm',
      'pana' => 'pana',
      'pire' => 'pire',
      'pock' => 'pock',
      'pose' => 'pose',
      'psio' => 'psio',
      'qa-a' => 'qa-a',
      'qc-2' => 'qc-2',
      'qc-3' => 'qc-3',
      'qc-5' => 'qc-5',
      'qc-7' => 'qc-7',
      'qc07' => 'qc07',
      'qc12' => 'qc12',
      'qc21' => 'qc21',
      'qc32' => 'qc32',
      'qc60' => 'qc60',
      'qci-' => 'qci-',
      'qwap' => 'qwap',
      'qtek' => 'qtek',
      'r380' => 'r380',
      'r600' => 'r600',
      'raks' => 'raks',
      'rim9' => 'rim9',
      'rove' => 'rove',
      's55/' => 's55/',
      'sage' => 'sage',
      'sams' => 'sams',
      'sc01' => 'sc01',
      'sch-' => 'sch-',
      'scp-' => 'scp-',
      'sdk/' => 'sdk/',
      'se47' => 'se47',
      'sec-' => 'sec-',
      'sec0' => 'sec0',
      'sec1' => 'sec1',
      'semc' => 'semc',
      'sgh-' => 'sgh-',
      'shar' => 'shar',
      'sie-' => 'sie-',
      'sk-0' => 'sk-0',
      'sl45' => 'sl45',
      'slid' => 'slid',
      'smb3' => 'smb3',
      'smt5' => 'smt5',
      'sp01' => 'sp01',
      'sph-' => 'sph-',
      'spv ' => 'spv ',
      'spv-' => 'spv-',
      'sy01' => 'sy01',
      'samm' => 'samm',
      'sany' => 'sany',
      'sava' => 'sava',
      'scoo' => 'scoo',
      'send' => 'send',
      'siem' => 'siem',
      'smar' => 'smar',
      'smit' => 'smit',
      'soft' => 'soft',
      'sony' => 'sony',
      't-mo' => 't-mo',
      't218' => 't218',
      't250' => 't250',
      't600' => 't600',
      't610' => 't610',
      't618' => 't618',
      'tcl-' => 'tcl-',
      'tdg-' => 'tdg-',
      'telm' => 'telm',
      'tim-' => 'tim-',
      'ts70' => 'ts70',
      'tsm-' => 'tsm-',
      'tsm3' => 'tsm3',
      'tsm5' => 'tsm5',
      'tx-9' => 'tx-9',
      'tagt' => 'tagt',
      'talk' => 'talk',
      'teli' => 'teli',
      'topl' => 'topl',
      'tosh' => 'tosh',
      'up.b' => 'up.b',
      'upg1' => 'upg1',
      'utst' => 'utst',
      'v400' => 'v400',
      'v750' => 'v750',
      'veri' => 'veri',
      'vk-v' => 'vk-v',
      'vk40' => 'vk40',
      'vk50' => 'vk50',
      'vk52' => 'vk52',
      'vk53' => 'vk53',
      'vm40' => 'vm40',
      'vx98' => 'vx98',
      'virg' => 'virg',
      'vite' => 'vite',
      'voda' => 'voda',
      'vulc' => 'vulc',
      'w3c ' => 'w3c ',
      'w3c-' => 'w3c-',
      'wapj' => 'wapj',
      'wapp' => 'wapp',
      'wapu' => 'wapu',
      'wapm' => 'wapm',
      'wig ' => 'wig ',
      'wapi' => 'wapi',
      'wapr' => 'wapr',
      'wapv' => 'wapv',
      'wapy' => 'wapy',
      'wapa' => 'wapa',
      'waps' => 'waps',
      'wapt' => 'wapt',
      'winc' => 'winc',
      'winw' => 'winw',
      'wonu' => 'wonu',
      'x700' => 'x700',
      'xda2' => 'xda2',
      'xdag' => 'xdag',
      'yas-' => 'yas-',
      'your' => 'your',
      'zte-' => 'zte-',
      'zeto' => 'zeto',
      'acs-' => 'acs-',
      'alav' => 'alav',
      'alca' => 'alca',
      'amoi' => 'amoi',
      'aste' => 'aste',
      'audi' => 'audi',
      'avan' => 'avan',
      'benq' => 'benq',
      'bird' => 'bird',
      'blac' => 'blac',
      'blaz' => 'blaz',
      'brew' => 'brew',
      'brvw' => 'brvw',
      'bumb' => 'bumb',
      'ccwa' => 'ccwa',
      'cell' => 'cell',
      'cldc' => 'cldc',
      'cmd-' => 'cmd-',
      'dang' => 'dang',
      'doco' => 'doco',
      'eml2' => 'eml2',
      'eric' => 'eric',
      'fetc' => 'fetc',
      'hipt' => 'hipt',
      'http' => 'http',
      'ibro' => 'ibro',
      'idea' => 'idea',
      'ikom' => 'ikom',
      'inno' => 'inno',
      'ipaq' => 'ipaq',
      'jbro' => 'jbro',
      'jemu' => 'jemu',
      'java' => 'java',
      'jigs' => 'jigs',
      'kddi' => 'kddi',
      'keji' => 'keji',
      'kyoc' => 'kyoc',
      'kyok' => 'kyok',
      'leno' => 'leno',
      'lg-c' => 'lg-c',
      'lg-d' => 'lg-d',
      'lg-g' => 'lg-g',
      'lge-' => 'lge-',
      'libw' => 'libw',
      'm-cr' => 'm-cr',
      'maui' => 'maui',
      'maxo' => 'maxo',
      'midp' => 'midp',
      'mits' => 'mits',
      'mmef' => 'mmef',
      'mobi' => 'mobi',
      'mot-' => 'mot-',
      'moto' => 'moto',
      'mwbp' => 'mwbp',
      'mywa' => 'mywa',
      'nec-' => 'nec-',
      'newt' => 'newt',
      'nok6' => 'nok6',
      'noki' => 'noki',
      'o2im' => 'o2im',
      'opwv' => 'opwv',
      'palm' => 'palm',
      'pana' => 'pana',
      'pant' => 'pant',
      'pdxg' => 'pdxg',
      'phil' => 'phil',
      'play' => 'play',
      'pluc' => 'pluc',
      'port' => 'port',
      'prox' => 'prox',
      'qtek' => 'qtek',
      'qwap' => 'qwap',
      'rozo' => 'rozo',
      'sage' => 'sage',
      'sama' => 'sama',
      'sams' => 'sams',
      'sany' => 'sany',
      'sch-' => 'sch-',
      'sec-' => 'sec-',
      'send' => 'send',
      'seri' => 'seri',
      'sgh-' => 'sgh-',
      'shar' => 'shar',
      'sie-' => 'sie-',
      'siem' => 'siem',
      'smal' => 'smal',
      'smar' => 'smar',
      'sony' => 'sony',
      'sph-' => 'sph-',
      'symb' => 'symb',
      't-mo' => 't-mo',
      'teli' => 'teli',
      'tim-' => 'tim-',
      'tosh' => 'tosh',
      'treo' => 'treo',
      'tsm-' => 'tsm-',
      'upg1' => 'upg1',
      'upsi' => 'upsi',
      'vk-v' => 'vk-v',
      'voda' => 'voda',
      'vx52' => 'vx52',
      'vx53' => 'vx53',
      'vx60' => 'vx60',
      'vx61' => 'vx61',
      'vx70' => 'vx70',
      'vx80' => 'vx80',
      'vx81' => 'vx81',
      'vx83' => 'vx83',
      'vx85' => 'vx85',
      'wap-' => 'wap-',
      'wapa' => 'wapa',
      'wapi' => 'wapi',
      'wapp' => 'wapp',
      'wapr' => 'wapr',
      'webc' => 'webc',
      'whit' => 'whit',
      'winw' => 'winw',
      'wmlb' => 'wmlb',
      'xda-' => 'xda-',
    )):

      // check against a list of trimmed user agents to see if we find a match
      $mobile_browser = array(
        'type' => 'mobile',
        'group' => '',
      );

      // set mobile browser to TRUE
      break;
  }
  return $mobile_browser;
}

/**
 *  Detection of the site type . the values comes out the configuration form.
 */
function mobile_tools_is_mobile_site() {
  if (variable_get('mobile-tools-site-type-detection', 'mobile_tools') == 'mobile_tools') {
    $site = _mobile_tools_site_detection();
    return $site;
  }
  else {
    return module_invoke(variable_get('mobile-tools-site-type-detection', 'mobile_tools'), 'is_mobile_site');
  }
}
function _mobile_tools_site_detection() {
  global $base_url;

  // first check if the url is a m.* or .mobi url!!
  $server_domain_elements = explode('.', $_SERVER['SERVER_NAME']);
  if (count($server_domain_elements) > 0) {
    if ($server_domain_elements[0] == 'm') {

      // check for m.* domain
      return 'mobile';
    }
    if ($server_domain_elements[count($server_domain_elements) - 1] == 'mobi') {

      // check for *.mobi
      return 'mobile';
    }
  }

  // If this doesn't return an answer, we will have to do a comparison of the mobile and desktop url!
  $mobile_url = parse_url(variable_get('mobile_tools_mobile_url', mobile_tools_create_mobile_url($base_url)));
  $mobile_url['host'] = mobile_tools_prepare_url($mobile_url['host']);
  $desktop_url = parse_url(variable_get('mobile_tools_desktop_url', $base_url));
  $desktop_url['host'] = mobile_tools_prepare_url($desktop_url['host']);
  if (!array_key_exists('path', $desktop_url)) {
    $desktop_url['path'] = '';
  }
  if (!array_key_exists('path', $mobile_url)) {
    $mobile_url['path'] = '';
  }
  $server_name = mobile_tools_prepare_url($_SERVER['SERVER_NAME']);

  // Check domain first
  if ($mobile_url['host'] == $server_name && $desktop_url['host'] != $server_name) {
    return 'mobile';
  }
  else {
    if ($mobile_url['host'] != $server_name && $desktop_url['host'] == $server_name) {
      return 'desktop';
    }
    else {
      if ($mobile_url['host'] == $server_name && $desktop_url['host'] == $server_name) {
        $significant = strlen($mobile_url['path']) > strlen($desktop_url['path']) ? 'mobile' : 'desktop';

        //we check the most significatn url (with the longest path)
        if (preg_match('|' . $desktop_url['path'] . '|', request_uri())) {
          if (preg_match('|' . $mobile_url['path'] . '|', request_uri())) {
            return $significant;

            // if both patterns match, return the significant
          }
          return 'desktop';
        }
        else {
          return 'mobile';
        }
      }
      else {
        return 'desktop';
      }
    }
  }
}

/**
 *  This function does some kind of normalisation of the urls when there is no subdomain available in the url
 *  e.g. domain.com becomes www.domain.com . this is because sometimes both www.domain.com and domain.com are the same 
 */
function mobile_tools_prepare_url($url) {
  $_url = parse_url($url);
  $_url = $url['host'];
  $_url = explode(".", $_url);
  if (count($_url) == 2) {
    return 'www' . implode(".", $_url);
  }
  else {
    return $url;
  }
}

/**
 * Helper function retrieving the device
 */
function mobile_tools_get_device() {
  $device = array();
  if ($_SESSION['mobile'] == 1) {
    $device['type'] = 'mobile';
  }
  else {
    $device['type'] = 'desktop';
  }
}

/**
 *  Implementation of the hook_token_values().
 */
function mobile_tools_token_values($type, $object = NULL) {
  global $base_url;
  if ($type == 'mobile_tools') {
    $mobile_url = variable_get('mobile_tools_mobile_url', mobile_tools_create_mobile_url($base_url));
    $desktop_url = variable_get('mobile_tools_desktop_url', $base_url);
    if ($mobile_url != FALSE || $desktop_url != FALSE) {
      $tokens['mobile-url'] = l($mobile_url, $mobile_url);
      $tokens['desktop-url'] = l($desktop_url, $desktop_url);
      $tokens['mobile-site-link'] = l('mobile site', $mobile_url);
      $tokens['desktop-site-link'] = l('desktop site', $desktop_url);
      if (mobile_tools_is_mobile_site() == 'mobile') {
        $tokens['mobile'] = t('Mobile');
        $tokens['desktop'] = l('Destkop', $desktop_url);
      }
      else {
        $tokens['mobile'] = l('Mobile', $mobile_url);
        $tokens['desktop'] = t('Desktop');
      }
      return $tokens;
    }
  }
}

/**
 * Altering the form for theme configuration to indicate that the theme is being used
 * as a mobile theme. 
 */
function mobile_tools_form_alter($form_id, &$form) {
  switch ($form_id) {
    case 'system_theme_settings':
      if (variable_get('mobile_tools_theme', FALSE) && arg(4) == variable_get('mobile_tools_theme_name', '')) {
        drupal_set_message(t('This theme will be used by Siruna when your site is being transcoded. Configure this for a mobile device'));
      }
      break;
    case 'user_admin_role':
      $query = "SELECT COUNT(*) as count FROM {mobile_tools_roles_relations} WHERE mrid = %d";
      $result = db_query($query, arg(4));
      $item = db_fetch_object($result);
      if ($item->count == 0) {
        $form['mobile_tools_configure_role_' . arg(4)] = array(
          '#type' => 'checkbox',
          '#title' => t('Create a mobile context for this user role'),
          '#default_value' => TRUE,
          '#description' => t('check if you want to add a mobile context to this role. Adding a mobile context will result in the creation of a new role that will be assigned to the user when the site is beeing mobilized. When unchecking all configurations will be lost for that role.'),
        );
        $form['mobile_tools_role_type'] = array(
          '#type' => 'hidden',
          '#value' => 'desktop',
        );
      }
      else {
        $form['mobile_tools_role_type'] = array(
          '#type' => 'hidden',
          '#value' => 'mobile',
        );
      }
      $form['#submit']['mobile_tools_roles_configuration_submit'] = array();
      break;
    case 'user_profile_form':
      unset($form['account']['roles']['#options']);
      $form['account']['roles']['#options'] = mobile_tools_user_roles();
      break;
    case 'node_configure':
      $form['default_nodes_main_mobile'] = array(
        '#type' => 'select',
        '#title' => t('Number of posts on main page for the mobile version'),
        '#default_value' => variable_get('default_nodes_main_mobile', 10),
        '#options' => array(
          1 => 1,
          2 => 2,
          3 => 3,
          4 => 4,
          5 => 5,
          6 => 6,
          7 => 7,
          8 => 8,
          9 => 9,
          10 => 10,
          15 => 15,
          20 => 20,
          25 => 25,
          30 => 30,
        ),
        '#description' => t('The default maximum number of posts to display per page on overview pages such as the main page (on Mobile).'),
      );
      $form['#submit']['mobile_tools_node_configuration_submit'] = array();
  }
}

/**
 * Implementation of hook_submit()
 */
function mobile_tools_node_configuration_submit($form_id, $form_values) {
  variable_set('default_main_nodes_original', $form_values['default_main_nodes']);
}

/**
 * Implementation of hook_submit()
 */
function mobile_tools_roles_configuration_submit($form_id, $form_values) {
  $role = mobile_tools_roles_info(array(
    'id' => $form['rid']['#value'],
  ));
  switch ($form['#post']['op']) {
    case 'Save role':
      if ($role->has_sibling == 1 && $form['#post']['mobile_tools_configure_role_' . $form['rid']['#value']] == FALSE && $role->type == 'desktop') {
        mobile_tools_edit_mobile_role('delete', $role);
      }
      elseif ($role->has_sibbling == FALSE && $form['#post']['mobile_tools_configure_role_' . $form['rid']['#value']] == TRUE && $role->type == 'desktop') {
        mobile_tools_edit_mobile_role('add', $role);
      }
      break;
    case 'Delete role':
      if ($role->type == 'mobile') {
        $role = mobile_tools_roles_info(array(
          'id' => $role->sibling['id'],
        ));
      }
      mobile_tools_edit_mobile_role('delete', $role);
  }
}

/**
 * Function helping in saving and deleting the mobile roles
 * @param $op
 *  the operation that has to be performed: 'delete' will delete the mobile role, 'add' will add the mobile role.  
 * @param $role
 *  the $role object of the normal role (the already existing non-mobile role) 
 */
function mobile_tools_edit_mobile_role($op, $role) {
  switch ($op) {
    case 'delete':
      db_query('DELETE FROM {role} WHERE rid = %d', $role->sibling['id']);
      db_query('DELETE FROM {mobile_tools_roles_relations} WHERE mrid = %d', $role->sibling['id']);
      break;
    case 'add':
      $result = db_query("INSERT INTO {role} (name) VALUES ('%s')", $role->name . ' (Mobile)');
      db_query("INSERT INTO {mobile_tools_roles_relations} (rid, mrid) VALUES (%d, %d)", $role->id, db_last_insert_id('role', 'rid'));
      break;
  }
}

/**
 * Helper function to assist in making a mobile url (m.*) from a given url
 * 
 * @parm $url
 *  orginal url
 * @return
 *  the mobile url     
 */
function mobile_tools_create_mobile_url($url) {
  $url_parsed = parse_url($url);
  if (!array_key_exists('path', $url_parsed)) {
    $url_parsed['path'] = "";
  }
  $url = $url_parsed['host'];
  $url = explode('.', $url);
  if (count($url) == 3) {
    $url[0] = 'm';
    return 'http://' . implode('.', $url) . $url_parsed['path'];
  }
  else {
    if (count($url) == 2) {
      return 'http://m.' . implode('.', $url) . $url_parsed['path'];
    }
    else {
      return 'http://' . implode('.', $url) . $url_parsed['path'] . '/mobile';
    }
  }
}

/**
 * Function helping in getting information for each role:
 * @param $identifier
 *  array('id' => id) or array('name' => name)
 *   
 * @return
 *    a $role object with the folowing info 
 *  $role->id
 * $role->name 
 * $role->type = mobile/desktop
 * $role->sibling[id]
 * $role->sibling[name]  
 */
function mobile_tools_roles_info($identifier) {
  if (array_key_exists('id', $identifier)) {
    $query = "SELECT * FROM {role} WHERE rid = %d";
    $result = db_query($query, $identifier['id']);
    $name = db_fetch_object($result)->name;
    $rid = $identifier['id'];
  }
  else {
    if (array_key_exists('name', $identifier)) {
      $query = "SELECT * FROM {role} WHERE name = '%s'";
      $result = db_query($query, $identifier['name']);
      $rid = db_fetch_object($result)->rid;
      $name = $identifier['name'];
    }
  }
  $role->id = $rid;
  $role->name = $name;
  $query = "SELECT COUNT(*) as count, mrid FROM {mobile_tools_roles_relations} WHERE rid = %d GROUP BY mrid";
  $result = db_query($query, $rid);
  $item = db_fetch_object($result);
  if ($item->count != 0) {
    $role->type = 'desktop';
    $role->has_sibling = 1;
    $result = db_query("SELECT * FROM {role} WHERE rid = %d", $item->mrid);
    $sibling = db_fetch_object($result);
  }
  else {
    $result = db_query("SELECT COUNT(*) as count, rid FROM {mobile_tools_roles_relations} WHERE mrid = %d GROUP BY rid", $rid);
    $item = db_fetch_object($result);
    if ($item->count == 0) {
      $role->has_sibling = 0;
      $role->type = 'desktop';
    }
    else {
      $role->type = 'mobile';
      $role->has_sibling = 1;
      $result = db_query("SELECT * FROM {role} WHERE rid = %d", $item->rid);
      $sibling = db_fetch_object($result);
    }
  }
  $role->sibling['id'] = $sibling->rid;
  $role->sibling['name'] = $sibling->name;
  return $role;
}

/**
 * Implementation of hook_devicecapability()
 * This default implementation invokes the responsible module
 */
function mobile_tools_devicecapability($capability) {
  return module_invoke(variable_get('mobile-tools-device-capability', 'wurfl'), 'devicecapability', $capability);
}

/**
 *  implementation of the hook_device_groups()
 *  This function returns the different device groups where this module can make a distinction for. This can be used
 *  to select different themes for different device groups.   
 */
function mobile_tools_device_groups() {
  return array(
    'iphone',
    'ipod',
    'android',
    'opera mini',
    'blackberry',
  );
}
function mobile_tools_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
  $url = $path;

  // Make the given path or URL absolute
  if (!preg_match('/^[a-z]+:\\/\\//', $url)) {
    global $base_url;
    $url = $base_url . '/' . $url;
  }
  $url .= empty($query) ? '' : '?' . $query;
  $url .= empty($fragment) ? '' : '#' . $fragment;

  // Remove newlines from the URL to avoid header injection attacks.
  $url = str_replace(array(
    "\n",
    "\r",
  ), '', $url);

  // Before the redirect, allow modules to react to the end of the page request.
  bootstrap_invoke_all('exit');

  // Even though session_write_close() is registered as a shutdown function, we
  // need all session data written to the database before redirecting.
  session_write_close();
  header('Location: ' . $url, TRUE, $http_response_code);

  // The "Location" header sends a REDIRECT status code to the http
  // daemon. In some cases this can go wrong, so we make sure none
  // of the code below the drupal_goto() call gets executed when we redirect.
  exit;
}
function mobile_tools_compatibility() {
  return array(
    'themekey',
    'domain',
    'image_fupload',
  );
}

Functions

Namesort descending Description
mobile_tools_block Implementation of hook_block() Provides the blocks that can be used to show a message to the user to go to the mobile or desktop version.
mobile_tools_compatibility
mobile_tools_create_mobile_url Helper function to assist in making a mobile url (m.*) from a given url
mobile_tools_detection_boot Being called in the hook_init() implementation This function is in charge of device detection, redirection or displaying a notification
mobile_tools_detection_configuration_form Configuration form for the mobile device detection, redirection and notification
mobile_tools_detection_configuration_options Helper function to return the configuration options
mobile_tools_devicecapability Implementation of hook_devicecapability() This default implementation invokes the responsible module
mobile_tools_device_groups implementation of the hook_device_groups() This function returns the different device groups where this module can make a distinction for. This can be used to select different themes for different device groups.
mobile_tools_edit_mobile_role Function helping in saving and deleting the mobile roles
mobile_tools_exit Implementation of hook_exit()
mobile_tools_form_alter Altering the form for theme configuration to indicate that the theme is being used as a mobile theme.
mobile_tools_get_device Helper function retrieving the device
mobile_tools_get_module_names Helper function to retrieve the name of the module that implements a hook
mobile_tools_goto
mobile_tools_help Implementation of hook_help($section).
mobile_tools_init Implementation of hook_boot().
mobile_tools_is_mobile_device Implementation of hook_is_mobile_device()
mobile_tools_is_mobile_site Detection of the site type . the values comes out the configuration form.
mobile_tools_list_theme_names Function returning the available themes
mobile_tools_menu Implementation of hook_menu().
mobile_tools_node_configuration_submit Implementation of hook_submit()
mobile_tools_notification_help
mobile_tools_perm Implementation of hook_perm().
mobile_tools_prepare_url This function does some kind of normalisation of the urls when there is no subdomain available in the url e.g. domain.com becomes www.domain.com . this is because sometimes both www.domain.com and domain.com are the same
mobile_tools_roles_configuration_form Configuration form for configuring the mobile context in the permission system
mobile_tools_roles_configuration_form_submit Implementation of hook_submit().
mobile_tools_roles_configuration_submit Implementation of hook_submit()
mobile_tools_roles_info Function helping in getting information for each role:
mobile_tools_roles_init Being called in the hook_init() implementation This function is in charge of changing the user role
mobile_tools_roles_overview
mobile_tools_site_type_options Helper function to return the options for definition of the Drupal usage
mobile_tools_themes_configuration_form Configuration form for configuring the mobile context in the theming system
mobile_tools_themes_init Being called in the hook_init() implementation This function is in charge of changing to the mobile theme
mobile_tools_token_values Implementation of the hook_token_values().
mobile_tools_user Implementation of the user_load function to assure that the right role is being assigned to the user. This is the same actions as in the hook_init() method
mobile_tools_user_roles Helper function to return the user roles
_mobile_tools_external Help function that retrieves the modules that implement the hook_is_mobile_device() or hook_is_mobile_site() hooks.
_mobile_tools_message Helper function returning the configurable message for the notification
_mobile_tools_site_detection

Constants