123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- <?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,
- // First-come, first-served
- 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']);
- }
- }
- /**
- * 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 <= $break_point) {
- $resolution = $break_point;
- }
- }
- } else {
- setcookie("adaptive_image", "", time() -1); // delete the mangled cookie
- }
- }
- return $resolution;
- }
|