You are here

field_orbit.module in ZURB Orbit 7

Same filename and directory in other branches
  1. 8 field_orbit.module
  2. 7.2 field_orbit.module

Implement a orbit formatter for fields.

File

field_orbit.module
View source
<?php

/**
 * @file
 * Implement a orbit formatter for fields.
 */

/**
 * Implements hook_field_formatter_info().
 */
function field_orbit_field_formatter_info() {
  $formatters = array(
    'orbit' => array(
      'label' => t('Orbit slideshow'),
      'field types' => array(
        'image',
        'imagefield_crop',
        'media',
        'field_collection',
      ),
      'settings' => array(
        'animation' => 'fade',
        'animationSpeed' => 800,
        'timer' => TRUE,
        'resetTimerOnClick' => FALSE,
        'advanceSpeed' => 4000,
        'pauseOnHover' => FALSE,
        'startClockOnMouseOut' => FALSE,
        'startClockOnMouseOutAfter' => 1000,
        'directionalNav' => TRUE,
        'captions' => TRUE,
        'captionAnimation' => 'fade',
        'captionAnimationSpeed' => 800,
        'bullets' => FALSE,
        'bulletThumbs' => FALSE,
        'bulletThumbLocation' => '',
        'fluid' => TRUE,
        'orbit_field_collection_image' => '',
        'orbit_image_style' => '',
        'orbit_link' => '',
        'orbit_caption' => '',
        'orbit_caption_link' => '',
      ),
    ),
  );
  return $formatters;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function field_orbit_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $element['orbit'] = array(
    '#type' => 'fieldset',
    '#title' => t('Orbit settings'),
  );
  $element['orbit']['animation'] = array(
    '#type' => 'select',
    '#title' => t('Animation'),
    '#default_value' => $settings['animation'],
    '#options' => array(
      'fade' => t('fade'),
      'horizontal-slide' => t('horizontal-slide'),
      'vertical-slide' => t('vertical-slide'),
      'horizontal-push' => t('horizontal-push'),
    ),
  );
  $element['orbit']['animationSpeed'] = array(
    '#type' => 'textfield',
    '#title' => t('Animation speed'),
    '#default_value' => $settings['animationSpeed'],
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
  );
  $element['orbit']['timer'] = array(
    '#type' => 'checkbox',
    '#title' => t('Timer'),
    '#default_value' => $settings['timer'],
  );
  $element['orbit']['resetTimerOnClick'] = array(
    '#type' => 'checkbox',
    '#title' => t('Reset timer on click'),
    '#default_value' => $settings['resetTimerOnClick'],
    '#description' => t('Resets the timer instead of pausing slideshow progress'),
  );
  $element['orbit']['advanceSpeed'] = array(
    '#type' => 'textfield',
    '#title' => t('Advance speed'),
    '#default_value' => $settings['advanceSpeed'],
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
  );
  $element['orbit']['pauseOnHover'] = array(
    '#type' => 'checkbox',
    '#title' => t('Pause on hover'),
    '#default_value' => $settings['pauseOnHover'],
    '#description' => t('If you hover pauses the slider'),
  );
  $element['orbit']['startClockOnMouseOut'] = array(
    '#type' => 'checkbox',
    '#title' => t('Start clock on mouseOut'),
    '#default_value' => $settings['startClockOnMouseOut'],
    '#description' => t('If clock should start on MouseOut'),
  );
  $element['orbit']['startClockOnMouseOutAfter'] = array(
    '#type' => 'textfield',
    '#title' => t('Start clock on mouseOut after'),
    '#default_value' => $settings['startClockOnMouseOutAfter'],
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
  );
  $element['orbit']['directionalNav'] = array(
    '#type' => 'checkbox',
    '#title' => t('Directional nav'),
    '#default_value' => $settings['directionalNav'],
    '#description' => t('Manual advancing directional navs'),
  );
  $element['orbit']['captions'] = array(
    '#type' => 'checkbox',
    '#title' => t('Captions'),
    '#default_value' => $settings['captions'],
  );
  $element['orbit']['captionAnimation'] = array(
    '#type' => 'select',
    '#title' => t('Caption animation'),
    '#default_value' => $settings['captionAnimation'],
    '#options' => array(
      'fade' => t('fade'),
      'slideOpen' => t('slideOpen'),
      'none' => t('none'),
    ),
  );
  $element['orbit']['captionAnimationSpeed'] = array(
    '#type' => 'textfield',
    '#title' => t('Caption animation speed'),
    '#default_value' => $settings['captionAnimationSpeed'],
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
  );
  $element['orbit']['bullets'] = array(
    '#type' => 'checkbox',
    '#title' => t('Bullets'),
    '#default_value' => $settings['bullets'],
    '#description' => t('Activate the bullet navigation'),
  );
  $element['orbit']['bulletThumbs'] = array(
    '#type' => 'checkbox',
    '#title' => t('Bullet thumbnails'),
    '#default_value' => $settings['bulletThumbs'],
  );
  $element['orbit']['bulletThumbLocation'] = array(
    '#type' => 'textfield',
    '#title' => t('Bullet thumbnail location'),
    '#default_value' => $settings['bulletThumbLocation'],
  );
  $element['orbit']['fluid'] = array(
    '#type' => 'checkbox',
    '#title' => t('Fluid'),
    '#default_value' => $settings['fluid'],
  );
  if ($field['type'] == 'field_collection') {
    $element['orbit_field_collection_image'] = array(
      '#title' => t('Image field'),
      '#type' => 'select',
      '#default_value' => $settings['orbit_field_collection_image'],
      '#empty_option' => t('None'),
      '#options' => _field_orbit_get_fields(array(
        'image',
        'imagefield_crop',
      ), $field['type'], $field['field_name']),
      '#required' => TRUE,
    );
  }
  $element['orbit_image_style'] = array(
    '#title' => t('Image style'),
    '#type' => 'select',
    '#default_value' => $settings['orbit_image_style'],
    '#empty_option' => t('None (original image)'),
    '#options' => image_style_options(FALSE),
  );
  $links = array(
    'content' => t('Content'),
    'file' => t('File'),
  );
  if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
    $links += _field_orbit_get_fields(array(
      'link_field',
      'node_reference',
    ), $field['type'], $field['field_name']);
  }
  $element['orbit_link'] = array(
    '#title' => t('Link image to'),
    '#type' => 'select',
    '#default_value' => $settings['orbit_link'],
    '#empty_option' => t('Nothing'),
    '#options' => $links,
  );
  if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
    $captions = _field_orbit_get_fields(array(
      'text',
    ), $field['type'], $field['field_name']);
  }
  else {
    $captions = array(
      'title' => t('Title text'),
      'alt' => t('Alt text'),
    );
  }
  $element['orbit_caption'] = array(
    '#title' => t('Caption'),
    '#type' => 'select',
    '#default_value' => $settings['orbit_caption'],
    '#empty_option' => t('Nothing'),
    '#options' => $captions,
  );
  $element['orbit_caption_link'] = array(
    '#title' => t('Caption link'),
    '#type' => 'select',
    '#default_value' => $settings['orbit_caption_link'],
    '#empty_option' => t('Nothing'),
    '#options' => $links,
    '#states' => array(
      'invisible' => array(
        ':input[name$="[settings_edit_form][settings][orbit_caption]"]' => array(
          'value' => '',
        ),
      ),
    ),
  );
  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function field_orbit_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $summary = array();
  $summary[] = t('Transition effect: @effect', array(
    '@effect' => $settings['animation'],
  ));
  $summary[] = t('Speed: @speedms', array(
    '@speed' => $settings['animationSpeed'],
  ));
  $summary[] = t('Show timer: @timer', array(
    '@timer' => $settings['timer'] ? 'yes' : 'no',
  ));
  $summary[] = t('Reset timer on click: @reset', array(
    '@reset' => $settings['resetTimerOnClick'] ? 'yes' : 'no',
  ));
  $summary[] = t('Advance speed: @speedms', array(
    '@speed' => $settings['advanceSpeed'],
  ));
  $summary[] = t('Pause on hover: @pause', array(
    '@pause' => $settings['pauseOnHover'] ? 'yes' : 'no',
  ));
  $summary[] = t('Start clock on mouseOut: @start', array(
    '@start' => $settings['startClockOnMouseOut'] ? 'yes' : 'no',
  ));
  $summary[] = t('Start clock on mouseOut after: @startms', array(
    '@start' => $settings['startClockOnMouseOutAfter'],
  ));
  $summary[] = t('Directional nav: @directionalNav', array(
    '@directionalNav' => $settings['directionalNav'] ? 'yes' : 'no',
  ));
  $summary[] = t('Show captions: @captions', array(
    '@captions' => $settings['captions'] ? 'yes' : 'no',
  ));
  $summary[] = t('Caption animation: @animation', array(
    '@animation' => $settings['captionAnimation'],
  ));
  $summary[] = t('Caption animation speed: @speedms', array(
    '@speed' => $settings['captionAnimationSpeed'],
  ));
  $summary[] = t('Bullets: @bullets', array(
    '@bullets' => $settings['bullets'] ? 'yes' : 'no',
  ));
  $summary[] = t('Bullet thumbnails: @thumbs', array(
    '@thumbs' => $settings['bulletThumbs'] ? 'yes' : 'no',
  ));
  $summary[] = t('Bullet thumb location: @location', array(
    '@location' => $settings['bulletThumbLocation'],
  ));
  $summary[] = t('Fluid: @fluid', array(
    '@fluid' => $settings['fluid'] ? 'yes' : 'no',
  ));
  $image_styles = image_style_options(FALSE);

  // Unset possible 'No defined styles' option.
  unset($image_styles['']);

  // Styles could be lost because of enabled/disabled modules that defines
  // their styles in code.
  if (isset($image_styles[$settings['orbit_image_style']])) {
    $summary[] = t('Image style: @style', array(
      '@style' => $image_styles[$settings['orbit_image_style']],
    ));
  }
  else {
    $summary[] = t('Original image');
  }
  $link_types = array(
    'content' => t('content'),
    'file' => t('file'),
  );
  if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
    $link_types += _field_orbit_get_fields(array(
      'link_field',
      'node_reference',
    ), $field['type'], $field['field_name']);
  }

  // Display this setting only if image is linked.
  if (isset($link_types[$settings['orbit_link']])) {
    $link_type_message = t('Link to: @link', array(
      '@link' => $link_types[$settings['orbit_link']],
    ));
    $summary[] = $link_type_message;
  }
  if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
    $caption_types = _field_orbit_get_fields(array(
      'text',
    ), $field['type'], $field['field_name']);
  }
  else {
    $caption_types = array(
      'title' => t('Title text'),
      'alt' => t('Alt text'),
    );
  }

  // Display this setting only if there's a caption.
  if (isset($caption_types[$settings['orbit_caption']])) {
    $caption_message = t('Caption: @caption', array(
      '@caption' => $caption_types[$settings['orbit_caption']],
    ));
    if (isset($link_types[$settings['orbit_caption_link']])) {
      $caption_message .= ' (' . t('Link to: @link', array(
        '@link' => $link_types[$settings['orbit_caption_link']],
      )) . ')';
    }
    $summary[] = $caption_message;
  }
  return implode('<br />', $summary);
}

