You are here

high_contrast.module in High contrast 7

Same filename and directory in other branches
  1. 8 high_contrast.module
  2. 6 high_contrast.module

High Contrast main module file.

File

high_contrast.module
View source
<?php

/**
 * @file
 * High Contrast main module file.
 */

/*
 * @todo Provide hooks: hook_high_contrast_enable, hook_high_contrast_disable.
 * @todo Make it work if cache is enabled.
 * @todo Add widgets: select list, radio buttons, etc.
 * @todo Improve CSS stylesheet.
 * @todo Logo change only works with delta_blocks modules logo block.
 * @todo Allow also jpg as default high contrast logo.
 */
define('HIGH_CONTRAST_CSS_PATH', 'css/high_contrast.css');

/**
 * Implements hook_init().
 */
function high_contrast_init() {
  $theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));

  // @todo: needed?
  drupal_add_css(drupal_get_path('module', 'high_contrast') . '/high_contrast.css');
  $high_contrast = [
    'link' => _high_contrast_link(),
  ];
  if (_high_contrast_css_exists()) {
    $high_contrast['cssFilePath'] = '/' . $theme_path . '/' . HIGH_CONTRAST_CSS_PATH;
  }
  else {

    // @todo: should nob be written on every request.
    $current_css_path = 'public://high_contrast_current.css';
    file_unmanaged_save_data(_high_contrast_get_current_css_styles(), $current_css_path, FILE_EXISTS_REPLACE);
    $high_contrast['cssFilePath'] = file_create_url($current_css_path);
  }

  // Get original logo path so we can find the img element from DOM and start
  // switching with high contrast version.
  // @todo: should we first try and read theme_get_setting('logo_path')?
  $logoPath = theme_get_setting('logo');
  if (!empty($logoPath)) {
    $high_contrast['logoPath'] = theme_get_setting('logo');
  }

  // Set high contrast logo path.
  if (_high_contrast_variable_get('high_contrast_default_logo') == 0 && _high_contrast_variable_get('high_contrast_logo_path') !== '') {
    $high_contrast['highContrastLogoPath'] = file_create_url(_high_contrast_variable_get('high_contrast_logo_path'));
  }
  elseif (file_exists($theme_path . '/logo-hg.png')) {
    $high_contrast['highContrastLogoPath'] = file_create_url($theme_path . '/logo-hg.png');
  }

  // Load main js as first script and after last css.
  // Should be fastest execution time.
  $high_contrast_min = file_get_contents(drupal_get_path('module', 'high_contrast') . '/js/high_contrast.min.js');

  // Fix 'Uncaught SyntaxError: Unexpected token ILLEGAL' in Chrome.
  $high_contrast_min = str_replace('id=\'high-contrast-css-placeholder\'></script>', 'id=\'high-contrast-css-placeholder\'>\\x3C/script>', $high_contrast_min);
  drupal_add_js('var highContrast = ' . json_encode($high_contrast) . ';' . $high_contrast_min, [
    'type' => 'inline',
    'weight' => '-999',
    'group' => '-999',
  ]);
}

/**
 * Implements hook_menu().
 */
function high_contrast_menu() {
  $items['admin/config/user-interface/high-contrast'] = [
    'title' => 'High Contrast',
    'description' => 'Settings related to High Contrast',
    'page callback' => 'drupal_get_form',
    'page arguments' => [
      'high_contrast_settings_form',
    ],
    'access callback' => 'user_access',
    'access arguments' => [
      'administer site configuration',
    ],
  ];
  return $items;
}

/**
 * Implements hook_block_info().
 */
