You are here

dynamic_background.module in Dynamic Background 7

Same filename and directory in other branches
  1. 6 dynamic_background.module
  2. 7.2 dynamic_background.module

This module enables administrators to upload images used as background on the site. The selected background image link is exposed as either $background in the page.tpl file or as /background.css.

File

dynamic_background.module
View source
<?php

/**
 * @file
 * This module enables administrators to upload images used as background on
 * the site. The selected background image link is exposed as either $background
 * in the page.tpl file or as /background.css.
 *
 */

// Get the upload form element
module_load_include('inc', 'dynamic_background', 'includes/upload.form');

/**
 * Implements hook_permission().
 */
function dynamic_background_permission() {
  return array(
    'configure dynamic backgrounds' => array(
      'title' => t('Configure dynamic backgrounds'),
    ),
    'set dynamic backgrounds' => array(
      'title' => t('Set dynamic backgrounds'),
    ),
    'dynamic backgrounds css' => array(
      'title' => t('Access dynamic backgrounds css'),
    ),
    'dynamic backgrounds weight' => array(
      'title' => t('Reorder dynamic backgrounds weight'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function dynamic_background_menu() {
  $items = array();
  $items['admin/config/user-interface/backgrounds'] = array(
    'title' => 'Dynamic background',
    'description' => 'Upload background images.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'dynamic_background_admin_images',
    ),
    'access arguments' => array(
      'set dynamic backgrounds',
    ),
    'file' => 'includes/backgrounds.admin.inc',
  );
  $items['admin/config/user-interface/backgrounds/images'] = array(
    'title' => 'Background images',
    'description' => 'Upload background images and select current active background.',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/config/user-interface/backgrounds/settings'] = array(
    'title' => 'Settings',
    'description' => 'Configure dynamic backgrounds settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'dynamic_background_admin_settings',
    ),
    'access arguments' => array(
      'configure dynamic backgrounds',
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => -5,
    'file' => 'includes/settings.admin.inc',
  );
  $items['admin/config/user-interface/backgrounds/weight'] = array(
    'title' => 'Weight',
    'description' => 'Configure dynamic backgrounds extension weight',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'dynamic_background_admin_weight_form',
    ),
    'access arguments' => array(
      'dynamic backgrounds weight',
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => -8,
    'file' => 'includes/weight.admin.inc',
  );
  $items['background.css'] = array(
    'page callback' => 'dynamic_background_css',
    'access arguments' => array(
      'dynamic backgrounds css',
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_dynamic_background_css for the main module.
 */
function dynamic_background_dynamic_background_css($vars) {
  $image = variable_get('dynamic_background_active', FALSE);
  $image_style = variable_get('dynamic_background_image_style', FALSE);
  if ($image) {
    return array(
      'image' => $image,
      'configuration' => variable_get('dynamic_background_css', array()),
      'image_style' => $image_style ? $image_style['style'] : FALSE,
    );
  }
}

/**
 * Implements hook_dynamic_background_weight for the main module.
 */
function dynamic_background_dynamic_background_weight() {
  return array(
    'weight' => -20,
  );
}

/**
 * Implements hook_theme(). This defines the default theming function for the
 * background_upload_form element and the weight administration form.
 */
function dynamic_background_theme() {
  return array(
    'background_upload_form' => array(
      'render element' => 'element',
    ),
    'dynamic_background_admin_weight_form' => array(
      'render element' => 'form',
      'file' => 'includes/weight.admin.inc',
    ),
  );
}

/**
 * Page preprocess function used to create the $background variable, so it
 * can be used in html.tpl.php. If selected have selected to use custom CSS, the
 * image will automatically be added to the page header.
 *
 */
function dynamic_background_preprocess_html(&$vars) {

  // Load image configuration.
  $image_conf = dynamic_background_load_image_configuration($vars);

  // Generate the css and add it to the site.
  if (isset($image_conf)) {
    $css = dynamic_background_create_css($image_conf);
    if ($css) {
      drupal_add_css($css, array(
        'type' => 'inline',
        'group' => 200,
      ));
    }

    // Set the one with the highest weight as the variable.
    $image = array_pop($image_conf);
    $vars['background'] = 'style="background-image: url(\'' . file_create_url($image['image']) . '\')"';
  }
}

/**
 * Page preprocess function used to create the $background variable, so it
 * can be used in page.tpl.php
 *
 */
function dynamic_background_preprocess_page(&$vars) {

  // Load image configuration.
  $image_conf = dynamic_background_load_image_configuration($vars);

  // Only look at the last element (with the highest weight).
  $image_conf = array_pop($image_conf);

  // Generate the css and add it to the site.
  if (isset($image_conf)) {
    $vars['background'] = 'style="background-image: url(\'' . file_create_url($image_conf['image']) . '\')"';
  }
}

/**
 * Menu callback function used to generate an body style css with the selected
 * background image. The callback is /background.css.
 */
function dynamic_background_css() {

  // Load image configuration.
  $image_conf = dynamic_background_load_image_configuration($vars);

  // Generate the css and add it to the site.
  if (isset($image_conf)) {
    $css = dynamic_background_create_css($image_conf);
    if ($css) {
      echo $css;
    }
  }
}

/**
 * Helper function that calls hook_dynamic_background_css() and sorts the
 * returned image configurations based on weight. This function may be called
 * by more then one preprocessor function, so a static cache applied.
 *
 * @staticvar type $images
 * @param type $reset
 * @return type
 */
function dynamic_background_load_image_configuration(&$vars, $reset = FALSE) {
  static $images;
  if (!isset($images) || $reset) {

    // If images is null, create empty array (as no images may be selected).
    if (is_null($images)) {
      $images = array();
    }

    // Implementation of hook_dynamic_background_css().
    foreach (module_implements('dynamic_background_css') as $module) {
      $function = $module . '_dynamic_background_css';
      $result = $function($vars);
      if ($result && is_array($result)) {

        // Add weight to the result array.
        $result['weight'] = _dynamic_background_get_weight($module);
        $images[$module] = $result;
      }
    }

    // Sort images based on weight and get images with highest weight.
    usort($images, 'dynamic_background_revers_weight_cmp');
  }
  return $images;
}

/**
 * Gets the weight of the extension/module.
 *
 * @TODO Implement static cache.
 *
 * @param string $module
 *   The name of module/extension to get weight for.
 * @return int
 *   The module/extension weight.
 */
function _dynamic_background_get_weight($module) {

  // Load administrator values
  $weights = variable_get('dynamic_background_weight', array());

  // Find weights sat by the administratio UI.
  foreach ($weights as $weight) {
    if ($weight['name'] == $module) {

      // Weight found for the module.
      return $weight['weight'];
    }
  }

  // Try to get the weight from hook_dynamic_background_weight().
  $function = $module . '_dynamic_background_weight';
  if (function_exists($function)) {
    $result = $function();
    return $result['weight'];
  }

  // No weight was found, so nutral weight returned.
  return 0;
}

/**
 * Helper function to sort image configuration arrays based on weight.
 *
 * @param array $a
 * @param array $b
 * @return int
 */
function dynamic_background_revers_weight_cmp($a, $b) {
  if ($a['weight'] == $b['weight']) {
    return 0;
  }
  return $a['weight'] > $b['weight'] ? -1 : 1;
}

/**
 * Helper function that creates a CSS based on user supplied css.
 *
 * @param array $images_conf
 * @param boolean $reset optional
 * @return string $css or FALSE if custom CSS have not been defined
 */
function dynamic_background_create_css($images_conf, $reset = FALSE) {
  static $css;
  if (!isset($css) || $reset) {

    // Build style array based on weight, this will allow weight base override
    // at the same time allowing different selectors.
    $style_array = array();
    foreach ($images_conf as $image_conf) {

      // Only use image if css behaviour have be set.
      if (!empty($image_conf['configuration'])) {

        // Add image style, if one have been defined.
        $image = $image_conf['image'];
        if (isset($image_conf['image_style']) && $image_conf['image_style']) {

          // Image style found, so update the image path with an image style
          // based one.
          $image = image_style_url($image_conf['image_style'], $image);
        }
        else {
          $image = file_create_url($image);
        }

        // Check if selector have been used, if it have and has a higher weight
        // override it.
        if (isset($style_array[$image_conf['configuration']['selector']])) {
          if ($style_array[$image_conf['configuration']['selector']]['weight'] > $image_conf['weight']) {

            // This css selector have been used before and the new whan was
            // fater, so override the select in the style array.
            $style_array[$image_conf['configuration']['selector']] = array(
              'css' => $image_conf['configuration']['css'],
              'image' => $image,
              'weight' => $image_conf['weight'],
            );
          }
        }
        else {

          // This selector have not been used before, so add it to the array.
          $style_array[$image_conf['configuration']['selector']] = array(
            'css' => $image_conf['configuration']['css'],
            'image' => $image,
            'weight' => $image_conf['weight'],
          );
        }
      }
    }

    // Build css based on weighted style array.
    $css = '';
    foreach ($style_array as $selector => $style) {
      $css .= $selector . " {\n        background-image: url('" . $style['image'] . "');\n        " . $style['css'] . "\n      }\n";
    }
  }
  return $css;
}

/**
 * Builds the CSS behaviour part of the form, this should be used by every
 * sub-module. The parameter is the variable name in which the css behaviour is
 * stored.
 *
 * @param string $form_key
 * @return array $form
 */
function dynamic_background_css_behaviour_form($form_key) {
  $form = array();

  // Add CSS behaviour options
  $default = variable_get($form_key, array());
  $form[$form_key] = array(
    '#type' => 'fieldset',
    '#title' => t('CSS behaviour'),
    '#collapsed' => FALSE,
    '#collapsible' => TRUE,
    '#tree' => TRUE,
  );
  $form[$form_key]['selector'] = array(
    '#type' => 'textfield',
    '#title' => t('CSS selector'),
    '#description' => t('The CSS selector string to target with the background image e.g. body #container.'),
    '#required' => TRUE,
    '#default_value' => isset($default['selector']) ? $default['selector'] : '',
  );
  $form[$form_key]['css'] = array(
    '#type' => 'textarea',
    '#title' => t('CSS'),
    '#description' => t('The CSS to insert with the background image e.g background-size: cover;.'),
    '#default_value' => isset($default['css']) ? $default['css'] : '',
  );
  return $form;
}

/**
 * Build the image style selection form, which can be used in sub-modules to add
 * support for image manipulation.
 *
 * @param type $form_key
 * @return type
 */
function dynamic_background_image_style_form($form_key) {
  $form = array();
  $form[$form_key] = array(
    '#type' => 'fieldset',
    '#title' => t('Image style'),
    '#description' => 'You can apply differect effects to your background image using image styles. If you don\'t want to add effects to the selected background image, just select "No style".',
    '#collapsed' => FALSE,
    '#collapsible' => TRUE,
    '#tree' => TRUE,
  );

  // Get image style information.
  $options = array(
    0 => t('No style'),
  );
  $styles = image_styles();
  foreach ($styles as $stylename => $settings) {
    $options[$stylename] = $stylename;
  }

  // Load default form values (current selected image style)
  $default = variable_get($form_key, array());
  $form[$form_key]['style'] = array(
    '#type' => 'select',
    '#title' => t('Choose a style to apply to background images.'),
    '#description' => t('To create an image style, go to <a href="@url">image style configuration</a>.', array(
      '@url' => '/admin/config/media/image-styles',
    )),
    '#options' => $options,
    '#default_value' => isset($default['style']) ? $default['style'] : 0,
  );
  return $form;
}

/**
 * Builds image selection part of a form to be used by sub-moduels, where the
 * user may select background images.
 *
 * @param int $selected_image_id
 * @return array $form
 */
function dynamic_background_image_selector_form($selected_image_id) {
  $form = array(
    '#tree' => TRUE,
  );

  // Get all uploaded images
  $images = variable_get('dynamic_background_images', array());
  foreach ($images as $id => $image) {
    if (!empty($image['picture'])) {

      // Create image thumbnail.
      $image = array(
        'style_name' => 'thumbnail',
        'path' => $images[$id]['picture'],
        'alt' => basename($images[$id]['picture']),
        'title' => basename($images[$id]['picture']),
      );
      $picture = theme('image_style', $image);
      $form[$id]['image'] = array(
        '#markup' => $picture,
        '#prefix' => '<div class="dynamic-background-picture">',
      );
      $form[$id]['selected'] = array(
        '#type' => 'checkbox',
        '#title' => t('Use background'),
        '#default_value' => !is_null($selected_image_id) && $id == $selected_image_id ? 1 : 0,
        '#suffix' => '</div>',
      );
    }
  }

  // Add some default styling to the image selector.
  drupal_add_css(drupal_get_path('module', 'dynamic_background') . '/css/dynamic_background.theme.css', 'module');
  drupal_add_js(drupal_get_path('module', 'dynamic_background') . '/js/dynamic_background_selector.js', 'file');
  return $form;
}

Functions

Namesort descending Description
dynamic_background_create_css Helper function that creates a CSS based on user supplied css.
dynamic_background_css Menu callback function used to generate an body style css with the selected background image. The callback is /background.css.
dynamic_background_css_behaviour_form Builds the CSS behaviour part of the form, this should be used by every sub-module. The parameter is the variable name in which the css behaviour is stored.
dynamic_background_dynamic_background_css Implements hook_dynamic_background_css for the main module.
dynamic_background_dynamic_background_weight Implements hook_dynamic_background_weight for the main module.
dynamic_background_image_selector_form Builds image selection part of a form to be used by sub-moduels, where the user may select background images.
dynamic_background_image_style_form Build the image style selection form, which can be used in sub-modules to add support for image manipulation.
dynamic_background_load_image_configuration Helper function that calls hook_dynamic_background_css() and sorts the returned image configurations based on weight. This function may be called by more then one preprocessor function, so a static cache applied.
dynamic_background_menu Implements hook_menu().
dynamic_background_permission Implements hook_permission().
dynamic_background_preprocess_html Page preprocess function used to create the $background variable, so it can be used in html.tpl.php. If selected have selected to use custom CSS, the image will automatically be added to the page header.
dynamic_background_preprocess_page Page preprocess function used to create the $background variable, so it can be used in page.tpl.php
dynamic_background_revers_weight_cmp Helper function to sort image configuration arrays based on weight.
dynamic_background_theme Implements hook_theme(). This defines the default theming function for the background_upload_form element and the weight administration form.
_dynamic_background_get_weight Gets the weight of the extension/module.