You are here

brightcove_field.module in Brightcove Video Connect 7.2

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);

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

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

  // entity type, field name, entity id or bundle
  $items['brightcove_field/browse/%/%/%'] = array(
    'title' => 'Brightcove Videos Browser',
    'page arguments' => array(),
    'page callback' => 'brightcove_field_browse',
    'delivery callback' => 'brightcove_field_deliver_dialog',
    'access callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      2,
      3,
      4,
    ),
    '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 callback' => 'brightcove_field_browse_access',
    'access arguments' => array(
      2,
      3,
      4,
    ),
    '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,
    ),
    'access callback' => 'entity_access',
    'access arguments' => array(
      'view',
      1,
      2,
    ),
    '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,
    ),
    'access callback' => 'entity_access',
    'access arguments' => array(
      'view',
      4,
      5,
    ),
    'delivery callback' => 'ajax_deliver',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Page callback for 'brightcove_dialog/ajax/%/%/%/%/%/%'.
 */
function brightcove_field_open_dialog($width, $height, $entity_type, $entity_id, $field_name, $delta) {
  return array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_dialog(t('Watch video'), 'player-dialog', '<div>', url("brightcove_field_player/{$entity_type}/{$entity_id}/{$field_name}/{$delta}"), $field_name, array(
        'width' => $width,
        'height' => $height,
      ), TRUE),
    ),
  );
}

/**
 * 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
      return entity_access('create', $entity_type, $entity_id_or_bundle) && 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($entity_type, $entity_id, $field_name, $delta) {
  $entities = entity_load($entity_type, array(
    $entity_id,
  ));
  $entity = array_shift($entities);
  $video_id = $entity->{$field_name}[isset($entity->language) ? $entity->language : 'und'][$delta]['video_id'];
  $player_name = $entity->{$field_name}[isset($entity->language) ? $entity->language : 'und'][$delta]['player_id'];
  list(, , $bundle) = entity_extract_ids($entity_type, $entity);
  $instance = field_info_instance($entity_type, $field_name, $bundle);
  return array(
    '#theme' => 'brightcove_field_embed',
    '#video_id' => $video_id,
    '#attached' => array(
      'js' => array(
        'http://admin.brightcove.com/js/BrightcoveExperiences.js',
      ),
    ),
    '#player' => brightcove_field_get_value($instance, $player_name),
  );
}

/**
 * Implementation of hook_field_info().
 */
function brightcove_field_field_info() {
  return array(
    'brightcove_video' => array(
      'label' => t('Brightcove Video'),
      'description' => t('Browse and upload videos 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();

  // Only allow Upload if this site has Write API keys.
  if (brightcove_write_api_access()) {
    $form['allow_upload'] = array(
      '#type' => 'checkbox',
      '#title' => t('Allow upload'),
      '#description' => t('Whether to allow uploading new videos to ' . 'Brightcove Studio from this field. ' . 'Requires Write API keys with at least a ' . '!link-to-editions-and-pricing', array(
        '!link-to-editions-and-pricing' => l(t('Professional account'), 'http://www.brightcove.com/en/video-platform/editions-and-pricing'),
      )),
      '#default_value' => $instance['settings']['allow_upload'],
    );
  }
  else {
    $form['allow_upload'] = array(
      '#type' => 'value',
      '#value' => $instance['settings']['allow_upload'],
    );
  }
  $form['brightcove_player'] = array(
    '#type' => 'select',
    '#title' => t('Brightcove Player'),
    '#default_value' => isset($instance['settings']['brightcove_player']) ? $instance['settings']['brightcove_player'] : NULL,
    '#options' => brightcove_player_list(),
    '#description' => t('Leave empty if you don\'t want to override the global settings.'),
  );
  $form['per_content_player'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow setting player per content'),
    '#default_value' => isset($instance['settings']['per_content_player']) ? $instance['settings']['per_content_player'] : NULL,
  );
  return $form;
}

/**
 * Implements hook_field_validate().
 */
function brightcove_field_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  foreach ($items as $delta => $item) {
    if (!empty($item['video_id'])) {
      $video = brightcove_video_load($item['video_id']);
      if (empty($video->id)) {
        if (brightcove_video_cache_get($item['video_id']) === NULL) {
          $errors[$field['field_name']][$langcode][$delta][] = array(
            'error' => 'brightcove_field',
            'message' => t('%name: invalid video.', array(
              '%name' => t($field['widget']['label']),
            )),
          );
        }
      }
    }
  }
}

/**
 * Implements hook_field_is_empty().
 */
function brightcove_field_field_is_empty($item, $field) {
  return empty($item['video_id']);
}

/**
 * Validate callback for the field.
 */
function brightcove_field_browser_validate($element, &$form_state) {
  $id = '';
  $field_name = $element['#field_name'];
  $field = field_info_field($field_name);
  $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);
      if (is_null(brightcove_video_cache_get($id)) && $video->id != $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($field['widget']['label']),
        )));
      }
    }
    else {

      // Didn't match ID, try looking up the video text at BC.
      $bc = brightcove_initialize();
      $result = NULL;
      try {
        $result = $bc ? $bc
          ->find('find_videos_by_text', array(
          'text' => $value,
        )) : array();
      } 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($field['widget']['label']),
        )));
      }
      else {
        if (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($field['widget']['label']),
          )));
        }
        else {
          $id = $result[0]->id;
        }
      }
    }
  }
  form_set_value($element, $id, $form_state);
}

