diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index b943d17..12a4543 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -418,6 +418,17 @@ public function getConfigDependencyName() { /** * {@inheritdoc} */ + public function getConfigTarget() { + // For configuration entities, use the config ID for the config target + // identifier. This ensures that default configuration (which does not yet + // have UUIDs) can be provided and installed with references to the target, + // and also makes config dependencies more readable. + return $this->id(); + } + + /** + * {@inheritdoc} + */ public function onDependencyRemoval(array $dependencies) { } diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index afdfcb0..5a9c85f 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -569,4 +569,13 @@ public function getConfigDependencyName() { return $this->getEntityTypeId() . ':' . $this->bundle() . ':' . $this->uuid(); } + /** + * {@inheritdoc} + */ + public function getConfigTarget() { + // For content entities, use the UUID for the config target identifier. + // This ensures that references to the target can be deployed reliably. + return $this->uuid(); + } + } diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php index 130612b..fac0380 100644 --- a/core/lib/Drupal/Core/Entity/EntityInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityInterface.php @@ -429,4 +429,15 @@ public function getConfigDependencyKey(); */ public function getConfigDependencyName(); + /** + * Gets the configuration target identifier for the entity. + * + * Used to supply the correct format for storing a reference targeting this + * entity in configuration. + * + * @return string + * The configuration target identifier. + */ + public function getConfigTarget(); + } diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 96365cc..b09d9ff 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -981,6 +981,27 @@ public function loadEntityByUuid($entity_type_id, $uuid) { /** * {@inheritdoc} */ + public function loadEntityByConfigTarget($entity_type_id, $target) { + $entity_type = $this->getDefinition($entity_type_id); + + // For configuration entities, the config target is given by the entity ID. + // @todo Should we allow entity types to return their target identifier key + // rather than hard-coding this check? + if ($entity_type instanceof ConfigEntityTypeInterface) { + $entity = $this->getStorage($entity_type_id)->load($target); + } + + // For content entities, the config target is given by the UUID. + else { + $entity = $this->loadEntityByUuid($entity_type_id, $target); + } + + return $entity; + } + + /** + * {@inheritdoc} + */ public function getEntityTypeFromClass($class_name) { // Check the already calculated classes first. diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php index d60c47d..f1e6921 100644 --- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php @@ -470,6 +470,26 @@ public function getFormModeOptions($entity_type_id, $include_disabled = FALSE); public function loadEntityByUuid($entity_type_id, $uuid); /** + * Loads an entity by the config target identifier. + * + * @param string $entity_type_id + * The entity type ID to load from. + * @param string $target + * The configuration target to load, as returned from + * \Drupal\Core\Entity\EntityInterface::getConfigTarget(). + * + * @return \Drupal\Core\Entity\EntityInterface|FALSE + * The entity object, or FALSE if there is no entity with the given UUID. + * + * @throws \Drupal\Core\Entity\EntityStorageException + * Thrown if the target identifier is a UUID but the entity type does not + * support UUIDs. + * + * @see \Drupal\Core\Entity\EntityInterface::getConfigTarget() + */ + public function loadEntityByConfigTarget($entity_type_id, $target); + + /** * Returns the entity type ID based on the class that is called on. * * Compares the class this is called on against the known entity classes diff --git a/core/lib/Drupal/Core/Entity/EntityStorageInterface.php b/core/lib/Drupal/Core/Entity/EntityStorageInterface.php index b4c897e..387e0fb 100644 --- a/core/lib/Drupal/Core/Entity/EntityStorageInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityStorageInterface.php @@ -104,7 +104,7 @@ public function deleteRevision($revision_id); * An associative array where the keys are the property names and the * values are the values those properties must have. * - * @return array + * @return \Drupal\Core\Entity\EntityInterface[] * An array of entity objects indexed by their ids. */ public function loadByProperties(array $values = array()); diff --git a/core/modules/taxonomy/config/install/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/install/views.view.taxonomy_term.yml index 15f80ec..885d416 100644 --- a/core/modules/taxonomy/config/install/views.view.taxonomy_term.yml +++ b/core/modules/taxonomy/config/install/views.view.taxonomy_term.yml @@ -227,7 +227,7 @@ display: admin_label: '' empty: true tokenize: true - entity_id: '!1' + target: '!1' view_mode: full bypass_access: false plugin_id: entity diff --git a/core/modules/views/config/schema/views.area.schema.yml b/core/modules/views/config/schema/views.area.schema.yml index 1262a89..a7d5aa2 100644 --- a/core/modules/views/config/schema/views.area.schema.yml +++ b/core/modules/views/config/schema/views.area.schema.yml @@ -8,9 +8,9 @@ views.area.entity: type: views_area label: 'Entity' mapping: - entity_id: + target: type: string - label: 'ID' + label: 'The target entity' view_mode: type: string label: 'View mode' diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index e42058e..6129d55 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -266,6 +266,7 @@ public function calculateDependencies() { $executable = $this->getExecutable(); $executable->initDisplay(); + $executable->initStyle(); $handler_types = array_keys(Views::getHandlerTypes()); foreach ($executable->displayHandlers as $display) { diff --git a/core/modules/views/src/Plugin/views/area/Entity.php b/core/modules/views/src/Plugin/views/area/Entity.php index 93d0ad7..a452ff9 100644 --- a/core/modules/views/src/Plugin/views/area/Entity.php +++ b/core/modules/views/src/Plugin/views/area/Entity.php @@ -7,9 +7,12 @@ namespace Drupal\views\Plugin\views\area; +use Drupal\Component\Uuid\Uuid; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides an area handler which renders an entity in a certain view mode. @@ -28,6 +31,43 @@ class Entity extends TokenizeAreaPluginBase { protected $entityType; /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * Constructs a new Entity instance. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + + $this->entityManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.manager') + ); + } + + /** * Overrides \Drupal\views\Plugin\views\area\AreaPluginBase::init(). */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { @@ -45,9 +85,10 @@ protected function defineOptions() { // this handler. $options['tokenize']['default'] = TRUE; - $options['entity_id'] = array('default' => ''); - $options['view_mode'] = array('default' => 'default'); - $options['bypass_access'] = array('default' => FALSE); + // Contains the config target identifier for the entity. + $options['target'] = ['default' => '']; + $options['view_mode'] = ['default' => 'default']; + $options['bypass_access'] = ['default' => FALSE]; return $options; } @@ -60,16 +101,31 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['view_mode'] = array( '#type' => 'select', - '#options' => \Drupal::entityManager()->getViewModeOptions($this->entityType), + '#options' => $this->entityManager->getViewModeOptions($this->entityType), '#title' => $this->t('View mode'), '#default_value' => $this->options['view_mode'], ); - $form['entity_id'] = array( - '#title' => $this->t('ID'), + $label = $this->entityManager->getDefinition($this->entityType)->getLabel(); + $target = $this->options['target']; + + // @todo This form appears to be missing some test coverage; no explicit + // fail when the below was broken. + + // If the target does not contain tokens, try to load the entity and + // display the entity ID to the admin form user. + if (!$this->view->getStyle()->hasToken($this->options['target'])) { + // @todo If the entity does not exist, this will will show the config + // target identifier. Is that the correct behavior? + if ($target_entity = $this->entityManager->loadEntityByConfigTarget($this->entityType, $this->options['target'])) { + $target = $target_entity->id(); + } + } + $form['target'] = [ + '#title' => $this->t('@entity_type_label ID', ['@entity_type_label' => $label]), '#type' => 'textfield', - '#default_value' => $this->options['entity_id'], - ); + '#default_value' => $target, + ]; $form['bypass_access'] = array( '#type' => 'checkbox', @@ -82,16 +138,62 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ + public function submitOptionsForm(&$form, FormStateInterface $form_state) { + parent::submitOptionsForm($form, $form_state); + + // @todo Add validation in https://www.drupal.org/node/2392833. + + // Load the referenced entity and store its config target identifier if + // the target does not contains tokens. + if (!$this->view->getStyle()->hasToken($this->options['target'])) { + $options = $form_state->getValue('options'); + if ($entity = $this->entityManager->getStorage($this->entityType)->load($options['target'])) { + $options['target'] = $entity->getConfigTarget(); + } + $form_state->setValue('options', $options); + } + } + + /** + * {@inheritdoc} + */ public function render($empty = FALSE) { + // @todo Simplify this code. if (!$empty || !empty($this->options['empty'])) { - $entity_id = $this->tokenizeValue($this->options['entity_id']); - $entity = entity_load($this->entityType, $entity_id); - if ($entity && (!empty($this->options['bypass_access']) || $entity->access('view'))) { - return entity_view($entity, $this->options['view_mode']); + if ($this->view->getStyle()->hasToken($this->options['target'])) { + $target_id = $this->tokenizeValue($this->options['target']); + if ($entity = $this->entityManager->getStorage($this->entityType)->load($target_id)) { + $target_entity = $entity; + } + } + else { + if ($entity = $this->entityManager->loadEntityByConfigTarget($this->entityType, $this->options['target'])) { + $target_entity = $entity; + } + } + if (isset($target_entity) && (!empty($this->options['bypass_access']) || $target_entity->access('view'))) { + $view_builder = $this->entityManager->getViewBuilder($this->entityType); + return $view_builder->view($target_entity, $this->options['view_mode']); } } - return array(); + return []; } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + // Ensure that we don't add dependencies for placeholders. + // @todo No tests fail even if this never is false; add coverage. + if (!$this->view->getStyle()->hasToken($this->options['target'])) { + if ($entity = $this->entityManager->loadEntityByConfigTarget($this->entityType, $this->options['target'])) { + $dependencies[$this->entityManager->getDefinition($this->entityType)->getConfigDependencyKey()][] = $entity->getConfigDependencyName(); + } + } + + return $dependencies; + } } diff --git a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php index bf6fbf6..4da1200 100644 --- a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php +++ b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php @@ -106,7 +106,7 @@ public function tokenForm(&$form, FormStateInterface $form_state) { */ public function tokenizeValue($value) { if ($this->options['tokenize']) { - $value = $this->view->style_plugin->tokenizeValue($value, 0); + $value = $this->view->getStyle()->tokenizeValue($value, 0); } // As we add the globalTokenForm() we also should replace the token here. return $this->globalTokenReplace($value); diff --git a/core/modules/views/src/Tests/Handler/AreaEntityTest.php b/core/modules/views/src/Tests/Handler/AreaEntityTest.php index af44b44..bbcacaf 100644 --- a/core/modules/views/src/Tests/Handler/AreaEntityTest.php +++ b/core/modules/views/src/Tests/Handler/AreaEntityTest.php @@ -73,17 +73,44 @@ public function testEntityAreaData() { */ public function testEntityArea() { + /** @var \Drupal\Core\Entity\EntityInterface[] $entities */ $entities = array(); for ($i = 0; $i < 3; $i++) { $random_label = $this->randomMachineName(); $data = array('bundle' => 'entity_test', 'name' => $random_label); $entity_test = $this->container->get('entity.manager')->getStorage('entity_test')->create($data); + + $uuid_map[0] = 'aa0c61cb-b7bb-4795-972a-493dabcf529c'; + $uuid_map[1] = '62cef0ff-6f30-4f7a-b9d6-a8ed5a3a6bf3'; + $uuid_map[2] = '3161d6e9-3326-4719-b513-8fa68a731ba2'; + $entity_test->uuid->value = $uuid_map[$i]; + $entity_test->save(); $entities[] = $entity_test; \Drupal::state()->set('entity_test_entity_access.view.' . $entity_test->id(), $i != 2); + } $view = Views::getView('test_entity_area'); + $preview = $view->preview('default', [$entities[1]->id()]); + $this->setRawContent(\Drupal::service('renderer')->render($preview)); + + $result = $this->xpath('//div[@class = "view-header"]'); + $this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.'); + $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.'); + + $result = $this->xpath('//div[@class = "view-footer"]'); + $this->assertTrue(strpos(trim((string) $result[0]), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.'); + $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.'); + + // Specify a UUID instead of the entity ID. + $uuid = $entities[0]->uuid(); + /** @var \Drupal\views\ViewStorageInterface $view */ + $view = Views::getView('test_entity_area'); + $item = $view->getHandler('default', 'header', 'entity_entity_test'); + $item['target'] = $uuid; + $view->setHandler('default', 'header', 'entity_entity_test', $item); + $preview = $view->preview('default', array($entities[1]->id())); $this->drupalSetContent(drupal_render($preview)); diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_area.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_area.yml index 38bbf78..c948544 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_area.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_area.yml @@ -1,6 +1,8 @@ langcode: und status: true -dependencies: { } +dependencies: + content: + - entity_test:entity_test:aa0c61cb-b7bb-4795-972a-493dabcf529c id: test_entity_area label: '' module: views @@ -21,7 +23,7 @@ display: field: entity_entity_test id: entity_entity_test table: views - entity_id: '1' + target: 'aa0c61cb-b7bb-4795-972a-493dabcf529c' view_mode: full plugin_id: entity footer: @@ -29,7 +31,7 @@ display: field: entity_entity_test id: entity_entity_test table: views - entity_id: '!1' + target: '!1' view_mode: full plugin_id: entity fields: diff --git a/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php b/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php new file mode 100644 index 0000000..b4cb957 --- /dev/null +++ b/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php @@ -0,0 +1,314 @@ +entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); + $this->entityStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); + $this->entityViewBuilder = $this->getMock('Drupal\Core\Entity\EntityViewBuilderInterface'); + + $this->executable = $this->getMockBuilder('Drupal\views\ViewExecutable') + ->disableOriginalConstructor() + ->getMock(); + $this->display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') + ->disableOriginalConstructor() + ->getMock(); + $this->stylePlugin = $this->getMockBuilder('Drupal\views\Plugin\views\style\StylePluginBase') + ->disableOriginalConstructor() + ->getMock(); + $this->executable->style_plugin = $this->stylePlugin; + + $this->entityHandler = new Entity(array(), 'entity', array('entity_type' => 'entity_test'), $this->entityManager); + + $this->display->expects($this->any()) + ->method('getPlugin') + ->with('style') + ->willReturn($this->stylePlugin); + $this->executable->expects($this->any()) + ->method('getStyle') + ->willReturn($this->stylePlugin); + + + $token = $this->getMockBuilder('Drupal\Core\Utility\Token') + ->disableOriginalConstructor() + ->getMock(); + $token->expects($this->any()) + ->method('replace') + ->willReturnArgument(0); + $container = new ContainerBuilder(); + $container->set('token', $token); + \Drupal::setContainer($container); + } + + /** + * Ensures that the entity manager returns an entity storage. + */ + protected function setupEntityManager() { + $this->entityManager->expects($this->any()) + ->method('getStorage') + ->with('entity_test') + ->willReturn($this->entityStorage); + $this->entityManager->expects($this->any()) + ->method('getViewBuilder') + ->with('entity_test') + ->willReturn($this->entityViewBuilder); + } + + /** + * @covers ::render + * @covers ::defineOptions + * @covers ::init + */ + public function testRenderWithId() { + $this->setupEntityManager(); + $options = [ + 'target' => 1, + 'tokenize' => FALSE, + ]; + + /** @var \Drupal\Core\Entity\EntityInterface $entity */ + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity->expects($this->once()) + ->method('access') + ->willReturn(TRUE); + + $this->entityStorage->expects($this->never()) + ->method('loadByProperties'); + $this->entityManager->expects($this->any()) + ->method('loadEntityByConfigTarget') + ->willReturn($entity); + $this->entityViewBuilder->expects($this->once()) + ->method('view') + ->with($entity, 'default') + ->willReturn(['#markup' => 'hallo']); + + $this->entityHandler->init($this->executable, $this->display, $options); + + $result = $this->entityHandler->render(); + $this->assertEquals(['#markup' => 'hallo'], $result); + } + + /** + * @covers ::render + * @covers ::defineOptions + * @covers ::init + */ + public function testRenderWithIdAndToken() { + $this->setupEntityManager(); + $options = [ + 'target' => '!1', + 'tokenize' => TRUE, + ]; + + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity->expects($this->once()) + ->method('access') + ->willReturn(TRUE); + + $this->stylePlugin->expects($this->once()) + ->method('tokenizeValue') + ->with('!1', 0) + ->willReturn(5); + $this->stylePlugin->expects($this->once()) + ->method('hasToken') + ->with('!1') + ->willReturn(TRUE); + + $this->entityStorage->expects($this->never()) + ->method('loadByProperties'); + $this->entityStorage->expects($this->once()) + ->method('load') + ->with(5) + ->willReturn($entity); + $this->entityViewBuilder->expects($this->once()) + ->method('view') + ->with($entity, 'default') + ->willReturn(['#markup' => 'hallo']); + + $this->entityHandler->init($this->executable, $this->display, $options); + + $result = $this->entityHandler->render(); + $this->assertEquals(['#markup' => 'hallo'], $result); + } + + /** + * @covers ::render + * @covers ::defineOptions + * @covers ::init + */ + public function testRenderWithUuid() { + $this->setupEntityManager(); + $uuid = '1d52762e-b9d8-4177-908f-572d1a5845a4'; + $options = [ + 'target' => $uuid, + 'tokenize' => FALSE, + ]; + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity->expects($this->once()) + ->method('access') + ->willReturn(TRUE); + + $this->entityStorage->expects($this->never()) + ->method('load'); + $this->entityManager->expects($this->once()) + ->method('loadEntityByConfigTarget') + ->willReturn($entity); + $this->entityViewBuilder->expects($this->once()) + ->method('view') + ->with($entity, 'default') + ->willReturn(['#markup' => 'hallo']); + + $this->entityHandler->init($this->executable, $this->display, $options); + + $result = $this->entityHandler->render(); + $this->assertEquals(['#markup' => 'hallo'], $result); + } + + /** + * @covers ::calculateDependencies + */ + public function testCalculateDependenciesWithPlaceholder() { + $this->setupEntityManager(); + + $options = [ + 'target' => '!1', + ]; + $this->entityHandler->init($this->executable, $this->display, $options); + + $this->assertEquals([], $this->entityHandler->calculateDependencies()); + } + + /** + * @covers ::calculateDependencies + */ + public function testCalculateDependenciesWithUuid() { + $this->setupEntityManager(); + + $uuid = '1d52762e-b9d8-4177-908f-572d1a5845a4'; + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity->expects($this->once()) + ->method('getConfigDependencyName') + ->willReturn('entity_test:test-bundle:1d52762e-b9d8-4177-908f-572d1a5845a4'); + $this->entityStorage->expects($this->never()) + ->method('load'); + $this->entityManager->expects($this->once()) + ->method('loadEntityByConfigTarget') + ->willReturn($entity); + $entity_type->expects($this->once()) + ->method('getConfigDependencyKey') + ->willReturn('content'); + $this->entityManager->expects($this->once()) + ->method('getDefinition') + ->willReturn($entity_type); + + $options = [ + 'target' => $uuid, + ]; + $this->entityHandler->init($this->executable, $this->display, $options); + + $this->assertEquals(['content' => ['entity_test:test-bundle:1d52762e-b9d8-4177-908f-572d1a5845a4']], $this->entityHandler->calculateDependencies()); + } + + /** + * @covers ::calculateDependencies + */ + public function testCalculateDependenciesWithEntityId() { + $this->setupEntityManager(); + + $uuid = '1d52762e-b9d8-4177-908f-572d1a5845a4'; + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity->expects($this->once()) + ->method('getConfigDependencyName') + ->willReturn('entity_test:test-bundle:1d52762e-b9d8-4177-908f-572d1a5845a4'); + $this->entityManager->expects($this->once()) + ->method('loadEntityByConfigTarget') + ->willReturn($entity); + $this->entityStorage->expects($this->never()) + ->method('loadByProperties'); + $entity_type->expects($this->once()) + ->method('getConfigDependencyKey') + ->willReturn('content'); + $this->entityManager->expects($this->once()) + ->method('getDefinition') + ->willReturn($entity_type); + + $options = [ + 'target' => 1, + ]; + $this->entityHandler->init($this->executable, $this->display, $options); + + $this->assertEquals(['content' => ['entity_test:test-bundle:1d52762e-b9d8-4177-908f-572d1a5845a4']], $this->entityHandler->calculateDependencies()); + } + +} diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php index 2f3e417..3644313 100644 --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -1153,6 +1153,13 @@ public function getConfigDependencyName() { /** * {@inheritdoc} */ + public function getConfigTarget() { + return $this->storage->getConfigTarget(); + } + + /** + * {@inheritdoc} + */ public function onDependencyRemoval(array $dependencies) { return $this->storage->onDependencyRemoval($dependencies); }