references_dialog.module in References dialog 7
This the main module file.
File
references_dialog.moduleView source
<?php
/**
* @file
* This the main module file.
*/
/**
* Implements hook_menu().
*/
function references_dialog_menu() {
// This redirect callback is used when adding and editing content in
// the overlay. When content is created or edited, we are directed here,
// so we can act properly on entities.
$entity_id = 2;
$entity_type = 3;
$items['references-dialog/redirect/%/%'] = array(
'page callback' => 'references_dialog_redirect_page',
'page arguments' => array(
$entity_id,
$entity_type,
),
'access callback' => 'references_dialog_redirect_access',
'access arguments' => array(
$entity_id,
$entity_type,
),
);
return $items;
}
/**
* Implements hook_theme().
*/
function references_dialog_theme() {
return array(
'references_dialog_page' => array(
'render element' => 'page',
'template' => 'references-dialog-page',
),
'references_dialog_links' => array(
'variables' => array(
'links' => NULL,
),
),
);
}
/**
* Implements hook_element_info().
*/
function references_dialog_element_info() {
$types['references_dialog'] = array(
'#input' => FALSE,
'#after_build' => array(
'references_dialog_build_element',
),
'#attached' => references_dialog_attached(),
);
return $types;
}
/**
* Get everything that needs to be attached in order for the links to work.
*/
function references_dialog_attached() {
$module_patch = drupal_get_path('module', 'references_dialog');
return array(
'js' => array(
$module_patch . '/js/references-dialog.js',
),
'css' => array(
$module_patch . '/css/references-dialog-admin.css',
),
'library' => array(
array(
'system',
'ui.dialog',
),
),
);
}
/**
* Implements hook_element_info_alter().
*/
function references_dialog_element_info_alter(&$info) {
// Add #after_builds to widgets that needs them.
foreach (references_dialog_widgets() as $widget) {
// If this element type is specified as a type that a widget should be
// attached to, go ahead and make it so.
if (isset($info[$widget['element_type']]) && (!isset($info[$widget['element_type']]['#after_build']) || !in_array('references_dialog_process_widget', $info[$widget['element_type']]['#after_build']))) {
$info[$widget['element_type']]['#after_build'][] = 'references_dialog_process_widget';
}
}
}
/**
* Implements hook_admin_paths().
*/
function references_dialog_admin_paths() {
// We only activate admin theme if we use the admin theme
// when editing nodes.
if (variable_get('node_admin_theme', FALSE)) {
return array(
'references-dialog/search/*' => TRUE,
);
}
}
/**
* Get search views attached to a particular field instance.
*
* @param array $instance
* A field instance.
*
* @return array
*/
function references_dialog_field_get_search_views(array $instance) {
$attachable = _references_dialog_get_attachable_name_by_instance($instance);
return references_dialog_get_search_views($attachable);
}
/**
* Provides attachable name by the field instance.
*
* @param array $instance
* Instance data.
*
* @return string
* Attachable has name format "entity_type:field_name:bundle".
*/
function _references_dialog_get_attachable_name_by_instance(array $instance) {
return implode(':', array(
$instance['entity_type'],
$instance['field_name'],
$instance['bundle'],
));
}
/**
* Get all search views that are available for a particular attachable.
*
* @param string $attachable
* The name of the attachable to look for.
*
* @return array
*/
function references_dialog_get_search_views($attachable) {
$search_views =& drupal_static(__FUNCTION__, array());
if (!isset($search_views[$attachable])) {
$search_views[$attachable] = array();
// Get all views that has a references_dialog display.
$results = references_dialog_get_applicable_views();
foreach ($results as $view_name => $result) {
foreach ($result as $display_name => $result_displays) {
foreach ($result_displays['attachables'] as $name => $view_attachable) {
if ($attachable == $view_attachable) {
$search_views[$attachable][$view_name] = $result_displays;
}
}
}
}
}
return $search_views[$attachable];
}
function references_dialog_get_applicable_views() {
$references_dialog_views =& drupal_static(__FUNCTION__, FALSE);
if (!$references_dialog_views) {
$references_dialog_views = cache_get('references_dialog_views');
$references_dialog_views = !empty($references_dialog_views) ? $references_dialog_views->data : FALSE;
}
if (!empty($references_dialog_views)) {
return $references_dialog_views;
}
$references_dialog_views = array();
// Get all references_dialog_views that has a references_dialog display.
$results = views_get_applicable_views('references_dialog display');
foreach ($results as $result) {
list($view, $display) = $result;
if (is_object($view)) {
$references_dialog_views[$view->name][$display] = array(
'display' => $display,
'title' => isset($view->display[$view->current_display]->display_options['title']) ? $view->display[$view->current_display]->display_options['title'] : t('Search'),
'attachables' => $view->display_handler
->get_option('attach'),
);
}
}
cache_set('references_dialog_views', $references_dialog_views);
return $references_dialog_views;
}
/**
* Implements hook_widget_info_alter().
*/
function references_dialog_field_widget_info_alter(array &$info) {
// Adds settings that we need to declare to widgets we are extending.
foreach (references_dialog_widgets() as $widget_name => $widget_info) {
if (isset($info[$widget_name]['settings'])) {
foreach (array_keys($widget_info['operations']) as $operation) {
$info[$widget_name]['settings']['references_dialog_' . $operation] = 0;
// Add search view setting if we have search.
if ($operation == 'search') {
$info[$widget_name]['settings']['references_dialog_search_view'] = '';
}
}
}
}
}
/**
* Get instances appropriate for a search view on a particular entity type.
*
* @param string $entity_type
* Name of the entity type.
*
* @return array
* An array of appropriate instances.
*/
function references_dialog_get_search_view_attachables($entity_type = NULL) {
$attachables = module_invoke_all('references_dialog_search_attachables');
// @todo Add an alter here.
if (isset($entity_type)) {
return $attachables[$entity_type];
}
else {
return $attachables;
}
}
/**
* Get an attachable by name.
*
* @param $entity_type
* The type of entity the attacable is attached to.
* @param $name
* The name of the attachable.
*/
function references_dialog_get_attachable($entity_type, $name) {
$attachables = module_invoke_all('references_dialog_search_attachables');
return $attachables[$entity_type][$name];
}
/**
* Implements hook_references_dialog_search_attachables().
*/
function references_dialog_references_dialog_search_attachables() {
$fields = field_info_fields();
$dialog_widgets = references_dialog_widgets();
$applicable_instances = array();
foreach ($fields as $field_name => $field) {
foreach ($field['bundles'] as $entity_type => $bundles) {
foreach ($bundles as $bundle_name) {
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
$widget_type = $instance['widget']['type'];
if (in_array($widget_type, array_keys($dialog_widgets)) && $instance['widget']['settings']['references_dialog_search']) {
// If the entity type is specified, in the declaration, add it here.
$dialog_widget = $dialog_widgets[$widget_type];
if (isset($dialog_widget['entity_type'])) {
$attachable_type = $dialog_widget['entity_type'];
}
elseif (isset($dialog_widgets[$instance['widget']['type']]['type_callback'])) {
$attachable_type = $dialog_widget['type_callback']($instance, $field);
}
if (isset($attachable_type)) {
$attachable_name = _references_dialog_get_attachable_name_by_instance($instance);
$applicable_instances[$attachable_type][$attachable_name] = array(
'label' => $instance['bundle'] . ': ' . $instance['label'],
'query' => 'references_dialog_field_attachable_query',
'widget' => $dialog_widget,
);
}
}
}
}
}
return $applicable_instances;
}
/**
* This query is used by field referneces dialog attachables.
*
* @param \stdClass $view
* The view to work with.
*/
function references_dialog_field_attachable_query($view) {
list($entity_type, $field_name, $bundle_name) = explode(':', $view->references_dialog['attachable']['name']);
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
$field_info = field_info_field($field_name);
$dialog_widget = references_dialog_widget_load($instance['widget']['type']);
if (isset($dialog_widget['views_query']) && function_exists($dialog_widget['views_query'])) {
$dialog_widget['views_query']($view, $instance, $field_info);
}
}
/**
* Return an array of supported widgets.
*/
function references_dialog_widgets() {
$widgets =& drupal_static(__FUNCTION__);
if ($widgets === NULL) {
$widgets = module_invoke_all('references_dialog_widgets');
drupal_alter('references_dialog_widgets', $widgets);
}
return $widgets;
}
/**
* Load a particular widget.
*
* @param string $widget
* The name of the widget.
*
* @return array
* The widget definition.
*/
function references_dialog_widget_load($widget) {
$widgets = references_dialog_widgets();
return $widgets[$widget];
}
/**
* Implements hook_form_alter().
*/
function references_dialog_form_field_ui_field_edit_form_alter(&$form, $form_state) {
$widgets = references_dialog_widgets();
if (array_key_exists($form['instance']['widget']['type']['#value'], $widgets)) {
$field = $form['#field'];
$instance = field_info_instance($form['instance']['entity_type']['#value'], $form['instance']['field_name']['#value'], $form['instance']['bundle']['#value']);
if (isset($form['instance']['widget']['settings'])) {
$form['instance']['widget']['settings'] += references_dialog_settings_form($field, $instance);
}
else {
$form['instance']['widget']['settings'] = references_dialog_settings_form($field, $instance);
}
}
}
/**
* A widget settings form for our references dialog fields.
*/
function references_dialog_settings_form($field, $instance) {
$widget = $instance['widget'];
$defaults = field_info_widget_settings($widget['type']);
$settings = array_merge($defaults, $widget['settings']);
$dialog_widget = references_dialog_widget_load($widget['type']);
// Add our own additions.
foreach ($dialog_widget['operations'] as $operation => $dialog_settings) {
$form['references_dialog_' . $operation] = array(
'#type' => 'checkbox',
'#title' => check_plain($dialog_settings['title']),
'#default_value' => isset($settings['references_dialog_' . $operation]) ? $settings['references_dialog_' . $operation] : FALSE,
);
}
return $form;
}
/**
* Menu access checker for references_dialog
*/
function references_dialog_search_access($entity_type, $field_name, $bundle_name) {
// @todo make an access check.
return TRUE;
}
/**
* Add our references dialog fields to the existing element
*/
function references_dialog_process_widget(&$element) {
if (!isset($element['#entity_type'])) {
return $element;
}
$field = field_info_field($element['#field_name']);
$instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
$widget_settings = $instance['widget']['settings'];
$widget_type = $instance['widget']['type'];
$widgets = references_dialog_widgets();
// Bail if we don't have anything to do here.
if (!in_array($widget_type, array_keys($widgets))) {
return $element;
}
$dialog_widget = references_dialog_widget_load($widget_type);
// Attach javascript and CSS needed.
$attached = references_dialog_attached();
$element['#attached']['js'][] = $attached['js'][0];
$element['#attached']['js'][] = references_dialog_js_settings($element['#id'], array(
'format' => $dialog_widget['format'],
));
$element['#attached']['css'][] = $attached['css'][0];
$element['#attached']['library'][] = $attached['library'][0];
$dialog_links = array();
foreach ($dialog_widget['operations'] as $operation => $settings) {
if (isset($widget_settings['references_dialog_' . $operation]) && $widget_settings['references_dialog_' . $operation]) {
$links = $settings['function']($element, $widget_settings, $field, $instance);
foreach ($links as $link) {
$link['attributes']['class'][] = $operation . '-dialog';
$dialog_links[] = references_dialog_link($link);
}
}
}
if (count($dialog_links)) {
// We add a div directly into the markup here since we really need it in order
// to make sure the javascript works.
$element['#suffix'] = reference_dialog_links_themed($element['#id'], $dialog_links);
}
return $element;
}
function references_dialog_build_element($element) {
$dialog_links = array();
$element['#attached']['js'][] = references_dialog_js_settings($element['#id'], array(
'format' => $element['#format'],
'target' => $element['#target'],
));
if (isset($element['#operations'])) {
foreach ($element['#operations'] as $operation => $link) {
$link['attributes']['class'][] = $operation . '-dialog';
$dialog_links[] = references_dialog_link($link);
}
}
if (isset($element['#attachable'])) {
$dialog_links = array_merge($dialog_links, references_dialog_get_views_search_links($element['#attachable']));
}
if (count($dialog_links)) {
// We add a div directly into the markup here since we really need it in order
// to make sure the javascript works.
$element['#suffix'] = reference_dialog_links_themed($element['#id'], $dialog_links);
}
return $element;
}
/**
* Provides themed dialog links.
*
* @param $id
* Identifier.
* @param array $dialog_links
* Links.
*
* @return string
* Themed links
*/
function reference_dialog_links_themed($id, $dialog_links) {
$links = theme('references_dialog_links', array(
'links' => $dialog_links,
));
return "<div class='dialog-links {$id}'>{$links}</div>";
}
/**
* Attach necessary info to a link definition.
*/
function references_dialog_link($link) {
if (!isset($link['attributes']['class']) || !in_array('references-dialog-activate', $link['attributes']['class'])) {
$link['attributes']['class'][] = 'references-dialog-activate';
}
return $link;
}
/**
* Javascript settings for the dialog.
*
* @param $id
* Identifier.
* @param array $settings
* Settings to add.
*
* @return array
* Prepared settings array.
*/
function references_dialog_js_settings($id, array $settings) {
if (isset($settings['callback_path'])) {
$settings['callback_path'] = url($settings['callback_path']);
}
return array(
'data' => array(
'ReferencesDialog' => array(
'fields' => array(
$id => $settings,
),
),
),
'type' => 'setting',
);
}
/**
* Process variables for references_dialog_page.
*/
function template_process_references_dialog_page(&$variables) {
// Generate messages last in order to capture as many as possible for the
// current page.
if (!isset($variables['messages'])) {
$variables['messages'] = $variables['page']['#show_messages'] ? theme('status_messages') : '';
}
}
/**
* Implements hook_entity_insert().
*/
function references_dialog_entity_insert($entity, $entity_type) {
// If we are in a dialog, we want to make sure that we redirect to the
// the close dialog page, so that the dialog may be closed.
if (references_dialog_in_dialog() && references_dialog_close_on_submit()) {
references_dialog_close_on_redirect($entity, $entity_type);
}
}
/**
* Implements hook_entity_update().
*/
function references_dialog_entity_update($entity, $entity_type) {
if (references_dialog_in_dialog() && references_dialog_close_on_submit()) {
references_dialog_close_on_redirect($entity, $entity_type);
}
}
/**
* Sets our destination parameter so that the dialog will close itself after
* redirect is completed.
*/
function references_dialog_close_on_redirect($entity, $entity_type) {
$entity_info = entity_get_info($entity_type);
// We use $_GET['destination'] since that overrides anything that happens
// in the form. It is a hack, but it is very effective, since we don't have
// to be worried about getting overrun by other form submit handlers.
$_GET['destination'] = 'references-dialog/redirect/' . $entity->{$entity_info['entity keys']['id']} . '/' . $entity_type . '?references-dialog-close=1&render=references-dialog';
}
/**
* Implements hook_init().
*/
function references_dialog_init() {
if (references_dialog_in_dialog()) {
if (module_exists('admin_menu')) {
module_invoke('admin_menu', 'suppress');
}
drupal_add_css(drupal_get_path('module', 'references_dialog') . '/css/references-dialog-search.css');
}
}
/**
* Menu callback for fetching a search view.
*
* @param $view_name a view to use.
* @param $display_name the display name.
* @param $instance_info information aboutythe current display in a packed form.
*/
function references_dialog_search_view($view_name, $display_name, $attachable) {
$args = func_get_args();
$args = array_slice($args, 3);
$view = views_get_view($view_name);
// Find the entity that matches our base table.
$entities = entity_get_info();
foreach ($entities as $entity_type => $entity_info) {
if ($entity_info['base table'] == $view->base_table) {
break;
}
}
// Add some nice data about our field that the display handler can use.
$view->references_dialog = array(
'attachable' => references_dialog_get_attachable($entity_type, $attachable) + array(
'name' => $attachable,
),
);
return $view
->execute_display($display_name, $args);
}
/**
* Implements hook_hook_info().
*/
function references_dialog_hook_info() {
$hooks['references_dialog_widgets'] = array(
'group' => 'dialog_widgets',
);
return $hooks;
}
function references_dialog_get_field_search_links($element, $widget_settings, $field, $instance) {
// We pack the necessary information for getting a field instance together in the
// url, so that we can retrieve the field instance and attach it to the view
// later on.
$attachable = _references_dialog_get_attachable_name_by_instance($instance);
return references_dialog_get_views_search_links($attachable);
}
/**
* Get all views search links for an instance.
* This function should be used by references dialog widgets that uses
* views for it's search functionality.
* @param type $instance
*/
function references_dialog_get_views_search_links($attachable) {
$applicable_views = references_dialog_get_search_views($attachable);
$links = array();
foreach ($applicable_views as $view_name => $view) {
$links[] = references_dialog_link(array(
'title' => $view['title'],
'href' => 'references-dialog/search/' . $view_name . '/' . $view['display'] . '/' . $attachable,
));
}
return $links;
}
/**
* Implements hook_page_alter().
*/
function references_dialog_page_alter(&$page) {
if (references_dialog_in_dialog()) {
unset($page['page_top']);
unset($page['page_bottom']);
$page['#theme'] = 'references_dialog_page';
}
}
/**
* Check if we are in a references dialog.
* @return boolean if we are in a dialog.
*/
function references_dialog_in_dialog() {
return isset($_GET['render']) && $_GET['render'] == 'references-dialog' || strstr(current_path(), 'references-dialog/search') !== FALSE;
}
/**
* Check if we should close the dialog upon submition.
*/
function references_dialog_close_on_submit() {
return !isset($_GET['closeonsubmit']) || $_GET['closeonsubmit'];
}
/**
* Implements of hook_views_api().
*/
function references_dialog_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'references_dialog') . '/views',
);
}
/**
* Implements of hook_views_plugins().
*/
function references_dialog_views_plugins() {
return array(
'display' => array(
'references_dialog' => array(
'title' => t('Reference dialog Search'),
'admin' => t('References'),
'theme' => 'views_view',
'help' => t('A view that can be used when referencing content.'),
'handler' => 'references_dialog_plugin_display',
'use ajax' => TRUE,
'use pager' => TRUE,
'uses hook menu' => TRUE,
'help topic' => 'references-dialog',
'references_dialog display' => TRUE,
'path' => drupal_get_path('module', 'references_dialog') . '/views',
),
),
);
}
function references_dialog_redirect_access() {
// @todo It is not really a security issue, but we should probably check
// that you can create the content you just created (silly), to access
// this page.
return TRUE;
}
/**
* Page callback for our redirect page.
*/
function references_dialog_redirect_page($entity_id, $entity_type) {
// Get some information about the entity we are dealing with.
$entity = entity_load($entity_type, array(
$entity_id,
));
$entity = reset($entity);
$entity_info = entity_get_info($entity_type);
$entity_id = $entity->{$entity_info['entity keys']['id']};
$entity_title = entity_label($entity_type, $entity);
// Add appropriate javascript that will be used by the parent page to
// fill in the required data.
if (isset($entity_id) && references_dialog_in_dialog() && isset($_GET['references-dialog-close'])) {
drupal_add_js(drupal_get_path('module', 'references_dialog') . '/js/references-dialog-child.js');
drupal_add_js(array(
'ReferencesDialog' => array(
'entity_id' => $entity_id,
'title' => $entity_title,
'entity_type' => $entity_type,
),
), 'setting');
}
return '';
}
/**
* Implements hook_references_dialog_entity_admin_paths().
*/
function references_dialog_references_dialog_entity_admin_paths() {
// We define the add and edit page callbacks for core entities here.
$admin_paths = array(
'node' => array(
'add' => 'node/add/[bundle-sanitized]',
'edit' => 'node/[entity_id]/edit',
),
'taxonomy_term' => array(
'edit' => 'taxonomy/term/[entity_id]/edit',
'add' => 'admin/structure/taxonomy/[bundle]/add',
),
// Dealing with taxonomy vocabularies like this is kind of silly,
// and accessing them is a bit harder since their admin page is accessible
// through their machine name, so we leave it at just adding them for now.
'taxonomy_vocabulary' => array(
'add' => 'admin/structure/taxonomy/add',
),
'comment' => array(
'edit' => 'comment/[entity_id]/edit',
),
'user' => array(
'add' => 'admin/people/create',
'edit' => 'user/[entity_id]/edit',
),
);
// The media module adds an edit callback for media as well.
// Note: this will probably not work until file_entity provides an access
// API, see http://drupal.org/node/1227706
if (module_exists('media')) {
$admin_paths['file'] = array(
'edit' => 'media/[entity_id]/edit',
);
}
// Bean provides add and edit paths for custom entities.
if (module_exists('bean')) {
$admin_paths['bean'] = array(
'add' => 'block/add/[bundle-sanitized]',
'edit' => 'block/[entity_id]/edit',
);
}
return $admin_paths;
}
/**
* Get the admin path (edit/add) page for a particular entity.
*
* @param string $entity_type the entity type
* @param string $op Which operation to perform. Either "edit" or "add".
* @param string $bundle The bundle to use.
* @param mixed $entity The entity to edit. This is only used with the "edit" operation.
*
* @return string The path where the entity can be edited or created.
*/
function references_dialog_get_admin_path($entity_type, $op, $bundle = NULL, $entity = NULL) {
// Let's cache the paths.
$paths =& drupal_static(__FUNCTION__, NULL);
if (!isset($paths)) {
$paths = module_invoke_all('references_dialog_entity_admin_paths');
}
if (isset($paths[$entity_type]) && isset($paths[$entity_type][$op])) {
$path = $paths[$entity_type][$op];
// Create a wrapper, so we can deal with this in a sane way.
$wrapper = entity_metadata_wrapper($entity_type, $entity);
// Replace [entity_id] with the entity id.
if (isset($entity)) {
$path = str_replace('[entity_id]', $wrapper
->getIdentifier(), $path);
}
if (!$bundle) {
$bundle = $wrapper
->getBundle();
}
if ($bundle) {
$path = str_replace('[bundle]', $bundle, $path);
// Some entities (like node) provide a sort of sanitized version.
// This makes sure we support this.
$bundle = strtr($bundle, array(
'_' => '-',
));
$path = str_replace('[bundle-sanitized]', $bundle, $path);
}
return $path;
}
return FALSE;
}
/**
* Theme function for theming the links for opening the references dialog.
*/
function theme_references_dialog_links($variables) {
return theme('links', array(
'links' => $variables['links'],
'attributes' => array(
'class' => array(
'references-dialog-links',
),
),
));
}
/**
* Implements hook_field_widget_info().
*/
function references_dialog_field_widget_info() {
return array(
'references_dialog_term_reference' => array(
'label' => t('Autocomplete term widget for References Dialog'),
'field types' => array(
'taxonomy_term_reference',
),
'settings' => array(
'size' => 60,
'autocomplete_path' => 'taxonomy/autocomplete',
'autocomplete_match' => 'starts_with',
),
),
);
}
/**
* Implements hook_field_widget_settings_form().
*/
function references_dialog_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$defaults = field_info_widget_settings($widget['type']);
$settings = array_merge($defaults, $widget['settings']);
$form = array();
if ($widget['type'] == 'references_dialog_term_reference') {
$form['autocomplete_match'] = [
'#type' => 'select',
'#title' => t('Autocomplete matching'),
'#default_value' => $settings['autocomplete_match'],
'#options' => [
'starts_with' => t('Starts with'),
'contains' => t('Contains'),
],
'#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes.'),
];
$form['size'] = [
'#type' => 'textfield',
'#title' => t('Size of textfield'),
'#default_value' => $settings['size'],
'#element_validate' => [
'_element_validate_integer_positive',
],
'#required' => TRUE,
];
}
return $form;
}
/**
* Implements hook_field_widget_form().
*/
function references_dialog_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
switch ($instance['widget']['type']) {
case 'references_dialog_term_reference':
if (isset($items[$delta]['tid'])) {
$term = taxonomy_term_load($items[$delta]['tid']);
$value = $term->name;
}
else {
$value = NULL;
}
$element += array(
'#type' => 'textfield',
'#default_value' => $value,
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $field['field_name'],
'#size' => $instance['widget']['settings']['size'],
'#maxlength' => NULL,
'#element_validate' => array(
'references_dialog_term_reference_autocomplete_validate',
),
);
break;
}
return array(
'tid' => $element,
);
}
/**
* Form element validate handler for taxonomy term autocomplete element.
*/
function references_dialog_term_reference_autocomplete_validate($element, &$form_state) {
// Autocomplete widgets do not send their tids in the form, so we must detect
// them here and process them independently.
$value = NULL;
if ($element['#value']) {
$term = FALSE;
$field = field_widget_field($element, $form_state);
$instance = field_widget_instance($element, $form_state);
// Check whether we have an explicit "[tid:n]" input.
preg_match('/^(?:\\s*|(.*) )?\\[\\s*tid\\s*:\\s*(\\d+)\\s*\\]$/', $element['#value'], $matches);
if (!empty($matches)) {
// Explicit tid.
list(, $term_name, $tid) = $matches;
if (!empty($term_name)) {
$term = taxonomy_term_load($tid);
}
}
else {
// Collect candidate vocabularies.
$vocabularies = array();
foreach ($field['settings']['allowed_values'] as $tree) {
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
$vocabularies[$vocabulary->vid] = $vocabulary;
}
}
if ($possibilities = taxonomy_term_load_multiple(array(), array(
'name' => trim($element['#value']),
'vid' => array_keys($vocabularies),
))) {
$term = array_pop($possibilities);
}
}
if ($term) {
$value = $term->tid;
}
else {
form_error($element, t('%name: found no valid post for this value.', array(
'%name' => $instance['label'],
)));
}
}
form_set_value($element, $value, $form_state);
}