You are here

brightcove_cck.module in Brightcove Video Connect 6

Same filename and directory in other branches
  1. 6.2 brightcove_cck/brightcove_cck.module

Brightcove CCK 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_cck/brightcove_cck.module
View source
<?php

/**
 * @file
 * Brightcove CCK 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.
 */

/**
 * Implementation of hook_menu().
 */
function brightcove_cck_menu() {
  $items = array();
  $items['brightcove_cck/autocomplete/%/%/%'] = array(
    'title' => 'Brightcove CCK autocomplete',
    'page callback' => 'brightcove_cck_autocomplete',
    'page arguments' => array(
      2,
      4,
    ),
    'access callback' => 'brightcove_cck_browse_access',
    'access arguments' => array(
      3,
      2,
    ),
    'file' => 'brightcove_cck.browse.inc',
    'type' => MENU_CALLBACK,
  );
  $items['brightcove_cck/browse/%/%'] = array(
    'title' => 'Brightcove Videos Browser',
    'page arguments' => array(
      2,
      3,
    ),
    'page callback' => 'brightcove_cck_browse',
    'access callback' => 'brightcove_cck_browse_access',
    'access arguments' => array(
      2,
      3,
    ),
    'file' => 'brightcove_cck.browse.inc',
    'type' => MENU_CALLBACK,
  );
  $items['brightcove_cck/upload/%/%'] = array(
    'title' => 'Upload video to Brightcove',
    'page arguments' => array(
      2,
      3,
    ),
    'page callback' => 'brightcove_cck_upload',
    'access callback' => 'brightcove_cck_browse_access',
    'access arguments' => array(
      2,
      3,
    ),
    'file' => 'brightcove_cck.browse.inc',
    'type' => MENU_CALLBACK,
  );
  $items['brightcove_cck_player/%node/%/%'] = array(
    'title' => 'Brightcove Videos Window Player',
    'page callback' => 'brightcove_cck_player',
    'page arguments' => array(
      1,
      2,
      3,
    ),
    'access callback' => 'node_access',
    'access arguments' => array(
      'view',
      1,
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Access callback for brightcove browser.
 *
 * @param $node_type
 * Node type.
 * @param $field_name
 * Field name.
 * @param arg(4)
 * Optional node which is edited.
 *
 * @return
 * TRUE if access is allowed, FALSE if access is forbidden.
 */
function brightcove_cck_browse_access($node_type, $field_name) {
  if (is_int(arg(4))) {
    $node = node_load(arg(4));
    if (node_access('update', $node) && content_access('edit', $field_name)) {
      return TRUE;
    }
    return FALSE;
  }

  // FIX: this used to pass $field_name to content_access(), but it needs a field array
  // I'm not sure which function is supposed to load the whole field array (b/c we have no $node to work with),
  // so I'm shortcutting it w/ this array, which works for content_permissions
  $field = array(
    'field_name' => $field_name,
  );
  if (node_access('create', $node_type) && content_access('edit', $field)) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Callback for brightcove_cck_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 none
 */
function brightcove_cck_player($node, $field_name, $delta) {
  if (node_access('view', $node) && content_access('view', $field_name)) {
    $field = $node->{$field_name}[$delta]['video_id'];
    $output = '<script src="http://admin.brightcove.com/js/BrightcoveExperiences.js" type="text/javascript"></script>';
    $bc = _brightcove_initialize();
    $output .= theme('brightcove_cck_embed', 'video', variable_get('brightcove_player', ''), variable_get('brightcove_player_key', ''), $field, array());
    print $output;
  }
}

/**
 * Implementation of hook_field_info().
 */
function brightcove_cck_field_info() {
  return array(
    'brightcove_video' => array(
      'label' => t('Brightcove Video'),
      'description' => t('Browse and upload videos at Brightcove.'),
    ),
  );
}

/**
 * Implementation of hook_field_settings().
 */
function brightcove_cck_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $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 <a href="http://www.brightcove.com/en/video-platform/editions-and-pricing">Professional account</a>.'),
          '#default_value' => $field['allow_upload'],
        );
      }
      return $form;
    case 'save':
      $settings = array(
        'allow_upload',
      );
      return $settings;
    case 'database columns':

      // We only save video_id as it's the only stable value in the video -
      // anything else might change and we won't be able to easily detect it.
      $columns = array(
        'video_id' => array(
          'type' => 'varchar',
          'length' => 15,
          'not null' => FALSE,
          'index' => TRUE,
        ),
      );
      return $columns;
    case 'views data':
      include_once drupal_get_path('module', 'brightcove_cck') . '/views/brightcove_cck.views.inc';
      $data = _brightcove_cck_views_data($field);
      return $data;
  }
}

