Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -7,227 +7,14 @@
namespace Drupal\entity_reference;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\OptGroup;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\OptionsProviderInterface;
use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint;
/**
* Alternative plugin implementation of the 'entity_reference' field type.
* Deprecated. Alternative implementation of the 'entity_reference' field type.
*
* Replaces the Core 'entity_reference' entity field type implementation, this
* supports configurable fields, auto-creation of referenced entities and more.
* @deprecated in Drupal 8.0.x and will be removed in Drupal 9.0.x. Use
* \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem instead.
*
* Required settings are:
* - target_type: The entity type to reference.
*
* @see entity_reference_field_info_alter().
* @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem
*/
class ConfigurableEntityReferenceItem extends EntityReferenceItem implements OptionsProviderInterface, PreconfiguredFieldUiOptionsInterface {
/**
* {@inheritdoc}
*/
public static function defaultStorageSettings() {
$settings = parent::defaultStorageSettings();
// The target bundle is handled by the 'target_bundles' property in the
// 'handler_settings' instance setting.
unset($settings['target_bundle']);
return $settings;
}
/**
* {@inheritdoc}
*/
public function getPossibleValues(AccountInterface $account = NULL) {
return $this->getSettableValues($account);
}
/**
* {@inheritdoc}
*/
public function getPossibleOptions(AccountInterface $account = NULL) {
return $this->getSettableOptions($account);
}
/**
* {@inheritdoc}
*/
public function getSettableValues(AccountInterface $account = NULL) {
// Flatten options first, because "settable options" may contain group
// arrays.
$flatten_options = OptGroup::flattenOptions($this->getSettableOptions($account));
return array_keys($flatten_options);
}
/**
* {@inheritdoc}
*/
public function getSettableOptions(AccountInterface $account = NULL) {
$field_definition = $this->getFieldDefinition();
if (!$options = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
return array();
}
// Rebuild the array by changing the bundle key into the bundle label.
$target_type = $field_definition->getSetting('target_type');
$bundles = \Drupal::entityManager()->getBundleInfo($target_type);
$return = array();
foreach ($options as $bundle => $entity_ids) {
$bundle_label = SafeMarkup::checkPlain($bundles[$bundle]['label']);
$return[$bundle_label] = $entity_ids;
}
return count($return) == 1 ? reset($return) : $return;
}
/**
* {@inheritdoc}
*/
public function getConstraints() {
$constraints = parent::getConstraints();
// Remove the 'AllowedValuesConstraint' validation constraint because entity
// reference fields already use the 'ValidReference' constraint.
foreach ($constraints as $key => $constraint) {
if ($constraint instanceof AllowedValuesConstraint) {
unset($constraints[$key]);
}
}
return $constraints;
}
/**
* {@inheritdoc}
*/
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
$element['target_type'] = array(
'#type' => 'select',
'#title' => t('Type of item to reference'),
'#options' => \Drupal::entityManager()->getEntityTypeLabels(TRUE),
'#default_value' => $this->getSetting('target_type'),
'#required' => TRUE,
'#disabled' => $has_data,
'#size' => 1,
);
return $element;
}
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$field = $form_state->getFormObject()->getEntity();
// Get all selection plugins for this entity type.
$selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups($this->getSetting('target_type'));
$handlers_options = array();
foreach (array_keys($selection_plugins) as $selection_group_id) {
// We only display base plugins (e.g., 'default', 'views', etc.) and not
// entity type specific plugins (e.g., 'default:node', 'default:user',
// etc.).
if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
$handlers_options[$selection_group_id] = SafeMarkup::checkPlain($selection_plugins[$selection_group_id][$selection_group_id]['label']);
}
elseif (array_key_exists($selection_group_id . ':' . $this->getSetting('target_type'), $selection_plugins[$selection_group_id])) {
$selection_group_plugin = $selection_group_id . ':' . $this->getSetting('target_type');
$handlers_options[$selection_group_plugin] = SafeMarkup::checkPlain($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
}
}
$form = array(
'#type' => 'container',
'#process' => array(
'_entity_reference_field_field_settings_ajax_process',
),
'#element_validate' => array(array(get_class($this), 'fieldSettingsFormValidate')),
);
$form['handler'] = array(
'#type' => 'details',
'#title' => t('Reference type'),
'#open' => TRUE,
'#tree' => TRUE,
'#process' => array('_entity_reference_form_process_merge_parent'),
);
$form['handler']['handler'] = array(
'#type' => 'select',
'#title' => t('Reference method'),
'#options' => $handlers_options,
'#default_value' => $field->getSetting('handler'),
'#required' => TRUE,
'#ajax' => TRUE,
'#limit_validation_errors' => array(),
);
$form['handler']['handler_submit'] = array(
'#type' => 'submit',
'#value' => t('Change handler'),
'#limit_validation_errors' => array(),
'#attributes' => array(
'class' => array('js-hide'),
),
'#submit' => array('entity_reference_settings_ajax_submit'),
);
$form['handler']['handler_settings'] = array(
'#type' => 'container',
'#attributes' => array('class' => array('entity_reference-settings')),
);
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
$form['handler']['handler_settings'] += $handler->buildConfigurationForm(array(), $form_state);
return $form;
}
/**
* Form element validation handler; Invokes selection plugin's validation.
*
* @param array $form
* The form where the settings form is being included in.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state of the (entire) configuration form.
*/
public static function fieldSettingsFormValidate(array $form, FormStateInterface $form_state) {
$field = $form_state->getFormObject()->getEntity();
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
$handler->validateConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public static function getPreconfiguredOptions() {
$options = array();
// Add all the commonly referenced entity types as distinct pre-configured
// options.
$entity_types = \Drupal::entityManager()->getDefinitions();
$common_references = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
return $entity_type->isCommonReferenceTarget();
});
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
foreach ($common_references as $entity_type) {
$options[$entity_type->id()] = [
'label' => $entity_type->getLabel(),
'field_storage_config' => [
'settings' => [
'target_type' => $entity_type->id(),
]
]
];
}
return $options;
}
}
class ConfigurableEntityReferenceItem extends EntityReferenceItem { }

View file

