adaptive_image.module in Adaptive Image 7
Adaptive Image - Adaptive images for Drupal
@author Stefan Auditor <stefan.auditor@erdfisch.de>
See also
File
adaptive_image.moduleView source
<?php
/**
* @file
* Adaptive Image - Adaptive images for Drupal
* @see http://adaptive-images.com/
*
* @author
* Stefan Auditor <stefan.auditor@erdfisch.de>
*/
/**
* Implements hook_init().
*/
function adaptive_image_init() {
// According to the documentation of hook_init() it should not be used to
// load JS or CSS. The CSS case has been moved to the info file. But the JS is
// here by intention, as we want it inline to prevent wait time while loading
// the script
// No need for drupal behaviours, jquery compatibility wrapper nor ready event
$js = "document.cookie = 'adaptive_image=' + Math.max(screen.width, screen.height) + '; path=/';";
drupal_add_js($js, array(
'type' => 'inline',
'scope' => 'header',
'group' => JS_LIBRARY,
'every_page' => TRUE,
'weight' => -500,
));
}
/**
* Implements hook_menu().
*/
function adaptive_image_menu() {
$items = array();
// Add image style generation paths adaptive URLs.
if (module_exists('image')) {
// Generate and deliver image derivatives of public files.
$directory_path = file_stream_wrapper_get_instance_by_scheme('public')
->getDirectoryPath();
$items[$directory_path . '/styles/%image_style/adaptive-image'] = array(
'title' => 'Generate image style',
'page callback' => 'adaptive_image_style_deliver',
'page arguments' => array(
count(explode('/', $directory_path)) + 1,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'adaptive_image.image.inc',
);
// Generate and deliver image derivatives of private files.
$items['system/files/styles/%image_style/adaptive-image'] = array(
'title' => 'Generate adaptive image style',
'page callback' => 'adaptive_image_style_deliver',
'page arguments' => array(
3,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'adaptive_image.image.inc',
);
}
return $items;
}
/**
* Implements hook_image_effect_info().
*/
function adaptive_image_image_effect_info() {
$effects = array();
$effects['adaptive_image'] = array(
'label' => t('Adaptive'),
'help' => t('Adaptive image scale according to client resolution.'),
'effect callback' => 'image_scale_effect',
'dimensions callback' => 'image_scale_dimensions',
'form callback' => 'adaptive_image_scale_form',
'summary theme' => 'adaptive_image_scale_summary',
);
return $effects;
}
/**
* Form structure for the image scale form.
*
* Note that this is not a complete form, it only contains the portion of the
* form for configuring the scale options. Therefore it does not not need to
* include metadata about the effect, nor a submit button.
*
* @param $data
* The current configuration for this scale effect.
*/
function adaptive_image_scale_form($data) {
$form['resolutions'] = array(
'#type' => 'textfield',
'#title' => t('Resolutions'),
'#default_value' => isset($data['resolutions']) ? $data['resolutions'] : '1382, 992, 768, 480',
'#required' => TRUE,
'#description' => t('The resolution break-points to use (screen widths, in pixels).'),
);
$form['mobile_first'] = array(
'#type' => 'checkbox',
'#title' => t('Mobile first'),
'#default_value' => isset($data['mobile_first']) ? $data['mobile_first'] : TRUE,
'#description' => t("Check this to send the smallest version when the resolution can not be determined."),
);
$resolutions = explode(',', str_replace(' ', '', $form['resolutions']['#default_value']));
$resolution = adaptive_image_resolution($resolutions);
// Provide needed defaults
$form['height'] = array(
'#type' => 'hidden',
'#default_value' => NULL,
);
$form['width'] = array(
'#type' => 'hidden',
'#default_value' => $resolution,
);
$form['upscale'] = array(
'#type' => 'hidden',
'#default_value' => NULL,
);
return $form;
}
/**
* Implements hook_theme().
*/
function adaptive_image_theme() {
return array(
'adaptive_image_scale_summary' => array(
'variables' => array(
'data' => NULL,
),
),
);
}
/**
* Returns HTML for a summary of an image scale effect.
*
* @param $variables
* An associative array containing:
* - data: The current configuration for this scale effect.
*
* @ingroup themeable
*/
function theme_adaptive_image_scale_summary($variables) {
$data = $variables['data'];
if ($data['resolutions']) {
return check_plain($data['resolutions']);
}
}
/**
* Validate Input of Resolutions-Field
*/
function adaptive_image_form_image_effect_form_alter(&$form, &$form_state, $form_id) {
if (strpos($form['#action'], 'adaptive_image')) {
$form['#validate'] = array(
'_adaptive_image_form_image_effect_form_validate',
);
}
}
/**
* Form validation handler
*/
function _adaptive_image_form_image_effect_form_validate($form, &$form_state) {
$resolutions = explode(',', $form['data']['resolutions']['#value']);
foreach ($resolutions as $width) {
$width = trim($width, ' ');
if (!is_numeric($width)) {
form_set_error('resolutions', t("Values have to be seperated by comma. For example: 1382, 992, 768, 480"));
}
}
}
/**
* Implements template_preprocess_image().
*
* Adds a class to adaptive images for max-width.
*/
function adaptive_image_preprocess_image(&$variables) {
global $base_url;
if (isset($variables['style_name'])) {
// Get image style settings
$style = image_style_load($variables['style_name']);
// Check if style contains the adaptive image effect
if ($style && adaptive_image_contains_effect($style)) {
$settings = adaptive_image_effect_settings($style);
$resolutions = explode(',', $settings['resolutions']);
$resolution = adaptive_image_resolution($resolutions);
// Only construct direct path if not private
if (!strpos($variables['path'], '/system/') && is_numeric($resolution)) {
$path_parts = pathinfo($variables['path']);
$derivative_uri = $path_parts['dirname'] . '/' . $resolution . '/' . $path_parts['basename'];
}
if (isset($derivative_uri) && file_exists(str_replace($base_url, '.', $derivative_uri))) {
// Deliver existing path to bypass menu callback
$variables['path'] = $derivative_uri;
}
else {
// Reconstruct the image path to %/%style_name/adaptive-image/% to
// trigger image generation or file access check
$variables['path'] = str_replace('styles/' . $variables['style_name'], 'styles/' . $variables['style_name'] . '/adaptive-image', $variables['path']);
}
// Add class for styling
$variables['attributes']['class'][] = 'adaptive-image';
// Remove fixed image dimensions
unset($variables['height']);
unset($variables['width']);
}
}
}
/**
* Check for adaptive image effect from style
*/
function adaptive_image_contains_effect($style) {
foreach ($style['effects'] as $effect) {
if ($effect['name'] == 'adaptive_image') {
return TRUE;
}
}
return FALSE;
}
/**
* Get adaptive image effect from style settings
*/
function adaptive_image_effect_settings($style) {
$settings = array();
foreach ($style['effects'] as $effect) {
if ($effect['name'] == 'adaptive_image') {
$settings = $effect['data'];
}
}
return $settings;
}
/**
* Determine current resolution
*/
function adaptive_image_resolution($resolutions) {
$resolution = '';
/* Check to see if a valid cookie exists */
if (count($resolutions) && isset($_COOKIE['adaptive_image'])) {
if (is_numeric($_COOKIE['adaptive_image'])) {
$client_width = (int) $_COOKIE['adaptive_image'];
// store the cookie value in a variable
/* the client width in the cookie is valid, now fit that number into the correct resolution break point */
rsort($resolutions);
// make sure the supplied break-points are in reverse size order
$resolution = $resolutions[0];
// by default it's the largest supported break-point
foreach ($resolutions as $break_point) {
// filter down
if ($client_width <= trim($break_point, ' ')) {
$resolution = $break_point;
}
}
}
else {
setcookie("adaptive_image", "", time() - 1);
// delete the mangled cookie
}
}
return $resolution;
}
Functions
Name | Description |
---|---|
adaptive_image_contains_effect | Check for adaptive image effect from style |
adaptive_image_effect_settings | Get adaptive image effect from style settings |
adaptive_image_form_image_effect_form_alter | Validate Input of Resolutions-Field |
adaptive_image_image_effect_info | Implements hook_image_effect_info(). |
adaptive_image_init | Implements hook_init(). |
adaptive_image_menu | Implements hook_menu(). |
adaptive_image_preprocess_image | Implements template_preprocess_image(). |
adaptive_image_resolution | Determine current resolution |
adaptive_image_scale_form | Form structure for the image scale form. |
adaptive_image_theme | Implements hook_theme(). |
theme_adaptive_image_scale_summary | Returns HTML for a summary of an image scale effect. |
_adaptive_image_form_image_effect_form_validate | Form validation handler |