diff --git a/docroot/sites/all/modules/contrib/entityreference/.gitignore b/docroot/sites/all/modules/contrib/entityreference/.gitignore new file mode 100644 index 00000000..036a8e8a --- /dev/null +++ b/docroot/sites/all/modules/contrib/entityreference/.gitignore @@ -0,0 +1,2 @@ +*.diff +*.patch diff --git a/docroot/sites/all/modules/contrib/entityreference/README.txt b/docroot/sites/all/modules/contrib/entityreference/README.txt index 78706c01..79cc1c6e 100644 --- a/docroot/sites/all/modules/contrib/entityreference/README.txt +++ b/docroot/sites/all/modules/contrib/entityreference/README.txt @@ -1,16 +1,95 @@ -DESCRIPTION -=========== -Provides a field type that can reference arbitrary entities. +CONTENTS OF THIS FILE +--------------------- -SITE BUILDERS -============= -Note that when using a select widget, Entity reference loads all the -entities in that list in order to get the entity's label. If there are -too many loaded entities that site might reach its memory limit and crash -(also known as WSOD). In such a case you are advised to change the widget -to "autocomplete". If you get a WSOD when trying to edit the field -settings, you can reach the widget settings directly by navigation to + * Introduction + * Requirements + * Installation + * Recommended Modules + * Configuration + * Maintainers - admin/structure/types/manage/[ENTITY-TYPE]/fields/[FIELD-NAME]/widget-type + +INTRODUCTION +------------ + +The Entity Reference module provides a field that can reference other entities. + + * For a full description of the module visit + https://www.drupal.org/project/entityreference + + * To submit bug reports and feature suggestions, or to track changes visit + https://www.drupal.org/project/issues/entityreference + + +REQUIREMENTS +------------ + +This module requires the following modules: + + * Entity API - https://www.drupal.org/project/entity + * Chaos tool suite (ctools) - https://www.drupal.org/project/ctools + + +RECOMMENDED MODULES +------------------- + +Modules extending Entity reference functionality: + + * Entity Reference View Widget - + https://www.drupal.org/project/entityreference_view_widget + * Entityreference Prepopulate - + https://www.drupal.org/project/entityreference_prepopulate + * Inline Entity Form - https://www.drupal.org/project/inline_entity_form + + +INSTALLATION +------------ + + * Install the Entity Reference module as you would normally install a + contributed Drupal module. Visit https://www.drupal.org/node/895232 for + further information. + + +CONFIGURATION +-------------- + + 1. Navigate to Administration > Modules and enable the Entity Reference + module and its dependencies. + 2. To add an entity reference field to a node, navigate to Administration > + Structure > Content types > [content type to edit] > Manage fields and + add a new field. Add a title and select the entity reference field type. + Select a widget: Select list, Autocomplete (Tags style), Autocomplete, or + Check boxes/radio buttons. Save. + 3. From the Field Setting tab select the entity reference "Target type": + Node, Comment, File, User, Taxonomy term, or Taxonomy vocabulary. + 4. From the Field Setting tab select select the Entity Selection Mode - + Simple (with optional filter by bundle) is the default. Select how to + Sort: Don't sort, A property of the base table of the entity, or A field + attached to this entity. Select the sort field or property and the sort + direction. Save. +Now when authoring content there is an option to make reference to another +entity. + + +Note that when using a select widget, Entity reference loads all the entities +in that list in order to get the entity's label. If there are too many loaded +entities that site might reach its memory limit and crash(also known as WSOD). +In such a case you are advised to change the widget to "autocomplete". If you +get a WSOD when trying to edit the field settings, you can reach the widget +settings directly by navigation to: + + * admin/structure/types/manage/[ENTITY-TYPE]/fields/[FIELD-NAME]/widget-type Replace ENTITY-TYPE and FIELD_NAME with the correct values. + +MAINTAINERS +----------- + + * Mathew Winstone (minorOffense) - https://www.drupal.org/u/minoroffense + * Bojan Živanović (bojanz) - https://www.drupal.org/u/bojanz + * David Pascoe-Deslauriers (spotzero) - https://www.drupal.org/u/spotzero + * Amitai Burstein (amitaibu) - https://www.drupal.org/u/amitaibu + +Supporting organizations: + + * Coldfront Labs Inc. - https://www.drupal.org/coldfront-labs-inc diff --git a/docroot/sites/all/modules/contrib/entityreference/entityreference.info b/docroot/sites/all/modules/contrib/entityreference/entityreference.info index 5b2a0f74..73c2c6d8 100644 --- a/docroot/sites/all/modules/contrib/entityreference/entityreference.info +++ b/docroot/sites/all/modules/contrib/entityreference/entityreference.info @@ -26,12 +26,13 @@ files[] = views/entityreference_plugin_row_fields.inc files[] = tests/entityreference.handlers.test files[] = tests/entityreference.taxonomy.test files[] = tests/entityreference.admin.test +files[] = tests/entityreference.form.test files[] = tests/entityreference.feeds.test +files[] = tests/entityreference.field.test files[] = tests/entityreference.entity_translation.test -; Information added by Drupal.org packaging script on 2017-08-16 -version = "7.x-1.5" +; Information added by Drupal.org packaging script on 2023-02-10 +version = "7.x-1.6" core = "7.x" project = "entityreference" -datestamp = "1502895850" - +datestamp = "1676069720" diff --git a/docroot/sites/all/modules/contrib/entityreference/entityreference.install b/docroot/sites/all/modules/contrib/entityreference/entityreference.install index ce610185..5fe29481 100644 --- a/docroot/sites/all/modules/contrib/entityreference/entityreference.install +++ b/docroot/sites/all/modules/contrib/entityreference/entityreference.install @@ -165,17 +165,15 @@ function entityreference_update_7002() { } /** - * Implements hook_update_N(). - * * Remove duplicate rows in the taxonomy_index table. */ function entityreference_update_7100() { - if (db_table_exists('taxonomy_index')) { + if (db_table_exists('taxonomy_index') && + ($tx_schema = drupal_get_schema('taxonomy_index'))) { if (db_table_exists('taxonomy_index_tmp')) { db_drop_table('taxonomy_index_tmp'); } - $tx_schema = drupal_get_schema('taxonomy_index'); db_create_table('taxonomy_index_tmp', $tx_schema); $select = db_select('taxonomy_index', 'tx'); $select->fields('tx', array('nid', 'tid')); diff --git a/docroot/sites/all/modules/contrib/entityreference/entityreference.module b/docroot/sites/all/modules/contrib/entityreference/entityreference.module index c0c9f58f..a3888f78 100644 --- a/docroot/sites/all/modules/contrib/entityreference/entityreference.module +++ b/docroot/sites/all/modules/contrib/entityreference/entityreference.module @@ -58,7 +58,7 @@ function entityreference_behavior_plugin_process(&$plugin, $info) { function entityreference_field_info() { $field_info['entityreference'] = array( 'label' => t('Entity Reference'), - 'description' => t('This field reference another entity.'), + 'description' => t('This field references another entity.'), 'settings' => array( // Default to the core target entity type node. 'target_type' => 'node', @@ -194,7 +194,12 @@ function _entityreference_get_behavior_handler($behavior) { ctools_include('plugins'); $class = ctools_plugin_load_class('entityreference', 'behavior', $behavior, 'class'); - $class = class_exists($class) ? $class : 'EntityReference_BehaviorHandler_Broken'; + // Ensure the class is available, setting it as broken if it isn't. + if (!$class || !class_exists($class)) { + include_once(dirname(__FILE__) . '/plugins/behavior/abstract.inc'); + $class = 'EntityReference_BehaviorHandler_Broken'; + } + $object_cache[$behavior] = new $class($behavior); } @@ -209,7 +214,7 @@ function entityreference_get_selection_handler($field, $instance = NULL, $entity $handler = $field['settings']['handler']; $class = ctools_plugin_load_class('entityreference', 'selection', $handler, 'class'); - if (class_exists($class)) { + if ($class && class_exists($class)) { return call_user_func(array($class, 'getInstance'), $field, $instance, $entity_type, $entity); } else { @@ -736,6 +741,7 @@ function entityreference_field_widget_info() { 'settings' => array( 'match_operator' => 'CONTAINS', 'size' => 60, + 'hide_ids' => FALSE, // We don't have a default here, because it's not the same between // the two widgets, and the Field API doesn't update default // settings when the widget changes. @@ -750,6 +756,7 @@ function entityreference_field_widget_info() { 'settings' => array( 'match_operator' => 'CONTAINS', 'size' => 60, + 'hide_ids' => FALSE, // We don't have a default here, because it's not the same between // the two widgets, and the Field API doesn't update default // settings when the widget changes. @@ -800,6 +807,12 @@ function entityreference_field_widget_settings_form($field, $instance) { '#element_validate' => array('_element_validate_integer_positive'), '#required' => TRUE, ); + $form['hide_ids'] = array( + '#type' => 'checkbox', + '#title' => t('Hide IDs'), + '#description' => t('If your target entities have unique labels you may choose not to have the IDs shown to the user. Note that this setting will make it impossible to reference entities with non-unique labels!'), + '#default_value' => $settings['hide_ids'], + ); } return $form; @@ -875,7 +888,7 @@ function entityreference_field_widget_form(&$form, &$form_state, $field, $instan foreach ($entities as $entity_id => $entity_item) { $label = $handler->getLabel($entity_item); - $key = "$label ($entity_id)"; + $key = $instance['widget']['settings']['hide_ids'] ? $label : "$label ($entity_id)"; // Labels containing commas or quotes must be wrapped in quotes. if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) { $key = '"' . str_replace('"', '""', $key) . '"'; @@ -1116,7 +1129,7 @@ function entityreference_autocomplete_callback_get_matches($type, $field, $insta if ($label == $denied_label) { continue; } - $key = "$label ($entity_id)"; + $key = $instance['widget']['settings']['hide_ids'] ? $label : "$label ($entity_id)"; // Strip starting/trailing white spaces, line breaks and tags. $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key))))); // Names containing commas or quotes must be wrapped in quotes. @@ -1184,6 +1197,7 @@ function entityreference_field_formatter_info() { 'view_mode' => 'default', 'links' => TRUE, 'use_content_language' => TRUE, + 'hide_title' => FALSE, ), ), ); @@ -1241,6 +1255,11 @@ function entityreference_field_formatter_settings_form($field, $instance, $view_ '#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; @@ -1270,6 +1289,7 @@ function entityreference_field_formatter_settings_summary($field, $instance, $vi $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('
', $summary); @@ -1415,9 +1435,9 @@ function entityreference_field_formatter_view($entity_type, $entity, $field, $in $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, FALSE); + $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][$column]['links'])) { + if (empty($settings['links']) && isset($result[$delta][$target_type][$item[$column]]['links'])) { $result[$delta][$target_type][$item[$column]]['links']['#access'] = FALSE; } $depth = 0; diff --git a/docroot/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info b/docroot/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info index 70bcc4f2..8d41affe 100644 --- a/docroot/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info +++ b/docroot/sites/all/modules/contrib/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info @@ -4,9 +4,8 @@ core = 7.x package = Fields dependencies[] = entityreference -; Information added by Drupal.org packaging script on 2017-08-16 -version = "7.x-1.5" +; Information added by Drupal.org packaging script on 2023-02-10 +version = "7.x-1.6" core = "7.x" project = "entityreference" -datestamp = "1502895850" - +datestamp = "1676069720" diff --git a/docroot/sites/all/modules/contrib/entityreference/plugins/behavior/abstract.inc b/docroot/sites/all/modules/contrib/entityreference/plugins/behavior/abstract.inc index de827bc0..0bcb843b 100644 --- a/docroot/sites/all/modules/contrib/entityreference/plugins/behavior/abstract.inc +++ b/docroot/sites/all/modules/contrib/entityreference/plugins/behavior/abstract.inc @@ -205,6 +205,9 @@ abstract class EntityReference_BehaviorHandler_Abstract implements EntityReferen * A broken implementation of EntityReference_BehaviorHandler. */ class EntityReference_BehaviorHandler_Broken extends EntityReference_BehaviorHandler_Abstract { + public $behavior; + public $plugin; + public function settingsForm($field, $instance) { $form['behavior_handler'] = array( '#markup' => t('The selected behavior handler is broken.'), diff --git a/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php b/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php index 6ec28a4b..15e15d5c 100644 --- a/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php +++ b/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php @@ -8,6 +8,11 @@ */ class EntityReference_SelectionHandler_Generic implements EntityReference_SelectionHandler { + public $field; + public $instance; + public $entity_type; + public $entity; + /** * Implements EntityReferenceHandler::getInstance(). */ @@ -17,6 +22,8 @@ public static function getInstance($field, $instance = NULL, $entity_type = NULL // Check if the entity type does exist and has a base table. $entity_info = entity_get_info($target_entity_type); if (empty($entity_info['base table'])) { + // Make sure the EntityReference_SelectionHandler_Broken class is available. + include_once(dirname(__FILE__) . '/abstract.inc'); return EntityReference_SelectionHandler_Broken::getInstance($field, $instance); } @@ -155,10 +162,16 @@ public static function settingsForm($field, $instance) { /** * Implements EntityReferenceHandler::getReferencableEntities(). */ - public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { + public function getReferencableEntities($match = '', $match_operator = 'CONTAINS', $limit = 0) { $options = array(); $entity_type = $this->field['settings']['target_type']; + if (is_null($match)) { + $match = ''; + } + // Remove escape formatting. + $match = trim(str_replace('""', '"', $match)); + $query = $this->buildEntityFieldQuery($match, $match_operator); if ($limit > 0) { $query->range(0, $limit); diff --git a/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php b/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php index cbed33b1..3909bacb 100644 --- a/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php +++ b/docroot/sites/all/modules/contrib/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php @@ -5,6 +5,11 @@ */ class EntityReference_SelectionHandler_Views implements EntityReference_SelectionHandler { + public $field; + public $instance; + public $entity; + public $view; + /** * Implements EntityReferenceHandler::getInstance(). */ @@ -56,7 +61,7 @@ public static function settingsForm($field, $instance) { $description = t('Provide a comma separated list of arguments to pass to the view.') . '
' . t('This field supports tokens.'); if (!module_exists('token')) { - $description .= '
' . t('Install the token module to get more tokens and display available once.', array('@url' => 'http://drupal.org/project/token')); + $description .= '
' . t('Install the token module to get more tokens and display available ones.', array('@url' => 'http://drupal.org/project/token')); } $form['view']['args'] = array( @@ -170,7 +175,38 @@ function validateReferencableEntities(array $ids) { * Implements EntityReferenceHandler::validateAutocompleteInput(). */ public function validateAutocompleteInput($input, &$element, &$form_state, $form) { - return NULL; + $bundled_entities = $this->getReferencableEntities($input, '=', 6); + $entities = array(); + foreach ($bundled_entities as $entities_list) { + $entities += $entities_list; + } + if (empty($entities)) { + // Error if there are no entities available for a required field. + form_error($element, t('No items found for %label', array('%label' => $element['#title']))); + } + elseif (count($entities) > 5) { + // Error if there are more than 5 matching entities. + form_error($element, t('Too many items found for %label. Specify the one you want by appending the id in parentheses, like "@value (@id)"', array( + '%label' => $element['#title'], + '@value' => $input, + '@id' => key($entities), + ))); + } + elseif (count($entities) > 1) { + // More helpful error if there are only a few matching entities. + $multiples = array(); + foreach ($entities as $id => $name) { + $multiples[] = filter_xss($name, array()) . ' (' . (int) $id . ')'; + } + form_error($element, t('Multiple items found for %label: !multiple', array( + '%label' => $element['#title'], + '!multiple' => theme('item_list', array('items' => $multiples)), + ))); + } + else { + // Take the one and only matching entity. + return (int) key($entities); + } } /** diff --git a/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test index ec78e7bc..df37c4ef 100644 --- a/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test +++ b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.admin.test @@ -9,6 +9,10 @@ * Test for Entity Reference admin UI. */ class EntityReferenceAdminTestCase extends DrupalWebTestCase { + public $admin_user; + public $type; + public $hyphen_type; + public static function getInfo() { return array( 'name' => 'Entity Reference UI', diff --git a/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.field.test b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.field.test new file mode 100644 index 00000000..af3a3384 --- /dev/null +++ b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.field.test @@ -0,0 +1,141 @@ + 'Entity Reference field', + 'description' => 'Tests for the entity reference field formatters and widgets.', + 'group' => 'Entity Reference', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(array('field_ui', 'entity', 'ctools', 'entityreference')); + + // Create test user. + $this->admin_user = $this->drupalCreateUser(array( + 'access content', + 'administer content types', + 'administer nodes', + 'bypass node access', + 'administer filters', + 'administer fields', + )); + $this->drupalLogin($this->admin_user); + + // Create content type. + $this->contentType = strtolower($this->randomName(8)); + $this->drupalCreateContentType(array('name' => $this->contentType, 'type' => $this->contentType)); + } + + /** + * Creates an entity reference field. + * + * @param string $field_name + * The name of the field. + * @param string $label + * The label of the field. + */ + protected function createEntityReferenceField($field_name, $label = 'Test label') { + $bundle_path = 'admin/structure/types/manage/' . $this->contentType; + + // First step: 'Add new field' on the 'Manage fields' page. + $this->drupalPost($bundle_path . '/fields', array( + 'fields[_add_new_field][label]' => $label, + 'fields[_add_new_field][field_name]' => $field_name, + 'fields[_add_new_field][type]' => 'entityreference', + 'fields[_add_new_field][widget_type]' => 'entityreference_autocomplete', + ), t('Save')); + + // Second step: 'Instance settings' form. + $this->drupalPost(NULL, array(), t('Save field settings')); + + // Third step: confirm. + $this->drupalPost(NULL, array(), t('Save settings')); + } + + /** + * Tests the "Show links" setting for the field formatter "Rendered entity". + */ + public function testShowLinksSetting() { + // Create an entity reference field. + $this->createEntityReferenceField('test'); + + // Set formatter to "Rendered entity". + $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/display', array( + 'fields[field_test][type]' => 'entityreference_entity_view', + ), t('Save')); + + // Set view mode option to "teaser" and enable the "Show links" option. + $this->drupalPostAJAX(NULL, array(), 'field_test_formatter_settings_edit'); + $edit = array( + 'fields[field_test][settings_edit_form][settings][view_mode]' => 'teaser', + 'fields[field_test][settings_edit_form][settings][links]' => 1, + ); + $this->drupalPostAJAX(NULL, $edit, 'field_test_formatter_settings_update'); + $this->drupalPost(NULL, array(), t('Save')); + + // Assert that the formatter says that links will be shown. + $this->assertText('Display links'); + $this->assertNoText('Do not display links'); + + // Create two nodes. The second node will reference the first one. + $node1 = $this->drupalCreateNode(array( + 'type' => $this->contentType, + )); + $node2 = $this->drupalCreateNode(array( + 'type' => $this->contentType, + 'field_test' => array( + LANGUAGE_NONE => array( + 0 => array( + 'target_id' => $node1->nid, + ), + ), + ), + )); + + // Assert that a read more link is shown on node 2. + $this->drupalGet('node/2'); + $this->assertText('Read more'); + + // Now turn off the "Show links" setting. + $this->drupalGet('admin/structure/types/manage/' . $this->contentType . '/display'); + $this->drupalPostAJAX(NULL, array(), 'field_test_formatter_settings_edit'); + $edit = array( + 'fields[field_test][settings_edit_form][settings][links]' => FALSE, + ); + $this->drupalPostAJAX(NULL, $edit, 'field_test_formatter_settings_update'); + $this->drupalPost(NULL, array(), t('Save')); + + // Assert that the formatter says that no links will be shown. + $this->assertText('Do not display links'); + + // And assert that the read more link is no longer displayed on node 2. + $this->drupalGet('node/2'); + $this->assertNoText('Read more'); + } + +} diff --git a/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.form.test b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.form.test new file mode 100644 index 00000000..af0d7973 --- /dev/null +++ b/docroot/sites/all/modules/contrib/entityreference/tests/entityreference.form.test @@ -0,0 +1,275 @@ + 'Entity Reference Form', + 'description' => 'Tests Entity Reference form widgets.', + 'group' => 'Entity Reference', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + // Enable entityreference module after views module is enabled to load + // the selection plugin EntityReference_SelectionHandler_Views. + parent::setUp(array('entity', 'ctools', 'views')); + module_enable(array('entityreference')); + + // Create test user. + $this->admin_user = $this->drupalCreateUser(array('bypass node access')); + $this->drupalLogin($this->admin_user); + } + + /** + * Test that the Generic autocomplete widget validates the value properly. + */ + public function testAutocompleteValidationWithGenericSelectionHandler() { + $type_referenced = $this->drupalCreateContentType(); + $type_referencing = $this->drupalCreateContentType(); + + $field_name = 'field_' . $type_referenced->type; + $field = array( + 'field_name' => $field_name, + 'settings' => array( + 'handler' => 'base', + 'target_type' => 'node', + 'handler_settings' => array( + 'target_bundles' => array($type_referenced->type), + ), + ), + ); + $field_instance = array( + 'field_name' => $field_name, + 'bundle' => $type_referencing->type, + ); + $this->createEntityReferenceFieldForNode($field, $field_instance); + + $node = $this->drupalCreateNode(array('type' => $type_referenced->type)); + $title_valid = $node->title; + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_valid); + $this->assertNoText('There are no entities matching "' . $title_valid . '"', + 'No validation error occurs for a valid title.'); + + $title_invalid = $this->randomName(); + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_invalid); + $this->assertText('There are no entities matching "' . $title_invalid . '"', + 'A validation error occurs for an invalid title.'); + + $title_many_nodes_has = $this->randomName(); + for ($i = 0; $i < 6; $i++) { + $node = $this->drupalCreateNode(array( + 'type' => $type_referenced->type, + 'title' => $title_many_nodes_has, + )); + } + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_many_nodes_has); + $this->assertText('Many entities are called ' . $title_many_nodes_has . '.', + 'A validation error occurs for a title shared by too many nodes.'); + + $title_several_nodes_has = $this->randomName(); + for ($i = 0; $i < 2; $i++) { + $node = $this->drupalCreateNode(array( + 'type' => $type_referenced->type, + 'title' => $title_several_nodes_has, + )); + } + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_several_nodes_has); + $this->assertText('Multiple entities match this reference; ', + 'A validation error occurs for a title shared by several nodes.'); + } + + /** + * Test that the Views autocomplete widget validates the value properly. + */ + public function testAutocompleteValidationWithViewsSelectionHandler() { + list($view_name, $display_name) = $this->createNodeEntityReferenceView(); + + $type_referenced = $this->drupalCreateContentType(); + $type_referencing = $this->drupalCreateContentType(); + + $field_name = 'field_' . $type_referenced->type; + $field = array( + 'field_name' => $field_name, + 'settings' => array( + "handler" => "views", + "target_type" => "node", + "handler_settings" => array( + "view" => array( + "view_name" => $view_name, + "display_name" => $display_name, + "args" => array(), + ), + "behaviors" => array( + "views-select-list" => array( + "status" => 0, + ), + ), + ), + ), + ); + $field_instance = array( + 'field_name' => $field_name, + 'bundle' => $type_referencing->type, + ); + $this->createEntityReferenceFieldForNode($field, $field_instance); + + $node = $this->drupalCreateNode(array('type' => $type_referenced->type)); + $title_valid = $node->title; + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_valid); + $this->assertNoText('No items found for ' . $field_name, + 'No validation error occurs for a valid title.'); + + $title_invalid = $this->randomName(); + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_invalid); + $this->assertText('No items found for ' . $field_name, + 'A validation error occurs for an invalid title.'); + + $title_many_nodes_has = $this->randomName(); + for ($i = 0; $i < 6; $i++) { + $node = $this->drupalCreateNode(array( + 'type' => $type_referenced->type, + 'title' => $title_many_nodes_has, + )); + } + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_many_nodes_has); + $this->assertText('Too many items found for ' . $field_name . '.', + 'A validation error occurs for a title shared by too many nodes.'); + + $title_several_nodes_has = $this->randomName(); + for ($i = 0; $i < 2; $i++) { + $node = $this->drupalCreateNode(array( + 'type' => $type_referenced->type, + 'title' => $title_several_nodes_has, + )); + } + $this->postNodeFormWithEntityReference($type_referencing, $field_name, $title_several_nodes_has); + $this->assertText('Multiple items found for ' . $field_name . ':', + 'A validation error occurs for a title shared by several nodes.'); + } + + /** + * Helper method to create a base field and field instance. + * + * @param array $field + * The field to be created. + * @param array $field_instance + * The field instance to be created. + */ + protected function createEntityReferenceFieldForNode($field, $field_instance) { + + // Add the common settings. + $field += array( + 'type' => 'entityreference', + 'translatable' => FALSE, + 'entity_types' => array('node'), + ); + $field_instance += array( + 'entity_type' => 'node', + 'widget' => array( + 'type' => 'entityreference_autocomplete', + 'module' => 'entityreference', + ), + ); + + $field = field_create_field($field); + field_create_instance($field_instance); + } + + /** + * Hepler method to submit node creation form. + * + * @param object $type + * Node type object. + * @param string $field_name + * Name of the Entity Reference field. + * @param string $title + * The node title to enter into the Entity Reference field. + */ + protected function postNodeFormWithEntityReference($type, $field_name, $title) { + $type_path = 'node/add/' . str_replace('_', '-', $type->type); + $edit = array( + $field_name . '[und][0][target_id]' => $title, + ); + + $this->drupalPost($type_path, $edit, t('Save')); + } + + /** + * Create an Entity Reference Views view for node list. + * + * @return view + * A Views view with a node Entity Reference display. + */ + protected function createNodeEntityReferenceView() { + $view_name = 'test_entityreference_select_node'; + $display_name = 'entityreference_1'; + + $view = new view(); + $view->name = $view_name; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = $view_name; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + + /* Display: Entity Reference */ + $handler = $view->new_display('entityreference', 'Entity Reference', $display_name); + $handler->display->display_options['defaults']['title'] = FALSE; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['defaults']['style_plugin'] = FALSE; + $handler->display->display_options['style_plugin'] = 'entityreference_style'; + $handler->display->display_options['style_options']['search_fields'] = array('title' => 'title'); + $handler->display->display_options['defaults']['style_options'] = FALSE; + $handler->display->display_options['defaults']['row_plugin'] = FALSE; + $handler->display->display_options['row_plugin'] = 'entityreference_fields'; + $handler->display->display_options['defaults']['row_options'] = FALSE; + + $view->save(); + + return array($view_name, $display_name); + } + +} diff --git a/docroot/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info b/docroot/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info index 5bbf9b6f..39677b54 100644 --- a/docroot/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info +++ b/docroot/sites/all/modules/contrib/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info @@ -8,9 +8,8 @@ dependencies[] = feeds dependencies[] = feeds_ui dependencies[] = entityreference -; Information added by Drupal.org packaging script on 2017-08-16 -version = "7.x-1.5" +; Information added by Drupal.org packaging script on 2023-02-10 +version = "7.x-1.6" core = "7.x" project = "entityreference" -datestamp = "1502895850" - +datestamp = "1676069720" diff --git a/docroot/sites/all/modules/contrib/entityreference/views/entityreference.views.inc b/docroot/sites/all/modules/contrib/entityreference/views/entityreference.views.inc index baa70343..21ea56d6 100644 --- a/docroot/sites/all/modules/contrib/entityreference/views/entityreference.views.inc +++ b/docroot/sites/all/modules/contrib/entityreference/views/entityreference.views.inc @@ -58,6 +58,15 @@ function entityreference_field_views_data_views_data_alter(&$data, $field) { $target_entity_info = entity_get_info($field['settings']['target_type']); if (isset($target_entity_info['base table'])) { $entity_info = entity_get_info($entity_type); + if (empty($entity_info)) { + watchdog( + 'entityreference', + 'Field %field_name refers to nonexistent entity type %type. You might want to remove this broken field instance. See documentation.', + array('%field_name' => $field['field_name'], '%type' => $entity), + WATCHDOG_WARNING + ); + continue; + } $entity = $entity_info['label']; if ($entity == t('Node')) { $entity = t('Content'); @@ -122,6 +131,8 @@ function entityreference_views_plugins() { 'help' => 'Returns results as a PHP array of labels and rendered rows.', 'handler' => 'entityreference_plugin_style', 'theme' => 'views_view_unformatted', + 'theme path' => drupal_get_path('module', 'views') . '/theme', + 'theme file' => 'theme.inc', 'uses row plugin' => TRUE, 'uses fields' => TRUE, 'uses options' => TRUE, diff --git a/docroot/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc b/docroot/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc index cca36509..30d8a42f 100644 --- a/docroot/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc +++ b/docroot/sites/all/modules/contrib/entityreference/views/entityreference_plugin_display.inc @@ -6,6 +6,8 @@ */ class entityreference_plugin_display extends views_plugin_display { + public $id_field_alias; + function option_definition() { $options = parent::option_definition();