@ -7,176 +7,14 @@
namespace Drupal\entity_reference\Plugin\views\display;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\display\EntityReference as ViewsEntityReference;
/**
* The plugin that handles an EntityReference display.
* Deprecated. The plugin that handles an EntityReference display.
*
* "entity_reference_display" is a custom property, used with
* \Drupal\views\Views::getApplicableViews() to retrieve all views with a
* 'Entity Reference' display.
* @deprecated in Drupal 8.0.x and will be removed in Drupal 9.0.x. Use
* \Drupal\views\Plugin\views\display\EntityReference instead.
*
* @ingroup views_display_plugins
*
* @ViewsDisplay(
* id = "entity_reference",
* title = @Translation("Entity Reference"),
* admin = @Translation("Entity Reference Source"),
* help = @Translation("Selects referenceable entities for an entity reference field."),
* theme = "views_view",
* register_theme = FALSE,
* uses_menu_links = FALSE,
* entity_reference_display = TRUE
* )
* @see \Drupal\views\Plugin\views\display\EntityReference
*/
class EntityReference extends DisplayPluginBase {
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::$useAJAX.
*/
protected $usesAJAX = FALSE;
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::$usesPager.
*/
protected $usesPager = FALSE;
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::$usesAttachments.
*/
protected $usesAttachments = FALSE;
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::defineOptions().
*/
protected function defineOptions() {
$options = parent::defineOptions();
// Force the style plugin to 'entity_reference_style' and the row plugin to
// 'fields'.
$options['style']['contains']['type'] = array('default' => 'entity_reference');
$options['defaults']['default']['style'] = FALSE;
$options['row']['contains']['type'] = array('default' => 'entity_reference');
$options['defaults']['default']['row'] = FALSE;
// Make sure the query is not cached.
$options['defaults']['default']['cache'] = FALSE;
// Set the display title to an empty string (not used in this display type).
$options['title']['default'] = '';
$options['defaults']['default']['title'] = FALSE;
return $options;
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::optionsSummary().
*
* Disable 'cache' and 'title' so it won't be changed.
*/
public function optionsSummary(&$categories, &$options) {
parent::optionsSummary($categories, $options);
unset($options['query']);
unset($options['title']);
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::getType().
*/
protected function getType() {
return 'entity_reference';
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::execute().
*/
public function execute() {
return $this->view->render($this->display['id']);
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::render().
*/
public function render() {
if (!empty($this->view->result) && $this->view->style_plugin->evenEmpty()) {
return $this->view->style_plugin->render($this->view->result);
}
return '';
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::usesExposed().
*/
public function usesExposed() {
return FALSE;
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::query().
*/
public function query() {
if (!empty($this->view->live_preview)) {
return;
}
// Make sure the id field is included in the results.
$id_field = $this->view->storage->get('base_field');
$this->id_field_alias = $this->view->query->addField($this->view->storage->get('base_table'), $id_field);
$options = $this->getOption('entity_reference_options');
// Restrict the autocomplete options based on what's been typed already.
if (isset($options['match'])) {
$style_options = $this->getOption('style');
$value = db_like($options['match']) . '%';
if ($options['match_operator'] != 'STARTS_WITH') {
$value = '%' . $value;
}
// Multiple search fields are OR'd together.
$conditions = db_or();
// Build the condition using the selected search fields.
foreach ($style_options['options']['search_fields'] as $field_id) {
if (!empty($field_id)) {
// Get the table and field names for the checked field.
$field_alias = $this->view->query->addField($this->view->field[$field_id]->table, $field_id);
$field = $this->view->query->fields[$field_alias];
// Add an OR condition for the field.
$conditions->condition($field['table'] . '.' . $field['field'], $value, 'LIKE');
}
}
$this->view->query->addWhere(0, $conditions);
}
// Add an IN condition for validation.
if (!empty($options['ids'])) {
$this->view->query->addWhere(0, $id_field, $options['ids']);
}
$this->view->setItemsPerPage($options['limit']);
}
/**
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::validate().
*/
public function validate() {
$errors = parent::validate();
// Verify that search fields are set up.
$style = $this->getOption('style');
if (!isset($style['options']['search_fields'])) {
$errors[] = $this->t('Display "@display" needs a selected search fields to work properly. See the settings for the Entity Reference list format.', array('@display' => $this->display['display_title']));
}
else {
// Verify that the search fields used actually exist.
$fields = array_keys($this->handlers['field']);
foreach ($style['options']['search_fields'] as $field_alias => $enabled) {
if ($enabled && !in_array($field_alias, $fields)) {
$errors[] = $this->t('Display "@display" uses field %field as search field, but the field is no longer present. See the settings for the Entity Reference list format.', array('@display' => $this->display['display_title'], '%field' => $field_alias));
}
}
}
return $errors;
}
}
class EntityReference extends ViewsEntityReference { }

View file

@ -7,56 +7,14 @@
namespace Drupal\entity_reference\Plugin\views\row;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\row\Fields;
use Drupal\views\Plugin\views\row\EntityReference as ViewsEntityReference;
/**
* EntityReference row plugin.
*
* @ingroup views_row_plugins
* @deprecated in Drupal 8.0.x and will be removed in Drupal 9.0.x. Use
* \Drupal\views\Plugin\views\row\EntityReference instead.
*
* @ViewsRow(
* id = "entity_reference",
* title = @Translation("Entity Reference inline fields"),
* help = @Translation("Displays the fields with an optional template."),
* theme = "views_view_fields",
* register_theme = FALSE,
* display_types = {"entity_reference"}
* )
* @see \Drupal\views\Plugin\views\row\EntityReference
*/
class EntityReference extends Fields {
/**
* Overrides \Drupal\views\Plugin\views\row\Fields::defineOptions().
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['separator'] = array('default' => '-');
return $options;
}
/**
* Overrides \Drupal\views\Plugin\views\row\Fields::buildOptionsForm().
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
// Expand the description of the 'Inline field' checkboxes.
$form['inline']['#description'] .= '<br />' . $this->t("<strong>Note:</strong> In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here." );
}
/**
* {@inheritdoc}
*/
public function preRender($row) {
// Force all fields to be inline by default.
if (empty($this->options['inline'])) {
$fields = $this->view->getHandlers('field', $this->displayHandler->display['id']);
$names = array_keys($fields);
$this->options['inline'] = array_combine($names, $names);
}
return parent::preRender($row);
}
}
class EntityReference extends ViewsEntityReference { }

View file

@ -7,103 +7,14 @@
namespace Drupal\entity_reference\Plugin\views\style;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\style\StylePluginBase;
use Drupal\views\Plugin\views\style\EntityReference as ViewsEntityReference;
/**
* EntityReference style plugin.
* Deprecated. EntityReference style plugin.
*
* @ingroup views_style_plugins
* @deprecated in Drupal 8.0.x and will be removed in Drupal 9.0.x. Use
* \Drupal\views\Plugin\views\style\EntityReference instead.
*
* @ViewsStyle(
* id = "entity_reference",
* title = @Translation("Entity Reference list"),
* help = @Translation("Returns results as a PHP array of labels and rendered rows."),
* theme = "views_view_unformatted",
* register_theme = FALSE,
* display_types = {"entity_reference"}
* )
* @see \Drupal\views\Plugin\views\style\EntityReference
*/
class EntityReference extends StylePluginBase {
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase::usesRowPlugin.
*/
protected $usesRowPlugin = TRUE;
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase::usesFields.
*/
protected $usesFields = TRUE;
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase::usesGrouping.
*/
protected $usesGrouping = FALSE;
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase\StylePluginBase::defineOptions().
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['search_fields'] = array('default' => array());
return $options;
}
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase\StylePluginBase::buildOptionsForm().
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$options = $this->displayHandler->getFieldLabels(TRUE);
$form['search_fields'] = array(
'#type' => 'checkboxes',
'#title' => $this->t('Search fields'),
'#options' => $options,
'#required' => TRUE,
'#default_value' => $this->options['search_fields'],
'#description' => $this->t('Select the field(s) that will be searched when using the autocomplete widget.'),
'#weight' => -3,
);
}
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase\StylePluginBase::render().
*/
public function render() {
if (!empty($this->view->live_preview)) {
return parent::render();
}
// Group the rows according to the grouping field, if specified.
$sets = $this->renderGrouping($this->view->result, $this->options['grouping']);
// Grab the alias of the 'id' field added by
// entity_reference_plugin_display.
$id_field_alias = $this->view->storage->get('base_field');
// @todo We don't display grouping info for now. Could be useful for select
// widget, though.
$results = array();
foreach ($sets as $records) {
foreach ($records as $values) {
$results[$values->{$id_field_alias}] = $this->view->rowPlugin->render($values);
// Sanitize HTML, remove line breaks and extra whitespace.
$results[$values->{$id_field_alias}]['#post_render'][] = function ($html, array $elements) {
return Xss::filterAdmin(preg_replace('/\s\s+/', ' ', str_replace("\n", '', $html)));
};
}
}
return $results;
}
/**
* {@inheritdoc}
*/
public function evenEmpty() {
return TRUE;
}
}
class EntityReference extends ViewsEntityReference { }

View file

@ -1,447 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceAdminTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\Core\Entity\Entity;
use Drupal\field_ui\Tests\FieldUiTestTrait;
use Drupal\node\Entity\Node;
use Drupal\simpletest\WebTestBase;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* Tests for the administrative UI.
*
* @group entity_reference
*/
class EntityReferenceAdminTest extends WebTestBase {
use FieldUiTestTrait;
/**
* Modules to install.
*
* Enable path module to ensure that the selection handler does not fail for
* entities with a path field.
* Enable views_ui module to see the no_view_help text.
*
* @var array
*/
public static $modules = array('node', 'field_ui', 'entity_reference', 'path', 'taxonomy', 'block', 'views', 'views_ui', 'entity_test');
/**
* The name of the content type created for testing purposes.
*
* @var string
*/
protected $type;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalPlaceBlock('system_breadcrumb_block');
// Create a content type, with underscores.
$type_name = strtolower($this->randomMachineName(8)) . '_test';
$type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
$this->type = $type->id();
// Create test user.
$admin_user = $this->drupalCreateUser(array(
'access content',
'administer node fields',
'administer node display',
'administer views',
'create ' . $type_name . ' content',
'edit own ' . $type_name . ' content',
));
$this->drupalLogin($admin_user);
}
/**
* Tests the Entity Reference Admin UI.
*/
public function testFieldAdminHandler() {
$bundle_path = 'admin/structure/types/manage/' . $this->type;
// First step: 'Add new field' on the 'Manage fields' page.
$this->drupalGet($bundle_path . '/fields/add-field');
// Check if the commonly referenced entity types appear in the list.
$this->assertOption('edit-new-storage-type', 'field_ui:entity_reference:node');
$this->assertOption('edit-new-storage-type', 'field_ui:entity_reference:user');
$this->drupalPostForm(NULL, array(
'label' => 'Test label',
'field_name' => 'test',
'new_storage_type' => 'entity_reference',
), t('Save and continue'));
// Node should be selected by default.
$this->assertFieldByName('settings[target_type]', 'node');
// Check that all entity types can be referenced.
$this->assertFieldSelectOptions('settings[target_type]', array_keys(\Drupal::entityManager()->getDefinitions()));
// Second step: 'Field settings' form.
$this->drupalPostForm(NULL, array(), t('Save field settings'));
// The base handler should be selected by default.
$this->assertFieldByName('settings[handler]', 'default:node');
// The base handler settings should be displayed.
$entity_type_id = 'node';
$bundles = entity_get_bundles($entity_type_id);
foreach ($bundles as $bundle_name => $bundle_info) {
$this->assertFieldByName('settings[handler_settings][target_bundles][' . $bundle_name . ']');
}
reset($bundles);
// Test the sort settings.
// Option 0: no sort.
$this->assertFieldByName('settings[handler_settings][sort][field]', '_none');
$this->assertNoFieldByName('settings[handler_settings][sort][direction]');
// Option 1: sort by field.
$this->drupalPostAjaxForm(NULL, array('settings[handler_settings][sort][field]' => 'nid'), 'settings[handler_settings][sort][field]');
$this->assertFieldByName('settings[handler_settings][sort][direction]', 'ASC');
// Test that a non-translatable base field is a sort option.
$this->assertFieldByXPath("//select[@name='settings[handler_settings][sort][field]']/option[@value='nid']");
// Test that a translatable base field is a sort option.
$this->assertFieldByXPath("//select[@name='settings[handler_settings][sort][field]']/option[@value='title']");
// Test that a configurable field is a sort option.
$this->assertFieldByXPath("//select[@name='settings[handler_settings][sort][field]']/option[@value='body.value']");
// Set back to no sort.
$this->drupalPostAjaxForm(NULL, array('settings[handler_settings][sort][field]' => '_none'), 'settings[handler_settings][sort][field]');
$this->assertNoFieldByName('settings[handler_settings][sort][direction]');
// Third step: confirm.
$this->drupalPostForm(NULL, array(
'required' => '1',
'settings[handler_settings][target_bundles][' . key($bundles) . ']' => key($bundles),
), t('Save settings'));
// Check that the field appears in the overview form.
$this->assertFieldByXPath('//table[@id="field-overview"]//tr[@id="field-test"]/td[1]', 'Test label', 'Field was created and appears in the overview page.');
// Check that the field settings form can be submitted again, even when the
// field is required.
// The first 'Edit' link is for the Body field.
$this->clickLink(t('Edit'), 1);
$this->drupalPostForm(NULL, array(), t('Save settings'));
// Switch the target type to 'taxonomy_term' and check that the settings
// specific to its selection handler are displayed.
$field_name = 'node.' . $this->type . '.field_test';
$edit = array(
'settings[target_type]' => 'taxonomy_term',
);
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
$this->drupalGet($bundle_path . '/fields/' . $field_name);
$this->assertFieldByName('settings[handler_settings][auto_create]');
// Switch the target type to 'user' and check that the settings specific to
// its selection handler are displayed.
$field_name = 'node.' . $this->type . '.field_test';
$edit = array(
'settings[target_type]' => 'user',
);
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
$this->drupalGet($bundle_path . '/fields/' . $field_name);
$this->assertFieldByName('settings[handler_settings][filter][type]', '_none');
// Switch the target type to 'node'.
$field_name = 'node.' . $this->type . '.field_test';
$edit = array(
'settings[target_type]' => 'node',
);
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
// Try to select the views handler.
$edit = array(
'settings[handler]' => 'views',
);
$this->drupalPostAjaxForm($bundle_path . '/fields/' . $field_name, $edit, 'settings[handler]');
$this->assertRaw(t('No eligible views were found. <a href="@create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href="@existing">existing view</a>.', array(
'@create' => \Drupal::url('views_ui.add'),
'@existing' => \Drupal::url('entity.view.collection'),
)));
$this->drupalPostForm(NULL, $edit, t('Save settings'));
// If no eligible view is available we should see a message.
$this->assertText('The views entity selection mode requires a view.');
// Enable the entity_reference_test module which creates an eligible view.
$this->container->get('module_installer')->install(array('entity_reference_test'));
$this->resetAll();
$this->drupalGet($bundle_path . '/fields/' . $field_name);
$this->drupalPostAjaxForm($bundle_path . '/fields/' . $field_name, $edit, 'settings[handler]');
$edit = array(
'settings[handler_settings][view][view_and_display]' => 'test_entity_reference:entity_reference_1',
);
$this->drupalPostForm(NULL, $edit, t('Save settings'));
$this->assertResponse(200);
// Switch the target type to 'entity_test'.
$edit = array(
'settings[target_type]' => 'entity_test',
);
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
$this->drupalGet($bundle_path . '/fields/' . $field_name);
$edit = array(
'settings[handler]' => 'views',
);
$this->drupalPostAjaxForm($bundle_path . '/fields/' . $field_name, $edit, 'settings[handler]');
$edit = array(
'required' => FALSE,
'settings[handler_settings][view][view_and_display]' => 'test_entity_reference_entity_test:entity_reference_1',
);
$this->drupalPostForm(NULL, $edit, t('Save settings'));
$this->assertResponse(200);
// Create a new view and display it as a entity reference.
$edit = array(
'id' => 'node_test_view',
'label' => 'Node Test View',
'show[wizard_key]' => 'node',
'page[create]' => 1,
'page[title]' => 'Test Node View',
'page[path]' => 'test/node/view',
'page[style][style_plugin]' => 'default',
'page[style][row_plugin]' => 'fields',
);
$this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit'));
$this->drupalPostForm(NULL, array(), t('Duplicate as Entity Reference'));
$this->clickLink(t('Settings'));
$edit = array(
'style_options[search_fields][title]' => 'title',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm('admin/structure/views/view/node_test_view/edit/entity_reference_1', array(), t('Save'));
$this->clickLink(t('Settings'));
// Create a test entity reference field.
$field_name = 'test_entity_ref_field';
$edit = array(
'new_storage_type' => 'field_ui:entity_reference:node',
'label' => 'Test Entity Reference Field',
'field_name' => $field_name,
);
$this->drupalPostForm($bundle_path . '/fields/add-field', $edit, t('Save and continue'));
$this->drupalPostForm(NULL, array(), t('Save field settings'));
// Add the view to the test field.
$edit = array(
'settings[handler]' => 'views',
);
$this->drupalPostAjaxForm(NULL, $edit, 'settings[handler]');
$edit = array(
'required' => FALSE,
'settings[handler_settings][view][view_and_display]' => 'node_test_view:entity_reference_1',
);
$this->drupalPostForm(NULL, $edit, t('Save settings'));
// Create nodes.
$node1 = Node::create([
'type' => $this->type,
'title' => 'Foo Node',
]);
$node1->save();
$node2 = Node::create([
'type' => $this->type,
'title' => 'Foo Node',
]);
$node2->save();
// Try to add a new node and fill the entity reference field.
$this->drupalGet('node/add/' . $this->type);
$result = $this->xpath('//input[@name="field_test_entity_ref_field[0][target_id]" and contains(@data-autocomplete-path, "/entity_reference_autocomplete/node/views/")]');
$target_url = $this->getAbsoluteUrl($result[0]['data-autocomplete-path']);
$this->drupalGet($target_url, array('query' => array('q' => 'Foo')));
$this->assertRaw($node1->getTitle() . ' (' . $node1->id() . ')');
$this->assertRaw($node2->getTitle() . ' (' . $node2->id() . ')');
$edit = array(
'title[0][value]' => 'Example',
'field_test_entity_ref_field[0][target_id]' => 'Test'
);
$this->drupalPostForm('node/add/' . $this->type, $edit, t('Save'));
// Assert that entity reference autocomplete field is validated.
$this->assertText(t('1 error has been found: Test Entity Reference Field'), 'Node save failed when required entity reference field was not correctly filled.');
$this->assertText(t('There are no entities matching "@entity"', ['@entity' => 'Test']));
$edit = array(
'title[0][value]' => 'Test',
'field_test_entity_ref_field[0][target_id]' => $node1->getTitle()
);
$this->drupalPostForm('node/add/' . $this->type, $edit, t('Save'));
// Assert the results multiple times to avoid sorting problem of nodes with
// the same title.
$this->assertText(t('1 error has been found: Test Entity Reference Field'));
$this->assertText(t('Multiple entities match this reference;'));
$this->assertText(t("@node1", ['@node1' => $node1->getTitle() . ' (' . $node1->id() . ')']));
$this->assertText(t("@node2", ['@node2' => $node2->getTitle() . ' (' . $node2->id() . ')']));
$edit = array(
'title[0][value]' => 'Test',
'field_test_entity_ref_field[0][target_id]' => $node1->getTitle() . '(' . $node1->id() . ')'
);
$this->drupalPostForm('node/add/' . $this->type, $edit, t('Save'));
$this->assertLink($node1->getTitle());
}
/**
* Tests the formatters for the Entity References.
*/
public function testAvailableFormatters() {
// Create a new vocabulary.
Vocabulary::create(array('vid' => 'tags', 'name' => 'tags'))->save();
// Create entity reference field with taxonomy term as a target.
$taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', 'tags');
// Create entity reference field with user as a target.
$user_field_name = $this->createEntityReferenceField('user');
// Create entity reference field with node as a target.
$node_field_name = $this->createEntityReferenceField('node', $this->type);
// Create entity reference field with date format as a target.
$date_format_field_name = $this->createEntityReferenceField('date_format');
// Display all newly created Entity Reference configuration.
$this->drupalGet('admin/structure/types/manage/' . $this->type . '/display');
// Check for Taxonomy Term select box values.
// Test if Taxonomy Term Entity Reference Field has the correct formatters.
$this->assertFieldSelectOptions('fields[field_' . $taxonomy_term_field_name . '][type]', array(
'entity_reference_label',
'entity_reference_entity_id',
'entity_reference_rss_category',
'entity_reference_entity_view',
'hidden',
));
// Test if User Reference Field has the correct formatters.
// Author should be available for this field.
// RSS Category should not be available for this field.
$this->assertFieldSelectOptions('fields[field_' . $user_field_name . '][type]', array(
'author',
'entity_reference_entity_id',
'entity_reference_entity_view',
'entity_reference_label',
'hidden',
));
// Test if Node Entity Reference Field has the correct formatters.
// RSS Category should not be available for this field.
$this->assertFieldSelectOptions('fields[field_' . $node_field_name . '][type]', array(
'entity_reference_label',
'entity_reference_entity_id',
'entity_reference_entity_view',
'hidden',
));
// Test if Date Format Reference Field has the correct formatters.
// RSS Category & Entity View should not be available for this field.
// This could be any field without a ViewBuilder.
$this->assertFieldSelectOptions('fields[field_' . $date_format_field_name . '][type]', array(
'entity_reference_label',
'entity_reference_entity_id',
'hidden',
));
}
/**
* Creates a new Entity Reference fields with a given target type.
*
* @param $target_type
* The name of the target type
* @param $bundle
* Name of the bundle
* Default = NULL
* @return string
* Returns the generated field name
*/
public function createEntityReferenceField($target_type, $bundle = NULL) {
// Generates a bundle path for the newly created content type.
$bundle_path = 'admin/structure/types/manage/' . $this->type;
// Generate a random field name, must be only lowercase characters.
$field_name = strtolower($this->randomMachineName());
$storage_edit = $field_edit = array();
$storage_edit['settings[target_type]'] = $target_type;
if ($bundle) {
$field_edit['settings[handler_settings][target_bundles][' . $bundle . ']'] = TRUE;
}
$this->fieldUIAddNewField($bundle_path, $field_name, NULL, 'entity_reference', $storage_edit, $field_edit);
// Returns the generated field name.
return $field_name;
}
/**
* Checks if a select element contains the specified options.
*
* @param string $name
* The field name.
* @param array $expected_options
* An array of expected options.
*
* @return bool
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertFieldSelectOptions($name, array $expected_options) {
$xpath = $this->buildXPathQuery('//select[@name=:name]', array(':name' => $name));
$fields = $this->xpath($xpath);
if ($fields) {
$field = $fields[0];
$options = $this->getAllOptionsList($field);
sort($options);
sort($expected_options);
return $this->assertIdentical($options, $expected_options);
}
else {
return $this->fail('Unable to find field ' . $name);
}
}
/**
* Extracts all options from a select element.
*
* @param \SimpleXMLElement $element
* The select element field information.
*
* @return array
* An array of option values as strings.
*/
protected function getAllOptionsList(\SimpleXMLElement $element) {
$options = array();
// Add all options items.
foreach ($element->option as $option) {
$options[] = (string) $option['value'];
}
// Loops trough all the option groups
foreach ($element->optgroup as $optgroup) {
$options = array_merge($this->getAllOptionsList($optgroup), $options);
}
return $options;
}
}

View file

@ -1,137 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceAutoCreateTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\simpletest\WebTestBase;
use Drupal\node\Entity\Node;
/**
* Tests creating new entity (e.g. taxonomy-term) from an autocomplete widget.
*
* @group entity_reference
*/
class EntityReferenceAutoCreateTest extends WebTestBase {
public static $modules = array('entity_reference', 'node');
/**
* The name of a content type that will reference $referencedType.
*
* @var string
*/
protected $referencingType;
/**
* The name of a content type that will be referenced by $referencingType.
*
* @var string
*/
protected $referencedType;
protected function setUp() {
parent::setUp();
// Create "referencing" and "referenced" node types.
$referencing = $this->drupalCreateContentType();
$this->referencingType = $referencing->id();
$referenced = $this->drupalCreateContentType();
$this->referencedType = $referenced->id();
entity_create('field_storage_config', array(
'field_name' => 'test_field',
'entity_type' => 'node',
'translatable' => FALSE,
'entity_types' => array(),
'settings' => array(
'target_type' => 'node',
),
'type' => 'entity_reference',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
))->save();
entity_create('field_config', array(
'label' => 'Entity reference field',
'field_name' => 'test_field',
'entity_type' => 'node',
'bundle' => $referencing->id(),
'settings' => array(
'handler' => 'default',
'handler_settings' => array(
// Reference a single vocabulary.
'target_bundles' => array(
$referenced->id(),
),
// Enable auto-create.
'auto_create' => TRUE,
),
),
))->save();
entity_get_display('node', $referencing->id(), 'default')
->setComponent('test_field')
->save();
entity_get_form_display('node', $referencing->id(), 'default')
->setComponent('test_field', array(
'type' => 'entity_reference_autocomplete',
))
->save();
}
/**
* Tests that the autocomplete input element appears and the creation of a new
* entity.
*/
public function testAutoCreate() {
$user1 = $this->drupalCreateUser(array('access content', "create $this->referencingType content"));
$this->drupalLogin($user1);
$this->drupalGet('node/add/' . $this->referencingType);
$this->assertFieldByXPath('//input[@id="edit-test-field-0-target-id" and contains(@class, "form-autocomplete")]', NULL, 'The autocomplete input element appears.');
$new_title = $this->randomMachineName();
// Assert referenced node does not exist.
$base_query = \Drupal::entityQuery('node');
$base_query
->condition('type', $this->referencedType)
->condition('title', $new_title);
$query = clone $base_query;
$result = $query->execute();
$this->assertFalse($result, 'Referenced node does not exist yet.');
$edit = array(
'title[0][value]' => $this->randomMachineName(),
'test_field[0][target_id]' => $new_title,
);
$this->drupalPostForm("node/add/$this->referencingType", $edit, 'Save');
// Assert referenced node was created.
$query = clone $base_query;
$result = $query->execute();
$this->assertTrue($result, 'Referenced node was created.');
$referenced_nid = key($result);
$referenced_node = Node::load($referenced_nid);
// Assert the referenced node is associated with referencing node.
$result = \Drupal::entityQuery('node')
->condition('type', $this->referencingType)
->execute();
$referencing_nid = key($result);
$referencing_node = Node::load($referencing_nid);
$this->assertEqual($referenced_nid, $referencing_node->test_field->target_id, 'Newly created node is referenced from the referencing node.');
// Now try to view the node and check that the referenced node is shown.
$this->drupalGet('node/' . $referencing_node->id());
$this->assertText($referencing_node->label(), 'Referencing node label found.');
$this->assertText($referenced_node->label(), 'Referenced node label found.');
}
}

View file

@ -1,160 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceFieldDefaultValueTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\Component\Utility\Unicode;
use Drupal\config\Tests\SchemaCheckTestTrait;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\simpletest\WebTestBase;
/**
* Tests entity reference field default values storage in CMI.
*
* @group entity_reference
*/
class EntityReferenceFieldDefaultValueTest extends WebTestBase {
use SchemaCheckTestTrait;
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('entity_reference', 'field_ui', 'node');
/**
* A user with permission to administer content types, node fields, etc.
*
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
protected function setUp() {
parent::setUp();
// Create default content type.
$this->drupalCreateContentType(array('type' => 'reference_content'));
$this->drupalCreateContentType(array('type' => 'referenced_content'));
// Create admin user.
$this->adminUser = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer node form display', 'bypass node access'));
$this->drupalLogin($this->adminUser);
}
/**
* Tests that default values are correctly translated to UUIDs in config.
*/
function testEntityReferenceDefaultValue() {
// Create a node to be referenced.
$referenced_node = $this->drupalCreateNode(array('type' => 'referenced_content'));
$field_name = Unicode::strtolower($this->randomMachineName());
$field_storage = entity_create('field_storage_config', array(
'field_name' => $field_name,
'entity_type' => 'node',
'type' => 'entity_reference',
'settings' => array('target_type' => 'node'),
));
$field_storage->save();
$field = entity_create('field_config', array(
'field_storage' => $field_storage,
'bundle' => 'reference_content',
'settings' => array(
'handler' => 'default',
'handler_settings' => array(
'target_bundles' => array('referenced_content'),
'sort' => array('field' => '_none'),
),
),
));
$field->save();
// Set created node as default_value.
$field_edit = array(
'default_value_input[' . $field_name . '][0][target_id]' => $referenced_node->getTitle() . ' (' .$referenced_node->id() . ')',
);
$this->drupalPostForm('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name, $field_edit, t('Save settings'));
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name);
$this->assertRaw('name="default_value_input[' . $field_name . '][0][target_id]" value="' . $referenced_node->getTitle() .' (' .$referenced_node->id() . ')', 'The default value is selected in instance settings page');
// Check if the ID has been converted to UUID in config entity.
$config_entity = $this->config('field.field.node.reference_content.' . $field_name)->get();
$this->assertTrue(isset($config_entity['default_value'][0]['target_uuid']), 'Default value contains target_uuid property');
$this->assertEqual($config_entity['default_value'][0]['target_uuid'], $referenced_node->uuid(), 'Content uuid and config entity uuid are the same');
// Ensure the configuration has the expected dependency on the entity that
// is being used a default value.
$this->assertEqual(array($referenced_node->getConfigDependencyName()), $config_entity['dependencies']['content']);
// Clear field definitions cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Create a new node to check that UUID has been converted to numeric ID.
$new_node = entity_create('node', array('type' => 'reference_content'));
$this->assertEqual($new_node->get($field_name)->offsetGet(0)->target_id, $referenced_node->id());
// Ensure that the entity reference config schemas are correct.
$field_config = $this->config('field.field.node.reference_content.' . $field_name);
$this->assertConfigSchema(\Drupal::service('config.typed'), $field_config->getName(), $field_config->get());
$field_storage_config = $this->config('field.storage.node.' . $field_name);
$this->assertConfigSchema(\Drupal::service('config.typed'), $field_storage_config->getName(), $field_storage_config->get());
}
/**
* Tests that dependencies due to default values can be removed.
*
* @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::onDependencyRemoval()
*/
function testEntityReferenceDefaultConfigValue() {
// Create a node to be referenced.
$referenced_node_type = $this->drupalCreateContentType(array('type' => 'referenced_config_to_delete'));
$referenced_node_type2 = $this->drupalCreateContentType(array('type' => 'referenced_config_to_preserve'));
$field_name = Unicode::strtolower($this->randomMachineName());
$field_storage = entity_create('field_storage_config', array(
'field_name' => $field_name,
'entity_type' => 'node',
'type' => 'entity_reference',
'settings' => array('target_type' => 'node_type'),
'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED,
));
$field_storage->save();
$field = entity_create('field_config', array(
'field_storage' => $field_storage,
'bundle' => 'reference_content',
'settings' => array(
'handler' => 'default',
'handler_settings' => array(
'sort' => array('field' => '_none'),
),
),
));
$field->save();
// Set created node as default_value.
$field_edit = array(
'default_value_input[' . $field_name . '][0][target_id]' => $referenced_node_type->label() . ' (' .$referenced_node_type->id() . ')',
'default_value_input[' . $field_name . '][1][target_id]' => $referenced_node_type2->label() . ' (' .$referenced_node_type2->id() . ')',
);
$this->drupalPostForm('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name, $field_edit, t('Save settings'));
// Check that the field has a dependency on the default value.
$config_entity = $this->config('field.field.node.reference_content.' . $field_name)->get();
$this->assertTrue(in_array($referenced_node_type->getConfigDependencyName(), $config_entity['dependencies']['config'], TRUE), 'The node type referenced_config_to_delete is a dependency of the field.');
$this->assertTrue(in_array($referenced_node_type2->getConfigDependencyName(), $config_entity['dependencies']['config'], TRUE), 'The node type referenced_config_to_preserve is a dependency of the field.');
// Check that the field does not have a dependency on the default value
// after deleting the node type.
$referenced_node_type->delete();
$config_entity = $this->config('field.field.node.reference_content.' . $field_name)->get();
$this->assertFalse(in_array($referenced_node_type->getConfigDependencyName(), $config_entity['dependencies']['config'], TRUE), 'The node type referenced_config_to_delete not a dependency of the field.');
$this->assertTrue(in_array($referenced_node_type2->getConfigDependencyName(), $config_entity['dependencies']['config'], TRUE), 'The node type referenced_config_to_preserve is a dependency of the field.');
}
}

View file

@ -1,301 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceFieldTranslatedReferenceViewTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\simpletest\WebTestBase;
/**
* Tests the translation of entity reference field display on nodes.
*
* @group entity_reference
*/
class EntityReferenceFieldTranslatedReferenceViewTest extends WebTestBase {
/**
* The langcode of the source language.
*
* @var string
*/
protected $baseLangcode = 'en';
/**
* Target langcode for translation.
*
* @var string
*/
protected $translateToLangcode = 'hu';
/**
* The test entity type name.
*
* @var string
*/
protected $testEntityTypeName = 'node';
/**
* Entity type which have the entity reference field.
*
* @var \Drupal\node\Entity\NodeType
*/
protected $referrerType;
/**
* Entity type which can be referenced.
*
* @var \Drupal\node\Entity\NodeType
*/
protected $referencedType;
/**
* The referrer entity.
*
* @var \Drupal\node\Entity\Node
*/
protected $referrerEntity;
/**
* The entity to refer.
*
* @var \Drupal\node\Entity\Node
*/
protected $referencedEntityWithoutTranslation;
/**
* The entity to refer.
*
* @var \Drupal\node\Entity\Node
*/
protected $referencedEntityWithTranslation;
/**
* The machine name of the entity reference field.
*
* @var string
*/
protected $referenceFieldName = 'test_reference_field';
/**
* The label of the untranslated referenced entity, used in assertions.
*
* @var string
*/
protected $labelOfNotTranslatedReference;
/**
* The original label of the referenced entity, used in assertions.
*
* @var string
*/
protected $originalLabel;
/**
* The translated label of the referenced entity, used in assertions.
*
* @var string
*/
protected $translatedLabel;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array(
'language',
'content_translation',
'entity_reference',
'node',
);
protected function setUp() {
parent::setUp();
$this->labelOfNotTranslatedReference = $this->randomMachineName();
$this->originalLabel = $this->randomMachineName();
$this->translatedLabel = $this->randomMachineName();
$this->setUpLanguages();
// We setup languages, so we need to ensure that the language manager
// and language path processor is updated.
$this->rebuildContainer();
$this->setUpContentTypes();
$this->enableTranslation();
$this->setUpEntityReferenceField();
$this->createContent();
}
/**
* Tests if the translated entity is displayed in an entity reference field.
*/
public function testTranslatedEntityReferenceDisplay() {
$url = $this->referrerEntity->urlInfo();
$translation_url = $this->referrerEntity->urlInfo('canonical', ['language' => ConfigurableLanguage::load($this->translateToLangcode)]);
$this->drupalGet($url);
$this->assertText($this->labelOfNotTranslatedReference, 'The label of not translated reference is displayed.');
$this->assertText($this->originalLabel, 'The default label of translated reference is displayed.');
$this->assertNoText($this->translatedLabel, 'The translated label of translated reference is not displayed.');
$this->drupalGet($translation_url);
$this->assertText($this->labelOfNotTranslatedReference, 'The label of not translated reference is displayed.');
$this->assertNoText($this->originalLabel, 'The default label of translated reference is not displayed.');
$this->assertText($this->translatedLabel, 'The translated label of translated reference is displayed.');
}
/**
* Adds additional languages.
*/
protected function setUpLanguages() {
ConfigurableLanguage::createFromLangcode($this->translateToLangcode)->save();
}
/**
* Creates a test subject contents, with translation.
*/
protected function createContent() {
$this->referencedEntityWithTranslation = $this->createReferencedEntityWithTranslation();
$this->referencedEntityWithoutTranslation = $this->createNotTranslatedReferencedEntity();
$this->referrerEntity = $this->createReferrerEntity();
}
/**
* Enables translations where it needed.
*/
protected function enableTranslation() {
// Enable translation for the entity types and ensure the change is picked
// up.
\Drupal::service('content_translation.manager')->setEnabled($this->testEntityTypeName, $this->referrerType->id(), TRUE);
\Drupal::service('content_translation.manager')->setEnabled($this->testEntityTypeName, $this->referencedType->id(), TRUE);
drupal_static_reset();
\Drupal::entityManager()->clearCachedDefinitions();
\Drupal::service('router.builder')->rebuild();
\Drupal::service('entity.definition_update_manager')->applyUpdates();
}
/**
* Adds term reference field for the article content type.
*/
protected function setUpEntityReferenceField() {
entity_create('field_storage_config', array(
'field_name' => $this->referenceFieldName,
'entity_type' => $this->testEntityTypeName,
'type' => 'entity_reference',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'translatable' => TRUE,
'settings' => array(
'allowed_values' => array(
array(
'target_type' => $this->testEntityTypeName,
),
),
),
))->save();
entity_create('field_config', array(
'field_name' => $this->referenceFieldName,
'bundle' => $this->referrerType->id(),
'entity_type' => $this->testEntityTypeName,
))
->save();
entity_get_form_display($this->testEntityTypeName, $this->referrerType->id(), 'default')
->setComponent($this->referenceFieldName, array(
'type' => 'entity_reference_autocomplete',
))
->save();
entity_get_display($this->testEntityTypeName, $this->referrerType->id(), 'default')
->setComponent($this->referenceFieldName, array(
'type' => 'entity_reference_label',
))
->save();
}
/**
* Create content types.
*/
protected function setUpContentTypes() {
$this->referrerType = $this->drupalCreateContentType(array(
'type' => 'referrer',
'name' => 'Referrer',
));
$this->referencedType = $this->drupalCreateContentType(array(
'type' => 'referenced_page',
'name' => 'Referenced Page',
));
}
/**
* Create a referenced entity with a translation.
*/
protected function createReferencedEntityWithTranslation() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->originalLabel,
'type' => $this->referencedType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
'langcode' => $this->baseLangcode,
));
$node->save();
$node->addTranslation($this->translateToLangcode, array(
'title' => $this->translatedLabel,
));
$node->save();
return $node;
}
/**
* Create the referenced entity.
*/
protected function createNotTranslatedReferencedEntity() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->labelOfNotTranslatedReference,
'type' => $this->referencedType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
'langcode' => $this->baseLangcode,
));
$node->save();
return $node;
}
/**
* Create the referrer entity.
*/
protected function createReferrerEntity() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->randomMachineName(),
'type' => $this->referrerType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
$this->referenceFieldName => array(
array('target_id' => $this->referencedEntityWithTranslation->id()),
array('target_id' => $this->referencedEntityWithoutTranslation->id()),
),
'langcode' => $this->baseLangcode,
));
$node->save();
$node->addTranslation($this->translateToLangcode, $node->toArray());
$node->save();
return $node;
}
}