/**
 * 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_video',
    ),
    'settings' => array(
      'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
      'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
    ),
  );
  $formatters['entity_link_videoStillURL'] = array(
    'label' => t('Default still image linked to entity'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $formatters['entity_link_thumbnailURL'] = array(
    'label' => t('Default thumbnail linked to entity'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $formatters['entity_image_videoStillURL'] = array(
    'label' => t('Default still image'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $formatters['entity_image_thumbnailURL'] = array(
    'label' => t('Default thumbnail'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $formatters['dialog_player_videoStillURL'] = array(
    'label' => t('Default still image -> Dialog player'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $formatters['dialog_player_thumbnailURL'] = array(
    'label' => t('Default thumbnail -> Dialog player'),
    'field types' => array(
      'brightcove_video',
    ),
  );
  $styles = image_styles();
  foreach ($styles as $style) {
    $formatters['dialog_' . $style['name'] . '__thumbnailURL'] = array(
      'label' => t('Image style @style thumbnail -> Dialog player', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
    $formatters['dialog_' . $style['name'] . '__videoStillURL'] = array(
      'label' => t('Image style @style still image -> Dialog player', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
    $formatters['entity_link_' . $style['name'] . '__videoStillURL'] = array(
      'label' => t('Image style @style still image linked to entity', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
    $formatters['entity_link_' . $style['name'] . '__thumbnailURL'] = array(
      'label' => t('Image style @style thumbnail linked to entity', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
    $formatters['entity_image_' . $style['name'] . '__videoStillURL'] = array(
      'label' => t('Image style @style still image', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
    $formatters['entity_image_' . $style['name'] . '__thumbnailURL'] = array(
      'label' => t('Image style @style thumbnail', array(
        '@style' => $style['name'],
      )),
      'field types' => array(
        'brightcove_video',
      ),
    );
  }
  foreach (_brightcove_field_get_object_formatter_keys() as $key => $label) {
    $formatters["brightcove_metadata_{$key}"] = array(
      'label' => t("Metadata: {$label}"),
      'field types' => array(
        'brightcove_video',
      ),
    );
  }
  return $formatters;
}
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'],
    ));
  }
  return $summary;
}
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'],
    );
  }
  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_field_browser' => array(
      'label' => t('Video browser & upload'),
      'field types' => array(
        'brightcove_video',
      ),
      '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(
        'video_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_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) {
  $entity_type = $element['#entity_type'];
  $entity_info = entity_get_info($entity_type);
  $eid = isset($form[$entity_info['entity keys']['id']]['#value']) ? $form[$entity_info['entity keys']['id']]['#value'] : NULL;
  $bundle = isset($form[$entity_info['entity keys']['bundle']]['#value']) ? $form[$entity_info['entity keys']['bundle']]['#value'] : NULL;
  $element['video_id'] = array(
    '#type' => 'textfield',
    '#default_value' => isset($items[$delta]['video_id']) ? $items[$delta]['video_id'] : NULL,
    '#title' => $element['#title'],
    '#value_callback' => 'brightcove_field_browser_value',
    '#autocomplete_path' => 'brightcove_field/autocomplete/' . $element['#entity_type'] . '/' . $element['#field_name'] . '/' . ($eid ? $eid : ($bundle ? $bundle : 0)),
    '#attributes' => array(
      'rel' => array(
        $element['#field_name'] . '-' . $delta,
      ),
      'class' => array(
        'brightcove-video-field',
        $element['#field_name'] . '-' . $delta,
      ),
      'data-field-name' => $element['#field_name'],
    ),
    '#element_validate' => array(
      'brightcove_field_browser_validate',
    ),
    '#field_name' => $element['#field_name'],
  );
  if (user_access('browse videos')) {

    // Button to browse videos.
    $element['actions']['browse'] = array(
      '#type' => 'button',
      '#attributes' => array(
        'class' => array(
          'brightcove-field-browse-button',
        ),
        'rel' => $element['#field_name'] . '-' . $delta,
        'data-entity-type' => $entity_type,
        'data-bundle' => $element['#bundle'],
        'data-field-name' => $element['#field_name'],
        'data-entity-id' => is_null($eid) ? '0' : $eid,
      ),
      '#executes_submit_callback' => FALSE,
      '#limit_validation_errors' => array(),
      '#default_value' => t('Browse'),
      '#value_callback' => 'brightcove_field_button_value_callback',
      '#ajax' => array(
        'callback' => 'ajax_browse_dialog_callback',
      ),
      '#name' => $element['#field_name'] . '-' . $delta,
    );
  }
  if (user_access('upload videos') && $instance['settings']['allow_upload']) {
    $element['actions']['upload'] = array(
      '#type' => 'button',
      '#attributes' => array(
        'class' => array(
          'brightcove-field-upload-button',
        ),
        'rel' => $element['#field_name'] . '-' . $delta,
        'data-entity-type' => $entity_type,
        'data-bundle' => $element['#bundle'],
        'data-field-name' => $element['#field_name'],
        'data-entity-id' => is_null($eid) ? '0' : $eid,
      ),
      '#limit_validation_errors' => array(),
      '#default_value' => t('Upload'),
      '#value_callback' => 'brightcove_field_button_value_callback',
      '#ajax' => array(
        'callback' => 'ajax_upload_dialog_callback',
      ),
      '#name' => $element['#field_name'] . '-' . $delta,
    );
  }
  $element['actions']['remove'] = array(
    '#type' => 'button',
    '#attributes' => array(
      'class' => array(
        'brightcove-field-remove-button',
      ),
      'rel' => $element['#field_name'] . '-' . $delta,
      'data-entity-type' => $entity_type,
      'data-field-name' => $element['#field_name'],
      'data-entity-id' => is_null($eid) ? '0' : $eid,
    ),
    '#default_value' => t('Remove'),
    '#value_callback' => 'brightcove_field_button_value_callback',
    '#name' => $element['#field_name'] . '-' . $delta,
  );
  $element['player'] = array(
    '#type' => $instance['settings']['per_content_player'] ? 'select' : 'value',
    '#title' => t('Player'),
    '#options' => brightcove_player_list(),
    '#default_value' => isset($items[$delta]['player']) ? $items[$delta]['player'] : NULL,
  );
  if (!isset($element['#default_value'])) {
    $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' => is_null($eid) ? '0' : $eid,
        ),
      ),
    );
  }
  $element['video_id']['#attached']['library'] = array(
    array(
      'system',
      'ui.dialog',
    ),
  );
  $element['video_id']['#attached']['css'] = array(
    drupal_get_path('module', 'brightcove_field') . '/styles/brightcove.css',
  );
  $element['video_id']['#attached']['js'] = array(
    drupal_get_path('module', 'brightcove_field') . '/js/brightcove.js',
  );
  $element['video_id']['#attached']['js'][] = array(
    'data' => $brightcove_field_settings[$element['#field_name']],
    'type' => 'setting',
  );
  return $element;
}

/**
 * Callback for Brightcove field browser widget.
 * Will return a field value in "video-name [id:videoId]" format.
 *
 */
