...
 
Commits (56)
......@@ -27,9 +27,16 @@ accept YouTube URLs of the following formats:
* http://youtube.com/watch?v=[video_id]
* http://youtu.be/[video_id]
* http://youtube.com/v/[video_id]
* http://youtube.com/embed/[video_id]
* http://youtube.com/?v=[video_id]
It will not be a problem if users submit values with http:// or https:// and
additional parameters after the URL will be ignored.
All formats listed above can also be provided without 'http://', with 'www.',
or with 'https://' rather than 'http://'. The last format can be provided with
additional parameters (ignored) and v does not have to be the first parameter.
To enable Colorbox support, enable the YouTube Field Colorbox module included in
this directory and consult its README file.
CONFIGURATION
......
SUMMARY - YouTube Field Colorbox
=================================
Provides Colorbox support to the YouTube Field module.
Provides the ability to link YouTube thumbnails to be opened in a YouTube video
player within a Colorbox modal window. Display settings can alter the Colorbox
size and other parameter options.
REQUIREMENTS
-------------
- YouTube Field
- Colorbox
INSTALLATION
-------------
Install this module as usual. Please see
http://drupal.org/documentation/install/modules-themes/modules-7
USAGE
------
To use this module:
1. The Colorbox plugin must be properly included. The status of this can be
checked at admin/reports/status.
2. 'Enable Colorbox load' must be enabled on the Colorbox module settings. This
setting is found at admin/config/media/colorbox.
CONFIGURATION
--------------
There are no global module settings.
Once enabled, to use and configure this module:
1. Create a YouTube field (see USAGE within YouTube Field's README).
2. Alter the YouTube field's display settings.
3. Select 'YouTube thumbnail' for the format option.
4. Under format settings (click gear), select 'Colorbox' under 'Link image to'.
5. Alter the parameters and other settings available when 'Colorbox' is chosen.
SUPPORT
--------
Please use the issue queue to report bugs or request support:
http://drupal.org/project/issues/youtube
name = YouTube Field Colorbox
description = Provides Colorbox support to YouTube Field thumbnail display settings.
package = Fields
core = 7.x
dependencies[] = colorbox
dependencies[] = youtube
<?php
/**
* @file
* Provides Colorbox support to YouTube Field display settings.
*/
/**
* The machine name for the YouTube Colorbox link type used by display settings.
*/
define('YOUTUBE_COLORBOX_LINK_TYPE', 'colorbox');
/**
* Implements hook_field_formatter_info_alter().
*/
function youtube_colorbox_field_formatter_info_alter(&$info) {
$info['youtube_thumbnail']['settings'][YOUTUBE_COLORBOX_LINK_TYPE]['parameters'] = array(
'width' => 640,
'height' => 480,
'autoplay' => '1',
);
}
/**
* Implements hook_youtube_thumbnail_link_types_alter().
*/
function youtube_colorbox_youtube_thumbnail_link_types_alter(&$link_types) {
// Add the "Colorbox" link type to YouTube Field's thumbnail display settings.
$link_types[YOUTUBE_COLORBOX_LINK_TYPE] = t('Colorbox');
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function youtube_colorbox_form_youtube_settings_form_alter(&$form, &$form_state) {
// Provide warning about the need to set 'Enable Colorbox load' to TRUE in the
// Colorbox module settings. Otherwise links provided by YouTube Colorbox will
// not work as expected. This warning appears in the YouTube module settings.
if (!variable_get('colorbox_load', FALSE)) {
$args = array('!colorbox_settings' => l('Colorbox module settings', 'admin/config/media/colorbox'));
$message = t('Please enable \'Enable Colorbox load\' in the !colorbox_settings for thumbnails linked by YouTube Field Colorbox to work as expected.', $args);
drupal_set_message($message, 'warning');
}
}
/**
* Implements hook_youtube_thumbnail_field_formatter_settings_alter().
*/
function youtube_colorbox_youtube_thumbnail_field_formatter_settings_alter(&$element, $instance, $settings, $field_name) {
$colorbox = $settings[YOUTUBE_COLORBOX_LINK_TYPE];
// Set the states input name variable. JS states functionality will otherwise
// break in Panels if the entity type is 'ctools'.
$input_name = 'fields[' . $field_name . '][settings_edit_form][settings][image_link]';
$input_name = ($instance['entity_type'] != 'ctools') ? $input_name : 'image_link';
// Setting elements.
$element[YOUTUBE_COLORBOX_LINK_TYPE] = array(
'#type' => 'fieldset',
'#title' => t('Colorbox Settings'),
'#states' => array(
'visible' => array(
':input[name="' . $input_name . '"]' => array('value' => YOUTUBE_COLORBOX_LINK_TYPE),
),
),
'#tree' => TRUE,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters'] = array(
'#type' => 'fieldset',
'#title' => t('Parameters'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['width'] = array(
'#type' => 'textfield',
'#title' => t('Width'),
'#size' => 5,
'#required' => TRUE,
'#field_suffix' => 'px',
'#default_value' => $colorbox['parameters']['width'],
'#element_validate' => array('youtube_colorbox_element_is_int'),
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['height'] = array(
'#type' => 'textfield',
'#title' => t('Height'),
'#size' => 5,
'#required' => TRUE,
'#field_suffix' => 'px',
'#default_value' => $colorbox['parameters']['height'],
'#element_validate' => array('youtube_colorbox_element_is_int'),
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['autoplay'] = array(
'#type' => 'checkbox',
'#title' => t('Play video automatically when loaded (autoplay).'),
'#default_value' => $colorbox['parameters']['autoplay'],
'#return_value' => 1,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['loop'] = array(
'#type' => 'checkbox',
'#title' => t('Loop the playback of the video (loop).'),
'#default_value' => $colorbox['parameters']['loop'],
'#return_value' => 1,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['showinfo'] = array(
'#type' => 'checkbox',
'#title' => t('Hide video title and uploader info (showinfo).'),
'#default_value' => $colorbox['parameters']['showinfo'],
'#return_value' => 1,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['controls'] = array(
'#type' => 'checkbox',
'#title' => t('Always hide video controls (controls).'),
'#default_value' => $colorbox['parameters']['controls'],
'#return_value' => 1,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['autohide'] = array(
'#type' => 'checkbox',
'#title' => t('Hide video controls after play begins (autohide).'),
'#default_value' => $colorbox['parameters']['autohide'],
'#return_value' => 1,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['iv_load_policy'] = array(
'#type' => 'checkbox',
'#title' => t('Hide video annotations by default (iv_load_policy).'),
'#default_value' => $colorbox['parameters']['iv_load_policy'],
'#return_value' => 3,
);
$element[YOUTUBE_COLORBOX_LINK_TYPE]['gallery'] = array(
'#type' => 'checkbox',
'#title' => t('Group all videos on the page into a gallery'),
'#default_value' => $colorbox['gallery'],
);
}
/**
* An element validation callback to check if the value is a positive integer.
*/
function youtube_colorbox_element_is_int($element, $form_state, $form) {
if (intval($element['#value']) < 1) {
$args = array('@element_title' => $element['#title']);
form_error($element, t('@element_title must be a positive integer value.', $args));
}
}
/**
* Implements hook_youtube_thumbnail_link_uri_alter().
*/
function youtube_colorbox_youtube_thumbnail_link_uri_alter(&$uri, &$settings, $item) {
if ($settings['image_link'] != YOUTUBE_COLORBOX_LINK_TYPE) {
return;
}
// Always open in an iframe for proper origin access.
$settings[YOUTUBE_COLORBOX_LINK_TYPE]['parameters']['iframe'] = TRUE;
// Field display settings.
$parameters = $settings[YOUTUBE_COLORBOX_LINK_TYPE]['parameters'];
// Invert parameters that should be 0 when their options are selected.
$invert_parameters = array('showinfo', 'controls');
foreach ($invert_parameters as $parameter) {
if (isset($parameters[$parameter])) {
$parameters[$parameter] = $parameters[$parameter] ? 0 : 1;
}
}
// Global YouTube module configuration.
$domain = variable_get('youtube_privacy', FALSE) ? 'youtube-nocookie.com' : 'youtube.com';
$player_class = variable_get('youtube_player_class', 'youtube-field-player');
if (!variable_get('youtube_suggest', TRUE)) {
$parameters['rel'] = '0';
}
if (variable_get('youtube_modestbranding', FALSE)) {
$parameters['modestbranding'] = '1';
}
if (variable_get('youtube_theme', FALSE)) {
$parameters['theme'] = 'light';
}
if (variable_get('youtube_color', FALSE)) {
$parameters['color'] = 'white';
}
if (variable_get('youtube_enablejsapi', FALSE)) {
global $base_url;
$parameters['enablejsapi'] = '1';
$parameters['origin'] = $base_url;
}
if (variable_get('youtube_wmode', TRUE)) {
$parameters['wmode'] = 'opaque';
}
$uri = array(
'path' => 'https://www.' . $domain . '/embed/' . $item['video_id'],
'options' => array(
'attributes' => array(
'class' => array('colorbox-load', $player_class),
'id' => drupal_html_id($player_class),
),
'html' => TRUE,
'external' => TRUE,
'query' => $parameters,
),
);
if (!empty($settings[YOUTUBE_COLORBOX_LINK_TYPE]['gallery'])) {
$uri['options']['attributes']['rel'] = 'youtube-gallery';
}
}
<?php
/**
* @file
* Hooks provided by the YouTube Field module.
*/
/**
* Alter the link types in the YouTube Thumbnail formatter's display settings.
*
* Useful when linking a YouTube Thumbnail to something other than the content
* or YouTube video, such as opening the video in a modal window.
*
* @param array $link_types
* An array of options to link a thumbnail to. The array items' keys are the
* machine names and values are the readable names.
*/
function hook_youtube_thumbnail_link_types_alter(&$link_types) {
// See youtube_colorbox_youtube_thumbnail_link_types_alter() within the
// YouTube Colorbox module for example usage.
}
/**
* Alter the field display settings for the YouTube Thumbnail formatter.
*
* Useful to add settings to a custom link type added with
* hook_youtube_thumbnail_link_types_alter().
*
* @param array $element
* The field formatter form to add settings to.
* @param array $instance
* The instance of the field being formatted.
* @param array $settings
* Existing form settings.
* @param string $field_name
* The machine name of the field.
*/
function hook_youtube_thumbnail_field_formatter_settings_alter(&$element, $instance, $settings, $field_name) {
// See youtube_colorbox_youtube_thumbnail_field_formatter_settings_alter()
// within the YouTube Colorbox module for example usage.
}
/**
* Alter a linked thumbnail's uri.
*
* Useful to define what a thumbnail should link to for a link type added with
* hook_youtube_thumbnail_link_types_alter().
*
* @param array $uri
* The current uri array. Contains the keys:
* - 'path': The link path, as eventually passed to l().
* - 'options': The link options, as eventually passed to l().
* @param array $settings
* The field item's display settings.
* @param array $item
* The field item to provide the link for.
*/
function hook_youtube_thumbnail_link_uri_alter(&$uri, &$settings, $item) {
// See youtube_colorbox_youtube_thumbnail_link_uri_alter() within the
// YouTube Colorbox module for example usage.
}
This diff is collapsed.
......@@ -5,5 +5,6 @@ core = 7.x
dependencies[] = field
dependencies[] = image
dependencies[] = file
files[] = youtube.migrate.inc
stylesheets[all][] = css/youtube.css
configure = admin/config/media/youtube
......@@ -34,13 +34,28 @@ function youtube_field_schema($field) {
*/
function youtube_uninstall() {
// Delete youtube variables when module is removed.
variable_del('youtube_suggest');
variable_del('youtube_modestbranding');
variable_del('youtube_theme');
variable_del('youtube_color');
variable_del('youtube_enablejsapi');
variable_del('youtube_playerid');
variable_del('youtube_modestbranding');
variable_del('youtube_player_class');
variable_del('youtube_privacy');
variable_del('youtube_suggest');
variable_del('youtube_theme');
variable_del('youtube_thumb_dir');
variable_del('youtube_thumb_hires');
variable_del('youtube_thumb_token_image_style');
variable_del('youtube_wmode');
variable_del('youtube_override');
}
/**
* Replace the youtube_playerid setting variable with youtube_player_class. This
* is needed to fix issue of duplicate player IDs on the same page.
*/
function youtube_update_7103() {
$legacy_player_id = variable_get('youtube_playerid');
if ($legacy_player_id) {
variable_set('youtube_player_class', $legacy_player_id);
}
variable_del('youtube_playerid');
}
<?php
/**
* @file
* YouTube Field support for use with the migrate module.
*/
/**
* Implements hook_migrate_api().
*/
function youtube_migrate_api() {
$api = array(
'api' => 2,
'field handlers' => array('MigrateYoutubeFieldHandler'),
);
return $api;
}
class MigrateYoutubeFieldHandler extends MigrateFieldHandler {
/**
* Declares the type(s) of fields used.
*/
public function __construct() {
$this->registerTypes(array('youtube'));
}
/**
* Arguments for a YouTube field migration.
*
* @param string $input
* The URL of the YouTube video. If a value is not supplied, this will be
* constructed from the $video_id.
*
* @return array
* An array of the defined variables in this scope.
*/
static function arguments($input = NULL) {
return get_defined_vars();
}
/**
* Implementation of MigrateFieldHandler::fields().
*
* @param $type
* The field type.
* @param $instance
* Instance info for the field.
* @param Migration $migration
* The migration context for the parent field. We can look at the mappings
* and determine which subfields are relevant.
* @return array
*/
public function fields($type, $instance, $migration = NULL) {
return array(
'input' => t('Subfield: The full YouTube video URL'),
);
}
/**
* Converts incoming data to the proper format for YouTube fields.
*
* @param object $entity
* The destination entity which will hold the field arrays.
* @param array $field_info
* Metadata for the YouTube field being populated.
* @param array $instance
* Metadata for this instance of the YouTube field being populated.
* @param array $values
* Array of YouTube values to be fielded.
*
* @return array|null
* An array of YouTube fields.
*/
public function prepare($entity, array $field_info, array $instance, array $values) {
if (isset($values['arguments'])) {
$arguments = $values['arguments'];
unset($values['arguments']);
}
else {
$arguments = array();
}
$language = $this->getFieldLanguage($entity, $field_info, $arguments);
$values = array_filter($values);
foreach ($values as $delta => $value) {
$item = array();
$video_id = youtube_get_video_id($value);
if (!empty($video_id)) {
$item['input'] = $value;
$item['video_id'] = $video_id;
}
$return[$language][$delta] = $item;
}
return isset($return) ? $return : NULL;
}
}
This diff is collapsed.
......@@ -8,40 +8,38 @@
* Theme function for videos.
*/
function theme_youtube_video($variables) {
$id = $variables['video_id'];
global $base_root;
$video_id = $variables['video_id'];
// Get field display settings.
$size = $variables['size'];
$width = array_key_exists('width', $variables)? $variables['width'] : NULL;
$height = array_key_exists('height', $variables)? $variables['height'] : NULL;
$autoplay = array_key_exists('autoplay', $variables)? $variables['autoplay'] : FALSE;
$showinfo = array_key_exists('showinfo', $variables)? $variables['showinfo'] : FALSE;
$controls = array_key_exists('controls', $variables)? $variables['controls'] : FALSE;
$autohide = array_key_exists('autohide', $variables)? $variables['autohide'] : FALSE;
$iv_load_policy = array_key_exists('iv_load_policy', $variables)? $variables['iv_load_policy'] : FALSE;
$width = array_key_exists('width', $variables) ? $variables['width'] : NULL;
$height = array_key_exists('height', $variables) ? $variables['height'] : NULL;
$autoplay = array_key_exists('autoplay', $variables) ? $variables['autoplay'] : FALSE;
$loop = array_key_exists('loop', $variables) ? $variables['loop'] : FALSE;
$showinfo = array_key_exists('showinfo', $variables) ? $variables['showinfo'] : FALSE;
$controls = array_key_exists('controls', $variables) ? $variables['controls'] : FALSE;
$autohide = array_key_exists('autohide', $variables) ? $variables['autohide'] : FALSE;
$iv_load_policy = array_key_exists('iv_load_policy', $variables) ? $variables['iv_load_policy'] : FALSE;
$playsinline = array_key_exists('playsinline', $variables) ? $variables['playsinline'] : FALSE;
$allow = array();
if (array_key_exists('allow_autoplay', $variables)) $allow[] = 'autoplay';
if (array_key_exists('allow_fullscreen', $variables)) $allow[] = 'fullscreen';
// Get YouTube settings.
$suggest = variable_get('youtube_suggest', TRUE);
$privacy = variable_get('youtube_privacy', FALSE);
$modestbranding = variable_get('youtube_modestbranding', FALSE);
$theme = variable_get('youtube_theme', FALSE);
$color = variable_get('youtube_color', FALSE);
$enablejsapi = variable_get('youtube_enablejsapi', FALSE);
$player_class = variable_get('youtube_player_class', 'youtube-field-player');
$wmode = variable_get('youtube_wmode', TRUE);
$privacy = variable_get('youtube_privacy', FALSE);
$dimensions = youtube_get_dimensions($size, $width, $height);
if ($enablejsapi) {
$playerid = variable_get('youtube_playerid', 'youtube-field-player');
}
else {
$playerid = 'youtube-field-player';
}
// Protocol changes based on current page TODO.
$protocol = (isset($_SERVER['HTTPS'])) ? 'https' : 'http';
// Query string changes based on setings.
// Query string changes based on settings.
$query = array();
if (!$suggest) {
$query['rel'] = '0';
......@@ -56,9 +54,8 @@ function theme_youtube_video($variables) {
$query['color'] = 'white';
}
if ($enablejsapi) {
global $base_url;
$query['enablejsapi'] = '1';
$query['origin'] = parse_url($base_url, PHP_URL_HOST);
$query['origin'] = $base_root;
}
if ($wmode) {
$query['wmode'] = 'opaque';
......@@ -66,6 +63,10 @@ function theme_youtube_video($variables) {
if ($autoplay) {
$query['autoplay'] = '1';
}
if ($loop) {
$query['loop'] = '1';
$query['playlist'] = $video_id;
}
if ($showinfo) {
$query['showinfo'] = '0';
}
......@@ -78,16 +79,53 @@ function theme_youtube_video($variables) {
if ($iv_load_policy) {
$query['iv_load_policy'] = '3';
}
if ($playsinline) {
$query['playsinline'] = '1';
}
// If the override setting is enabled, add any additional parameters provided
// in the initial field value to the query of the embedded video.
if (variable_get('youtube_override')) {
if ($url_parts = drupal_parse_url($variables['input'])) {
foreach ($url_parts['query'] as $key => $value) {
if ($key == 'v') {
continue;
}
$query[$key] = $value;
}
}
}
// Domain changes based on settings.
$domain = ($privacy) ? 'youtube-nocookie.com' : 'youtube.com';
$path = $protocol . '://www.' . $domain . '/embed/' . $id;
$path = 'https://www.' . $domain . '/embed/' . $video_id;
$src = url($path, array('query' => $query));
$output = '<iframe id="' . $playerid . '" width="' . $dimensions['width'] . '"
height="' . $dimensions['height'] . '" src="' . $src . '"
frameborder="0" allowfullscreen></iframe>';
$player_title = t('Embedded video');
if (!empty($variables['entity_title'])) {
$player_title .= t(' for @entity_title', array(
'@entity_title' => $variables['entity_title'],
));
}
// Alternative content for browsers that don't understand iframes (WCAG).
$alternative_content = l($player_title, $src);
$attributes = array(
'id' => drupal_html_id($player_class),
'class' => $player_class,
'width' => $dimensions['width'],
'height' => $dimensions['height'],
'src' => $src,
'title' => $player_title,
'frameborder' => "0",
'allowfullscreen' => "",
"allow" => implode('; ', $allow),
);
$output = '<iframe ' . drupal_attributes($attributes) . '>' . $alternative_content . '</iframe>';
if ($size == 'responsive') {
$output = '<div class="youtube-container--responsive">' . $output . '</div>';
......@@ -101,37 +139,42 @@ function theme_youtube_video($variables) {
* Theme function for thumbnails.
*/
function theme_youtube_thumbnail($variables) {
$id = $variables['video_id'];
$video_id = $variables['video_id'];
$style = $variables['image_style'];
// Get YouTube settings - TODO is this needed?
$size = variable_get('youtube_size', '420x315');
$dimensions = youtube_get_dimensions($size);
$files = variable_get('file_public_path', conf_path() . '/files');
$youtube = variable_get('youtube_thumb_dir', 'youtube');
$dest = $files . '/' . $youtube . '/' . $id . '.png';
$uri = youtube_build_thumbnail_uri($video_id);
// Check to see if a thumbnail exists locally.
if (!file_exists($dest)) {
if (!file_exists($uri)) {
// Retrieve the image from YouTube.
if (!youtube_get_remote_image($id)) {
if (!youtube_get_remote_image($video_id)) {
// Use the remote source if local copy fails.
$src = youtube_build_remote_image_path($id);
$src = youtube_build_remote_image_path($video_id);
return theme('image', array('path' => $src));
}
}
$alt = t('Embedded thumbnail');
if (!empty($variables['entity_title'])) {
$alt .= t(' for @entity_title', array(
'@entity_title' => $variables['entity_title'],
));
}
if ($style) {
$uri = 'public://' . $youtube . '/' . $id . '.png';
$image = theme('image_style', array('style_name' => $style, 'path' => $uri));
$image = theme('image_style', array(
'style_name' => $style,
'path' => $uri,
'alt' => $alt,
));
}
else {
$path = $files . '/' . $youtube . '/' . $id . '.png';
$image = theme('image', array('path' => $path));
$image = theme('image', array(
'path' => $uri,
'alt' => $alt
));
}
// Check if an url path is provided
// Check if a URL path is provided.
if ($variables['image_link'] != NULL) {
$url_path = $variables['image_link']['path'];
$options = $variables['image_link']['options'];
......