View file

@ -1,224 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceIntegrationTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\config\Tests\AssertConfigEntityImportTrait;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\entity_reference\Tests\EntityReferenceTestTrait;
use Drupal\field\Entity\FieldConfig;
use Drupal\simpletest\WebTestBase;
/**
* Tests various Entity reference UI components.
*
* @group entity_reference
*/
class EntityReferenceIntegrationTest extends WebTestBase {
use AssertConfigEntityImportTrait;
use EntityReferenceTestTrait;
/**
* The entity type used in this test.
*
* @var string
*/
protected $entityType = 'entity_test';
/**
* The bundle used in this test.
*
* @var string
*/
protected $bundle = 'entity_test';
/**
* The name of the field used in this test.
*
* @var string
*/
protected $fieldName;
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('config_test', 'entity_test', 'entity_reference', 'field_ui');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create a test user.
$web_user = $this->drupalCreateUser(array('administer entity_test content', 'administer entity_test fields', 'view test entity'));
$this->drupalLogin($web_user);
}
/**
* Tests the entity reference field with all its supported field widgets.
*/
public function testSupportedEntityTypesAndWidgets() {
foreach ($this->getTestEntities() as $key => $referenced_entities) {
$this->fieldName = 'field_test_' . $referenced_entities[0]->getEntityTypeId();
// Create an Entity reference field.
$this->createEntityReferenceField($this->entityType, $this->bundle, $this->fieldName, $this->fieldName, $referenced_entities[0]->getEntityTypeId(), 'default', array(), 2);
// Test the default 'entity_reference_autocomplete' widget.
entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName)->save();
$entity_name = $this->randomMachineName();
$edit = array(
'name[0][value]' => $entity_name,
$this->fieldName . '[0][target_id]' => $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')',
// Test an input of the entity label without a ' (entity_id)' suffix.
$this->fieldName . '[1][target_id]' => $referenced_entities[1]->label(),
);
$this->drupalPostForm($this->entityType . '/add', $edit, t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
// Try to post the form again with no modification and check if the field
// values remain the same.
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$this->drupalGet($this->entityType . '/manage/' . $entity->id());
$this->assertFieldByName($this->fieldName . '[0][target_id]', $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')');
$this->assertFieldByName($this->fieldName . '[1][target_id]', $referenced_entities[1]->label() . ' (' . $referenced_entities[1]->id() . ')');
$this->drupalPostForm(NULL, array(), t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
// Test the 'entity_reference_autocomplete_tags' widget.
entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName, array(
'type' => 'entity_reference_autocomplete_tags',
))->save();
$entity_name = $this->randomMachineName();
$target_id = $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')';
// Test an input of the entity label without a ' (entity_id)' suffix.
$target_id .= ', ' . $referenced_entities[1]->label();
$edit = array(
'name[0][value]' => $entity_name,
$this->fieldName . '[target_id]' => $target_id,
);
$this->drupalPostForm($this->entityType . '/add', $edit, t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
// Try to post the form again with no modification and check if the field
// values remain the same.
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$this->drupalGet($this->entityType . '/manage/' . $entity->id());
$this->assertFieldByName($this->fieldName . '[target_id]', $target_id . ' (' . $referenced_entities[1]->id() . ')');
$this->drupalPostForm(NULL, array(), t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
// Test all the other widgets supported by the entity reference field.
// Since we don't know the form structure for these widgets, just test
// that editing and saving an already created entity works.
$exclude = array('entity_reference_autocomplete', 'entity_reference_autocomplete_tags');
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$supported_widgets = \Drupal::service('plugin.manager.field.widget')->getOptions('entity_reference');
$supported_widget_types = array_diff(array_keys($supported_widgets), $exclude);
foreach ($supported_widget_types as $widget_type) {
entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName, array(
'type' => $widget_type,
))->save();
$this->drupalPostForm($this->entityType . '/manage/' . $entity->id(), array(), t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
}
// Reset to the default 'entity_reference_autocomplete' widget.
entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName)->save();
// Set first entity as the default_value.
$field_edit = array(
'default_value_input[' . $this->fieldName . '][0][target_id]' => $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')',
);
if ($key == 'content') {
$field_edit['settings[handler_settings][target_bundles][' . $referenced_entities[0]->getEntityTypeId() . ']'] = TRUE;
}
$this->drupalPostForm($this->entityType . '/structure/' . $this->bundle .'/fields/' . $this->entityType . '.' . $this->bundle . '.' . $this->fieldName, $field_edit, t('Save settings'));
// Ensure the configuration has the expected dependency on the entity that
// is being used a default value.
$field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
$this->assertTrue(in_array($referenced_entities[0]->getConfigDependencyName(), $field->getDependencies()[$key]), SafeMarkup::format('Expected @type dependency @name found', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
// Ensure that the field can be imported without change even after the
// default value deleted.
$referenced_entities[0]->delete();
// Reload the field since deleting the default value can change the field.
\Drupal::entityManager()->getStorage($field->getEntityTypeId())->resetCache([$field->id()]);
$field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
$this->assertConfigEntityImport($field);
// Once the default value has been removed after saving the dependency
// should be removed.
$field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
$field->save();
$dependencies = $field->getDependencies();
$this->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]->getConfigDependencyName(), $dependencies[$key]), SafeMarkup::format('@type dependency @name does not exist.', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
}
}
/**
* Asserts that the reference field values are correct.
*
* @param string $entity_name
* The name of the test entity.
* @param \Drupal\Core\Entity\EntityInterface[] $referenced_entities
* An array of referenced entities.
*/
protected function assertFieldValues($entity_name, $referenced_entities) {
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', array('%entity_type' => $this->entityType)));
$this->assertEqual($entity->{$this->fieldName}->target_id, $referenced_entities[0]->id());
$this->assertEqual($entity->{$this->fieldName}->entity->id(), $referenced_entities[0]->id());
$this->assertEqual($entity->{$this->fieldName}->entity->label(), $referenced_entities[0]->label());
$this->assertEqual($entity->{$this->fieldName}[1]->target_id, $referenced_entities[1]->id());
$this->assertEqual($entity->{$this->fieldName}[1]->entity->id(), $referenced_entities[1]->id());
$this->assertEqual($entity->{$this->fieldName}[1]->entity->label(), $referenced_entities[1]->label());
}
/**
* Creates two content and two config test entities.
*
* @return array
* An array of entity objects.
*/
protected function getTestEntities() {
$config_entity_1 = entity_create('config_test', array('id' => $this->randomMachineName(), 'label' => $this->randomMachineName()));
$config_entity_1->save();
$config_entity_2 = entity_create('config_test', array('id' => $this->randomMachineName(), 'label' => $this->randomMachineName()));
$config_entity_2->save();
$content_entity_1 = entity_create('entity_test', array('name' => $this->randomMachineName()));
$content_entity_1->save();
$content_entity_2 = entity_create('entity_test', array('name' => $this->randomMachineName()));
$content_entity_2->save();
return array(
'config' => array(
$config_entity_1,
$config_entity_2,
),
'content' => array(
$content_entity_1,
$content_entity_2,
),
);
}
}

View file

@ -1,69 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceTestTrait.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Provides common functionality for the EntityReference test classes.
*/
trait EntityReferenceTestTrait {
/**
* Creates a field of an entity reference field storage on the specified bundle.
*
* @param string $entity_type
* The type of entity the field will be attached to.
* @param string $bundle
* The bundle name of the entity the field will be attached to.
* @param string $field_name
* The name of the field; if it already exists, a new instance of the existing
* field will be created.
* @param string $field_label
* The label of the field.
* @param string $target_entity_type
* The type of the referenced entity.
* @param string $selection_handler
* The selection handler used by this field.
* @param array $selection_handler_settings
* An array of settings supported by the selection handler specified above.
* (e.g. 'target_bundles', 'sort', 'auto_create', etc).
* @param int $cardinality
* The cardinality of the field.
*
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
*/
protected function createEntityReferenceField($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = array(), $cardinality = 1) {
// Look for or add the specified field to the requested entity bundle.
if (!FieldStorageConfig::loadByName($entity_type, $field_name)) {
FieldStorageConfig::create(array(
'field_name' => $field_name,
'type' => 'entity_reference',
'entity_type' => $entity_type,
'cardinality' => $cardinality,
'settings' => array(
'target_type' => $target_entity_type,
),
))->save();
}
if (!FieldConfig::loadByName($entity_type, $bundle, $field_name)) {
FieldConfig::create(array(
'field_name' => $field_name,
'entity_type' => $entity_type,
'bundle' => $bundle,
'label' => $field_label,
'settings' => array(
'handler' => $selection_handler,
'handler_settings' => $selection_handler_settings,
),
))->save();
}
}
}

View file

@ -1,232 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\Views\EntityReferenceRelationshipTest.
*/
namespace Drupal\entity_reference\Tests\Views;
use Drupal\entity_reference\Tests\EntityReferenceTestTrait;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\entity_test\Entity\EntityTestMul;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewKernelTestBase;
use Drupal\views\Views;
/**
* Tests entity reference relationship data.
*
* @group entity_reference
* @see entity_reference_field_views_data()
*/
class EntityReferenceRelationshipTest extends ViewKernelTestBase {
use EntityReferenceTestTrait;
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array(
'test_entity_reference_entity_test_view',
'test_entity_reference_reverse_entity_test_view',
'test_entity_reference_entity_test_mul_view',
'test_entity_reference_reverse_entity_test_mul_view',
);
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('user', 'field', 'entity_test', 'entity_reference', 'views', 'entity_reference_test_views');
/**
* The entity_test entities used by the test.
*
* @var array
*/
protected $entities = array();
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('entity_test');
$this->installEntitySchema('entity_test_mul');
// Create reference from entity_test to entity_test_mul.
$this->createEntityReferenceField('entity_test','entity_test','field_test_data','field_test_data','entity_test_mul');
// Create reference from entity_test_mul to entity_test.
$this->createEntityReferenceField('entity_test_mul', 'entity_test_mul', 'field_data_test', 'field_data_test', 'entity_test');
ViewTestData::createTestViews(get_class($this), array('entity_reference_test_views'));
}
/**
* Tests using the views relationship.
*/
public function testNoDataTableRelationship() {
// Create some test entities which link each other.
$referenced_entity = EntityTestMul::create();
$referenced_entity->save();
$entity = EntityTest::create();
$entity->field_test_data->target_id = $referenced_entity->id();
$entity->save();
$this->assertEqual($entity->field_test_data[0]->entity->id(), $referenced_entity->id());
$this->entities[] = $entity;
$entity = EntityTest::create();
$entity->field_test_data->target_id = $referenced_entity->id();
$entity->save();
$this->assertEqual($entity->field_test_data[0]->entity->id(), $referenced_entity->id());
$this->entities[] = $entity;
Views::viewsData()->clear();
// Check the generated views data.
$views_data = Views::viewsData()->get('entity_test__field_test_data');
$this->assertEqual($views_data['field_test_data']['relationship']['id'], 'standard');
$this->assertEqual($views_data['field_test_data']['relationship']['base'], 'entity_test_mul_property_data');
$this->assertEqual($views_data['field_test_data']['relationship']['base field'], 'id');
$this->assertEqual($views_data['field_test_data']['relationship']['relationship field'], 'field_test_data_target_id');
$this->assertEqual($views_data['field_test_data']['relationship']['entity type'], 'entity_test_mul');
// Check the backwards reference.
$views_data = Views::viewsData()->get('entity_test_mul_property_data');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['id'], 'entity_reverse');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['base'], 'entity_test');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['base field'], 'id');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field table'], 'entity_test__field_test_data');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field field'], 'field_test_data_target_id');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field_name'], 'field_test_data');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['entity_type'], 'entity_test');
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
// Check an actual test view.
$view = Views::getView('test_entity_reference_entity_test_view');
$this->executeView($view);
/** @var \Drupal\views\ResultRow $row */
foreach ($view->result as $index => $row) {
// Check that the actual ID of the entity is the expected one.
$this->assertEqual($row->id, $this->entities[$index]->id());
// Also check that we have the correct result entity.
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
// Test the forward relationship.
$this->assertEqual($row->entity_test_mul_property_data_entity_test__field_test_data_i, 1);
// Test that the correct relationship entity is on the row.
$this->assertEqual($row->_relationship_entities['field_test_data']->id(), 1);
$this->assertEqual($row->_relationship_entities['field_test_data']->bundle(), 'entity_test_mul');
}
// Check the backwards reference view.
$view = Views::getView('test_entity_reference_reverse_entity_test_view');
$this->executeView($view);
/** @var \Drupal\views\ResultRow $row */
foreach ($view->result as $index => $row) {
$this->assertEqual($row->id, 1);
$this->assertEqual($row->_entity->id(), 1);
// Test the backwards relationship.
$this->assertEqual($row->field_test_data_entity_test_mul_property_data_id, $this->entities[$index]->id());
// Test that the correct relationship entity is on the row.
$this->assertEqual($row->_relationship_entities['reverse__entity_test__field_test_data']->id(), $this->entities[$index]->id());
$this->assertEqual($row->_relationship_entities['reverse__entity_test__field_test_data']->bundle(), 'entity_test');
}
}
/**
* Tests views data generated for relationship.
*
* @see entity_reference_field_views_data()
*/
public function testDataTableRelationship() {
// Create some test entities which link each other.
$referenced_entity = EntityTest::create();
$referenced_entity->save();
$entity = EntityTestMul::create();
$entity->field_data_test->target_id = $referenced_entity->id();
$entity->save();
$this->assertEqual($entity->field_data_test[0]->entity->id(), $referenced_entity->id());
$this->entities[] = $entity;
$entity = EntityTestMul::create();
$entity->field_data_test->target_id = $referenced_entity->id();
$entity->save();
$this->assertEqual($entity->field_data_test[0]->entity->id(), $referenced_entity->id());
$this->entities[] = $entity;
Views::viewsData()->clear();
// Check the generated views data.
$views_data = Views::viewsData()->get('entity_test_mul__field_data_test');
$this->assertEqual($views_data['field_data_test']['relationship']['id'], 'standard');
$this->assertEqual($views_data['field_data_test']['relationship']['base'], 'entity_test');
$this->assertEqual($views_data['field_data_test']['relationship']['base field'], 'id');
$this->assertEqual($views_data['field_data_test']['relationship']['relationship field'], 'field_data_test_target_id');
$this->assertEqual($views_data['field_data_test']['relationship']['entity type'], 'entity_test');
// Check the backwards reference.
$views_data = Views::viewsData()->get('entity_test');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['id'], 'entity_reverse');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['base'], 'entity_test_mul_property_data');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['base field'], 'id');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field table'], 'entity_test_mul__field_data_test');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field field'], 'field_data_test_target_id');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field_name'], 'field_data_test');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['entity_type'], 'entity_test_mul');
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
// Check an actual test view.
$view = Views::getView('test_entity_reference_entity_test_mul_view');
$this->executeView($view);
/** @var \Drupal\views\ResultRow $row */
foreach ($view->result as $index => $row) {
// Check that the actual ID of the entity is the expected one.
$this->assertEqual($row->id, $this->entities[$index]->id());
// Also check that we have the correct result entity.
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
// Test the forward relationship.
$this->assertEqual($row->entity_test_entity_test_mul__field_data_test_id, 1);
// Test that the correct relationship entity is on the row.
$this->assertEqual($row->_relationship_entities['field_data_test']->id(), 1);
$this->assertEqual($row->_relationship_entities['field_data_test']->bundle(), 'entity_test');
}
// Check the backwards reference view.
$view = Views::getView('test_entity_reference_reverse_entity_test_mul_view');
$this->executeView($view);
/** @var \Drupal\views\ResultRow $row */
foreach ($view->result as $index => $row) {
$this->assertEqual($row->id, 1);
$this->assertEqual($row->_entity->id(), 1);
// Test the backwards relationship.
$this->assertEqual($row->field_data_test_entity_test_id, $this->entities[$index]->id());
// Test that the correct relationship entity is on the row.
$this->assertEqual($row->_relationship_entities['reverse__entity_test_mul__field_data_test']->id(), $this->entities[$index]->id());
$this->assertEqual($row->_relationship_entities['reverse__entity_test_mul__field_data_test']->bundle(), 'entity_test_mul');
}
}
}