/**
 * Implementation of hook_field().
 */
function brightcove_cck_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'validate':
      foreach ($items as $delta => $item) {
        if (is_array($item)) {
          $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
          if (is_array($item) && isset($item['_error_element'])) {
            unset($item['_error_element']);
          }
          if (!empty($item['video_id'])) {
            $video = brightcove_video_load($item['video_id']);
            if (empty($video->id)) {

              // Check for video in session - uploaded file.
              if (is_null(brightcove_video_cache_get($item['video_id']))) {
                form_set_error($error_element, t('%name: invalid video.', array(
                  '%name' => t($field['widget']['label']),
                )));
              }
            }
          }
        }
      }
      return $items;
  }
}

/**
 * Implementation fo hook_content_is_empty().
 */
function brightcove_cck_content_is_empty($item, $field) {
  if (!empty($item['video_id'])) {
    return FALSE;
  }
  return TRUE;
}

/**
 * Validate callback for the field.
 */
function brightcove_cck_browser_validate($element, &$form_state) {
  $field_name = $element['#field_name'];
  $type_name = $element['#type_name'];
  $field = content_fields($field_name, $type_name);
  $field_key = $element['#columns'][0];
  $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 ($video->id != $id && is_null(brightcove_video_cache_get($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();
      try {
        $result = $bc
          ->find('find_videos_by_text', array(
          'text' => $value,
        ));
      } 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_cck_field_formatter_info() {
  $formatters = array(
    'default' => array(
      'label' => t('Standard video player'),
      'field types' => array(
        'brightcove_video',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
  $formatters['node_link_videoStillURL'] = array(
    'label' => t('Default still image linked to node'),
    'field types' => array(
      'brightcove_video',
    ),
    'multiple values' => CONTENT_HANDLE_CORE,
  );
  $formatters['node_link_thumbnailURL'] = array(
    'label' => t('Default thumbnail linked to node'),
    'field types' => array(
      'brightcove_video',
    ),
    'multiple values' => CONTENT_HANDLE_CORE,
  );
  $formatters['node_image_videoStillURL'] = array(
    'label' => t('Default still image'),
    'field types' => array(
      'brightcove_video',
    ),
    'multiple values' => CONTENT_HANDLE_CORE,
  );
  $formatters['node_image_thumbnailURL'] = array(
    'label' => t('Default thumbnail'),
    'field types' => array(
      'brightcove_video',
    ),
    'multiple values' => CONTENT_HANDLE_CORE,
  );
  if (module_exists('lightbox2')) {
    $formatters['lightbox2_player_videoStillURL'] = array(
      'label' => t('Default still image -> Lightbox2 player'),
      'field types' => array(
        'brightcove_video',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    );
    $formatters['lightbox2_player_thumbnailURL'] = array(
      'label' => t('Default thumbnail -> Lightbox2 player'),
      'field types' => array(
        'brightcove_video',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    );
  }
  if (module_exists('imagecache')) {
    $presets = imagecache_presets();
    foreach ($presets as $preset_id => $preset) {
      if (module_exists('lightbox2')) {
        $formatters['lightbox2_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
          'label' => t('Imagecache @preset thumbnail -> Lightbox2 player', array(
            '@preset' => $preset['presetname'],
          )),
          'field types' => array(
            'brightcove_video',
          ),
          'multiple values' => CONTENT_HANDLE_CORE,
        );
        $formatters['lightbox2_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
          'label' => t('Imagecache @preset still image -> Lightbox2 player', array(
            '@preset' => $preset['presetname'],
          )),
          'field types' => array(
            'brightcove_video',
          ),
          'multiple values' => CONTENT_HANDLE_CORE,
        );
      }
      $formatters['node_link_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
        'label' => t('Imagecache @preset still image linked to node', array(
          '@preset' => $preset['presetname'],
        )),
        'field types' => array(
          'brightcove_video',
        ),
        'multiple values' => CONTENT_HANDLE_CORE,
      );
      $formatters['node_link_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
        'label' => t('Imagecache @preset thumbnail linked to node', array(
          '@preset' => $preset['presetname'],
        )),
        'field types' => array(
          'brightcove_video',
        ),
        'multiple values' => CONTENT_HANDLE_CORE,
      );
      $formatters['node_image_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
        'label' => t('Imagecache @preset still image', array(
          '@preset' => $preset['presetname'],
        )),
        'field types' => array(
          'brightcove_video',
        ),
        'multiple values' => CONTENT_HANDLE_CORE,
      );
      $formatters['node_image_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
        'label' => t('Imagecache @preset thumbnail', array(
          '@preset' => $preset['presetname'],
        )),
        'field types' => array(
          'brightcove_video',
        ),
        'multiple values' => CONTENT_HANDLE_CORE,
      );
    }
  }
  return $formatters;
}

/**
 * Implementation of hook_widget_info().
 */
function brightcove_cck_widget_info() {
  return array(
    'brightcove_cck_browser' => array(
      'label' => t('Video browser & upload'),
      'field types' => array(
        'brightcove_video',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
      'callbacks' => array(
        'default value' => CONTENT_CALLBACK_DEFAULT,
      ),
    ),
  );
}

/**
 * Implementation of hook_elements().
 */
function brightcove_cck_elements() {
  $elements = array(
    'brightcove_cck_browser' => array(
      '#input' => TRUE,
      '#columns' => array(
        'video_id',
      ),
      '#delta' => 0,
      '#process' => array(
        'brightcove_cck_browser_process',
      ),
      '#autocomplete_path' => FALSE,
    ),
    'brightcove_cck_browse_button' => array(
      '#input' => FALSE,
    ),
  );
  return $elements;
}

/**
 * Brightcove CCK field form that returns the actual field to the user.
 * Parts of this and subsequent JS taken from Nodereference Explorer. Thanks!
 */
function brightcove_cck_browser_process($element, $edit, $form_state, $form) {
  global $brightcove_cck_settings;
  $field_key = $element['#columns'][0];
  $field_info = content_fields($element['#field_name'], $element['#type_name']);
  modalframe_parent_js();

  //dialog internal area
  $element[$field_key] = array(
    '#type' => 'textfield',
    '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : '',
    '#autocomplete_path' => 'brightcove_cck/autocomplete/' . $element['#field_name'] . '/' . $element['#type_name'] . '/' . $form['nid']['#value'],
    // 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'],
    '#type_name' => $element['#type_name'],
    '#delta' => $element['#delta'],
    '#columns' => $element['#columns'],
    '#attributes' => array(
      'rel' => $element['#field_name'],
      'class' => 'brightcove-video-field',
    ),
  );

  // Button to browse videos.
  $element['actions']['browse'] = array(
    '#type' => 'brightcove_cck_browse_button',
    '#id' => $element['#id'] . '-browse',
    '#attributes' => array(
      'class' => 'brightcove-cck-browse-button',
      'rel' => $element['#id'] . '-video-id',
    ),
    '#value' => t('Browse'),
  );
  if ($field_info['allow_upload']) {
    $element['actions']['upload'] = array(
      '#type' => 'brightcove_cck_browse_button',
      '#id' => $element['#id'] . '-upload',
      '#attributes' => array(
        'class' => 'brightcove-cck-upload-button',
        'rel' => $element['#id'] . '-video-id',
      ),
      '#value' => t('Upload'),
    );
  }
  $element['actions']['remove'] = array(
    '#type' => 'brightcove_cck_browse_button',
    '#id' => $element['#id'] . '-remove',
    '#attributes' => array(
      'class' => 'brightcove-cck-remove-button',
      'rel' => $element['#id'] . '-video-id',
    ),
    '#value' => t('Detach'),
  );
  if (!isset($element['#default_value'][$field_key])) {
    $element['actions']['remove']['#attributes']['disabled'] = 'disabled';
  }
  if (empty($brightcove_cck_settings[$element['#field_name']])) {
    $brightcove_cck_settings[$element['#field_name']] = array(
      'brightcove_cck' => array(
        $element['#field_name'] => array(
          'node_type' => $element['#type_name'],
          'field_name' => $element['#field_name'],
          'nid' => $nid = $form['nid']['#value'],
        ),
      ),
    );
    drupal_add_js($brightcove_cck_settings[$element['#field_name']], 'setting');
  }
  if (empty($element[$field_key]['#element_validate'])) {
    $element[$field_key]['#element_validate'] = array();
  }
  array_unshift($element[$field_key]['#element_validate'], 'brightcove_cck_browser_validate');

  // Used so that hook_field('validate') knows where to flag an error.
  // @see userreference.module
  $element['_error_element'] = array(
    '#type' => 'value',
    '#value' => implode('][', array_merge($element['#parents'], array(
      $field_key,
      $field_key,
    ))),
  );
  return $element;
}

/**
 * Implementation of hook_widget().
 */
function brightcove_cck_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  switch ($field['widget']['type']) {
    case 'brightcove_cck_browser':
      $element = array(
        '#type' => 'brightcove_cck_browser',
        '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
        '#value_callback' => 'brightcove_cck_browser_value',
      );
      break;
  }
  return $element;
}

/**
 * Callback for Brightcove CCK browser widget.
 * Will return a field value in "video-name [id:videoId]" format.
 *
 */
function brightcove_cck_browser_value($element, $edit = FALSE) {
  $field_key = $element['#columns'][0];
  $id = $element['#default_value'][$field_key];
  if ((int) $id > 1) {
    $video = brightcove_video_load($id);
    if ($video->id) {
      return array(
        $field_key => check_plain($video->name) . ' [id:' . $video->id . ']',
      );
    }
    else {
      if (!is_null(brightcove_video_cache_get($id))) {
        return array(
          $field_key => check_plain(brightcove_video_cache_get($id)->name) . ' [id:' . $id . ']',
        );
      }
    }
  }
  return array(
    $field_key => NULL,
  );
}

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

/**
 * Implementation of hook_theme().
 */
function brightcove_cck_theme() {
  $theme = array(
    'brightcove_cck_browser' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'brightcove_cck_formatter_default' => array(
      'arguments' => array(
        'element',
      ),
      'file' => 'brightcove_cck.formatters.inc',
    ),
    'brightcove_cck_player' => array(
      'arguments' => array(
        'player' => NULL,
        'video_id' => NULL,
      ),
      'template' => 'brightcove-cck-player',
      'pattern' => 'brightcove-cck-player',
    ),
    'brightcove_cck_lightbox2' => array(
      'arguments' => array(
        'output' => NULL,
        'video_id' => NULL,
        'video_width' => NULL,
        'video_height' => NULL,
        'lightbox2_width' => NULL,
        'lightbox2_height' => NULL,
        'destination' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'type_name' => NULL,
        'preset' => NULL,
      ),
      'template' => 'brightcove-cck-lightbox2',
      'pattern' => 'brightcove_cck_lightbox2__',
      'preprocess functions' => array(
        'template_preprocess_brightcove_cck_lightbox2',
      ),
    ),
    'brightcove_cck_node_link' => array(
      'arguments' => array(
        'output' => NULL,
        'video_id' => NULL,
        'destination' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'type_name' => NULL,
        'preset' => NULL,
      ),
      'template' => 'brightcove-cck-node-link',
      'pattern' => 'brightcove_cck_node_link__',
      'preprocess functions' => array(
        'template_preprocess_brightcove_cck_node_link',
      ),
    ),
    'brightcove_cck_node_image' => array(
      'arguments' => array(
        'output' => NULL,
        'video_id' => NULL,
        'nid' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'type_name' => NULL,
      ),
      'template' => 'brightcove-cck-node-image',
      'pattern' => 'brightcove_cck_node_image__',
      'preprocess functions' => array(
        'template_preprocess_brightcove_cck_node_image',
      ),
    ),
    'brightcove_cck_lightbox2_imagecache' => array(
      'arguments' => array(
        'output' => NULL,
        'video_id' => NULL,
        'video_width' => NULL,
        'video_height' => NULL,
        'lightbox2_width' => NULL,
        'lightbox2_height' => NULL,
        'destination' => NULL,
        'image_field' => NULL,
        'field_name' => NULL,
        'type_name' => NULL,
      ),
      'template' => 'brightcove-cck-lightbox2-imagecache',
      'pattern' => 'brightcove_cck_lightbox2_imagecache__',
      'preprocess functions' => array(
        'template_preprocess_brightcove_cck_lightbox2_imagecache',
      ),
    ),
    'brightcove_cck_browse_button' => array(
      'arguments' => array(
        'element' => NULL,
      ),
      'function' => 'theme_brightcove_cck_browse_button',
      'file' => 'theme.inc',
    ),
    'brightcove_cck_browse_item' => array(
      'arguments' => array(
        'item' => NULL,
      ),
      'file' => 'theme.inc',
    ),
    'brightcove_cck_browse_items' => array(
      'arguments' => array(
        'item' => NULL,
      ),
      'file' => 'theme.inc',
    ),
    'brightcove_cck_embed' => array(
      'arguments' => array(
        'type' => NULL,
        'player' => NULL,
        'player_key' => NULL,
        'video_id' => NULL,
        'params' => NULL,
      ),
      'function' => 'theme_brightcove_cck_embed',
      'file' => 'theme.inc',
    ),
  );
  $theme['brightcove_cck_formatter_node_link_thumbnailURL'] = array(
    'arguments' => array(
      'element' => NULL,
      'image' => NULL,
      'preset' => NULL,
    ),
    'function' => 'theme_brightcove_cck_node_link',
    'file' => 'brightcove_cck.formatters.inc',
  );
  $theme['brightcove_cck_formatter_node_link_videoStillURL'] = array(
    'arguments' => array(
      'element' => NULL,
      'image' => NULL,
      'preset' => NULL,
    ),
    'function' => 'theme_brightcove_cck_node_link',
    'file' => 'brightcove_cck.formatters.inc',
  );
  $theme['brightcove_cck_formatter_node_image_thumbnailURL'] = array(
    'arguments' => array(
      'element' => NULL,
      'image' => NULL,
      'preset' => NULL,
    ),
    'function' => 'theme_brightcove_cck_node_image',
    'file' => 'brightcove_cck.formatters.inc',
  );
  $theme['brightcove_cck_formatter_node_image_videoStillURL'] = array(
    'arguments' => array(
      'element' => NULL,
      'image' => NULL,
      'preset' => NULL,
    ),
    'function' => 'theme_brightcove_cck_node_image',
    'file' => 'brightcove_cck.formatters.inc',
  );
  if (module_exists('lightbox2')) {
    $theme['brightcove_cck_formatter_lightbox2_player_thumbnailURL'] = array(
      'arguments' => array(
        'element' => NULL,
        'image' => NULL,
        'preset' => NULL,
      ),
      'function' => 'theme_brightcove_cck_lightbox2_player',
      'file' => 'brightcove_cck.formatters.inc',
    );
    $theme['brightcove_cck_formatter_lightbox2_player_videoStillURL'] = array(
      'arguments' => array(
        'element' => NULL,
        'image' => NULL,
        'preset' => NULL,
      ),
      'function' => 'theme_brightcove_cck_lightbox2_player',
      'file' => 'brightcove_cck.formatters.inc',
    );
  }
  if (module_exists('imagecache')) {
    $presets = imagecache_presets();
    foreach ($presets as $preset_id => $preset) {
      if (module_exists('lightbox2')) {
        $theme['brightcove_cck_formatter_lightbox2_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
          'arguments' => array(
            'element',
          ),
          'function' => 'theme_brightcove_cck_lightbox2_imagecache',
          'file' => 'brightcove_cck.formatters.inc',
        );
        $theme['brightcove_cck_formatter_lightbox2_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
          'arguments' => array(
            'element',
          ),
          'function' => 'theme_brightcove_cck_lightbox2_imagecache',
          'file' => 'brightcove_cck.formatters.inc',
        );
      }
      $theme['brightcove_cck_formatter_node_link_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
        'arguments' => array(
          'element',
        ),
        'function' => 'theme_brightcove_cck_node_link_imagecache',
        'file' => 'brightcove_cck.formatters.inc',
      );
      $theme['brightcove_cck_formatter_node_link_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
        'arguments' => array(
          'element',
        ),
        'function' => 'theme_brightcove_cck_node_link_imagecache',
        'file' => 'brightcove_cck.formatters.inc',
      );
      $theme['brightcove_cck_formatter_node_image_imagecache_' . $preset['presetname'] . '__thumbnailURL'] = array(
        'arguments' => array(
          'element',
        ),
        'function' => 'theme_brightcove_cck_node_image_imagecache',
        'file' => 'brightcove_cck.formatters.inc',
      );
      $theme['brightcove_cck_formatter_node_image_imagecache_' . $preset['presetname'] . '__videoStillURL'] = array(
        'arguments' => array(
          'element',
        ),
        'function' => 'theme_brightcove_cck_node_image_imagecache',
        'file' => 'brightcove_cck.formatters.inc',
      );
    }
  }
  return $theme;
}

/**
 * Filter form for video browser.
 */
function brightcove_cck_filter_form(&$form_state) {
  $form['search'] = array(
    '#type' => 'fieldset',
    '#title' => t('Filter videos'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($_SESSION['brightcove_cck_filter']) ? TRUE : FALSE,
  );
  $form['search']['keywords'] = array(
    '#type' => 'textfield',
    '#title' => t('Keywords'),
    '#size' => 25,
    '#default_value' => $_SESSION['brightcove_cck_filter']['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_cck_filter']['search']) ? $_SESSION['brightcove_cck_filter']['search'] : 'name',
    '#attributes' => array(
      'class' => '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',
    '#value' => t('Filter'),
  );
  $form['search']['reset'] = array(
    '#type' => 'submit',
    '#name' => 'reset',
    '#value' => t('Reset'),
  );
  return $form;
}

/**
 * Submit callback for brightcove_cck_filter_form().
 *
 * Set session variables based on selection.
 *
 * @see brightcove_cck_browse().
 */
function brightcove_cck_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_cck_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_cck_filter']['keywords'] = $keywords;
  $_SESSION['brightcove_cck_filter']['search'] = $search;
}

/**
 * Browse form. Will return a form for one video item.
 *
 * @see brightcove_cck_forms().
 */
function brightcove_cck_browser_form(&$form_state, $item) {
  $form['id'] = array(
    '#type' => 'value',
    '#value' => $item['video_id'],
  );
  $form['title'] = array(
    '#type' => 'value',
    '#value' => $item['title'],
  );
  $form['text_title'] = array(
    '#type' => 'item',
    '#value' => $item['title'],
  );
  $form['text_image'] = array(
    '#type' => 'item',
    '#value' => $item['thumbnail'],
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#name' => 'submit-' . $item['video_id'],
    '#value' => t('Attach'),
  );
  $form['#submit'] = array(
    "brightcove_cck_browser_form_submit",
  );
  return $form;
}

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

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

/**
 * 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_cck_forms($form_id, $args) {
  $forms = array();
  if (strpos($form_id, "brightcove_cck_browser_form") === 0) {
    $forms[$form_id] = array(
      'callback' => 'brightcove_cck_browser_form',
    );
  }
  return $forms;
}

/**
 * Implementation of hook_views_api().
 */
function brightcove_cck_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'brightcove_cck') . '/views',
  );
}

/**
 * Browse form. Will return a form for one video item.
 */
function brightcove_cck_upload_form(&$form_state) {
  drupal_add_js(drupal_get_path('module', 'brightcove_cck') . '/js/upload.js');
  drupal_add_css(drupal_get_path('module', 'brightcove_cck') . '/styles/upload.css');
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#description' => t('Video name or title.'),
    '#required' => TRUE,
    '#default_value' => $form_state['values']['title'],
  );
  $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' => $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' => $form_state['values']['tags'],
  );
  $form['advanced']['long'] = array(
    '#type' => 'textarea',
    '#rows' => 4,
    '#title' => t('Long description'),
    '#description' => t('Video long description.'),
    '#default_value' => $form_state['values']['long'],
  );
  $form['advanced']['linktext'] = array(
    '#type' => 'textfield',
    '#title' => t('Related link text'),
    '#description' => t('Related link description or text.'),
    '#default_value' => $form_state['values']['linktext'],
  );
  $form['advanced']['linkurl'] = array(
    '#type' => 'textfield',
    '#title' => t('Related link url'),
    '#description' => t('Related link URL.'),
    '#default_value' => $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-' . $item['video_id'],
    '#value' => t('Attach'),
  );
  $form['#attributes'] = array(
    'enctype' => "multipart/form-data",
  );
  $form['#submit'] = array(
    "brightcove_cck_upload_form_submit",
  );
  return $form;
}

/**
 * Submit callback for brightcove_cck_upload_form.
 *
 * Will save a file and upload it to Brightcove.
 */
function brightcove_cck_upload_form_submit($form, &$form_state) {
  $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, file_directory_path())) {
    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;
    }

    // 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'] = split(',', $form_state['values']['tags']);
    }
    $id = brightcove_upload_video($file->filepath, $meta);

    // 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);
    db_query('DELETE FROM {files} WHERE fid = %d', $file->fid);
    unlink($file->filepath);
    $return['selected'] = $form_state['values']['title'] . ' [id:' . $id . ']';
    modalframe_close_dialog($return);
  }
  else {
    drupal_set_message(t('Only Video files are allowed here.'), 'error');
  }
}

