Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

Commit 80a35cd

Browse files
committed
Allow to merge an array of stages into a pipeline
1 parent fe8f353 commit 80a35cd

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

src/Builder/Pipeline.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,29 @@
88
use IteratorAggregate;
99
use MongoDB\Builder\Type\StageInterface;
1010
use MongoDB\Exception\InvalidArgumentException;
11-
use Traversable;
1211

1312
use function array_is_list;
1413
use function array_merge;
14+
use function is_array;
1515

1616
/**
1717
* An aggregation pipeline consists of one or more stages that process documents.
1818
*
1919
* @see https://www.mongodb.com/docs/manual/core/aggregation-pipeline/
2020
*
2121
* @psalm-immutable
22-
* @implements IteratorAggregate<StageInterface>
22+
* @implements IteratorAggregate<StageInterface|array<string,mixed>|object>
2323
*/
24-
class Pipeline implements IteratorAggregate
24+
final class Pipeline implements IteratorAggregate
2525
{
26-
/** @var StageInterface[] */
2726
private readonly array $stages;
2827

29-
/** @no-named-arguments */
30-
public function __construct(StageInterface|Pipeline ...$stagesOrPipelines)
28+
/**
29+
* @param StageInterface|Pipeline|list<StageInterface> ...$stagesOrPipelines
30+
*
31+
* @no-named-arguments
32+
*/
33+
public function __construct(StageInterface|Pipeline|array ...$stagesOrPipelines)
3134
{
3235
if (! array_is_list($stagesOrPipelines)) {
3336
throw new InvalidArgumentException('Named arguments are not supported for pipelines');
@@ -36,7 +39,9 @@ public function __construct(StageInterface|Pipeline ...$stagesOrPipelines)
3639
$stages = [];
3740

3841
foreach ($stagesOrPipelines as $stageOrPipeline) {
39-
if ($stageOrPipeline instanceof Pipeline) {
42+
if (is_array($stageOrPipeline) && array_is_list($stageOrPipeline)) {
43+
$stages = array_merge($stages, $stageOrPipeline);
44+
} elseif ($stageOrPipeline instanceof Pipeline) {
4045
$stages = array_merge($stages, $stageOrPipeline->stages);
4146
} else {
4247
$stages[] = $stageOrPipeline;
@@ -46,8 +51,7 @@ public function __construct(StageInterface|Pipeline ...$stagesOrPipelines)
4651
$this->stages = $stages;
4752
}
4853

49-
/** @return Traversable<StageInterface> */
50-
public function getIterator(): Traversable
54+
public function getIterator(): ArrayIterator
5155
{
5256
return new ArrayIterator($this->stages);
5357
}

tests/Builder/PipelineTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ public function testMergingPipeline(): void
2626
{
2727
$stages = array_map(
2828
fn (int $i) => $this->createMock(StageInterface::class),
29-
range(0, 5),
29+
range(0, 7),
3030
);
3131

3232
$pipeline = new Pipeline(
3333
$stages[0],
3434
$stages[1],
3535
new Pipeline($stages[2], $stages[3]),
36-
$stages[4],
37-
new Pipeline($stages[5]),
36+
[$stages[4], $stages[5]],
37+
new Pipeline($stages[6]),
38+
[$stages[7]],
3839
);
3940

4041
$this->assertSame($stages, iterator_to_array($pipeline));

0 commit comments

Comments
 (0)