function brightcove_field_browser_value($element, $value, $form_state) {
  if (!$value) {
    $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}]";
    }
    else {
      if (!is_null(brightcove_video_cache_get($value))) {
        $value = check_plain(brightcove_video_cache_get($value)->name) . " [id:{$value}]";
      }
    }
  }
  return $value;
}

/**
 * Theme function returning a video field.
 */
function theme_brightcove_field_browser($element) {
  return $element['#children'];
}

/**
 * Implementation of hook_theme().
 */
function brightcove_field_theme() {
  $theme = array(
    'brightcove_field_browser' => array(
      'variables' => array(
        'element' => NULL,
      ),
    ),
    'brightcove_field_formatter_default' => array(
      'variables' => array(
        'element' => NULL,
        'instance' => array(),
        'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
        'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
      ),
      'file' => 'brightcove_field.formatters.inc',
    ),
    'brightcove_field_player' => array(
      'variables' => array(
        'player' => NULL,
        'video_id' => NULL,
      ),
      'template' => 'brightcove-field-player',
      'pattern' => 'brightcove-field-player',
    ),
    '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_entity_link' => array(
      'variables' => array(
        'output' => NULL,
        'video_id' => NULL,
        'destination' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'entity_type' => NULL,
        'style' => NULL,
      ),
      'template' => 'brightcove-field-entity-link',
      'pattern' => 'brightcove_field_entity_link__',
    ),
    'brightcove_field_entity_image' => array(
      'variables' => array(
        'output' => NULL,
        'video_id' => NULL,
        'entity_id' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'entity_type' => NULL,
      ),
      'template' => 'brightcove-field-entity-image',
      'pattern' => 'brightcove_field_entity_image__',
    ),
    'brightcove_field_dialog_image' => 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,
      ),
      'template' => 'brightcove-field-dialog-image',
      'pattern' => 'brightcove_field_dialog_image__',
    ),
    '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(
      // TODO when submitting the admin form, do a theme rebuild (form_alter)
      'variables' => array(
        'type' => 'video',
        'player' => NULL,
        'video_id' => NULL,
        'params' => array(),
        'width' => BRIGHTCOVE_DEFAULT_VIDEO_WIDTH,
        'height' => BRIGHTCOVE_DEFAULT_VIDEO_HEIGHT,
      ),
      'function' => 'theme_brightcove_field_embed',
      'file' => 'theme.inc',
    ),
  );
  $theme['brightcove_field_formatter_entity_link_thumbnailURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_entity_link',
    'file' => 'brightcove_field.formatters.inc',
  );
  $theme['brightcove_field_formatter_entity_link_videoStillURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_entity_link',
    'file' => 'brightcove_field.formatters.inc',
  );
  $theme['brightcove_field_formatter_entity_image_thumbnailURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_entity_image',
    'file' => 'brightcove_field.formatters.inc',
  );
  $theme['brightcove_field_formatter_entity_image_videoStillURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_entity_image',
    'file' => 'brightcove_field.formatters.inc',
  );
  $theme['brightcove_field_formatter_dialog_player_thumbnailURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_dialog_player',
    'file' => 'brightcove_field.formatters.inc',
  );
  $theme['brightcove_field_formatter_dialog_player_videoStillURL'] = array(
    'variables' => array(
      'element' => NULL,
      'image' => NULL,
      'style' => NULL,
      'entity_type' => NULL,
      'entity' => NULL,
      'field' => NULL,
      'instance' => NULL,
      'display' => NULL,
      'delta' => NULL,
    ),
    'function' => 'theme_brightcove_field_dialog_player',
    'file' => 'brightcove_field.formatters.inc',
  );
  $styles = image_styles();
  foreach ($styles as $style) {
    $theme['brightcove_field_formatter_dialog_image_' . $style['name'] . '__thumbnailURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_dialog_image',
      'file' => 'brightcove_field.formatters.inc',
    );
    $theme['brightcove_field_formatter_dialog_image_' . $style['name'] . '__videoStillURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_dialog_image',
      'file' => 'brightcove_field.formatters.inc',
    );
    $theme['brightcove_field_formatter_entity_link_image_' . $style['name'] . '__thumbnailURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_entity_link_image',
      'file' => 'brightcove_field.formatters.inc',
    );
    $theme['brightcove_field_formatter_entity_link_image_' . $style['name'] . '__videoStillURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_entity_link_image',
      'file' => 'brightcove_field.formatters.inc',
    );
    $theme['brightcove_field_formatter_entity_image_image_' . $style['name'] . '__thumbnailURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_entity_image_style',
      'file' => 'brightcove_field.formatters.inc',
    );
    $theme['brightcove_field_formatter_entity_image_image_' . $style['name'] . '__videoStillURL'] = array(
      'variables' => array(
        'element',
      ),
      'function' => 'theme_brightcove_field_entity_image_style',
      'file' => 'brightcove_field.formatters.inc',
    );
  }
  $theme["brightcove_field_formatter_metadata"] = array(
    'variables' => array(
      'video' => NULL,
      // video object
      'key' => NULL,
      'label' => NULL,
    ),
    'function' => 'theme_brightcove_field_formatter_metadata',
    'file' => 'brightcove_field.formatters.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'),
  );
  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['video_id'],
  );
  $form['title'] = array(
    '#type' => 'value',
    '#default_value' => $item['title'],
  );
  $form['text_title'] = array(
    '#prefix' => '<div class="video-title">',
    '#suffix' => '</div>',
    '#markup' => $item['title'],
  );
  $form['text_image'] = array(
    '#prefix' => '<div class="video-image">',
    '#suffix' => '</div>',
    '#markup' => $item['thumbnail'],
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#name' => 'submit-' . $item['video_id'],
    '#default_value' => t('Attach'),
    '#ajax' => array(
      'callback' => 'ajax_browse_dialog_close_callback',
    ),
  );
  return $form;
}

