Completed
Push — master ( e112b2...aa67e9 )
by De Cramer
02:06
created

ChainProcessor::processItemWithOperation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 3
dl 0
loc 12
ccs 9
cts 9
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Oliverde8\Component\PhpEtl;
4
5
use Oliverde8\Component\PhpEtl\ChainOperation\ChainOperationInterface;
6
use Oliverde8\Component\PhpEtl\Exception\ChainOperationException;
7
use Oliverde8\Component\PhpEtl\Item\ChainBreakItem;
8
use Oliverde8\Component\PhpEtl\Item\DataItem;
9
use Oliverde8\Component\PhpEtl\Item\GroupedItemInterface;
10
use Oliverde8\Component\PhpEtl\Item\ItemInterface;
11
use Oliverde8\Component\PhpEtl\Item\StopItem;
12
13
/**
14
 * Class ChainProcessor
15
 *
16
 * @author    de Cramer Oliver<[email protected]>
17
 * @copyright 2018 Oliverde8
18
 * @package Oliverde8\Component\PhpEtl
19
 */
20
class ChainProcessor
21
{
22
    /** @var ChainOperationInterface[] */
23
    protected $chainLinks = [];
24
25
    /** @var string[] */
26
    protected $chainLinkNames = [];
27
28
    /**
29
     * ChainProcessor constructor.
30
     *
31
     * @param ChainOperationInterface[] $chainLinks
32
     */
33 5
    public function __construct(array $chainLinks)
34
    {
35 5
        $this->chainLinkNames = array_keys($chainLinks);
36 5
        $this->chainLinks = array_values($chainLinks);
37 5
    }
38
39
    /**
40
     * Process items.
41
     *
42
     * @param \Iterator $items
43
     * @param $context
44
     * @throws ChainOperationException
45
     */
46 5
    public function process(\Iterator $items, $context)
47
    {
48 5
        if (!isset($context['etl']['identifier'])) {
49 5
            $context['etl']['identifier'] = '';
50
        }
51
52 5
        $this->processItems($items, 0, $context);
53 4
    }
54
55
    /**
56
     * Process list of items with chain starting at $startAt.
57
     *
58
     * @param \Iterator $items
59
     * @param int $startAt
60
     * @param array $context
61
     *
62
     * @return ItemInterface
63
     * @throws ChainOperationException
64
     */
65 5
    protected function processItems(\Iterator $items, $startAt, &$context)
66
    {
67 5
        $identifierPrefix = $context['etl']['identifier'];
68
69 5
        $count = 1;
70 5
        foreach ($items as $item) {
71 5
            $context['etl']['identifier'] = $identifierPrefix . $count++;
72
73 5
            $dataItem = new DataItem($item);
74 5
            $this->processItem($dataItem, $startAt, $context);
75
        }
76
77 4
        $stopItem = new StopItem();
78 4
        $context['etl']['identifier'] = $identifierPrefix . 'STOP';
79 4
        while ($this->processItem($stopItem, $startAt, $context) !== $stopItem);
80
81 4
        return $stopItem;
82
    }
83
84
    /**
85
     * Process an item, with chains starting at.
86
     *
87
     * @param ItemInterface $item
88
     * @param $startAt
89
     * @param $context
90
     *
91
     * @return mixed|ItemInterface|StopItem
92
     * @throws ChainOperationException
93
     */
94 5
    protected function processItem(ItemInterface $item, $startAt, &$context)
95
    {
96 5
        for ($chainNumber = $startAt; $chainNumber < count($this->chainLinks); $chainNumber++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
97 5
            $item = $this->processItemWithOperation($item, $chainNumber, $context);
98
99 4
            if ($item instanceof GroupedItemInterface) {
100 2
                $context['etl']['identifier'] .= "chain link:" . $this->chainLinkNames[$chainNumber] . "-";
101 2
                $this->processItems($item->getIterator(), $chainNumber + 1, $context);
102
103 2
                return new StopItem();
104 4
            } else if ($item instanceof ChainBreakItem) {
105 3
                return $item;
106
            }
107
        }
108
109 4
        return $item;
110
    }
111
112
    /**
113
     * Process an item and handle errors during the process.
114
     *
115
     * @param $item
116
     * @param $chainNumber
117
     * @param $context
118
     *
119
     *
120
     * @return ItemInterface
121
     * @throws ChainOperationException
122
     */
123 5
    protected function processItemWithOperation($item, $chainNumber, &$context)
124
    {
125
        try {
126 5
            return $this->chainLinks[$chainNumber]->process($item, $context);
127 1
        } catch (\Exception $exception) {
128 1
            throw new ChainOperationException(
129
                "An exception was thrown during the handling of the chain link : "
130 1
                    . "{$this->chainLinkNames[$chainNumber]} "
131 1
                    . "with the item {$context['etl']['identifier']}.",
132 1
                0,
133 1
                $exception,
134 1
                $this->chainLinkNames[$chainNumber]
135
            );
136
        }
137
    }
138
}
139