function high_contrast_block_info() {
  $blocks = [];
  $blocks['high_contrast_switcher'] = [
    'info' => t('High contrast switcher'),
    'cache' => DRUPAL_CACHE_GLOBAL,
  ];
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function high_contrast_block_view($delta = '') {
  $block = [];
  switch ($delta) {
    case 'high_contrast_switcher':
      $block['subject'] = '<none>';
      $block['content'] = theme('high_contrast_switcher');
      break;
  }
  return $block;
}

/**
 * Settings form.
 */
function high_contrast_settings_form() {
  $form = [];
  $theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));
  $widgets = [
    'links' => 'Links',
  ];
  $form['high_contrast_switcher_widget'] = [
    '#type' => 'select',
    '#title' => t('Switcher widget'),
    '#default_value' => _high_contrast_variable_get('high_contrast_switcher_widget'),
    '#options' => $widgets,
    '#required' => TRUE,
  ];
  $form['high_contrast_switcher_label'] = [
    '#type' => 'textfield',
    '#title' => t('Switcher label'),
    '#default_value' => _high_contrast_variable_get('high_contrast_switcher_label'),
    '#required' => TRUE,
  ];
  $form['high_contrast_high_label'] = [
    '#type' => 'textfield',
    '#title' => t('High contrast label'),
    '#default_value' => _high_contrast_variable_get('high_contrast_high_label'),
    '#required' => TRUE,
  ];
  $form['high_contrast_separator'] = [
    '#type' => 'textfield',
    '#title' => t('Separator'),
    '#default_value' => _high_contrast_variable_get('high_contrast_separator'),
    '#required' => TRUE,
  ];
  $form['high_contrast_normal_label'] = [
    '#type' => 'textfield',
    '#title' => t('Normal contrast label'),
    '#default_value' => _high_contrast_variable_get('high_contrast_normal_label'),
    '#required' => TRUE,
  ];
  if (!_high_contrast_css_exists()) {
    $form['high_contrast_css_styles'] = [
      '#type' => 'textarea',
      '#title' => t('Used CSS styles'),
      '#default_value' => _high_contrast_get_current_css_styles(),
      '#required' => TRUE,
      '#attributes' => [
        'style' => 'width:50em; height:30em; line-height:1.2em; font-family:"Courier New", "Courier";',
      ],
      '#description' => 'To use css file, create high_contrast.css file under your theme css folder (' . HIGH_CONTRAST_CSS_PATH . ').',
    ];
    $form['high_contrast_css_styles']['#suffix'] = t('<p>Default CSS styles used to override the active theme:</p>');
    $form['high_contrast_css_styles']['#suffix'] .= '<div><pre>' . _high_contrast_get_default_css_styles() . '</pre></div>';
  }
  else {
    $form['high_contrast_css_styles'] = [
      '#type' => 'item',
      '#markup' => t('High contrast is using !css_path', [
        '!css_path' => $theme_path . '/' . HIGH_CONTRAST_CSS_PATH,
      ]),
    ];
  }
  $form['high_contrast_logo'] = [
    '#type' => 'fieldset',
    '#title' => t('High contrast logo image settings'),
    '#description' => t('If toggled on, the following high contrast logo will be displayed.'),
    '#attributes' => [
      'class' => [
        'theme-settings-bottom',
      ],
    ],
  ];
  $form['high_contrast_logo']['high_contrast_default_logo'] = [
    '#type' => 'checkbox',
    '#title' => t('Use the default logo (file named logo-hg in your theme folder if it exists'),
    '#default_value' => _high_contrast_variable_get('high_contrast_default_logo'),
    '#tree' => FALSE,
    '#description' => t('Check here if you want the theme to use the logo supplied with it.'),
  ];
  $form['high_contrast_logo']['high_contrast_settings'] = [
    '#type' => 'container',
    '#states' => [
      // Hide the logo settings when using the default logo.
      'invisible' => [
        'input[name="high_contrast_default_logo"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['high_contrast_logo']['high_contrast_settings']['high_contrast_logo_path'] = [
    '#type' => 'textfield',
    '#title' => t('Path to custom high contrast logo'),
    '#description' => t('The path to the file you would like to use as your logo file instead of the default logo.'),
    '#default_value' => _high_contrast_variable_get('high_contrast_logo_path'),
  ];
  $form['high_contrast_logo']['high_contrast_settings']['high_contrast_logo_upload'] = [
    '#type' => 'file',
    '#title' => t('Upload high contrast logo image'),
    '#maxlength' => 40,
    '#description' => t("If you don't have direct file access to the server, use this field to upload your logo."),
  ];
  $form = system_settings_form($form);

  // We don't want to call system_settings_form_submit(), so change #submit.
  array_pop($form['#submit']);
  $form['#submit'][] = 'high_contrast_settings_form_submit';
  $form['#validate'][] = 'high_contrast_settings_form_validate';
  return $form;
}

/**
 * Validator for the system_theme_settings() form.
 */
function high_contrast_settings_form_validate($form, &$form_state) {

  // Handle file uploads.
  $validators = [
    'file_validate_is_image' => [],
  ];

  // Check for a new uploaded logo.
  $file = file_save_upload('high_contrast_logo_upload', $validators);
  if (isset($file)) {

    // File upload was attempted.
    if ($file) {

      // Put the temporary file in form_values so we can save it on submit.
      $form_state['values']['high_contrast_logo_upload'] = $file;
    }
    else {

      // File upload failed.
      form_set_error('high_contrast_logo_upload', t('The logo could not be uploaded.'));
    }
  }
}

/**
 * Process high_contrast_settings_form form submissions.
 */
function high_contrast_settings_form_submit($form, &$form_state) {

  // Exclude unnecessary elements before saving.
  form_state_values_clean($form_state);
  $values = $form_state['values'];

  // If the user uploaded a new logo or favicon, save it to a permanent location
  // and use it in place of the default theme-provided file.
  if ($file = $values['high_contrast_logo_upload']) {
    unset($values['high_contrast_logo_upload']);
    $filename = file_unmanaged_copy($file->uri);
    $values['high_contrast_default_logo'] = 0;
    $values['high_contrast_logo_path'] = $filename;
    $values['high_contrast_toggle_logo'] = 1;
  }

  // If the user entered a path relative to the system files directory for
  // a logo or favicon, store a public:// URI so the theme system can handle it.
  if (!empty($values['high_contrast_logo_path'])) {
    $values['high_contrast_logo_path'] = _high_contrast_theme_settings_validate_path($values['high_contrast_logo_path']);
  }
  foreach ($values as $key => $val) {
    variable_set($key, $val);
  }
  drupal_set_message(t('The configuration options have been saved.'));
  cache_clear_all();
}

/**
 * Toggle high contrast styles and redirects the user to a destination url.
 */
function high_contrast_switch($enable = FALSE) {
  $destination = '';
  $_SESSION['high_contrast_activated'] = $enable;
  if (isset($_GET['destination'])) {
    $destination = $_GET['destination'];
  }
  drupal_goto($destination);
}

/**
 * Implements hook_theme().
 */
function high_contrast_theme() {
  return [
    'high_contrast_switcher' => [
      'render element' => 'element',
    ],
    'high_contrast_switcher_links' => [
      'render element' => 'element',
    ],
  ];
}

/**
 * Theme function for high contrast switcher.
 */
function theme_high_contrast_switcher($vars) {
  $code = theme('high_contrast_switcher_links');

  /*
   * //TO-DO: More widgets
   * $widget = _high_contrast_variable_get('high_contrast_widget');
   *
   * if ($widget == 'select'){
   * $code = theme('high_contrast_switcher_select');
   * }
   * else if ($widget == 'radio'){
   * $code = theme('high_contrast_switcher_radio');
   * }
   * else{
   * $code = theme('high_contrast_switcher_links');
   * }
   */
  return $code;
}

/**
 * Get HTML for switcher links().
 */
function theme_high_contrast_switcher_links($vars) {
  $label = t(_high_contrast_variable_get('high_contrast_switcher_label'));
  $link_high = l(t(_high_contrast_variable_get('high_contrast_high_label')), 'javascript:drupalHighContrast.enableStyles()', [
    'fragment' => '',
    'external' => TRUE,
  ]);
  $link_normal = l(t(_high_contrast_variable_get('high_contrast_normal_label')), 'javascript:drupalHighContrast.disableStyles()', [
    'fragment' => '',
    'external' => TRUE,
  ]);
  $separator = _high_contrast_variable_get('high_contrast_separator');

  // Output.
  $code = '
    <div class="high_contrast_switcher high_contrast_switcher_links">
      <p>
        <span class="high_contrast_switcher_label">' . $label . '</span>' . '<span class="high_contrast_switcher_high">' . $link_high . '</span>' . '<span class="high_contrast_switcher_separator">' . $separator . '</span>' . '<span class="high_contrast_switcher_normal">' . $link_normal . '</span>' . '</p>
    </div>
    ';
  return $code;
}

/**
 * Implements hook_preprocess_html().
 */
function high_contrast_preprocess_html(&$vars) {
  if (isset($_SESSION['high_contrast_activated']) && $_SESSION['high_contrast_activated'] == 1) {
    $vars['classes_array'][] = 'high-contrast';
  }
}

/**
 * HELPER FUNCTIONS.
 */

/**
 * Wrapper for variable_get().
 */
function _high_contrast_variable_get($var) {
  return variable_get($var, '');
}

/**
 * Get default css styles if none exist yet.
 */
function _high_contrast_get_current_css_styles() {
  $theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));
  if (_high_contrast_css_exists()) {
    $styles = file_get_contents($theme_path . '/' . HIGH_CONTRAST_CSS_PATH);
  }
  else {
    $styles = _high_contrast_variable_get('high_contrast_css_styles');
    if (empty($styles)) {
      $styles = _high_contrast_get_default_css_styles();
      variable_set('high_contrast_css_styles', $styles);
    }
  }
  return $styles;
}

