Completed
Pull Request — master (#1749)
by Gabriel
11:34
created

DocumentRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 3
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\Common\Collections\Collection;
9
use Doctrine\Common\Collections\Criteria;
10
use Doctrine\Common\Collections\Selectable;
11
use Doctrine\Common\Persistence\ObjectRepository;
12
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
13
use Doctrine\ODM\MongoDB\Query\QueryExpressionVisitor;
14
use function is_array;
15
16
/**
17
 * A DocumentRepository serves as a repository for documents with generic as well as
18
 * business specific methods for retrieving documents.
19
 *
20
 * This class is designed for inheritance and users can subclass this class to
21
 * write their own repositories with business-specific methods to locate documents.
22
 *
23
 */
24
class DocumentRepository implements ObjectRepository, Selectable
25
{
26
    /**
27
     * @var string
28
     */
29
    protected $documentName;
30
31
    /**
32
     * @var DocumentManager
33
     */
34
    protected $dm;
35
36
    /**
37
     * @var UnitOfWork
38
     */
39
    protected $uow;
40
41
    /**
42
     * @var ClassMetadata
43
     */
44
    protected $class;
45
46
    /**
47
     * Initializes this instance with the specified document manager, unit of work and
48
     * class metadata.
49
     *
50
     * @param DocumentManager $dm            The DocumentManager to use.
51
     * @param UnitOfWork      $uow           The UnitOfWork to use.
52
     * @param ClassMetadata   $classMetadata The class metadata.
53
     */
54 324
    public function __construct(DocumentManager $dm, UnitOfWork $uow, ClassMetadata $classMetadata)
55
    {
56 324
        $this->documentName = $classMetadata->name;
57 324
        $this->dm = $dm;
58 324
        $this->uow = $uow;
59 324
        $this->class = $classMetadata;
60 324
    }
61
62
    /**
63
     * Creates a new Query\Builder instance that is preconfigured for this document name.
64
     *
65
     * @return Query\Builder $qb
66
     */
67 16
    public function createQueryBuilder()
68
    {
69 16
        return $this->dm->createQueryBuilder($this->documentName);
70
    }
71
72
    /**
73
     * Creates a new Aggregation\Builder instance that is prepopulated for this document name.
74
     *
75
     * @return Aggregation\Builder
76
     */
77
    public function createAggregationBuilder()
78
    {
79
        return $this->dm->createAggregationBuilder($this->documentName);
80
    }
81
82
    /**
83
     * Clears the repository, causing all managed documents to become detached.
84
     */
85
    public function clear()
86
    {
87
        $this->dm->clear($this->class->rootDocumentName);
88
    }
89
90
    /**
91
     * Finds a document matching the specified identifier. Optionally a lock mode and
92
     * expected version may be specified.
93
     *
94
     * @param mixed $id          Identifier.
95
     * @param int   $lockMode    Optional. Lock mode; one of the LockMode constants.
96
     * @param int   $lockVersion Optional. Expected version.
97
     * @throws Mapping\MappingException
98
     * @throws LockException
99
     * @return object|null The document, if found, otherwise null.
100
     */
101 230
    public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
102
    {
103 230
        if ($id === null) {
104
            return null;
105
        }
106
107
        /* TODO: What if the ID object has a field with the same name as the
108
         * class' mapped identifier field name?
109
         */
110 230
        if (is_array($id)) {
111 2
            list($identifierFieldName) = $this->class->getIdentifierFieldNames();
112
113 2
            if (isset($id[$identifierFieldName])) {
114
                $id = $id[$identifierFieldName];
115
            }
116
        }
117
118
        // Check identity map first
119 230
        $document = $this->uow->tryGetById($id, $this->class);
120 230
        if ($document) {
121 21
            if ($lockMode !== LockMode::NONE) {
122
                $this->dm->lock($document, $lockMode, $lockVersion);
123
            }
124
125 21
            return $document; // Hit!
126
        }
127
128 224
        $criteria = ['_id' => $id];
129
130 224
        if ($lockMode === LockMode::NONE) {
131 224
            return $this->getDocumentPersister()->load($criteria);
132
        }
133
134
        if ($lockMode === LockMode::OPTIMISTIC) {
135
            if (! $this->class->isVersioned) {
136
                throw LockException::notVersioned($this->documentName);
137
            }
138
            
139
            $document = $this->getDocumentPersister()->load($criteria);
140
            if ($document) {
141
                $this->uow->lock($document, $lockMode, $lockVersion);
142
            }
143
144
            return $document;
145
        }
146
147
        return $this->getDocumentPersister()->load($criteria, null, [], $lockMode);
148
    }
149
150
    /**
151
     * Finds all documents in the repository.
152
     *
153
     * @return array
154
     */
155 10
    public function findAll()
156
    {
157 10
        return $this->findBy([]);
158
    }
159
160
    /**
161
     * Finds documents by a set of criteria.
162
     *
163
     * @param array    $criteria Query criteria
164
     * @param array    $sort     Sort array for Cursor::sort()
165
     * @param int|null $limit    Limit for Cursor::limit()
166
     * @param int|null $skip     Skip for Cursor::skip()
167
     *
168
     * @return array
169
     */
170 11
    public function findBy(array $criteria, ?array $sort = null, $limit = null, $skip = null)
171
    {
172 11
        return $this->getDocumentPersister()->loadAll($criteria, $sort, $limit, $skip)->toArray(false);
0 ignored issues
show
Unused Code introduced by
The call to Iterator::toArray() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
173
    }
174
175
    /**
176
     * Finds a single document by a set of criteria.
177
     *
178
     * @param array $criteria
179
     * @return object
180
     */
181 74
    public function findOneBy(array $criteria)
182
    {
183 74
        return $this->getDocumentPersister()->load($criteria);
184
    }
185
186
    /**
187
     * @return string
188
     */
189
    public function getDocumentName()
190
    {
191
        return $this->documentName;
192
    }
193
194
    /**
195
     * @return DocumentManager
196
     */
197
    public function getDocumentManager()
198
    {
199
        return $this->dm;
200
    }
201
202
    /**
203
     * @return Mapping\ClassMetadata
204
     */
205
    public function getClassMetadata()
206
    {
207
        return $this->class;
208
    }
209
210
    /**
211
     * @return string
212
     */
213
    public function getClassName()
214
    {
215
        return $this->getDocumentName();
216
    }
217
218
    /**
219
     * Selects all elements from a selectable that match the expression and
220
     * returns a new collection containing these elements.
221
     *
222
     * @see Selectable::matching()
223
     * @return Collection
224
     */
225 4
    public function matching(Criteria $criteria)
226
    {
227 4
        $visitor = new QueryExpressionVisitor($this->createQueryBuilder());
228 4
        $queryBuilder = $this->createQueryBuilder();
229
230 4
        if ($criteria->getWhereExpression() !== null) {
231 1
            $expr = $visitor->dispatch($criteria->getWhereExpression());
232 1
            $queryBuilder->setQueryArray($expr->getQuery());
233
        }
234
235 4
        if ($criteria->getMaxResults() !== null) {
236
            $queryBuilder->limit($criteria->getMaxResults());
237
        }
238
239 4
        if ($criteria->getFirstResult() !== null) {
240
            $queryBuilder->skip($criteria->getFirstResult());
241
        }
242
243 4
        if ($criteria->getOrderings() !== null) {
244 4
            $queryBuilder->sort($criteria->getOrderings());
245
        }
246
247
        // @TODO: wrap around a specialized Collection for efficient count on large collections
248 4
        return new ArrayCollection($queryBuilder->getQuery()->execute()->toArray());
249
    }
250
251 306
    protected function getDocumentPersister()
252
    {
253 306
        return $this->uow->getDocumentPersister($this->documentName);
254
    }
255
}
256