Commit 381b05e5 authored by catch's avatar catch

Issue #2269025 by penyaskito, andypost, grom358, Berdir, mikeegoulding,...

Issue #2269025 by penyaskito, andypost, grom358, Berdir, mikeegoulding, larowlan: Fixed CommentManager::getAllFields() should have a static cache.
parent e5a896b9
......@@ -134,6 +134,16 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
*/
protected $fieldMap = array();
/**
* An array keyed by field type. Each value is an array whose key are entity
* types including arrays in the same form that $fieldMap.
*
* It helps access the mapping between types and fields by the field type.
*
* @var array
*/
protected $fieldMapByFieldType = array();
/**
* Constructs a new Entity plugin manager.
*
......@@ -565,6 +575,25 @@ public function getFieldMap() {
return $this->fieldMap;
}
/**
* {@inheritdoc}
*/
public function getFieldMapByFieldType($field_type) {
if (!isset($this->fieldMapByFieldType[$field_type])) {
$filtered_map = array();
$map = $this->getFieldMap();
foreach ($map as $entity_type => $fields) {
foreach ($fields as $field_name => $field_info) {
if ($field_info['type'] == $field_type) {
$filtered_map[$entity_type][$field_name] = $field_info;
}
}
}
$this->fieldMapByFieldType[$field_type] = $filtered_map;
}
return $this->fieldMapByFieldType[$field_type];
}
/**
* Builds field storage definitions for an entity type.
*
......@@ -610,6 +639,7 @@ public function clearCachedFieldDefinitions() {
$this->fieldDefinitions = array();
$this->fieldStorageDefinitions = array();
$this->fieldMap = array();
$this->fieldMapByFieldType = array();
$this->displayModeInfo = array();
$this->extraFields = array();
Cache::deleteTags(array('entity_field_info' => TRUE));
......
......@@ -81,7 +81,7 @@ public function getFieldDefinitions($entity_type_id, $bundle);
public function getFieldStorageDefinitions($entity_type_id);
/**
* Collects a lightweight map of fields across bundles.
* Returns a lightweight map of fields across bundles.
*
* @return array
* An array keyed by entity type. Each value is an array which keys are
......@@ -91,6 +91,20 @@ public function getFieldStorageDefinitions($entity_type_id);
*/
public function getFieldMap();
/**
* Returns a lightweight map of fields across bundles filtered by field type.
*
* @param string $field_type
* The field type to filter by.
*
* @return array
* An array keyed by entity type. Each value is an array which keys are
* field names and value is an array with two entries:
* - type: The field type.
* - bundles: The bundles in which the field appears.
*/
public function getFieldMapByFieldType($field_type);
/**
* Creates a new access controller instance.
*
......
......@@ -114,27 +114,10 @@ public function getFields($entity_type_id) {
return array();
}
$map = $this->getAllFields();
$map = $this->entityManager->getFieldMapByFieldType('comment');
return isset($map[$entity_type_id]) ? $map[$entity_type_id] : array();
}
/**
* {@inheritdoc}
*/
public function getAllFields() {
$map = $this->entityManager->getFieldMap();
// Build a list of comment fields only.
$comment_fields = array();
foreach ($map as $entity_type => $data) {
foreach ($data as $field_name => $field_info) {
if ($field_info['type'] == 'comment') {
$comment_fields[$entity_type][$field_name] = $field_info;
}
}
}
return $comment_fields;
}
/**
* {@inheritdoc}
*/
......
......@@ -43,11 +43,6 @@ interface CommentManagerInterface {
*/
public function getFields($entity_type_id);
/**
* Utility function to return all comment fields.
*/
public function getAllFields();
/**
* Utility method to add the default comment field to an entity.
*
......
<?php
/**
* @file
* Contains \Drupal\comment\Tests\CommentManagerTest.
*/
namespace Drupal\comment\Tests;
use Drupal\comment\CommentManager;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\comment\CommentManager
* @group comment
*/
class CommentManagerTest extends UnitTestCase {
/**
* Tests the getFields method.
*
* @covers ::getFields()
*/
public function testGetFields() {
// Set up a content entity type.
$entity_type = $this->getMock('Drupal\Core\Entity\ContentEntityTypeInterface');
$entity_type->expects($this->any())
->method('getClass')
->will($this->returnValue('Node'));
$entity_type->expects($this->any())
->method('isSubclassOf')
->with('\Drupal\Core\Entity\ContentEntityInterface')
->will($this->returnValue(TRUE));
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$entity_manager->expects($this->once())
->method('getFieldMapByFieldType')
->will($this->returnValue(array(
'node' => array(
'field_foobar' => array(
'type' => 'comment',
),
),
)));
$entity_manager->expects($this->any())
->method('getDefinition')
->will($this->returnValue($entity_type));
$comment_manager = new CommentManager(
$entity_manager,
$this->getMockBuilder('Drupal\Core\Entity\Query\QueryFactory')->disableOriginalConstructor()->getMock(),
$this->getMock('Drupal\Core\Config\ConfigFactoryInterface'),
$this->getMock('Drupal\Core\StringTranslation\TranslationInterface'),
$this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'),
$this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'),
$this->getMock('Drupal\Core\Session\AccountInterface')
);
$comment_fields = $comment_manager->getFields('node');
$this->assertArrayHasKey('field_foobar', $comment_fields);
}
}
......@@ -102,12 +102,10 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// Reflect machine name changes in the definitions of existing 'taxonomy'
// fields.
$field_ids = array();
$field_map = \Drupal::entityManager()->getFieldMap();
$field_map = \Drupal::entityManager()->getFieldMapByFieldType('taxonomy_term_reference');
foreach ($field_map as $entity_type => $fields) {
foreach ($fields as $field => $info) {
if ($info['type'] == 'taxonomy_term_reference') {
$field_ids[] = $entity_type . '.' . $field;
}
$field_ids[] = $entity_type . '.' . $field;
}
}
......
......@@ -1161,6 +1161,99 @@ public function testGetFieldMapFromCache() {
$this->assertEquals($expected, $this->entityManager->getFieldMap());
}
/**
* @covers ::getFieldMapByFieldType
*/
public function testGetFieldMapByFieldType() {
// Set up a content entity type.
$entity_type = $this->getMock('Drupal\Core\Entity\ContentEntityTypeInterface');
$entity = $this->getMockBuilder('Drupal\Tests\Core\Entity\EntityManagerTestEntity')
->disableOriginalConstructor()
->getMockForAbstractClass();
$entity_class = get_class($entity);
$entity_type->expects($this->any())
->method('getClass')
->will($this->returnValue($entity_class));
$entity_type->expects($this->any())
->method('getKeys')
->will($this->returnValue(array()));
$entity_type->expects($this->any())
->method('id')
->will($this->returnValue('test_entity_type'));
$entity_type->expects($this->any())
->method('isSubclassOf')
->with('\Drupal\Core\Entity\ContentEntityInterface')
->will($this->returnValue(TRUE));
// Set up the module handler to return two bundles for the fieldable entity
// type.
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->moduleHandler->expects($this->any())
->method('alter');
$this->moduleHandler->expects($this->any())
->method('getImplementations')
->will($this->returnValue(array()));
$module_implements_value_map = array(
array(
'entity_bundle_info', array(),
array(
'test_entity_type' => array(
'first_bundle' => array(),
'second_bundle' => array(),
),
),
),
);
$this->moduleHandler->expects($this->any())
->method('invokeAll')
->will($this->returnValueMap($module_implements_value_map));
// Define an ID field definition as a base field.
$id_definition = $this->getMockBuilder('Drupal\Core\Field\FieldDefinition')
->disableOriginalConstructor()
->getMock();
$id_definition->expects($this->exactly(2))
->method('getType')
->will($this->returnValue('integer'));
$base_field_definitions = array(
'id' => $id_definition,
);
$entity_class::$baseFieldDefinitions = $base_field_definitions;
// Set up a by bundle field definition that only exists on one bundle.
$bundle_definition = $this->getMockBuilder('Drupal\Core\Field\FieldDefinition')
->disableOriginalConstructor()
->getMock();
$bundle_definition->expects($this->once())
->method('getType')
->will($this->returnValue('string'));
$entity_class::$bundleFieldDefinitions = array(
'test_entity_type' => array(
'first_bundle' => array(),
'second_bundle' => array(
'by_bundle' => $bundle_definition,
),
),
);
$this->setUpEntityManager(array(
'test_entity_type' => $entity_type,
));
$integerFields = $this->entityManager->getFieldMapByFieldType('integer');
$this->assertCount(1, $integerFields['test_entity_type']);
$this->assertArrayNotHasKey('non_fieldable', $integerFields);
$this->assertArrayHasKey('id', $integerFields['test_entity_type']);
$this->assertArrayNotHasKey('by_bundle', $integerFields['test_entity_type']);
$stringFields = $this->entityManager->getFieldMapByFieldType('string');
$this->assertCount(1, $stringFields['test_entity_type']);
$this->assertArrayNotHasKey('non_fieldable', $stringFields);
$this->assertArrayHasKey('by_bundle', $stringFields['test_entity_type']);
$this->assertArrayNotHasKey('id', $stringFields['test_entity_type']);
}
/**
* Gets a mock controller class name.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment