Commit 97823b5a authored by alexpott's avatar alexpott

Issue #2429191 by claudiu.cristea, amateescu, yched, nlisgo, Berdir, alexpott,...

Issue #2429191 by claudiu.cristea, amateescu, yched, nlisgo, Berdir, alexpott, klausi, Wim Leers, xjm, catch: Deprecate entity_reference.module and move its functionality to core
parent 02bd75b1
......@@ -323,10 +323,6 @@ Email module
Editor module
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
Entity Reference module
- Amitai Burstein 'Amitaibu' https://www.drupal.org/u/amitaibu
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Field UI module
- Yves Chedemois 'yched' https://www.drupal.org/u/yched
- Kristof De Jaeger 'swentel' https://www.drupal.org/u/swentel
......
......@@ -12,6 +12,7 @@
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
......@@ -135,7 +136,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#required' => TRUE,
'#size' => 6,
'#multiple' => TRUE,
'#element_validate' => array('_entity_reference_element_validate_filter'),
'#element_validate' => [[get_class($this), 'elementValidateFilter']],
);
}
else {
......@@ -182,7 +183,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
$form['sort']['settings'] = array(
'#type' => 'container',
'#attributes' => array('class' => array('entity_reference-settings')),
'#process' => array('_entity_reference_form_process_merge_parent'),
'#process' => [[EntityReferenceItem::class, 'formProcessMergeParent']],
);
if ($selection_handler_settings['sort']['field'] != '_none') {
......@@ -225,6 +226,14 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
/**
* Form element validation handler; Filters the #value property of an element.
*/
public static function elementValidateFilter(&$element, FormStateInterface $form_state) {
$element['#value'] = array_filter($element['#value']);
$form_state->setValueForElement($element, $element['#value']);
}
/**
* {@inheritdoc}
*/
......@@ -320,8 +329,7 @@ protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS')
// Add entity-access tag.
$query->addTag($target_type . '_access');
// Add the Selection handler for
// entity_reference_query_entity_reference_alter().
// Add the Selection handler for system_query_entity_reference_alter().
$query->addTag('entity_reference');
$query->addMetaData('entity_reference_selection_handler', $this);
......
......@@ -18,6 +18,7 @@
* label = @Translation("Check boxes/radio buttons"),
* field_types = {
* "boolean",
* "entity_reference",
* "list_integer",
* "list_float",
* "list_string",
......
......@@ -18,6 +18,7 @@
* id = "options_select",
* label = @Translation("Select list"),
* field_types = {
* "entity_reference",
* "list_integer",
* "list_float",
* "list_string"
......
......@@ -6,6 +6,5 @@ version: VERSION
core: 8.x
configure: aggregator.admin_settings
dependencies:
- entity_reference
- file
- options
......@@ -5,7 +5,6 @@ dependencies:
- core.entity_view_mode.aggregator_item.summary
module:
- aggregator
- entity_reference
id: aggregator_item.aggregator_item.summary
targetEntityType: aggregator_item
bundle: aggregator_item
......
......@@ -24,7 +24,7 @@ class AggregatorTitleTest extends KernelTestBase {
*
* @var array
*/
public static $modules = array('file', 'field', 'options', 'aggregator', 'entity_reference');
public static $modules = ['file', 'field', 'options', 'aggregator'];
/**
* The field name that is tested.
......
......@@ -5,7 +5,6 @@ dependencies:
- field.field.node.book.body
- node.type.book
module:
- entity_reference
- text
id: node.book.default
targetEntityType: node
......
......@@ -23,7 +23,7 @@ class BookUninstallTest extends KernelTestBase {
*
* @var array
*/
public static $modules = array('system', 'user', 'field', 'filter', 'text', 'entity_reference', 'node', 'book');
public static $modules = ['system', 'user', 'field', 'filter', 'text', 'node', 'book'];
/**
* {@inheritdoc}
......
......@@ -32,7 +32,7 @@ class ConfigImportRecreateTest extends KernelTestBase {
*
* @var array
*/
public static $modules = array('system', 'field', 'text', 'user', 'node', 'entity_reference');
public static $modules = ['system', 'field', 'text', 'user', 'node'];
protected function setUp() {
parent::setUp();
......
......@@ -34,7 +34,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
*
* @var array
*/
public static $modules = array('system', 'user', 'node', 'field', 'text', 'config_test', 'entity_reference');
public static $modules = ['system', 'user', 'node', 'field', 'text', 'config_test'];
/**
* {@inheritdoc}
......
......@@ -589,7 +589,7 @@ public function testUnmetDependency() {
$error_log = $this->configImporter->getErrors();
$expected = [
'Unable to install the <em class="placeholder">unknown_module</em> module since it does not exist.',
'Unable to install the <em class="placeholder">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User, Entity Reference</em> modules.',
'Unable to install the <em class="placeholder">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User</em> modules.',
'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Classy</em> theme.',
'Configuration <em class="placeholder">config_test.dynamic.dotted.config</em> depends on the <em class="placeholder">unknown</em> configuration that will not exist after import.',
......
# Schema for the views plugins of the Entity Reference module.
views.display.entity_reference:
type: views_display
label: 'Entity Reference'
views.row.entity_reference:
type: views.row.fields
label: 'Entity Reference inline fields'
views.style.entity_reference:
type: views_style
label: 'Entity Reference list'
mapping:
search_fields:
type: sequence
label: 'Search fields'
sequence:
type: string
label: 'Search field'
name: 'Entity Reference'
type: module
description: 'Provides a field that can reference other entities.'
description: 'Deprecated. All the functionality has been moved to Core.'
package: Field types
version: VERSION
core: 8.x
dependencies:
- field
hidden: true
<?php
/**
* @file
* Provides views data for the entity_reference module.
*/
use Drupal\field\FieldStorageConfigInterface;
/**
* Implements hook_field_views_data().
*/
function entity_reference_field_views_data(FieldStorageConfigInterface $field_storage) {
$data = views_field_default_views_data($field_storage);
$entity_manager = \Drupal::entityManager();
foreach ($data as $table_name => $table_data) {
// Add a relationship to the target entity type.
$target_entity_type_id = $field_storage->getSetting('target_type');
$target_entity_type = $entity_manager->getDefinition($target_entity_type_id);
$entity_type_id = $field_storage->getTargetEntityTypeId();
$entity_type = $entity_manager->getDefinition($entity_type_id);
$target_base_table = $target_entity_type->getDataTable() ?: $target_entity_type->getBaseTable();
$field_name = $field_storage->getName();
// Provide a relationship for the entity type with the entity reference
// field.
$args = array(
'@label' => $target_entity_type->getLabel(),
'@field_name' => $field_name,
);
$data[$table_name][$field_name]['relationship'] = array(
'title' => t('@label referenced from @field_name', $args),
'label' => t('@field_name: @label', $args),
'group' => $entity_type->getLabel(),
'help' => t('Appears in: @bundles.', array('@bundles' => implode(', ', $field_storage->getBundles()))),
'id' => 'standard',
'base' => $target_base_table,
'entity type' => $target_entity_type_id,
'base field' => $target_entity_type->getKey('id'),
'relationship field' => $field_name . '_target_id',
);
// Provide a reverse relationship for the entity type that is referenced by
// the field.
$args['@entity'] = $entity_type->getLabel();
$args['@label'] = $target_entity_type->getLowercaseLabel();
$pseudo_field_name = 'reverse__' . $entity_type_id . '__' . $field_name;
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $entity_manager->getStorage($entity_type_id)->getTableMapping();
$data[$target_base_table][$pseudo_field_name]['relationship'] = array(
'title' => t('@entity using @field_name', $args),
'label' => t('@field_name', array('@field_name' => $field_name)),
'group' => $target_entity_type->getLabel(),
'help' => t('Relate each @entity with a @field_name set to the @label.', $args),
'id' => 'entity_reverse',
'base' => $entity_type->getDataTable() ?: $entity_type->getBaseTable(),
'entity_type' => $entity_type_id,
'base field' => $entity_type->getKey('id'),
'field_name' => $field_name,
'field table' => $table_mapping->getDedicatedDataTableName($field_storage),
'field field' => $field_name . '_target_id',
'join_extra' => array(
array(
'field' => 'deleted',
'value' => 0,
'numeric' => TRUE,
),
),
);
}
return $data;
}
......@@ -7,218 +7,14 @@
namespace Drupal\entity_reference;
use Drupal\Component\Utility\Html;
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 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) {
// The label does not need sanitizing since it is used as an optgroup
// which is only supported by select elements and auto-escaped.
$bundle_label = $bundles[$bundle]['label'];
$return[(string) $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] = Html::escape($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] = Html::escape($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 { }
......@@ -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().