Completed
Push — master ( 1358d6...984c1e )
by Karsten
01:40
created

PsiFactoryImpl::createIterator()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 31
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.0909

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 31
ccs 11
cts 13
cp 0.8462
rs 8.439
cc 5
eloc 14
nc 6
nop 2
crap 5.0909
1
<?php
2
/**
3
 * File was created 11.05.2015 07:05
4
 *
5
 * @author Karsten J. Gerber <[email protected]>
6
 */
7
namespace PeekAndPoke\Component\Psi;
8
9
use PeekAndPoke\Component\Psi\Exception\PsiException;
10
use PeekAndPoke\Component\Psi\Interfaces\PsiFactory;
11
use PeekAndPoke\Component\Psi\Iterator\KeylessAppendIterator;
12
use PeekAndPoke\Component\Psi\Solver\DefaultOperationChainSolver;
13
14
/**
15
 * PsiFactory
16
 *
17
 * @author Karsten J. Gerber <[email protected]>
18
 */
19
class PsiFactoryImpl implements PsiFactory
20
{
21
    /**
22
     * {@inheritdoc}
23
     */
24 70
    public function createSolver()
25
    {
26 70
        return new DefaultOperationChainSolver();
27
    }
28
29
    /**
30
     * {@inheritdoc}
31
     */
32 70
    public function createIterator(array $iteratables, PsiOptions $options)
33
    {
34 70
        $count = count($iteratables);
35
36 70
        if ($count === 1) {
37 67
            return $this->createSingleIterator($iteratables[0]);
38
        }
39
40 3
        if ($count > 1) {
41
            // when we have multiple inputs we need an option to decide on how to deal with colliding keys
42 3
            if ($options->isPreserveKeysOfMultipleInputs()) {
43
                // this iterator return the original keys of each child iterator
44
                // -> this leads to conflicts OR means we preserve keys
45
                $iterator = new \AppendIterator();
46
            } else {
47
                // this iterator will create numeric keys from 0 .. n
48 3
                $iterator = new KeylessAppendIterator();
49
            }
50
51 3
            foreach ($iteratables as $iteratable) {
52
53 3
                $iterator->append(
54 3
                    $this->createSingleIterator($iteratable)
55
                );
56
            }
57
58 3
            return $iterator;
59
        }
60
61
        return new \ArrayIterator();
62
    }
63
64
    /**
65
     * @param mixed $iteratable
66
     * @return \Iterator
67
     *
68
     * @throws PsiException
69
     */
70 70
    private function createSingleIterator($iteratable)
71
    {
72 70
        if ($iteratable === null) {
73 3
            return new \ArrayIterator();
74
        }
75
76 69
        if ($iteratable instanceof \Iterator) {
77
            return $iteratable;
78
        }
79
80 69
        if ($iteratable instanceof \Traversable) {
81
            // TODO: figure out if that is correct
82
            return new \IteratorIterator($iteratable);
83
        }
84
85 69
        if (is_array($iteratable)) {
86 69
            return new \ArrayIterator($iteratable);
87
        }
88
89
        // TODO: what about classes implementing \ArrayAccess and/or \Countable?
90
91
        throw new PsiException('Invalid input, not an array or an Iterator or a Traversable');
92
    }
93
}
94