Added possibility to select an image style and several changes.
[project/backstretch_formatter.git] / backstretch_formatter.module
1 <?php
2
3 /**
4 * @file
5 * Main file for Backstretch Formatter module.
6 */
7
8 /**
9 * Implements hook_libraries_info().
10 */
11 function backstretch_formatter_libraries_info() {
12 $libraries = array();
13
14 $libraries['jquery.backstretch'] = array(
15 'name' => 'jQuery Backstretch',
16 'vendor url' => 'http://srobbin.com/jquery-plugins/backstretch/',
17 'download url' => 'https://raw.github.com/srobbin/jquery-backstretch/master/jquery.backstretch.min.js',
18 'version arguments' => array(
19 'file' => 'jquery.backstretch.min.js',
20 'pattern' => '/ v([\d\.]+) /',
21 'lines' => 1,
22 ),
23 'files' => array(
24 'js' => array('jquery.backstretch.min.js'),
25 ),
26 );
27
28 return $libraries;
29 }
30
31 /**
32 * Implements hook_field_formatter_info().
33 */
34 function backstretch_formatter_field_formatter_info() {
35 return array(
36 'backstretch' => array(
37 'label' => t('Backstretch'),
38 'field types' => array('image'),
39 'settings' => array(
40 'image_style' => '',
41 'element' => '',
42 'element_other' => '',
43 'duration' => 5000,
44 'fade' => 0,
45 'center_x' => TRUE,
46 'center_y' => TRUE,
47 ),
48 ),
49 );
50 }
51
52 /**
53 * Implements hook_field_formatter_settings_form().
54 */
55 function backstretch_formatter_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
56 // This gets the view mode where the settings are stored.
57 $display = $instance['display'][$view_mode];
58 // This gets the settings.
59 $settings = $display['settings'];
60
61 $element = array();
62
63 $image_styles = image_style_options(FALSE);
64 $element['image_style'] = array(
65 '#title' => t('Image style'),
66 '#type' => 'select',
67 '#default_value' => $settings['image_style'],
68 '#options' => $image_styles,
69 '#empty_option' => t('None (original image)'),
70 );
71
72 $element['element'] = array(
73 '#type' => 'select',
74 '#title' => t('Attach to'),
75 '#default_value' => $settings['element'],
76 '#options' => array(
77 'other' => t('Other element'),
78 ),
79 '#empty_option' => t('Whole page'),
80 '#description' => t('Where the Backstretch should be attached to.'),
81 );
82
83 $element['element_other'] = array(
84 '#type' => 'textfield',
85 '#title' => t('Other element'),
86 '#default_value' => $settings['element_other'],
87 '#description' => t('Enter the CSS selector for the element.'),
88 '#states' => array(
89 'visible' => array(
90 ':input[name$="[element]"]' => array('value' => 'other'),
91 ),
92 ),
93 );
94
95 // Make duration and fade setting only available for multiple value field.
96 if ($field['cardinality'] != '1') {
97 $element['duration'] = array(
98 '#type' => 'textfield',
99 '#title' => t('Duration'),
100 '#default_value' => $settings['duration'],
101 '#description' => t('Amount of time in between slides.'),
102 '#size' => 10,
103 '#field_suffix' => 'ms',
104 '#element_validate' => array('element_validate_integer_positive'),
105 );
106
107 $element['fade'] = array(
108 '#type' => 'textfield',
109 '#title' => t('Fade'),
110 '#default_value' => $settings['fade'],
111 '#description' => t('Speed of fade transition between slides. Can be an integer or a string like: %slow or %fast.', array('%slow' => 'slow', '%fast' => 'fast')),
112 '#size' => 10,
113 '#element_validate' => array('backstretch_formatter_element_validate_duration'),
114 );
115 }
116
117 $element['center_x'] = array(
118 '#type' => 'checkbox',
119 '#title' => t('Horizontal centered'),
120 '#default_value' => $settings['center_x'],
121 '#description' => t('Should we center the image on the X axis?'),
122 );
123
124 $element['center_y'] = array(
125 '#type' => 'checkbox',
126 '#title' => t('Vertically centered'),
127 '#default_value' => $settings['center_y'],
128 '#description' => t('Should we center the image on the Y axis?'),
129 );
130
131 return $element;
132 }
133
134 /**
135 * Implements hook_field_formatter_settings_summary().
136 */
137 function backstretch_formatter_field_formatter_settings_summary($field, $instance, $view_mode) {
138 $display = $instance['display'][$view_mode];
139 $settings = $display['settings'];
140
141 $options_info = backstretch_formatter_formatter_options();
142 $options = array();
143
144 foreach ($settings as $name => $value) {
145 if (array_key_exists($name, $options_info)) {
146 $option = $options_info[$name];
147 $label = $option['label'];
148 $suffix = isset($option['suffix']) ? $option['suffix'] : '';
149 $type = isset($option['type']) ? $option['type'] : '';
150
151 // We need some special handling with the element setting.
152 if ($name == 'element') {
153 continue;
154 }
155 if ($name == 'element_other') {
156 $value = ($settings['element'] == '') ? t('Whole page') : $value;
157 }
158 if ($name == 'image_style' && $value == '') {
159 continue;
160 }
161 // Display just the label when the setting is a boolean.
162 if ($type != 'bool') {
163 $options[$name] = $label . ': ' . $value . $suffix;
164 }
165 else {
166 $options[$name] = $label . $suffix;
167 }
168 }
169 }
170
171 // Remove slideshow specific settings when only one image is allowed.
172 if ($field['cardinality'] == '1') {
173 unset($options['duration'], $options['fade']);
174 }
175
176 $summary = '<h3>jQuery Backstretch</h3>';
177 $summary .= theme('item_list', array('items' => $options));
178
179 return $summary;
180 }
181
182 /**
183 * Implements hook_field_formatter_view().
184 */
185 function backstretch_formatter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
186 // Store the field formatter settings.
187 $settings = $display['settings'];
188
189 // Display an error message and return if jQuery is not at least 1.7.
190 $jquery = drupal_get_library('system', 'jquery');
191 if (version_compare($jquery['version'], '1.7', '<')) {
192 drupal_set_message(t('The jQuery Backstretch plugin requires at least jQuery 1.7. Please change the version in the <a href="!url">settings</a>.', array('!url' => url('admin/config/development/jquery_update'))), 'error');
193 return;
194 }
195
196 // We store the default values from Backstretch formatter here.
197 $formatters = backstretch_formatter_field_formatter_info();
198 $default = $formatters['backstretch']['settings'];
199
200 // We need the js variable name.
201 $options_info = backstretch_formatter_formatter_options();
202 // Here we store all options later.
203 $options = array();
204
205 foreach ($settings as $name => $value) {
206 if (array_key_exists($name, $options_info)) {
207 $option = $options_info[$name];
208 $js = $option['js'];
209
210 // We need some special handling with the element settings.
211 if ($name == 'element' || ($name == 'element_other' && $settings['element'] == '')) {
212 continue;
213 }
214
215 // We only put the setting into $options when it is
216 // not the default value.
217 if ($value != $default[$name] && $js) {
218 $options[$js] = $value;
219 }
220 }
221 }
222
223 // We need the entity id here because there could be multiple images with
224 // Backstretch formatter.
225 $ids = entity_extract_ids($entity_type, $entity);
226 $id = str_replace('_', '-', $entity_type) . '-' . $ids[0];
227
228 // Iterate all items and store the absolute url to it.
229 foreach ($items as &$item) {
230 $uri = $item['uri'];
231 // Get url to image.
232 if ($settings['image_style']) {
233 $url = image_style_url($settings['image_style'], $uri);
234 }
235 else {
236 $url = file_create_url($uri);
237 }
238 $options['items'][] = $url;
239 }
240
241 // Prepare a renderable array.
242 $element = array(
243 '#theme' => 'backstretch',
244 '#id' => $id,
245 '#options' => $options,
246 );
247
248 return $element;
249 }
250
251 /**
252 * Implements hook_theme().
253 */
254 function backstretch_formatter_theme() {
255 return array(
256 'backstretch' => array(
257 'variables' => array('id' => 0, 'options' => array()),
258 ),
259 );
260 }
261
262 /**
263 * Theme function for a Backstretch.
264 */
265 function theme_backstretch($variables) {
266 // Normalize the variables.
267 $id = $variables['id'];
268 $options = $variables['options'];
269
270 // Load necessary for the Backstretch.
271 libraries_load('jquery.backstretch');
272 drupal_add_js(drupal_get_path('module', 'backstretch_formatter') . '/js/backstretch_formatter.js');
273 drupal_add_js(array('backstretchFormatter' => array($id => $options)), 'setting');
274
275 return '';
276 }
277
278 /**
279 * Helper function which returns the options.
280 *
281 * @return array
282 * An array which contains the options.
283 * Every item has a label and their Javascript name.
284 * Optionally with a suffix which will be append to the value in summary.
285 */
286 function backstretch_formatter_formatter_options() {
287 return array(
288 'image_style' => array(
289 'label' => t('Image style'),
290 'js' => '',
291 ),
292 'element_other' => array(
293 'label' => t('Attach to'),
294 'js' => 'selector',
295 ),
296 'fade' => array(
297 'label' => t('Fade speed'),
298 'js' => 'fade',
299 ),
300 'duration' => array(
301 'label' => t('Time between slides'),
302 'js' => 'duration',
303 'suffix' => 'ms',
304 ),
305 'center_x' => array(
306 'label' => t('Horizontally centerd'),
307 'js' => 'centeredX',
308 'type' => 'bool',
309 ),
310 'center_y' => array(
311 'label' => t('Vertically centered'),
312 'js' => 'centeredY',
313 'type' => 'bool',
314 ),
315 );
316 }
317
318 /**
319 * Form element validation handler for elements that must be a duration.
320 */
321 function backstretch_formatter_element_validate_duration($element, &$form_state) {
322 $value = $element['#value'];
323 // A duration can be an integer or a string like 'slow' or 'fast'.
324 if ($value !== '' && !(is_numeric($value) && intval($value) == $value && $value >= 0) && ($value != 'slow' && $value != 'fast')) {
325 form_error($element, t('%name must be an integer, "slow" or "fast".', array('%name' => $element['#title'])));
326 }
327 }