/**
 * Implements hook_field_formatter_view().
 */
function field_orbit_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $element = array();

  // Media field support
  if ($field['type'] == 'media') {
    foreach ($items as $delta => $item) {
      $items[$delta] = (array) $item;
      $items[$delta]['uri'] = $item['file']->uri;
    }
  }
  elseif ($field['type'] == 'field_collection') {
    foreach ($items as $delta => $item) {
      $items[$delta] = (array) field_collection_field_get_entity($item);
      $items[$delta]['uri'] = $items[$delta][$settings['orbit_field_collection_image']][$langcode][0]['uri'];
    }
  }

  // Get correct caption
  if ($settings['orbit_caption'] != '') {
    foreach ($items as $delta => $item) {
      if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
        if ($field['type'] == 'media') {
          $items[$delta]['caption'] = $items[$delta]['file']->{$settings}['orbit_caption'];
        }
        elseif ($field['type'] == 'field_collection') {
          $items[$delta]['caption'] = $items[$delta][$settings['orbit_caption']];
        }
        if (!empty($items[$delta]['caption']) && isset($items[$delta]['caption'][$langcode])) {
          $items[$delta]['caption'] = $items[$delta]['caption'][$langcode][0]['value'];
        }
        else {
          $items[$delta]['caption'] = '';
        }
      }
      else {
        $items[$delta]['caption'] = $item[$settings['orbit_caption']];
      }
    }
  }
  $links = array(
    'orbit_link' => 'path',
    'orbit_caption_link' => 'caption_path',
  );
  $content_uri = entity_uri($entity_type, $entity);

  // Get the correct field for identifying entity (used to get correct links)
  $entity_info = entity_get_info($entity_type);
  $entity_id_field = $entity_info['entity keys']['id'];

  // Loop through required links (because image and caption can have different links).
  foreach ($links as $setting => $path) {

    // Check if the formatter involves a link.
    $link_type = '';
    switch ($settings[$setting]) {
      case 'content':
        $link_type = 'content';
        break;
      case 'file':
        $link_type = 'file';
        break;
      default:
        if (($field['type'] == 'media' || $field['type'] == 'field_collection') && drupal_substr($settings[$setting], 0, 6) == 'field_') {
          $infos = field_info_field($settings[$setting]);
          $link_type = $infos['type'];
        }
        break;
    }

    // Generate special links (other than node)
    foreach ($items as $delta => $item) {
      $uri = array();
      switch ($link_type) {
        case 'content':
          $uri = $content_uri;
          break;
        case 'file':
          $uri = array(
            'path' => file_create_url($item['uri']),
            'options' => array(),
          );
          break;
        case 'link_field':
          if ($field['type'] == 'media') {
            $pathfield = $item['file']->{$settings}[$setting];
          }
          elseif ($field['type'] == 'field_collection') {
            $pathfield = $item[$settings[$setting]];
          }
          if (isset($pathfield[$langcode])) {
            $uri = array(
              'path' => $pathfield[$langcode][0]['url'],
              'options' => array(),
            );
          }
          break;
        case 'node_reference':
          if ($field['type'] == 'media') {
            $pathfield = $item['file']->{$settings}[$setting];
          }
          elseif ($field['type'] == 'field_collection') {
            $pathfield = $item[$settings[$setting]];
          }
          if (isset($pathfield[$langcode])) {
            $uri = array(
              'path' => drupal_get_path_alias('node/' . $pathfield[$langcode][0]['nid'], $langcode),
              'options' => array(),
            );
          }
          break;
      }
      $items[$delta][$path] = !empty($uri) ? $uri : '';
    }
  }
  if (count($items)) {
    $element[] = array(
      '#theme' => 'field_orbit',
      '#items' => $items,
      '#options' => array(
        'animation' => $settings['animation'],
        'animationSpeed' => $settings['animationSpeed'],
        'timer' => $settings['timer'],
        'resetTimerOnClick' => $settings['resetTimerOnClick'],
        'advanceSpeed' => $settings['advanceSpeed'],
        'pauseOnHover' => $settings['pauseOnHover'],
        'startClockOnMouseOut' => $settings['startClockOnMouseOut'],
        'startClockOnMouseOutAfter' => $settings['startClockOnMouseOutAfter'],
        'directionalNav' => $settings['directionalNav'],
        'captions' => $settings['captions'],
        'captionAnimation' => $settings['captionAnimation'],
        'captionAnimationSpeed' => $settings['captionAnimationSpeed'],
        'bullets' => $settings['bullets'],
        'bulletThumbs' => $settings['bulletThumbs'],
        'bulletThumbLocation' => $settings['bulletThumbLocation'],
        'fluid' => $settings['fluid'],
      ),
      '#entity' => $entity,
    );
  }
  return $element;
}