/**
 * Submit callback for brightcove_field_browser_form().
 *
 * Just take the value and pass it to modalframe.
 */
function brightcove_field_browser_form_submit($form, &$form_state) {

  // The value is "title [id:ID]" - recognised by validating element.
  $return['selected'] = check_plain($form_state['values']['title']) . ' [id:' . check_plain($form_state['values']['id']) . ']';
}

/**
 * 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['#prefix'] = '<div id="dialog-upload-form">';
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#description' => t('Video name or title.'),
    '#required' => TRUE,
    '#default_value' => !empty($form_state['values']['title']) ? $form_state['values']['title'] : '',
  );
  $custom_fields = variable_get('brightcove_custom_fields', 0);
  for ($i = 0; $i < $custom_fields; ++$i) {
    $key = variable_get("brightcove_custom_fields_{$i}_key");
    $label = variable_get("brightcove_custom_fields_{$i}_label");
    $type = variable_get("brightcove_custom_fields_{$i}_type");
    $values = array_map('trim', explode("\n", (string) variable_get("brightcove_custom_fields_{$i}_values")));
    $required = variable_get("brightcove_custom_fields_{$i}_required");
    $typedic = array(
      'text' => 'textfield',
      'list' => 'select',
    );
    if (isset($typedic[$type])) {
      $form["custom_field_{$i}"] = array(
        '#type' => $typedic[$type],
        '#title' => t($label),
        '#key' => $key,
        '#required' => (bool) $required,
      ) + ($type == 'list' ? array(
        '#options' => drupal_map_assoc($values),
      ) : array());
    }
  }
  $form['file_upload'] = array(
    '#type' => 'file',
    '#title' => t('Video file'),
    '#size' => 40,
  );
  $form['short'] = array(
    '#type' => 'textarea',
    '#rows' => 3,
    '#required' => TRUE,
    '#title' => t('Short description'),
    '#description' => t('Video short description.'),
    '#default_value' => !empty($form_state['values']['short']) ? $form_state['values']['short'] : '',
  );
  $form['advanced'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#title' => t('Advanced attributes'),
  );
  $form['advanced']['tags'] = array(
    '#type' => 'textfield',
    '#title' => t('Tags'),
    '#description' => t('Associated tags, separated by comma.'),
    '#default_value' => !empty($form_state['values']['tags']) ? $form_state['values']['tags'] : '',
  );
  $form['advanced']['long'] = array(
    '#type' => 'textarea',
    '#rows' => 4,
    '#title' => t('Long description'),
    '#description' => t('Video long description.'),
    '#default_value' => !empty($form_state['values']['long']) ? $form_state['values']['long'] : '',
  );
  $form['advanced']['linktext'] = array(
    '#type' => 'textfield',
    '#title' => t('Related link text'),
    '#description' => t('Related link description or text.'),
    '#default_value' => !empty($form_state['values']['linktext']) ? $form_state['values']['linktext'] : '',
  );
  $form['advanced']['linkurl'] = array(
    '#type' => 'textfield',
    '#title' => t('Related link url'),
    '#description' => t('Related link URL.'),
    '#default_value' => !empty($form_state['values']['linkurl']) ? $form_state['values']['linkurl'] : '',
  );

  /*  $form['attach'] = array(
      '#type' => 'submit',
      '#value' => t('Upload'),
      '#name' => 'upload',
      '#ahah' => array(
      'path' => 'upload/js',
      'wrapper' => 'attach-wrapper',
      'progress' => array('type' => 'bar', 'message' => t('Please wait...')),
      ),*/
  $form['submit'] = array(
    '#type' => 'submit',
    '#name' => 'submit-',
    //'#name' => 'submit-' . $item['video_id'],
    '#default_value' => t('Attach'),
    '#ajax' => array(
      'callback' => 'ajax_upload_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;
}

/**
 * Implements hook_content_migrate_field_alter().
 */
function brightcove_field_content_migrate_field_alter(&$field_value, $instance_value) {
  switch ($field_value['type']) {
    case 'brightcove_video':
      $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_video':
      $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().
 */
function brightcove_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $theme = '';
  $variables = array();
  $settings = $display['settings'];
  if ($display['type'] == 'default') {
    $theme = 'brightcove_field_formatter_default';
  }
  if (in_array($display['type'], array(
    'entity_link_videoStillURL',
    'entity_link_thumbnailURL',
    'entity_image_videoStillURL',
    'entity_image_thumbnailURL',
    'dialog_player_videoStillURL',
    'dialog_player_thumbnailURL',
  ))) {
    $theme = "brightcove_field_formatter_{$display['type']}";
    $variables['#image'] = '';
    $variables['#style'] = '';
  }
  foreach (image_styles() as $style) {
    if (in_array($display['type'], array(
      "dialog_{$style['name']}__thumbnailURL",
      "dialog_{$style['name']}__videoStillURL",
      "entity_link_{$style['name']}__thumbnailURL",
      "entity_link_{$style['name']}__videoStillURL",
      "entity_image_{$style['name']}__thumbnailURL",
      "entity_image_{$style['name']}__videoStillURL",
    ))) {
      $theme = "brightcove_field_formatter_{$display['type']}";
    }
  }
  foreach (_brightcove_field_get_object_formatter_keys() as $key => $label) {
    if ($display['type'] == "brightcove_metadata_{$key}") {
      $theme = 'brightcove_field_formatter_metadata';
      $variables['#key'] = $key;
      $variables['#label'] = $label;
    }
  }
  if (strpos($display['type'], 'dialog') === 0) {
    $variables['#attached']['js'][] = 'misc/ajax.js';
    $variables['#attached']['js'][] = drupal_get_path('module', 'brightcove_field') . '/js/brightcove.js';
    $variables['#attached']['library'][] = array(
      'system',
      'ui.dialog',
    );
    $variables['#attached']['css'][] = drupal_get_path('module', 'brightcove_field') . '/styles/brightcove.css';
  }
  if ($theme) {
    foreach ($items as $delta => $item) {
      $element[$delta] = array(
        '#theme' => $theme,
        '#element' => $item,
        '#delta' => $delta,
        '#entity_type' => $entity_type,
        '#entity' => $entity,
        '#field' => $field,
        '#instance' => $instance,
        '#display' => $display,
        '#video' => brightcove_video_load($item['video_id']),
        '#width' => isset($settings['width']) ? $settings['width'] : NULL,
        '#height' => isset($settings['height']) ? $settings['height'] : NULL,
      ) + $variables;
    }
  }
  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,
  );
}
function ajax_browse_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 = 'Brightcove Video Browser';
  $id = 'browse-dialog';
  $selector = '<div id="' . $id . '">';
  $path = url("brightcove_field/browse/{$et}/{$fn}/" . ($eid ? $eid : ($bundle ? $bundle : 0)));
  $commands = array();
  $commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}
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_upload_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/{$et}/{$fn}/" . ($eid ? $eid : ($bundle ? $bundle : 0)));
  $commands = array();
  $commands[] = ajax_command_dialog($title, $id, $selector, $path, $field_rel, NULL, TRUE);
  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}
