View source
<?php
define('ENTITYREFERENCE_DENIED', '- Restricted access -');
function entityreference_ctools_plugin_directory($module, $plugin) {
if ($module == 'entityreference') {
return 'plugins/' . $plugin;
}
}
function entityreference_init() {
if (module_exists('feeds')) {
module_load_include('inc', 'entityreference', 'entityreference.feeds');
}
}
function entityreference_ctools_plugin_type() {
$plugins['selection'] = array(
'classes' => array(
'class',
),
);
$plugins['behavior'] = array(
'classes' => array(
'class',
),
'process' => 'entityreference_behavior_plugin_process',
);
return $plugins;
}
function entityreference_behavior_plugin_process(&$plugin, $info) {
$plugin += array(
'description' => '',
'behavior type' => 'field',
'access callback' => FALSE,
'force enabled' => FALSE,
);
}
function entityreference_field_info() {
$field_info['entityreference'] = array(
'label' => t('Entity Reference'),
'description' => t('This field references another entity.'),
'settings' => array(
'target_type' => 'node',
'handler' => 'base',
'handler_settings' => array(),
),
'instance_settings' => array(),
'default_widget' => 'entityreference_autocomplete',
'default_formatter' => 'entityreference_label',
'property_callbacks' => array(
'entityreference_field_property_callback',
),
);
return $field_info;
}
function entityreference_flush_caches() {
$base_tables = array();
foreach (entity_get_info() as $entity_type => $entity_info) {
if (!empty($entity_info['base table']) && !empty($entity_info['entity keys']['id'])) {
$base_tables[$entity_type] = array(
$entity_info['base table'],
$entity_info['entity keys']['id'],
);
}
}
variable_set('entityreference:base-tables', $base_tables);
}
function entityreference_theme($existing, $type, $theme, $path) {
return array(
'entityreference_label' => array(
'variables' => array(
'label' => NULL,
'item' => NULL,
'settings' => NULL,
'uri' => NULL,
),
),
'entityreference_entity_id' => array(
'variables' => array(
'item' => NULL,
'settings' => NULL,
),
),
);
}
function entityreference_menu() {
$items = array();
$items['entityreference/autocomplete/single/%/%/%'] = array(
'title' => 'Entity Reference Autocomplete',
'page callback' => 'entityreference_autocomplete_callback',
'page arguments' => array(
2,
3,
4,
5,
),
'access callback' => 'entityreference_autocomplete_access_callback',
'access arguments' => array(
2,
3,
4,
5,
),
'type' => MENU_CALLBACK,
);
$items['entityreference/autocomplete/tags/%/%/%'] = array(
'title' => 'Entity Reference Autocomplete',
'page callback' => 'entityreference_autocomplete_callback',
'page arguments' => array(
2,
3,
4,
5,
),
'access callback' => 'entityreference_autocomplete_access_callback',
'access arguments' => array(
2,
3,
4,
5,
),
'type' => MENU_CALLBACK,
);
return $items;
}
function entityreference_field_is_empty($item, $field) {
$empty = !isset($item['target_id']) || !is_numeric($item['target_id']);
foreach (entityreference_get_behavior_handlers($field) as $handler) {
$handler
->is_empty_alter($empty, $item, $field);
}
return $empty;
}
function entityreference_get_behavior_handlers($field, $instance = NULL) {
$object_cache = drupal_static(__FUNCTION__);
$identifier = $field['field_name'];
if (!empty($instance)) {
$identifier .= ':' . $instance['entity_type'] . ':' . $instance['bundle'];
}
if (!isset($object_cache[$identifier])) {
$object_cache[$identifier] = array();
$field['settings'] += array(
'behaviors' => array(),
);
$object_cache[$field['field_name']] = array();
$behaviors = !empty($field['settings']['handler_settings']['behaviors']) ? $field['settings']['handler_settings']['behaviors'] : array();
if (!empty($instance['settings']['behaviors'])) {
$behaviors = array_merge($behaviors, $instance['settings']['behaviors']);
}
foreach ($behaviors as $behavior => $settings) {
if (empty($settings['status'])) {
continue;
}
$object_cache[$identifier][] = _entityreference_get_behavior_handler($behavior);
}
}
return $object_cache[$identifier];
}
function _entityreference_get_behavior_handler($behavior) {
$object_cache = drupal_static(__FUNCTION__);
if (!isset($object_cache[$behavior])) {
ctools_include('plugins');
$class = ctools_plugin_load_class('entityreference', 'behavior', $behavior, 'class');
$class = class_exists($class) ? $class : 'EntityReference_BehaviorHandler_Broken';
$object_cache[$behavior] = new $class($behavior);
}
return $object_cache[$behavior];
}
function entityreference_get_selection_handler($field, $instance = NULL, $entity_type = NULL, $entity = NULL) {
ctools_include('plugins');
$handler = $field['settings']['handler'];
$class = ctools_plugin_load_class('entityreference', 'selection', $handler, 'class');
if (class_exists($class)) {
return call_user_func(array(
$class,
'getInstance',
), $field, $instance, $entity_type, $entity);
}
else {
return EntityReference_SelectionHandler_Broken::getInstance($field, $instance, $entity_type, $entity);
}
}
function entityreference_field_load($entity_type, $entities, $field, $instances, $langcode, &$items) {
foreach (entityreference_get_behavior_handlers($field) as $handler) {
$handler
->load($entity_type, $entities, $field, $instances, $langcode, $items);
}
}
function entityreference_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
$ids = array();
foreach ($items as $delta => $item) {
if (!entityreference_field_is_empty($item, $field) && $item['target_id'] !== NULL) {
$ids[$item['target_id']] = $delta;
}
}
if ($ids) {
$valid_ids = entityreference_get_selection_handler($field, $instance, $entity_type, $entity)
->validateReferencableEntities(array_keys($ids));
if (!empty($valid_ids)) {
$invalid_entities = array_diff_key($ids, array_flip($valid_ids));
if ($invalid_entities) {
foreach ($invalid_entities as $id => $delta) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'entityreference_invalid_entity',
'message' => t('The referenced entity (@type: @id) is invalid.', array(
'@type' => $field['settings']['target_type'],
'@id' => $id,
)),
);
}
}
}
}
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->validate($entity_type, $entity, $field, $instance, $langcode, $items, $errors);
}
}
function entityreference_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->presave($entity_type, $entity, $field, $instance, $langcode, $items);
}
}
function entityreference_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->insert($entity_type, $entity, $field, $instance, $langcode, $items);
}
}
function entityreference_field_attach_insert($entity_type, $entity) {
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
$field = field_info_field($field_name);
if ($field['type'] == 'entityreference') {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->postInsert($entity_type, $entity, $field, $instance);
}
}
}
}
function entityreference_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->update($entity_type, $entity, $field, $instance, $langcode, $items);
}
}
function entityreference_field_attach_update($entity_type, $entity) {
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
$field = field_info_field($field_name);
if ($field['type'] == 'entityreference') {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->postUpdate($entity_type, $entity, $field, $instance);
}
}
}
}
function entityreference_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->delete($entity_type, $entity, $field, $instance, $langcode, $items);
}
}
function entityreference_field_attach_delete($entity_type, $entity) {
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
$field = field_info_field($field_name);
if ($field['type'] == 'entityreference') {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->postDelete($entity_type, $entity, $field, $instance);
}
}
}
}
function entityreference_entity_insert($entity, $entity_type) {
entityreference_entity_crud($entity, $entity_type, 'entityPostInsert');
}
function entityreference_entity_update($entity, $entity_type) {
entityreference_entity_crud($entity, $entity_type, 'entityPostUpdate');
}
function entityreference_entity_delete($entity, $entity_type) {
entityreference_entity_crud($entity, $entity_type, 'entityPostDelete');
}
function entityreference_entity_crud($entity, $entity_type, $method_name) {
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
$field = field_info_field($field_name);
if ($field['type'] == 'entityreference') {
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->{$method_name}($entity_type, $entity, $field, $instance);
}
}
}
}
function entityreference_field_settings_form($field, $instance, $has_data) {
$form = array(
'#type' => 'container',
'#attached' => array(
'css' => array(
drupal_get_path('module', 'entityreference') . '/entityreference.admin.css',
),
),
'#process' => array(
'_entityreference_field_settings_process',
'_entityreference_field_settings_ajax_process',
),
'#element_validate' => array(
'_entityreference_field_settings_validate',
),
'#field' => $field,
'#instance' => $instance,
'#has_data' => $has_data,
);
return $form;
}
function _entityreference_field_settings_process($form, $form_state) {
$field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field'];
$instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance'];
$has_data = $form['#has_data'];
$settings = $field['settings'];
$settings += array(
'handler' => 'base',
);
$entity_type_options = array();
foreach (entity_get_info() as $entity_type => $entity_info) {
$entity_type_options[$entity_type] = $entity_info['label'];
}
$form['target_type'] = array(
'#type' => 'select',
'#title' => t('Target type'),
'#options' => $entity_type_options,
'#default_value' => $field['settings']['target_type'],
'#required' => TRUE,
'#description' => t('The entity type that can be referenced through this field.'),
'#disabled' => $has_data,
'#size' => 1,
'#ajax' => TRUE,
'#limit_validation_errors' => array(),
);
ctools_include('plugins');
$handlers = ctools_get_plugins('entityreference', 'selection');
uasort($handlers, 'ctools_plugin_sort');
$handlers_options = array();
foreach ($handlers as $handler => $handler_info) {
$handlers_options[$handler] = check_plain($handler_info['title']);
}
$form['handler'] = array(
'#type' => 'fieldset',
'#title' => t('Entity selection'),
'#tree' => TRUE,
'#process' => array(
'_entityreference_form_process_merge_parent',
),
);
$form['handler']['handler'] = array(
'#type' => 'select',
'#title' => t('Mode'),
'#options' => $handlers_options,
'#default_value' => $settings['handler'],
'#required' => TRUE,
'#ajax' => TRUE,
'#limit_validation_errors' => array(),
);
$form['handler_submit'] = array(
'#type' => 'submit',
'#value' => t('Change handler'),
'#limit_validation_errors' => array(),
'#attributes' => array(
'class' => array(
'js-hide',
),
),
'#submit' => array(
'entityreference_settings_ajax_submit',
),
);
$form['handler']['handler_settings'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'entityreference-settings',
),
),
);
$handler = entityreference_get_selection_handler($field, $instance);
$form['handler']['handler_settings'] += $handler
->settingsForm($field, $instance);
_entityreference_get_behavior_elements($form, $field, $instance, 'field');
if (!empty($form['behaviors'])) {
$form['behaviors'] += array(
'#type' => 'fieldset',
'#title' => t('Additional behaviors'),
'#parents' => array_merge($form['#parents'], array(
'handler_settings',
'behaviors',
)),
);
}
return $form;
}
function _entityreference_field_settings_ajax_process($form, $form_state) {
_entityreference_field_settings_ajax_process_element($form, $form);
return $form;
}
function _entityreference_field_settings_ajax_process_element(&$element, $main_form) {
if (isset($element['#ajax']) && $element['#ajax'] === TRUE) {
$element['#ajax'] = array(
'callback' => 'entityreference_settings_ajax',
'wrapper' => $main_form['#id'],
'element' => $main_form['#array_parents'],
);
}
foreach (element_children($element) as $key) {
_entityreference_field_settings_ajax_process_element($element[$key], $main_form);
}
}
function _entityreference_form_process_merge_parent($element) {
$parents = $element['#parents'];
array_pop($parents);
$element['#parents'] = $parents;
return $element;
}
function _entityreference_element_validate_filter(&$element, &$form_state) {
$element['#value'] = array_filter($element['#value']);
form_set_value($element, $element['#value'], $form_state);
}
function _entityreference_field_settings_validate($form, &$form_state) {
$field = $form['#field'];
if (isset($form_state['values']['field'])) {
$field['settings'] = $form_state['values']['field']['settings'];
}
$form_state['entityreference']['field'] = $field;
unset($form_state['values']['field']['settings']['handler_submit']);
}
function entityreference_field_instance_settings_form($field, $instance) {
$form['settings'] = array(
'#type' => 'container',
'#attached' => array(
'css' => array(
drupal_get_path('module', 'entityreference') . '/entityreference.admin.css',
),
),
'#weight' => 10,
'#tree' => TRUE,
'#process' => array(
'_entityreference_form_process_merge_parent',
'_entityreference_field_instance_settings_form',
'_entityreference_field_settings_ajax_process',
),
'#element_validate' => array(
'_entityreference_field_instance_settings_validate',
),
'#field' => $field,
'#instance' => $instance,
);
return $form;
}
function _entityreference_field_instance_settings_form($form, $form_state) {
$field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field'];
$instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance'];
_entityreference_get_behavior_elements($form, $field, $instance, 'instance');
if (!empty($form['behaviors'])) {
$form['behaviors'] += array(
'#type' => 'fieldset',
'#title' => t('Additional behaviors'),
'#process' => array(
'_entityreference_field_settings_ajax_process',
),
);
}
return $form;
}
function _entityreference_field_instance_settings_validate($form, &$form_state) {
$instance = $form['#instance'];
if (isset($form_state['values']['instance'])) {
$instance = drupal_array_merge_deep($instance, $form_state['values']['instance']);
}
$form_state['entityreference']['instance'] = $instance;
}
function _entityreference_get_behavior_elements(&$element, $field, $instance, $level) {
$behavior_plugins = entityreference_get_accessible_behavior_plugins($field, $instance);
if ($behavior_plugins[$level]) {
$element['behaviors'] = array();
foreach ($behavior_plugins[$level] as $name => $plugin) {
if ($level == 'field') {
$settings = !empty($field['settings']['handler_settings']['behaviors'][$name]) ? $field['settings']['handler_settings']['behaviors'][$name] : array();
}
else {
$settings = !empty($instance['settings']['behaviors'][$name]) ? $instance['settings']['behaviors'][$name] : array();
}
$settings += array(
'status' => $plugin['force enabled'],
);
$element['behaviors'][$name] = array(
'#tree' => TRUE,
);
$element['behaviors'][$name]['status'] = array(
'#type' => 'checkbox',
'#title' => check_plain($plugin['title']),
'#description' => $plugin['description'],
'#default_value' => $settings['status'],
'#disabled' => $plugin['force enabled'],
'#ajax' => TRUE,
);
if ($settings['status']) {
$handler = _entityreference_get_behavior_handler($name);
if ($behavior_elements = $handler
->settingsForm($field, $instance)) {
foreach ($behavior_elements as $key => &$behavior_element) {
$behavior_element += array(
'#default_value' => !empty($settings[$key]) ? $settings[$key] : NULL,
);
}
$behavior_elements += array(
'#type' => 'container',
'#process' => array(
'_entityreference_form_process_merge_parent',
),
'#attributes' => array(
'class' => array(
'entityreference-settings',
),
),
);
$element['behaviors'][$name]['settings'] = $behavior_elements;
}
}
}
}
}
function entityreference_get_accessible_behavior_plugins($field, $instance) {
ctools_include('plugins');
$plugins = array(
'field' => array(),
'instance' => array(),
);
foreach (ctools_get_plugins('entityreference', 'behavior') as $name => $plugin) {
$handler = _entityreference_get_behavior_handler($name);
$level = $plugin['behavior type'];
if ($handler
->access($field, $instance)) {
$plugins[$level][$name] = $plugin;
}
}
return $plugins;
}
function entityreference_settings_ajax($form, $form_state) {
$trigger = $form_state['triggering_element'];
return drupal_array_get_nested_value($form, $trigger['#ajax']['element']);
}
function entityreference_settings_ajax_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
}
function entityreference_field_property_callback(&$info, $entity_type, $field, $instance, $field_type) {
$field_type['property_type'] = $field['settings']['target_type'];
entity_metadata_field_default_property_callback($info, $entity_type, $field, $instance, $field_type);
foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
$handler
->property_info_alter($info, $entity_type, $field, $instance, $field_type);
}
}
function entityreference_field_widget_info() {
$widgets['entityreference_autocomplete'] = array(
'label' => t('Autocomplete'),
'description' => t('An autocomplete text field.'),
'field types' => array(
'entityreference',
),
'settings' => array(
'match_operator' => 'CONTAINS',
'size' => 60,
'path' => '',
),
);
$widgets['entityreference_autocomplete_tags'] = array(
'label' => t('Autocomplete (Tags style)'),
'description' => t('An autocomplete text field.'),
'field types' => array(
'entityreference',
),
'settings' => array(
'match_operator' => 'CONTAINS',
'size' => 60,
'path' => '',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
),
);
return $widgets;
}
function entityreference_field_widget_info_alter(&$info) {
if (module_exists('options')) {
$info['options_select']['field types'][] = 'entityreference';
$info['options_buttons']['field types'][] = 'entityreference';
}
}
function entityreference_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'] + field_info_widget_settings($widget['type']);
$form = array();
if ($widget['type'] == 'entityreference_autocomplete' || $widget['type'] == 'entityreference_autocomplete_tags') {
$form['match_operator'] = array(
'#type' => 'select',
'#title' => t('Autocomplete matching'),
'#default_value' => $settings['match_operator'],
'#options' => array(
'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'] = array(
'#type' => 'textfield',
'#title' => t('Size of textfield'),
'#default_value' => $settings['size'],
'#element_validate' => array(
'_element_validate_integer_positive',
),
'#required' => TRUE,
);
}
return $form;
}
function entityreference_options_list($field, $instance = NULL, $entity_type = NULL, $entity = NULL) {
if (!($options = entityreference_get_selection_handler($field, $instance, $entity_type, $entity)
->getReferencableEntities())) {
return array();
}
$target_type = $field['settings']['target_type'];
$entity_info = entity_get_info($target_type);
$return = array();
foreach ($options as $bundle => $entity_ids) {
$bundle_label = check_plain($entity_info['bundles'][$bundle]['label']);
$return[$bundle_label] = $entity_ids;
}
return count($return) == 1 ? reset($return) : $return;
}
function entityreference_query_entityreference_alter(QueryAlterableInterface $query) {
$handler = $query
->getMetadata('entityreference_selection_handler');
$handler
->entityFieldQueryAlter($query);
}
function entityreference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$entity_info = entity_get_info($field['settings']['target_type']);
if (empty($entity_info)) {
return;
}
$entity_type = $instance['entity_type'];
$entity = isset($element['#entity']) ? $element['#entity'] : NULL;
$handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);
if ($instance['widget']['type'] == 'entityreference_autocomplete' || $instance['widget']['type'] == 'entityreference_autocomplete_tags') {
if ($instance['widget']['type'] == 'entityreference_autocomplete') {
if (isset($items[$delta])) {
$items = array(
$items[$delta],
);
}
else {
$items = array();
}
}
$entity_ids = array();
$entity_labels = array();
foreach ($items as $item) {
if (isset($item['target_id'])) {
$entity_ids[] = $item['target_id'];
}
}
$entities = entity_load($field['settings']['target_type'], $entity_ids);
foreach ($entities as $entity_id => $entity_item) {
$label = $handler
->getLabel($entity_item);
$key = "{$label} ({$entity_id})";
if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
$key = '"' . str_replace('"', '""', $key) . '"';
}
$entity_labels[] = $key;
}
if (!empty($instance['widget']['settings']['path'])) {
$autocomplete_path = $instance['widget']['settings']['path'];
}
else {
$autocomplete_path = $instance['widget']['type'] == 'entityreference_autocomplete' ? 'entityreference/autocomplete/single' : 'entityreference/autocomplete/tags';
}
$autocomplete_path .= '/' . $field['field_name'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/';
$id = 'NULL';
if ($entity) {
list($eid) = entity_extract_ids($entity_type, $entity);
if ($eid) {
$id = $eid;
}
}
$autocomplete_path .= $id;
if ($instance['widget']['type'] == 'entityreference_autocomplete') {
$element += array(
'#type' => 'textfield',
'#maxlength' => 1024,
'#default_value' => implode(', ', $entity_labels),
'#autocomplete_path' => $autocomplete_path,
'#size' => $instance['widget']['settings']['size'],
'#element_validate' => array(
'_entityreference_autocomplete_validate',
),
);
return array(
'target_id' => $element,
);
}
else {
$element += array(
'#type' => 'textfield',
'#maxlength' => 1024,
'#default_value' => implode(', ', $entity_labels),
'#autocomplete_path' => $autocomplete_path,
'#size' => $instance['widget']['settings']['size'],
'#element_validate' => array(
'_entityreference_autocomplete_tags_validate',
),
);
return $element;
}
}
}
function _entityreference_autocomplete_validate($element, &$form_state, $form) {
$value = '';
if (!empty($element['#value'])) {
if (preg_match("/.+\\((\\d+)\\)/", $element['#value'], $matches)) {
$value = $matches[1];
}
else {
$field = field_info_field($element['#field_name']);
$handler = entityreference_get_selection_handler($field);
$field_name = $element['#field_name'];
$field = field_info_field($field_name);
$instance = field_info_instance($element['#entity_type'], $field_name, $element['#bundle']);
$handler = entityreference_get_selection_handler($field, $instance);
$value = $handler
->validateAutocompleteInput($element['#value'], $element, $form_state, $form);
}
}
form_set_value($element, $value, $form_state);
}
function _entityreference_autocomplete_tags_validate($element, &$form_state, $form) {
$value = array();
if (!empty($element['#value'])) {
$entities = drupal_explode_tags($element['#value']);
$value = array();
foreach ($entities as $entity) {
if (preg_match("/.+\\((\\d+)\\)/", $entity, $matches)) {
$value[] = array(
'target_id' => $matches[1],
);
}
else {
$field = field_info_field($element['#field_name']);
$handler = entityreference_get_selection_handler($field);
$value[] = array(
'target_id' => $handler
->validateAutocompleteInput($entity, $element, $form_state, $form),
);
}
}
}
form_set_value($element, $value, $form_state);
}
function entityreference_field_widget_error($element, $error) {
form_error($element, $error['message']);
}
function entityreference_autocomplete_access_callback($type, $field_name, $entity_type, $bundle_name) {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
if (!$field || !$instance || $field['type'] != 'entityreference' || !field_access('edit', $field, $entity_type)) {
return FALSE;
}
return TRUE;
}
function entityreference_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '', $string = '') {
$args = func_get_args();
array_shift($args);
array_shift($args);
array_shift($args);
array_shift($args);
array_shift($args);
$string = implode('/', $args);
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
return entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id, $string);
}
function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
$matches = array();
$prefix = '';
$entity = NULL;
if ($entity_id !== 'NULL') {
$entity = entity_load_single($entity_type, $entity_id);
$has_view_access = entity_access('view', $entity_type, $entity) !== FALSE;
$has_update_access = entity_access('update', $entity_type, $entity) !== FALSE;
if (!$entity || !($has_view_access || $has_update_access)) {
return MENU_ACCESS_DENIED;
}
}
$handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);
if ($type == 'tags') {
$tags_typed = drupal_explode_tags($string);
$tag_last = drupal_strtolower(array_pop($tags_typed));
if (!empty($tag_last)) {
$prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
}
}
else {
$tag_last = $string;
}
if (isset($tag_last)) {
$entity_labels = $handler
->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);
$denied_label = t(ENTITYREFERENCE_DENIED);
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
if ($label == $denied_label) {
continue;
}
$key = "{$label} ({$entity_id})";
$key = preg_replace('/\\s\\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
$key = '"' . str_replace('"', '""', $key) . '"';
}
$matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label . '</div>';
}
}
}
drupal_json_output($matches);
}
function entityreference_field_type_settings($field) {
$settings = array(
'entity_type' => NULL,
'column' => NULL,
);
if ($field['type'] == 'entityreference') {
$settings['entity_type'] = $field['settings']['target_type'];
$settings['column'] = 'target_id';
}
elseif ($field['type'] == 'taxonomy_term_reference') {
$settings['entity_type'] = 'taxonomy_term';
$settings['column'] = 'tid';
}
return $settings;
}
function entityreference_field_formatter_info() {
return array(
'entityreference_label' => array(
'label' => t('Label'),
'description' => t('Display the label of the referenced entities.'),
'field types' => array(
'entityreference',
),
'settings' => array(
'link' => FALSE,
'bypass_access' => FALSE,
),
),
'entityreference_entity_id' => array(
'label' => t('Entity id'),
'description' => t('Display the id of the referenced entities.'),
'field types' => array(
'entityreference',
),
),
'entityreference_entity_view' => array(
'label' => t('Rendered entity'),
'description' => t('Display the referenced entities rendered by entity_view().'),
'field types' => array(
'entityreference',
'taxonomy_term_reference',
),
'settings' => array(
'view_mode' => 'default',
'links' => TRUE,
'use_content_language' => TRUE,
'hide_title' => FALSE,
),
),
);
}
function entityreference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$field_type_settings = entityreference_field_type_settings($field);
$element = array();
if ($display['type'] == 'entityreference_label') {
$element['bypass_access'] = array(
'#title' => t('Show entity labels regardless of user access'),
'#description' => t("All entities in the field will be shown, without checking them for access. If the 'Link' setting is also enabled, an entity which the user does not have access to view will show without a link."),
'#type' => 'checkbox',
'#default_value' => $settings['bypass_access'],
);
$element['link'] = array(
'#title' => t('Link label to the referenced entity'),
'#type' => 'checkbox',
'#default_value' => $settings['link'],
);
}
if ($display['type'] == 'entityreference_entity_view') {
$entity_info = entity_get_info($field_type_settings['entity_type']);
$options = array(
'default' => t('Default'),
);
if (!empty($entity_info['view modes'])) {
foreach ($entity_info['view modes'] as $view_mode => $view_mode_settings) {
$options[$view_mode] = $view_mode_settings['label'];
}
}
$element['view_mode'] = array(
'#type' => 'select',
'#options' => $options,
'#title' => t('View mode'),
'#default_value' => $settings['view_mode'],
'#access' => count($options) > 1,
);
$element['links'] = array(
'#type' => 'checkbox',
'#title' => t('Show links'),
'#default_value' => $settings['links'],
);
$element['use_content_language'] = array(
'#type' => 'checkbox',
'#title' => t('Use current content language'),
'#default_value' => $settings['use_content_language'],
);
$element['hide_title'] = array(
'#type' => 'checkbox',
'#title' => t('Hide title'),
'#default_value' => $settings['hide_title'],
);
}
return $element;
}
function entityreference_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$field_type_settings = entityreference_field_type_settings($field);
$summary = array();
if ($display['type'] == 'entityreference_label') {
$summary[] = $settings['link'] ? t('Link to the referenced entity') : t('No link');
$summary[] = $settings['bypass_access'] ? t('Show labels regardless of access') : t('Respect entity access for label visibility');
}
if ($display['type'] == 'entityreference_entity_view') {
$entity_info = entity_get_info($field_type_settings['entity_type']);
$view_mode_label = $settings['view_mode'] == 'default' ? t('Default') : $settings['view_mode'];
if (isset($entity_info['view modes'][$settings['view_mode']]['label'])) {
$view_mode_label = $entity_info['view modes'][$settings['view_mode']]['label'];
}
$summary[] = t('Rendered as @mode', array(
'@mode' => $view_mode_label,
));
$summary[] = !empty($settings['links']) ? t('Display links') : t('Do not display links');
$summary[] = !empty($settings['use_content_language']) ? t('Use current content language') : t('Use field language');
$summary[] = !empty($settings['hide_title']) ? t('Hide Title') : t('Show Title');
}
return implode('<br />', $summary);
}
function entityreference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
$field_type_settings = entityreference_field_type_settings($field);
$target_type = $field_type_settings['entity_type'];
$column = $field_type_settings['column'];
$target_ids = array();
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => $item) {
if (isset($item[$column])) {
$target_ids[] = $item[$column];
}
}
}
if ($target_ids) {
$target_entities = entity_load($target_type, $target_ids);
}
else {
$target_entities = array();
}
foreach ($entities as $id => $entity) {
$rekey = FALSE;
foreach ($items[$id] as $delta => $item) {
if (isset($target_entities[$item[$column]]) && isset($target_entities[$item[$column]])) {
$items[$id][$delta]['entity'] = $target_entities[$item[$column]];
$has_view_access = entity_access('view', $target_type, $target_entities[$item[$column]]) !== FALSE;
$has_update_access = entity_access('update', $target_type, $target_entities[$item[$column]]) !== FALSE;
$items[$id][$delta]['access'] = $has_view_access || $has_update_access;
}
else {
unset($items[$id][$delta]);
$rekey = TRUE;
}
}
if ($rekey) {
$items[$id] = array_values($items[$id]);
}
}
}
function entityreference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$result = array();
$settings = $display['settings'];
$field_type_settings = entityreference_field_type_settings($field);
$target_type = $field_type_settings['entity_type'];
$column = $field_type_settings['column'];
switch ($display['type']) {
case 'entityreference_label':
$handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);
foreach ($items as $delta => $item) {
if (empty($item['access']) && !$display['settings']['bypass_access']) {
continue;
}
$label = entity_label($field['settings']['target_type'], $item['entity']);
$display_link = $display['settings']['link'] && $item['access'];
$uri = NULL;
if ($display_link) {
$uri = entity_uri($target_type, $item['entity']);
}
$result[$delta] = array(
'#theme' => 'entityreference_label',
'#label' => $label,
'#item' => $item,
'#uri' => $uri,
'#settings' => array(
'display' => $display['settings'],
'field' => $field['settings'],
),
);
}
break;
case 'entityreference_entity_id':
foreach ($items as $delta => $item) {
if (empty($item['access'])) {
continue;
}
$result[$delta] = array(
'#theme' => 'entityreference_entity_id',
'#item' => $item,
'#settings' => array(
'display' => $display['settings'],
'field' => $field['settings'],
),
);
}
break;
case 'entityreference_entity_view':
$target_langcode = $langcode;
if (!empty($settings['use_content_language']) && !empty($GLOBALS['language_content']->language)) {
$target_langcode = $GLOBALS['language_content']->language;
}
foreach ($items as $delta => $item) {
if (empty($item['access'])) {
continue;
}
static $depth = 0;
$depth++;
if ($depth > 20) {
throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array(
'@entity_type' => $target_type,
'@entity_id' => $item[$column],
)));
}
$target_entity = clone $item['entity'];
unset($target_entity->content);
$result[$delta] = entity_view($target_type, array(
$item[$column] => $target_entity,
), $settings['view_mode'], $target_langcode, !empty($settings['hide_title']));
if (empty($settings['links']) && isset($result[$delta][$target_type][$item[$column]]['links'])) {
$result[$delta][$target_type][$item[$column]]['links']['#access'] = FALSE;
}
$depth = 0;
}
break;
}
return $result;
}
class EntityReferenceRecursiveRenderingException extends Exception {
}
function entityreference_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'entityreference') . '/views',
);
}
function theme_entityreference_label($vars) {
$label = $vars['label'];
$settings = $vars['settings'];
$item = $vars['item'];
$uri = $vars['uri'];
$output = '';
if ($settings['display']['link'] && isset($uri['path'])) {
$output .= l($label, $uri['path'], $uri['options']);
}
else {
$output .= check_plain($label);
}
return $output;
}
function theme_entityreference_entity_id($vars) {
$settings = $vars['settings'];
$item = $vars['item'];
$output = '';
$output = check_plain($item['target_id']);
return $output;
}