View source
<?php
define('RESP_IMG_CLASS', 'resp-img-picture');
define('RESP_IMG_SEPARATOR', '__');
define('RESP_IMG_SOURCE_TYPE_THEME', 'theme');
define('RESP_IMG_SOURCE_TYPE_MODULE', 'module');
define('RESP_IMG_SOURCE_TYPE_CUSTOM', 'custom');
define('RESP_IMG_GROUP', 'group');
function resp_img_add_js() {
static $added = FALSE;
if (!$added) {
$added = TRUE;
drupal_add_js(drupal_get_path('module', 'resp_img') . '/picturefill/matchmedia.js', array(
'type' => 'file',
'weight' => -10,
'group' => JS_DEFAULT,
));
drupal_add_js(drupal_get_path('module', 'resp_img') . '/picturefill/picturefill.js', array(
'type' => 'file',
'weight' => -10,
'group' => JS_DEFAULT,
));
drupal_add_css(drupal_get_path('module', 'resp_img') . '/css/resp_img.css', array(
'type' => 'file',
'weight' => -10,
));
}
}
function resp_img_theme() {
return array(
'picture' => array(
'variables' => array(
'style_name' => NULL,
'path' => NULL,
'width' => NULL,
'height' => NULL,
'alt' => '',
'title' => NULL,
'attributes' => array(),
'breakpoints' => array(),
),
),
'picture_formatter' => array(
'variables' => array(
'item' => NULL,
'path' => NULL,
'image_style' => NULL,
'breakpoints' => array(),
),
),
);
}
function resp_img_field_attach_view_alter(&$output, $context) {
foreach (element_children($output) as $field_name) {
$element =& $output[$field_name];
if ($element['#field_type'] == 'image') {
$instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
if (isset($instance['display'][$context['view_mode']])) {
$settings = $instance['display'][$context['view_mode']]['settings'];
}
else {
$settings = $instance['display']['default']['settings'];
}
$breakpoint_styles = array();
if (isset($settings['resp_img_responsive']) && $settings['resp_img_responsive']) {
foreach ($settings['resp_img'] as $breakpoint_name => $multipliers) {
if (is_array($multipliers)) {
foreach ($multipliers as $multiplier => $image_style) {
if (!empty($settings['resp_img'][$breakpoint_name][$multiplier])) {
if (!isset($breakpoint_styles[$breakpoint_name])) {
$breakpoint_styles[$breakpoint_name] = array();
}
$breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
}
}
}
}
}
$element['#formatter'] = 'picture';
$num_fields = count($element['#items']);
if (!empty($breakpoint_styles)) {
for ($delta = 0; $delta < $num_fields; $delta++) {
$element[$delta]['#theme'] = 'picture_formatter';
$element[$delta]['#breakpoints'] = $breakpoint_styles;
}
}
else {
for ($delta = 0; $delta < $num_fields; $delta++) {
$element[$delta]['#theme'] = 'picture_formatter';
$element[$delta]['#breakpoints'] = 'all';
}
}
}
}
}
function theme_picture_formatter($variables) {
if (!isset($variables['breakpoints']) || empty($variables['breakpoints'])) {
return theme('image_formatter', $variables);
}
resp_img_add_js();
$item = $variables['item'];
if (isset($item['title']) && drupal_strlen($item['title']) == 0) {
unset($item['title']);
}
$item['style_name'] = $variables['image_style'];
$item['breakpoints'] = $variables['breakpoints'];
$output = theme('picture', $item);
if (isset($variables['path']['path'])) {
$path = $variables['path']['path'];
$options = isset($variables['path']['options']) ? $variables['path']['options'] : array();
$options['html'] = TRUE;
$output = l($output, $path, $options);
}
return $output;
}
function theme_picture($variables) {
if (!isset($variables['attributes'])) {
$variables['attributes'] = array();
}
if (!isset($variables['attributes']['class'])) {
$variables['attributes']['class'] = array();
}
$variables['attributes']['class'][] = RESP_IMG_CLASS;
if (isset($variables['width']) && empty($variables['width'])) {
unset($variables['width']);
unset($variables['height']);
}
elseif (isset($variables['height']) && empty($variables['height'])) {
unset($variables['width']);
unset($variables['height']);
}
$images = array();
$output = array();
if (!is_array($variables['breakpoints'])) {
$default_breakpoint = resp_img_breakpoint_default();
if ($default_breakpoint && strpos($variables['style_name'], $default_breakpoint)) {
$breakpoints = breakpoints_breakpoint_load_all_active();
$image_styles = image_styles();
foreach ($breakpoints as $breakpoint) {
if ($breakpoint->breakpoint == $default_breakpoint) {
$images[] = array(
'image' => theme_image_style($variables),
);
}
else {
$new_image = $variables;
$new_image['style_name'] = str_replace($default_breakpoint, $breakpoint->breakpoint, $variables['style_name']);
if (array_key_exists($new_image['style_name'], $image_styles)) {
$images[] = array(
'image' => theme_image_style($new_image),
'media' => $breakpoint->breakpoint,
);
}
}
}
}
}
else {
$img = theme('image_style', $variables);
$img = str_replace('<img', '', $img);
$img = str_replace('/>', '', $img);
$images[] = array(
'image' => $img,
);
foreach ($variables['breakpoints'] as $breakpoint_name => $multipliers) {
$breakpoint = breakpoints_breakpoint_load_by_fullkey($breakpoint_name);
if ($breakpoint) {
$new_images = array();
foreach ($multipliers as $multiplier => $image_style) {
$new_image = $variables;
$new_image['style_name'] = $image_style;
$new_image['#multiplier'] = $multiplier;
$new_images[] = $new_image;
}
$img = theme('image_style', $new_images[0]);
$img = str_replace('<img', '', $img);
$img = str_replace('/>', '', $img);
if (count($new_images) == 1) {
$images[] = array(
'image' => $img,
'media' => $breakpoint->breakpoint,
);
}
else {
$srcset = array();
foreach ($new_images as $new_image) {
$srcset[] = image_style_url($new_image['style_name'], $new_image['uri']) . ' ' . $new_image['#multiplier'];
}
$img = preg_replace('/src="[^"]*"/', '', $img);
$images[] = array(
'srcset' => implode(', ', $srcset),
'media' => $breakpoint->breakpoint,
'image' => $img,
);
}
}
}
}
if (!empty($images)) {
$output[] = '<picture alt="' . check_plain($variables['alt']) . '" title="' . check_plain($variables['title']) . '">';
foreach ($images as $image) {
if (isset($image['media']) && !empty($image['media'])) {
if (!isset($image['srcset'])) {
$output[] = '<!-- <source media="' . $image['media'] . '" ' . $image['image'] . '> -->';
$output[] = '<source media="' . $image['media'] . '" ' . $image['image'] . '>';
}
else {
$output[] = '<!-- <source class="' . RESP_IMG_CLASS . '" media="' . $image['media'] . '" srcset="' . $image['srcset'] . '" ' . $image['image'] . '> -->';
$output[] = '<source class="' . RESP_IMG_CLASS . '" media="' . $image['media'] . '" srcset="' . $image['srcset'] . '" ' . $image['image'] . '>';
}
}
else {
$output[] = '<!-- <source ' . $image['image'] . '> -->';
$output[] = '<source ' . $image['image'] . '>';
}
}
$output[] = '<noscript><img ' . $images[0]['image'] . '/></noscript>';
$output[] = '</picture>';
return implode("\n", $output);
}
}
function resp_img_field_formatter_info_alter(&$info) {
foreach ($info as $formatter_key => &$formatter) {
if ($formatter_key == 'image') {
if (!isset($formatter['settings']) || !is_array($formatter['settings'])) {
$formatter['settings'] = array();
}
$formatter['settings'] += array(
'resp_img_responsive' => FALSE,
'resp_img' => array(),
);
}
}
}
function resp_img_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
if (isset($context['field']['type']) && $context['field']['type'] === 'image') {
$settings = $context['instance']['display'][$context['view_mode']]['settings'];
$theme_breakpoints = breakpoints_breakpoint_load_all_active();
if (!empty($theme_breakpoints)) {
$element['resp_img_responsive'] = array(
'#type' => 'checkbox',
'#title' => t('Go responsive'),
'#default_value' => isset($settings['resp_img_responsive']) ? $settings['resp_img_responsive'] : FALSE,
'#description' => t('If you enable this, you can select an image style for each defined breakpoint/breakpoint.<br />
The image style at the top will be used as default/fallback.<br />
If you leave all dropdowns empty the logic will try to use the default breakpoint.'),
);
$element['resp_img'] = array(
'#type' => 'container',
'#states' => array(
'invisible' => array(
'input[name="fields[field_image][settings_edit_form][settings][resp_img_responsive]"]' => array(
'checked' => FALSE,
),
),
),
);
$image_styles = image_style_options(TRUE);
foreach ($theme_breakpoints as $breakpoint_name => $breakpoint) {
$label = $breakpoint->name . ' [' . $breakpoint->breakpoint . ']';
$element['resp_img'][$breakpoint_name]['1x'] = array(
'#title' => check_plain($label),
'#type' => 'select',
'#options' => $image_styles,
'#default_value' => isset($settings['resp_img'][$breakpoint_name]['1x']) ? $settings['resp_img'][$breakpoint_name]['1x'] : '',
);
if (isset($breakpoint->multipliers) && !empty($breakpoint->multipliers)) {
foreach ($breakpoint->multipliers as $multiplier => $value) {
if ($multiplier != '1x' && $value) {
$element['resp_img'][$breakpoint_name][$multiplier] = array(
'#title' => check_plain($multiplier . ' ' . $label),
'#type' => 'select',
'#options' => $image_styles,
'#default_value' => isset($settings['resp_img'][$breakpoint_name][$multiplier]) ? $settings['resp_img'][$breakpoint_name][$multiplier] : '',
);
}
}
}
}
}
}
}
function resp_img_field_formatter_settings_summary_alter(&$summary, $context) {
if (isset($context['field']['type']) && $context['field']['type'] === 'image') {
$settings = $context['instance']['display'][$context['view_mode']]['settings'];
if (isset($settings['resp_img_responsive']) && $settings['resp_img_responsive']) {
$summary .= '<br />Responsive mode activated';
}
}
}