diff -u b/core/modules/entity_reference/lib/Drupal/entity_reference/Type/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Type/ConfigurableEntityReferenceItem.php --- b/core/modules/entity_reference/lib/Drupal/entity_reference/Type/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Type/ConfigurableEntityReferenceItem.php @@ -47,8 +47,8 @@ * Duplicated from \Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase, * since we cannot extend it. */ - public function __construct(array $definition, $plugin_id, array $plugin_definition, $name = NULL, TypedDataInterface $parent = NULL) { - parent::__construct($definition, $plugin_id, $plugin_definition, $name, $parent); + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + parent::__construct($definition, $name, $parent); if (isset($definition['instance'])) { $this->instance = $definition['instance']; } diff -u b/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc --- b/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -437,147 +437,6 @@ } /** - * Invokes a field hook across fields on multiple entities. - * - * @param $op - * Possible operations include: - * - load - * - prepare_view - * For all other operations, use _field_invoke() / field_invoke_default() - * instead. - * @param $entity_type - * The type of entities in $entities; e.g. 'node' or 'user'. - * @param $entities - * An array of entities, keyed by entity ID. - * @param $a - * - The $age parameter in the 'load' operation. - * - Otherwise NULL. - * @param $b - * Currently always NULL. - * @param $options - * An associative array of additional options, with the following keys: - * - field_name: The name of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's - * bundle. NOTE: This option is not compatible with the 'deleted' option; - * the 'field_id' option should be used instead. - * - field_id: The ID of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's - * bundles. - * - default: A boolean value, specifying which implementation of the - * operation should be invoked. - * - if FALSE (default), the field types implementation of the operation - * will be invoked (hook_field_[op]) - * - If TRUE, the default field implementation of the field operation will - * be invoked (field_default_[op]) - * Internal use only. Do not explicitely set to TRUE, but use - * _field_invoke_multiple_default() instead. - * - deleted: If TRUE, the function will operate on deleted fields as well as - * non-deleted fields. If unset or FALSE, only non-deleted fields are - * operated on. - * - langcode: A language code or an array of arrays of language codes keyed - * by entity ID and field name. It will be used to narrow down to a single - * value the available languages to act on. - * - * @return - * An array of returned values keyed by entity ID. - */ -function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b = NULL, $options = array()) { - // Merge default options. - $default_options = array( - 'default' => FALSE, - 'deleted' => FALSE, - 'langcode' => NULL, - ); - $options += $default_options; - - $fields = array(); - $grouped_instances = array(); - $grouped_entities = array(); - $grouped_items = array(); - $return = array(); - - // Go through the entities and collect the fields on which the hook should be - // invoked. - // - // We group fields by ID, not by name, because this function can operate on - // deleted fields which may have non-unique names. However, entities can only - // contain data for a single field for each name, even if that field - // is deleted, so we reference field data via the - // $entity->$field_name property. - foreach ($entities as $entity) { - // Determine the list of instances to iterate on. - $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options); - $id = $entity->id(); - - foreach ($instances as $instance) { - $field_id = $instance['field_id']; - $field_name = $instance['field_name']; - $field = field_info_field_by_id($field_id); - $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op; - if (function_exists($function)) { - // Add the field to the list of fields to invoke the hook on. - if (!isset($fields[$field_id])) { - $fields[$field_id] = $field; - } - // Extract the field values into a separate variable, easily accessed - // by hook implementations. - // Unless a language code suggestion is provided we iterate on all the - // available language codes. - $available_langcodes = field_available_languages($entity_type, $field); - $langcode = !empty($options['langcode'][$id]) ? $options['langcode'][$id] : $options['langcode']; - $langcodes = _field_language_suggestion($available_langcodes, $langcode, $field_name); - foreach ($langcodes as $langcode) { - $grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); - // Group the instances and entities corresponding to the current - // field. - $grouped_instances[$field_id][$langcode][$id] = $instance; - $grouped_entities[$field_id][$langcode][$id] = $entities[$id]; - } - } - } - // Initialize the return value for each entity. - $return[$id] = array(); - } - - // For each field, invoke the field hook and collect results. - foreach ($fields as $field_id => $field) { - $field_name = $field['field_name']; - $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op; - // Iterate over all the field translations. - foreach ($grouped_items[$field_id] as $langcode => &$items) { - $entities = $grouped_entities[$field_id][$langcode]; - $instances = $grouped_instances[$field_id][$langcode]; - $results = $function($entity_type, $entities, $field, $instances, $langcode, $items, $a, $b); - if (isset($results)) { - // Collect results by entity. - // For hooks with array results, we merge results together. - // For hooks with scalar results, we collect results in an array. - foreach ($results as $id => $result) { - if (is_array($result)) { - $return[$id] = array_merge($return[$id], $result); - } - else { - $return[$id][] = $result; - } - } - } - } - - // Populate field values back in the entities, but avoid replacing missing - // fields with an empty array (those are not equivalent on update). - foreach ($grouped_entities[$field_id] as $langcode => $entities) { - foreach ($entities as $id => $entity) { - if ($grouped_items[$field_id][$langcode][$id] !== array() || isset($entity->{$field_name}[$langcode])) { - $entity->{$field_name}[$langcode] = $grouped_items[$field_id][$langcode][$id]; - } - } - } - } - - return $return; -} - -/** * Invoke field.module's version of a field hook. * * This function invokes the field_default_[op]() function. @@ -592,62 +451,6 @@ } /** - * Invoke field.module's version of a field hook on multiple entities. - * - * This function invokes the field_default_[op]() function. - * Use _field_invoke_multiple() to invoke the field type implementation, - * hook_field_[op](). - * - * @param $op - * Possible operations include: - * - load - * - prepare_view - * For all other operations, use _field_invoke() / field_invoke_default() - * instead. - * @param $entity_type - * The type of entities in $entities; e.g. 'node' or 'user'. - * @param $entities - * An array of entities, keyed by entity ID. - * @param $a - * - The $age parameter in the 'load' operation. - * - Otherwise NULL. - * @param $b - * Currently always NULL. - * @param $options - * An associative array of additional options, with the following keys: - * - field_name: The name of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's - * bundle. NOTE: This option is not compatible with the 'deleted' option; - * the 'field_id' option should be used instead. - * - field_id: The ID of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's - * bundles. - * - default': A boolean value, specifying which implementation of the - * operation should be invoked. - * - if FALSE (default), the field types implementation of the operation - * will be invoked (hook_field_[op]) - * - If TRUE, the default field implementation of the field operation will - * be invoked (field_default_[op]) - * Internal use only. Do not explicitely set to TRUE, but use - * _field_invoke_multiple_default() instead. - * - deleted: If TRUE, the function will operate on deleted fields as well as - * non-deleted fields. If unset or FALSE, only non-deleted fields are - * operated on. - * - language: A language code or an array of arrays of language codes keyed - * by entity ID and field name. It will be used to narrow down to a single - * value the available languages to act on. - * - * @return - * An array of returned values keyed by entity ID. - * - * @see _field_invoke_multiple() - */ -function _field_invoke_multiple_default($op, $entity_type, $entities, &$a = NULL, &$b = NULL, $options = array()) { - $options['default'] = TRUE; - return _field_invoke_multiple($op, $entity_type, $entities, $a, $b, $options); -} - -/** * Retrieves a list of instances to operate on. * * Helper for _field_invoke(). diff -u b/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module --- b/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -84,25 +84,6 @@ } /** - * Generic op to test _field_invoke_multiple behavior. - * - * This simulates a multiple field operation callback to be invoked by - * _field_invoke_multiple(). - */ -function field_test_field_test_op_multiple($entity_type, $entities, $field, $instances, $langcode, &$items) { - $result = array(); - foreach ($entities as $id => $entity) { - // Entities, instances and items are assumed to be consistently grouped by - // language. To verify this we try to access all the passed data structures - // by entity id. If they are grouped correctly, one entity, one instance and - // one array of items should be available for each entity id. - $field_name = $instances[$id]['field_name']; - $result[$id] = array($langcode => hash('sha256', serialize(array($entity_type, $entity, $field_name, $langcode, $items[$id])))); - } - return $result; -} - -/** * Implements hook_field_available_languages_alter(). */ function field_test_field_available_languages_alter(&$langcodes, $context) { --- a/core/modules/field/field.multilingual.inc +++ b/core/modules/field/field.multilingual.inc @@ -34,10 +34,9 @@ * property returned by field_info_field() and whether the entity type the field * is attached to supports translation. * - * By default, _field_invoke() and _field_invoke_multiple() process a field in - * all available languages, unless they are given a language code suggestion. - * Based on that suggestion, _field_language_suggestion() determines the - * languages to act on. + * By default, _field_invoke() processes a field in all available languages, + * unless they are given a language code suggestion. Based on that suggestion, + * _field_language_suggestion() determines the languages to act on. * * Most field_attach_*() functions act on all available language codes, except * for the following: only in patch2: unchanged: --- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php @@ -139,79 +139,6 @@ function testFieldInvoke() { } /** - * Test the multilanguage logic of _field_invoke_multiple(). - */ - function testFieldInvokeMultiple() { - // Enable field translations for the entity. - field_test_entity_info_translatable('test_entity', TRUE); - - $values = array(); - $options = array(); - $entities = array(); - $entity_type = 'test_entity'; - $entity_count = 5; - $available_langcodes = field_available_languages($this->entity_type, $this->field); - - for ($id = 1; $id <= $entity_count; ++$id) { - $entity = field_test_create_entity($id, $id, $this->instance['bundle']); - $langcodes = $available_langcodes; - - // Populate some extra languages to check whether _field_invoke() - // correctly uses the result of field_available_languages(). - $extra_langcodes = mt_rand(1, 4); - for ($i = 0; $i < $extra_langcodes; ++$i) { - $langcodes[] = $this->randomName(2); - } - - // For each given language provide some random values. - $language_count = count($langcodes); - for ($i = 0; $i < $language_count; ++$i) { - $langcode = $langcodes[$i]; - // Avoid to populate at least one field translation to check that - // per-entity language suggestions work even when available field values - // are different for each language. - if ($i !== $id) { - for ($delta = 0; $delta < $this->field['cardinality']; $delta++) { - $values[$id][$langcode][$delta]['value'] = mt_rand(1, 127); - } - } - // Ensure that a language for which there is no field translation is - // used as display language to prepare per-entity language suggestions. - elseif (!isset($display_langcode)) { - $display_langcode = $langcode; - } - } - - $entity->{$this->field_name} = $values[$id]; - $entities[$id] = $entity; - - // Store per-entity language suggestions. - $options['langcode'][$id] = field_language($entity, NULL, $display_langcode); - } - - $grouped_results = _field_invoke_multiple('test_op_multiple', $entity_type, $entities); - foreach ($grouped_results as $id => $results) { - foreach ($results as $langcode => $result) { - if (isset($values[$id][$langcode])) { - $hash = hash('sha256', serialize(array($entity_type, $entities[$id], $this->field_name, $langcode, $values[$id][$langcode]))); - // Check whether the parameters passed to _field_invoke_multiple() - // were correctly forwarded to the callback function. - $this->assertEqual($hash, $result, format_string('The result for entity %id/%language is correctly stored.', array('%id' => $id, '%language' => $langcode))); - } - } - $this->assertEqual(count($results), count($available_langcodes), format_string('No unavailable language has been processed for entity %id.', array('%id' => $id))); - } - - $null = NULL; - $grouped_results = _field_invoke_multiple('test_op_multiple', $entity_type, $entities, $null, $null, $options); - foreach ($grouped_results as $id => $results) { - foreach ($results as $langcode => $result) { - $this->assertTrue(isset($options['langcode'][$id]), format_string('The result language code %langcode for entity %id was correctly suggested (display language: %display_langcode).', array('%id' => $id, '%langcode' => $langcode, '%display_langcode' => $display_langcode))); - } - } - } - - /** * Test translatable fields storage/retrieval. */ function testTranslatableFieldSaveLoad() {