You are here

brightcove_field.module in Brightcove Video Connect 7.3

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.module
View 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() {
  $path = brightcove_get_experiences_js_url();
  drupal_add_js($path, array(
    'type' => 'external',
    'defer' => false,
    'async' => true,
  ));
}

/**
 * Implementation of hook_menu().
 */
function brightcove_field_menu() {
  $items = array();

  // bc object type, entity type, field name
  $items['brightcove_field/autocomplete/video/%/%'] = array(
    'title' => 'Brightcove field autocomplete',
    'page callback' => 'brightcove_field_autocomplete',
    'page arguments' => array(
      2,
      4,
      6,
    ),
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'browse videos',
      3,
      4,
      5,
    ),
    'file' => 'brightcove_field.browse.inc',
    'type' => MENU_CALLBACK,
  );
  $items['brightcove_field/autocomplete/playlist/%/%'] = array(
    'title' => 'Brightcove field autocomplete',
    'page callback' => 'brightcove_field_autocomplete',
    'page arguments' => array(
      2,
      4,
      6,
    ),
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'browse playlists',
      3,
      4,
      5,
    ),
    'file' => 'brightcove_field.browse.inc',
    'type' => MENU_CALLBACK,
  );

  // bc object type, entity type, field name, entity id or bundle
  $items['brightcove_field/browse/video/%/%'] = array(
    'title' => 'Brightcove Videos Browser',
    'page arguments' => array(
      2,
    ),
    'page callback' => 'brightcove_field_browse',
    'delivery callback' => 'brightcove_field_deliver_dialog',
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'browse videos',
      3,
      4,
      5,
    ),
    'file' => 'brightcove_field.browse.inc',
    'type' => MENU_CALLBACK,
  );

  // bc object type, entity type, field name, entity id or bundle
  $items['brightcove_field/browse/playlist/%/%'] = array(
    'title' => 'Brightcove Videos Browser',
    'page arguments' => array(
      2,
    ),
    'page callback' => 'brightcove_field_browse',
    'delivery callback' => 'brightcove_field_deliver_dialog',
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'browse playlists',
      3,
      4,
      5,
    ),
    'file' => 'brightcove_field.browse.inc',
    'type' => MENU_CALLBACK,
  );

  // entity type, field name, entity id or bundle
  $items['brightcove_field/upload/video/%/%'] = array(
    'title' => 'Upload video to Brightcove',
    'page callback' => 'brightcove_field_upload',
    'delivery callback' => 'brightcove_field_deliver_dialog',
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'upload videos',
      3,
      4,
      5,
    ),
    'file' => 'brightcove_field.browse.inc',
    'type' => MENU_CALLBACK,
  );

  // entity type, field name, entity id or bundle
  $items['brightcove_field/upload/playlist/%/%'] = array(
    'title' => 'Upload playlist to Brightcove',
    'page callback' => 'brightcove_field_create',
    'delivery callback' => 'brightcove_field_deliver_dialog',
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      'administer brightcove playlists',
      3,
      4,
      5,
    ),
    '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 callback' => 'brightcove_field_view_access',
    'access arguments' => array(
      2,
      3,
      4,
    ),
    '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 callback' => 'brightcove_field_view_access',
    'access arguments' => array(
      5,
      6,
      7,
    ),
    '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'];
  $field_name = $form_state['triggering_element']['#parents'][0];
  $entity = $form['#entity'];
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $eid = array_shift(entity_extract_ids($entity_type, $entity));
  $entity_id_or_bundle = !empty($eid) ? $eid : $bundle;
  $title = 'Brightcove Video Browser';
  $id = 'browse-dialog';
  $selector = '<div id="' . $id . '">';
  $path = url("brightcove_field/browse/video/{$entity_type}/{$field_name}/{$entity_id_or_bundle}");
  $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) {
  $field_rel = $form_state['triggering_element']['#attributes']['rel'];
  $field_name = $form_state['triggering_element']['#parents'][0];
  $entity = $form['#entity'];
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $eid = array_shift(entity_extract_ids($entity_type, $entity));
  $entity_id_or_bundle = !empty($eid) ? $eid : $bundle;
  $title = 'Upload Video to Brightcove';
  $id = 'upload-dialog';
  $selector = '<div id="' . $id . '">';
  $path = url("brightcove_field/upload/video/{$entity_type}/{$field_name}/{$entity_id_or_bundle}");
  $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'];
  $field_name = $form_state['triggering_element']['#parents'][0];
  $entity = $form['#entity'];
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $eid = array_shift(entity_extract_ids($entity_type, $entity));
  $entity_id_or_bundle = !empty($eid) ? $eid : $bundle;
  $title = 'Brightcove Playlist Browser';
  $id = 'browse-dialog';
  $selector = '<div id="' . $id . '">';
  $path = url("brightcove_field/browse/playlist/{$entity_type}/{$field_name}/{$entity_id_or_bundle}");
  $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'];
  $field_name = $form_state['triggering_element']['#parents'][0];
  $entity = $form['#entity'];
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $eid = array_shift(entity_extract_ids($entity_type, $entity));
  $entity_id_or_bundle = !empty($eid) ? $eid : $bundle;
  $title = 'Create Playlist to Brightcove';
  $id = 'create-dialog';
  $selector = '<div id="' . $id . '">';
  $path = url("brightcove_field/upload/playlist/{$entity_type}/{$field_name}/{$entity_id_or_bundle}");
  $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($perm, $entity_type, $field_name, $entity_id_or_bundle = NULL) {
  if (user_access($perm)) {
    $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);
  }
  return FALSE;
}