/**
 * Implements hook_theme().
 */
function field_orbit_theme() {
  return array(
    'field_orbit' => array(
      'variables' => array(
        'items' => NULL,
        'options' => NULL,
        'entity' => NULL,
      ),
      'template' => 'field_orbit',
    ),
  );
}

/**
 * Implements template_preprocess().
 */
function template_preprocess_field_orbit(&$variables) {
  drupal_add_css(drupal_get_path('module', 'field_orbit') . '/vendor/orbit.css');
  drupal_add_js(array(
    'field_orbit' => array(
      'field-orbit-' . $variables['id'] => $variables['options'],
    ),
  ), 'setting');
  drupal_add_js(drupal_get_path('module', 'field_orbit') . '/vendor/jquery.foundation.orbit.min.js', array(
    'scope' => 'footer',
  ));
  drupal_add_js(drupal_get_path('module', 'field_orbit') . '/field_orbit.js', array(
    'scope' => 'footer',
  ));

  // Generate classes
  $variables['classes_array'][] = 'field-orbit-' . $variables['id'];

  // Generate slides
  $field_orbit_zebra = 'odd';
  $variables['slides_max_width'] = 0;
  $variables['slides_max_height'] = 0;
  foreach ($variables['items'] as $num => $item) {

    // Generate classes
    $classes = array(
      'field-orbit-slide',
      'field-orbit-slide-' . (1 + $num),
    );
    $field_orbit_zebra = $field_orbit_zebra == 'odd' ? 'even' : 'odd';
    $classes[] = $field_orbit_zebra;
    if ($num == 0) {
      $classes[] = 'first';
    }
    elseif ($num == count($variables['items']) - 1) {
      $classes[] = 'last';
    }
    $variables['items'][$num]['classes'] = implode(' ', $classes);

    // Generate the image html
    $image = array();
    $image['path'] = $item['uri'];
    $image['attributes']['class'] = array(
      'field-orbit-image',
      'field-orbit-image-' . (1 + $num),
    );
    $image['alt'] = isset($item['alt']) ? $item['alt'] : '';
    if (isset($item['width']) && isset($item['height'])) {
      $image['width'] = $item['width'];
      $image['height'] = $item['height'];
    }
    else {
      $image_dims = getimagesize($image['path']);
      $image['width'] = $image_dims[0];
      $image['height'] = $image_dims[1];
    }
    if (!empty($item['caption'])) {
      $image['attributes']['data-caption'] = '#field-orbit-image-' . ($num + 1) . '-caption';
      $variables['items'][$num]['caption_id'] = 'field-orbit-image-' . ($num + 1) . '-caption';
    }
    if (isset($item['title']) && drupal_strlen($item['title']) > 0) {
      $image['title'] = $item['title'];
    }
    if (isset($variables['image_style']) && $variables['image_style'] != '') {
      $image['style_name'] = $variables['image_style'];
      $variables['items'][$num]['image'] = theme('image_style', $image);
    }
    else {
      $variables['items'][$num]['image'] = theme('image', $image);
    }

    // Get image sizes and keeps the bigger ones, so height is correctly calculated by Cycle
    $dimensions = array(
      'width' => $image['width'],
      'height' => $image['height'],
    );
    if (isset($variables['image_style']) && $variables['image_style'] != '') {
      if (function_exists('image_style_transform_dimensions')) {
        image_style_transform_dimensions($image['style_name'], $dimensions);
      }

      // manual calculation if Drupal < 7.9 or image_style_transform_dimensions doesn't work
      if (!function_exists('image_style_transform_dimensions') || !is_numeric($dimensions['width'])) {
        $thumbnail_path = image_style_path($variables['image_style'], $image['path']);

        // if thumbnail is not generated, do it, so we can get the dimensions
        if (!file_exists($thumbnail_path)) {
          image_style_create_derivative(image_style_load($variables['image_style']), $image['path'], $thumbnail_path);
        }
        $thumbnail_dims = getimagesize($thumbnail_path);
        $dimensions = array(
          'width' => $thumbnail_dims[0],
          'height' => $thumbnail_dims[1],
        );
      }
    }

    // If the theme function hasn't added width and height attributes to the image, add them
    if (strpos($variables['items'][$num]['image'], 'width=') === FALSE) {
      $variables['items'][$num]['image'] = drupal_substr($variables['items'][$num]['image'], 0, -2) . "width=\"{$dimensions['width']}\" height=\"{$dimensions['height']}\" />";
    }

    // Add links if needed
    $links = array(
      'path' => 'image',
    );
    if (isset($item['caption']) && $item['caption'] != '') {
      $links['caption_path'] = 'caption';
    }

    // Loop thru required links (because image and caption can have different links)
    foreach ($links as $link => $out) {
      if (!empty($item[$link])) {
        $path = $item[$link]['path'];
        $options = $item[$link]['options'];

        // When displaying an image inside a link, the html option must be TRUE.
        $options['html'] = TRUE;

        // Generate differnet rel attribute for image and caption, so colorbox doesn't double the image list
        if (isset($options['attributes']['rel'])) {
          $options['attributes']['rel'] .= $out;
        }
        $options = array_merge($options, drupal_parse_url($path));
        $variables['items'][$num][$out] = l($variables['items'][$num][$out], $options['path'], $options);
      }
    }
  }
}

/*
 * Helper functions.
 */
function _field_orbit_get_fields($field_types, $entity_type, $field_name = '') {
  $links = array();
  $fields = field_info_fields();
  switch ($entity_type) {
    case 'media':
      $bundle = 'file';
      $bundle_instance = 'image';
      $entity_label = t('Media field:');
      break;
    case 'field_collection':
      $bundle = 'field_collection_item';
      $bundle_instance = $field_name;
      $entity_label = t('Field Collection field:');
      break;
  }
  foreach ($fields as $name => $field) {
    if (in_array($bundle, array_keys($field['bundles'])) && in_array($bundle_instance, $field['bundles'][$bundle]) && in_array($field['type'], $field_types)) {
      $infos = field_info_instance($bundle, $name, $bundle_instance);
      $links[$name] = $entity_label . ' ' . $infos['label'];
    }
  }
  return $links;
}