Skip to content

Commit

Permalink
Merge pull request #162 from Metadrop/feature/entity-replacement-mult…
Browse files Browse the repository at this point in the history
…iple

Allow adding multiple entity-replacements tokens in a single value
  • Loading branch information
omarlopesino authored Nov 7, 2023
2 parents cb2c6d9 + 254b7c2 commit 3e937ea
Showing 1 changed file with 76 additions and 21 deletions.
97 changes: 76 additions & 21 deletions src/Behat/Context/EntityContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,44 +317,99 @@ protected function checkEntityValues($entity, $fields) {
return $errors;
}

/**
* Make replacement on given string when this one contains entity-replacement.
*
* [entity-replacement:{entity_type}:{field_name}:{field_value}:{destiny_replacement_field_name}]
*
* entity_type -> the entity type on which to search.
* field_name -> the entity field to search on.
* field_value -> the value of the field that the entity should have.
* destiny_replacement_field_name -> The name of the field on which to take the value to be used as a replacement.
*
* Examples:
* - [entity-replacement:user:mail:behat@metadrop.net:uid]
* Output: 123
* - [entity-replacement:user:mail:behat@metadrop.net:uid], [entity-replacement:user:mail:behat_2@metadrop.net:uid], [entity-replacement:user:mail:behat_3@metadrop.net:uid]
* Output: 123, 124, 125
* - [entity-replacement:user:mail:behat@metadrop.net:uid] - [entity-replacement:user:mail:behat_2@metadrop.net:uid] - [entity-replacement:user:mail:behat_3@metadrop.net:uid]
* Output: 123 - 124 - 125
* - entity-replacement:user:mail:behat@metadrop.net:uid (This way can only be use for single replacement)
* Output: 123
*
* Every token will be replaced, and the text between them will
* remain the same.
*
* @param string $value
* String that contains a single or multiple entity-replacement tokens.
*
* @return string|bool
* Replaced or untouched string or FALSE otherwise.
*
* @throws \Exception
*/
protected function entityTokensReplacements($value) {
$entity_tokens = [];
$replacements = [];
if (strpos($value, 'entity-replacement') === 0) {
$entity_tokens = (array) $value;
}
else {
$matches = [];
preg_match_all('#\[entity-replacement:?([^]]*)\]#', $value, $matches);
$entity_tokens = reset($matches);
}

if (empty($entity_tokens)) {
return FALSE;
}

// Get entity type list.
$entity_types = $this->getCore()->getEntityTypes();

foreach ($entity_tokens as $entity_token) {
$token_pieces = explode(':', str_replace(['[', ']'], ['', ''], $entity_token));
array_shift($token_pieces);
if (count($token_pieces) < 4) {
throw new \Exception(sprintf('Missing arguments to find the entity token with name: %s', $entity_token));
}

list($entity_type, $field_key, $field_value, $destiny_replacement) = $token_pieces;

if (!in_array($entity_type, $entity_types)) {
throw new \Exception(sprintf('The "%s" token or its entity values are not valid!', $entity_token));
}

$entity = $this->getCore()->getEntityByField($entity_type, $field_key, $field_value);
$replacements[] = !empty($entity) ? $this->getCore()->getEntityFieldValue($destiny_replacement, $entity, $entity_token) : $entity_token;
}

return str_replace($entity_tokens, $replacements, $value);
}

/**
* Replacement tokens.
*
* @param array|mixed $values
* Fields to replace.
*/
protected function replaceTokens($values) {
// Get entity type list.
$entity_types = $this->getCore()->getEntityTypes();
foreach ($values as $key => $value) {
if (strpos($value, 'entity-replacement') === 0) {
$token_pieces = explode(':', $value);
array_shift($token_pieces);
$entity_type = $token_pieces[0];
$field_key = $token_pieces[1];
$field_value = $token_pieces[2];
$destiny_replacement = $token_pieces[3];

$keys_exists = isset($entity_type) && isset($field_key) && isset($field_value) && isset($destiny_replacement);

if (!$keys_exists || !in_array($entity_type, $entity_types)) {
throw new \Exception('Token or entity values are not valid!');
}
$entity = $this->getCore()->getEntityByField($entity_type, $field_key, $field_value);

if (!empty($entity)) {
$values[$key] = $this->getCore()->getEntityFieldValue($destiny_replacement, $entity, $values[$key]);
}
$entity_types = $this->getCore()->getEntityTypes();
foreach ($values as $key => &$value) {
if (($replacement = $this->entityTokensReplacements($value)) !== FALSE) {
$value = $replacement;
}
elseif (strtok($value, ':') == 'relative-date' && ($relative_date = strtok(':')) !== FALSE) {
$timestamp = strtotime($relative_date);
// Get the rest of the string, not only string separated by ":",
// This way we make sure if the format is something like "Y:m:d"
// it won't be cut by ":".
$format = strtok('');
$values[$key] = $format === FALSE ? $timestamp : \date($format, $timestamp);
$value = $format === FALSE ? $timestamp : \date($format, $timestamp);
}
}

return $values;
}

Expand Down

0 comments on commit 3e937ea

Please sign in to comment.