function ajax_upload_dialog_close_callback($form, $form_state) {
  $id = NULL;
  $commands = array();
  $msg_selector = '#upload-messages';
  $limits['extensions'] = '3g2 3gp asf avi dv flv f4v m4v mov mp4 mpeg mpg mts m2ts qt wmv';
  $validators = array(
    'file_validate_extensions' => array(
      $limits['extensions'],
    ),
  );

  // Save new file uploads.
  if ($file = file_save_upload('file_upload', $validators, drupal_realpath(file_default_scheme() . ':/'))) {
    if ($file->filesize <= 0) {

      // Some uploaded files had zero size, that's an error.
      drupal_set_message(t('Uploaded file not found. Are you sure that you uploaded an existing file?'), 'error');
      return $form;
    }
    if (form_get_errors()) {
      return $form;
    }

    // Do something with $file here.
    $meta = array(
      'name' => $form_state['values']['title'],
      'shortDescription' => $form_state['values']['short'],
      'longDescription' => $form_state['values']['long'],
      'linkText' => $form_state['values']['linktext'],
      'linkURL' => $form_state['values']['linkurl'],
      'referenceId' => brightcove_generate_reference(),
    );
    if (!empty($form_state['values']['tags'])) {
      $meta['tags'] = explode(',', $form_state['values']['tags']);
    }
    if ($custom_fields = variable_get('brightcove_custom_fields', 0)) {
      $meta['customFields'] = array();
      for ($i = 0; $i < $custom_fields; ++$i) {
        $key = $form["custom_field_{$i}"]['#key'];
        $meta['customFields'][$key] = $form_state['values']["custom_field_{$i}"];
      }
    }
    $id = brightcove_upload_video(drupal_realpath($file->uri), $meta);
    if ($id) {

      // Construct Video object with ID - we need to cache it and save to
      // session. Brightcove Media API doesn't clear it's cache when a new
      // video is uploaded, therefore the node save would fail.
      $video = new StdClass();
      $video->id = $id;
      $video->name = $form_state['values']['title'];
      brightcove_video_cache_set($id, $video);

      // invalidating brightcove video load cache
      cache_set("bc:video:{$id}", FALSE, 'cache');
    }
    $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[] = ajax_command_close_dialog($selector, $data, NULL, $dialog_type);
    return array(
      '#type' => 'ajax',
      '#commands' => $commands,
    );
  }
  else {
    drupal_set_message(t('Only Video files are allowed here.'), 'error');
    return $form;
  }
}

/**
 * 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;
}
function _brightcove_field_get_object_formatter_keys() {
  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'),
  );
}

/**
 * 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['video_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'][$value])) {
    $instance['settings'][$value];
  }
  return NULL;
}

Functions

Namesort descending Description
ajax_browse_dialog_callback
ajax_browse_dialog_close_callback
ajax_command_close_dialog Creates a Drupal Ajax 'ui_close_dialog' command.
ajax_command_dialog Creates a Drupal Ajax 'ui_dialog' command.
ajax_upload_dialog_callback
ajax_upload_dialog_close_callback
brightcove_field_browser_form Browse form. Will return a form for one video item.
brightcove_field_browser_form_submit Submit callback for brightcove_field_browser_form().
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_validate Validate callback for the field.
brightcove_field_browser_value Callback for Brightcove field browser widget. Will return a field value in "video-name [id:videoId]" format.
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_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
brightcove_field_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_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_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_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.
theme_brightcove_field_browser Theme function returning a video field.
_brightcove_field_formatter_dimension_validate
_brightcove_field_get_object_formatter_keys

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_MINIMUM_VIDEO_HEIGHT
BRIGHTCOVE_MINIMUM_VIDEO_WIDTH