/**
 * Access callback for brightcove view in dialog.
 */
function brightcove_field_view_access($entity_type, $entity_id, $field_name) {
  $field = field_info_field($field_name);
  if (is_numeric($entity_id)) {
    $entity = entity_load($entity_type, array(
      $entity_id,
    ));
    if (count($entity)) {
      $entity = array_shift($entity);
      return entity_access('view', $entity_type, $entity) && field_access('view', $field, $entity_type);
    }
  }
  return FALSE;
}

/**
 * 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');
  $entities = entity_load($entity_type, array(
    $entity_id,
  ));
  $entity = array_shift($entities);

  // Get settings for the proper field instance.
  $field_info = field_info_instance($entity_type, $field_name, $entity->type);
  $width = !empty($field_info['display']['default']['settings']['width']) ? $field_info['display']['default']['settings']['width'] : BRIGHTCOVE_DEFAULT_VIDEO_WIDTH;
  $height = !empty($field_info['display']['default']['settings']['height']) ? $field_info['display']['default']['settings']['height'] : BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT;
  $path = brightcove_get_experiences_js_url();
  drupal_add_js($path, array(
    'type' => 'external',
    'defer' => false,
    'async' => true,
  ));
  $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' => $height,
    'width' => $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' => '',
      'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
      'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
    ),
  );
  $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,
      '#attributes' => array(
        'name' => 'brightcove-image-link',
      ),
    );
    $element['width'] = array(
      '#title' => t('Width'),
      '#type' => 'textfield',
      '#default_value' => $settings['width'],
      '#element_validate' => array(
        'brightcove_field_formatter_width_validate',
      ),
      '#formatter_type' => $display['type'],
      '#states' => array(
        'visible' => array(
          ':input[name="brightcove-image-link"]' => array(
            'value' => 'dialog',
          ),
        ),
      ),
    );
    $element['height'] = array(
      '#title' => t('Height'),
      '#type' => 'textfield',
      '#default_value' => $settings['height'],
      '#element_validate' => array(
        'brightcove_field_formatter_height_validate',
      ),
      '#formatter_type' => $display['type'],
      '#states' => array(
        'visible' => array(
          ':input[name="brightcove-image-link"]' => array(
            'value' => 'dialog',
          ),
        ),
      ),
    );
    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><meta http-equiv="content-type" content="text/html; charset=UTF-8"><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.');
}

Functions

Namesort descending Description
ajax_browse_dialog_close_callback
ajax_browse_playlist_dialog_callback
ajax_browse_video_dialog_callback
ajax_command_close_dialog Creates a Drupal Ajax 'ui_close_dialog' command.
ajax_command_dialog Creates a Drupal Ajax 'ui_dialog' command.
ajax_create_playlist_dialog_callback
ajax_create_playlist_dialog_close_callback
ajax_upload_video_dialog_callback
ajax_upload_video_dialog_close_callback
brightcove_field_admin_paths Implements hook_admin_paths().
brightcove_field_browser_form Browse form. Will return a form for one video item.
brightcove_field_browser_playlist_validate Validate callback for the playlist field.
brightcove_field_browser_process Brightcove field form that returns the actual field to the user. Parts of this and subsequent JS taken from Nodereference Explorer. Thanks!
brightcove_field_browser_video_validate Validate callback for the video field.
brightcove_field_browse_access Access callback for brightcove browser.
brightcove_field_button_value_callback Value callback for the buttons.
brightcove_field_content_migrate_field_alter Implements hook_content_migrate_field_alter().
brightcove_field_content_migrate_instance_alter Implements hook_content_migrate_instance_alter().
brightcove_field_create_form Create form. Will return a form for one playlist item.
brightcove_field_deliver_dialog Custom page delivery callback, for content in dialog.
brightcove_field_element_info Implements hook_element_info().
brightcove_field_field_formatter_info Implementation of hook_formatter_info().
brightcove_field_field_formatter_settings_form Impelements hook_field_formatter_settings_form().
brightcove_field_field_formatter_settings_summary Implements hook_field_formatter_settings_summary().
brightcove_field_field_formatter_view Implements hook_field_formatter_view().
brightcove_field_field_info Implementation of hook_field_info().
brightcove_field_field_insert Implements hook_field_insert().
brightcove_field_field_instance_settings_form Implements hook_field_settings_form().
brightcove_field_field_is_empty Implements hook_field_is_empty().
brightcove_field_field_update IMplements hook_field_update().
brightcove_field_field_validate Implements hook_field_validate().
brightcove_field_field_widget_form Implements hook_field_widget_form().
brightcove_field_field_widget_info Implementation of hook_widget_info().
brightcove_field_filter_form Filter form for video browser.
brightcove_field_filter_form_submit Submit callback for brightcove_field_filter_form().
brightcove_field_filter_info Implements hook_filter_info().
brightcove_field_formatter_height_validate
brightcove_field_formatter_width_validate
brightcove_field_forms Implementation of hook_forms().
brightcove_field_get_value
brightcove_field_image_default_styles Implements hook_image_default_styles().
brightcove_field_init Implements hook_init().
brightcove_field_menu Implementation of hook_menu().
brightcove_field_open_dialog Page callback for 'brightcove_dialog/ajax/%/%/%/%/%/%'.
brightcove_field_player Callback for brightcove_field_player - checks access to the field and prints a player for Lightbox2.
brightcove_field_playlist_browser_value Callback for Brightcove field browser widget. Will return a field value in "playlist-name [id:playlistId]" format.
brightcove_field_refresh_video_entity_link Updates the video entity link on a video.
brightcove_field_theme Implementation of hook_theme().
brightcove_field_upload_form Upload form. Will return a form for one video item.
brightcove_field_video_browser_value Callback for Brightcove field browser widget. Will return a field value in "video-name [id:videoId]" format.
brightcove_field_view_access Access callback for brightcove view in dialog.
theme_brightcove_field_browser Theme function returning a video field.
_brightcove_field_formatter_dimension_validate
_brightcove_field_get_object_formatter_keys Brightcove video metadata properties.
_filter_brightcove Process callback for the brightcove filter.
_filter_brightcove_replace Callback for preg_replace() in _filter_brightcove().
_filter_brightcove_settings Settings callback for the brightcove filter.
_filter_brightcove_tips Tips callback for brightcove filter.

Constants

Namesort descending 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