You are here

atom_reference.module in Scald: Media Management made easy 6

Defines a new field type, allowing to directly reference Scald Atoms from a node.

File

atom_reference/atom_reference.module
View source
<?php

/**
 * @file
 *   Defines a new field type, allowing to directly reference Scald Atoms from
 *   a node.
 */

/**
 * Implements hook_field_info().
 */
function atom_reference_field_info() {
  return array(
    'atom_reference' => array(
      'label' => t('Atom Reference'),
      'description' => 'This field stores the ID of a related atom as an integer value',
    ),
  );
}

/**
 * Implements hook_field_settings().
 */
function atom_reference_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $types = _scald_types();
      $options = array();
      foreach (_scald_types() as $name => $type) {
        $options[$name] = $type['title'];
      }
      $form = array();
      $form['referencable_types'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Atom types that can be referenced'),
        '#multiple' => TRUE,
        '#options' => $options,
        '#default_value' => $field['referencable_types'],
      );
      return $form;
    case 'save':
      return array(
        'referencable_types',
      );
    case 'database columns':
      $columns = array(
        'sid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => FALSE,
          'index' => TRUE,
        ),
      );
      return $columns;
    case 'views data':
      $data = content_views_field_views_data($field);
      $db_info = content_database_info($field);
      $table_alias = content_views_tablename($field);

      // Relationship: add a relationship for related atom.
      $data[$table_alias][$field['field_name'] . '_sid']['relationship'] = array(
        'base' => 'scald_atoms',
        'field' => $db_info['columns']['sid']['column'],
        'handler' => 'content_handler_relationship',
        'label' => t($field['widget']['label']),
        'content_field_name' => $field['field_name'],
      );
      return $data;
  }
}

/**
 * Implements hook_field().
 */
function atom_reference_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'validate':

      // Ensure that the types of the referenced atoms match the one of those
      // that were defined in the field configuration.
      $types = $field['referencable_types'];
      foreach ($items as $item) {
        if (!$item['sid']) {
          continue;
        }
        $atom = scald_fetch($item['sid']);
        if (!isset($types[$atom->type]) || empty($types[$atom->type])) {
          form_set_error('toto', t("Atom %title is of type %type, which can't be referenced in field %field", array(
            '%title' => $atom->title,
            '%type' => $atom->type,
            '%field' => $field['widget']['label'],
          )));
        }
      }
    case 'sanitize':

      // Get some safe values about the references atoms, checking that
      // they still exist and are fetchable.
      $sids = array();
      foreach ($items as $delta => $item) {
        if (is_array($item)) {
          $items[$delta]['safe'] = array();
          if (isset($item['sid'])) {
            $atom = scald_fetch($item['sid']);
            if (is_object($atom)) {
              $items[$delta]['safe']['sid'] = $atom->sid;
              $items[$delta]['safe']['title'] = check_plain($atom->title);
            }
          }
        }
      }
      break;
  }
}

/**
 * Implements hook_content_is_empty().
 */
function atom_reference_content_is_empty($item, $field) {
  return empty($item['sid']);
}

/**
 * Implements hook_field_formatter_info().
 */
