You are here

royalsliderfield.module in RoyalSlider Integration 7

RoyalSlider Field module.

File

contrib/royalsliderfield/royalsliderfield.module
View source
<?php

/**
 * @file
 * RoyalSlider Field module.
 */

/**
 * Implements hook_field_info().
 */
function royalsliderfield_field_info() {
  return array(
    'royalsliderfields' => array(
      'label' => t('RoyalSlider Slides'),
      'description' => t('The slides of the carousel'),
      'settings' => array(
        'required_field' => 'rs_image',
      ),
      'default_widget' => 'royalsliderfields_widget',
      'default_formatter' => 'royalsliderfields_formatter',
    ),
  );
}

/**
 * Implements hook_field_is_empty().
 *
 * Each slide must have at least an image or HTML content defined. Otherwise it
 * should be considered empty.
 */
function royalsliderfield_field_is_empty($item, $field) {
  if (empty($item['rs_image']) && empty($item['rs_caption']) && empty($item['rs_video']) && empty($item['rs_content']['value']) && empty($item['rs_link'])) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implements hook_field_formatter_info().
 *
 * @see royalsliderfield_field_formatter_view()
 * @see _royalslider_optionsets()
 */
function royalsliderfield_field_formatter_info() {
  $options = _royalslider_optionsets();
  $default = NULL;
  if (isset($options['default'])) {
    $default = 'default';
  }
  return array(
    'royalsliderfields_formatter' => array(
      'label' => t('RoyalSlider Full Slide'),
      'field types' => array(
        'royalsliderfields',
      ),
      'settings' => array(
        'royalslider_optionset' => $default,
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 *
 * @see royalsliderfield_field_formatter_info()
 */
function royalsliderfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];
  switch ($display['type']) {
    case 'royalsliderfields_formatter':
      $slides = array();
      foreach ($items as $delta => $item) {
        $slides[$delta] = $item;
      }
      list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
      $element[0] = array(
        '#theme' => 'royalsliderfield',
        '#royalslider_id' => "royalslider-{$entity_type}-{$bundle}-{$instance['field_name']}-{$id}",
        '#slides' => $slides,
        '#optionset' => $settings['royalslider_optionset'],
      );
      break;
  }
  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function royalsliderfield_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  if ($display['type'] == 'royalsliderfields_formatter') {

    // TODO: Exclude disabled optionsets.
    $options = _royalslider_optionsets();
    if (isset($settings['royalslider_optionset'])) {
      return t('Optionset: @set', array(
        '@set' => $options[$settings['royalslider_optionset']],
      ));
    }
  }
  return '';
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function royalsliderfield_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $element = array();
  if ($display['type'] == 'royalsliderfields_formatter') {
    $element['royalslider_optionset'] = array(
      '#type' => 'select',
      '#title' => t('RoyalSlider optionset'),
      '#options' => _royalslider_optionsets(),
      '#default_value' => $settings['royalslider_optionset'],
    );
  }
  return $element;
}

/**
 * Implements hook_field_widget_info().
 *
 * @see royalsliderfield_field_widget_form()
 */
function royalsliderfield_field_widget_info() {
  return array(
    'royalsliderfields_widget' => array(
      'label' => t('Default'),
      'field types' => array(
        'royalsliderfields',
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function royalsliderfield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $required = $instance['required'] && $delta == 0 ? 1 : 0;
  $required_field = isset($instance['settings']['required_field']) ? $instance['settings']['required_field'] : 'rs_image';
  $element['rs_image'] = array(
    '#title' => t('Image'),
    '#description' => t('Allowed extensions: gif png jpg jpeg'),
    '#type' => 'managed_file',
    '#required' => $required && $required_field == 'rs_image' ? TRUE : FALSE,
    '#default_value' => isset($items[$delta]['rs_image']) ? $items[$delta]['rs_image'] : '',
    '#upload_location' => 'public://royalslider_images',
    '#upload_validators' => array(
      'file_validate_extensions' => array(
        'gif png jpg jpeg',
      ),
    ),
  );
  $element['rs_caption'] = array(
    '#title' => t('Image Caption'),
    '#description' => t('Image description.'),
    '#type' => 'textfield',
    '#required' => FALSE,
    '#default_value' => isset($items[$delta]['rs_caption']) ? $items[$delta]['rs_caption'] : '',
  );
  $element['rs_video'] = array(
    '#title' => t('Video URL'),
    '#description' => t('Add a Vimeo or YouTube video URL.'),
    '#type' => 'textfield',
    '#required' => FALSE,
    '#default_value' => isset($items[$delta]['rs_video']) ? $items[$delta]['rs_video'] : '',
  );
  $element['rs_content'] = array(
    '#type' => 'text_format',
    '#base_type' => 'textarea',
    '#title' => t('HTML Content'),
    '#format' => isset($items[$delta]['format']) ? $items[$delta]['format'] : filter_default_format(),
    '#required' => $required && $required_field == 'rs_content' ? TRUE : FALSE,
    '#default_value' => isset($items[$delta]['rs_content']) ? $items[$delta]['rs_content'] : NULL,
  );
  $element['rs_link'] = array(
    '#title' => t('Link'),
    '#description' => t('This will add an onclick attribute on the slide.'),
    '#type' => 'textfield',
    '#required' => FALSE,
    '#default_value' => isset($items[$delta]['rs_link']) ? $items[$delta]['rs_link'] : '',
  );
  return $element;
}

/**
 * Implements hook_field_presave().
 */
function royalsliderfield_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  if ($field['type'] == 'royalsliderfields') {
    foreach ($items as $delta => $value) {
      _royalsliderfield_process($items[$delta], $delta, $field, $entity);
    }
  }
}

/**
 * Prepares the image and HTML content.
 *
 * Other fields needs no additional processes.
 *
 * @see royalsliderfield_field_presave()
 */
function _royalsliderfield_process(&$item, $delta, $field, $entity) {
  $item['format'] = $item['rs_content']['format'];
  $item['rs_content'] = $item['rs_content']['value'];
  if (!empty($item['rs_image'])) {
    $file = file_load($item['rs_image']);
    $file->status = FILE_STATUS_PERMANENT;
    file_save($file);
    file_usage_add($file, 'royalsliderfield', 'royalsliderfield', $item['rs_image']);
  }
}

/**
 * Implements hook_field_widget_error().
 *
 * @see royalsliderfield_field_validate()
 * @see form_error()
 */
function royalsliderfield_field_widget_error($element, $error, $form, &$form_state) {
  if (isset($error) && count($error)) {
    foreach ($error as $err) {
      switch ($err['error']) {
        case 'royalsliderfields_image':
          form_error($element['rs_image'], $err['message']);
          break;
        case 'royalsliderfields_content':
          form_error($element['rs_content'], $err['message']);
          break;
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function royalsliderfield_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  if ($form['#field']['type'] == 'royalsliderfields') {
    if (isset($form['#instance']['settings']['required_field']) && !empty($form['#instance']['settings']['required_field'])) {
      $default_value = $form['#instance']['settings']['required_field'];
    }
    else {
      $default_value = 'rs_image';
    }
    $form['instance']['settings']['required_field'] = array(
      '#type' => 'select',
      '#title' => t('Select the field to make it required.'),
      '#options' => array(
        'rs_image' => t('Image'),
        'rs_content' => t('HTML Content'),
      ),
      '#default_value' => $default_value,
      '#description' => t('Select the component to make required for this widget.'),
      '#weight' => -6,
      '#states' => array(
        'visible' => array(
          ':input[name="instance[required]"]' => array(
            'checked' => TRUE,
          ),
        ),
      ),
    );

    // Set cardinality to unlimited.
    $form['field']['cardinality']['#default_value'] = FIELD_CARDINALITY_UNLIMITED;

    // Should we also hide cardinality setting?
    // $form['field']['#access'] = FALSE;
  }
}

/**
 * Implements hook_theme().
 */
function royalsliderfield_theme($existing, $type, $theme, $path) {
  return array(
    'royalsliderfield' => array(
      'variables' => array(
        'royalslider_id' => '',
        'optionset' => 'default',
        'skin' => '',
        'slides' => array(),
      ),
      'template' => 'royalsliderfield',
    ),
    'royalsliderfield_slide' => array(
      'variables' => array(
        'royalslider_id' => '',
        'optionset' => 'default',
        'slide' => NULL,
      ),
      'template' => 'royalsliderfield-slide',
    ),
  );
}

/**
 * Implements hook_preprocess_HOOK().
 *
 * Preprocess theme variables for the RoyalSlider wrapper.
 */
function royalsliderfield_preprocess_royalsliderfield(&$variables) {
  $optionset = royalslider_optionset_load($variables['optionset']);
  $id = drupal_html_id($variables['royalslider_id']);
  $variables['attributes_array']['class'][] = 'royalSlider';
  $variables['attributes_array']['id'] = $id;

  // Setup skin & fallback to default.
  $skin = !empty($variables['skin']) ? $variables['skin'] : $optionset->skin;
  $skins = royalslider_skins();
  $skin_class = isset($skins[$skin]['class']) ? $skins[$skin]['class'] : $skins['default']['class'];
  $variables['attributes_array']['class'][] = $skin_class;
  $slides_processed = array();
  foreach ($variables['slides'] as $slide) {
    $slides_processed[] = array(
      '#theme' => 'royalsliderfield_slide',
      '#royalslider_id' => $id,
      '#optionset' => $optionset,
      '#slide' => $slide,
    );
  }
  $variables['slides_processed'] = $slides_processed;

  // Add RoyalSlider library and skin.
  if (!empty($slides_processed)) {
    royalslider_add($id, $optionset, $skin);
    drupal_add_js(drupal_get_path('module', 'royalsliderfield') . '/royalsliderfield.js', array(
      'type' => 'file',
      'scope' => 'footer',
    ));
    return;
  }
}

/**
 * Implements hook_preprocess_HOOK().
 *
 * Preprocess theme variables for each RoyalSlider slide.
 */
function royalsliderfield_preprocess_royalsliderfield_slide(&$variables) {

  // Only set slider dimensions once.
  static $slider_size_added = FALSE;
  $optionset = $variables['optionset'];
  $slide = $variables['slide'];

  // Extract necessary details from the optionset.
  $skin = $optionset->skin;
  $imagestyle_fullscreen = $optionset->imagestyle_fullscreen;
  $imagestyle_normal = $optionset->imagestyle_normal;
  $imagestyle_thumbnail = $optionset->imagestyle_thumbnail;
  $attributes = array();
  $variables['rs_image'] = $slide['rs_image'];
  $variables['rs_caption'] = $slide['rs_caption'];
  $variables['rs_video'] = $slide['rs_video'];
  $variables['rs_content'] = $slide['rs_content'];
  $variables['format'] = $slide['format'];
  $variables['rs_link'] = $slide['rs_link'];
  $variables['content'] = '';

  // Image.
  $img_uri = $img_uri_normal = $img_uri_fullscreen = $img_uri_thumbnail = '';
  $img_url = $img_url_normal = $img_url_fullscreen = $img_url_thumbnail = '';
  $dimensions = array();
  if (isset($slide) && ($fid = $slide['rs_image'])) {
    $file = file_load($fid);
    $img_uri = $img_uri_normal = $img_uri_fullscreen = $img_uri_thumbnail = $file->uri;
    $img_url = $img_url_normal = $img_url_fullscreen = $img_url_thumbnail = file_create_url($file->uri);

    // Update image URLs for the defined image styles.
    //
    // Full Screen image style URL.
    if (!empty($imagestyle_fullscreen)) {
      $img_uri_fullscreen = image_style_path($imagestyle_fullscreen, $img_uri);
      $img_url_fullscreen = image_style_url($imagestyle_fullscreen, $img_uri);
    }

    // Normal image style URL.
    if (!empty($imagestyle_normal)) {
      $img_uri_normal = image_style_path($imagestyle_normal, $img_uri);
      $img_url_normal = image_style_url($imagestyle_normal, $img_uri);
    }

    // Thumbnail image style URL.
    if (!empty($imagestyle_thumbnail)) {
      $img_uri_thumbnail = image_style_path($imagestyle_thumbnail, $img_uri);
      $img_url_thumbnail = image_style_url($imagestyle_thumbnail, $img_uri);
    }

    // Full Screen support.
    if ($optionset->options['fullscreen']['enabled']) {
      $attributes['data-rsBigImg'] = $img_url_fullscreen;
    }

    // Thumbnail navigation.
    if ($optionset->options['controlNavigation'] === 'thumbnails') {
      $attributes['data-rsTmb'] = $img_url_thumbnail;
    }

    // Image dimensions.
    $dimensions = array();
    $image = image_get_info($img_uri_normal);
    if ($optionset->options['drupalAutoSetImageDimensions']) {
      $dimensions = array(
        'width' => $image['width'],
        'height' => $image['height'],
      );
      $attributes['data-rsw'] = $dimensions['width'];
      $attributes['data-rsh'] = $dimensions['height'];
    }
    else {
      if (isset($optionset->options['imgWidth'])) {
        $dimensions['width'] = $optionset->options['imgWidth'];
        $attributes['data-rsw'] = $optionset->options['imgWidth'];
      }
      if (isset($optionset->options['imgHeight'])) {
        $dimensions['height'] = $optionset->options['imgHeight'];
        $attributes['data-rsh'] = $optionset->options['imgHeight'];
      }
    }
    $attributes['alt'] = $slide['rs_caption'];
    $attributes['title'] = $slide['rs_caption'];
    $attributes['class'] = 'rsImg';

    // Set slider dimensions.
    if ($optionset->options['autoScaleSlider']) {

      // Only add them once.
      if (!$slider_size_added) {
        drupal_add_js(array(
          'royalslider' => array(
            'instances' => array(
              $variables['royalslider_id'] => array(
                'slider_height' => $dimensions['height'],
                'slider_width' => $dimensions['width'],
              ),
            ),
          ),
        ), 'setting');
      }
      $slider_size_added = TRUE;
    }
    $rs_image = '';
    if ($rs_video = royalsliderfield_get_video_id($slide['rs_video'])) {
      $attributes['data-rsVideo'] = $slide['rs_video'];
    }
    if ($optionset->options['usePreloader']) {
      $rs_image = l($variables['rs_caption'], $img_url_normal, array(
        'attributes' => $attributes,
      ));
    }
    else {
      $rs_image = theme('image', array(
        'attributes' => $attributes,
        'path' => $img_uri_normal,
      ));
    }
    $variables['content'] = $rs_image;
  }
  if (!empty($slide['rs_content'])) {
    $variables['content'] .= '<div class="rsContent-content">' . check_markup($slide['rs_content'], $slide['format']) . '</div>';
  }
  $onclick = '';
  if (!empty($slide['rs_link'])) {
    $onclick = ' data-rslink="' . url($slide['rs_link']) . '"';
  }
  $variables['content'] = '<div class="rsContent"' . $onclick . '>' . $variables['content'] . '</div>';
}

/**
 * Get YouTube or vimeo video ID.
 *
 * @param string $url
 *   Accepts video URLs in following formats:
 *   - youtube.com/watch?v=VIDEO_ID
 *   - youtu.be/VIDEO_ID
 *   - vimeo.com/VIDEO_ID
 *
 * @return string
 *   Video ID or FALSE.
 */
function royalsliderfield_get_video_id($url) {
  if (strstr($url, 'youtube.com/watch?') && preg_match('/v=[^&]*(?=&|$)/', $url, $matches)) {
    $video_id = ltrim($matches[0], 'v=');
  }
  elseif (strstr($url, 'youtu.be/')) {
    $anchor = 'be/';
    $position = strpos($url, $anchor);
    $video_id = trim(substr($url, $position + strlen($anchor)));
  }
  elseif (strstr($url, 'vimeo.com/') && preg_match('([0-9]+)', $url, $matches)) {
    $video_id = $matches[0];
  }
  if (!empty($video_id)) {
    return $video_id;
  }
  return FALSE;
}