From 695bdecc09d4b0c6e19ff6969b73f0c58f9aeeb9 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 16:30:30 +0200 Subject: [PATCH 01/19] OPENEUROPA-3271: Add new entity meta bundle and plugin. --- .../emr.entity_meta_type.oe_list_page.yml | 5 + ...ity_meta.oe_list_page.list_page_plugin.yml | 18 ++ ...a.oe_list_page.list_page_plugin_config.yml | 18 ++ ...d.storage.entity_meta.list_page_plugin.yml | 20 ++ ...ge.entity_meta.list_page_plugin_config.yml | 18 ++ src/ListPageWrapper.php | 51 +++++ src/Plugin/EntityMetaRelation/ListPage.php | 175 ++++++++++++++++++ 7 files changed, 305 insertions(+) create mode 100755 config/install/emr.entity_meta_type.oe_list_page.yml create mode 100644 config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml create mode 100644 config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml create mode 100644 config/install/field.storage.entity_meta.list_page_plugin.yml create mode 100644 config/install/field.storage.entity_meta.list_page_plugin_config.yml create mode 100644 src/ListPageWrapper.php create mode 100755 src/Plugin/EntityMetaRelation/ListPage.php diff --git a/config/install/emr.entity_meta_type.oe_list_page.yml b/config/install/emr.entity_meta_type.oe_list_page.yml new file mode 100755 index 00000000..6bb5d2cb --- /dev/null +++ b/config/install/emr.entity_meta_type.oe_list_page.yml @@ -0,0 +1,5 @@ +langcode: en +status: true +dependencies: { } +id: oe_list_page +label: 'List Page' diff --git a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml new file mode 100644 index 00000000..ba0fabcd --- /dev/null +++ b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + config: + - emr.entity_meta_type.oe_list_page + - field.storage.entity_meta.list_page_plugin +id: entity_meta.oe_list_page.list_page_plugin +field_name: list_page_plugin +entity_type: entity_meta +bundle: oe_list_page +label: 'Source plugin' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: { } +field_type: string diff --git a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml new file mode 100644 index 00000000..96dcf4b7 --- /dev/null +++ b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + config: + - emr.entity_meta_type.oe_list_page + - field.storage.entity_meta.list_page_plugin_config +id: entity_meta.oe_list_page.list_page_plugin_config +field_name: list_page_plugin_config +entity_type: entity_meta +bundle: oe_list_page +label: 'Source plugin configuration' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: { } +field_type: string_long diff --git a/config/install/field.storage.entity_meta.list_page_plugin.yml b/config/install/field.storage.entity_meta.list_page_plugin.yml new file mode 100644 index 00000000..3235dfba --- /dev/null +++ b/config/install/field.storage.entity_meta.list_page_plugin.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + module: + - emr +id: entity_meta.list_page_plugin +field_name: list_page_plugin +entity_type: entity_meta +type: string +settings: + max_length: 255 + is_ascii: false + case_sensitive: false +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/install/field.storage.entity_meta.list_page_plugin_config.yml b/config/install/field.storage.entity_meta.list_page_plugin_config.yml new file mode 100644 index 00000000..45c31ef4 --- /dev/null +++ b/config/install/field.storage.entity_meta.list_page_plugin_config.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + module: + - emr +id: entity_meta.list_page_plugin_config +field_name: list_page_plugin_config +entity_type: entity_meta +type: string_long +settings: + case_sensitive: false +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/src/ListPageWrapper.php b/src/ListPageWrapper.php new file mode 100644 index 00000000..c6c71723 --- /dev/null +++ b/src/ListPageWrapper.php @@ -0,0 +1,51 @@ +entityMeta->set('list_page_plugin', $entity_type . ':' . $bundle); + $this->entityMeta->set('list_page_plugin_config', serialize([ + 'entity_type' => $entity_type, + 'bundle' => $bundle, + ])); + + } + + /** + * Returns the plugin configuration. + * + * @return array + * The plugin configuration. + */ + public function getListPageConfiguration(): array { + return $this->entityMeta->get('list_page_plugin_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('list_page_plugin_config')->value); + } + + /** + * Sets the plugin configuration. + * + * @param array $configuration + * The plugin configuration. + */ + public function setPluginConfiguration(array $configuration): void { + $this->entityMeta->set('list_page_plugin_config', serialize($configuration)); + } + +} diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php new file mode 100755 index 00000000..95099c6f --- /dev/null +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -0,0 +1,175 @@ +entityTypeBundleInfo = $entity_type_bundle_info; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_field.manager'), + $container->get('entity_type.manager'), + $container->get('entity_type.bundle.info') + ); + } + + /** + * Ajax request handler. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state. + * + * @return array + * The form element. + */ + public function updateEntityBundles(array &$form, FormStateInterface $form_state): array { + $key = $this->getFormKey(); + return $form[$key]['bundle']; + } + + /** + * {@inheritdoc} + */ + public function build(array $form, FormStateInterface $form_state, ContentEntityInterface $entity): array { + $key = $this->getFormKey(); + $this->buildFormContainer($form, $form_state, $key); + $entity_meta_bundle = $this->getPluginDefinition()['entity_meta_bundle']; + + // Get the related List Page entity meta. + /** @var \Drupal\emr\Field\EntityMetaItemListInterface $entity_meta_list */ + $entity_meta_list = $entity->get('emr_entity_metas'); + /** @var \Drupal\emr\Entity\EntityMetaInterface $navigation_block_entity_meta */ + $entity_meta = $entity_meta_list->getEntityMeta($entity_meta_bundle); + /** @var \Drupal\oe_list_pages\ListPageWrapper $entity_meta_wrapper */ + $entity_meta_wrapper = $entity_meta->getWrapper(); + + $entity_type_options = []; + $entity_types = $this->entityTypeManager->getDefinitions(); + foreach ($entity_types as $entity_key => $entity_type) { + if (!$entity_type instanceof ContentEntityTypeInterface) { + continue; + } + $entity_type_options[$entity_key] = $entity_type->getLabel(); + } + + $configuration = $entity_meta_wrapper->getListPageConfiguration(); + $entity_type_id = $configuration['entity_type'] ?? NULL; + + $form[$key]['entity_type'] = [ + '#type' => 'select', + '#title' => $this->t('Entity types'), + '#options' => $entity_type_options, + '#default_value' => $form_state->getValue('entity_type') ?? $entity_type_id, + '#empty_option' => $this->t('- Select -'), + '#ajax' => [ + 'callback' => [$this, 'updateEntityBundles'], + 'disable-refocus' => FALSE, + 'event' => 'change', + 'wrapper' => 'entity-bundles', + ], + ]; + + $bundle_options = []; + if ($form[$key]['entity_type']['#default_value']) { + $bundles = $this->entityTypeBundleInfo->getBundleInfo($form[$key]['entity_type']['#default_value']); + foreach ($bundles as $bundle_key => $bundle) { + $bundle_options[$bundle_key] = $bundle['label']; + } + } + + $entity_bundle_id = $configuration['bundle'] ?? NULL; + + $form[$key]['bundle'] = [ + '#type' => 'select', + '#title' => $this->t('Bundles'), + '#prefix' => '
', + '#suffix' => '
', + '#default_value' => $form_state->getValue('entity_type') ?? $entity_bundle_id, + '#options' => $bundle_options, + '#states' => [ + 'visible' => [ + ':input[name="entity_type"]' => ['empty' => FALSE], + ], + ], + ]; + + // Set the entity meta so we use it in the submit handler. + $form_state->set($entity_meta_bundle . '_entity_meta', $entity_meta); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, FormStateInterface $form_state): void { + // Do not save new entity meta if we don't have required values. + if (!$form_state->getValue('entity_type') || !$form_state->getValue('bundle')) { + return; + } + /** @var \Drupal\Core\Entity\ContentEntityInterface $host_entity */ + $host_entity = $form_state->getFormObject()->getEntity(); + + $entity_meta_bundle = $this->getPluginDefinition()['entity_meta_bundle']; + + /** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ + $entity_meta = $form_state->get($entity_meta_bundle . '_entity_meta'); + /** @var \Drupal\oe_list_pages\ListPageWrapper $entity_meta_wrapper */ + $entity_meta_wrapper = $entity_meta->getWrapper(); + + $entity_meta_wrapper->setListPageSource($form_state->getValue('entity_type'), $form_state->getValue('bundle')); + $host_entity->get('emr_entity_metas')->attach($entity_meta); + } + +} From fd02aca0a74f43e893598a8368e9ccb59f6b1a85 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 16:32:57 +0200 Subject: [PATCH 02/19] OPENEUROPA-3271: Update info yml file. --- oe_list_pages.info.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/oe_list_pages.info.yml b/oe_list_pages.info.yml index 7a57d1dd..5dc62131 100644 --- a/oe_list_pages.info.yml +++ b/oe_list_pages.info.yml @@ -6,5 +6,13 @@ type: module core: 8.x dependencies: - - emr_node:emr_node + - emr:emr_node - search_api:search_api + +config_devel: + install: + - emr.entity_meta_type.oe_list_page + - field.field.entity_meta.oe_list_page.list_page_plugin + - field.field.entity_meta.oe_list_page.list_page_plugin_config + - field.storage.entity_meta.list_page_plugin + - field.storage.entity_meta.list_page_plugin_config From af2616bd8653a1218650d2e00a3b2ef6210b3793 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 16:46:53 +0200 Subject: [PATCH 03/19] OPENEUROPA-3272: Minor corrections. --- src/Plugin/EntityMetaRelation/ListPage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index 95099c6f..9958ecc0 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -1,6 +1,6 @@ Date: Mon, 8 Jun 2020 17:50:19 +0200 Subject: [PATCH 04/19] OPENEUROPA-3272: Correct field names. --- ...d.entity_meta.oe_list_page.list_page_plugin_config.yml | 8 ++++---- ...eld.entity_meta.oe_list_page.oe_list_pages_source.yml} | 8 ++++---- ...=> field.storage.entity_meta.oe_list_pages_config.yml} | 4 ++-- ...=> field.storage.entity_meta.oe_list_pages_source.yml} | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) rename config/install/{field.field.entity_meta.oe_list_page.list_page_plugin.yml => field.field.entity_meta.oe_list_page.oe_list_pages_source.yml} (62%) rename config/install/{field.storage.entity_meta.list_page_plugin_config.yml => field.storage.entity_meta.oe_list_pages_config.yml} (77%) rename config/install/{field.storage.entity_meta.list_page_plugin.yml => field.storage.entity_meta.oe_list_pages_source.yml} (80%) diff --git a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml index 96dcf4b7..007f3aa7 100644 --- a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml +++ b/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml @@ -3,12 +3,12 @@ status: true dependencies: config: - emr.entity_meta_type.oe_list_page - - field.storage.entity_meta.list_page_plugin_config -id: entity_meta.oe_list_page.list_page_plugin_config -field_name: list_page_plugin_config + - field.storage.entity_meta.oe_list_pages_config +id: entity_meta.oe_list_page.oe_list_pages_config +field_name: oe_list_pages_config entity_type: entity_meta bundle: oe_list_page -label: 'Source plugin configuration' +label: 'List Pages configuration' description: '' required: false translatable: false diff --git a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml b/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml similarity index 62% rename from config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml rename to config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml index ba0fabcd..f6d0529d 100644 --- a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin.yml +++ b/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml @@ -3,12 +3,12 @@ status: true dependencies: config: - emr.entity_meta_type.oe_list_page - - field.storage.entity_meta.list_page_plugin -id: entity_meta.oe_list_page.list_page_plugin -field_name: list_page_plugin + - field.storage.entity_meta.oe_list_pages_source +id: entity_meta.oe_list_page.oe_list_pages_source +field_name: oe_list_pages_source entity_type: entity_meta bundle: oe_list_page -label: 'Source plugin' +label: 'List Pages source' description: '' required: false translatable: false diff --git a/config/install/field.storage.entity_meta.list_page_plugin_config.yml b/config/install/field.storage.entity_meta.oe_list_pages_config.yml similarity index 77% rename from config/install/field.storage.entity_meta.list_page_plugin_config.yml rename to config/install/field.storage.entity_meta.oe_list_pages_config.yml index 45c31ef4..2851f013 100644 --- a/config/install/field.storage.entity_meta.list_page_plugin_config.yml +++ b/config/install/field.storage.entity_meta.oe_list_pages_config.yml @@ -3,8 +3,8 @@ status: true dependencies: module: - emr -id: entity_meta.list_page_plugin_config -field_name: list_page_plugin_config +id: entity_meta.oe_list_pages_config +field_name: oe_list_pages_config entity_type: entity_meta type: string_long settings: diff --git a/config/install/field.storage.entity_meta.list_page_plugin.yml b/config/install/field.storage.entity_meta.oe_list_pages_source.yml similarity index 80% rename from config/install/field.storage.entity_meta.list_page_plugin.yml rename to config/install/field.storage.entity_meta.oe_list_pages_source.yml index 3235dfba..f1f2d0fc 100644 --- a/config/install/field.storage.entity_meta.list_page_plugin.yml +++ b/config/install/field.storage.entity_meta.oe_list_pages_source.yml @@ -3,8 +3,8 @@ status: true dependencies: module: - emr -id: entity_meta.list_page_plugin -field_name: list_page_plugin +id: entity_meta.oe_list_pages_source +field_name: oe_list_pages_source entity_type: entity_meta type: string settings: From b6d7d0bade0f492d0d39ecb6ba09d85aba73264f Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 19:13:45 +0200 Subject: [PATCH 05/19] OPENEUROPA-3272: Fixes in field names. --- ...y_meta.oe_list_page.oe_list_pages_config.yml} | 0 src/ListPageWrapper.php | 16 ++++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) rename config/install/{field.field.entity_meta.oe_list_page.list_page_plugin_config.yml => field.field.entity_meta.oe_list_page.oe_list_pages_config.yml} (100%) diff --git a/config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml b/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_config.yml similarity index 100% rename from config/install/field.field.entity_meta.oe_list_page.list_page_plugin_config.yml rename to config/install/field.field.entity_meta.oe_list_page.oe_list_pages_config.yml diff --git a/src/ListPageWrapper.php b/src/ListPageWrapper.php index c6c71723..72c47cc3 100644 --- a/src/ListPageWrapper.php +++ b/src/ListPageWrapper.php @@ -7,7 +7,7 @@ use Drupal\emr\EntityMetaWrapper; /** - * Wrapper for the list page plugins. + * Wrapper for the list page. */ class ListPageWrapper extends EntityMetaWrapper { @@ -20,8 +20,8 @@ class ListPageWrapper extends EntityMetaWrapper { * Bundle of entity type. */ public function setListPageSource(string $entity_type, string $bundle): void { - $this->entityMeta->set('list_page_plugin', $entity_type . ':' . $bundle); - $this->entityMeta->set('list_page_plugin_config', serialize([ + $this->entityMeta->set('oe_list_pages_source', $entity_type . ':' . $bundle); + $this->entityMeta->set('oe_list_pages_config', serialize([ 'entity_type' => $entity_type, 'bundle' => $bundle, ])); @@ -29,23 +29,23 @@ public function setListPageSource(string $entity_type, string $bundle): void { } /** - * Returns the plugin configuration. + * Returns the entity meta configuration. * * @return array - * The plugin configuration. + * The configuration. */ public function getListPageConfiguration(): array { - return $this->entityMeta->get('list_page_plugin_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('list_page_plugin_config')->value); + return $this->entityMeta->get('oe_list_pages_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('oe_list_pages_config')->value); } /** - * Sets the plugin configuration. + * Sets the entity meta configuration. * * @param array $configuration * The plugin configuration. */ public function setPluginConfiguration(array $configuration): void { - $this->entityMeta->set('list_page_plugin_config', serialize($configuration)); + $this->entityMeta->set('oe_list_pages_config', serialize($configuration)); } } From 229986dc7442b6db342b06ccb3f0a17b5119b5ac Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 19:14:15 +0200 Subject: [PATCH 06/19] OPENEUROPA-3272: Add Kernel tests. --- tests/Kernel/ListPagesTest.php | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tests/Kernel/ListPagesTest.php diff --git a/tests/Kernel/ListPagesTest.php b/tests/Kernel/ListPagesTest.php new file mode 100644 index 00000000..c1b63295 --- /dev/null +++ b/tests/Kernel/ListPagesTest.php @@ -0,0 +1,106 @@ +installConfig(['oe_list_pages', 'emr', 'emr_node']); + $this->installEntitySchema('node'); + $this->installEntitySchema('entity_meta'); + $this->installEntitySchema('entity_meta_relation'); + + $values = ['type' => 'list_page', 'name' => 'List page']; + $this->nodeType = NodeType::create($values); + $this->nodeType->save(); + + /** @var \Drupal\emr\EntityMetaRelationInstaller $installer */ + $installer = \Drupal::service('emr.installer'); + $installer->installEntityMetaTypeOnContentEntityType('oe_list_page', 'node', [ + 'list_page', + ]); + + $this->nodeStorage = $this->entityTypeManager->getStorage('node'); + $this->entityMetaStorage = $this->entityTypeManager->getStorage('entity_meta'); + } + + /** + * Tests that node works correctly with entity meta. + */ + public function testListPagesEntityMeta(): void { + $node_storage = $this->entityTypeManager->getStorage('node'); + $node = $node_storage->create([ + 'type' => $this->nodeType->id(), + 'title' => 'List Page', + ]); + $node->save(); + + /** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ + $entity_meta = $node->get('emr_entity_metas') + ->getEntityMeta('oe_list_page'); + $this->assertFalse($entity_meta->isNew()); + /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ + $wrapper = $entity_meta->getWrapper(); + $this->assertFalse($wrapper->getListPageConfiguration()); + $wrapper->setListPageSource('node', 'list_page'); + $wrapper->getEntityMeta()->save(); + + $updated_node = $node_storage->load($node->id()); + /** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ + $entity_meta = $updated_node->get('emr_entity_metas') + ->getEntityMeta('oe_list_page'); + + /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ + $wrapper = $entity_meta->getWrapper(); + $this->assertEqual($wrapper->getListPageConfiguration(), [ + 'entity_type' => 'node', + 'bundle' => 'list_page', + ]); + } + +} From 2b80488152930c4fa885aad70d85c8cfccadcb4b Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Mon, 8 Jun 2020 19:32:19 +0200 Subject: [PATCH 07/19] OPENEUROPA-3272: Fix code issue. --- tests/Kernel/ListPagesTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Kernel/ListPagesTest.php b/tests/Kernel/ListPagesTest.php index c1b63295..8fb93725 100644 --- a/tests/Kernel/ListPagesTest.php +++ b/tests/Kernel/ListPagesTest.php @@ -1,6 +1,6 @@ Date: Wed, 10 Jun 2020 15:52:43 +0100 Subject: [PATCH 08/19] OPENEUROPA-3272: Remove usage of #states. --- src/Plugin/EntityMetaRelation/ListPage.php | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index 9958ecc0..eb938c0b 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -75,7 +75,7 @@ public static function create(ContainerInterface $container, array $configuratio */ public function updateEntityBundles(array &$form, FormStateInterface $form_state): array { $key = $this->getFormKey(); - return $form[$key]['bundle']; + return $form[$key]['bundle_wrapper']; } /** @@ -108,15 +108,16 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $form[$key]['entity_type'] = [ '#type' => 'select', - '#title' => $this->t('Entity types'), + '#title' => $this->t('Source entity type'), '#options' => $entity_type_options, '#default_value' => $form_state->getValue('entity_type') ?? $entity_type_id, '#empty_option' => $this->t('- Select -'), + '#required' => TRUE, '#ajax' => [ 'callback' => [$this, 'updateEntityBundles'], 'disable-refocus' => FALSE, 'event' => 'change', - 'wrapper' => 'entity-bundles', + 'wrapper' => 'list-page-entity-bundles', ], ]; @@ -130,20 +131,23 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $entity_bundle_id = $configuration['bundle'] ?? NULL; - $form[$key]['bundle'] = [ - '#type' => 'select', - '#title' => $this->t('Bundles'), - '#prefix' => '
', - '#suffix' => '
', - '#default_value' => $form_state->getValue('entity_type') ?? $entity_bundle_id, - '#options' => $bundle_options, - '#states' => [ - 'visible' => [ - ':input[name="entity_type"]' => ['empty' => FALSE], - ], + $form[$key]['bundle_wrapper'] = [ + '#type' => 'container', + '#attributes' => [ + 'id' => 'list-page-entity-bundles', ], ]; + if (!empty($form_state->getValue('entity_type')) || !empty($configuration['bundle'])) { + $form[$key]['bundle_wrapper']['bundle'] = [ + '#type' => 'select', + '#title' => $this->t('Source bundle'), + '#default_value' => $form_state->getValue('bundle') ?? $entity_bundle_id, + '#options' => $bundle_options, + '#required' => TRUE, + ]; + } + // Set the entity meta so we use it in the submit handler. $form_state->set($entity_meta_bundle . '_entity_meta', $entity_meta); From 7ec22956c868934af074bb2d9a0c2b32ff638977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni?= Date: Wed, 10 Jun 2020 17:23:05 +0100 Subject: [PATCH 09/19] OPENEUROPA-3272: Refactor field names, wrapper and tests. --- ...meta.oe_list_page.oe_list_page_config.yml} | 6 +++--- ...meta.oe_list_page.oe_list_page_source.yml} | 8 +++---- ...orage.entity_meta.oe_list_page_config.yml} | 4 ++-- ...orage.entity_meta.oe_list_page_source.yml} | 4 ++-- src/ListPageWrapper.php | 21 ++++++++++++------- src/Plugin/EntityMetaRelation/ListPage.php | 13 ++++++++++++ tests/Kernel/ListPagesTest.php | 7 ++----- 7 files changed, 39 insertions(+), 24 deletions(-) rename config/install/{field.field.entity_meta.oe_list_page.oe_list_pages_config.yml => field.field.entity_meta.oe_list_page.oe_list_page_config.yml} (69%) rename config/install/{field.field.entity_meta.oe_list_page.oe_list_pages_source.yml => field.field.entity_meta.oe_list_page.oe_list_page_source.yml} (64%) rename config/install/{field.storage.entity_meta.oe_list_pages_config.yml => field.storage.entity_meta.oe_list_page_config.yml} (79%) rename config/install/{field.storage.entity_meta.oe_list_pages_source.yml => field.storage.entity_meta.oe_list_page_source.yml} (80%) diff --git a/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_config.yml b/config/install/field.field.entity_meta.oe_list_page.oe_list_page_config.yml similarity index 69% rename from config/install/field.field.entity_meta.oe_list_page.oe_list_pages_config.yml rename to config/install/field.field.entity_meta.oe_list_page.oe_list_page_config.yml index 007f3aa7..44975372 100644 --- a/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_config.yml +++ b/config/install/field.field.entity_meta.oe_list_page.oe_list_page_config.yml @@ -3,9 +3,9 @@ status: true dependencies: config: - emr.entity_meta_type.oe_list_page - - field.storage.entity_meta.oe_list_pages_config -id: entity_meta.oe_list_page.oe_list_pages_config -field_name: oe_list_pages_config + - field.storage.entity_meta.oe_list_page_config +id: entity_meta.oe_list_page.oe_list_page_config +field_name: oe_list_page_config entity_type: entity_meta bundle: oe_list_page label: 'List Pages configuration' diff --git a/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml b/config/install/field.field.entity_meta.oe_list_page.oe_list_page_source.yml similarity index 64% rename from config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml rename to config/install/field.field.entity_meta.oe_list_page.oe_list_page_source.yml index f6d0529d..14c9ef90 100644 --- a/config/install/field.field.entity_meta.oe_list_page.oe_list_pages_source.yml +++ b/config/install/field.field.entity_meta.oe_list_page.oe_list_page_source.yml @@ -3,14 +3,14 @@ status: true dependencies: config: - emr.entity_meta_type.oe_list_page - - field.storage.entity_meta.oe_list_pages_source -id: entity_meta.oe_list_page.oe_list_pages_source -field_name: oe_list_pages_source + - field.storage.entity_meta.oe_list_page_source +id: entity_meta.oe_list_page.oe_list_page_source +field_name: oe_list_page_source entity_type: entity_meta bundle: oe_list_page label: 'List Pages source' description: '' -required: false +required: true translatable: false default_value: { } default_value_callback: '' diff --git a/config/install/field.storage.entity_meta.oe_list_pages_config.yml b/config/install/field.storage.entity_meta.oe_list_page_config.yml similarity index 79% rename from config/install/field.storage.entity_meta.oe_list_pages_config.yml rename to config/install/field.storage.entity_meta.oe_list_page_config.yml index 2851f013..0e9ba1de 100644 --- a/config/install/field.storage.entity_meta.oe_list_pages_config.yml +++ b/config/install/field.storage.entity_meta.oe_list_page_config.yml @@ -3,8 +3,8 @@ status: true dependencies: module: - emr -id: entity_meta.oe_list_pages_config -field_name: oe_list_pages_config +id: entity_meta.oe_list_page_config +field_name: oe_list_page_config entity_type: entity_meta type: string_long settings: diff --git a/config/install/field.storage.entity_meta.oe_list_pages_source.yml b/config/install/field.storage.entity_meta.oe_list_page_source.yml similarity index 80% rename from config/install/field.storage.entity_meta.oe_list_pages_source.yml rename to config/install/field.storage.entity_meta.oe_list_page_source.yml index f1f2d0fc..d4e1aae6 100644 --- a/config/install/field.storage.entity_meta.oe_list_pages_source.yml +++ b/config/install/field.storage.entity_meta.oe_list_page_source.yml @@ -3,8 +3,8 @@ status: true dependencies: module: - emr -id: entity_meta.oe_list_pages_source -field_name: oe_list_pages_source +id: entity_meta.oe_list_page_source +field_name: oe_list_page_source entity_type: entity_meta type: string settings: diff --git a/src/ListPageWrapper.php b/src/ListPageWrapper.php index 72c47cc3..6c3f350b 100644 --- a/src/ListPageWrapper.php +++ b/src/ListPageWrapper.php @@ -12,7 +12,7 @@ class ListPageWrapper extends EntityMetaWrapper { /** - * Set the entity/bundle pair. + * Set the entity/bundle pair for source. * * @param string $entity_type * Entity type name. @@ -20,12 +20,17 @@ class ListPageWrapper extends EntityMetaWrapper { * Bundle of entity type. */ public function setListPageSource(string $entity_type, string $bundle): void { - $this->entityMeta->set('oe_list_pages_source', $entity_type . ':' . $bundle); - $this->entityMeta->set('oe_list_pages_config', serialize([ - 'entity_type' => $entity_type, - 'bundle' => $bundle, - ])); + $this->entityMeta->set('oe_list_page_source', $entity_type . ':' . $bundle); + } + /** + * Returns the entity meta source. + * + * @return string + * The configuration. + */ + public function getListPageSource(): ?string { + return $this->entityMeta->get('oe_list_page_source')->value; } /** @@ -35,7 +40,7 @@ public function setListPageSource(string $entity_type, string $bundle): void { * The configuration. */ public function getListPageConfiguration(): array { - return $this->entityMeta->get('oe_list_pages_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('oe_list_pages_config')->value); + return $this->entityMeta->get('oe_list_page_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('oe_list_page_config')->value); } /** @@ -45,7 +50,7 @@ public function getListPageConfiguration(): array { * The plugin configuration. */ public function setPluginConfiguration(array $configuration): void { - $this->entityMeta->set('oe_list_pages_config', serialize($configuration)); + $this->entityMeta->set('oe_list_page_config', serialize($configuration)); } } diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index eb938c0b..9e7299dc 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\emr\Entity\EntityMetaInterface; use Drupal\emr\Plugin\EntityMetaRelationContentFormPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -176,4 +177,16 @@ public function submit(array $form, FormStateInterface $form_state): void { $host_entity->get('emr_entity_metas')->attach($entity_meta); } + /** + * {@inheritdoc} + */ + public function fillDefaultEntityMetaValues(EntityMetaInterface $entity_meta): void { + // Set the default value to be the first node bundle. + // This avoid any meta of this type is created without value. + $bundles = $this->entityTypeBundleInfo->getBundleInfo('node'); + /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ + $wrapper = $entity_meta->getWrapper(); + $wrapper->setListPageSource('node', key($bundles)); + } + } diff --git a/tests/Kernel/ListPagesTest.php b/tests/Kernel/ListPagesTest.php index 8fb93725..306f04f5 100644 --- a/tests/Kernel/ListPagesTest.php +++ b/tests/Kernel/ListPagesTest.php @@ -86,7 +86,7 @@ public function testListPagesEntityMeta(): void { $this->assertFalse($entity_meta->isNew()); /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $this->assertFalse($wrapper->getListPageConfiguration()); + $this->assertEquals('node:list_page', $wrapper->getListPageSource()); $wrapper->setListPageSource('node', 'list_page'); $wrapper->getEntityMeta()->save(); @@ -97,10 +97,7 @@ public function testListPagesEntityMeta(): void { /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $this->assertEqual($wrapper->getListPageConfiguration(), [ - 'entity_type' => 'node', - 'bundle' => 'list_page', - ]); + $this->assertEquals($wrapper->getListPageConfiguration(), []); } } From 7aef93247b2fd0d4edd89375021e379487797fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni?= Date: Wed, 10 Jun 2020 17:38:53 +0100 Subject: [PATCH 10/19] OPENEUROPA-3272: Fix tests and wrapper. --- src/ListPageWrapper.php | 2 +- tests/Kernel/ListPagesTest.php | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ListPageWrapper.php b/src/ListPageWrapper.php index 6c3f350b..0ef9a273 100644 --- a/src/ListPageWrapper.php +++ b/src/ListPageWrapper.php @@ -49,7 +49,7 @@ public function getListPageConfiguration(): array { * @param array $configuration * The plugin configuration. */ - public function setPluginConfiguration(array $configuration): void { + public function setListPageConfiguration(array $configuration): void { $this->entityMeta->set('oe_list_page_config', serialize($configuration)); } diff --git a/tests/Kernel/ListPagesTest.php b/tests/Kernel/ListPagesTest.php index 306f04f5..dea8c2ad 100644 --- a/tests/Kernel/ListPagesTest.php +++ b/tests/Kernel/ListPagesTest.php @@ -51,6 +51,7 @@ protected function setUp() { parent::setUp(); $this->installConfig(['oe_list_pages', 'emr', 'emr_node']); + $this->installSchema('node', ['node_access']); $this->installEntitySchema('node'); $this->installEntitySchema('entity_meta'); $this->installEntitySchema('entity_meta_relation'); @@ -81,14 +82,16 @@ public function testListPagesEntityMeta(): void { $node->save(); /** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ - $entity_meta = $node->get('emr_entity_metas') - ->getEntityMeta('oe_list_page'); + $entity_meta = $node->get('emr_entity_metas')->getEntityMeta('oe_list_page'); $this->assertFalse($entity_meta->isNew()); /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); $this->assertEquals('node:list_page', $wrapper->getListPageSource()); + $this->assertEquals([], $wrapper->getListPageConfiguration()); $wrapper->setListPageSource('node', 'list_page'); - $wrapper->getEntityMeta()->save(); + $wrapper->setListPageConfiguration(['exposed' => ['list']]); + $node->get('emr_entity_metas')->attach($entity_meta); + $node->save(); $updated_node = $node_storage->load($node->id()); /** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ @@ -97,7 +100,7 @@ public function testListPagesEntityMeta(): void { /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $this->assertEquals($wrapper->getListPageConfiguration(), []); + $this->assertEquals($wrapper->getListPageConfiguration(), ['exposed' => ['list']]); } } From acb00a83be57a40ee6d1a25ede331d1c8dd06779 Mon Sep 17 00:00:00 2001 From: upchuk Date: Thu, 11 Jun 2020 12:46:40 +0200 Subject: [PATCH 11/19] OPENEUROPA-3272: Fixing form and list page wrapper --- src/ListPageWrapper.php | 57 +++++++++++++++++----- src/Plugin/EntityMetaRelation/ListPage.php | 19 +++++--- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/ListPageWrapper.php b/src/ListPageWrapper.php index 0ef9a273..9ed95fc8 100644 --- a/src/ListPageWrapper.php +++ b/src/ListPageWrapper.php @@ -7,39 +7,74 @@ use Drupal\emr\EntityMetaWrapper; /** - * Wrapper for the list page. + * Wrapper for the list page entity meta. */ class ListPageWrapper extends EntityMetaWrapper { /** - * Set the entity/bundle pair for source. + * Set the entity/bundle pair for the list page source. * * @param string $entity_type * Entity type name. * @param string $bundle * Bundle of entity type. */ - public function setListPageSource(string $entity_type, string $bundle): void { + public function setSource(string $entity_type, string $bundle): void { $this->entityMeta->set('oe_list_page_source', $entity_type . ':' . $bundle); } /** - * Returns the entity meta source. + * Returns the entity meta list page source. * - * @return string - * The configuration. + * This is a pair of entity_type:bundle that will be used for querying on this + * list page. + * + * @return string|null + * The entity_type:bundle pair source. */ - public function getListPageSource(): ?string { + public function getSource(): ?string { return $this->entityMeta->get('oe_list_page_source')->value; } + /** + * Returns the entity type used as the source. + * + * @return string|null + * The entity type. + */ + public function getSourceEntityType(): ?string { + $source = $this->getSource(); + if (!$source) { + return NULL; + } + + list($entity_type, $bundle) = explode(':', $source); + return $entity_type; + } + + /** + * Returns the bundle used in the source. + * + * @return string|null + * The bundle. + */ + public function getSourceEntityBundle(): ?string { + $source = $this->getSource(); + if (!$source) { + return NULL; + } + + list($entity_type, $bundle) = explode(':', $source); + return $bundle; + } + /** * Returns the entity meta configuration. * * @return array - * The configuration. + * The list page configuration. */ - public function getListPageConfiguration(): array { + public function getConfiguration(): array { return $this->entityMeta->get('oe_list_page_config')->isEmpty() ? [] : unserialize($this->entityMeta->get('oe_list_page_config')->value); } @@ -47,9 +82,9 @@ public function getListPageConfiguration(): array { * Sets the entity meta configuration. * * @param array $configuration - * The plugin configuration. + * The list page configuration. */ - public function setListPageConfiguration(array $configuration): void { + public function setConfiguration(array $configuration): void { $this->entityMeta->set('oe_list_page_config', serialize($configuration)); } diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index 9e7299dc..33a5ba25 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -104,12 +104,14 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $entity_type_options[$entity_key] = $entity_type->getLabel(); } - $configuration = $entity_meta_wrapper->getListPageConfiguration(); - $entity_type_id = $configuration['entity_type'] ?? NULL; + // @todo throw event to limit the allowed entity types. + + $entity_type_id = $entity_meta_wrapper->getSourceEntityType(); $form[$key]['entity_type'] = [ '#type' => 'select', '#title' => $this->t('Source entity type'), + '#description' => $this->t('Select the entity type that will be used as the source for this list page.'), '#options' => $entity_type_options, '#default_value' => $form_state->getValue('entity_type') ?? $entity_type_id, '#empty_option' => $this->t('- Select -'), @@ -128,9 +130,11 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity foreach ($bundles as $bundle_key => $bundle) { $bundle_options[$bundle_key] = $bundle['label']; } + + // @todo throw event to limit the allowed bundles. } - $entity_bundle_id = $configuration['bundle'] ?? NULL; + $entity_bundle_id = $entity_meta_wrapper->getSourceEntityBundle(); $form[$key]['bundle_wrapper'] = [ '#type' => 'container', @@ -139,7 +143,7 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity ], ]; - if (!empty($form_state->getValue('entity_type')) || !empty($configuration['bundle'])) { + if (!empty($form_state->getValue('entity_type')) || $entity_bundle_id) { $form[$key]['bundle_wrapper']['bundle'] = [ '#type' => 'select', '#title' => $this->t('Source bundle'), @@ -173,7 +177,7 @@ public function submit(array $form, FormStateInterface $form_state): void { /** @var \Drupal\oe_list_pages\ListPageWrapper $entity_meta_wrapper */ $entity_meta_wrapper = $entity_meta->getWrapper(); - $entity_meta_wrapper->setListPageSource($form_state->getValue('entity_type'), $form_state->getValue('bundle')); + $entity_meta_wrapper->setSource($form_state->getValue('entity_type'), $form_state->getValue('bundle')); $host_entity->get('emr_entity_metas')->attach($entity_meta); } @@ -182,11 +186,12 @@ public function submit(array $form, FormStateInterface $form_state): void { */ public function fillDefaultEntityMetaValues(EntityMetaInterface $entity_meta): void { // Set the default value to be the first node bundle. - // This avoid any meta of this type is created without value. + // We want to do this because we don't want any entity meta being created + // without a value (via the API). $bundles = $this->entityTypeBundleInfo->getBundleInfo('node'); /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $wrapper->setListPageSource('node', key($bundles)); + $wrapper->setSource('node', key($bundles)); } } From 0089d00f2ff54e156384da1374b663b73233d772 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 01:03:24 +0200 Subject: [PATCH 12/19] OPENEUROPA-3272: Add event triggering inside entity meta relations plugin. --- src/Plugin/EntityMetaRelation/ListPage.php | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index 33a5ba25..df5fc714 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -14,7 +14,10 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\emr\Entity\EntityMetaInterface; use Drupal\emr\Plugin\EntityMetaRelationContentFormPluginBase; +use Drupal\oe_list_pages\ListPageEvents; +use Drupal\oe_list_pages\ListPageSourceRetrieveEvent; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Plugin implementation of the entity_meta_relation. @@ -41,12 +44,20 @@ class ListPage extends EntityMetaRelationContentFormPluginBase { */ private $entityTypeBundleInfo; + /** + * The event dispatcher. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + */ + private $eventDispatcher; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EventDispatcherInterface $dispatcher) { parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_field_manager, $entity_type_manager); $this->entityTypeBundleInfo = $entity_type_bundle_info; + $this->eventDispatcher = $dispatcher; } /** @@ -59,7 +70,8 @@ public static function create(ContainerInterface $container, array $configuratio $plugin_definition, $container->get('entity_field.manager'), $container->get('entity_type.manager'), - $container->get('entity_type.bundle.info') + $container->get('entity_type.bundle.info'), + $container->get('event_dispatcher') ); } @@ -104,7 +116,9 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $entity_type_options[$entity_key] = $entity_type->getLabel(); } - // @todo throw event to limit the allowed entity types. + $event = new ListPageSourceRetrieveEvent($entity_type_options); + $this->eventDispatcher->dispatch(ListPageEvents::ALTER_ALLOWED_ENTITY_TYPES, $event); + $entity_type_options = $event->getEntityTypes(); $entity_type_id = $entity_meta_wrapper->getSourceEntityType(); @@ -125,13 +139,15 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity ]; $bundle_options = []; - if ($form[$key]['entity_type']['#default_value']) { - $bundles = $this->entityTypeBundleInfo->getBundleInfo($form[$key]['entity_type']['#default_value']); + if ($selected_entity_type = $form[$key]['entity_type']['#default_value']) { + $bundles = $this->entityTypeBundleInfo->getBundleInfo($selected_entity_type); foreach ($bundles as $bundle_key => $bundle) { $bundle_options[$bundle_key] = $bundle['label']; } - // @todo throw event to limit the allowed bundles. + $event->setBundles($selected_entity_type, $bundle_options); + $this->eventDispatcher->dispatch(ListPageEvents::ALTER_ALLOWED_BUNDLES, $event); + $bundle_options = $event->getBundles(); } $entity_bundle_id = $entity_meta_wrapper->getSourceEntityBundle(); From 4209aac84000a78e19d3510f4be0ff343059a2ff Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 01:05:30 +0200 Subject: [PATCH 13/19] OPENEUROPA-3272: Add event declaration classes. --- src/ListPageEvents.php | 26 +++++++++ src/ListPageSourceRetrieveEvent.php | 88 +++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/ListPageEvents.php create mode 100644 src/ListPageSourceRetrieveEvent.php diff --git a/src/ListPageEvents.php b/src/ListPageEvents.php new file mode 100644 index 00000000..2034871b --- /dev/null +++ b/src/ListPageEvents.php @@ -0,0 +1,26 @@ +entityTypeIds = $entity_type_ids; + $this->bundles = $bundles; + } + + /** + * Returns the allowed entity types. + * + * @return string[] + * The list of entity types. + */ + public function getEntityTypes(): array { + return $this->entityTypeIds; + } + + /** + * Set the allowed entity types. + * + * @param array $entity_type_ids + * The list of entity types. + */ + public function setEntityTypes(array $entity_type_ids): void { + $this->entityTypeIds = $entity_type_ids; + } + + /** + * Returns the allowed bundles. + * + * @return string[] + * The list of allowed bundles. + */ + public function getBundles(): array { + return $this->bundles; + } + + /** + * Set the allowed bundles. + * + * @param string $entity_type + * The entity type. + * @param array $bundles + * The bundles. + */ + public function setBundles(string $entity_type, array $bundles): void { + $this->entityTypeIds = [$entity_type => $entity_type]; + $this->bundles = $bundles; + } + +} From 8e811b8539710f23747ae03c241377cf110f1a54 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 01:09:35 +0200 Subject: [PATCH 14/19] OPENEUROPA-3272: Test module with EventSubscriber usage. --- .../oe_list_pages_test.info.yml | 9 ++ .../oe_list_pages_test.services.yml | 6 ++ .../ListPagesTestSubscriber.php | 95 +++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100755 tests/modules/oe_list_pages_test/oe_list_pages_test.info.yml create mode 100755 tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml create mode 100755 tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php diff --git a/tests/modules/oe_list_pages_test/oe_list_pages_test.info.yml b/tests/modules/oe_list_pages_test/oe_list_pages_test.info.yml new file mode 100755 index 00000000..d76a1428 --- /dev/null +++ b/tests/modules/oe_list_pages_test/oe_list_pages_test.info.yml @@ -0,0 +1,9 @@ +name: OpenEuropa List Pages +type: module +description: The test module for OE List Pages. + +package: Testing +core: 8.x + +dependencies: + - oe_list_pages diff --git a/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml b/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml new file mode 100755 index 00000000..f05e4639 --- /dev/null +++ b/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml @@ -0,0 +1,6 @@ +services: + oe_list_pages_test.event_subscriber: + class: Drupal\oe_list_pages_test\EventSubscriber\ListPagesTestSubscriber + arguments: ['@config.factory'] + tags: + - { name: event_subscriber } diff --git a/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php b/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php new file mode 100755 index 00000000..a3fa4953 --- /dev/null +++ b/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php @@ -0,0 +1,95 @@ +config = $config_factory->get('oe_list_pages_test.settings'); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + return [ + ListPageEvents::ALTER_ALLOWED_ENTITY_TYPES => ['onEntityTypesRetrieving'], + ListPageEvents::ALTER_ALLOWED_BUNDLES => ['onBundlesRetrieving'], + ]; + } + + /** + * Event handler for limiting allowed entity types. + * + * @param \Drupal\oe_list_pages\ListPageSourceRetrieveEvent $event + * The event object. + */ + public function onEntityTypesRetrieving(ListPageSourceRetrieveEvent $event): void { + $event->addCacheableDependency($this->config); + $entity_types = $event->getEntityTypes(); + $allowed_entity_bundles = $this->config->get('allowed_entity_types_bundles'); + if ($allowed_entity_bundles === NULL) { + return; + } + $allowed_entity_bundles = array_keys($allowed_entity_bundles); + + foreach (array_keys($entity_types) as $entity_type) { + if (!in_array($entity_type, $allowed_entity_bundles)) { + unset($entity_types[$entity_type]); + } + } + $event->setEntityTypes($entity_types); + } + + /** + * Event handler for limiting allowed bundles. + * + * @param \Drupal\oe_list_pages\ListPageSourceRetrieveEvent $event + * The event object. + */ + public function onBundlesRetrieving(ListPageSourceRetrieveEvent $event): void { + $event->addCacheableDependency($this->config); + $entity_types = $event->getEntityTypes(); + $entity_type = reset($entity_types); + $bundles = $event->getBundles(); + + $allowed_entity_bundles = $this->config->get('allowed_entity_types_bundles'); + if ($allowed_entity_bundles === NULL) { + return; + } + + $allowed_bundles = $allowed_entity_bundles[$entity_type] ? array_keys($allowed_entity_bundles[$entity_type]) : NULL; + + foreach (array_keys($bundles) as $bundle) { + if (!in_array($bundle, $allowed_bundles)) { + unset($bundles[$bundle]); + } + } + + $event->setBundles($entity_type, $bundles); + } + +} From 25ab58835bd25074e9ca5bcce26ec26e11f1cee7 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 01:13:13 +0200 Subject: [PATCH 15/19] OPENEUROPA-3272: Add Functional Javascript test. --- .../ListPagesPluginTest.php | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100755 tests/FunctionalJavascript/ListPagesPluginTest.php diff --git a/tests/FunctionalJavascript/ListPagesPluginTest.php b/tests/FunctionalJavascript/ListPagesPluginTest.php new file mode 100755 index 00000000..2e6f9722 --- /dev/null +++ b/tests/FunctionalJavascript/ListPagesPluginTest.php @@ -0,0 +1,180 @@ +drupalCreateContentType([ + 'type' => 'node_type1', + 'name' => 'Node Type 1', + ]); + + $this->drupalCreateContentType([ + 'type' => 'node_type2', + 'name' => 'Node Type 2', + ]); + + $this->drupalCreateContentType([ + 'type' => 'node_type3', + 'name' => 'Node Type 3', + ]); + + Vocabulary::create([ + 'vid' => 'voc1', + 'name' => 'Vocabulary 1', + ])->save(); + + Vocabulary::create([ + 'vid' => 'voc2', + 'name' => 'Vocabulary 2', + ])->save(); + + Vocabulary::create([ + 'vid' => 'voc3', + 'name' => 'Vocabulary 3', + ])->save(); + + /** @var \Drupal\emr\EntityMetaRelationInstaller $installer */ + $installer = \Drupal::service('emr.installer'); + $installer->installEntityMetaTypeOnContentEntityType('oe_list_page', 'node', [ + 'node_type1', + ]); + } + + /** + * Test List Page entity meta plugin and available entity types/bundles. + */ + public function testListPagePluginConfigForm(): void { + + $this->drupalLogin($this->rootUser); + $this->drupalGet('node/add/node_type1'); + $this->clickLink('List Page'); + + $actual_entity_types = $this->getSelectOptions('Source entity type'); + + $expected_entity_types = [ + '' => '- Select -', + 'entity_meta_relation' => 'Entity Meta Relation', + 'entity_meta' => 'Entity meta', + 'node' => 'Content', + 'path_alias' => 'URL alias', + 'search_api_task' => 'Search task', + 'user' => 'User', + 'taxonomy_term' => 'Taxonomy term', + ]; + $this->assertEquals($expected_entity_types, $actual_entity_types); + $this->assertOptionSelected('Source entity type', 'Content'); + + $actual_bundles = $this->getSelectOptions('Source bundle'); + $expected_bundles = [ + 'node_type1' => 'Node Type 1', + 'node_type2' => 'Node Type 2', + 'node_type3' => 'Node Type 3', + ]; + $this->assertEquals($expected_bundles, $actual_bundles); + + $this->getSession()->getPage()->selectFieldOption('Source entity type', 'taxonomy_term'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $actual_bundles = $this->getSelectOptions('Source bundle'); + $expected_bundles = [ + 'voc1' => 'Vocabulary 1', + 'voc2' => 'Vocabulary 2', + 'voc3' => 'Vocabulary 3', + ]; + $this->assertEquals($expected_bundles, $actual_bundles); + + $config = \Drupal::configFactory()->getEditable('oe_list_pages_test.settings'); + $config->set('allowed_entity_types_bundles', [ + 'node' => [ + 'node_type2' => 'node_type2', + 'node_type3' => 'node_type3', + ], + 'taxonomy_term' => [ + 'voc1' => 'voc1', + 'voc3' => 'voc3', + ], + ]); + $config->save(); + $this->drupalGet('node/add/node_type1'); + $this->clickLink('List Page'); + $actual_entity_types = $this->getSelectOptions('Source entity type'); + $this->assertEquals([ + '' => '- Select -', + 'node' => 'Content', + 'taxonomy_term' => 'Taxonomy term', + ], $actual_entity_types); + $this->assertOptionSelected('Source entity type', 'Content'); + $actual_bundles = $this->getSelectOptions('Source bundle'); + $expected_bundles = [ + 'node_type2' => 'Node Type 2', + 'node_type3' => 'Node Type 3', + ]; + $this->assertEquals($expected_bundles, $actual_bundles); + $this->getSession()->getPage()->selectFieldOption('Source entity type', 'taxonomy_term'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $actual_bundles = $this->getSelectOptions('Source bundle'); + $expected_bundles = [ + 'voc1' => 'Vocabulary 1', + 'voc3' => 'Vocabulary 3', + ]; + $this->assertEquals($expected_bundles, $actual_bundles); + } + + /** + * Get available options of select box. + * + * @param string $field + * The label, id or name of select box. + * + * @return array + * Select box options. + */ + protected function getSelectOptions(string $field): array { + $page = $this->getSession()->getPage(); + $options = $page->findField($field)->findAll('css', 'option'); + $actual_options = []; + foreach ($options as $option) { + $actual_options[$option->getValue()] = $option->getText(); + } + return $actual_options; + } + +} From 92196c8a68f6ac7951021923001496b725fe4739 Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 01:14:44 +0200 Subject: [PATCH 16/19] OPENEUROPA-3272: Enable support of Functional javascript tests. --- docker-compose.yml | 21 +++++++++++++++++++++ phpunit.xml.dist | 1 + runner.yml.dist | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 7a02cb4f..1e164598 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,27 @@ services: # ports: # - 3306:3306 + # If you would like to see what is going on you can run the following on your host: + # docker run --rm -p 4444:4444 -p 5900:5900 --network="host" selenium/standalone-chrome-debug:latest + # Newer version of this image might run into this issue: + # @link https://github.com/elgalu/docker-selenium/issues/20 + selenium: + image: selenium/standalone-chrome-debug:3.141.59-oxygen + expose: + - '4444' + environment: + - DISPLAY=:99 + - SE_OPTS=-debug + - SCREEN_WIDTH=1280 + - SCREEN_HEIGHT=800 + - VNC_NO_PASSWORD=1 + ports: + - '4444:4444' + - "5900:5900" + volumes: + - /dev/shm:/dev/shm + shm_size: 2g + #### Mac users: uncomment the "volumes" key to enable the NFS file sharing. You can find more information about Docker for Mac here: https://github.com/openeuropa/openeuropa/blob/master/docs/starting/tooling.md#using-docker-on-macos #volumes: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 7002013e..db99eb82 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,6 +6,7 @@ + diff --git a/runner.yml.dist b/runner.yml.dist index 0f099b9b..544bf5a5 100644 --- a/runner.yml.dist +++ b/runner.yml.dist @@ -30,6 +30,12 @@ drupal: - "vendor" - "${drupal.root}" + +selenium: + host: "http://selenium" + port: "4444" + browser: "chrome" + commands: drupal:site-setup: - { task: "symlink", from: "../../..", to: "${drupal.root}/modules/custom/oe_list_pages" } From c43d707d8b2af8adc4caed1ac6fc7275dcdf358a Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 07:49:42 +0200 Subject: [PATCH 17/19] OPENEUROPA-3272: Adjust existing tests. --- tests/Kernel/ListPagesTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Kernel/ListPagesTest.php b/tests/Kernel/ListPagesTest.php index dea8c2ad..9aa8b566 100644 --- a/tests/Kernel/ListPagesTest.php +++ b/tests/Kernel/ListPagesTest.php @@ -86,10 +86,10 @@ public function testListPagesEntityMeta(): void { $this->assertFalse($entity_meta->isNew()); /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $this->assertEquals('node:list_page', $wrapper->getListPageSource()); - $this->assertEquals([], $wrapper->getListPageConfiguration()); - $wrapper->setListPageSource('node', 'list_page'); - $wrapper->setListPageConfiguration(['exposed' => ['list']]); + $this->assertEquals('node:list_page', $wrapper->getSource()); + $this->assertEquals([], $wrapper->getConfiguration()); + $wrapper->setSource('node', 'list_page'); + $wrapper->setConfiguration(['exposed' => ['list']]); $node->get('emr_entity_metas')->attach($entity_meta); $node->save(); @@ -100,7 +100,7 @@ public function testListPagesEntityMeta(): void { /** @var \Drupal\oe_list_pages\ListPageWrapper $wrapper */ $wrapper = $entity_meta->getWrapper(); - $this->assertEquals($wrapper->getListPageConfiguration(), ['exposed' => ['list']]); + $this->assertEquals($wrapper->getConfiguration(), ['exposed' => ['list']]); } } From 39f0fa0e310a344baecdd71c0f898a63af78dfba Mon Sep 17 00:00:00 2001 From: Sergii Pavlenko Date: Fri, 12 Jun 2020 08:00:20 +0200 Subject: [PATCH 18/19] OPENEUROPA-3272: Enable selenium for drone. --- .drone.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.drone.yml b/.drone.yml index 85b59905..821c8a86 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,6 +11,15 @@ services: image: percona/percona-server:5.6 environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes + selenium: + image: selenium/standalone-chrome:3.141.5 + shm_size: 2g + environment: + - DISPLAY=:99 + - SCREEN_WIDTH=1280 + - SCREEN_HEIGHT=800 + - NODE_MAX_INSTANCES=5 + - NODE_MAX_SESSION=5 pipeline: composer-install: From 6b33863552e0d4f0e1aed8503239c7c5ae723ed3 Mon Sep 17 00:00:00 2001 From: upchuk Date: Fri, 12 Jun 2020 11:24:13 +0200 Subject: [PATCH 19/19] OPENEUROPA-3272: Refactiring test and event subscriber. --- composer.json | 2 +- src/ListPageEvents.php | 8 +- ...Event.php => ListPageSourceAlterEvent.php} | 31 ++-- src/Plugin/EntityMetaRelation/ListPage.php | 21 +-- .../ListPagesPluginTest.php | 148 +++++++++++++----- .../oe_list_pages_test.services.yml | 2 +- .../ListPagesTestSubscriber.php | 63 +++----- 7 files changed, 162 insertions(+), 113 deletions(-) rename src/{ListPageSourceRetrieveEvent.php => ListPageSourceAlterEvent.php} (58%) diff --git a/composer.json b/composer.json index 2eaf4bcf..9e0982bb 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "prefer-stable": true, "require": { "drupal/core": "^8.8", - "openeuropa/entity_meta_relation": "dev-OPENEUROPA-3271", + "openeuropa/entity_meta_relation": "dev-8.x-1.x", "drupal/search_api": "~1.17", "php": ">=7.2" }, diff --git a/src/ListPageEvents.php b/src/ListPageEvents.php index 2034871b..a52599af 100644 --- a/src/ListPageEvents.php +++ b/src/ListPageEvents.php @@ -10,17 +10,17 @@ final class ListPageEvents { /** - * Name of the event fired on retrieving allowed entity types. + * Event fired when altering the entity types. * * @var string */ - const ALTER_ALLOWED_ENTITY_TYPES = 'oe_list_pages.allowed_entity_types_alter'; + const ALTER_ENTITY_TYPES = 'oe_list_pages.entity_types_alter'; /** - * Name of the event fired on retrieving allowed bundles. + * Event fired when altering the bundles. * * @var string */ - const ALTER_ALLOWED_BUNDLES = 'oe_list_pages.allowed_bundles_alter'; + const ALTER_BUNDLES = 'oe_list_pages.bundles_alter'; } diff --git a/src/ListPageSourceRetrieveEvent.php b/src/ListPageSourceAlterEvent.php similarity index 58% rename from src/ListPageSourceRetrieveEvent.php rename to src/ListPageSourceAlterEvent.php index dc3f24bc..a5a88b84 100644 --- a/src/ListPageSourceRetrieveEvent.php +++ b/src/ListPageSourceAlterEvent.php @@ -4,23 +4,22 @@ namespace Drupal\oe_list_pages; -use Drupal\Core\Cache\RefinableCacheableDependencyInterface; -use Drupal\Core\Cache\RefinableCacheableDependencyTrait; use Symfony\Component\EventDispatcher\Event; /** - * Defines a ListPageSourceRetrieveEvent event. + * Event thrown in order to alter the list source. + * + * The entity types and bundles that can be selected for a list source can + * be altered by subscribing to this event. */ -class ListPageSourceRetrieveEvent extends Event implements RefinableCacheableDependencyInterface { - - use RefinableCacheableDependencyTrait; +class ListPageSourceAlterEvent extends Event { /** * The list of entity types. * * @var array */ - protected $entityTypeIds; + protected $entityTypes; /** * The list of bundles. @@ -30,15 +29,15 @@ class ListPageSourceRetrieveEvent extends Event implements RefinableCacheableDep protected $bundles; /** - * Constructs a new ListPageSourceRetrieveEvent. + * Constructs a new ListPageSourceAlterEvent. * - * @param array $entity_type_ids + * @param array $entity_types * The list of entity type ids. * @param array $bundles * The list of entity bundles. */ - public function __construct(array $entity_type_ids, array $bundles = []) { - $this->entityTypeIds = $entity_type_ids; + public function __construct(array $entity_types, array $bundles = []) { + $this->entityTypes = $entity_types; $this->bundles = $bundles; } @@ -49,17 +48,17 @@ public function __construct(array $entity_type_ids, array $bundles = []) { * The list of entity types. */ public function getEntityTypes(): array { - return $this->entityTypeIds; + return $this->entityTypes; } /** * Set the allowed entity types. * - * @param array $entity_type_ids + * @param array $entity_types * The list of entity types. */ - public function setEntityTypes(array $entity_type_ids): void { - $this->entityTypeIds = $entity_type_ids; + public function setEntityTypes(array $entity_types): void { + $this->entityTypes = $entity_types; } /** @@ -81,7 +80,7 @@ public function getBundles(): array { * The bundles. */ public function setBundles(string $entity_type, array $bundles): void { - $this->entityTypeIds = [$entity_type => $entity_type]; + $this->entityTypes = [$entity_type]; $this->bundles = $bundles; } diff --git a/src/Plugin/EntityMetaRelation/ListPage.php b/src/Plugin/EntityMetaRelation/ListPage.php index df5fc714..b04c22c5 100755 --- a/src/Plugin/EntityMetaRelation/ListPage.php +++ b/src/Plugin/EntityMetaRelation/ListPage.php @@ -15,7 +15,7 @@ use Drupal\emr\Entity\EntityMetaInterface; use Drupal\emr\Plugin\EntityMetaRelationContentFormPluginBase; use Drupal\oe_list_pages\ListPageEvents; -use Drupal\oe_list_pages\ListPageSourceRetrieveEvent; +use Drupal\oe_list_pages\ListPageSourceAlterEvent; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -109,16 +109,16 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $entity_type_options = []; $entity_types = $this->entityTypeManager->getDefinitions(); - foreach ($entity_types as $entity_key => $entity_type) { + foreach ($entity_types as $entity_type_key => $entity_type) { if (!$entity_type instanceof ContentEntityTypeInterface) { continue; } - $entity_type_options[$entity_key] = $entity_type->getLabel(); + $entity_type_options[$entity_type_key] = $entity_type->getLabel(); } - $event = new ListPageSourceRetrieveEvent($entity_type_options); - $this->eventDispatcher->dispatch(ListPageEvents::ALTER_ALLOWED_ENTITY_TYPES, $event); - $entity_type_options = $event->getEntityTypes(); + $event = new ListPageSourceAlterEvent(array_keys($entity_type_options)); + $this->eventDispatcher->dispatch(ListPageEvents::ALTER_ENTITY_TYPES, $event); + $entity_type_options = array_intersect_key($entity_type_options, array_combine($event->getEntityTypes(), $event->getEntityTypes())); $entity_type_id = $entity_meta_wrapper->getSourceEntityType(); @@ -127,8 +127,9 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity '#title' => $this->t('Source entity type'), '#description' => $this->t('Select the entity type that will be used as the source for this list page.'), '#options' => $entity_type_options, + // If there is no selection, the default entity type will be Node, due to + // self::fillDefaultEntityMetaValues(). '#default_value' => $form_state->getValue('entity_type') ?? $entity_type_id, - '#empty_option' => $this->t('- Select -'), '#required' => TRUE, '#ajax' => [ 'callback' => [$this, 'updateEntityBundles'], @@ -145,9 +146,9 @@ public function build(array $form, FormStateInterface $form_state, ContentEntity $bundle_options[$bundle_key] = $bundle['label']; } - $event->setBundles($selected_entity_type, $bundle_options); - $this->eventDispatcher->dispatch(ListPageEvents::ALTER_ALLOWED_BUNDLES, $event); - $bundle_options = $event->getBundles(); + $event->setBundles($selected_entity_type, array_keys($bundle_options)); + $this->eventDispatcher->dispatch(ListPageEvents::ALTER_BUNDLES, $event); + $bundle_options = array_intersect_key($bundle_options, array_combine($event->getBundles(), $event->getBundles())); } $entity_bundle_id = $entity_meta_wrapper->getSourceEntityBundle(); diff --git a/tests/FunctionalJavascript/ListPagesPluginTest.php b/tests/FunctionalJavascript/ListPagesPluginTest.php index 2e6f9722..c07ac39f 100755 --- a/tests/FunctionalJavascript/ListPagesPluginTest.php +++ b/tests/FunctionalJavascript/ListPagesPluginTest.php @@ -5,11 +5,12 @@ namespace Drupal\Tests\oe_list_pages\FunctionalJavascript; use Drupal\FunctionalJavascriptTests\WebDriverTestBase; +use Drupal\node\Entity\Node; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait; /** - * Tests the JavaScript functionality of the OpenEuropa List Pages module. + * Tests the List pages EMR plugin form. * * @group oe_list_pages */ @@ -20,17 +21,7 @@ class ListPagesPluginTest extends WebDriverTestBase { /** * {@inheritdoc} */ - protected $strictConfigSchema = FALSE; - - /** - * {@inheritdoc} - */ - protected $defaultTheme = 'stark'; - - /** - * {@inheritdoc} - */ - public static $modules = [ + protected static $modules = [ 'taxonomy', 'node', 'oe_list_pages_test', @@ -43,55 +34,55 @@ protected function setUp() { parent::setUp(); $this->drupalCreateContentType([ - 'type' => 'node_type1', + 'type' => 'node_type_one', 'name' => 'Node Type 1', ]); $this->drupalCreateContentType([ - 'type' => 'node_type2', + 'type' => 'node_type_two', 'name' => 'Node Type 2', ]); $this->drupalCreateContentType([ - 'type' => 'node_type3', + 'type' => 'node_type_three', 'name' => 'Node Type 3', ]); Vocabulary::create([ - 'vid' => 'voc1', + 'vid' => 'vocab_one', 'name' => 'Vocabulary 1', ])->save(); Vocabulary::create([ - 'vid' => 'voc2', + 'vid' => 'vocab_two', 'name' => 'Vocabulary 2', ])->save(); Vocabulary::create([ - 'vid' => 'voc3', + 'vid' => 'vocab_three', 'name' => 'Vocabulary 3', ])->save(); /** @var \Drupal\emr\EntityMetaRelationInstaller $installer */ $installer = \Drupal::service('emr.installer'); $installer->installEntityMetaTypeOnContentEntityType('oe_list_page', 'node', [ - 'node_type1', + 'node_type_one', ]); } /** * Test List Page entity meta plugin and available entity types/bundles. */ - public function testListPagePluginConfigForm(): void { - + public function testListPagePluginForm(): void { $this->drupalLogin($this->rootUser); - $this->drupalGet('node/add/node_type1'); + $this->drupalGet('node/add/node_type_one'); + + // Open the list page details element. $this->clickLink('List Page'); $actual_entity_types = $this->getSelectOptions('Source entity type'); $expected_entity_types = [ - '' => '- Select -', 'entity_meta_relation' => 'Entity Meta Relation', 'entity_meta' => 'Entity meta', 'node' => 'Content', @@ -101,61 +92,132 @@ public function testListPagePluginConfigForm(): void { 'taxonomy_term' => 'Taxonomy term', ]; $this->assertEquals($expected_entity_types, $actual_entity_types); + // By default, Node is selected if there are no stored values. $this->assertOptionSelected('Source entity type', 'Content'); $actual_bundles = $this->getSelectOptions('Source bundle'); $expected_bundles = [ - 'node_type1' => 'Node Type 1', - 'node_type2' => 'Node Type 2', - 'node_type3' => 'Node Type 3', + 'node_type_one' => 'Node Type 1', + 'node_type_two' => 'Node Type 2', + 'node_type_three' => 'Node Type 3', ]; $this->assertEquals($expected_bundles, $actual_bundles); + // Switch to the taxonomy term and assert that we have different bundles. $this->getSession()->getPage()->selectFieldOption('Source entity type', 'taxonomy_term'); $this->assertSession()->assertWaitOnAjaxRequest(); $actual_bundles = $this->getSelectOptions('Source bundle'); $expected_bundles = [ - 'voc1' => 'Vocabulary 1', - 'voc2' => 'Vocabulary 2', - 'voc3' => 'Vocabulary 3', + 'vocab_one' => 'Vocabulary 1', + 'vocab_two' => 'Vocabulary 2', + 'vocab_three' => 'Vocabulary 3', + ]; + $this->assertEquals($expected_bundles, $actual_bundles); + + // Switch to a bundle-less entity type and assert we have only one bundle + // selection available. + $this->getSession()->getPage()->selectFieldOption('Source entity type', 'user'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $actual_bundles = $this->getSelectOptions('Source bundle'); + $expected_bundles = [ + 'user' => 'User', ]; $this->assertEquals($expected_bundles, $actual_bundles); - $config = \Drupal::configFactory()->getEditable('oe_list_pages_test.settings'); - $config->set('allowed_entity_types_bundles', [ + // Set state values to trigger the test event subscriber and make some + // limitations. + $allowed = [ 'node' => [ - 'node_type2' => 'node_type2', - 'node_type3' => 'node_type3', + 'node_type_two', + 'node_type_three', ], 'taxonomy_term' => [ - 'voc1' => 'voc1', - 'voc3' => 'voc3', + 'vocab_one', + 'vocab_three', ], - ]); - $config->save(); - $this->drupalGet('node/add/node_type1'); + ]; + \Drupal::state()->set('oe_list_pages_test.allowed_entity_types_bundles', $allowed); + + $this->drupalGet('node/add/node_type_one'); $this->clickLink('List Page'); $actual_entity_types = $this->getSelectOptions('Source entity type'); $this->assertEquals([ - '' => '- Select -', 'node' => 'Content', 'taxonomy_term' => 'Taxonomy term', ], $actual_entity_types); $this->assertOptionSelected('Source entity type', 'Content'); $actual_bundles = $this->getSelectOptions('Source bundle'); $expected_bundles = [ - 'node_type2' => 'Node Type 2', - 'node_type3' => 'Node Type 3', + 'node_type_two' => 'Node Type 2', + 'node_type_three' => 'Node Type 3', ]; $this->assertEquals($expected_bundles, $actual_bundles); $this->getSession()->getPage()->selectFieldOption('Source entity type', 'taxonomy_term'); $this->assertSession()->assertWaitOnAjaxRequest(); $actual_bundles = $this->getSelectOptions('Source bundle'); $expected_bundles = [ - 'voc1' => 'Vocabulary 1', - 'voc3' => 'Vocabulary 3', + 'vocab_one' => 'Vocabulary 1', + 'vocab_three' => 'Vocabulary 3', ]; $this->assertEquals($expected_bundles, $actual_bundles); + + // Select a bundle and save the node. + $this->getSession()->getPage()->fillField('Title', 'Node title'); + $this->getSession()->getPage()->selectFieldOption('Source bundle', 'vocab_three'); + $this->getSession()->getPage()->pressButton('Save'); + + // Assert the entity meta was correctly saved. + $node = Node::load(1); + $this->assertEquals(1, $node->getRevisionId()); + $this->assertEquals('Node title', $node->label()); + /** @var \Drupal\emr\Field\ComputedEntityMetasItemList $entity_meta_list */ + $entity_meta_list = $node->get('emr_entity_metas'); + $entity_meta = $entity_meta_list->getEntityMeta('oe_list_page'); + $this->assertFalse($entity_meta->isNew()); + + /** @var \Drupal\oe_list_pages\ListPageWrapper $entity_meta_wrapper */ + $entity_meta_wrapper = $entity_meta->getWrapper(); + $this->assertEquals('taxonomy_term:vocab_three', $entity_meta_wrapper->getSource()); + $this->assertEquals('taxonomy_term', $entity_meta_wrapper->getSourceEntityType()); + $this->assertEquals('vocab_three', $entity_meta_wrapper->getSourceEntityBundle()); + + // Edit the node and assert that we show correct values in the form. + $this->drupalGet($node->toUrl('edit-form')); + $this->clickLink('List Page'); + $this->assertOptionSelected('Source entity type', 'Taxonomy term'); + $this->assertOptionSelected('Source bundle', 'Vocabulary 3'); + + // Change the source to a Node type. + $this->getSession()->getPage()->fillField('Title', 'Node title 2'); + $this->getSession()->getPage()->selectFieldOption('Source entity type', 'node'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->getSession()->getPage()->selectFieldOption('Source bundle', 'node_type_two'); + $this->getSession()->getPage()->pressButton('Save'); + + \Drupal::entityTypeManager()->getStorage('node')->resetCache(); + $node = Node::load(1); + $this->assertEquals(2, $node->getRevisionId()); + /** @var \Drupal\emr\Field\ComputedEntityMetasItemList $entity_meta_list */ + $entity_meta_list = $node->get('emr_entity_metas'); + $entity_meta = $entity_meta_list->getEntityMeta('oe_list_page'); + $entity_meta_wrapper = $entity_meta->getWrapper(); + $this->assertEquals('node:node_type_two', $entity_meta_wrapper->getSource()); + $this->assertEquals('node', $entity_meta_wrapper->getSourceEntityType()); + $this->assertEquals('node_type_two', $entity_meta_wrapper->getSourceEntityBundle()); + + // Assert the previous entity meta revision kept the old value. + $first_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(1); + $this->assertEquals(1, $first_revision->getRevisionId()); + /** @var \Drupal\emr\Field\ComputedEntityMetasItemList $entity_meta_list */ + $entity_meta_list = $first_revision->get('emr_entity_metas'); + $entity_meta = $entity_meta_list->getEntityMeta('oe_list_page'); + $this->assertFalse($entity_meta->isNew()); + + /** @var \Drupal\oe_list_pages\ListPageWrapper $entity_meta_wrapper */ + $entity_meta_wrapper = $entity_meta->getWrapper(); + $this->assertEquals('taxonomy_term:vocab_three', $entity_meta_wrapper->getSource()); + $this->assertEquals('taxonomy_term', $entity_meta_wrapper->getSourceEntityType()); + $this->assertEquals('vocab_three', $entity_meta_wrapper->getSourceEntityBundle()); } /** diff --git a/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml b/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml index f05e4639..f6862f0f 100755 --- a/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml +++ b/tests/modules/oe_list_pages_test/oe_list_pages_test.services.yml @@ -1,6 +1,6 @@ services: oe_list_pages_test.event_subscriber: class: Drupal\oe_list_pages_test\EventSubscriber\ListPagesTestSubscriber - arguments: ['@config.factory'] + arguments: ['@state'] tags: - { name: event_subscriber } diff --git a/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php b/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php index a3fa4953..f6392fd0 100755 --- a/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php +++ b/tests/modules/oe_list_pages_test/src/EventSubscriber/ListPagesTestSubscriber.php @@ -4,9 +4,9 @@ namespace Drupal\oe_list_pages_test\EventSubscriber; -use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\State\StateInterface; use Drupal\oe_list_pages\ListPageEvents; -use Drupal\oe_list_pages\ListPageSourceRetrieveEvent; +use Drupal\oe_list_pages\ListPageSourceAlterEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -15,20 +15,20 @@ class ListPagesTestSubscriber implements EventSubscriberInterface { /** - * The config. + * The state. * - * @var \Drupal\Core\Config\Config + * @var \Drupal\Core\State\StateInterface */ - private $config; + protected $state; /** * Constructs event subscriber. * - * @param \Drupal\Core\Config\ConfigFactory $config_factory - * The Config Factory. + * @param \Drupal\Core\State\StateInterface $state + * The state. */ - public function __construct(ConfigFactory $config_factory) { - $this->config = $config_factory->get('oe_list_pages_test.settings'); + public function __construct(StateInterface $state) { + $this->state = $state; } /** @@ -36,60 +36,47 @@ public function __construct(ConfigFactory $config_factory) { */ public static function getSubscribedEvents() { return [ - ListPageEvents::ALTER_ALLOWED_ENTITY_TYPES => ['onEntityTypesRetrieving'], - ListPageEvents::ALTER_ALLOWED_BUNDLES => ['onBundlesRetrieving'], + ListPageEvents::ALTER_ENTITY_TYPES => ['onEntityTypesAlter'], + ListPageEvents::ALTER_BUNDLES => ['onBundlesAlter'], ]; } /** - * Event handler for limiting allowed entity types. + * Event handler for limiting the allowed entity types. * - * @param \Drupal\oe_list_pages\ListPageSourceRetrieveEvent $event + * @param \Drupal\oe_list_pages\ListPageSourceAlterEvent $event * The event object. */ - public function onEntityTypesRetrieving(ListPageSourceRetrieveEvent $event): void { - $event->addCacheableDependency($this->config); + public function onEntityTypesAlter(ListPageSourceAlterEvent $event): void { $entity_types = $event->getEntityTypes(); - $allowed_entity_bundles = $this->config->get('allowed_entity_types_bundles'); - if ($allowed_entity_bundles === NULL) { + $allowed = $this->state->get('oe_list_pages_test.allowed_entity_types_bundles'); + if ($allowed === NULL) { return; } - $allowed_entity_bundles = array_keys($allowed_entity_bundles); - foreach (array_keys($entity_types) as $entity_type) { - if (!in_array($entity_type, $allowed_entity_bundles)) { - unset($entity_types[$entity_type]); - } - } - $event->setEntityTypes($entity_types); + $allowed_entity_types = array_keys($allowed); + $event->setEntityTypes(array_intersect($entity_types, $allowed_entity_types)); } /** - * Event handler for limiting allowed bundles. + * Event handler for limiting the allowed bundles. * - * @param \Drupal\oe_list_pages\ListPageSourceRetrieveEvent $event + * @param \Drupal\oe_list_pages\ListPageSourceAlterEvent $event * The event object. */ - public function onBundlesRetrieving(ListPageSourceRetrieveEvent $event): void { - $event->addCacheableDependency($this->config); + public function onBundlesAlter(ListPageSourceAlterEvent $event): void { $entity_types = $event->getEntityTypes(); $entity_type = reset($entity_types); $bundles = $event->getBundles(); - $allowed_entity_bundles = $this->config->get('allowed_entity_types_bundles'); - if ($allowed_entity_bundles === NULL) { + $allowed = $this->state->get('oe_list_pages_test.allowed_entity_types_bundles'); + if ($allowed === NULL) { return; } - $allowed_bundles = $allowed_entity_bundles[$entity_type] ? array_keys($allowed_entity_bundles[$entity_type]) : NULL; - - foreach (array_keys($bundles) as $bundle) { - if (!in_array($bundle, $allowed_bundles)) { - unset($bundles[$bundle]); - } - } + $allowed_bundles = $allowed[$entity_type] ?? []; - $event->setBundles($entity_type, $bundles); + $event->setBundles($entity_type, array_intersect($bundles, $allowed_bundles)); } }