function atom_reference_field_formatter_info() {
  return array(
    'default' => array(
      'label' => 'Title',
      'field types' => array(
        'atom_reference',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'library' => array(
      'label' => 'Library',
      'field types' => array(
        'atom_reference',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'editor' => array(
      'label' => 'Editor',
      'field types' => array(
        'atom_reference',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}

/**
 * Implements hook_theme().
 * Defines all the theme callbacks used by the formatters mentionned above,
 * in hook_field_formatter_info, and the theme function releated to the new
 * widget elements we're declaring below.
 */
function atom_reference_theme() {
  return array(
    'atom_reference_formatter_default' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'atom_reference_formatter_library' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'atom_reference_formatter_editor' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'atom_reference_textfield' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
  );
}

/**
 * Theme function for the 'default' formatter.
 */
function theme_atom_reference_formatter_default($element) {
  return scald_render($element['#item']['sid'], 'title');
}

/**
 * Theme function for the 'library' formatter.
 */
function theme_atom_reference_formatter_library($element) {
  return scald_render($element['#item']['sid'], 'sdl_library_item');
}

/**
 * Theme function for the 'editor' formatter.
 */
function theme_atom_reference_formatter_editor($element) {
  return scald_render($element['#item']['sid'], 'sdl_editor_representation');
}

/**
 * Implements hook_widget_info.
 */
function atom_reference_widget_info() {
  return array(
    'atom_reference_textfield' => array(
      'label' => t('Text field'),
      'field types' => array(
        'atom_reference',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}

/**
 * Implements hook_elements.
 */
function atom_reference_elements() {
  return array(
    'atom_reference_textfield' => array(
      '#input' => TRUE,
      '#delta' => 0,
      '#columns' => array(
        'sid',
      ),
      '#process' => array(
        'atom_reference_textfield_process',
      ),
    ),
  );
}

/**
 * Implements hook_widget.
 */
function atom_reference_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  if ($field['referencable_types']) {
    $types = array_keys(array_filter($field['referencable_types']));
  }
  else {
    $types = array();
  }
  $element = array(
    '#type' => $field['widget']['type'],
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
    '#types' => $types,
  );
  return $element;
}

/**
 * Process an individual element, building the actual form api components needed
 * for this widget.
 */
function atom_reference_textfield_process($element, $edit, $form_state, $form) {
  dnd_add_library();
  drupal_add_js(drupal_get_path('module', 'atom_reference') . '/atom_reference.js');
  drupal_add_css(drupal_get_path('module', 'atom_reference') . '/atom_reference.css');
  $default = isset($element['#value']['sid']) ? $element['#value']['sid'] : '';
  if ($default) {
    $prefix = '<div class="atom_reference_drop_zone">' . scald_render($default, 'sdl_editor_representation') . '</div>';
  }
  else {
    $placeholder = t('Drop a resource here');
    $prefix = '<div class="atom_reference_drop_zone"><em>' . $placeholder . '</em></div>';
  }
  $help = format_plural(count($element['#types']), 'Allowed resource format: %types', 'Allowed resource formats: %types', array(
    '%types' => implode(', ', $element['#types']),
  ));
  $element['sid'] = array(
    '#type' => 'textfield',
    '#default_value' => $default,
    '#title' => $element['#title'],
    '#description' => $element['#description'] . $help,
    '#required' => $element['#required'],
    '#field_name' => $element['#field_name'],
    '#type_name' => $element['#type_name'],
    '#delta' => $element['#delta'],
    '#columns' => $element['#columns'],
    '#attributes' => array(
      'atom:types' => implode(',', $element['#types']),
    ),
    '#field_prefix' => $prefix,
  );
  return $element;
}

/**
 * Theme function for the custom widget we've defined.
 */
function theme_atom_reference_textfield($element) {
  return $element['#children'];
}

Functions

Namesort descending Description
atom_reference_content_is_empty Implements hook_content_is_empty().
atom_reference_elements Implements hook_elements.
atom_reference_field Implements hook_field().
atom_reference_field_formatter_info Implements hook_field_formatter_info().
atom_reference_field_info Implements hook_field_info().
atom_reference_field_settings Implements hook_field_settings().
atom_reference_textfield_process Process an individual element, building the actual form api components needed for this widget.
atom_reference_theme Implements hook_theme(). Defines all the theme callbacks used by the formatters mentionned above, in hook_field_formatter_info, and the theme function releated to the new widget elements we're declaring below.
atom_reference_widget Implements hook_widget.
atom_reference_widget_info Implements hook_widget_info.
theme_atom_reference_formatter_default Theme function for the 'default' formatter.
theme_atom_reference_formatter_editor Theme function for the 'editor' formatter.
theme_atom_reference_formatter_library Theme function for the 'library' formatter.
theme_atom_reference_textfield Theme function for the custom widget we've defined.