brightcove_field.module in Brightcove Video Connect 7.4
Same filename and directory in other branches
Brightcove field module provides a Content Construction Kit module to developers, allowing them to browse videos in their Brightcove Studio and upload them.
@author Jakub Suchy <jakub@dynamiteheads.com>, Andrew Burcin <andrew@dynamiteheads.com>
Module development sponsored by Brightcove, Inc.
File
brightcove_field/brightcove_field.moduleView source
<?php
/**
* @file
* Brightcove field module provides a Content Construction Kit module to
* developers, allowing them to browse videos in their Brightcove Studio and
* upload them.
*
* @author
* Jakub Suchy <jakub@dynamiteheads.com>, Andrew Burcin <andrew@dynamiteheads.com>
*
* Module development sponsored by Brightcove, Inc.
*/
define('BRIGHTCOVE_DEFAULT_VIDEO_WIDTH', 425);
define('BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT', 350);
define('BRIGHTCOVE_MINIMUM_VIDEO_WIDTH', 180);
define('BRIGHTCOVE_MINIMUM_VIDEO_HEIGHT', 176);
define('BRIGHTCOVE_VIDEO_WIDGET', 'brightcove_field_video_browser');
define('BRIGHTCOVE_PLAYLIST_WIDGET', 'brightcove_field_playlist_browser');
// Brightcove Economic model options.
// @see http://docs.brightcove.com/en/media/#EconomicsEnum
define('BRIGHTCOVE_ECONOMICS_FREE', 'FREE');
define('BRIGHTCOVE_ECONOMICS_AD_SUPPORTED', 'AD_SUPPORTED');
/**
* Implements hook_init().
*/
function brightcove_field_init() {
// This is required in order to make the filter work.
drupal_add_js('http://admin.brightcove.com/js/BrightcoveExperiences.js');
}
/**
* Implementation of hook_menu().
*/
function brightcove_field_menu() {
$items = array();
// bc object type, entity type, field name
$items['brightcove_field/autocomplete/%/%/%'] = array(
'title' => 'Brightcove field autocomplete',
'page callback' => 'brightcove_field_autocomplete',
'page arguments' => array(
2,
4,
6,
),
'access arguments' => array(
'browse videos',
),
'file' => 'brightcove_field.browse.inc',
'type' => MENU_CALLBACK,
);
// bc object type, entity type, field name, entity id or bundle
$items['brightcove_field/browse/%'] = array(
'title' => 'Brightcove Videos Browser',
'page arguments' => array(
2,
),
'page callback' => 'brightcove_field_browse',
'delivery callback' => 'brightcove_field_deliver_dialog',
'access arguments' => array(
'browse videos',
),
'file' => 'brightcove_field.browse.inc',
'type' => MENU_CALLBACK,
);
// entity type, field name, entity id or bundle
$items['brightcove_field/upload'] = array(
'title' => 'Upload video to Brightcove',
'page arguments' => array(),
'page callback' => 'brightcove_field_upload',
'delivery callback' => 'brightcove_field_deliver_dialog',
'access arguments' => array(
'upload videos',
),
'file' => 'brightcove_field.browse.inc',
'type' => MENU_CALLBACK,
);
// entity type, field name, entity id or bundle
$items['brightcove_field/create'] = array(
'title' => 'Upload video to Brightcove',
'page arguments' => array(),
'page callback' => 'brightcove_field_create',
'delivery callback' => 'brightcove_field_deliver_dialog',
'access arguments' => array(
'browse playlists',
),
'file' => 'brightcove_field.browse.inc',
'type' => MENU_CALLBACK,
);
// entity type, entity id, field name, delta
$items['brightcove_field_player/%/%/%/%/%'] = array(
'title' => 'Brightcove Videos Window Player',
'page callback' => 'brightcove_field_player',
'page arguments' => array(
1,
2,
3,
4,
5,
),
'access arguments' => array(
'browse videos',
),
'delivery callback' => 'brightcove_field_deliver_dialog',
'type' => MENU_CALLBACK,
);
// width, height, entity_type, entity_id, field_name, delta
$items['brightcove_dialog/ajax/%/%/%/%/%/%/%'] = array(
'title' => '',
'page callback' => 'brightcove_field_open_dialog',
'page arguments' => array(
2,
3,
4,
5,
6,
7,
8,
),
'access arguments' => array(
'browse videos',
),
'delivery callback' => 'ajax_deliver',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Page callback for 'brightcove_dialog/ajax/%/%/%/%/%/%'.
*/
function brightcove_field_open_dialog($type, $width, $height, $entity_type, $entity_id, $field_name, $delta) {
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_dialog(t('Watch @type', array(
'@type' => t($type),
)), 'player-dialog', '<div>', url("brightcove_field_player/{$type}/{$entity_type}/{$entity_id}/{$field_name}/{$delta}"), $field_name, array(
'width' => $width,
'height' => $height,
), TRUE),
),
);
}
function ajax_browse_dialog_close_callback($form, $form_state) {
$selector = '#browse-dialog';
$data = check_plain($form_state['values']['title']) . ' [id:' . check_plain($form_state['values']['id']) . ']';
$dialog_type = 'browse';
$commands = array();
$commands[] = ajax_command_close_dialog($selector, $data, NULL, $dialog_type);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_browse_video_dialog_callback($form, $form_state) {
$field_rel = $form_state['triggering_element']['#attributes']['rel'];
$title = 'Brightcove Video Browser';
$id = 'browse-dialog';
$selector = '<div id="' . $id . '">';
$path = url("brightcove_field/browse/video");
$commands = array();
$commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_upload_video_dialog_callback($form, $form_state) {
$et = $form_state['triggering_element']['#attributes']['data-entity-type'];
$bundle = $form_state['triggering_element']['#attributes']['data-bundle'];
$fn = $form_state['triggering_element']['#attributes']['data-field-name'];
$eid = $form_state['triggering_element']['#attributes']['data-entity-id'];
$field_rel = $form_state['triggering_element']['#attributes']['rel'];
$title = 'Upload Video to Brightcove';
$id = 'upload-dialog';
$selector = '<div id="' . $id . '">';
$path = url("brightcove_field/upload");
$commands = array();
$commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_upload_video_dialog_close_callback($form, $form_state) {
$id = _brightcove_upload_form_callback($form, $form_state);
$selector = '#upload-dialog';
$data_title = check_plain($form_state['values']['title']);
$data_id = check_plain($id);
$data = $id ? "{$data_title} [id:{$data_id}]" : '';
$dialog_type = 'upload';
$commands = array();
$commands[] = ajax_command_close_dialog($selector, $data, NULL, $dialog_type);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_browse_playlist_dialog_callback($form, $form_state) {
$field_rel = $form_state['triggering_element']['#attributes']['rel'];
$title = 'Brightcove Playlist Browser';
$id = 'browse-dialog';
$selector = '<div id="' . $id . '">';
$path = url("brightcove_field/browse/playlist");
$commands = array();
$commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_create_playlist_dialog_callback($form, $form_state) {
$field_rel = $form_state['triggering_element']['#attributes']['rel'];
$title = 'Create Playlist to Brightcove';
$id = 'create-dialog';
$selector = '<div id="' . $id . '">';
$path = url("brightcove_field/create");
$commands = array();
$commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function ajax_create_playlist_dialog_close_callback($form, $form_state) {
$id = _brightcove_create_form_callback($form, $form_state);
$selector = '#create-dialog';
$data_title = check_plain($form_state['values']['name']);
$data_id = check_plain($id);
$data = $id ? "{$data_title} [id:{$data_id}]" : '';
$dialog_type = 'create';
$commands = array();
$commands[] = ajax_command_close_dialog($selector, $data, NULL, $dialog_type);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Access callback for brightcove browser.
*/
function brightcove_field_browse_access($entity_type, $field_name, $entity_id_or_bundle = NULL) {
$field = field_info_field($field_name);
if ($entity_id_or_bundle) {
if (is_numeric($entity_id_or_bundle)) {
// entity id is given
$entity = entity_load($entity_type, array(
$entity_id_or_bundle,
));
if (count($entity)) {
$entity = array_shift($entity);
return entity_access('update', $entity_type, $entity) && field_access('edit', $field, $entity_type);
}
}
else {
// bundle is given
$info = entity_get_info($entity_type);
if (!empty($info['bundles'][$entity_id_or_bundle]) && !empty($info['entity keys']['bundle'])) {
$key = $info['entity keys']['bundle'];
$entity = entity_create($entity_type, array(
$key => $entity_id_or_bundle,
));
return entity_access('create', $entity_type, $entity) && field_access('edit', $field, $entity_type);
}
}
}
return entity_access('create', $entity_type) && field_access('edit', $field, $entity_type);
}
/**
* Callback for brightcove_field_player - checks access to the field and prints a player for Lightbox2.
*
* @param $node
* Node object.
* @param $field_name
* Field that is being displayed.
* @param $delta
* Field delta.
*
* @return array
*/
function brightcove_field_player($type, $entity_type, $entity_id, $field_name, $delta) {
module_load_include('inc', 'brightcove_field', 'theme');
drupal_add_js('http://admin.brightcove.com/js/BrightcoveExperiences.js', 'external');
$entities = entity_load($entity_type, array(
$entity_id,
));
$entity = array_shift($entities);
$language = isset($entity->language) ? $entity->language : LANGUAGE_NONE;
$brightcove_id = $entity->{$field_name}[$language][$delta]['brightcove_id'];
$player = $entity->{$field_name}[$language][$delta]['player'];
if (!$player) {
$instance = field_info_instance($entity_type, $field_name, $entity->type);
$player = $instance['settings']['brightcove_player'] ? $instance['settings']['brightcove_player'] : variable_get('brightcove_player_default', '');
}
$variables = array(
'type' => $type == 'playlist' ? 'brightcove-playlist' : 'brightcove',
'brightcove_id' => $brightcove_id,
'params' => array(
'id' => 'brightcove-dialog-player',
),
'player' => $player,
'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
);
return theme('brightcove_field_embed', $variables);
}
/**
* Implements hook_admin_paths().
*/
function brightcove_field_admin_paths() {
if (variable_get('node_admin_theme')) {
$paths = array(
'brightcove_field/upload' => TRUE,
'brightcove_field/browse/*' => TRUE,
);
return $paths;
}
}
/**
* Implementation of hook_field_info().
*/
function brightcove_field_field_info() {
return array(
'brightcove_field' => array(
'label' => t('Brightcove'),
'description' => t('Browse and upload videos or playlists at Brightcove.'),
'settings' => array(),
'instance_settings' => array(
'allow_upload' => FALSE,
'brightcove_player' => '',
'per_content_player' => FALSE,
),
'default_widget' => 'brightcove_field_browser',
'default_formatter' => 'default',
),
);
}
/**
* Implements hook_field_settings_form().
*/
function brightcove_field_field_instance_settings_form($field, $instance) {
$form = array();
switch ($instance['widget']['type']) {
case BRIGHTCOVE_VIDEO_WIDGET:
module_load_include('inc', 'brightcove_field', 'brightcove_field.video');
_brightcove_field_video_instance_settings_form($form, $field, $instance);
break;
case BRIGHTCOVE_PLAYLIST_WIDGET:
module_load_include('inc', 'brightcove_field', 'brightcove_field.playlist');
_brightcove_field_playlist_instance_settings_form($form, $field, $instance);
break;
}
return $form;
}
/**
* Implements hook_field_validate().
*/
function brightcove_field_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
switch ($instance['widget']['type']) {
case BRIGHTCOVE_VIDEO_WIDGET:
foreach ($items as $delta => $item) {
if (!empty($item['brightcove_id'])) {
$video = brightcove_video_load($item['brightcove_id']);
if (empty($video->id) && empty($_SESSION['brightcove']['video'][$item['brightcove_id']])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'brightcove_field',
'message' => t('%name: invalid video.', array(
'%name' => t(isset($field['widget']['label']) ? $field['widget']['label'] : ''),
)),
);
}
}
}
break;
case BRIGHTCOVE_PLAYLIST_WIDGET:
foreach ($items as $delta => $item) {
if (!empty($item['brightcove_id'])) {
$video = brightcove_playlist_load($item['brightcove_id']);
if (empty($video->id) && empty($_SESSION['brightcove']['playlist'][$item['brightcove_id']])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'brightcove_field',
'message' => t('%name: invalid playlist.', array(
'%name' => t(isset($field['widget']['label']) ? $field['widget']['label'] : ''),
)),
);
}
}
}
break;
}
}
/**
* Implements hook_field_is_empty().
*/
function brightcove_field_field_is_empty($item, $field) {
return empty($item['brightcove_id']);
}
/**
* Implementation of hook_formatter_info().
*/
function brightcove_field_field_formatter_info() {
$formatters = array();
$formatters['default'] = array(
'label' => t('Standard video player'),
'field types' => array(
'brightcove_field',
),
'settings' => array(
'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
),
);
$formatters['brightcove_image'] = array(
'label' => t('Brightcove Image'),
'field types' => array(
'brightcove_field',
),
'settings' => array(
'brightcove_image_style' => '',
'brightcove_image_link' => '',
'brightcove_image_type' => '',
),
);
$formatters['brightcove_metadata'] = array(
'label' => t('Brightcove Metadata'),
'field types' => array(
'brightcove_field',
),
'settings' => array(
'brightcove_metadata_type' => 'name',
),
);
return $formatters;
}
/**
* Implements hook_field_formatter_settings_summary().
*
* @param $field
* @param $instance
* @param $view_mode
* @return array|null|string
*/
function brightcove_field_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = '';
if ($display['type'] == 'default') {
$summary = t('Size: @width x @height', array(
'@width' => $settings['width'],
'@height' => $settings['height'],
));
}
if ($display['type'] == 'brightcove_image') {
$image_styles = image_style_options(FALSE);
// Unset possible 'No defined styles' option.
unset($image_styles['']);
if (isset($image_styles[$settings['brightcove_image_style']])) {
$summary = t('Image style: @style', array(
'@style' => $image_styles[$settings['brightcove_image_style']],
));
}
else {
$summary = t('Original image');
}
}
if ($display['type'] == 'brightcove_metadata') {
$metadata_options = _brightcove_field_get_object_formatter_keys();
if (isset($settings['brightcove_metadata_type'])) {
$summary = t('Metadata: @metadata', array(
'@metadata' => $metadata_options[$settings['brightcove_metadata_type']],
));
}
else {
$summary = t('Metadata: @metadata', array(
'@metadata' => reset($metadata_options),
));
}
}
return $summary;
}
/**
* Impelements hook_field_formatter_settings_form().
*
* @param $field
* @param $instance
* @param $view_mode
* @param $form
* @param $form_state
* @return array
*/
function brightcove_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'default') {
$element['width'] = array(
'#title' => t('Width'),
'#type' => 'textfield',
'#default_value' => $settings['width'],
'#required' => TRUE,
'#element_validate' => array(
'brightcove_field_formatter_width_validate',
),
'#formatter_type' => $display['type'],
);
$element['height'] = array(
'#title' => t('Height'),
'#type' => 'textfield',
'#default_value' => $settings['height'],
'#required' => TRUE,
'#element_validate' => array(
'brightcove_field_formatter_height_validate',
),
'#formatter_type' => $display['type'],
);
}
if ($display['type'] == 'brightcove_image') {
$image_styles = image_style_options(FALSE);
$element['brightcove_image_style'] = array(
'#title' => t('Image style'),
'#type' => 'select',
'#default_value' => $settings['brightcove_image_style'],
'#empty_option' => t('None (original image)'),
'#options' => $image_styles,
);
$link_types = array(
'entity' => t('Entity'),
'dialog' => t('Dialog'),
);
$element['brightcove_image_link'] = array(
'#title' => t('Link image to'),
'#type' => 'select',
'#default_value' => $settings['brightcove_image_link'],
'#empty_option' => t('Nothing'),
'#options' => $link_types,
);
if ($instance['widget']['type'] == BRIGHTCOVE_VIDEO_WIDGET) {
$image_types = array(
'thumbnailURL' => t('thumbnailURL'),
'videoStillURL' => t('videoStillURL'),
);
$element['brightcove_image_type'] = array(
'#title' => t('Image type'),
'#type' => 'select',
'#default_value' => $settings['brightcove_image_type'],
'#empty_option' => $image_types[0],
'#options' => $image_types,
);
}
else {
$element['brightcove_image_type'] = array(
'#type' => 'value',
'#value' => 'thumbnailURL',
);
}
}
if ($display['type'] == 'brightcove_metadata') {
$type = $instance['widget']['type'] == BRIGHTCOVE_VIDEO_WIDGET ? 'video' : 'playlist';
$metadata_options = _brightcove_field_get_object_formatter_keys($type);
$element['brightcove_metadata_type'] = array(
'#title' => t('Image type'),
'#type' => 'select',
'#default_value' => $settings['brightcove_metadata_type'],
'#options' => $metadata_options,
);
}
return $element;
}
function _brightcove_field_formatter_dimension_validate($value, $element, $error_msg) {
if (!is_numeric($element['#value']) || (int) $element['#value'] < $value) {
form_error($element, $error_msg);
}
}
function brightcove_field_formatter_width_validate($element) {
$minwidth = BRIGHTCOVE_MINIMUM_VIDEO_WIDTH;
$errormsg = t('The video width must be a number, greater than %num', array(
'%num' => $minwidth,
));
_brightcove_field_formatter_dimension_validate($minwidth, $element, $errormsg);
}
function brightcove_field_formatter_height_validate($element) {
$minheight = BRIGHTCOVE_MINIMUM_VIDEO_HEIGHT;
$errormsg = t('The video height must be a number, greater than %num', array(
'%num' => $minheight,
));
_brightcove_field_formatter_dimension_validate($minheight, $element, $errormsg);
}
/**
* Implementation of hook_widget_info().
*/
function brightcove_field_field_widget_info() {
return array(
BRIGHTCOVE_VIDEO_WIDGET => array(
'label' => t('Video (upload/browse)'),
'field types' => array(
'brightcove_field',
),
'behaviors' => array(
'default value' => FIELD_BEHAVIOR_NONE,
),
),
BRIGHTCOVE_PLAYLIST_WIDGET => array(
'label' => t('Playlist (create/browse)'),
'field types' => array(
'brightcove_field',
),
'behaviors' => array(
'default value' => FIELD_BEHAVIOR_NONE,
),
),
);
}
/**
* Implements hook_element_info().
*/
function brightcove_field_element_info() {
$elements = array(
'brightcove_field_browser' => array(
'#input' => TRUE,
'#columns' => array(
'brightcove_id',
),
'#delta' => 0,
'#process' => array(
'brightcove_field_browser_process',
),
'#autocomplete_path' => FALSE,
),
'brightcove_field_browse_button' => array(
'#input' => FALSE,
),
);
return $elements;
}
/**
* Brightcove field form that returns the actual field to the user.
* Parts of this and subsequent JS taken from Nodereference Explorer. Thanks!
*/
function brightcove_field_browser_process($element, $form_state, $form) {
$field_key = $element['#columns'][0];
$entity_type = $form['#entity_type'];
$entity_info = entity_get_info($entity_type);
$eid = $form[$entity_info['entity keys']['id']]['#value'];
$field_info = field_info_field($element['#field_name']);
$element[$field_key] = array(
'#type' => 'textfield',
'#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : '',
'#autocomplete_path' => 'brightcove_field/autocomplete/' . $element['#field_name'] . '/' . $element['#entity_type'] . '/' . $eid,
// The following values were set by the content module and need
// to be passed down to the nested element.
'#title' => $element['#title'],
'#required' => $element['#required'],
'#description' => $element['#description'],
'#field_name' => $element['#field_name'],
'#delta' => $element['#delta'],
'#columns' => $element['#columns'],
'#attributes' => array(
'rel' => $element['#field_name'],
'class' => array(
'brightcove-video-field',
),
),
);
if (user_access('browse videos')) {
// Button to browse videos.
$element['actions']['browse'] = array(
'#type' => 'brightcove_field_browse_button',
'#id' => $element['#id'] . '-browse',
'#attributes' => array(
'class' => array(
'brightcove-field-browse-button',
),
'rel' => $element['#id'] . '-video-id',
),
'#value' => t('Browse'),
);
}
if (user_access('upload videos') && $field_info['settings']['allow_upload']) {
$element['actions']['upload'] = array(
'#type' => 'brightcove_field_browse_button',
'#id' => $element['#id'] . '-upload',
'#attributes' => array(
'class' => array(
'brightcove-field-upload-button',
),
'rel' => $element['#id'] . '-video-id',
),
'#value' => t('Upload'),
);
}
$element['actions']['remove'] = array(
'#type' => 'brightcove_field_browse_button',
'#id' => $element['#id'] . '-remove',
'#attributes' => array(
'class' => array(
'brightcove-field-remove-button',
),
'rel' => $element['#id'] . '-video-id',
),
'#value' => t('Remove'),
);
if (!isset($element['#default_value'][$field_key])) {
$element['actions']['remove']['#attributes']['disabled'] = 'disabled';
}
if (empty($brightcove_field_settings[$element['#field_name']])) {
$brightcove_field_settings[$element['#field_name']] = array(
'brightcove_field' => array(
$element['#field_name'] => array(
'entity_type' => $entity_type,
'field_name' => $element['#field_name'],
'entity_id' => $eid,
),
),
);
drupal_add_js($brightcove_field_settings[$element['#field_name']], array(
'type' => 'setting',
));
}
if (empty($element[$field_key]['#element_validate'])) {
$element[$field_key]['#element_validate'] = array();
}
array_unshift($element[$field_key]['#element_validate'], 'brightcove_field_browser_video_validate');
return $element;
}
/**
* Value callback for the buttons.
*
* @return null
*/
function brightcove_field_button_value_callback() {
return NULL;
}
/**
* Implements hook_field_widget_form().
*/
function brightcove_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
if ($instance['widget']['type'] == BRIGHTCOVE_VIDEO_WIDGET) {
module_load_include('inc', 'brightcove_field', 'brightcove_field.video');
_brightcove_field_video_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
}
elseif ($instance['widget']['type'] == BRIGHTCOVE_PLAYLIST_WIDGET) {
module_load_include('inc', 'brightcove_field', 'brightcove_field.playlist');
_brightcove_field_playlist_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
}
return $element;
}
/**
* Callback for Brightcove field browser widget.
* Will return a field value in "video-name [id:videoId]" format.
*
*/
function brightcove_field_video_browser_value($element, $value, $form_state) {
if (!$value && !$form_state['input']) {
$value = $element['#default_value'];
}
if ((int) $value > 1) {
$video = brightcove_video_load($value);
if (!empty($video->id)) {
$value = check_plain($video->name) . " [id:{$video->id}]";
}
}
return $value;
}
/**
* Callback for Brightcove field browser widget.
* Will return a field value in "playlist-name [id:playlistId]" format.
*
*/
function brightcove_field_playlist_browser_value($element, $value, $form_state) {
if (!$value && !$form_state['input']) {
$value = $element['#default_value'];
}
if ((int) $value > 1) {
$playlist = brightcove_playlist_load($value);
if (!empty($playlist->id)) {
$value = check_plain($playlist->name) . " [id:{$playlist->id}]";
}
}
return $value;
}
/**
* Validate callback for the video field.
*/
function brightcove_field_browser_video_validate($element, &$form_state) {
$id = '';
$value = $element['#value'];
if (!empty($value)) {
// Assign ID to the value.
// 231289 [id:72431493001]
$id = brightcove_parse_id($value);
if (is_numeric($id)) {
// Matched ID, check if the video exists.
$video = brightcove_video_load($id);
// Check value in session variable for newly uploaded video.
if (empty($video) && empty($_SESSION['brightcove']['video'][$id])) {
form_error($element, t('%name: Found no valid video with that name. Please note that it might take several minutes after the video has been uploaded in Brightcove Studio to appear in the API.', array(
'%name' => t($element['#title']),
)));
}
}
else {
// Didn't match ID, try looking up the video text at BC.
$bc = brightcove_initialize();
$result = NULL;
try {
$result = $bc
->search('video', array(
'all' => 'display_name:' . $value,
), array(
'sort_by' => 'CREATION_DATE',
'sort_order' => 'DESC',
));
} catch (Exception $error) {
form_error($element, t('There was a problem accessing Brightcove. Please try again'));
watchdog('brightcove', 'Validating element with Brightcove failed', array(), WATCHDOG_ERROR);
}
if (count($result) > 1) {
// This title is ambiguous.
form_error($element, t('%name: Video title %title matched more than one video. In case of doubt, use text "title [id:ID_OF_THE_VIDEO]"', array(
'%title',
$value,
'%name' => t($element['#title']),
)));
}
elseif (count($result) == 0) {
// No video found.
form_error($element, t('%name: Found no valid video with that name. Please note that it might take several minutes after the video has been uploaded in Brightcove Studio to appear in the API.', array(
'%name' => t($element['#title']),
)));
}
else {
$id = $result[0]->id;
}
}
}
form_set_value($element, $id, $form_state);
}
/**
* Validate callback for the playlist field.
*/
function brightcove_field_browser_playlist_validate($element, &$form_state) {
$id = '';
$value = $element['#value'];
if (!empty($value)) {
// Assign ID to the value.
// 231289 [id:72431493001]
$id = brightcove_parse_id($value);
if (is_numeric($id)) {
// Matched ID, check if the video exists.
$playlist = brightcove_playlist_load($id);
if (empty($playlist) && empty($_SESSION['brightcove']['playlist'][$id])) {
form_error($element, t('%name: Found no valid playlist with that name.', array(
'%name' => t($element['#title']),
)));
}
}
else {
$result = brightcove_field_get_matched_playlists($value);
if (count($result) > 1) {
// This title is ambiguous.
form_error($element, t('%name: Playlist title %title matched more than one plalists. In case of doubt, use text "title [id:ID_OF_THE_PLAYLIST]"', array(
'%title',
$value,
'%name' => t($element['#title']),
)));
}
elseif (count($result) == 0) {
// No video found.
form_error($element, t('%name: Found no valid playlist with that name.', array(
'%name' => t($element['#title']),
)));
}
else {
$id = $result[0]->id;
}
}
}
form_set_value($element, $id, $form_state);
}
/**
* Theme function returning a video field.
*/
function theme_brightcove_field_browser($element) {
return $element['#children'];
}
/**
* Implementation of hook_theme().
*
* @param $existing
* @param $type
* @param $theme
* @param $path
* @return array
*/
function brightcove_field_theme($existing, $type, $theme, $path) {
$theme = array(
// Brightcove image field formatter theme function.
'brightcove_field_image' => array(
'render element' => 'elements',
'file' => 'brightcove_field.formatters.inc',
),
// Brightcove metadata formatter theme function.
'brightcove_field_metadata' => array(
'render element' => 'elements',
'file' => 'brightcove_field.formatters.inc',
),
// The media browser form theme function.
'brightcove_field_browser' => array(
'variables' => array(
'element' => NULL,
),
),
// The default formatter of the brightcove field.
'brightcove_field_formatter_default' => array(
'variables' => array(
'type' => 'brightcove',
'element' => NULL,
'instance' => array(),
'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
),
'file' => 'brightcove_field.formatters.inc',
),
'brightcove_field_dialog' => array(
'variables' => array(
'output' => NULL,
'video_id' => NULL,
'video_width' => NULL,
'video_height' => NULL,
'dialog_width' => NULL,
'dialog_height' => NULL,
'destination' => NULL,
'image_field' => NULL,
'field_name' => NULL,
'entity_type' => NULL,
'style' => NULL,
),
'template' => 'brightcove-field-dialog',
'pattern' => 'brightcove_field_dialog__',
),
'brightcove_field_browse_button' => array(
'variables' => array(
'element' => NULL,
),
'function' => 'theme_brightcove_field_browse_button',
'file' => 'theme.inc',
),
'brightcove_field_browse_item' => array(
'variables' => array(
'item' => NULL,
),
'file' => 'theme.inc',
),
'brightcove_field_browse_items' => array(
'variables' => array(
'item' => NULL,
),
'file' => 'theme.inc',
),
'brightcove_field_embed' => array(
'variables' => array(
'type' => 'brightcove',
'player' => NULL,
'brightcove_id' => NULL,
'params' => array(),
'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
),
'template' => 'brightcove-field-player',
'file' => 'theme.inc',
),
);
return $theme;
}
/**
* Filter form for video browser.
*/
function brightcove_field_filter_form($form, &$form_state) {
$form['search'] = array(
'#type' => 'fieldset',
'#title' => t('Filter videos'),
'#collapsible' => TRUE,
'#collapsed' => empty($_SESSION['brightcove_field_filter']) ? TRUE : FALSE,
);
$keywords = '';
if (!empty($_SESSION['brightcove_field_filter']['keywords'])) {
$keywords = $_SESSION['brightcove_field_filter']['keywords'];
}
$form['search']['keywords'] = array(
'#type' => 'textfield',
'#title' => t('Keywords'),
'#size' => 25,
'#default_value' => $keywords,
'#description' => t('Comma separated keywords to search for.'),
);
$form['search']['search'] = array(
'#type' => 'radios',
'#title' => t('Search in'),
'#options' => array(
'name' => t('Names and descriptions'),
'tags' => t('Tags: at least one of these'),
'and_tags' => t('Tags: all of these'),
),
'#default_value' => isset($_SESSION['brightcove_field_filter']['search']) ? $_SESSION['brightcove_field_filter']['search'] : 'name',
'#attributes' => array(
'class' => array(
'search-radio',
),
),
'#description' => t('"Names and descriptions" searches in Video name, short and long descriptions. Tags searches in Video associated tags.'),
);
$form['search']['submit'] = array(
'#type' => 'submit',
'#name' => 'submit',
'#default_value' => t('Filter'),
);
$form['search']['reset'] = array(
'#type' => 'submit',
'#name' => 'reset',
'#default_value' => t('Reset'),
);
$form['#submit'] = array(
'brightcove_field_filter_form_submit',
);
return $form;
}
/**
* Submit callback for brightcove_field_filter_form().
*
* Set session variables based on selection.
*
* @see brightcove_field_browse().
*/
function brightcove_field_filter_form_submit($form, &$form_state) {
$keywords = $form_state['values']['keywords'];
$search = $form_state['values']['search'];
// Reset the form if keywords are empty or reset button was clicked.
if (empty($keywords) || $form_state['clicked_button']['#name'] == 'reset') {
unset($_SESSION['brightcove_field_filter']);
return;
}
// The only thing we do is set session variables based on the selection.
// Browse callback will take care of the rest.
$_SESSION['brightcove_field_filter']['keywords'] = $keywords;
$_SESSION['brightcove_field_filter']['search'] = $search;
}
/**
* Browse form. Will return a form for one video item.
*
* @see brightcove_field_forms().
*/
function brightcove_field_browser_form($form, &$form_state, $item) {
$form['id'] = array(
'#type' => 'value',
'#default_value' => $item['brightcove_id'],
);
$form['title'] = array(
'#type' => 'value',
'#default_value' => $item['title'],
);
$form['text_title'] = array(
'#prefix' => '<div class="brightcove-title">',
'#suffix' => '</div>',
'#markup' => $item['title'],
);
$form['text_image'] = array(
'#prefix' => '<div class="brightcove-image">',
'#suffix' => '</div>',
'#markup' => $item['thumbnail'],
);
$form['submit'] = array(
'#type' => 'submit',
'#name' => 'submit-' . $item['brightcove_id'],
'#default_value' => t('Attach'),
'#ajax' => array(
'callback' => 'ajax_browse_dialog_close_callback',
),
);
return $form;
}
/**
* Implementation of hook_forms().
*
* Needed to help Drupal determine which form to render - every video item in
* the browser is a separate form.
*/
function brightcove_field_forms($form_id, $args) {
$forms = array();
if (strpos($form_id, "brightcove_field_browser_form") === 0) {
$forms[$form_id] = array(
'callback' => 'brightcove_field_browser_form',
);
}
return $forms;
}
/**
* Upload form. Will return a form for one video item.
*/
function brightcove_field_upload_form($form, $form_state) {
$form = _brightcove_upload_form($form, $form_state);
$form['#prefix'] = '<div id="dialog-upload-form">';
$form['submit'] = array(
'#type' => 'submit',
'#name' => 'submit-',
'#default_value' => t('Attach'),
'#ajax' => array(
'callback' => 'ajax_upload_video_dialog_close_callback',
'wrapper' => 'dialog-upload-form',
),
);
$form['#suffix'] = '</div>';
$form['#attached']['js'] = array(
drupal_get_path('module', 'brightcove_field') . '/js/brightcove.js',
);
$form['#attached']['css'] = array(
drupal_get_path('module', 'brightcove_field') . '/styles/upload.css',
);
return $form;
}
/**
* Create form. Will return a form for one playlist item.
*/
function brightcove_field_create_form($form, &$form_state) {
module_load_include('inc', 'brightcove', 'brightcove.playlist');
_brightcove_playlist_form($form, $form_state);
$form['#prefix'] = '<div id="dialog-create-form">';
$form['submit'] = array(
'#type' => 'submit',
'#name' => 'submit-',
'#default_value' => t('Create'),
'#ajax' => array(
'callback' => 'ajax_create_playlist_dialog_close_callback',
'wrapper' => 'dialog-create-form',
),
);
$form['#suffix'] = '</div>';
$form['#attached']['js'] = array(
drupal_get_path('module', 'brightcove_field') . '/js/brightcove.js',
);
$form['#attached']['css'] = array(
drupal_get_path('module', 'brightcove_field') . '/styles/upload.css',
);
return $form;
}
/**
* Implements hook_content_migrate_field_alter().
*/
function brightcove_field_content_migrate_field_alter(&$field_value, $instance_value) {
switch ($field_value['type']) {
case 'brightcove_field':
$field_value['module'] = 'brightcove_field';
break;
}
}
/**
* Implements hook_content_migrate_instance_alter().
*/
function brightcove_field_content_migrate_instance_alter(&$instance_value, $field_value) {
switch ($field_value['type']) {
case 'brightcove_field':
$instance_value['settings']['allow_upload'] = $field_value['settings']['allow_upload'];
if ($instance_value['widget']['module'] == 'brightcove_cck') {
$instance_value['widget']['module'] = 'brightcove_field';
if (strpos($instance_value['widget']['type'], 'brightcove_cck') !== FALSE) {
$instance_value['widget']['type'] = str_replace('brightcove_cck', 'brightcove_field', $instance_value['widget']['type']);
}
}
break;
}
}
/**
* Implements hook_image_default_styles().
*/
function brightcove_field_image_default_styles() {
$styles = array();
$styles['brightcove_browser'] = array(
'effects' => array(
array(
'name' => 'image_scale_and_crop',
'data' => array(
'width' => 120,
'height' => 120,
),
'weight' => 0,
),
),
);
return $styles;
}
/**
* Implements hook_field_formatter_view().
*
* @param $entity_type
* @param $entity
* @param $field
* @param $instance
* @param $langcode
* @param $items
* @param $display
* @return array
*/
function brightcove_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$theme = NULL;
$variables = array();
$settings = $display['settings'];
$variables['#brightcove_widget_type'] = $instance['widget']['type'];
if ($display['type'] == 'default') {
$theme = 'brightcove_field_formatter_default';
}
if ($display['type'] == 'brightcove_image') {
$theme = 'brightcove_field_image';
$variables['#brightcove_image_style'] = $settings['brightcove_image_style'];
$variables['#brightcove_image_link'] = $settings['brightcove_image_link'];
$variables['#brightcove_image_type'] = $settings['brightcove_image_type'];
}
if ($display['type'] == 'brightcove_metadata') {
$metadata_options = _brightcove_field_get_object_formatter_keys();
$theme = 'brightcove_field_metadata';
$variables['#key'] = $settings['brightcove_metadata_type'];
$variables['#label'] = $metadata_options[$settings['brightcove_metadata_type']];
}
if (isset($settings['brightcove_image_link']) && $settings['brightcove_image_link'] == 'dialog') {
$variables['#attached']['library'][] = array(
'system',
'drupal.ajax',
);
$variables['#attached']['library'][] = array(
'system',
'ui.dialog',
);
$variables['#attached']['js'][] = drupal_get_path('module', 'brightcove_field') . '/js/brightcove.js';
$variables['#attached']['css'][] = drupal_get_path('module', 'brightcove_field') . '/styles/brightcove.css';
}
if ($theme) {
switch ($instance['widget']['type']) {
case BRIGHTCOVE_VIDEO_WIDGET:
foreach ($items as $delta => $item) {
$video = FALSE;
if (isset($item['brightcove_id'])) {
$video = brightcove_video_load($item['brightcove_id']);
}
$element[$delta] = array(
'#theme' => $theme,
'#type' => 'brightcove',
'#element' => $item,
'#delta' => $delta,
'#entity_type' => $entity_type,
'#entity' => $entity,
'#field' => $field,
'#instance' => $instance,
'#display' => $display,
'#video' => $video,
'#width' => isset($settings['width']) ? $settings['width'] : NULL,
'#height' => isset($settings['height']) ? $settings['height'] : NULL,
) + $variables;
}
break;
case BRIGHTCOVE_PLAYLIST_WIDGET:
foreach ($items as $delta => $item) {
$playlist = FALSE;
if (isset($item['brightcove_id'])) {
$playlist = brightcove_playlist_load($item['brightcove_id']);
}
$element[$delta] = array(
'#theme' => $theme,
'#type' => 'brightcove-player',
'#element' => $item,
'#delta' => $delta,
'#entity_type' => $entity_type,
'#entity' => $entity,
'#field' => $field,
'#instance' => $instance,
'#display' => $display,
'#playlist' => $playlist,
'#width' => isset($settings['width']) ? $settings['width'] : NULL,
'#height' => isset($settings['height']) ? $settings['height'] : NULL,
) + $variables;
}
break;
}
}
return $element;
}
/**
* Creates a Drupal Ajax 'ui_dialog' command.
*
* The 'ui_dialog' command instructs the client to display a jQuery UI
* Dialog box.
*
* This command is implemented by Drupal.ajax.prototype.commands.ui()
* defined in brightcove/brightcove_field/brightcove.js.
*
* @param $title
* Optional. String, title of dialog.
* @param $id
* Optional. Additional id to put on dialog.
* @param $selector
* Selector of the element that should be made into a dialog.
* @param $data
* Path if $iframe is TRUE.
* Html if $iframe is FALSE.
* @param $field_rel
* Rel attribute of the corresponding field.
* @param $settings
* TODO
* @param $iframe
* Optional. Boolean, if the dialog should contain an iframe or other html content
*
* @return
* An array suitable for use with the ajax_render() function.
*/
function ajax_command_dialog($title = 'Dialog', $id = NULL, $selector = '<div>', $data, $field_rel, $settings = NULL, $iframe = FALSE) {
return array(
'command' => 'ui_dialog',
'title' => $title,
'id' => $id,
'selector' => $selector,
'data' => $data,
'field_rel' => $field_rel,
'settings' => $settings,
'iframe' => $iframe,
);
}
/**
* Creates a Drupal Ajax 'ui_close_dialog' command.
*
* The 'dialog' command instructs the client to close a jQuery UI
* Dialog box.
*
* This command is implemented by Drupal.ajax.prototype.commands.ui()
* defined in brightcove/brightcove_field/brightcove.js.
*
* @param $selector
* Selector of the dialog that should be closed.
* @param $data
* Data to send on close, depends on dialog type.
* @param $settings
* TODO
* @param $dialog_type
* Type of dialog to close.
*
* @return
* An array suitable for use with the ajax_render() function.
*/
function ajax_command_close_dialog($selector = '<div>', $data, $settings = NULL, $dialog_type) {
return array(
'command' => 'ui_dialog_close',
'selector' => $selector,
'data' => $data,
'settings' => $settings,
'dialog_type' => $dialog_type,
);
}
/**
* Custom page delivery callback, for content in dialog.
*
* @param $page
* Content returned by page callback.
* @print
* Html for display.
*/
function brightcove_field_deliver_dialog($page) {
if (is_array($page)) {
$page = drupal_render($page);
}
$output = '<html><head><title></title>' . drupal_get_css() . drupal_get_js() . '</head><body class="dialog">' . $page . '</body></html>';
print $output;
}
/**
* Brightcove video metadata properties.
*
* @return array
*/
function _brightcove_field_get_object_formatter_keys($type = 'video') {
switch ($type) {
case 'video':
return array(
'name' => t('Name'),
'shortDescription' => t('Short description'),
'longDescription' => t('Long description'),
'creationDate' => t('Creation date'),
'publishedDate' => t('Published date'),
'lastModifiedDate' => t('Last modified date'),
'length' => t('Length'),
'playsTotal' => t('Total plays'),
'playsTrailingWeek' => t('Trailing week plays'),
);
case 'playlist':
return array(
'name' => t('Name'),
'shortDescription' => t('Short description'),
);
}
}
/**
* Updates the video entity link on a video.
*
* @param $entity_type
* Type of the entity to reference.
* @param $entity
* The entity to reference.
* @param $items
* The $items array of hook_field_insert() and hook_field_update().
* Example:
* array(
* array('video_id' => 0),
* array('video_id' => 1),
* array('video_id' => 2),
* )
*/
function brightcove_field_refresh_video_entity_link($entity_type, $entity, $items) {
if ($entity_link_field = variable_get('brightcove_link_field')) {
if ($entity_link = entity_uri($entity_type, $entity)) {
$absolute_entity_link = url($entity_link['path'], array(
'absolute' => TRUE,
) + $entity_link['options']);
$bc = brightcove_initialize();
$video_ids = array();
foreach ($items as $item) {
$video_ids[] = $item['brightcove_id'];
}
if ($video_ids) {
$videos = $bc
->find('videosbyids', array(
'video_ids' => implode(',', $video_ids),
'video_fields' => 'id,customFields',
));
foreach ($videos as $video) {
if (!isset($video->customFields)) {
$video->customFields = new stdClass();
}
$video->customFields->{$entity_link_field} = $absolute_entity_link;
$bc
->update('video', $video);
}
}
}
}
}
/**
* Implements hook_field_insert().
*/
function brightcove_field_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
brightcove_field_refresh_video_entity_link($entity_type, $entity, $items);
}
/**
* IMplements hook_field_update().
*/
function brightcove_field_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
brightcove_field_refresh_video_entity_link($entity_type, $entity, $items);
}
function brightcove_field_get_value($instance, $stored) {
if ($stored) {
return $stored;
}
if (!empty($instance['settings']['brightcove_player'])) {
return $instance['settings']['brightcove_player'];
}
elseif ($pid = variable_get('brightcove_player_default')) {
return $pid;
}
return NULL;
}
/**
* Implements hook_filter_info().
*/
function brightcove_field_filter_info() {
$filters = array();
$filters['filter_brightcove'] = array(
'title' => t('Brightcove filter'),
'process callback' => '_filter_brightcove',
'settings callback' => '_filter_brightcove_settings',
'default settings' => array(
'player' => variable_get('brightcove_player_default'),
),
'tips callback' => '_filter_brightcove_tips',
);
return $filters;
}
/**
* Settings callback for the brightcove filter.
*/
function _filter_brightcove_settings($form, &$form_state, $filter, $format, $defaults) {
$filter->settings += $defaults;
$settings = array();
$settings['player'] = array(
'#type' => 'radios',
'#title' => t('Player'),
'#options' => brightcove_player_list(),
'#default_value' => $filter->settings['player'],
);
return $settings;
}
/**
* Process callback for the brightcove filter.
*
* @TODO: refactor this function to use a closure when we can use PHP 5.3 (D8?)
*/
function _filter_brightcove($text, $filter) {
$current_filter =& drupal_static(__FUNCTION__);
$current_filter = $filter;
return preg_replace_callback('#\\[brightcove:([\\d]+)\\]#', '_filter_brightcove_replace', $text);
}
/**
* Callback for preg_replace() in _filter_brightcove().
*
* @TODO: make this function a closure.
*/
function _filter_brightcove_replace($videoid) {
$filter =& drupal_static('_filter_brightcove');
return theme('brightcove_field_embed', array(
'player' => $filter && $filter->settings['player'] ? $filter->settings['player'] : variable_get('brightcove_player_default'),
'video_id' => $videoid[1],
));
}
/**
* Tips callback for brightcove filter.
*
* @TODO: improve documentation.
*/
function _filter_brightcove_tips($filter, $format, $long = FALSE) {
return t('To embed a brightcove video use the [brightcove:VIDEOID] syntax, ' . 'where VIDEOID is the ID of the brightcove video what you want to embed.');
}
/**
* Helper function to prepare parameters to entity_access() function.
*
* @param $op
* The operation being performed. One of 'view', 'update', 'create' or
* 'delete'.
* @param $entity_type
* The entity type of the entity to check for.
* @param $entity_id
* Optionally an id belonging to the checked entity.
* @param $account
* The user to check for. Leave it to NULL to check for the global user.
*
* @return boolean
* Whether access is allowed or not. If the entity type does not specify any
* access information, NULL is returned.
*
* @see brightcove_field_menu()
* @see entity_access()
*/
function brightcove_field_entity_access($op, $entity_type, $entity_id = NULL, $account = NULL) {
$entity = entity_load($entity_type, array(
$entity_id,
));
$entity = reset($entity);
return entity_access($op, $entity_type, $entity, $account);
}
Functions
Constants
Name | Description |
---|---|
BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT | |
BRIGHTCOVE_DEFAULT_VIDEO_WIDTH | @file Brightcove field module provides a Content Construction Kit module to developers, allowing them to browse videos in their Brightcove Studio and upload them. |
BRIGHTCOVE_ECONOMICS_AD_SUPPORTED | |
BRIGHTCOVE_ECONOMICS_FREE | |
BRIGHTCOVE_MINIMUM_VIDEO_HEIGHT | |
BRIGHTCOVE_MINIMUM_VIDEO_WIDTH | |
BRIGHTCOVE_PLAYLIST_WIDGET | |
BRIGHTCOVE_VIDEO_WIDGET |