Completed
Pull Request — master (#1719)
by Maciej
32:40 queued 05:23
created

DocumentRepository::__call()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.9256

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 12
cts 18
cp 0.6667
rs 8.439
c 0
b 0
f 0
cc 5
eloc 19
nc 7
nop 2
crap 5.9256

2 Methods

Rating   Name   Duplication   Size   Complexity  
A DocumentRepository::getClassMetadata() 0 4 1
A DocumentRepository::getClassName() 0 4 1
1
<?php
2
3
namespace Doctrine\ODM\MongoDB;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Collection;
7
use Doctrine\Common\Collections\Criteria;
8
use Doctrine\Common\Collections\Selectable;
9
use Doctrine\Common\Inflector\Inflector;
10
use Doctrine\Common\Persistence\ObjectRepository;
11
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
12
use Doctrine\ODM\MongoDB\Query\QueryExpressionVisitor;
13
14
/**
15
 * A DocumentRepository serves as a repository for documents with generic as well as
16
 * business specific methods for retrieving documents.
17
 *
18
 * This class is designed for inheritance and users can subclass this class to
19
 * write their own repositories with business-specific methods to locate documents.
20
 *
21
 * @since       1.0
22
 */
23
class DocumentRepository implements ObjectRepository, Selectable
24
{
25
    /**
26
     * @var string
27
     */
28
    protected $documentName;
29
30
    /**
31
     * @var DocumentManager
32
     */
33
    protected $dm;
34
35
    /**
36
     * @var UnitOfWork
37
     */
38
    protected $uow;
39
40
    /**
41
     * @var ClassMetadata
42
     */
43
    protected $class;
44
45
    /**
46
     * Initializes this instance with the specified document manager, unit of work and
47
     * class metadata.
48
     *
49
     * @param DocumentManager $dm The DocumentManager to use.
50
     * @param UnitOfWork $uow The UnitOfWork to use.
51
     * @param ClassMetadata $classMetadata The class metadata.
52
     */
53 328
    public function __construct(DocumentManager $dm, UnitOfWork $uow, ClassMetadata $classMetadata)
54
    {
55 328
        $this->documentName = $classMetadata->name;
56 328
        $this->dm = $dm;
57 328
        $this->uow = $uow;
58 328
        $this->class = $classMetadata;
59 328
    }
60
61
    /**
62
     * Creates a new Query\Builder instance that is preconfigured for this document name.
63
     *
64
     * @return Query\Builder $qb
65
     */
66 16
    public function createQueryBuilder()
67
    {
68 16
        return $this->dm->createQueryBuilder($this->documentName);
69
    }
70
71
    /**
72
     * Creates a new Aggregation\Builder instance that is prepopulated for this document name.
73
     *
74
     * @return Aggregation\Builder
75
     */
76
    public function createAggregationBuilder()
77
    {
78
        return $this->dm->createAggregationBuilder($this->documentName);
79
    }
80
81
    /**
82
     * Clears the repository, causing all managed documents to become detached.
83
     */
84
    public function clear()
85
    {
86
        $this->dm->clear($this->class->rootDocumentName);
87
    }
88
89
    /**
90
     * Finds a document matching the specified identifier. Optionally a lock mode and
91
     * expected version may be specified.
92
     *
93
     * @param mixed $id Identifier.
94
     * @param int $lockMode Optional. Lock mode; one of the LockMode constants.
95
     * @param int $lockVersion Optional. Expected version.
96
     * @throws Mapping\MappingException
97
     * @throws LockException
98
     * @return object|null The document, if found, otherwise null.
99
     */
100 234
    public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
101
    {
102 234
        if ($id === null) {
103
            return null;
104
        }
105
106
        /* TODO: What if the ID object has a field with the same name as the
107
         * class' mapped identifier field name?
108
         */
109 234
        if (is_array($id)) {
110 2
            list($identifierFieldName) = $this->class->getIdentifierFieldNames();
111
112 2
            if (isset($id[$identifierFieldName])) {
113
                $id = $id[$identifierFieldName];
114
            }
115
        }
116
117
        // Check identity map first
118 234
        if ($document = $this->uow->tryGetById($id, $this->class)) {
119 21
            if ($lockMode !== LockMode::NONE) {
120
                $this->dm->lock($document, $lockMode, $lockVersion);
121
            }
122
123 21
            return $document; // Hit!
124
        }
125
126 228
        $criteria = array('_id' => $id);
127
128 228
        if ($lockMode === LockMode::NONE) {
129 228
            return $this->getDocumentPersister()->load($criteria);
130
        }
131
132
        if ($lockMode === LockMode::OPTIMISTIC) {
133
            if (!$this->class->isVersioned) {
134
                throw LockException::notVersioned($this->documentName);
135
            }
136
            if ($document = $this->getDocumentPersister()->load($criteria)) {
137
                $this->uow->lock($document, $lockMode, $lockVersion);
138
            }
139
140
            return $document;
141
        }
142
143
        return $this->getDocumentPersister()->load($criteria, null, array(), $lockMode);
144
    }
145
146
    /**
147
     * Finds all documents in the repository.
148
     *
149
     * @return array
150
     */
151 10
    public function findAll()
152
    {
153 10
        return $this->findBy(array());
154
    }
155
156
    /**
157
     * Finds documents by a set of criteria.
158
     *
159
     * @param array        $criteria Query criteria
160
     * @param array        $sort     Sort array for Cursor::sort()
161
     * @param integer|null $limit    Limit for Cursor::limit()
162
     * @param integer|null $skip     Skip for Cursor::skip()
163
     *
164
     * @return array
165
     */
166 11
    public function findBy(array $criteria, array $sort = null, $limit = null, $skip = null)
167
    {
168 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...
169
    }
170
171
    /**
172
     * Finds a single document by a set of criteria.
173
     *
174
     * @param array $criteria
175
     * @return object
176
     */
177 74
    public function findOneBy(array $criteria)
178
    {
179 74
        return $this->getDocumentPersister()->load($criteria);
180
    }
181
182
    /**
183
     * @return string
184
     */
185
    public function getDocumentName()
186
    {
187
        return $this->documentName;
188
    }
189
190
    /**
191
     * @return DocumentManager
192
     */
193
    public function getDocumentManager()
194
    {
195
        return $this->dm;
196
    }
197
198
    /**
199
     * @return Mapping\ClassMetadata
200
     */
201
    public function getClassMetadata()
202
    {
203
        return $this->class;
204
    }
205
206
    /**
207
     * @return string
208
     */
209
    public function getClassName()
210
    {
211
        return $this->getDocumentName();
212
    }
213
214
    /**
215
     * Selects all elements from a selectable that match the expression and
216
     * returns a new collection containing these elements.
217
     *
218
     * @see Selectable::matching()
219
     * @param Criteria $criteria
220
     * @return Collection
221
     */
222 4
    public function matching(Criteria $criteria)
223
    {
224 4
        $visitor = new QueryExpressionVisitor($this->createQueryBuilder());
225 4
        $queryBuilder = $this->createQueryBuilder();
226
227 4
        if ($criteria->getWhereExpression() !== null) {
228 1
            $expr = $visitor->dispatch($criteria->getWhereExpression());
229 1
            $queryBuilder->setQueryArray($expr->getQuery());
230
        }
231
232 4
        if ($criteria->getMaxResults() !== null) {
233
            $queryBuilder->limit($criteria->getMaxResults());
234
        }
235
236 4
        if ($criteria->getFirstResult() !== null) {
237
            $queryBuilder->skip($criteria->getFirstResult());
238
        }
239
240 4
        if ($criteria->getOrderings() !== null) {
241 4
            $queryBuilder->sort($criteria->getOrderings());
242
        }
243
244
        // @TODO: wrap around a specialized Collection for efficient count on large collections
245 4
        return new ArrayCollection($queryBuilder->getQuery()->execute()->toArray());
246
    }
247
248 310
    protected function getDocumentPersister()
249
    {
250 310
        return $this->uow->getDocumentPersister($this->documentName);
251
    }
252
}
253