Completed
Pull Request — master (#285)
by
unknown
01:48
created

CombinedAdapter::getSlice()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 18
cts 18
cp 1
rs 9.1448
c 0
b 0
f 0
cc 5
nc 5
nop 2
crap 5
1
<?php
2
3
namespace Pagerfanta\Adapter;
4
5
/**
6
 * CombinedAdapter
7
 *
8
 * @author Mike Meier <[email protected]>
9
 */
10
class CombinedAdapter implements AdapterInterface
11
{
12
    /**
13
     * @var AdapterInterface[]
14
     */
15
    private $adapters;
16
17
    /**
18
     * @var array<string, int>
19
     */
20
    private $counts = [];
21
22
    /**
23
     * @var int
24
     */
25
    private $total = 0;
26
27
    /**
28
     * @var bool
29
     */
30
    private $init = false;
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param AdapterInterface[] $adapters The adapters to combine.
36
     */
37 2
    public function __construct(array $adapters)
38
    {
39 2
        $this->adapters = $adapters;
40 2
    }
41
42
    /**
43
     * Returns the combined adapters.
44
     *
45
     * @return AdapterInterface[] The combined Adapters.
46
     */
47 1
    public function getAdapters(): array
48
    {
49 1
        return $this->adapters;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 1
    public function getNbResults(): int
56
    {
57 1
        $this->initCounts();
58
59 1
        return $this->total;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 1
    public function getSlice($offset, $length): \Traversable
66
    {
67 1
        $this->initCounts();
68
69 1
        $currentNeeded = $length;
70 1
        $currentOffset = $offset;
71
72 1
        foreach ($this->adapters as $adapterKey => $adapter) {
73 1
            if ($currentNeeded <= 0) {
74 1
                break;
75
            }
76
77 1
            $adapterCount = $this->counts[spl_object_hash($adapter)];
78 1
            $adapterCanProvide = $adapterCount - $currentOffset;
79
80 1
            if ($adapterCanProvide < 0) {
81 1
                $currentOffset -= $adapterCount;
82 1
                continue;
83
            }
84
85 1
            $adapterLength = min($adapterCanProvide, $currentNeeded);
86 1
            foreach ($adapter->getSlice($currentOffset, $adapterLength) as $value) {
87 1
                yield $value;
88
            }
89
90 1
            $currentNeeded -= $adapterLength;
91 1
            $currentOffset = 0;
92
        }
93 1
    }
94
95 2
    private function initCounts()
96
    {
97 2
        if ($this->init) {
98 1
            return;
99
        }
100
101 2
        foreach ($this->adapters as $adapter) {
102 2
            $count = $adapter->getNbResults();
103 2
            $this->counts[spl_object_hash($adapter)] = $count;
104 2
            $this->total += $count;
105
        }
106
107 2
        $this->init = true;
108 2
    }
109
}
110