Mercurial > hg > rr-repo
comparison sites/all/modules/entityreference/entityreference.module @ 4:ce11bbd8f642
added modules
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Thu, 19 Sep 2013 10:38:44 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:b28be78d8160 | 4:ce11bbd8f642 |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Implements hook_ctools_plugin_directory(). | |
5 */ | |
6 function entityreference_ctools_plugin_directory($module, $plugin) { | |
7 if ($module == 'entityreference') { | |
8 return 'plugins/' . $plugin; | |
9 } | |
10 } | |
11 | |
12 /** | |
13 * Implements hook_init(). | |
14 */ | |
15 function entityreference_init() { | |
16 // Include feeds.module integration. | |
17 if (module_exists('feeds')) { | |
18 module_load_include('inc', 'entityreference', 'entityreference.feeds'); | |
19 } | |
20 } | |
21 | |
22 /** | |
23 * Implements hook_ctools_plugin_type(). | |
24 */ | |
25 function entityreference_ctools_plugin_type() { | |
26 $plugins['selection'] = array( | |
27 'classes' => array('class'), | |
28 ); | |
29 $plugins['behavior'] = array( | |
30 'classes' => array('class'), | |
31 'process' => 'entityreference_behavior_plugin_process', | |
32 ); | |
33 return $plugins; | |
34 } | |
35 | |
36 /** | |
37 * CTools callback; Process the behavoir plugins. | |
38 */ | |
39 function entityreference_behavior_plugin_process(&$plugin, $info) { | |
40 $plugin += array( | |
41 'description' => '', | |
42 'behavior type' => 'field', | |
43 'access callback' => FALSE, | |
44 'force enabled' => FALSE, | |
45 ); | |
46 } | |
47 | |
48 /** | |
49 * Implements hook_field_info(). | |
50 */ | |
51 function entityreference_field_info() { | |
52 $field_info['entityreference'] = array( | |
53 'label' => t('Entity Reference'), | |
54 'description' => t('This field reference another entity.'), | |
55 'settings' => array( | |
56 // Default to the core target entity type node. | |
57 'target_type' => 'node', | |
58 // The handler for this field. | |
59 'handler' => 'base', | |
60 // The handler settings. | |
61 'handler_settings' => array(), | |
62 ), | |
63 'instance_settings' => array(), | |
64 'default_widget' => 'entityreference_autocomplete', | |
65 'default_formatter' => 'entityreference_label', | |
66 'property_callbacks' => array('entityreference_field_property_callback'), | |
67 ); | |
68 return $field_info; | |
69 } | |
70 | |
71 /** | |
72 * Implements hook_flush_caches(). | |
73 */ | |
74 function entityreference_flush_caches() { | |
75 // Because of the intricacies of the info hooks, we are forced to keep a | |
76 // separate list of the base tables of each entities, so that we can use | |
77 // it in entityreference_field_schema() without calling entity_get_info(). | |
78 // See http://drupal.org/node/1416558 for details. | |
79 $base_tables = array(); | |
80 foreach (entity_get_info() as $entity_type => $entity_info) { | |
81 if (!empty($entity_info['base table']) && !empty($entity_info['entity keys']['id'])) { | |
82 $base_tables[$entity_type] = array($entity_info['base table'], $entity_info['entity keys']['id']); | |
83 } | |
84 } | |
85 // We are using a variable because cache is going to be cleared right after | |
86 // hook_flush_caches() is finished. | |
87 variable_set('entityreference:base-tables', $base_tables); | |
88 } | |
89 | |
90 /** | |
91 * Implements hook_menu(). | |
92 */ | |
93 function entityreference_menu() { | |
94 $items = array(); | |
95 | |
96 $items['entityreference/autocomplete/single/%/%/%'] = array( | |
97 'title' => 'Entity Reference Autocomplete', | |
98 'page callback' => 'entityreference_autocomplete_callback', | |
99 'page arguments' => array(2, 3, 4, 5), | |
100 'access callback' => 'entityreference_autocomplete_access_callback', | |
101 'access arguments' => array(2, 3, 4, 5), | |
102 'type' => MENU_CALLBACK, | |
103 ); | |
104 $items['entityreference/autocomplete/tags/%/%/%'] = array( | |
105 'title' => 'Entity Reference Autocomplete', | |
106 'page callback' => 'entityreference_autocomplete_callback', | |
107 'page arguments' => array(2, 3, 4, 5), | |
108 'access callback' => 'entityreference_autocomplete_access_callback', | |
109 'access arguments' => array(2, 3, 4, 5), | |
110 'type' => MENU_CALLBACK, | |
111 ); | |
112 | |
113 return $items; | |
114 } | |
115 | |
116 /** | |
117 * Implements hook_field_is_empty(). | |
118 */ | |
119 function entityreference_field_is_empty($item, $field) { | |
120 $empty = !isset($item['target_id']) || !is_numeric($item['target_id']); | |
121 | |
122 // Invoke the behaviors to allow them to override the empty status. | |
123 foreach (entityreference_get_behavior_handlers($field) as $handler) { | |
124 $handler->is_empty_alter($empty, $item, $field); | |
125 } | |
126 return $empty; | |
127 } | |
128 | |
129 /** | |
130 * Get the behavior handlers for a given entityreference field. | |
131 */ | |
132 function entityreference_get_behavior_handlers($field, $instance = NULL) { | |
133 $object_cache = drupal_static(__FUNCTION__); | |
134 $identifier = $field['field_name']; | |
135 if (!empty($instance)) { | |
136 $identifier .= ':' . $instance['entity_type'] . ':' . $instance['bundle']; | |
137 } | |
138 | |
139 if (!isset($object_cache[$identifier])) { | |
140 $object_cache[$identifier] = array(); | |
141 | |
142 // Merge in defaults. | |
143 $field['settings'] += array('behaviors' => array()); | |
144 | |
145 $object_cache[$field['field_name']] = array(); | |
146 $behaviors = !empty($field['settings']['handler_settings']['behaviors']) ? $field['settings']['handler_settings']['behaviors'] : array(); | |
147 if (!empty($instance['settings']['behaviors'])) { | |
148 $behaviors = array_merge($behaviors, $instance['settings']['behaviors']); | |
149 } | |
150 foreach ($behaviors as $behavior => $settings) { | |
151 if (empty($settings['status'])) { | |
152 // Behavior is not enabled. | |
153 continue; | |
154 } | |
155 | |
156 $object_cache[$identifier][] = _entityreference_get_behavior_handler($behavior); | |
157 } | |
158 } | |
159 | |
160 return $object_cache[$identifier]; | |
161 } | |
162 | |
163 /** | |
164 * Get the behavior handler for a given entityreference field and instance. | |
165 * | |
166 * @param $handler | |
167 * The behavior handler name. | |
168 */ | |
169 function _entityreference_get_behavior_handler($behavior) { | |
170 $object_cache = drupal_static(__FUNCTION__); | |
171 | |
172 if (!isset($object_cache[$behavior])) { | |
173 ctools_include('plugins'); | |
174 $class = ctools_plugin_load_class('entityreference', 'behavior', $behavior, 'class'); | |
175 | |
176 $class = class_exists($class) ? $class : 'EntityReference_BehaviorHandler_Broken'; | |
177 $object_cache[$behavior] = new $class($behavior); | |
178 } | |
179 | |
180 return $object_cache[$behavior]; | |
181 } | |
182 | |
183 /** | |
184 * Get the selection handler for a given entityreference field. | |
185 */ | |
186 function entityreference_get_selection_handler($field, $instance = NULL, $entity_type = NULL, $entity = NULL) { | |
187 ctools_include('plugins'); | |
188 $handler = $field['settings']['handler']; | |
189 $class = ctools_plugin_load_class('entityreference', 'selection', $handler, 'class'); | |
190 | |
191 if (class_exists($class)) { | |
192 return call_user_func(array($class, 'getInstance'), $field, $instance, $entity_type, $entity); | |
193 } | |
194 else { | |
195 return EntityReference_SelectionHandler_Broken::getInstance($field, $instance, $entity_type, $entity); | |
196 } | |
197 } | |
198 | |
199 /** | |
200 * Implements hook_field_load(). | |
201 */ | |
202 function entityreference_field_load($entity_type, $entities, $field, $instances, $langcode, &$items) { | |
203 // Invoke the behaviors. | |
204 foreach (entityreference_get_behavior_handlers($field) as $handler) { | |
205 $handler->load($entity_type, $entities, $field, $instances, $langcode, $items); | |
206 } | |
207 } | |
208 | |
209 /** | |
210 * Implements hook_field_validate(). | |
211 */ | |
212 function entityreference_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { | |
213 $ids = array(); | |
214 foreach ($items as $delta => $item) { | |
215 if (!entityreference_field_is_empty($item, $field) && $item['target_id'] !== NULL) { | |
216 $ids[$item['target_id']] = $delta; | |
217 } | |
218 } | |
219 | |
220 if ($ids) { | |
221 $valid_ids = entityreference_get_selection_handler($field, $instance, $entity_type, $entity)->validateReferencableEntities(array_keys($ids)); | |
222 | |
223 $invalid_entities = array_diff_key($ids, array_flip($valid_ids)); | |
224 if ($invalid_entities) { | |
225 foreach ($invalid_entities as $id => $delta) { | |
226 $errors[$field['field_name']][$langcode][$delta][] = array( | |
227 'error' => 'entityreference_invalid_entity', | |
228 'message' => t('The referenced entity (@type: @id) is invalid.', array('@type' => $field['settings']['target_type'], '@id' => $id)), | |
229 ); | |
230 } | |
231 } | |
232 } | |
233 | |
234 // Invoke the behaviors. | |
235 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
236 $handler->validate($entity_type, $entity, $field, $instance, $langcode, $items, $errors); | |
237 } | |
238 } | |
239 | |
240 /** | |
241 * Implements hook_field_presave(). | |
242 * | |
243 * Adds the target type to the field data structure when saving. | |
244 */ | |
245 function entityreference_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { | |
246 // Invoke the behaviors. | |
247 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
248 $handler->presave($entity_type, $entity, $field, $instance, $langcode, $items); | |
249 } | |
250 } | |
251 | |
252 /** | |
253 * Implements hook_field_insert(). | |
254 */ | |
255 function entityreference_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) { | |
256 // Invoke the behaviors. | |
257 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
258 $handler->insert($entity_type, $entity, $field, $instance, $langcode, $items); | |
259 } | |
260 } | |
261 | |
262 /** | |
263 * Implements hook_field_attach_insert(). | |
264 * | |
265 * Emulates a post-insert hook. | |
266 */ | |
267 function entityreference_field_attach_insert($entity_type, $entity) { | |
268 list(, , $bundle) = entity_extract_ids($entity_type, $entity); | |
269 foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) { | |
270 $field = field_info_field($field_name); | |
271 if ($field['type'] == 'entityreference') { | |
272 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
273 $handler->postInsert($entity_type, $entity, $field, $instance); | |
274 } | |
275 } | |
276 } | |
277 } | |
278 | |
279 /** | |
280 * Implements hook_field_update(). | |
281 */ | |
282 function entityreference_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) { | |
283 // Invoke the behaviors. | |
284 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
285 $handler->update($entity_type, $entity, $field, $instance, $langcode, $items); | |
286 } | |
287 } | |
288 | |
289 /** | |
290 * Implements hook_field_attach_update(). | |
291 * | |
292 * Emulates a post-update hook. | |
293 */ | |
294 function entityreference_field_attach_update($entity_type, $entity) { | |
295 list(, , $bundle) = entity_extract_ids($entity_type, $entity); | |
296 foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) { | |
297 $field = field_info_field($field_name); | |
298 if ($field['type'] == 'entityreference') { | |
299 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
300 $handler->postUpdate($entity_type, $entity, $field, $instance); | |
301 } | |
302 } | |
303 } | |
304 } | |
305 | |
306 /** | |
307 * Implements hook_field_delete(). | |
308 */ | |
309 function entityreference_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) { | |
310 // Invoke the behaviors. | |
311 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
312 $handler->delete($entity_type, $entity, $field, $instance, $langcode, $items); | |
313 } | |
314 } | |
315 | |
316 /** | |
317 * Implements hook_field_attach_delete(). | |
318 * | |
319 * Emulates a post-delete hook. | |
320 */ | |
321 function entityreference_field_attach_delete($entity_type, $entity) { | |
322 list(, , $bundle) = entity_extract_ids($entity_type, $entity); | |
323 foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) { | |
324 $field = field_info_field($field_name); | |
325 if ($field['type'] == 'entityreference') { | |
326 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
327 $handler->postDelete($entity_type, $entity, $field, $instance); | |
328 } | |
329 } | |
330 } | |
331 } | |
332 | |
333 /** | |
334 * Implements hook_entity_insert(). | |
335 */ | |
336 function entityreference_entity_insert($entity, $entity_type) { | |
337 entityreference_entity_crud($entity, $entity_type, 'entityPostInsert'); | |
338 } | |
339 | |
340 /** | |
341 * Implements hook_entity_update(). | |
342 */ | |
343 function entityreference_entity_update($entity, $entity_type) { | |
344 entityreference_entity_crud($entity, $entity_type, 'entityPostUpdate'); | |
345 } | |
346 | |
347 /** | |
348 * Implements hook_entity_delete(). | |
349 */ | |
350 function entityreference_entity_delete($entity, $entity_type) { | |
351 entityreference_entity_crud($entity, $entity_type, 'entityPostDelete'); | |
352 } | |
353 | |
354 /** | |
355 * Invoke a behavior based on entity CRUD. | |
356 * | |
357 * @param $entity | |
358 * The entity object. | |
359 * @param $entity_type | |
360 * The entity type. | |
361 * @param $method_name | |
362 * The method to invoke. | |
363 */ | |
364 function entityreference_entity_crud($entity, $entity_type, $method_name) { | |
365 list(, , $bundle) = entity_extract_ids($entity_type, $entity); | |
366 foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) { | |
367 $field = field_info_field($field_name); | |
368 if ($field['type'] == 'entityreference') { | |
369 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
370 $handler->{$method_name}($entity_type, $entity, $field, $instance); | |
371 } | |
372 } | |
373 } | |
374 } | |
375 | |
376 /** | |
377 * Implements hook_field_settings_form(). | |
378 */ | |
379 function entityreference_field_settings_form($field, $instance, $has_data) { | |
380 // The field settings infrastructure is not AJAX enabled by default, | |
381 // because it doesn't pass over the $form_state. | |
382 // Build the whole form into a #process in which we actually have access | |
383 // to the form state. | |
384 $form = array( | |
385 '#type' => 'container', | |
386 '#attached' => array( | |
387 'css' => array(drupal_get_path('module', 'entityreference') . '/entityreference.admin.css'), | |
388 ), | |
389 '#process' => array( | |
390 '_entityreference_field_settings_process', | |
391 '_entityreference_field_settings_ajax_process', | |
392 ), | |
393 '#element_validate' => array('_entityreference_field_settings_validate'), | |
394 '#field' => $field, | |
395 '#instance' => $instance, | |
396 '#has_data' => $has_data, | |
397 ); | |
398 return $form; | |
399 } | |
400 | |
401 function _entityreference_field_settings_process($form, $form_state) { | |
402 $field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field']; | |
403 $instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance']; | |
404 $has_data = $form['#has_data']; | |
405 | |
406 $settings = $field['settings']; | |
407 $settings += array('handler' => 'base'); | |
408 | |
409 // Select the target entity type. | |
410 $entity_type_options = array(); | |
411 foreach (entity_get_info() as $entity_type => $entity_info) { | |
412 $entity_type_options[$entity_type] = $entity_info['label']; | |
413 } | |
414 | |
415 $form['target_type'] = array( | |
416 '#type' => 'select', | |
417 '#title' => t('Target type'), | |
418 '#options' => $entity_type_options, | |
419 '#default_value' => $field['settings']['target_type'], | |
420 '#required' => TRUE, | |
421 '#description' => t('The entity type that can be referenced through this field.'), | |
422 '#disabled' => $has_data, | |
423 '#size' => 1, | |
424 '#ajax' => TRUE, | |
425 '#limit_validation_errors' => array(), | |
426 ); | |
427 | |
428 ctools_include('plugins'); | |
429 $handlers = ctools_get_plugins('entityreference', 'selection'); | |
430 uasort($handlers, 'ctools_plugin_sort'); | |
431 $handlers_options = array(); | |
432 foreach ($handlers as $handler => $handler_info) { | |
433 $handlers_options[$handler] = check_plain($handler_info['title']); | |
434 } | |
435 | |
436 $form['handler'] = array( | |
437 '#type' => 'fieldset', | |
438 '#title' => t('Entity selection'), | |
439 '#tree' => TRUE, | |
440 '#process' => array('_entityreference_form_process_merge_parent'), | |
441 ); | |
442 | |
443 $form['handler']['handler'] = array( | |
444 '#type' => 'select', | |
445 '#title' => t('Mode'), | |
446 '#options' => $handlers_options, | |
447 '#default_value' => $settings['handler'], | |
448 '#required' => TRUE, | |
449 '#ajax' => TRUE, | |
450 '#limit_validation_errors' => array(), | |
451 ); | |
452 $form['handler_submit'] = array( | |
453 '#type' => 'submit', | |
454 '#value' => t('Change handler'), | |
455 '#limit_validation_errors' => array(), | |
456 '#attributes' => array( | |
457 'class' => array('js-hide'), | |
458 ), | |
459 '#submit' => array('entityreference_settings_ajax_submit'), | |
460 ); | |
461 | |
462 $form['handler']['handler_settings'] = array( | |
463 '#type' => 'container', | |
464 '#attributes' => array('class' => array('entityreference-settings')), | |
465 ); | |
466 | |
467 $handler = entityreference_get_selection_handler($field, $instance); | |
468 $form['handler']['handler_settings'] += $handler->settingsForm($field, $instance); | |
469 | |
470 _entityreference_get_behavior_elements($form, $field, $instance, 'field'); | |
471 if (!empty($form['behaviors'])) { | |
472 $form['behaviors'] += array( | |
473 '#type' => 'fieldset', | |
474 '#title' => t('Additional behaviors'), | |
475 '#parents' => array_merge($form['#parents'], array('handler_settings', 'behaviors')), | |
476 ); | |
477 } | |
478 | |
479 return $form; | |
480 } | |
481 | |
482 function _entityreference_field_settings_ajax_process($form, $form_state) { | |
483 _entityreference_field_settings_ajax_process_element($form, $form); | |
484 return $form; | |
485 } | |
486 | |
487 function _entityreference_field_settings_ajax_process_element(&$element, $main_form) { | |
488 if (isset($element['#ajax']) && $element['#ajax'] === TRUE) { | |
489 $element['#ajax'] = array( | |
490 'callback' => 'entityreference_settings_ajax', | |
491 'wrapper' => $main_form['#id'], | |
492 'element' => $main_form['#array_parents'], | |
493 ); | |
494 } | |
495 | |
496 foreach (element_children($element) as $key) { | |
497 _entityreference_field_settings_ajax_process_element($element[$key], $main_form); | |
498 } | |
499 } | |
500 | |
501 function _entityreference_form_process_merge_parent($element) { | |
502 $parents = $element['#parents']; | |
503 array_pop($parents); | |
504 $element['#parents'] = $parents; | |
505 return $element; | |
506 } | |
507 | |
508 function _entityreference_element_validate_filter(&$element, &$form_state) { | |
509 $element['#value'] = array_filter($element['#value']); | |
510 form_set_value($element, $element['#value'], $form_state); | |
511 } | |
512 | |
513 function _entityreference_field_settings_validate($form, &$form_state) { | |
514 // Store the new values in the form state. | |
515 $field = $form['#field']; | |
516 if (isset($form_state['values']['field'])) { | |
517 $field['settings'] = $form_state['values']['field']['settings']; | |
518 } | |
519 $form_state['entityreference']['field'] = $field; | |
520 | |
521 unset($form_state['values']['field']['settings']['handler_submit']); | |
522 } | |
523 | |
524 /** | |
525 * Implements hook_field_instance_settings_form(). | |
526 */ | |
527 function entityreference_field_instance_settings_form($field, $instance) { | |
528 $form['settings'] = array( | |
529 '#type' => 'container', | |
530 '#attached' => array( | |
531 'css' => array(drupal_get_path('module', 'entityreference') . '/entityreference.admin.css'), | |
532 ), | |
533 '#weight' => 10, | |
534 '#tree' => TRUE, | |
535 '#process' => array( | |
536 '_entityreference_form_process_merge_parent', | |
537 '_entityreference_field_instance_settings_form', | |
538 '_entityreference_field_settings_ajax_process', | |
539 ), | |
540 '#element_validate' => array('_entityreference_field_instance_settings_validate'), | |
541 '#field' => $field, | |
542 '#instance' => $instance, | |
543 ); | |
544 | |
545 return $form; | |
546 } | |
547 | |
548 function _entityreference_field_instance_settings_form($form, $form_state) { | |
549 $field = isset($form_state['entityreference']['field']) ? $form_state['entityreference']['field'] : $form['#field']; | |
550 $instance = isset($form_state['entityreference']['instance']) ? $form_state['entityreference']['instance'] : $form['#instance']; | |
551 | |
552 _entityreference_get_behavior_elements($form, $field, $instance, 'instance'); | |
553 if (!empty($form['behaviors'])) { | |
554 $form['behaviors'] += array( | |
555 '#type' => 'fieldset', | |
556 '#title' => t('Additional behaviors'), | |
557 '#process' => array( | |
558 '_entityreference_field_settings_ajax_process', | |
559 ), | |
560 ); | |
561 } | |
562 return $form; | |
563 } | |
564 | |
565 function _entityreference_field_instance_settings_validate($form, &$form_state) { | |
566 // Store the new values in the form state. | |
567 $instance = $form['#instance']; | |
568 if (isset($form_state['values']['instance'])) { | |
569 $instance = drupal_array_merge_deep($instance, $form_state['values']['instance']); | |
570 } | |
571 $form_state['entityreference']['instance'] = $instance; | |
572 } | |
573 | |
574 /** | |
575 * Get the field or instance elements for the field configuration. | |
576 */ | |
577 function _entityreference_get_behavior_elements(&$element, $field, $instance, $level) { | |
578 // Add the accessible behavior handlers. | |
579 $behavior_plugins = entityreference_get_accessible_behavior_plugins($field, $instance); | |
580 | |
581 if ($behavior_plugins[$level]) { | |
582 $element['behaviors'] = array(); | |
583 | |
584 foreach ($behavior_plugins[$level] as $name => $plugin) { | |
585 if ($level == 'field') { | |
586 $settings = !empty($field['settings']['handler_settings']['behaviors'][$name]) ? $field['settings']['handler_settings']['behaviors'][$name] : array(); | |
587 } | |
588 else { | |
589 $settings = !empty($instance['settings']['behaviors'][$name]) ? $instance['settings']['behaviors'][$name] : array(); | |
590 } | |
591 $settings += array('status' => $plugin['force enabled']); | |
592 | |
593 // Render the checkbox. | |
594 $element['behaviors'][$name] = array( | |
595 '#tree' => TRUE, | |
596 ); | |
597 $element['behaviors'][$name]['status'] = array( | |
598 '#type' => 'checkbox', | |
599 '#title' => check_plain($plugin['title']), | |
600 '#description' => $plugin['description'], | |
601 '#default_value' => $settings['status'], | |
602 '#disabled' => $plugin['force enabled'], | |
603 '#ajax' => TRUE, | |
604 ); | |
605 | |
606 if ($settings['status']) { | |
607 $handler = _entityreference_get_behavior_handler($name); | |
608 if ($behavior_elements = $handler->settingsForm($field, $instance)) { | |
609 foreach ($behavior_elements as $key => &$behavior_element) { | |
610 $behavior_element += array( | |
611 '#default_value' => !empty($settings[$key]) ? $settings[$key] : NULL, | |
612 ); | |
613 } | |
614 | |
615 // Get the behavior settings. | |
616 $behavior_elements += array( | |
617 '#type' => 'container', | |
618 '#process' => array('_entityreference_form_process_merge_parent'), | |
619 '#attributes' => array( | |
620 'class' => array('entityreference-settings'), | |
621 ), | |
622 ); | |
623 $element['behaviors'][$name]['settings'] = $behavior_elements; | |
624 } | |
625 } | |
626 } | |
627 } | |
628 } | |
629 | |
630 /** | |
631 * Get all accessible behavior plugins. | |
632 */ | |
633 function entityreference_get_accessible_behavior_plugins($field, $instance) { | |
634 ctools_include('plugins'); | |
635 $plugins = array('field' => array(), 'instance' => array()); | |
636 foreach (ctools_get_plugins('entityreference', 'behavior') as $name => $plugin) { | |
637 $handler = _entityreference_get_behavior_handler($name); | |
638 $level = $plugin['behavior type']; | |
639 if ($handler->access($field, $instance)) { | |
640 $plugins[$level][$name] = $plugin; | |
641 } | |
642 } | |
643 return $plugins; | |
644 } | |
645 | |
646 /** | |
647 * Ajax callback for the handler settings form. | |
648 * | |
649 * @see entityreference_field_settings_form() | |
650 */ | |
651 function entityreference_settings_ajax($form, $form_state) { | |
652 $trigger = $form_state['triggering_element']; | |
653 return drupal_array_get_nested_value($form, $trigger['#ajax']['element']); | |
654 } | |
655 | |
656 /** | |
657 * Submit handler for the non-JS case. | |
658 * | |
659 * @see entityreference_field_settings_form() | |
660 */ | |
661 function entityreference_settings_ajax_submit($form, &$form_state) { | |
662 $form_state['rebuild'] = TRUE; | |
663 } | |
664 | |
665 /** | |
666 * Property callback for the Entity Metadata framework. | |
667 */ | |
668 function entityreference_field_property_callback(&$info, $entity_type, $field, $instance, $field_type) { | |
669 // Set the property type based on the targe type. | |
670 $field_type['property_type'] = $field['settings']['target_type']; | |
671 | |
672 // Then apply the default. | |
673 entity_metadata_field_default_property_callback($info, $entity_type, $field, $instance, $field_type); | |
674 | |
675 // Invoke the behaviors to allow them to change the properties. | |
676 foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) { | |
677 $handler->property_info_alter($info, $entity_type, $field, $instance, $field_type); | |
678 } | |
679 } | |
680 | |
681 /** | |
682 * Implements hook_field_widget_info(). | |
683 */ | |
684 function entityreference_field_widget_info() { | |
685 $widgets['entityreference_autocomplete'] = array( | |
686 'label' => t('Autocomplete'), | |
687 'description' => t('An autocomplete text field.'), | |
688 'field types' => array('entityreference'), | |
689 'settings' => array( | |
690 'match_operator' => 'CONTAINS', | |
691 'size' => 60, | |
692 // We don't have a default here, because it's not the same between | |
693 // the two widgets, and the Field API doesn't update default | |
694 // settings when the widget changes. | |
695 'path' => '', | |
696 ), | |
697 ); | |
698 | |
699 $widgets['entityreference_autocomplete_tags'] = array( | |
700 'label' => t('Autocomplete (Tags style)'), | |
701 'description' => t('An autocomplete text field.'), | |
702 'field types' => array('entityreference'), | |
703 'settings' => array( | |
704 'match_operator' => 'CONTAINS', | |
705 'size' => 60, | |
706 // We don't have a default here, because it's not the same between | |
707 // the two widgets, and the Field API doesn't update default | |
708 // settings when the widget changes. | |
709 'path' => '', | |
710 ), | |
711 'behaviors' => array( | |
712 'multiple values' => FIELD_BEHAVIOR_CUSTOM, | |
713 ), | |
714 ); | |
715 | |
716 return $widgets; | |
717 } | |
718 | |
719 /** | |
720 * Implements hook_field_widget_info_alter(). | |
721 */ | |
722 function entityreference_field_widget_info_alter(&$info) { | |
723 if (module_exists('options')) { | |
724 $info['options_select']['field types'][] = 'entityreference'; | |
725 $info['options_buttons']['field types'][] = 'entityreference'; | |
726 } | |
727 } | |
728 | |
729 /** | |
730 * Implements hook_field_widget_settings_form(). | |
731 */ | |
732 function entityreference_field_widget_settings_form($field, $instance) { | |
733 $widget = $instance['widget']; | |
734 $settings = $widget['settings'] + field_info_widget_settings($widget['type']); | |
735 | |
736 $form = array(); | |
737 | |
738 if ($widget['type'] == 'entityreference_autocomplete' || $widget['type'] == 'entityreference_autocomplete_tags') { | |
739 $form['match_operator'] = array( | |
740 '#type' => 'select', | |
741 '#title' => t('Autocomplete matching'), | |
742 '#default_value' => $settings['match_operator'], | |
743 '#options' => array( | |
744 'STARTS_WITH' => t('Starts with'), | |
745 'CONTAINS' => t('Contains'), | |
746 ), | |
747 '#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.'), | |
748 ); | |
749 $form['size'] = array( | |
750 '#type' => 'textfield', | |
751 '#title' => t('Size of textfield'), | |
752 '#default_value' => $settings['size'], | |
753 '#element_validate' => array('_element_validate_integer_positive'), | |
754 '#required' => TRUE, | |
755 ); | |
756 } | |
757 | |
758 return $form; | |
759 } | |
760 | |
761 /** | |
762 * Implements hook_options_list(). | |
763 */ | |
764 function entityreference_options_list($field, $instance = NULL, $entity_type = NULL, $entity = NULL) { | |
765 if (!$options = entityreference_get_selection_handler($field, $instance, $entity_type, $entity)->getReferencableEntities()) { | |
766 return array(); | |
767 } | |
768 | |
769 // Rebuild the array, by changing the bundle key into the bundle label. | |
770 $target_type = $field['settings']['target_type']; | |
771 $entity_info = entity_get_info($target_type); | |
772 | |
773 $return = array(); | |
774 foreach ($options as $bundle => $entity_ids) { | |
775 $bundle_label = check_plain($entity_info['bundles'][$bundle]['label']); | |
776 $return[$bundle_label] = $entity_ids; | |
777 } | |
778 | |
779 return count($return) == 1 ? reset($return) : $return; | |
780 } | |
781 | |
782 /** | |
783 * Implements hook_query_TAG_alter(). | |
784 */ | |
785 function entityreference_query_entityreference_alter(QueryAlterableInterface $query) { | |
786 $handler = $query->getMetadata('entityreference_selection_handler'); | |
787 $handler->entityFieldQueryAlter($query); | |
788 } | |
789 | |
790 /** | |
791 * Implements hook_field_widget_form(). | |
792 */ | |
793 function entityreference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { | |
794 $entity_type = $instance['entity_type']; | |
795 $entity = isset($element['#entity']) ? $element['#entity'] : NULL; | |
796 $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity); | |
797 | |
798 if ($instance['widget']['type'] == 'entityreference_autocomplete' || $instance['widget']['type'] == 'entityreference_autocomplete_tags') { | |
799 | |
800 if ($instance['widget']['type'] == 'entityreference_autocomplete') { | |
801 // We let the Field API handles multiple values for us, only take | |
802 // care of the one matching our delta. | |
803 if (isset($items[$delta])) { | |
804 $items = array($items[$delta]); | |
805 } | |
806 else { | |
807 $items = array(); | |
808 } | |
809 } | |
810 | |
811 $entity_ids = array(); | |
812 $entity_labels = array(); | |
813 | |
814 // Build an array of entities ID. | |
815 foreach ($items as $item) { | |
816 $entity_ids[] = $item['target_id']; | |
817 } | |
818 | |
819 // Load those entities and loop through them to extract their labels. | |
820 $entities = entity_load($field['settings']['target_type'], $entity_ids); | |
821 | |
822 foreach ($entities as $entity_id => $entity_item) { | |
823 $label = $handler->getLabel($entity_item); | |
824 $key = "$label ($entity_id)"; | |
825 // Labels containing commas or quotes must be wrapped in quotes. | |
826 if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) { | |
827 $key = '"' . str_replace('"', '""', $key) . '"'; | |
828 } | |
829 $entity_labels[] = $key; | |
830 } | |
831 | |
832 // Prepare the autocomplete path. | |
833 if (!empty($instance['widget']['settings']['path'])) { | |
834 $autocomplete_path = $instance['widget']['settings']['path']; | |
835 } | |
836 else { | |
837 $autocomplete_path = $instance['widget']['type'] == 'entityreference_autocomplete' ? 'entityreference/autocomplete/single' : 'entityreference/autocomplete/tags'; | |
838 } | |
839 | |
840 $autocomplete_path .= '/' . $field['field_name'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/'; | |
841 // Use <NULL> as a placeholder in the URL when we don't have an entity. | |
842 // Most webservers collapse two consecutive slashes. | |
843 $id = 'NULL'; | |
844 if ($entity) { | |
845 list($eid) = entity_extract_ids($entity_type, $entity); | |
846 if ($eid) { | |
847 $id = $eid; | |
848 } | |
849 } | |
850 $autocomplete_path .= $id; | |
851 | |
852 if ($instance['widget']['type'] == 'entityreference_autocomplete') { | |
853 $element += array( | |
854 '#type' => 'textfield', | |
855 '#maxlength' => 1024, | |
856 '#default_value' => implode(', ', $entity_labels), | |
857 '#autocomplete_path' => $autocomplete_path, | |
858 '#size' => $instance['widget']['settings']['size'], | |
859 '#element_validate' => array('_entityreference_autocomplete_validate'), | |
860 ); | |
861 return array('target_id' => $element); | |
862 } | |
863 else { | |
864 $element += array( | |
865 '#type' => 'textfield', | |
866 '#maxlength' => 1024, | |
867 '#default_value' => implode(', ', $entity_labels), | |
868 '#autocomplete_path' => $autocomplete_path, | |
869 '#size' => $instance['widget']['settings']['size'], | |
870 '#element_validate' => array('_entityreference_autocomplete_tags_validate'), | |
871 ); | |
872 return $element; | |
873 } | |
874 } | |
875 } | |
876 | |
877 function _entityreference_autocomplete_validate($element, &$form_state, $form) { | |
878 // If a value was entered into the autocomplete... | |
879 $value = ''; | |
880 if (!empty($element['#value'])) { | |
881 // Take "label (entity id)', match the id from parenthesis. | |
882 if (preg_match("/.+\((\d+)\)/", $element['#value'], $matches)) { | |
883 $value = $matches[1]; | |
884 } | |
885 else { | |
886 // Try to get a match from the input string when the user didn't use the | |
887 // autocomplete but filled in a value manually. | |
888 $field = field_info_field($element['#field_name']); | |
889 $handler = entityreference_get_selection_handler($field); | |
890 $field_name = $element['#field_name']; | |
891 $field = field_info_field($field_name); | |
892 $instance = field_info_instance($element['#entity_type'], $field_name, $element['#bundle']); | |
893 $handler = entityreference_get_selection_handler($field, $instance); | |
894 $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form); | |
895 } | |
896 } | |
897 // Update the value of this element so the field can validate the product IDs. | |
898 form_set_value($element, $value, $form_state); | |
899 } | |
900 | |
901 function _entityreference_autocomplete_tags_validate($element, &$form_state, $form) { | |
902 $value = array(); | |
903 // If a value was entered into the autocomplete... | |
904 if (!empty($element['#value'])) { | |
905 $entities = drupal_explode_tags($element['#value']); | |
906 $value = array(); | |
907 foreach ($entities as $entity) { | |
908 // Take "label (entity id)', match the id from parenthesis. | |
909 if (preg_match("/.+\((\d+)\)/", $entity, $matches)) { | |
910 $value[] = array( | |
911 'target_id' => $matches[1], | |
912 ); | |
913 } | |
914 else { | |
915 // Try to get a match from the input string when the user didn't use the | |
916 // autocomplete but filled in a value manually. | |
917 $field = field_info_field($element['#field_name']); | |
918 $handler = entityreference_get_selection_handler($field); | |
919 $value[] = array( | |
920 'target_id' => $handler->validateAutocompleteInput($entity, $element, $form_state, $form), | |
921 ); | |
922 } | |
923 } | |
924 } | |
925 // Update the value of this element so the field can validate the product IDs. | |
926 form_set_value($element, $value, $form_state); | |
927 } | |
928 | |
929 /** | |
930 * Implements hook_field_widget_error(). | |
931 */ | |
932 function entityreference_field_widget_error($element, $error) { | |
933 form_error($element, $error['message']); | |
934 } | |
935 | |
936 /** | |
937 * Menu Access callback for the autocomplete widget. | |
938 * | |
939 * @param $type | |
940 * The widget type (i.e. 'single' or 'tags'). | |
941 * @param $field_name | |
942 * The name of the entity-reference field. | |
943 * @param $entity_type | |
944 * The entity type. | |
945 * @param $bundle_name | |
946 * The bundle name. | |
947 * @return | |
948 * True if user can access this menu item. | |
949 */ | |
950 function entityreference_autocomplete_access_callback($type, $field_name, $entity_type, $bundle_name) { | |
951 $field = field_info_field($field_name); | |
952 $instance = field_info_instance($entity_type, $field_name, $bundle_name); | |
953 | |
954 if (!$field || !$instance || $field['type'] != 'entityreference' || !field_access('edit', $field, $entity_type)) { | |
955 return FALSE; | |
956 } | |
957 return TRUE; | |
958 } | |
959 | |
960 /** | |
961 * Menu callback: autocomplete the label of an entity. | |
962 * | |
963 * @param $type | |
964 * The widget type (i.e. 'single' or 'tags'). | |
965 * @param $field_name | |
966 * The name of the entity-reference field. | |
967 * @param $entity_type | |
968 * The entity type. | |
969 * @param $bundle_name | |
970 * The bundle name. | |
971 * @param $entity_id | |
972 * Optional; The entity ID the entity-reference field is attached to. | |
973 * Defaults to ''. | |
974 * @param $string | |
975 * The label of the entity to query by. | |
976 */ | |
977 function entityreference_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '', $string = '') { | |
978 $field = field_info_field($field_name); | |
979 $instance = field_info_instance($entity_type, $field_name, $bundle_name); | |
980 | |
981 return entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id, $string); | |
982 } | |
983 | |
984 /** | |
985 * Return JSON based on given field, instance and string. | |
986 * | |
987 * This function can be used by other modules that wish to pass a mocked | |
988 * definition of the field on instance. | |
989 * | |
990 * @param $type | |
991 * The widget type (i.e. 'single' or 'tags'). | |
992 * @param $field | |
993 * The field array defintion. | |
994 * @param $instance | |
995 * The instance array defintion. | |
996 * @param $entity_type | |
997 * The entity type. | |
998 * @param $entity_id | |
999 * Optional; The entity ID the entity-reference field is attached to. | |
1000 * Defaults to ''. | |
1001 * @param $string | |
1002 * The label of the entity to query by. | |
1003 */ | |
1004 function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') { | |
1005 $matches = array(); | |
1006 | |
1007 $entity = NULL; | |
1008 if ($entity_id !== 'NULL') { | |
1009 $entity = entity_load_single($entity_type, $entity_id); | |
1010 if (!$entity || !entity_access('view', $entity_type, $entity)) { | |
1011 return MENU_ACCESS_DENIED; | |
1012 } | |
1013 } | |
1014 | |
1015 $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity); | |
1016 | |
1017 if ($type == 'tags') { | |
1018 // The user enters a comma-separated list of tags. We only autocomplete the last tag. | |
1019 $tags_typed = drupal_explode_tags($string); | |
1020 $tag_last = drupal_strtolower(array_pop($tags_typed)); | |
1021 if (!empty($tag_last)) { | |
1022 $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : ''; | |
1023 } | |
1024 } | |
1025 else { | |
1026 // The user enters a single tag. | |
1027 $prefix = ''; | |
1028 $tag_last = $string; | |
1029 } | |
1030 | |
1031 if (isset($tag_last)) { | |
1032 // Get an array of matching entities. | |
1033 $entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10); | |
1034 | |
1035 // Loop through the products and convert them into autocomplete output. | |
1036 foreach ($entity_labels as $values) { | |
1037 foreach ($values as $entity_id => $label) { | |
1038 $key = "$label ($entity_id)"; | |
1039 // Strip things like starting/trailing white spaces, line breaks and tags. | |
1040 $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key))))); | |
1041 // Names containing commas or quotes must be wrapped in quotes. | |
1042 if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) { | |
1043 $key = '"' . str_replace('"', '""', $key) . '"'; | |
1044 } | |
1045 $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label . '</div>'; | |
1046 } | |
1047 } | |
1048 } | |
1049 | |
1050 drupal_json_output($matches); | |
1051 } | |
1052 | |
1053 /** | |
1054 * Implements hook_field_formatter_info(). | |
1055 */ | |
1056 function entityreference_field_formatter_info() { | |
1057 return array( | |
1058 'entityreference_label' => array( | |
1059 'label' => t('Label'), | |
1060 'description' => t('Display the label of the referenced entities.'), | |
1061 'field types' => array('entityreference'), | |
1062 'settings' => array( | |
1063 'link' => FALSE, | |
1064 ), | |
1065 ), | |
1066 'entityreference_entity_id' => array( | |
1067 'label' => t('Entity id'), | |
1068 'description' => t('Display the id of the referenced entities.'), | |
1069 'field types' => array('entityreference'), | |
1070 ), | |
1071 'entityreference_entity_view' => array( | |
1072 'label' => t('Rendered entity'), | |
1073 'description' => t('Display the referenced entities rendered by entity_view().'), | |
1074 'field types' => array('entityreference'), | |
1075 'settings' => array( | |
1076 'view_mode' => '', | |
1077 'links' => TRUE, | |
1078 ), | |
1079 ), | |
1080 ); | |
1081 } | |
1082 | |
1083 /** | |
1084 * Implements hook_field_formatter_settings_form(). | |
1085 */ | |
1086 function entityreference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { | |
1087 $display = $instance['display'][$view_mode]; | |
1088 $settings = $display['settings']; | |
1089 | |
1090 if ($display['type'] == 'entityreference_label') { | |
1091 $element['link'] = array( | |
1092 '#title' => t('Link label to the referenced entity'), | |
1093 '#type' => 'checkbox', | |
1094 '#default_value' => $settings['link'], | |
1095 ); | |
1096 } | |
1097 | |
1098 if ($display['type'] == 'entityreference_entity_view') { | |
1099 $entity_info = entity_get_info($field['settings']['target_type']); | |
1100 $options = array(); | |
1101 if (!empty($entity_info['view modes'])) { | |
1102 foreach ($entity_info['view modes'] as $view_mode => $view_mode_settings) { | |
1103 $options[$view_mode] = $view_mode_settings['label']; | |
1104 } | |
1105 } | |
1106 | |
1107 if (count($options) > 1) { | |
1108 $element['view_mode'] = array( | |
1109 '#type' => 'select', | |
1110 '#options' => $options, | |
1111 '#title' => t('View mode'), | |
1112 '#default_value' => $settings['view_mode'], | |
1113 ); | |
1114 } | |
1115 | |
1116 $element['links'] = array( | |
1117 '#type' => 'checkbox', | |
1118 '#title' => t('Show links'), | |
1119 '#default_value' => $settings['links'], | |
1120 ); | |
1121 } | |
1122 | |
1123 return $element; | |
1124 } | |
1125 | |
1126 /** | |
1127 * Implements hook_field_formatter_settings_summary(). | |
1128 */ | |
1129 function entityreference_field_formatter_settings_summary($field, $instance, $view_mode) { | |
1130 $display = $instance['display'][$view_mode]; | |
1131 $settings = $display['settings']; | |
1132 | |
1133 $summary = array(); | |
1134 | |
1135 if ($display['type'] == 'entityreference_label') { | |
1136 $summary[] = $settings['link'] ? t('Link to the referenced entity') : t('No link'); | |
1137 } | |
1138 | |
1139 if ($display['type'] == 'entityreference_entity_view') { | |
1140 $entity_info = entity_get_info($field['settings']['target_type']); | |
1141 $summary[] = t('Rendered as @mode', array('@mode' => isset($entity_info['view modes'][$settings['view_mode']]['label']) ? $entity_info['view modes'][$settings['view_mode']]['label'] : $settings['view_mode'])); | |
1142 $summary[] = !empty($settings['links']) ? t('Display links') : t('Do not display links'); | |
1143 } | |
1144 | |
1145 return implode('<br />', $summary); | |
1146 } | |
1147 | |
1148 /** | |
1149 * Implements hook_field_formatter_prepare_view(). | |
1150 */ | |
1151 function entityreference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) { | |
1152 $target_ids = array(); | |
1153 | |
1154 // Collect every possible entity attached to any of the entities. | |
1155 foreach ($entities as $id => $entity) { | |
1156 foreach ($items[$id] as $delta => $item) { | |
1157 if (isset($item['target_id'])) { | |
1158 $target_ids[] = $item['target_id']; | |
1159 } | |
1160 } | |
1161 } | |
1162 | |
1163 if ($target_ids) { | |
1164 $target_entities = entity_load($field['settings']['target_type'], $target_ids); | |
1165 } | |
1166 else { | |
1167 $target_entities = array(); | |
1168 } | |
1169 | |
1170 // Iterate through the fieldable entities again to attach the loaded data. | |
1171 foreach ($entities as $id => $entity) { | |
1172 $rekey = FALSE; | |
1173 | |
1174 foreach ($items[$id] as $delta => $item) { | |
1175 // Check whether the referenced entity could be loaded. | |
1176 if (isset($target_entities[$item['target_id']])) { | |
1177 // Replace the instance value with the term data. | |
1178 $items[$id][$delta]['entity'] = $target_entities[$item['target_id']]; | |
1179 // Check whether the user has access to the referenced entity. | |
1180 $items[$id][$delta]['access'] = entity_access('view', $field['settings']['target_type'], $target_entities[$item['target_id']]); | |
1181 } | |
1182 // Otherwise, unset the instance value, since the entity does not exist. | |
1183 else { | |
1184 unset($items[$id][$delta]); | |
1185 $rekey = TRUE; | |
1186 } | |
1187 } | |
1188 | |
1189 if ($rekey) { | |
1190 // Rekey the items array. | |
1191 $items[$id] = array_values($items[$id]); | |
1192 } | |
1193 } | |
1194 } | |
1195 | |
1196 /** | |
1197 * Implements hook_field_formatter_view(). | |
1198 */ | |
1199 function entityreference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { | |
1200 $result = array(); | |
1201 $settings = $display['settings']; | |
1202 | |
1203 // Rebuild the items list to contain only those with access. | |
1204 foreach ($items as $key => $item) { | |
1205 if (empty($item['access'])) { | |
1206 unset($items[$key]); | |
1207 } | |
1208 } | |
1209 | |
1210 switch ($display['type']) { | |
1211 case 'entityreference_label': | |
1212 $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity); | |
1213 | |
1214 foreach ($items as $delta => $item) { | |
1215 $label = $handler->getLabel($item['entity']); | |
1216 // If the link is to be displayed and the entity has a uri, display a link. | |
1217 // Note the assignment ($url = ) here is intended to be an assignment. | |
1218 if ($display['settings']['link'] && ($uri = entity_uri($field['settings']['target_type'], $item['entity']))) { | |
1219 $result[$delta] = array('#markup' => l($label, $uri['path'], $uri['options'])); | |
1220 } | |
1221 else { | |
1222 $result[$delta] = array('#markup' => check_plain($label)); | |
1223 } | |
1224 } | |
1225 break; | |
1226 | |
1227 case 'entityreference_entity_id': | |
1228 foreach ($items as $delta => $item) { | |
1229 $result[$delta] = array('#markup' => check_plain($item['target_id'])); | |
1230 } | |
1231 break; | |
1232 | |
1233 case 'entityreference_entity_view': | |
1234 foreach ($items as $delta => $item) { | |
1235 // Protect ourselves from recursive rendering. | |
1236 static $depth = 0; | |
1237 $depth++; | |
1238 if ($depth > 20) { | |
1239 throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $entity_type, '@entity_id' => $item['target_id']))); | |
1240 } | |
1241 | |
1242 $entity = clone $item['entity']; | |
1243 unset($entity->content); | |
1244 $result[$delta] = entity_view($field['settings']['target_type'], array($item['target_id'] => $entity), $settings['view_mode'], $langcode, FALSE); | |
1245 | |
1246 if (empty($settings['links']) && isset($result[$delta][$field['settings']['target_type']][$item['target_id']]['links'])) { | |
1247 $result[$delta][$field['settings']['target_type']][$item['target_id']]['links']['#access'] = FALSE; | |
1248 } | |
1249 $depth = 0; | |
1250 } | |
1251 break; | |
1252 } | |
1253 | |
1254 return $result; | |
1255 } | |
1256 | |
1257 /** | |
1258 * Exception thrown when the entity view renderer goes into a potentially infinite loop. | |
1259 */ | |
1260 class EntityReferenceRecursiveRenderingException extends Exception {} | |
1261 | |
1262 /** | |
1263 * Implements hook_views_api(). | |
1264 */ | |
1265 function entityreference_views_api() { | |
1266 return array( | |
1267 'api' => 3, | |
1268 'path' => drupal_get_path('module', 'entityreference') . '/views', | |
1269 ); | |
1270 } |