You are here

vimeo_link_formatter.module in Vimeo Link Formatter 7

Provides a field formatter for Link fields to format them as Vimeo video players.

File

vimeo_link_formatter.module
View source
<?php

/**
 * @file
 * Provides a field formatter for Link fields to format them as Vimeo video players.
 */

/**
 * Implementats hook_field_formatter_info().
 */
function vimeo_link_formatter_field_formatter_info() {
  $formatters = array();
  $formatters['vimeo_link_formatter_player'] = array(
    'label' => t('Vimeo Player'),
    'description' => t('Embeds a Vimeo player, if the URL is for a Vimeo.com video page.'),
    'field types' => array(
      'link_field',
    ),
    'settings' => vimeo_link_formatter_default_settings_player(),
  );
  $formatters['vimeo_link_formatter_thumbnail'] = array(
    'label' => t('Vimeo Thumbnail'),
    'description' => t('Displays the thumbnail of Vimeo video, if the URL is for a Vimeo.com video page.'),
    'field types' => array(
      'link_field',
    ),
    'settings' => vimeo_link_formatter_default_settings_thumbnail(),
  );
  return $formatters;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function vimeo_link_formatter_field_formatter_settings_summary($field, $instance, $view_mode) {
  module_load_include('inc', 'vimeo_link_formatter', 'vimeo_link_formatter.admin');

  // Call the function which handles this formatter.
  $function = __FUNCTION__ . '_' . $instance['display'][$view_mode]['type'];
  return call_user_func($function, $field, $instance, $view_mode);
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function vimeo_link_formatter_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  module_load_include('inc', 'vimeo_link_formatter', 'vimeo_link_formatter.admin');

  // Call the function which handles this formatter.
  $function = __FUNCTION__ . '_' . $instance['display'][$view_mode]['type'];
  return call_user_func($function, $field, $instance, $view_mode, $form, $form_state);
}

/**
 * Implements hook_field_formatter_view().
 */
function vimeo_link_formatter_field_formatter_view(&$entity_type, &$entity, &$field, &$instance, &$langcode, &$items, &$display) {

  // Call the function which handles this formatter.
  $function = __FUNCTION__ . '_' . $display['type'];
  return call_user_func($function, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
}

/**
 * Implements vimeo_link_formatter_field_formatter_view_FORMATTER();
 *
 * Renders $items as <iframe>s for the vimeo_link_formatter_player formatter.
 *
 * @return Array
 *    A render()-compatible array of #markup strings, E.g.
 *      <iframe src="http://player.vimeo.com/video/14309120?title=0&amp;
 *      byline=0&amp;portrait=0&amp;color=c9ff23&amp;autoplay=1&amp;loop=1"
 *      width="400" height="225" frameborder="0"></iframe>
 */
function vimeo_link_formatter_field_formatter_view_vimeo_link_formatter_player($entity_type, $entity, $field, $instance, $langcode, $items, $display) {

  // Attributes for the <iframe>.
  // Makes IE's <iframe> borders play nicely.
  $attributes = array(
    'frameborder' => 0,
  );
  $settings = array(
    'width',
    'height',
  );
  foreach ($settings as $name) {
    $attributes[$name] = $display['settings'][$name];
  }
  $player_id = drupal_html_id('vimeo-player');
  $attributes['id'] = $player_id;
  $attributes = drupal_attributes($attributes);

  // Default Vimeo Player formatter settings.
  $defaults = vimeo_link_formatter_default_settings_player();

  // Options for Drupal's url() function.
  $url_options = array(
    'query' => array(),
    'external' => TRUE,
  );

  // Build up the query string.
  foreach ($display['settings'] as $name => $value) {

    // Vimeo does not pay attention to the value of the paramter, but
    // whether the parameter is set or not.  So it is important not to set
    // parameters to their default values.  I.e.
    //   Do not set title=1, because that is Vimeo.com's default, and setting
    //   title=1 will cause the same effect as setting title=0, which is not
    //   desirable.
    // Also, skip over the settings used for attributes.
    if (!in_array($name, $settings) && isset($defaults[$name]) && $defaults[$name] !== $value) {
      if ($name == 'js_api') {
        $url_options['query']['api'] = 1;
        $url_options['query']['player_id'] = $player_id;
      }
      else {
        $url_options['query'][$name] = $value;
      }
    }
  }
  $ret = array();
  foreach ($items as $delta => $item) {

    // Extract the ID from the URL.
    if ($vimeo = vimeo_link_formatter_id($item['url'])) {

      // Allow modules to alter embed code.
      $embed = array(
        'title' => $item['title'],
        'url_options' => $url_options,
        'attributes' => $attributes,
      );
      drupal_alter('vimeo_link_formatter_embed', $embed, $item, $display);
      $url = url($vimeo['protocol'] . '://player.vimeo.com/video/' . $vimeo['id'], $embed['url_options']);
      $title = check_plain($embed['title']);
      $ret[] = array(
        '#markup' => '<iframe title="' . $title . '" src="' . $url . '"' . $embed['attributes'] . '></iframe>',
      );
    }
    else {

      // The link is not a valid Vimeo.com link.
      // @todo Handle this better, perhaps with node-form validation or more
      // formatter settings?
    }
  }
  return $ret;
}

/**
 * Vimeo.com's default player settings.
 *
 * @see vimeo_link_formatter_field_formatter_settings_form_vimeo_link_formatter_player()
 *
 * @return Array
 *    Default values keyed by the setting name.
 */
function vimeo_link_formatter_default_settings_player() {
  $defaults = array(
    // Use the data types that Form API forms return them as;  Integer for
    // Booleans, and Strings for text-input numbers.
    'title' => 1,
    'byline' => 1,
    'portrait' => 1,
    'color' => '00adef',
    'autoplay' => 0,
    'loop' => 0,
    'width' => '400',
    'height' => '225',
    'js_api' => 0,
  );
  return $defaults;
}

/**
 * Vimeo.com's default thumbnail settings.
 *
 * @see vimeo_link_formatter_field_formatter_settings_form_vimeo_link_formatter_thumbnail()
 *
 * @return Array
 *    Default values keyed by the setting name.
 */
function vimeo_link_formatter_default_settings_thumbnail() {
  $defaults = array(
    'thumb_size' => 'medium',
    'image_link' => '',
  );
  return $defaults;
}

/**
 * Implementation of vimeo_link_formatter_field_formatter_view_FORMATTER();
 *
 * @return Vimeo remote image html
 */
function vimeo_link_formatter_field_formatter_view_vimeo_link_formatter_thumbnail($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $ret = array();
  foreach ($items as $delta => $item) {

    // Extract the ID from the URL.
    if ($vimeo = vimeo_link_formatter_id($item['url'])) {

      // Get the cached thumbnail data.
      $cache_id = 'vimeo_link_formatter_thumbnail_hash_' . $vimeo['id'];
      if ($cached = cache_get($cache_id, 'cache')) {
        $video_hash = $cached->data;
      }
      else {
        if ($video_raw = drupal_http_request($vimeo['protocol'] . '://vimeo.com/api/v2/video/' . $vimeo['id'] . '.php')->data) {
          $video_hash = @unserialize($video_raw);

          // Cache the response to avoid making an HTTP request everytime this
          // video's thumbnail is rendered.
          cache_set($cache_id, $video_hash, 'cache', CACHE_PERMANENT);
        }
      }
      if (!empty($video_hash)) {

        // Render the thumbnail's <img> markup.
        $thumb_size = $display['settings']['thumb_size'] ? $display['settings']['thumb_size'] : 'medium';
        if (module_exists('imagecache_external')) {
          $thumb_url = $video_hash[0]["thumbnail_large"];
          $img = theme('imagecache_external', array(
            'path' => $thumb_url,
            'style_name' => $thumb_size,
            'alt' => $video_hash[0]['title'],
          ));
        }
        else {
          $thumb_url = $video_hash[0]["thumbnail_{$thumb_size}"];
          $img = theme('image', array(
            'path' => $thumb_url,
            'alt' => $video_hash[0]['title'],
          ));
        }

        // Check if the formatter involves a link.
        if ($display['settings']['image_link'] == 'content') {
          $uri = entity_uri($entity_type, $entity);

          // By using a render array, URLs may be altered.
          $ret[] = array(
            '#theme' => 'link',
            '#path' => $uri['path'],
            '#text' => $img,
            '#options' => array(
              'html' => TRUE,
              'attributes' => array(),
            ),
          );
        }
        else {
          if ($display['settings']['image_link'] == 'video') {
            $ret[] = array(
              '#theme' => 'link',
              '#path' => $item['url'],
              '#text' => $img,
              '#options' => array(
                'html' => TRUE,
                'absolute' => TRUE,
                'attributes' => array(),
              ),
            );
          }
          else {

            // Just the thumbnail's <img> html.
            $ret[] = array(
              '#markup' => $img,
            );
          }
        }
      }
    }
    else {

      // The link is not a valid Vimeo.com link.
      // @todo Handle this better, perhaps with node-form validation or more
      // formatter settings?
    }
  }
  return $ret;
}

/**
 * Gets the Vimeo ID from a vimeo.com URL.
 *
 * @param $url String
 *
 * @return String
 *   The numeric ID as a string.
 */
function vimeo_link_formatter_id($url) {
  preg_match('@(http|https)://(www\\.)?vimeo\\.com/.*?([0-9]+)@', $url, $matches);
  return isset($matches[3]) ? array(
    'protocol' => $matches[1],
    'id' => $matches[3],
  ) : NULL;
}