diff --git a/src/Behat/Context/EntityContext.php b/src/Behat/Context/EntityContext.php index cf4a2a4..9a13719 100644 --- a/src/Behat/Context/EntityContext.php +++ b/src/Behat/Context/EntityContext.php @@ -317,6 +317,76 @@ 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. * @@ -324,27 +394,11 @@ protected function checkEntityValues($entity, $fields) { * 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); @@ -352,9 +406,10 @@ protected function replaceTokens($values) { // 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; }