/**
 * Default CSS.
 */
function _high_contrast_get_default_css_styles() {
  $color1 = 'black';
  $color2 = 'yellow';
  $color3 = 'white';
  $css = '
*{
  background-color:' . $color1 . ' !important;
  background-image:none !important;
  color:' . $color3 . ' !important;
  line-height:1.5em !important;
  text-shadow: none !important;
}

a, a *{
  background-color:' . $color1 . ' !important;
  color:' . $color2 . ' !important;
  text-decoration:underline !important;
}
  a:hover, a:hover *{
    background-color:' . $color2 . ' !important;
    color:' . $color1 . ' !important;
    text-decoration:underline !important;
    text-decoration:none !important;
  }

input{
  background-color:' . $color3 . ' !important;
  color:' . $color1 . ' !important;
}

input[type=submit],
input[type=button],
button{
  background-color: ' . $color2 . ' !important;
  color: ' . $color1 . ' !important;
}
  input[type=submit]:hover,
  input[type=button]:hover,
  button:hover{
    text-decoration:underline !important;
  }
';
  return $css;
}

/**
 * Helper function for the system_theme_settings form.
 *
 * Attempts to validate normal system paths, paths relative to the public files
 * directory, or stream wrapper URIs. If the given path is any of the above,
 * returns a valid path or URI that the theme system can display.
 *
 * @param string $path
 *   A path relative to the Drupal root or to the public files directory, or
 *   a stream wrapper URI.
 *
 * @return mixed
 *   A valid path that can be displayed through the theme system, or FALSE if
 *   the path could not be validated.
 */
