Projet

Général

Profil

Paste
Télécharger (7,44 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / adaptive_image / adaptive_image.module @ 87dbc3bf

1
<?php
2

    
3
/**
4
 * @file
5
 * Adaptive Image - Adaptive images for Drupal
6
 * @see http://adaptive-images.com/
7
 *
8
 * @author
9
 * Stefan Auditor <stefan.auditor@erdfisch.de>
10
 */
11

    
12
/**
13
 * Implements hook_init().
14
 */
15
function adaptive_image_init() {
16
  // According to the documentation of hook_init() it should not be used to
17
  // load JS or CSS. The CSS case has been moved to the info file. But the JS is
18
  // here by intention, as we want it inline to prevent wait time while loading
19
  // the script
20

    
21
  // No need for drupal behaviours, jquery compatibility wrapper nor ready event
22
  $js = "document.cookie = 'adaptive_image=' + Math.max(screen.width, screen.height) + '; path=/';";
23
  drupal_add_js($js,
24
    // First-come, first-served
25
    array(
26
      'type' => 'inline',
27
      'scope' => 'header',
28
      'group' => JS_LIBRARY,
29
      'every_page' => TRUE,
30
      'weight' => -500,
31
    )
32
  );
33
}
34

    
35
/**
36
 * Implements hook_menu().
37
 */
38
function adaptive_image_menu() {
39
  $items = array();
40

    
41
  // Add image style generation paths adaptive URLs.
42
  if (module_exists('image')) {
43
    // Generate and deliver image derivatives of public files.
44
    $directory_path = file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath();
45
    $items[$directory_path . '/styles/%image_style/adaptive-image'] = array(
46
      'title' => 'Generate image style',
47
      'page callback' => 'adaptive_image_style_deliver',
48
      'page arguments' => array(count(explode('/', $directory_path)) + 1),
49
      'access callback' => TRUE,
50
      'type' => MENU_CALLBACK,
51
      'file' => 'adaptive_image.image.inc',
52
    );
53
    // Generate and deliver image derivatives of private files.
54
    $items['system/files/styles/%image_style/adaptive-image'] = array(
55
      'title' => 'Generate adaptive image style',
56
      'page callback' => 'adaptive_image_style_deliver',
57
      'page arguments' => array(3),
58
      'access callback' => TRUE,
59
      'type' => MENU_CALLBACK,
60
      'file' => 'adaptive_image.image.inc',
61
    );
62
  }
63

    
64
  return $items;
65
}
66

    
67
/**
68
 * Implements hook_image_effect_info().
69
 */
70
function adaptive_image_image_effect_info() {
71
  $effects = array();
72
  $effects['adaptive_image'] = array(
73
    'label' => t('Adaptive'),
74
    'help' => t('Adaptive image scale according to client resolution.'),
75
    'effect callback' => 'image_scale_effect',
76
    'dimensions callback' => 'image_scale_dimensions',
77
    'form callback' => 'adaptive_image_scale_form',
78
    'summary theme' => 'adaptive_image_scale_summary',
79
  );
80
  return $effects;
81
}
82

    
83
/**
84
 * Form structure for the image scale form.
85
 *
86
 * Note that this is not a complete form, it only contains the portion of the
87
 * form for configuring the scale options. Therefore it does not not need to
88
 * include metadata about the effect, nor a submit button.
89
 *
90
 * @param $data
91
 *   The current configuration for this scale effect.
92
 */
93
function adaptive_image_scale_form($data) {
94
  $form['resolutions'] = array(
95
    '#type' => 'textfield',
96
    '#title' => t('Resolutions'),
97
    '#default_value' => isset($data['resolutions']) ? $data['resolutions'] : '1382, 992, 768, 480',
98
    '#required' => TRUE,
99
    '#description' => t('The resolution break-points to use (screen widths, in pixels).'),
100
  );
101
  $form['mobile_first'] = array(
102
    '#type' => 'checkbox',
103
    '#title' => t('Mobile first'),
104
    '#default_value' => isset($data['mobile_first']) ? $data['mobile_first'] : TRUE,
105
    '#description' => t("Check this to send the smallest version when the resolution can not be determined."),
106
  );
107

    
108
  $resolutions = explode(',', str_replace(' ', '', $form['resolutions']['#default_value']));
109
  $resolution = adaptive_image_resolution($resolutions);
110
  // Provide needed defaults
111
  $form['height']  = array('#type' => 'hidden','#default_value' => NULL);
112
  $form['width']   = array('#type' => 'hidden','#default_value' => $resolution);
113
  $form['upscale'] = array('#type' => 'hidden','#default_value' => NULL);
114
  return $form;
115
}
116

    
117
/**
118
 * Implements hook_theme().
119
 */
120
function adaptive_image_theme() {
121
  return array(
122
    'adaptive_image_scale_summary' => array(
123
      'variables' => array('data' => NULL),
124
    ),
125
  );
126
}
127

    
128
/**
129
 * Returns HTML for a summary of an image scale effect.
130
 *
131
 * @param $variables
132
 *   An associative array containing:
133
 *   - data: The current configuration for this scale effect.
134
 *
135
 * @ingroup themeable
136
 */
137
function theme_adaptive_image_scale_summary($variables) {
138
  $data = $variables['data'];
139
  if ($data['resolutions']) {
140
    return check_plain($data['resolutions']);
141
  }
142
}
143

    
144
/**
145
 * Implements template_preprocess_image().
146
 *
147
 * Adds a class to adaptive images for max-width.
148
 */
149
function adaptive_image_preprocess_image(&$variables) {
150
  global $base_url;
151

    
152
  if (isset($variables['style_name'])) {
153
    // Get image style settings
154
    $style = image_style_load($variables['style_name']);
155

    
156
    // Check if style contains the adaptive image effect
157
    if ($style && adaptive_image_contains_effect($style)) {
158
      $settings = adaptive_image_effect_settings($style);
159
      $resolutions = explode(',', $settings['resolutions']);
160
      $resolution = adaptive_image_resolution($resolutions);
161

    
162
      // Only construct direct path if not private
163
      if (!strpos($variables['path'], '/system/') && is_numeric($resolution)) {
164
        $path_parts = pathinfo($variables['path']);
165
        $derivative_uri = $path_parts['dirname'] . '/' . $resolution . '/' . $path_parts['basename'];
166
      }
167

    
168
      if (isset($derivative_uri) && file_exists(str_replace($base_url, '.', $derivative_uri))) {
169
        // Deliver existing path to bypass menu callback
170
        $variables['path'] = $derivative_uri;
171
      }
172
      else {
173
        // Reconstruct the image path to %/%style_name/adaptive-image/% to
174
        // trigger image generation or file access check
175
        $variables['path'] = str_replace('styles/' . $variables['style_name'], 'styles/' . $variables['style_name'] . '/adaptive-image', $variables['path']);
176
      }
177

    
178
      // Add class for styling
179
      $variables['attributes']['class'] = 'adaptive-image';
180

    
181
      // Remove fixed image dimensions
182
      unset($variables['height']);
183
      unset($variables['width']);
184
    }
185
  }
186
}
187

    
188
/**
189
 * Check for adaptive image effect from style
190
 */
191
function adaptive_image_contains_effect($style) {
192
  foreach ($style['effects'] as $effect) {
193
    if ($effect['name'] == 'adaptive_image') {
194
      return TRUE;
195
    }
196
  }
197
  return FALSE;
198
}
199

    
200
/**
201
 * Get adaptive image effect from style settings
202
 */
203
function adaptive_image_effect_settings($style) {
204
  $settings = array();
205
  foreach ($style['effects'] as $effect) {
206
    if ($effect['name'] == 'adaptive_image') {
207
      $settings = $effect['data'];
208
    }
209
  }
210
  return $settings;
211
}
212

    
213
/**
214
 * Determine current resolution
215
 */
216
function adaptive_image_resolution($resolutions) {
217
  $resolution = '';
218
  /* Check to see if a valid cookie exists */
219
  if (count($resolutions) && isset($_COOKIE['adaptive_image'])) {
220
    if (is_numeric($_COOKIE['adaptive_image'])) {
221
      $client_width = (int) $_COOKIE['adaptive_image']; // store the cookie value in a variable
222

    
223
      /* the client width in the cookie is valid, now fit that number into the correct resolution break point */
224
      rsort($resolutions); // make sure the supplied break-points are in reverse size order
225
      $resolution = $resolutions[0]; // by default it's the largest supported break-point
226

    
227
      foreach ($resolutions as $break_point) { // filter down
228
        if ($client_width <= $break_point) {
229
          $resolution = $break_point;
230
        }
231
      }
232
    } else {
233
      setcookie("adaptive_image", "", time() -1); // delete the mangled cookie
234
    }
235
  }
236
  return $resolution;
237
}