This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | declare(strict_types=1); |
||
3 | /** |
||
4 | * Minotaur |
||
5 | * |
||
6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
||
7 | * use this file except in compliance with the License. You may obtain a copy of |
||
8 | * the License at |
||
9 | * |
||
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
11 | * |
||
12 | * Unless required by applicable law or agreed to in writing, software |
||
13 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
||
14 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
||
15 | * License for the specific language governing permissions and limitations under |
||
16 | * the License. |
||
17 | * |
||
18 | * @copyright 2015-2017 Appertly |
||
19 | * @license Apache-2.0 |
||
20 | */ |
||
21 | namespace Minotaur\Db; |
||
22 | |||
23 | use ArrayIterator; |
||
24 | use MongoDB\BSON\ObjectID; |
||
25 | use MongoDB\Driver\Cursor; |
||
26 | use MongoDB\Driver\Manager; |
||
27 | use MongoDB\Driver\ReadPreference; |
||
28 | use MongoDB\Driver\WriteConcern; |
||
29 | use MongoDB\Driver\WriteResult; |
||
30 | use Caridea\Dao\MongoDb as MongoDbDao; |
||
31 | use Caridea\Event\PublisherAware; |
||
32 | use Minotaur\Getter; |
||
33 | |||
34 | /** |
||
35 | * Abstract MongoDB DAO Service |
||
36 | */ |
||
37 | abstract class AbstractMongoDao extends MongoDbDao implements EntityRepo, DbRefResolver, PublisherAware |
||
38 | { |
||
39 | use MongoHelper; |
||
40 | use \Caridea\Dao\Event\Publishing; |
||
41 | |||
42 | /** |
||
43 | * @var bool Whether to enforce optimistic locking |
||
44 | */ |
||
45 | private $versioned = true; |
||
46 | /** |
||
47 | * @var bool Whether entities will be put in the first-level cache |
||
48 | */ |
||
49 | private $caching = true; |
||
50 | /** |
||
51 | * @var array<string,?string> The MongoDB type map when reading records |
||
52 | */ |
||
53 | private $typeMap = ['root' => null, 'document' => null]; |
||
54 | /** |
||
55 | * @var \MongoDB\Driver\ReadPreference The MongoDB read preference, or `null` |
||
56 | */ |
||
57 | private $readPreference; |
||
58 | /** |
||
59 | * @var \MongoDB\Driver\ReadPreference The MongoDB write concern, or `null` |
||
60 | */ |
||
61 | private $writeConcern; |
||
62 | /** |
||
63 | * @var array<string,mixed> First-level cache |
||
64 | */ |
||
65 | private $cache = []; |
||
66 | |||
67 | /** |
||
68 | * Creates a new AbstractMongoDao. |
||
69 | * |
||
70 | * Current accepted configuration values: |
||
71 | * * `versioned` – Whether to enforce optimistic locking via a version field (default: true) |
||
72 | * * `caching` – Whether to cache entities by ID (default: true) |
||
73 | * * `typeMapRoot` – The type used to unserialize BSON root documents |
||
74 | * * `typeMapDocument` – The type used to unserialize BSON nested documents |
||
75 | * * `readPreference` – Must be a `MongoDB\Driver\ReadPreference` |
||
76 | * * `writeConcern` – Must be a `MongoDB\Driver\WriteConcern` |
||
77 | * |
||
78 | * As for the `typeMap` options, you can see |
||
79 | * [Deserialization from BSON](http://php.net/manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps) |
||
80 | * for more information. |
||
81 | * |
||
82 | * @param \MongoDB\Driver\Manager $manager The MongoDB Manager |
||
83 | * @param string $collection The collection to wrap |
||
84 | * @param array<string,mixed> $options Optional. Map of configuration values |
||
85 | */ |
||
86 | public function __construct( |
||
87 | Manager $manager, |
||
88 | string $collection, |
||
89 | array $options = null |
||
90 | ) { |
||
91 | parent::__construct($manager, $collection); |
||
92 | if ($options !== null) { |
||
93 | $this->versioned = array_key_exists('version', $options) ? |
||
94 | (bool) $options['version'] : true; |
||
95 | $this->caching = array_key_exists('caching', $options) ? |
||
96 | (bool) $options['caching'] : true; |
||
97 | if (array_key_exists('typeMapRoot', $options)) { |
||
98 | $r = $options['typeMapRoot']; |
||
99 | $this->typeMap['root'] = $r === null ? null : (string)$r; |
||
100 | } |
||
101 | if (array_key_exists('typeMapDocument', $options)) { |
||
102 | $d = $options['typeMapDocument']; |
||
103 | $this->typeMap['document'] = $d === null ? null : (string)$d; |
||
104 | } |
||
105 | $rp = $options['readPreference'] ?? null; |
||
106 | if ($rp instanceof ReadPreference) { |
||
0 ignored issues
–
show
|
|||
107 | $this->readPreference = $rp; |
||
108 | } |
||
109 | $wc = $options['writeConcern'] ?? null; |
||
110 | if ($wc instanceof WriteConcern) { |
||
0 ignored issues
–
show
The class
MongoDB\Driver\WriteConcern does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
111 | $this->writeConcern = $wc; |
||
0 ignored issues
–
show
It seems like
$wc of type object<MongoDB\Driver\WriteConcern> is incompatible with the declared type object<MongoDB\Driver\ReadPreference> of property $writeConcern .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
112 | } |
||
113 | } |
||
114 | $this->publisher = new \Caridea\Event\NullPublisher(); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * @inheritDoc |
||
119 | */ |
||
120 | public function countAll(array $criteria): int |
||
121 | { |
||
122 | $result = $this->doExecute(function (Manager $m, string $c) use ($criteria) { |
||
123 | list($db, $coll) = explode('.', $c, 2); |
||
124 | $command = new \MongoDB\Driver\Command([ |
||
125 | 'count' => $coll, |
||
126 | 'query' => $criteria, |
||
127 | ]); |
||
128 | $cursor = $m->executeCommand($db, $command, $this->readPreference); |
||
129 | $cursor->setTypeMap(['root' => 'array']); |
||
130 | $resa = $cursor->toArray(); |
||
131 | return count($resa) > 0 ? current($resa) : null; |
||
132 | }); |
||
133 | |||
134 | // Older server versions may return a float |
||
135 | if (!is_array($result) || !array_key_exists('n', $result) || !(is_int($result['n']) || is_float($result['n']))) { |
||
136 | throw new \Caridea\Dao\Exception\Unretrievable('count command did not return a numeric "n" value'); |
||
137 | } |
||
138 | |||
139 | return (int) $result['n']; |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * @inheritDoc |
||
144 | */ |
||
145 | public function findOne(array $criteria) |
||
146 | { |
||
147 | return $this->maybeCache( |
||
148 | $this->doExecute(function (Manager $m, string $c) use ($criteria) { |
||
149 | $q = new \MongoDB\Driver\Query($criteria, ['limit' => 1]); |
||
150 | $res = $m->executeQuery($c, $q, $this->readPreference); |
||
151 | $res->setTypeMap($this->typeMap); |
||
152 | $resa = $res->toArray(); |
||
153 | return count($resa) > 0 ? current($resa) : null; |
||
154 | }) |
||
155 | ); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * @inheritDoc |
||
160 | */ |
||
161 | public function findAll(array $criteria, \Caridea\Http\Pagination $pagination = null, bool $totalCount = false): iterable |
||
162 | { |
||
163 | $total = null; |
||
164 | if ($totalCount === true && $pagination !== null && ($pagination->getMax() != PHP_INT_MAX || $pagination->getOffset() > 0)) { |
||
165 | $total = $this->countAll($criteria); |
||
166 | } |
||
167 | $results = $this->doExecute(function (Manager $m, string $c) use ($criteria, $pagination) { |
||
168 | $qo = []; |
||
169 | if ($pagination !== null) { |
||
170 | if ($pagination->getMax() != PHP_INT_MAX) { |
||
171 | $qo['limit'] = $pagination->getMax(); |
||
172 | } |
||
173 | $qo['skip'] = $pagination->getOffset(); |
||
174 | $sorts = []; |
||
175 | foreach ($pagination->getOrder() as $k => $v) { |
||
176 | $sorts[$k] = $v ? 1 : -1; |
||
177 | } |
||
178 | if (count($sorts) > 0) { |
||
179 | $qo['sort'] = $sorts; |
||
180 | } |
||
181 | } |
||
182 | $q = new \MongoDB\Driver\Query($criteria, $qo); |
||
183 | $res = $m->executeQuery($c, $q, $this->readPreference); |
||
184 | $res->setTypeMap($this->typeMap); |
||
185 | return $res; |
||
186 | }); |
||
187 | return $total === null ? $results : new CursorSubset($results, $total); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * @inheritDoc |
||
192 | */ |
||
193 | public function findById($id) |
||
194 | { |
||
195 | try { |
||
196 | $mid = $this->toId($id); |
||
197 | } catch (\MongoDB\Driver\Exception\InvalidArgumentException $e) { |
||
0 ignored issues
–
show
The class
MongoDB\Driver\Exception\InvalidArgumentException does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
198 | if ($e->getMessage() === 'Invalid BSON ID provided') { |
||
199 | throw new \Caridea\Dao\Exception\Unretrievable('Could not find document', 0, $e); |
||
200 | } |
||
201 | throw $e; |
||
202 | } |
||
203 | return $this->getFromCache((string)$id) ?? |
||
204 | $this->findOne(['_id' => $mid]); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * @inheritDoc |
||
209 | */ |
||
210 | public function get($id) |
||
211 | { |
||
212 | return $this->ensure($id, $this->findById($id)); |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * @inheritDoc |
||
217 | */ |
||
218 | public function getAll(iterable $ids): iterable |
||
219 | { |
||
220 | $ids = is_array($ids) ? $ids : iterator_to_array($ids); |
||
221 | if (count($ids) === 0) { |
||
222 | return []; |
||
223 | } |
||
224 | try { |
||
225 | $mids = $this->toIds($ids); |
||
226 | } catch (\MongoDB\Driver\Exception\InvalidArgumentException $e) { |
||
0 ignored issues
–
show
The class
MongoDB\Driver\Exception\InvalidArgumentException does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
227 | if ($e->getMessage() === 'Invalid BSON ID provided') { |
||
228 | throw new \Caridea\Dao\Exception\Unretrievable('Could not load documents', 0, $e); |
||
229 | } |
||
230 | throw $e; |
||
231 | } |
||
232 | $cmp = array_flip(array_map(function ($a) { |
||
233 | return (string) $a; |
||
234 | }, $ids)); |
||
235 | $fromCache = array_intersect_key($this->cache, $cmp); |
||
236 | if (count($fromCache) === count($ids)) { |
||
237 | return $fromCache; |
||
238 | } elseif (count($fromCache) > 0) { |
||
239 | $mids = array_filter($mids, function ($a) { |
||
240 | return !array_key_exists((string)$a, $this->cache); |
||
241 | }); |
||
242 | if(count($mids) < 2){ |
||
0 ignored issues
–
show
|
|||
243 | return array_merge( |
||
244 | $fromCache, |
||
245 | $this->maybeCacheAll($this->findAll(['_id' => $mids])) |
||
246 | ); |
||
247 | } |
||
248 | return array_merge( |
||
249 | $fromCache, |
||
250 | $this->maybeCacheAll($this->findAll(['_id' => ['$in' => array_values($mids)]])) |
||
251 | ); |
||
252 | } else { |
||
253 | return $this->maybeCacheAll($this->findAll(['_id' => ['$in' => array_values($mids)]])); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * @inheritDoc |
||
259 | */ |
||
260 | public function getInstanceMap(iterable $entities): array |
||
261 | { |
||
262 | $instances = []; |
||
263 | foreach ($entities as $entity) { |
||
264 | $instances[(string) Getter::getId($entity)] = $entity; |
||
265 | } |
||
266 | return $instances; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Gets the read preference. |
||
271 | * |
||
272 | * If no read preference was specified at creation, this method returns the |
||
273 | * read preference as returned by the `Manager`. |
||
274 | * |
||
275 | * @return - The read preference, or `null` |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
276 | */ |
||
277 | public function getReadPreference(): ReadPreference |
||
278 | { |
||
279 | return $this->readPreference ?? $this->manager->getReadPreference(); |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Gets the write concern. |
||
284 | * |
||
285 | * If no write concern was specified at creation, this method returns the |
||
286 | * write concern as returned by the `Manager`. |
||
287 | * |
||
288 | * @return - The write concern |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
289 | */ |
||
290 | public function getWriteConcern(): WriteConcern |
||
291 | { |
||
292 | return $this->writeConcern ?? $this->manager->getWriteConcern(); |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * @inheritDoc |
||
297 | */ |
||
298 | public function isResolvable(string $ref): bool |
||
299 | { |
||
300 | return strstr($this->collection, '.') === ".$ref"; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * @inheritDoc |
||
305 | */ |
||
306 | public function resolve(array $ref) |
||
307 | { |
||
308 | if (!array_key_exists('$ref', $ref) || !array_key_exists('$id', $ref)) { |
||
309 | throw new \InvalidArgumentException('Not a DBRef. Needs both $ref and $id keys.'); |
||
310 | } |
||
311 | if (!$this->isResolvable($ref['$ref'])) { |
||
312 | throw new \InvalidArgumentException("Unsupported reference type: " . $ref['$ref']); |
||
313 | } |
||
314 | return $this->findById($ref['$id']); |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * @inheritDoc |
||
319 | */ |
||
320 | public function resolveAll(iterable $refs): iterable |
||
321 | { |
||
322 | $types = []; |
||
323 | $ids = []; |
||
324 | foreach ($refs as $ref) { |
||
325 | $types[$ref['$ref']] = true; |
||
326 | $ids[] = $ref['$id']; |
||
327 | } |
||
328 | foreach ($types as $type => $_) { |
||
329 | if (!$this->isResolvable($type)) { |
||
330 | throw new \InvalidArgumentException("Unsupported reference type: " . $type); |
||
331 | } |
||
332 | } |
||
333 | return $this->getAll($ids); |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * Creates a record. |
||
338 | * |
||
339 | * @param $record - The record to insert, ready to go |
||
340 | * @return - Whatever MongoDB returns |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
341 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
342 | * @throws \Caridea\Dao\Exception\Violating If a constraint is violated |
||
343 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
344 | */ |
||
345 | protected function doCreate(array $record): WriteResult |
||
346 | { |
||
347 | if ($this->versioned) { |
||
348 | $record['version'] = 0; |
||
349 | } |
||
350 | |||
351 | return $this->doExecute(function (Manager $m, string $c) use ($record) { |
||
352 | $bulk = new \MongoDB\Driver\BulkWrite(); |
||
353 | $bulk->insert($record); |
||
354 | return $m->executeBulkWrite($c, $bulk, $this->writeConcern); |
||
355 | }); |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Creates a record using a MongoDB `Persistable`. |
||
360 | * |
||
361 | * @param $record - The document to insert, ready to go |
||
362 | * @return - Whatever MongoDB returns |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
363 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
364 | * @throws \Caridea\Dao\Exception\Violating If a constraint is violated |
||
365 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
366 | */ |
||
367 | protected function doPersist(\MongoDB\BSON\Persistable $record): WriteResult |
||
368 | { |
||
369 | $this->preInsert($record); |
||
370 | $wr = $this->doExecute(function (Manager $m, string $c) use ($record) { |
||
371 | $bulk = new \MongoDB\Driver\BulkWrite(); |
||
372 | $bulk->insert($record); |
||
373 | return $m->executeBulkWrite($c, $bulk, $this->writeConcern); |
||
374 | }); |
||
375 | $this->postInsert($record); |
||
376 | return $wr; |
||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Updates a record. |
||
381 | * |
||
382 | * @param $entity - The entity to update |
||
383 | * @param $version - Optional version for optimistic lock checking |
||
384 | * @return - Whatever MongoDB returns |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
385 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
386 | * @throws \Caridea\Dao\Exception\Conflicting If optimistic/pessimistic lock fails |
||
387 | * @throws \Caridea\Dao\Exception\Violating If a constraint is violated |
||
388 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
389 | */ |
||
390 | protected function doUpdateModifiable(Entity\Modifiable $entity, int $version = null): ?WriteResult |
||
391 | { |
||
392 | if (!$entity->isDirty()) { |
||
393 | return null; |
||
394 | } |
||
395 | $mid = Getter::getId($entity); |
||
396 | $ops = $entity->getChanges(); |
||
397 | |||
398 | if ($this->versioned) { |
||
399 | if ($version !== null) { |
||
400 | $orig = $this->findOne(['_id' => $mid]); |
||
401 | if ($version < (int) Getter::get($orig, 'version')) { |
||
402 | throw new \Caridea\Dao\Exception\Conflicting("Document version conflict"); |
||
403 | } |
||
404 | } |
||
405 | $ops['$inc']['version'] = 1; |
||
406 | } |
||
407 | |||
408 | $this->preUpdate($entity); |
||
409 | unset($this->cache[(string) $mid]); |
||
410 | $wr = $this->doExecute(function (Manager $m, string $c) use ($mid, $ops) { |
||
411 | $bulk = new \MongoDB\Driver\BulkWrite(); |
||
412 | $bulk->update(['_id' => $mid], $ops); |
||
413 | return $m->executeBulkWrite($c, $bulk, $this->writeConcern); |
||
414 | }); |
||
415 | $this->postUpdate($entity); |
||
416 | return $wr; |
||
417 | } |
||
418 | |||
419 | /** |
||
420 | * Updates a record. |
||
421 | * |
||
422 | * @param \MongoDB\BSON\ObjectID|string $id The document identifier, either a string or `ObjectID` |
||
423 | * @param array<string,array<string,mixed>> $operations The operations to send to MongoDB |
||
0 ignored issues
–
show
There is no parameter named
$operations . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
424 | * @param $version - Optional version for optimistic lock checking |
||
425 | * @return - Whatever MongoDB returns |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
426 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
427 | * @throws \Caridea\Dao\Exception\Unretrievable If the document doesn't exist |
||
428 | * @throws \Caridea\Dao\Exception\Conflicting If optimistic/pessimistic lock fails |
||
429 | * @throws \Caridea\Dao\Exception\Violating If a constraint is violated |
||
430 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
431 | */ |
||
432 | protected function doUpdate($id, array $ops, int $version = null): WriteResult |
||
433 | { |
||
434 | // ensure record exists |
||
435 | $mid = $this->toId($id); |
||
436 | $orig = $this->get($id); |
||
437 | |||
438 | // check optimistic locking |
||
439 | if ($this->versioned) { |
||
440 | if ($version !== null) { |
||
441 | if ($version < (int) Getter::get($orig, 'version')) { |
||
442 | throw new \Caridea\Dao\Exception\Conflicting("Document version conflict"); |
||
443 | } |
||
444 | } |
||
445 | $ops['$inc']['version'] = 1; |
||
446 | } |
||
447 | |||
448 | // do update operation |
||
449 | unset($this->cache[(string)$id]); |
||
450 | return $this->doExecute(function (Manager $m, string $c) use ($mid, $ops) { |
||
451 | $bulk = new \MongoDB\Driver\BulkWrite(); |
||
452 | $bulk->update(['_id' => $mid], $ops); |
||
453 | return $m->executeBulkWrite($c, $bulk, $this->writeConcern); |
||
454 | }); |
||
455 | } |
||
456 | |||
457 | /** |
||
458 | * Deletes a record. |
||
459 | * |
||
460 | * @param \MongoDB\BSON\ObjectID|string $id The document identifier, either a string or `ObjectID` |
||
461 | * @return - Whatever MongoDB returns |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
462 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
463 | * @throws \Caridea\Dao\Exception\Unretrievable If the document doesn't exist |
||
464 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
465 | */ |
||
466 | protected function doDelete($id): WriteResult |
||
467 | { |
||
468 | $mid = $this->toId($id); |
||
469 | $entity = $this->get($mid); |
||
470 | unset($this->cache[(string)$id]); |
||
471 | $this->preDelete($entity); |
||
472 | $wr = $this->doExecute(function (Manager $m, string $c) use ($mid) { |
||
473 | $bulk = new \MongoDB\Driver\BulkWrite(); |
||
474 | $bulk->delete(['_id' => $mid], ['limit' => 1]); |
||
475 | return $m->executeBulkWrite($c, $bulk, $this->writeConcern); |
||
476 | }); |
||
477 | $this->postDelete($entity); |
||
478 | return $wr; |
||
479 | } |
||
480 | |||
481 | /** |
||
482 | * Executes an aggregation command. |
||
483 | * |
||
484 | * @param iterable<array<string,mixed>> $pipeline The aggregation pipeline operations |
||
0 ignored issues
–
show
The doc-type
iterable<array<string,mixed>> could not be parsed: Expected "|" or "end of type", but got "<" at position 8. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
485 | * @param array<string,mixed> $options Any aggregation options |
||
486 | * @see https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ |
||
487 | * @since 0.7.2 |
||
488 | */ |
||
489 | protected function doAggregate(iterable $pipeline, array $options): \MongoDB\Driver\Cursor |
||
490 | { |
||
491 | return $this->doExecute(function (Manager $m, string $c) use ($pipeline, $options) { |
||
492 | list($db, $coll) = explode('.', $c, 2); |
||
493 | $cmd = [ |
||
494 | 'aggregate' => $coll, |
||
495 | 'pipeline' => $options, |
||
496 | ]; |
||
497 | foreach ($options as $k => $v) { |
||
498 | $cmd[$k] = $v; |
||
499 | } |
||
500 | $command = new \MongoDB\Driver\Command($cmd); |
||
501 | return $m->executeCommand($db, $command, $this->readPreference); |
||
502 | }); |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Executes a projection. |
||
507 | * |
||
508 | * @param array<string,mixed> $criteria Field to value pairs |
||
509 | * @param array<string,mixed> $projections Field name to projection value |
||
510 | * (either boolean or projection operator) |
||
511 | * @param $pagination - Optional pagination parameters |
||
512 | * @param $totalCount - Return a `CursorSubset` that includes the total |
||
513 | * number of records. This is only done if `$pagination` is not using |
||
514 | * the defaults. |
||
515 | * @return - The projection cursor |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
516 | * @throws \Caridea\Dao\Exception\Unreachable If the connection fails |
||
517 | * @throws \Caridea\Dao\Exception\Unretrievable If the result cannot be returned |
||
518 | * @throws \Caridea\Dao\Exception\Generic If any other database problem occurs |
||
519 | */ |
||
520 | protected function doProjection(array $criteria, array $projections, \Caridea\Http\Pagination $pagination = null, bool $totalCount = false): iterable |
||
521 | { |
||
522 | $total = null; |
||
523 | if ($totalCount === true && $pagination !== null && ($pagination->getMax() != PHP_INT_MAX || $pagination->getOffset() > 0)) { |
||
524 | $total = $this->countAll($criteria); |
||
525 | } |
||
526 | $results = $this->doExecute(function (Manager $m, string $c) use ($criteria, $projections, $pagination) { |
||
527 | $qo = []; |
||
528 | if ($pagination !== null) { |
||
529 | if ($pagination->getMax() != PHP_INT_MAX) { |
||
530 | $qo['limit'] = $pagination->getMax(); |
||
531 | } |
||
532 | $qo['skip'] = $pagination->getOffset(); |
||
533 | $sorts = []; |
||
534 | foreach ($pagination->getOrder() as $k => $v) { |
||
535 | $sorts[$k] = $v ? 1 : -1; |
||
536 | } |
||
537 | if (count($sorts) > 0) { |
||
538 | $qo['sort'] = $sorts; |
||
539 | } |
||
540 | } |
||
541 | if (!$projections->isEmpty()) { |
||
0 ignored issues
–
show
|
|||
542 | $qo['projection'] = $projections; |
||
543 | } |
||
544 | $q = new \MongoDB\Driver\Query($criteria, $qo); |
||
545 | return $m->executeQuery($c, $q, $this->readPreference); |
||
546 | }); |
||
547 | return $total === null ? $results : new CursorSubset($results, $total); |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * Possibly add the entity to the cache. |
||
552 | * |
||
553 | * @param $entity - The entity to possibly cache |
||
554 | * @return - The same entity that came in |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
555 | */ |
||
556 | protected function maybeCache($entity) |
||
557 | { |
||
558 | if ($this->caching && $entity !== null) { |
||
559 | $id = (string) Getter::getId($entity); |
||
560 | if (!array_key_exists($id, $this->cache)) { |
||
561 | $this->cache[$id] = $entity; |
||
562 | } |
||
563 | } |
||
564 | return $entity; |
||
565 | } |
||
566 | |||
567 | /** |
||
568 | * Possibly add entities to the cache. |
||
569 | * |
||
570 | * @param $entities - The entities to possibly cache |
||
571 | * @return - The same entities that came in |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
572 | */ |
||
573 | protected function maybeCacheAll(iterable $entities): iterable |
||
574 | { |
||
575 | if ($this->caching) { |
||
576 | $results = $entities instanceof \MongoDB\Driver\Cursor ? |
||
0 ignored issues
–
show
The class
MongoDB\Driver\Cursor does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
577 | $entities->toArray() : (is_array($entities) ? $entities : iterator_to_array($entities, false)); |
||
578 | foreach ($results as $entity) { |
||
579 | if ($entity !== null) { |
||
580 | $id = (string) Getter::getId($entity); |
||
581 | if (!array_key_exists($id, $this->cache)) { |
||
582 | $this->cache[$id] = $entity; |
||
583 | } |
||
584 | } |
||
585 | } |
||
586 | return $results; |
||
587 | } else { |
||
588 | return $entities; |
||
589 | } |
||
590 | } |
||
591 | |||
592 | /** |
||
593 | * Gets an entry from the cache |
||
594 | * |
||
595 | * @param $id - The cache key |
||
596 | * @return - The entity found or null |
||
0 ignored issues
–
show
The doc-type
- could not be parsed: Unknown type name "-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
597 | */ |
||
598 | protected function getFromCache(string $id) |
||
599 | { |
||
600 | return $this->cache[$id] ?? null; |
||
601 | } |
||
602 | } |
||
603 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.