function _high_contrast_theme_settings_validate_path($path) {

  // Absolute local file paths are invalid.
  if (drupal_realpath($path) == $path) {
    return FALSE;
  }

  // A path relative to the Drupal root or a fully qualified URI is valid.
  if (is_file($path)) {
    return $path;
  }

  // Prepend 'public://' for relative file paths within public filesystem.
  if (file_uri_scheme($path) === FALSE) {
    $path = 'public://' . $path;
  }
  if (is_file($path)) {
    return $path;
  }
  return FALSE;
}

/**
 * Helper function to find out if the css/high_contrast.css exists.
 */
function _high_contrast_css_exists() {
  $theme_path = drupal_get_path('theme', variable_get('theme_default', NULL));
  if (file_exists($theme_path . '/' . HIGH_CONTRAST_CSS_PATH)) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Return high contrast toggle link HTML.
 *
 * It's needed because we load the js really early and we don't have
 * Drupal.t() set there to translate the link.
 *
 * @return string
 *   HTML for toggle link.
 */
function _high_contrast_link() {
  $destination = drupal_get_destination();
  return l(t('Toggle high contrast'), '', [
    'attributes' => [
      'class' => [
        'element-invisible',
        'element-focusable',
      ],
      'rel' => 'nofollow',
    ],
  ]);
}

Functions

Namesort descending Description
high_contrast_block_info Implements hook_block_info().
high_contrast_block_view Implements hook_block_view().
high_contrast_init Implements hook_init().
high_contrast_menu Implements hook_menu().
high_contrast_preprocess_html Implements hook_preprocess_html().
high_contrast_settings_form Settings form.
high_contrast_settings_form_submit Process high_contrast_settings_form form submissions.
high_contrast_settings_form_validate Validator for the system_theme_settings() form.
high_contrast_switch Toggle high contrast styles and redirects the user to a destination url.
high_contrast_theme Implements hook_theme().
theme_high_contrast_switcher Theme function for high contrast switcher.
theme_high_contrast_switcher_links Get HTML for switcher links().
_high_contrast_css_exists Helper function to find out if the css/high_contrast.css exists.
_high_contrast_get_current_css_styles Get default css styles if none exist yet.
_high_contrast_get_default_css_styles Default CSS.
_high_contrast_link Return high contrast toggle link HTML.
_high_contrast_theme_settings_validate_path Helper function for the system_theme_settings form.
_high_contrast_variable_get Wrapper for variable_get().

Constants