Skip to content

Commit

Permalink
Merge pull request #10 from php-etl/feature/replace-expression
Browse files Browse the repository at this point in the history
add a "mapValues" expression that will do a preg_match
  • Loading branch information
gplanchat committed Jun 8, 2023
2 parents 6684d2e + 9d38c41 commit 71f0566
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ List of available functions
* `reduce(callable $callback, iterable $source) : string`
* `list(int $length, mixed $value) : iterable`
* `arrayFilter(array $array, ?callable $callback = null) : array`
* `mapValues(array $input, iterable $values) : array`

#### Functions that can be used with `reduce`

Expand Down
1 change: 1 addition & 0 deletions src/ArrayExpressionLanguageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function getFunctions(): array
new ExtractData('extractData'),
new List_('list'),
new FilterList('filterList'),
new MapValues('mapValues'),
];
}
}
87 changes: 87 additions & 0 deletions src/MapValues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace Kiboko\Component\ArrayExpressionLanguage;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;

class MapValues extends ExpressionFunction
{
public function __construct($name)
{
parent::__construct(
$name,
$this->compile(...)->bindTo($this),
$this->evaluate(...)->bindTo($this)
);
}

private function compile(string $input, string $values): string
{
return <<<PHP
(function () use(\$input) {
\$inputs = {$input};
\$patterns = [];
\$replacements = [];
foreach ({$values} as \$pattern => \$replacement) {
\$patterns[] = '('.\$pattern.')';
\$replacements[] = \$replacement;
}
\$pattern = '/^' . implode('|', \$patterns) . '$/';
if (is_iterable(\$inputs)) {
foreach (\$inputs as \$key => \$input) {
preg_match(\$pattern, (string) \$input, \$matches);
if (empty(\$matches)) {
throw new \Exception(sprintf(
'No replacement found for value "%s". Expected values: %s',
\$input,
implode(', ', array_keys(\$replacements))
));
}
array_shift(\$matches);
\$inputs[\$key] = \$replacements[array_keys(array_filter(\$matches))[0]];
}
}
return \$inputs;
})()
PHP;
}

private function evaluate(array $context, array $input, array $values)
{
$inputs = $input;
$patterns = [];
$replacements = [];
foreach ($values as $pattern => $replacement) {
$patterns[] = '('.$pattern.')';
$replacements[] = $replacement;
}

$pattern = '/^' . implode('|', $patterns) . '$/';

if (is_iterable($inputs)) {
foreach ($inputs as $key => $input) {
preg_match($pattern, (string) $input, $matches);

if (empty($matches)) {
throw new \Exception(sprintf(
'No replacement found for value "%s". Expected values: %s',
$input,
implode(', ', array_keys($replacements))
));
}

array_shift($matches);
$inputs[$key] = $replacements[array_keys(array_filter($matches))[0]];
}
}

return $inputs;
}
}

0 comments on commit 71f0566

Please sign in to comment.