atom_reference.module in Scald: Media Management made easy 7
Defines a new field type, allowing to directly reference Scald Atoms from a node.
File
modules/fields/atom_reference/atom_reference.moduleView source
<?php
/**
* @file
* Defines a new field type, allowing to directly reference Scald Atoms from
* a node.
*/
/**
* Implements hook_library().
*/
function atom_reference_library() {
$path = drupal_get_path('module', 'atom_reference');
$libraries['library'] = array(
'title' => 'Atom reference library',
'website' => 'http://drupal.org/project/scald',
'version' => '1.x',
'js' => array(
$path . '/atom_reference.js' => array(),
drupal_get_path('module', 'ctools') . '/js/dropbutton.js' => array(),
),
'css' => array(
$path . '/atom_reference.css' => array(),
drupal_get_path('module', 'ctools') . '/css/dropbutton.css' => array(),
drupal_get_path('module', 'ctools') . '/css/button.css' => array(),
),
);
return $libraries;
}
/**
* Implements hook_field_info().
*/
function atom_reference_field_info() {
return array(
'atom_reference' => array(
'label' => t('Atom Reference'),
'description' => t('This field stores the ID of a related atom as an integer value.'),
'instance_settings' => array(
'referencable_types' => array(),
),
'default_widget' => 'atom_reference_textfield',
'default_formatter' => 'title',
'property_type' => 'scald_atom',
),
);
}
/**
* Implements hook_field_instance_settings_form().
*/
function atom_reference_field_instance_settings_form($field, $instance) {
$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' => $instance['settings']['referencable_types'],
);
$allow_override = isset($instance['settings']['allow_override']) ? $instance['settings']['allow_override'] : FALSE;
$form['allow_override'] = array(
'#type' => 'checkbox',
'#title' => t('Allow context override'),
'#default_value' => $allow_override,
);
return $form;
}
/**
* Implements hook_field_views_data().
*/
function atom_reference_field_views_data($field) {
$data = field_views_field_default_views_data($field);
$current_table = _field_sql_storage_tablename($field);
$revision_table = _field_sql_storage_revision_tablename($field);
$column = _field_sql_storage_columnname($field['field_name'], 'sid');
// Relationship: add a relationship for related atom.
$data[$current_table][$column]['relationship'] = array(
'base' => 'scald_atoms',
'field' => $column,
'handler' => 'views_handler_relationship',
'label' => $data[$current_table][$field['field_name']]['title'],
'field_name' => $field['field_name'],
);
// Relationship: add a relationship for revisions.
$data[$revision_table][$column]['relationship'] = array(
'base' => 'scald_atoms',
'field' => $column,
'handler' => 'views_handler_relationship',
'label' => t('Atom reference item revision from !field_name', array(
'!field_name' => $field['field_name'],
)),
'field_name' => $field['field_name'],
);
return $data;
}
/**
* Implements hook_field_validate().
*/
function atom_reference_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
// Ensure that the types of the referenced atoms match the one of those
// that were defined in the field configuration.
$types = atom_reference_field_referenceable_types($instance);
foreach ($items as $delta => $item) {
if (empty($item['sid'])) {
continue;
}
$atom = scald_fetch($item['sid']);
if (!isset($types[$atom->type]) || empty($types[$atom->type])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'atom_reference_bad_type',
'message' => t("Atom %title is of type %type, which can't be referenced in field %field", array(
'%title' => $atom->title,
'%type' => $atom->type,
'%field' => $instance['label'],
)),
);
}
}
}
/**
* Implements hook_field_presave().
*/
function atom_reference_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach ($items as $delta => $item) {
if (empty($item['sid'])) {
continue;
}
$options = array();
if (!empty($item['options'])) {
$options = unserialize($item['options']);
}
foreach ($item as $name => $option) {
if ($name == 'sid' || $name == 'options') {
continue;
}
if (!empty($item[$name])) {
$options[$name] = $option;
}
else {
unset($options[$name]);
}
}
$items[$delta]['options'] = serialize($options);
}
}
/**
* Implements hook_field_is_empty().
*/
function atom_reference_field_is_empty($item, $field) {
return empty($item['sid']);
}
/**
* Implements hook_field_formatter_info().
*/
function atom_reference_field_formatter_info() {
// Expose all the Scald Contexts as formatters for the Atom Reference field.
$formatters = array();
$contexts = scald_contexts_public();
foreach ($contexts as $name => $context) {
$formatters[$name] = array(
'label' => $context['title'],
'field types' => array(
'atom_reference',
),
'settings' => array(
'link' => 0,
'override' => 0,
),
);
}
return $formatters;
}
/**
* Implements hook_field_formatter_settings_form().
*/
function atom_reference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
$element['link'] = array(
'#title' => t('Link to content'),
'#type' => 'select',
'#default_value' => $settings['link'],
'#options' => array(
'no',
'yes',
),
);
if (isset($instance['settings']['allow_override']) && $instance['settings']['allow_override']) {
$element['override'] = array(
'#title' => t('Allow context override'),
'#type' => 'checkbox',
'#default_value' => $settings['override'],
);
}
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function atom_reference_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$link = empty($settings['link']) ? t('No') : t('Yes');
$summary = t('Link to content: @choice', array(
'@choice' => $link,
));
return $summary;
}
/**
* Implements hook_field_formatter_view.
*/
function atom_reference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$render_context = $display['type'];
$contexts = scald_contexts();
$element = array();
$uri = false;
// Check if the formatter involves a link.
if ($display['settings']['link']) {
$uri = entity_uri($entity_type, $entity);
}
if (!empty($contexts[$render_context])) {
foreach ($items as $delta => $item) {
$options = array();
if (!empty($item['options'])) {
$options += unserialize($item['options']);
}
$context = $render_context;
if (isset($display['settings']['override']) && $display['settings']['override'] && !empty($options['context']) && $options['context'] !== 'use_the_default') {
$context = $options['context'];
}
$sid = $item['sid'];
if ($uri) {
$options['link'] = $uri['path'];
}
$element[$delta] = array(
'#markup' => scald_render($sid, $context, drupal_json_encode($options)),
);
}
}
return $element;
}
/**
* Implements hook_field_widget_info.
*/
function atom_reference_field_widget_info() {
return array(
'atom_reference_textfield' => array(
'label' => t('Drop box'),
'field types' => array(
'atom_reference',
),
'settings' => array(
'context' => 'sdl_editor_representation',
),
),
);
}
/**
* Implements hook_field_widget_settings_form.
*/
function atom_reference_field_widget_settings_form($field, $instance) {
$preview_context = isset($instance['widget']['settings']['context']) ? $instance['widget']['settings']['context'] : variable_get('dnd_context_default', 'sdl_editor_representation');
$form['context'] = array(
'#type' => 'select',
'#title' => t('Preview context'),
'#options' => array(),
'#default_value' => $preview_context,
'#description' => t('Scald preview context to be displayed in the edit form.'),
);
$contexts = scald_contexts_public();
foreach ($contexts as $name => $context) {
// TODO: Atom reference shouldn't need the context to be parsable, there's
// nothing converting back and forth between the SAS and the rendered
// representation.
if (!empty($context['parseable'])) {
$form['context']['#options'][$name] = $context['title'];
}
}
return $form;
}
/**
* Implements hook_field_widget_form.
*/
function atom_reference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$all = scald_types();
$options = array();
$types = atom_reference_field_referenceable_types($instance);
foreach ($types as $name => $value) {
if ($value && isset($all[$name])) {
$options[$name] = $all[$name]->title;
}
}
$help = format_plural(count($options), 'Allowed resource format: %types', 'Allowed resource formats: %types', array(
'%types' => implode(', ', $options),
));
$preview_context = $instance['widget']['settings']['context'];
$element['#description'] .= ' ' . $help;
$element['#type'] = 'textfield';
$element['#attributes'] = array(
'data-types' => implode(',', array_keys($options)),
'data-dnd-context' => $preview_context,
);
$element['#default_value'] = isset($items[$delta]) ? $items[$delta]['sid'] : '';
$element['#preview_context'] = $preview_context;
$element['#process'][] = 'atom_reference_field_widget_form_process';
$element['#attached'] = array(
'library' => array(
array(
'atom_reference',
'library',
),
),
);
$options = array();
if (!empty($items[$delta]['options'])) {
$options = unserialize($items[$delta]['options']);
}
$return = array(
'sid' => $element,
);
if (isset($instance['settings']['allow_override']) && $instance['settings']['allow_override']) {
$rendering_context = 'use_the_default';
if (!empty($options['context'])) {
$rendering_context = $options['context'];
}
$context_element = array(
'#type' => 'select',
'#title' => t('Representation context'),
'#attributes' => array(
'class' => array(
'context-select',
),
),
'#options' => array(),
'#default_value' => $rendering_context,
'#description' => t('Scald rendering context used in field display.'),
);
$context_element['#weight'] = 20;
$contexts = scald_contexts_public();
$context_element['#options']['use_the_default'] = t('Use the default');
foreach ($contexts as $name => $context) {
if ($name !== 'sdl_library_item') {
$context_element['#options'][$name] = $context['title'];
}
}
$return['context'] = $context_element;
}
return $return;
}
/**
* Atom types that are allowed to be referenced in that field instance.
*/
function atom_reference_field_referenceable_types($instance) {
$types = $instance['settings']['referencable_types'];
$all = scald_types();
// All types are allowed if no type is explicitely selected (default setting).
if (!array_filter($types)) {
$types = array_fill_keys(array_keys($all), '1');
}
return $types;
}
/**
* Process the Atom Reference widget element.
*
* Add either the atom reference representation or the placeholder
* on the fly, depending on the field being filled.
*/
function atom_reference_field_widget_form_process(&$element) {
// Get the default value, rendering context and format the placeholder accordingly.
$preview_context = variable_get('dnd_context_default', 'sdl_editor_representation');
if (isset($element['#preview_context'])) {
$preview_context = $element['#preview_context'];
}
$default = $element['#value'];
if ($default) {
$prefix = '<div class="atom_reference_drop_zone" data-rendering-context="' . $preview_context . '">' . scald_render($default, $preview_context) . '</div>';
}
else {
$placeholder = t('Drop a resource from Scald media library here.');
$prefix = '<div class="atom_reference_drop_zone" data-rendering-context="' . $preview_context . '"><em>' . $placeholder . '</em></div>';
}
$element['#field_prefix'] = $prefix;
if (isset($element['#entity_type']) && module_exists('i18n_field')) {
$instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
$translated_label = i18n_field_translate_property($instance, 'label');
$element['#title'] = $translated_label;
}
return $element;
}
/**
* Implements hook_field_widget_error.
*/
function atom_reference_field_widget_error($element, $error, $form, &$form_state) {
$name = implode('][', $element['sid']['#array_parents']);
form_set_error($name, $error['message']);
}
/**
* Provide default field comparison options.
*/
function atom_reference_field_diff_default_options($field_type) {
return array(
'show_id' => 0,
'show_type' => 1,
'entity_title' => 'Atom',
);
}
/**
* Provide a form for setting the field comparison options.
*/
function atom_reference_field_diff_options_form($field_type, $settings) {
$options_form = array();
$options_form['show_id'] = array(
'#type' => 'checkbox',
'#title' => t('Show atom id'),
'#default_value' => $settings['show_id'],
);
$options_form['show_type'] = array(
'#type' => 'checkbox',
'#title' => t('Show atom type'),
'#default_value' => $settings['show_type'],
);
$options_form['entity_title'] = array(
'#type' => 'textfield',
'#title' => t('The title to use for the atom entity'),
'#default_value' => $settings['entity_title'],
'#description' => t('This can be useful if you call Atoms differently on your website, such as Resources.'),
);
return $options_form;
}
/**
* Diff field callback for preloading the scald atom entities.
*/
function atom_reference_field_diff_view_prepare(&$old_items, &$new_items, $context) {
$sids = array();
foreach (array_merge_recursive($old_items, $new_items) as $info) {
$sids[$info['sid']] = $info['sid'];
}
$atoms = scald_atom_load_multiple($sids);
foreach ($old_items as $delta => $info) {
$old_items[$delta]['atom'] = isset($atoms[$info['sid']]) ? $atoms[$info['sid']] : NULL;
}
foreach ($new_items as $delta => $info) {
$new_items[$delta]['atom'] = isset($atoms[$info['sid']]) ? $atoms[$info['sid']] : NULL;
}
}
/**
* Diff field callback for parsing atom_reference field comparative values.
*/
function atom_reference_field_diff_view($items, $context) {
$instance = $context['instance'];
$settings = $context['settings'];
$diff_items = array();
foreach ($items as $delta => $item) {
if (!isset($item['atom'])) {
continue;
}
$diff_items[$delta] = $item['atom']->title;
if ($settings['show_id'] || $settings['show_type']) {
$diff_items[$delta] .= ' (';
}
if ($settings['show_type']) {
$diff_items[$delta] .= t('!type', array(
'!type' => ucfirst($item['atom']->type),
));
}
if ($settings['show_id']) {
if ($settings['show_type']) {
$diff_items[$delta] .= ', ';
}
$diff_items[$delta] .= t('@entity_name ID: !id', array(
'@entity_name' => $settings['entity_title'],
'!id' => $item['atom']->sid,
));
}
if ($settings['show_id'] || $settings['show_type']) {
$diff_items[$delta] .= ')';
}
}
return $diff_items;
}