Completed
Push — master ( 56408e...5dfd0e )
by Maciej
22:59 queued 12:13
created

HydratingIterator::getIterator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 3
cts 4
cp 0.75
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2.0625
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Iterator;
6
7
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
8
use Doctrine\ODM\MongoDB\UnitOfWork;
9
use Generator;
10
use Iterator;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Doctrine\ODM\MongoDB\Iterator\Iterator.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use RuntimeException;
12
use Traversable;
13
14
/**
15
 * Iterator that wraps a traversable and hydrates results into objects
16
 *
17
 * @internal
18
 */
19
final class HydratingIterator implements Iterator
20
{
21
    /** @var Generator|null */
22
    private $iterator;
23
24
    /** @var UnitOfWork */
25
    private $unitOfWork;
26
27
    /** @var ClassMetadata */
28
    private $class;
29
30
    /** @var array */
31
    private $unitOfWorkHints;
32
33 120
    public function __construct(Traversable $traversable, UnitOfWork $unitOfWork, ClassMetadata $class, array $unitOfWorkHints = [])
34
    {
35 120
        $this->iterator        = $this->wrapTraversable($traversable);
36 120
        $this->unitOfWork      = $unitOfWork;
37 120
        $this->class           = $class;
38 120
        $this->unitOfWorkHints = $unitOfWorkHints;
39 120
    }
40
41 89
    public function __destruct()
42
    {
43 89
        $this->iterator = null;
44 89
    }
45
46
    /**
47
     * @see http://php.net/iterator.current
48
     *
49
     * @return mixed
50
     */
51 111
    public function current()
52
    {
53 111
        return $this->hydrate($this->getIterator()->current());
54
    }
55
56
    /**
57
     * @see http://php.net/iterator.mixed
58
     *
59
     * @return mixed
60
     */
61 120
    public function key()
62
    {
63 120
        return $this->getIterator()->key();
64
    }
65
66
    /**
67
     * @see http://php.net/iterator.next
68
     */
69 68
    public function next() : void
70
    {
71 68
        $this->getIterator()->next();
72 68
    }
73
74
    /**
75
     * @see http://php.net/iterator.rewind
76
     */
77 119
    public function rewind() : void
78
    {
79 119
        $this->getIterator()->rewind();
80 119
    }
81
82
    /**
83
     * @see http://php.net/iterator.valid
84
     */
85 120
    public function valid() : bool
86
    {
87 120
        return $this->key() !== null;
88
    }
89
90 120
    private function getIterator() : Generator
91
    {
92 120
        if ($this->iterator === null) {
93
            throw new RuntimeException('Iterator has already been destroyed');
94
        }
95
96 120
        return $this->iterator;
97
    }
98
99 111
    private function hydrate($document)
100
    {
101 111
        return $document !== null ? $this->unitOfWork->getOrCreateDocument($this->class->name, $document, $this->unitOfWorkHints) : null;
102
    }
103
104 120
    private function wrapTraversable(Traversable $traversable) : Generator
105
    {
106 120
        foreach ($traversable as $key => $value) {
107 111
            yield $key => $value;
108
        }
109 79
    }
110
}
111