View file

@ -1,147 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\Views\SelectionTest.
*/
namespace Drupal\entity_reference\Tests\Views;
use Drupal\simpletest\WebTestBase;
use Drupal\views\Views;
/**
* Tests entity reference selection handler.
*
* @group entity_reference
*/
class SelectionTest extends WebTestBase {
public static $modules = array('node', 'views', 'entity_reference', 'entity_reference_test', 'entity_test');
/**
* Nodes for testing.
*
* @var array
*/
protected $nodes = array();
/**
* The entity reference field to test.
*
* @var \Drupal\Core\Field\FieldDefinitionInterface
*/
protected $field;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Create nodes.
$type = $this->drupalCreateContentType()->id();
$node1 = $this->drupalCreateNode(array('type' => $type));
$node2 = $this->drupalCreateNode(array('type' => $type));
$node3 = $this->drupalCreateNode();
foreach (array($node1, $node2, $node3) as $node) {
$this->nodes[$node->getType()][$node->id()] = $node->label();
}
// Create a field.
$field_storage = entity_create('field_storage_config', array(
'field_name' => 'test_field',
'entity_type' => 'entity_test',
'translatable' => FALSE,
'settings' => array(
'target_type' => 'node',
),
'type' => 'entity_reference',
'cardinality' => '1',
));
$field_storage->save();
$field = entity_create('field_config', array(
'field_storage' => $field_storage,
'bundle' => 'test_bundle',
'settings' => array(
'handler' => 'views',
'handler_settings' => array(
'view' => array(
'view_name' => 'test_entity_reference',
'display_name' => 'entity_reference_1',
'arguments' => array(),
),
),
),
));
$field->save();
$this->field = $field;
}
/**
* Confirm the expected results are returned.
*
* @param array $result
* Query results keyed by node type and nid.
*/
protected function assertResults(array $result) {
$success = FALSE;
foreach ($result as $node_type => $values) {
foreach ($values as $nid => $label) {
if (!$success = $this->nodes[$node_type][$nid] == trim(strip_tags($label))) {
// There was some error, so break.
break;
}
}
}
$this->assertTrue($success, 'Views selection handler returned expected values.');
}
/**
* Tests the selection handler.
*/
public function testSelectionHandler() {
// Get values from selection handler.
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
$result = $handler->getReferenceableEntities();
$this->assertResults($result);
}
/**
* Tests the selection handler with a relationship.
*/
public function testSelectionHandlerRelationship() {
// Add a relationship to the view.
$view = Views::getView('test_entity_reference');
$view->setDisplay();
$view->displayHandlers->get('default')->setOption('relationships', array(
'test_relationship' => array(
'id' => 'uid',
'table' => 'node_field_data',
'field' => 'uid',
),
));
// Add a filter depending on the relationship to the test view.
$view->displayHandlers->get('default')->setOption('filters', array(
'uid' => array(
'id' => 'uid',
'table' => 'users_field_data',
'field' => 'uid',
'relationship' => 'test_relationship',
)
));
// Set view to distinct so only one row per node is returned.
$query_options = $view->display_handler->getOption('query');
$query_options['options']['distinct'] = TRUE;
$view->display_handler->setOption('query', $query_options);
$view->save();
// Get values from the selection handler.
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
$result = $handler->getReferenceableEntities();
$this->assertResults($result);
}
}