bat_calendar_reference.module in Booking and Availability Management Tools for Drupal 7
Same filename and directory in other branches
Defines a field type for referencing event information.
File
modules/bat_calendar_reference/bat_calendar_reference.moduleView source
<?php
/**
* @file
* Defines a field type for referencing event information.
*/
/**
* Implements hook_permission().
*/
function bat_calendar_reference_permission() {
$permissions = array(
'reference unit calendar events' => array(
'title' => t('Reference unit calendar events'),
'description' => t('Allows users to embed events information in other nodes.'),
),
);
return $permissions;
}
/**
* Implements hook_menu().
*/
function bat_calendar_reference_menu() {
$items['bat_calendar_reference/autocomplete/units/%/%/%'] = array(
'page callback' => 'bat_calendar_reference_units_autocomplete',
'page arguments' => array(
3,
4,
5,
),
'access arguments' => array(
'reference unit calendar events',
),
'type' => MENU_CALLBACK,
);
$items['bat_calendar_reference/autocomplete/unit_types/%/%/%'] = array(
'page callback' => 'bat_calendar_reference_unit_types_autocomplete',
'page arguments' => array(
3,
4,
5,
),
'access arguments' => array(
'reference unit calendar events',
),
'type' => MENU_CALLBACK,
);
$items['bat_calendar_reference/autocomplete/event_types/%/%/%'] = array(
'page callback' => 'bat_calendar_reference_event_types_autocomplete',
'page arguments' => array(
3,
4,
5,
),
'access arguments' => array(
'reference unit calendar events',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_field_info().
*/
function bat_calendar_reference_field_info() {
return array(
'bat_calendar_unit_reference' => array(
'label' => t('BAT Calendar Unit Reference'),
'description' => t('Display unit events information embedded from other fieldable content.'),
'settings' => array(
'referenceable_unit_types' => array(),
),
'default_widget' => 'bat_calendar_reference_unit_autocomplete',
'default_formatter' => 'bat_calendar_reference_timeline_view',
),
'bat_calendar_unit_type_reference' => array(
'label' => t('BAT Calendar Unit Type Reference'),
'description' => t('Display unit type events information embedded from other fieldable content.'),
'settings' => array(),
'default_widget' => 'bat_calendar_reference_unit_type_autocomplete',
'default_formatter' => 'bat_calendar_reference_timeline_view',
),
);
}
/**
* Implements hook_field_is_empty().
*/
function bat_calendar_reference_field_is_empty($item, $field) {
if ($field['type'] == 'bat_calendar_unit_reference') {
return empty($item['unit_id']);
}
elseif ($field['type'] == 'bat_calendar_unit_type_reference') {
return empty($item['unit_type_id']);
}
}
/**
* Implements hook_field_formatter_info().
*/
function bat_calendar_reference_field_formatter_info() {
$ret = array(
'bat_calendar_reference_month_view' => array(
'label' => t('Month View'),
'description' => t('Displays event information on a calendar.'),
'field types' => array(
'bat_calendar_unit_reference',
'bat_calendar_unit_type_reference',
'entityreference',
),
),
'bat_calendar_reference_timeline_view' => array(
'label' => t('Timeline View'),
'description' => t('Displays event information on a calendar.'),
'field types' => array(
'bat_calendar_unit_reference',
'bat_calendar_unit_type_reference',
'entityreference',
),
),
);
return $ret;
}
/**
* Implements hook_field_formatter_prepare_view().
*/
function bat_calendar_reference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
if ($field['type'] == 'entityreference') {
entityreference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, $items, $displays);
}
}
/**
* Implements hook_field_formatter_view().
*/
function bat_calendar_reference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$fc_user_settings = array();
$header = '';
$calendar_id = drupal_html_id($field['field_name'] . '-calendar-formatter');
switch ($display['type']) {
case 'bat_calendar_reference_timeline_view':
case 'bat_calendar_reference_month_view':
if ($field['type'] == 'bat_calendar_unit_type_reference') {
$unit_type_names = array();
$unit_type_ids = array();
foreach ($items as $delta => $item) {
if ($unit_type = bat_type_load($item['unit_type_id'])) {
$unit_type_names[] = $unit_type->name;
$unit_type_ids[] = $unit_type->type_id;
}
if ($type = bat_event_type_load($item['event_type_id'])) {
$event_type = $type->type;
$event_granularity = $type->event_granularity;
}
}
if (!empty($unit_type_ids)) {
$header = '<div class="calendar-title"><h2>' . implode(', ', $unit_type_names) . '</h2></div>';
// Inject settings in javascript that we will use.
$fc_user_settings[$calendar_id] = array(
'unitTypes' => $unit_type_ids,
'unitIDs' => '',
'eventType' => $event_type,
'calendar_id' => 'fullcalendar-scheduler',
'modal_style' => 'default',
'eventGranularity' => $event_granularity,
'editable' => FALSE,
'selectable' => FALSE,
'eventStartEditable' => FALSE,
'background' => '1',
);
if ($display['type'] == 'bat_calendar_reference_month_view') {
$fc_user_settings[$calendar_id]['defaultView'] = 'month';
$fc_user_settings[$calendar_id]['views'] = 'month';
$fc_user_settings[$calendar_id]['background'] = '0';
$fc_user_settings[$calendar_id]['headerLeft'] = 'today';
$fc_user_settings[$calendar_id]['headerCenter'] = 'title';
$fc_user_settings[$calendar_id]['headerRight'] = 'prev, next';
}
}
}
elseif ($field['type'] == 'bat_calendar_unit_reference') {
$unit_names = array();
$unit_ids = array();
foreach ($items as $delta => $item) {
if ($unit = bat_unit_load($item['unit_id'])) {
$unit_names[] = $unit->name;
$unit_ids[] = $unit->unit_id;
}
if ($type = bat_event_type_load($item['event_type_id'])) {
$event_type = $type->type;
$event_granularity = $type->event_granularity;
}
}
if (!empty($unit_ids)) {
$header = '<div class="calendar-title"><h2>' . implode(', ', $unit_names) . '</h2></div>';
// Inject settings in javascript that we will use.
$fc_user_settings[$calendar_id] = array(
'unitTypes' => 'all',
'unitIDs' => $unit_ids,
'eventType' => $event_type,
'calendar_id' => 'fullcalendar-scheduler',
'modal_style' => 'default',
'eventGranularity' => $event_granularity,
'editable' => FALSE,
'selectable' => FALSE,
'eventStartEditable' => FALSE,
'background' => '1',
);
if ($display['type'] == 'bat_calendar_reference_month_view') {
$fc_user_settings[$calendar_id]['defaultView'] = 'month';
$fc_user_settings[$calendar_id]['views'] = 'month';
$fc_user_settings[$calendar_id]['background'] = '0';
$fc_user_settings[$calendar_id]['headerLeft'] = 'today';
$fc_user_settings[$calendar_id]['headerCenter'] = 'title';
$fc_user_settings[$calendar_id]['headerRight'] = 'prev, next';
}
}
}
break;
}
if (!empty($fc_user_settings)) {
$calendar_settings = array(
'modal_style' => 'default',
'calendar_id' => 'fullcalendar-scheduler',
'user_settings' => array(
'batCalendar' => $fc_user_settings,
),
);
$element[] = array(
'#theme' => 'bat_fullcalendar',
'#calendar_settings' => $calendar_settings,
'#js_files' => array(
drupal_get_path('module', 'bat_calendar_reference') . '/js/bat_calendar_reference.js',
),
'#css_files' => array(
drupal_get_path('module', 'bat_fullcalendar') . '/css/bat_fullcalendar_timeline.css',
drupal_get_path('module', 'bat_fullcalendar') . '/css/fullcalendar.theme.css',
),
'#attributes' => array(
'id' => $calendar_id,
'class' => array(
'cal',
'clearfix',
),
),
'#prefix' => $header,
);
}
return $element;
}
/**
* Implements hook_field_settings_form().
*/
function bat_calendar_reference_field_settings_form($field, $instance, $has_data) {
$settings = $field['settings'];
$form = array();
if ($field['type'] == 'bat_calendar_unit_reference') {
$form['referenceable_unit_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Unit types that can be referenced'),
'#multiple' => TRUE,
'#default_value' => isset($settings['referenceable_unit_types']) ? $settings['referenceable_unit_types'] : array(),
'#options' => array_map('check_plain', bat_unit_types_ids()),
);
}
$form['referenceable_event_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Event types that can be referenced'),
'#multiple' => TRUE,
'#default_value' => isset($settings['referenceable_event_types']) ? $settings['referenceable_event_types'] : array(),
'#options' => array_map('check_plain', bat_event_types_ids()),
);
return $form;
}
/**
* Implements hook_field_validate().
*/
function bat_calendar_reference_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
// Check for non-numeric values.
foreach ($items as $delta => $item) {
if (is_array($item)) {
if (!empty($item['unit_id'])) {
if (!is_numeric($item['unit_id'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'invalid_unit',
'message' => t('%name: invalid input.', array(
'%name' => $instance['label'],
)),
);
}
}
if (!empty($item['unit_type_id'])) {
if (!is_numeric($item['unit_type_id'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'invalid_unit_type',
'message' => t('%name: invalid input.', array(
'%name' => $instance['label'],
)),
);
}
}
if (!empty($item['event_type_id'])) {
if (!is_numeric($item['event_type_id'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'invalid_event_type',
'message' => t('%name: invalid input.', array(
'%name' => $instance['label'],
)),
);
}
}
}
}
}
/**
* Retrieves an array of candidate referenceable booking units.
*
* @param array $field
* The field definition.
* @param array $options
* An array of options to limit the scope of the returned list. The following
* key/value pairs are accepted:
* - string: string to filter unit names on (used by autocomplete).
* - match: operator to match the above string against, can be any of:
* 'contains', 'equals', 'starts_with'. Defaults to 'contains'.
* - ids: array of specific unit ids to lookup.
* - limit: maximum size of the the result set. Defaults to 0 (no limit).
*
* @return array
* An array of valid units in the form:
* array(
* unit_id => array(
* 'name' => The unit title,
* 'rendered' => The text to display in widgets (can be HTML)
* ),
* ...
* )
*/
function bat_calendar_reference_units_potential_references($field, $options = array()) {
// Fill in default options.
$options += array(
'string' => '',
'match' => 'contains',
'ids' => array(),
'limit' => 0,
);
$results =& drupal_static(__FUNCTION__, array());
// Create unique id for static cache.
$cid = $field['field_name'] . ':' . $options['match'] . ':' . ($options['string'] !== '' ? $options['string'] : implode('-', $options['ids'])) . ':' . $options['limit'];
if (!isset($results[$cid])) {
$references = FALSE;
if ($references === FALSE) {
$references = _bat_calendar_reference_units_potential_references($field, $options);
}
// Store the results.
$results[$cid] = !empty($references) ? $references : array();
}
return $results[$cid];
}
/**
* @param array $field
* @param array $options
*
* @return array
*/
function _bat_calendar_reference_units_potential_references($field, $options) {
// Avoid useless work.
if (!isset($field['settings']['referenceable_unit_types'])) {
return array();
}
if (!count($field['settings']['referenceable_unit_types'])) {
return array();
}
$query = db_select('bat_units', 'u');
$unit_unit_id_alias = $query
->addField('u', 'unit_id');
$unit_name_alias = $query
->addField('u', 'name', 'name');
$unit_type_alias = $query
->addField('u', 'type', 'type');
if (is_array($field['settings']['referenceable_unit_types'])) {
$referenceable_unit_types = array_filter($field['settings']['referenceable_unit_types']);
if (!empty($referenceable_unit_types)) {
$query
->condition('u.type_id', array_filter($field['settings']['referenceable_unit_types']), 'IN');
}
}
if ($options['string'] !== '') {
switch ($options['match']) {
case 'contains':
$query
->condition('u.name', '%' . $options['string'] . '%', 'LIKE');
break;
case 'starts_with':
$query
->condition('u.name', $options['string'] . '%', 'LIKE');
break;
case 'equals':
default:
// No match type or incorrect match type: use "=".
$query
->condition('u.name', $options['string']);
break;
}
}
if ($options['ids']) {
$query
->condition('u.unit_id', $options['ids'], 'IN');
}
if ($options['limit']) {
$query
->range(0, $options['limit']);
}
$query
->orderBy($unit_name_alias)
->orderBy($unit_type_alias);
$result = $query
->execute()
->fetchAll();
$references = array();
foreach ($result as $unit) {
$references[$unit->unit_id] = array(
'title' => $unit->name,
'rendered' => check_plain($unit->name),
);
}
return $references;
}
/**
* @param array $field
* @param array $options
*
* @return array
*/
function bat_calendar_reference_event_types_potential_references($field, $options = array()) {
// Fill in default options.
$options += array(
'string' => '',
'match' => 'contains',
'ids' => array(),
'limit' => 0,
);
$results =& drupal_static(__FUNCTION__, array());
// Create unique id for static cache.
$cid = $field['field_name'] . ':' . $options['match'] . ':' . ($options['string'] !== '' ? $options['string'] : implode('-', $options['ids'])) . ':' . $options['limit'];
if (!isset($results[$cid])) {
$references = FALSE;
if ($references === FALSE) {
$references = _bat_calendar_reference_event_types_potential_references($field, $options);
}
// Store the results.
$results[$cid] = !empty($references) ? $references : array();
}
return $results[$cid];
}
/**
* @param array $field
* @param array $options
*
* @return array
*/
function _bat_calendar_reference_event_types_potential_references($field, $options) {
// Avoid useless work.
if (!isset($field['settings']['referenceable_event_types'])) {
return array();
}
if (!count($field['settings']['referenceable_event_types'])) {
return array();
}
$query = db_select('bat_event_type', 'u');
$unit_unit_id_alias = $query
->addField('u', 'id');
$event_type_label_alias = $query
->addField('u', 'label', 'label');
if (is_array($field['settings']['referenceable_event_types'])) {
$referenceable_event_types = array_filter($field['settings']['referenceable_event_types']);
if (!empty($referenceable_event_types)) {
$query
->condition('u.id', array_filter($field['settings']['referenceable_event_types']), 'IN');
}
}
if ($options['string'] !== '') {
switch ($options['match']) {
case 'contains':
$query
->condition('u.label', '%' . $options['string'] . '%', 'LIKE');
break;
case 'starts_with':
$query
->condition('u.label', $options['string'] . '%', 'LIKE');
break;
case 'equals':
default:
// No match type or incorrect match type: use "=".
$query
->condition('u.label', $options['string']);
break;
}
}
if ($options['limit']) {
$query
->range(0, $options['limit']);
}
$query
->orderBy($event_type_label_alias);
$result = $query
->execute()
->fetchAll();
$references = array();
foreach ($result as $event_type) {
$references[$event_type->id] = array(
'title' => $event_type->label,
'rendered' => check_plain($event_type->label),
);
}
return $references;
}
/**
* @param array $field
* @param array $options
*
* @return array
*/
function bat_calendar_reference_unit_types_potential_references($field, $options = array()) {
// Fill in default options.
$options += array(
'string' => '',
'match' => 'contains',
'ids' => array(),
'limit' => 0,
);
$results =& drupal_static(__FUNCTION__, array());
// Create unique id for static cache.
$cid = $field['field_name'] . ':' . $options['match'] . ':' . ($options['string'] !== '' ? $options['string'] : implode('-', $options['ids'])) . ':' . $options['limit'];
if (!isset($results[$cid])) {
$references = FALSE;
if ($references === FALSE) {
$references = _bat_calendar_reference_unit_types_potential_references($field, $options);
}
// Store the results.
$results[$cid] = !empty($references) ? $references : array();
}
return $results[$cid];
}
/**
* @param array $field
* @param array $options
*
* @return array
*/
function _bat_calendar_reference_unit_types_potential_references($field, $options) {
$query = db_select('bat_types', 'u');
$unit_unit_id_alias = $query
->addField('u', 'type_id');
$type_name_alias = $query
->addField('u', 'name', 'name');
if ($options['string'] !== '') {
switch ($options['match']) {
case 'contains':
$query
->condition('u.name', '%' . $options['string'] . '%', 'LIKE');
break;
case 'starts_with':
$query
->condition('u.name', $options['string'] . '%', 'LIKE');
break;
case 'equals':
default:
// No match type or incorrect match type: use "=".
$query
->condition('u.name', $options['string']);
break;
}
}
if ($options['limit']) {
$query
->range(0, $options['limit']);
}
$query
->orderBy($type_name_alias);
$result = $query
->execute()
->fetchAll();
$references = array();
foreach ($result as $unit_type) {
$references[$unit_type->type_id] = array(
'title' => $unit_type->name,
'rendered' => check_plain($unit_type->name),
);
}
return $references;
}
/**
* Menu callback for the units autocomplete results.
*/
function bat_calendar_reference_units_autocomplete($entity_type, $bundle, $field_name, $string = '') {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle);
$options = array(
'string' => $string,
'match' => $instance['widget']['settings']['autocomplete_match'],
'limit' => 10,
);
$references = bat_calendar_reference_units_potential_references($field, $options);
$matches = array();
foreach ($references as $id => $row) {
// Markup is fine in autocompletion results (might happen when rendered
// through Views) but we want to remove hyperlinks.
$suggestion = preg_replace('/<a href="([^<]*)">([^<]*)<\\/a>/', '$2', $row['rendered']);
// Add a class wrapper for a few required CSS overrides.
$matches[$row['title'] . " [unit_id:{$id}]"] = '<div class="reference-autocomplete">' . $suggestion . '</div>';
}
drupal_json_output($matches);
}
/**
* Menu callback for the unit types autocomplete results.
*/
function bat_calendar_reference_unit_types_autocomplete($entity_type, $bundle, $field_name, $string = '') {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle);
$options = array(
'string' => $string,
'match' => $instance['widget']['settings']['autocomplete_match'],
'limit' => 10,
);
$references = bat_calendar_reference_unit_types_potential_references($field, $options);
$matches = array();
foreach ($references as $id => $row) {
// Markup is fine in autocompletion results (might happen when rendered
// through Views) but we want to remove hyperlinks.
$suggestion = preg_replace('/<a href="([^<]*)">([^<]*)<\\/a>/', '$2', $row['rendered']);
// Add a class wrapper for a few required CSS overrides.
$matches[$row['title'] . " [type_id:{$id}]"] = '<div class="reference-autocomplete">' . $suggestion . '</div>';
}
drupal_json_output($matches);
}
/**
* Menu callback for the event types autocomplete results.
*/
function bat_calendar_reference_event_types_autocomplete($entity_type, $bundle, $field_name, $string = '') {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle);
$options = array(
'string' => $string,
'match' => $instance['widget']['settings']['autocomplete_match'],
'limit' => 10,
);
$references = bat_calendar_reference_event_types_potential_references($field, $options);
$matches = array();
foreach ($references as $id => $row) {
// Markup is fine in autocompletion results (might happen when rendered
// through Views) but we want to remove hyperlinks.
$suggestion = preg_replace('/<a href="([^<]*)">([^<]*)<\\/a>/', '$2', $row['rendered']);
// Add a class wrapper for a few required CSS overrides.
$matches[$row['title'] . " [event_type_id:{$id}]"] = '<div class="reference-autocomplete">' . $suggestion . '</div>';
}
drupal_json_output($matches);
}
/**
* Implements hook_field_widget_info().
*/
function bat_calendar_reference_field_widget_info() {
return array(
'bat_calendar_reference_unit_autocomplete' => array(
'label' => t('Calendar Unit reference'),
'description' => t('Display the list of referenceable units and event types as a textfield with autocomplete behaviour.'),
'field types' => array(
'bat_calendar_unit_reference',
),
'settings' => array(
'autocomplete_match' => 'contains',
),
),
'bat_calendar_reference_unit_type_autocomplete' => array(
'label' => t('Calendar Unit type reference'),
'description' => t('Display the list of referenceable units and event types as a textfield with autocomplete behaviour.'),
'field types' => array(
'bat_calendar_unit_type_reference',
),
'settings' => array(
'autocomplete_match' => 'contains',
),
),
);
}
/**
* Implements hook_field_widget_form().
*/
function bat_calendar_reference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$widget = array(
'#theme_wrappers' => array(
'container',
'form_element',
),
'#attributes' => array(
'class' => array(
'container-inline',
),
),
);
switch ($instance['widget']['type']) {
case 'bat_calendar_reference_unit_autocomplete':
$widget['unit_id'] = array(
'#type' => 'textfield',
'#title' => t('Unit'),
'#default_value' => isset($items[$delta]['unit_id']) ? $items[$delta]['unit_id'] : NULL,
'#autocomplete_path' => 'bat_calendar_reference/autocomplete/units/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
'#size' => 60,
'#maxlength' => 255,
'#element_validate' => array(
'bat_calendar_reference_autocomplete_unit_validate',
),
'#value_callback' => 'bat_calendar_reference_unit_autocomplete_value',
);
$widget['event_type_id'] = array(
'#type' => 'textfield',
'#title' => t('Event type'),
'#default_value' => isset($items[$delta]['event_type_id']) ? $items[$delta]['event_type_id'] : NULL,
'#autocomplete_path' => 'bat_calendar_reference/autocomplete/event_types/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
'#size' => 60,
'#maxlength' => 255,
'#element_validate' => array(
'bat_calendar_reference_autocomplete_event_type_validate',
),
'#value_callback' => 'bat_calendar_reference_event_type_autocomplete_value',
);
break;
case 'bat_calendar_reference_unit_type_autocomplete':
$widget['unit_type_id'] = array(
'#type' => 'textfield',
'#title' => t('Unit type'),
'#default_value' => isset($items[$delta]['unit_type_id']) ? $items[$delta]['unit_type_id'] : NULL,
'#autocomplete_path' => 'bat_calendar_reference/autocomplete/unit_types/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
'#size' => 60,
'#maxlength' => 255,
'#element_validate' => array(
'bat_calendar_reference_autocomplete_unit_type_validate',
),
'#value_callback' => 'bat_calendar_reference_unit_type_autocomplete_value',
);
$widget['event_type_id'] = array(
'#type' => 'textfield',
'#title' => t('Event type'),
'#default_value' => isset($items[$delta]['event_type_id']) ? $items[$delta]['event_type_id'] : NULL,
'#autocomplete_path' => 'bat_calendar_reference/autocomplete/event_types/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
'#size' => 60,
'#maxlength' => 255,
'#element_validate' => array(
'bat_calendar_reference_autocomplete_event_type_validate',
),
'#value_callback' => 'bat_calendar_reference_event_type_autocomplete_value',
);
break;
}
return $element + $widget;
}
/**
* Value callback for a bat_calendar_reference autocomplete element.
*
* Replace the unit id with a unit name.
*/
function bat_calendar_reference_unit_autocomplete_value($element, $input = FALSE, $form_state = array()) {
if ($input === FALSE) {
$unit_id = $element['#default_value'];
if (!empty($unit_id)) {
if ($unit = bat_unit_load($unit_id)) {
$value = $unit->name;
$value .= ' [unit_id:' . $unit_id . ']';
return $value;
}
else {
return '';
}
}
}
}
/**
* Value callback for a bat_calendar_reference autocomplete element.
*
* Replace the unit type id with a unit type name.
*/
function bat_calendar_reference_unit_type_autocomplete_value($element, $input = FALSE, $form_state = array()) {
if ($input === FALSE) {
$type_id = $element['#default_value'];
if (!empty($type_id)) {
if ($unit_type = bat_type_load($type_id)) {
$value = $unit_type->name;
$value .= ' [type_id:' . $type_id . ']';
return $value;
}
else {
return '';
}
}
}
}
/**
* Value callback for a bat_calendar_reference autocomplete element.
*
* Replace the event type id with a event type label.
*/
function bat_calendar_reference_event_type_autocomplete_value($element, $input = FALSE, $form_state = array()) {
if ($input === FALSE) {
$event_type = $element['#default_value'];
if (!empty($event_type)) {
if ($type = bat_event_type_load($event_type)) {
$value = $type->label;
$value .= ' [event_type_id:' . $event_type . ']';
return $value;
}
else {
return '';
}
}
}
}
/**
* Validate unit.
*/
function bat_calendar_reference_autocomplete_unit_validate($element, &$form_state, $form) {
$parents = $element['#array_parents'];
array_pop($parents);
$field_widget = drupal_array_get_nested_value($form, $parents);
$field = field_widget_field($field_widget, $form_state);
$instance = field_widget_instance($field_widget, $form_state);
$value = $element['#value'];
$unit_id = NULL;
if (!empty($value)) {
// Check whether we have an explicit "[unit_id:n]" input.
preg_match('/^(?:\\s*|(.*) )?\\[\\s*unit_id\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
if (!empty($matches)) {
list(, $title, $unit_id) = $matches;
if (!empty($title)) {
$unit = bat_unit_load($unit_id);
$real_title = $unit->name;
if (trim($title) != trim($real_title)) {
form_error($element, t('%name: title mismatch. Please check your selection.', array(
'%name' => $instance['label'],
)));
}
}
}
else {
$options = array(
'string' => $value,
'match' => 'equals',
'limit' => 1,
);
$references = bat_calendar_reference_units_potential_references($field, $options);
if ($references) {
$unit_id = key($references);
}
else {
form_error($element, t('%name: unable to find a unit with that title.', array(
'%name' => $instance['label'],
)));
}
}
}
form_set_value($element, $unit_id, $form_state);
}
/**
* Validate unit type.
*/
function bat_calendar_reference_autocomplete_unit_type_validate($element, &$form_state, $form) {
$parents = $element['#array_parents'];
array_pop($parents);
$field_widget = drupal_array_get_nested_value($form, $parents);
$field = field_widget_field($field_widget, $form_state);
$instance = field_widget_instance($field_widget, $form_state);
$value = $element['#value'];
$type_id = NULL;
if (!empty($value)) {
// Check whether we have an explicit "[type_id:n]" input.
preg_match('/^(?:\\s*|(.*) )?\\[\\s*type_id\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
if (!empty($matches)) {
list(, $title, $type_id) = $matches;
if (!empty($title)) {
$unit = bat_type_load($type_id);
$real_title = $unit->name;
if (trim($title) != trim($real_title)) {
form_error($element, t('%name: title mismatch. Please check your selection.', array(
'%name' => $instance['label'],
)));
}
}
}
else {
$options = array(
'string' => $value,
'match' => 'equals',
'limit' => 1,
);
$references = bat_calendar_reference_unit_types_potential_references($field, $options);
if ($references) {
$unit_id = key($references);
}
else {
form_error($element, t('%name: unable to find a unit type with that title.', array(
'%name' => $instance['label'],
)));
}
}
}
form_set_value($element, $type_id, $form_state);
}
/**
* Validate event type.
*/
function bat_calendar_reference_autocomplete_event_type_validate($element, &$form_state, $form) {
$parents = $element['#array_parents'];
array_pop($parents);
$field_widget = drupal_array_get_nested_value($form, $parents);
$field = field_widget_field($field_widget, $form_state);
$instance = field_widget_instance($field_widget, $form_state);
$value = $element['#value'];
$type_id = NULL;
if (!empty($value)) {
// Check whether we have an explicit "[event_type_id:n]" input.
preg_match('/^(?:\\s*|(.*) )?\\[\\s*event_type_id\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
if (!empty($matches)) {
list(, $title, $type_id) = $matches;
if (!empty($title)) {
$event_type = bat_event_type_load($type_id);
$real_title = $event_type->label;
if (trim($title) != trim($real_title)) {
form_error($element, t('%name: title mismatch. Please check your selection.', array(
'%name' => $instance['label'],
)));
}
}
}
else {
$options = array(
'string' => $value,
'match' => 'equals',
'limit' => 1,
);
$references = bat_calendar_reference_event_types_potential_references($field, $options);
if ($references) {
$type_id = key($references);
}
else {
form_error($element, t('%name: unable to find an event type with that title.', array(
'%name' => $instance['label'],
)));
}
}
}
form_set_value($element, $type_id, $form_state);
}
/**
* Implements hook_field_widget_error().
*/
function bat_calendar_reference_field_widget_error($element, $error, $form, &$form_state) {
form_error($element['unit_id'], $error['message']);
}