/**
 * Implementation of hook_imagecache_default_presets().
 */
function brightcove_cck_imagecache_default_presets() {
  $presets = array();
  $presets['brightcove_browser'] = array(
    'presetname' => 'brightcove_browser',
    'actions' => array(
      0 => array(
        'weight' => '0',
        'module' => 'imagecache',
        'action' => 'imagecache_scale_and_crop',
        'data' => array(
          'width' => '120',
          'height' => '120',
        ),
      ),
    ),
  );
  return $presets;
}

Functions

Namesort descending Description
brightcove_cck_browser_form Browse form. Will return a form for one video item.
brightcove_cck_browser_form_submit Submit callback for brightcove_cck_browser_form().
brightcove_cck_browser_process Brightcove CCK field form that returns the actual field to the user. Parts of this and subsequent JS taken from Nodereference Explorer. Thanks!
brightcove_cck_browser_validate Validate callback for the field.
brightcove_cck_browser_value Callback for Brightcove CCK browser widget. Will return a field value in "video-name [id:videoId]" format.
brightcove_cck_browse_access Access callback for brightcove browser.
brightcove_cck_content_is_empty Implementation fo hook_content_is_empty().
brightcove_cck_elements Implementation of hook_elements().
brightcove_cck_field Implementation of hook_field().
brightcove_cck_field_formatter_info Implementation of hook_formatter_info().
brightcove_cck_field_info Implementation of hook_field_info().
brightcove_cck_field_settings Implementation of hook_field_settings().
brightcove_cck_filter_form Filter form for video browser.
brightcove_cck_filter_form_submit Submit callback for brightcove_cck_filter_form().
brightcove_cck_forms Implementation of hook_forms().
brightcove_cck_imagecache_default_presets Implementation of hook_imagecache_default_presets().
brightcove_cck_menu Implementation of hook_menu().
brightcove_cck_player Callback for brightcove_cck_player - checks access to the field and prints a player for Lightbox2.
brightcove_cck_theme Implementation of hook_theme().
brightcove_cck_upload_form Browse form. Will return a form for one video item.
brightcove_cck_upload_form_submit Submit callback for brightcove_cck_upload_form.
brightcove_cck_views_api Implementation of hook_views_api().
brightcove_cck_widget Implementation of hook_widget().
brightcove_cck_widget_info Implementation of hook_widget_info().
theme_brightcove_cck_browser Theme function returning a video field.