Skip to content

Commit 64b8ac1

Browse files
author
Valentin Clavreul
committed
Merge remote-tracking branch 'origin/v3.0-dev' into v3.1-dev
2 parents 5b784c3 + 746f8bf commit 64b8ac1

File tree

6 files changed

+286
-11
lines changed

6 files changed

+286
-11
lines changed
Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
services:
2-
CleverAge\ProcessBundle\Transformer\:
3-
resource: '../../../Transformer/*'
4-
exclude: '../../../Transformer/GenericTransformer.php'
2+
_defaults:
53
autowire: true
64
public: false
7-
tags:
8-
- { name: cleverage.transformer }
9-
- { name: monolog.logger, channel: cleverage_process_transformer }
10-
11-
CleverAge\ProcessBundle\Transformer\RulesTransformer:
12-
arguments:
13-
$transformerRegistry: '@CleverAge\ProcessBundle\Registry\TransformerRegistry'
5+
bind:
146
$language: '@cleverage_process.expression_language'
7+
8+
CleverAge\ProcessBundle\Transformer\:
9+
resource: '../../../Transformer/*'
10+
exclude: '../../../Transformer/GenericTransformer.php'
1511
tags:
1612
- { name: cleverage.transformer }
1713
- { name: monolog.logger, channel: cleverage_process_transformer }
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace CleverAge\ProcessBundle\Task;
4+
5+
use CleverAge\ProcessBundle\Model\AbstractConfigurableTask;
6+
use CleverAge\ProcessBundle\Model\BlockingTaskInterface;
7+
use CleverAge\ProcessBundle\Model\ProcessState;
8+
use Symfony\Component\OptionsResolver\OptionsResolver;
9+
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
10+
11+
/**
12+
* Attempt to aggregate inputs in an associative array with a key formed by configurable fields of the input.
13+
* This task could be used to remove duplicates from the aggregate.
14+
*
15+
* @author Alix Mauro <[email protected]>
16+
*/
17+
class GroupByAggregateIterableTask extends AbstractConfigurableTask implements BlockingTaskInterface
18+
{
19+
/** @var string */
20+
const GROUP_BY_OPTION = 'group_by_accessors';
21+
22+
/** @var array */
23+
protected $result;
24+
25+
/** @var PropertyAccessorInterface */
26+
protected $accessor;
27+
28+
/**
29+
* @param PropertyAccessorInterface $accessor
30+
*/
31+
public function __construct(PropertyAccessorInterface $accessor)
32+
{
33+
$this->result = [];
34+
$this->accessor = $accessor;
35+
}
36+
37+
/**
38+
* {@inheritDoc}
39+
*/
40+
public function execute(ProcessState $state): void
41+
{
42+
$options = $this->getOptions($state);
43+
$input = $state->getInput();
44+
$groupByAccessors = $options[self::GROUP_BY_OPTION];
45+
46+
$keyParts = [];
47+
foreach ($groupByAccessors as $groupByAccessor) {
48+
try {
49+
$keyParts[] = $this->accessor->getValue($input, $groupByAccessor);
50+
} catch (\Exception $e) {
51+
$state->addErrorContextValue('property', $groupByAccessor);
52+
$state->setException($e);
53+
54+
return;
55+
}
56+
}
57+
58+
$key = implode('-', $keyParts);
59+
$this->result[$key] = $input;
60+
}
61+
62+
/**
63+
* {@inheritDoc}
64+
*/
65+
public function proceed(ProcessState $state): void
66+
{
67+
if (0 === \count($this->result)) {
68+
$state->setSkipped(true);
69+
} else {
70+
$state->setOutput($this->result);
71+
}
72+
}
73+
74+
/**
75+
* {@inheritDoc}
76+
*/
77+
protected function configureOptions(OptionsResolver $resolver): void
78+
{
79+
$resolver->setRequired(
80+
[
81+
self::GROUP_BY_OPTION,
82+
]
83+
);
84+
$resolver->setAllowedTypes(self::GROUP_BY_OPTION, ['array']);
85+
}
86+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of the CleverAge/ProcessBundle package.
4+
*
5+
* Copyright (C) 2017-2019 Clever-Age
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace CleverAge\ProcessBundle\Transformer;
12+
13+
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;
14+
use Symfony\Component\OptionsResolver\OptionsResolver;
15+
16+
/**
17+
* Return always the same value configured in options, redundant when used inside mapping except in certain useful
18+
* circumstances
19+
*
20+
* @author Vincent Chalnot <[email protected]>
21+
*/
22+
class ConstantTransformer implements ConfigurableTransformerInterface
23+
{
24+
/**
25+
* @param OptionsResolver $resolver
26+
*
27+
* @throws ExceptionInterface
28+
*/
29+
public function configureOptions(OptionsResolver $resolver): void
30+
{
31+
$resolver->setRequired(
32+
[
33+
'constant',
34+
]
35+
);
36+
}
37+
38+
/**
39+
* Must return the transformed $value
40+
*
41+
* @param mixed $value
42+
* @param array $options
43+
*
44+
* @return mixed $value
45+
*/
46+
public function transform($value, array $options = [])
47+
{
48+
return $options['constant'] ?? null;
49+
}
50+
51+
/**
52+
* Returns the unique code to identify the transformer
53+
*
54+
* @return string
55+
*/
56+
public function getCode(): string
57+
{
58+
return 'constant';
59+
}
60+
}

Transformer/ConvertValueTransformer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public function transform($value, array $options = [])
4444
"Value of type {$type} is not a valid array index, set auto_cast to true to cast it to a string"
4545
);
4646
}
47+
if (is_array($value)) { // Array to string conversion is a simple notice so we need to catch it here
48+
throw new \UnexpectedValueException(
49+
"Unexpected input of type 'array' in convert_value transformer"
50+
);
51+
}
4752
$value = (string) $value; // Let's cast it to string
4853
}
4954

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of the CleverAge/ProcessBundle package.
4+
*
5+
* Copyright (C) 2017-2019 Clever-Age
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace CleverAge\ProcessBundle\Transformer;
12+
13+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
14+
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;
15+
use Symfony\Component\OptionsResolver\Options;
16+
use Symfony\Component\OptionsResolver\OptionsResolver;
17+
18+
/**
19+
* Parse an input using the Expression Language and returning a specific value upon a specific condition
20+
*
21+
* @author Vincent Chalnot <[email protected]>
22+
*/
23+
class ExpressionLanguageMapTransformer implements ConfigurableTransformerInterface
24+
{
25+
/** @var ExpressionLanguage */
26+
protected $language;
27+
28+
/**
29+
* @param ExpressionLanguage $language
30+
*/
31+
public function __construct(ExpressionLanguage $language)
32+
{
33+
$this->language = $language;
34+
}
35+
36+
/**
37+
* @param OptionsResolver $resolver
38+
*
39+
* @throws ExceptionInterface
40+
*/
41+
public function configureOptions(OptionsResolver $resolver): void
42+
{
43+
$resolver->setRequired(
44+
[
45+
'map',
46+
]
47+
);
48+
$resolver->setAllowedTypes('map', ['array']);
49+
$resolver->setDefaults(
50+
[
51+
'ignore_missing' => false,
52+
'keep_missing' => false,
53+
]
54+
);
55+
$resolver->setAllowedTypes('ignore_missing', ['boolean']);
56+
$resolver->setAllowedTypes('keep_missing', ['boolean']);
57+
$resolver->setNormalizer(
58+
'map',
59+
function (Options $options, $values) {
60+
if (!is_array($values)) {
61+
throw new \UnexpectedValueException('The map must be an array');
62+
}
63+
$resolver = new OptionsResolver();
64+
$resolver->setRequired(
65+
[
66+
'condition',
67+
'output',
68+
]
69+
);
70+
$resolver->setNormalizer(
71+
'condition',
72+
function (Options $options, $value) {
73+
return $this->language->parse($value, ['data']);
74+
}
75+
);
76+
$resolver->setNormalizer(
77+
'output',
78+
function (Options $options, $value) {
79+
return $this->language->parse($value, ['data']);
80+
}
81+
);
82+
$parsedValues = [];
83+
foreach ($values as $value) {
84+
$parsedValues[] = $resolver->resolve($value);
85+
}
86+
87+
return $parsedValues;
88+
}
89+
);
90+
}
91+
92+
/**
93+
* Must return the transformed $value
94+
*
95+
* @param mixed $value
96+
* @param array $options
97+
*
98+
* @return mixed $value
99+
*/
100+
public function transform($value, array $options = [])
101+
{
102+
$input = ['data' => $value];
103+
foreach ($options['map'] as $mapItem) {
104+
if ($this->language->evaluate($mapItem['condition'], $input)) {
105+
return $this->language->evaluate($mapItem['output'], $input);
106+
}
107+
}
108+
109+
if ($options['keep_missing']) {
110+
return $value;
111+
}
112+
if (!$options['ignore_missing']) {
113+
throw new \UnexpectedValueException("No expression accepting value '{$value}' in map");
114+
}
115+
116+
return null;
117+
}
118+
119+
/**
120+
* Returns the unique code to identify the transformer
121+
*
122+
* @return string
123+
*/
124+
public function getCode(): string
125+
{
126+
return 'expression_language_map';
127+
}
128+
}

Transformer/WrapperTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function configureOptions(OptionsResolver $resolver)
4646
'wrapper_key',
4747
]
4848
);
49-
$resolver->setAllowedTypes('wrapper_key', ['string']);
49+
$resolver->setAllowedTypes('wrapper_key', ['string', 'int']);
5050
}
5151

5252
/**

0 commit comments

Comments
 (0)