Completed
Push — master-3 ( 911075...e0a0a2 )
by Krzysztof
11:33
created

ChainSearch::validateCells()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 4
nop 1
crap 5
1
<?php
2
3
namespace KGzocha\Searcher\Chain;
4
5
use KGzocha\Searcher\Criteria\Collection\CriteriaCollectionInterface;
6
use KGzocha\Searcher\Result\ResultCollection;
7
use KGzocha\Searcher\SearcherInterface;
8
9
/**
10
 * This class represents whole chain of searchers, but it behaves like regular searcher.
11
 * It will perform all (not skipped) sub-searches, transform theirs results into CriteriaCollection
12
 * and pass those criteria to next sub-search.
13
 * At the end it will return collection of all the results from all the steps.
14
 *
15
 * @author Krzysztof Gzocha <[email protected]>
16
 */
17
class ChainSearch implements SearcherInterface
18
{
19
    const MINIMUM_CELLS = 2;
20
21
    /**
22
     * @var CellInterface[]
23
     */
24
    private $cells;
25
26
    /**
27
     * @param CellInterface[] $cells
28
     */
29 9
    public function __construct(array $cells)
30
    {
31 9
        $this->validateCells($cells);
32 6
        $this->cells = $cells;
33 6
    }
34
35
    /**
36
     * Will perform multiple sub-searches.
37
     * Results from first search will be transformed and passed as CriteriaCollection
38
     * to another sub-search.
39
     * Whole process will return collection of results from each sub-search.
40
     *
41
     * @param CriteriaCollectionInterface $criteriaCollection
42
     *
43
     * @return ResultCollection
44
     */
45 4
    public function search(
46
        CriteriaCollectionInterface $criteriaCollection
47
    ) {
48 4
        $previousCriteria = null;
49 4
        $previousResults = null;
50 4
        $resultsArray = [];
51
52 4
        foreach ($this->cells as $cell) {
53 4
            if ($cell->getTransformer()->skip($previousResults)) {
54 2
                continue;
55
            }
56
57
            // Assumed only for first iteration
58 4
            if (!$previousCriteria) {
59 4
                $previousCriteria = $criteriaCollection;
60
            }
61
62 4
            $previousResults = $cell->getSearcher()->search($previousCriteria);
63 4
            if ($cell->hasTransformer()) {
64 4
                $previousCriteria = $cell->getTransformer()->transform($previousResults, $previousCriteria);
65
            }
66
67 4
            if ($cell->getName()) {
68 3
                $resultsArray[$cell->getName()] = $previousResults;
69 3
                continue;
70
            }
71
72 1
            array_push($resultsArray, $previousResults);
73
        }
74
75 4
        return new ResultCollection($resultsArray);
76
    }
77
78
    /**
79
     * @param CellInterface[] $cells
80
     * @throws \InvalidArgumentException
81
     */
82 9
    private function validateCells(array $cells)
83
    {
84 9
        if (self::MINIMUM_CELLS > count($cells)) {
85 2
            throw new \InvalidArgumentException(
86 2
                'At least two searchers are required to create a chain'
87
            );
88
        }
89
90 7
        foreach ($cells as $cell) {
91 7
            if (is_object($cell) && $cell instanceof CellInterface) {
92 7
                continue;
93
            }
94
95 1
            throw new \InvalidArgumentException(sprintf(
96 1
                'All cells passed to %s should be object and must implement CellInterface',
97 1
                __CLASS__
98
            ));
99
        }
100 6
    }
101
}
102