- Issue created by @lexsoft
- @lexsoft opened merge request.
- Status changed to Needs review
almost 2 years ago 4:15pm 14 March 2023 - Status changed to Active
almost 2 years ago 12:12pm 15 March 2023 - 🇩🇪Germany jurgenhaas Gottmadingen
This looks great, thanks a lot @lexsoft for your contribution.
Just 2 things I'd like to ask for:
- The token replacement looks a bit too complicated. In other places we simply have e.g.
$name = $this->tokenServices->replace($this->configuration['field_name']);
which seems perfectly sufficient. Any reason we could do it that way in this case too? - Would you mind providing a simple test to verify that this also works with and without a token?
- The token replacement looks a bit too complicated. In other places we simply have e.g.
- 🇬🇧United Kingdom lexsoft London
Hi @jurgenhaas,
1. This should also work
$name = $this->tokenServices->replace($this->configuration['field_name'])
. I've just took a copy from the work was done on same module.2. Will provide a simple example with and without token.
- 🇩🇪Germany mxh Offenburg
Will provide a simple example with and without token.
Ideally this may be covered with a Kernel test. There is already
Drupal\Tests\eca_content\Kernel\LoadEntityRefTest
, which could be extended by your suggested example. - 🇬🇧United Kingdom lexsoft London
Please find attached a simple example of usage using load via ref with tokens and without.
Modules used:"drupal/eca": "^1.1", "drupal/bpmn_io": "^1.1", "drupal/token": "^1.11"
- 🇬🇧United Kingdom lexsoft London
@mxh I have tried to extend the test
Drupal\Tests\eca_content\Kernel\LoadEntityRefTest
but I'm running into:Testing Drupal\Tests\eca_content\Kernel\LoadEntityRefTest E 1 / 1 (100%) Time: 00:01.036, Memory: 4.00 MB There was 1 error: 1) Drupal\Tests\eca_content\Kernel\LoadEntityRefTest::testLoadEntityRef InvalidArgumentException: Field [node:field_node_ref_mn] does not exist for entity type node/article. /var/www/html/web/modules/contrib/eca/modules/content/src/Plugin/Action/LoadEntityRef.php:61 /var/www/html/web/modules/contrib/eca/modules/content/src/Plugin/Action/LoadEntity.php:76 /var/www/html/web/modules/contrib/eca/modules/content/tests/src/Kernel/LoadEntityRefTest.php:220 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php:728 ERRORS! Tests: 1, Assertions: 12, Errors: 1.
Not sure what I've done wrong but here is my try:
public function testLoadEntityRef() { // Create the Article content type with revisioning and translation enabled. /** @var \Drupal\node\NodeTypeInterface $node_type */ $node_type = NodeType::create([ 'type' => 'article', 'name' => 'Article', 'new_revision' => TRUE, ]); $node_type->save(); ContentLanguageSettings::create([ 'id' => 'node.article', 'target_entity_type_id' => 'node', 'target_bundle' => 'article', 'default_langcode' => LanguageInterface::LANGCODE_DEFAULT, 'language_alterable' => TRUE, ])->save(); // Create a reference field. $field_definition = FieldStorageConfig::create([ 'field_name' => 'field_node_ref', 'type' => 'entity_reference', 'entity_type' => 'node', 'settings' => [ 'target_type' => 'node', ], 'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED, ]); $field_definition->save(); $field = FieldConfig::create([ 'field_storage' => $field_definition, 'label' => 'A node reference.', 'entity_type' => 'node', 'bundle' => 'article', ]); $field->save(); // Create a plaintext field to be used as token. FieldStorageConfig::create([ 'field_name' => 'field_node_ref_mn', 'type' => 'string', 'entity_type' => 'node', 'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED, ])->save(); FieldConfig::create([ 'field_name' => 'field_node_ref_mn', 'label' => 'The reference field machine name.', 'entity_type' => 'node', 'bundle' => 'article', ])->save(); // Create a reference field target for token. FieldStorageConfig::create([ 'field_name' => 'field_node_ref_target_token', 'type' => 'entity_reference', 'entity_type' => 'node', 'settings' => [ 'target_type' => 'node', ], 'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED, ])->save(); FieldConfig::create([ 'field_name' => 'field_node_ref_target_token', 'label' => 'A node reference target token.', 'entity_type' => 'node', 'bundle' => 'article', ])->save(); /** @var \Drupal\Core\Action\ActionManager $action_manager */ $action_manager = \Drupal::service('plugin.manager.action'); /** @var \Drupal\eca\Token\TokenInterface $token_services */ $token_services = \Drupal::service('eca.token_services'); /** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */ $account_switcher = \Drupal::service('account_switcher'); $referenced = Node::create([ 'type' => 'article', 'title' => 'I am a referenced node.', 'langcode' => 'en', 'uid' => 1, 'status' => 0, ]); $referenced->save(); $referenced_by_token = Node::create([ 'type' => 'article', 'title' => 'I am a referenced node using tokens.', 'langcode' => 'en', 'uid' => 1, 'status' => 0, ]); $referenced_by_token->save(); $node = Node::create([ 'type' => 'article', 'title' => '123', 'langcode' => 'en', 'uid' => 1, 'status' => 0, ]); $node->save(); $first_vid = $node->getRevisionId(); $node->title = '456'; $node->field_node_ref->target_id = $referenced->id(); $node->field_node_ref_target_token->target_id = $referenced_by_token->id(); $node->field_node_ref_mn->value = 'field_node_ref_target_token'; $node->setNewRevision(TRUE); $node->save(); // Create an action that that loads the referenced entity. /** @var \Drupal\eca_content\Plugin\Action\SetFieldValue $action */ $defaults = [ 'token_name' => 'mynode', 'from' => 'current', 'entity_type' => '_none', 'entity_id' => '', 'revision_id' => '', 'properties' => '', 'langcode' => '_interface', 'latest_revision' => FALSE, 'unchanged' => FALSE, 'field_name_entity_ref' => 'field_node_ref', ]; /** @var \Drupal\eca_content\Plugin\Action\LoadEntity $action */ $action = $action_manager->createInstance('eca_token_load_entity_ref', [] + $defaults); $this->assertFalse($action->access($node), 'User without permissions must not have access.'); // Now switch to priviledged user. $account_switcher->switchTo(User::load(1)); /** @var \Drupal\eca_content\Plugin\Action\LoadEntity $action */ $action = $action_manager->createInstance('eca_token_load_entity_ref', [] + $defaults); $this->assertTrue($action->access($node), 'User with permissions must have access.'); $this->assertFalse($token_services->hasTokenData('mynode'), 'Token must not yet be defined.'); $action->execute($node); $this->assertTrue($token_services->hasTokenData('mynode'), 'Token must be defined.'); $this->assertSame($referenced->id(), $token_services->getTokenData('mynode')->id()); $token_services->addTokenData('node', $node); /** @var \Drupal\eca_content\Plugin\Action\LoadEntity $action */ $action = $action_manager->createInstance('eca_token_load_entity_ref', [ 'field_name_entity_ref' => '[node:field_node_ref_mn]', ] + $defaults); $action->execute($node); $this->assertTrue($token_services->hasTokenData('mynode'), 'Token must be defined.'); $this->assertSame($referenced_by_token->id(), $token_services->getTokenData('mynode')->id());
- 🇩🇪Germany mxh Offenburg
@lexsoft That's a very nice test implementation! The token "[node:field_node_ref_mn]" won't get replaced in this test, because the contrib Token module is not installed. Node tokens will only be replaced when contrib Token module is installed. The property
protected static $modules
in the kernel test could be extended by thetoken
module.Alternatively without using contrib Token module, you could just add a token yourself by using
$token_services->addTokenData('ref_field_name', 'field_node_ref')
and then use that token[ref_field_name]
in the action to test.If you get stuck again, just let us know here. We're happy to help get this going.
- 🇬🇧United Kingdom lexsoft London
@mxh Brilliant! Thanks a lot, it works now.
- Status changed to Needs review
almost 2 years ago 2:07pm 17 March 2023 - Status changed to RTBC
almost 2 years ago 4:22pm 17 March 2023 - 🇩🇪Germany mxh Offenburg
The MR is looking good. This needs to be merged into 1.2.x first, then we may consider backporting this into 1.1.x and 1.0.x (The MR is currently set to be merged into 1.1.x). Backport should be fine IMO. Although it's a new feature rather than a bug fix, this change should not break existing configurations as token syntax wouldn't work on that configuration field until now.
- 🇩🇪Germany jurgenhaas Gottmadingen
Amazing work, thank you so much.
While re-basing this to 1.2.x I realized that we had a test in the 1.1.x branch which was missing in 1.2.x - no idea how that came about. That formerly missing test is now also part of this MR after the rebase, it came from
Issue #3344752 by boromino, mxh, jurgenhaas: Config read without overridden always empty
Another quick question, that confuses me a bit: as we now added
token
to the list of modules, how is that even possible for a contrib module which is not a dependency? - 🇩🇪Germany mxh Offenburg
Another quick question, that confuses me a bit: as we now added token to the list of modules, how is that even possible for a contrib module which is not a dependency?
I guess Drupal's test infrastructure automatically installs required dev packages that are defined in composer.json. We're also already using contrib token in one other kernel test.
-
jurgenhaas →
committed af10be1e on 1.2.x authored by
lexsoft →
Issue #3347915 by lexsoft, jurgenhaas: eca_content - "Entity: load via...
-
jurgenhaas →
committed af10be1e on 1.2.x authored by
lexsoft →
- Status changed to Fixed
almost 2 years ago 9:15am 20 March 2023 - 🇩🇪Germany jurgenhaas Gottmadingen
Ah, it's in require-dev and that certainly gets loaded for tests.
Automatically closed - issue fixed for 2 weeks with no activity.