Skip to content

Commit d774afc

Browse files
Alix MauroVincentChalnot
authored andcommitted
Add GroupByAggregateIterableTask.
1 parent 9f37cef commit d774afc

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed
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+
}

0 commit comments

Comments
 (0)