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 | |||
3 | /** |
||
4 | * This file is part of the PHPMongo package. |
||
5 | * |
||
6 | * (c) Dmytro Sokil <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Sokil\Mongo; |
||
13 | |||
14 | use Sokil\Mongo\Enum\FieldType; |
||
15 | use GeoJson\Geometry\Geometry; |
||
16 | use GeoJson\Geometry\Point; |
||
17 | use Sokil\Mongo\Type\TypeChecker; |
||
18 | |||
19 | /** |
||
20 | * This class represents all expressions used to query document from collection |
||
21 | * |
||
22 | * @link http://docs.mongodb.org/manual/reference/operator/query/ |
||
23 | * @author Dmytro Sokil <[email protected]> |
||
24 | */ |
||
25 | class Expression implements ArrayableInterface |
||
26 | { |
||
27 | /** |
||
28 | * @deprecated Since 1.22 using this property is NOT ALLOWED. Use getters and setters instead. |
||
29 | * @var array |
||
30 | */ |
||
31 | protected $_expression = array(); |
||
32 | |||
33 | /** |
||
34 | * Create new instance of expression |
||
35 | * @return Expression |
||
36 | */ |
||
37 | public function expression() |
||
38 | { |
||
39 | return new self; |
||
40 | } |
||
41 | /** |
||
42 | * @param string $field |
||
43 | * @param string|array $value |
||
44 | * |
||
45 | * @return Expression |
||
46 | */ |
||
47 | public function where($field, $value) |
||
48 | { |
||
49 | if (!isset($this->_expression[$field]) || !is_array($value) || !is_array($this->_expression[$field])) { |
||
50 | $this->_expression[$field] = $value; |
||
51 | } else { |
||
52 | $this->_expression[$field] = array_merge_recursive($this->_expression[$field], $value); |
||
53 | } |
||
54 | |||
55 | return $this; |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Filter empty field |
||
60 | * |
||
61 | * @param string $field |
||
62 | * |
||
63 | * @return Expression |
||
64 | */ |
||
65 | View Code Duplication | public function whereEmpty($field) |
|
0 ignored issues
–
show
|
|||
66 | { |
||
67 | return $this->where( |
||
68 | '$or', |
||
69 | array( |
||
70 | array($field => null), |
||
71 | array($field => ''), |
||
72 | array($field => array()), |
||
73 | array($field => array('$exists' => false)) |
||
74 | ) |
||
75 | ); |
||
76 | } |
||
77 | |||
78 | View Code Duplication | public function whereNotEmpty($field) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
79 | { |
||
80 | return $this->where('$nor', array( |
||
81 | array($field => null), |
||
82 | array($field => ''), |
||
83 | array($field => array()), |
||
84 | array($field => array('$exists' => false)) |
||
85 | )); |
||
86 | } |
||
87 | |||
88 | public function whereGreater($field, $value) |
||
89 | { |
||
90 | return $this->where($field, array('$gt' => $value)); |
||
91 | } |
||
92 | |||
93 | public function whereGreaterOrEqual($field, $value) |
||
94 | { |
||
95 | return $this->where($field, array('$gte' => $value)); |
||
96 | } |
||
97 | |||
98 | public function whereLess($field, $value) |
||
99 | { |
||
100 | return $this->where($field, array('$lt' => $value)); |
||
101 | } |
||
102 | |||
103 | public function whereLessOrEqual($field, $value) |
||
104 | { |
||
105 | return $this->where($field, array('$lte' => $value)); |
||
106 | } |
||
107 | |||
108 | public function whereNotEqual($field, $value) |
||
109 | { |
||
110 | return $this->where($field, array('$ne' => $value)); |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * Selects the documents where the value of a |
||
115 | * field equals any value in the specified array. |
||
116 | * |
||
117 | * @param string $field |
||
118 | * @param array $values |
||
119 | * @return Expression |
||
120 | */ |
||
121 | public function whereIn($field, array $values) |
||
122 | { |
||
123 | return $this->where($field, array('$in' => $values)); |
||
124 | } |
||
125 | |||
126 | public function whereNotIn($field, array $values) |
||
127 | { |
||
128 | return $this->where($field, array('$nin' => $values)); |
||
129 | } |
||
130 | |||
131 | public function whereExists($field) |
||
132 | { |
||
133 | return $this->where($field, array('$exists' => true)); |
||
134 | } |
||
135 | |||
136 | public function whereNotExists($field) |
||
137 | { |
||
138 | return $this->where($field, array('$exists' => false)); |
||
139 | } |
||
140 | |||
141 | public function whereHasType($field, $type) |
||
142 | { |
||
143 | return $this->where($field, array('$type' => (int) $type)); |
||
144 | } |
||
145 | |||
146 | public function whereDouble($field) |
||
147 | { |
||
148 | return $this->whereHasType($field, FieldType::DOUBLE); |
||
149 | } |
||
150 | |||
151 | public function whereString($field) |
||
152 | { |
||
153 | return $this->whereHasType($field, FieldType::STRING); |
||
154 | } |
||
155 | |||
156 | public function whereObject($field) |
||
157 | { |
||
158 | return $this->whereHasType($field, FieldType::OBJECT); |
||
159 | } |
||
160 | |||
161 | public function whereBoolean($field) |
||
162 | { |
||
163 | return $this->whereHasType($field, FieldType::BOOLEAN); |
||
164 | } |
||
165 | |||
166 | public function whereArray($field) |
||
167 | { |
||
168 | return $this->whereJsCondition('Array.isArray(this.' . $field . ')'); |
||
169 | } |
||
170 | |||
171 | public function whereArrayOfArrays($field) |
||
172 | { |
||
173 | return $this->whereHasType($field, FieldType::ARRAY_TYPE); |
||
174 | } |
||
175 | |||
176 | public function whereObjectId($field) |
||
177 | { |
||
178 | return $this->whereHasType($field, FieldType::OBJECT_ID); |
||
179 | } |
||
180 | |||
181 | public function whereDate($field) |
||
182 | { |
||
183 | return $this->whereHasType($field, FieldType::DATE); |
||
184 | } |
||
185 | |||
186 | public function whereNull($field) |
||
187 | { |
||
188 | return $this->whereHasType($field, FieldType::NULL); |
||
189 | } |
||
190 | |||
191 | public function whereJsCondition($condition) |
||
192 | { |
||
193 | return $this->where('$where', $condition); |
||
194 | } |
||
195 | |||
196 | public function whereLike($field, $regex, $caseInsensitive = true) |
||
197 | { |
||
198 | // regex |
||
199 | $expression = array( |
||
200 | '$regex' => $regex, |
||
201 | ); |
||
202 | |||
203 | // options |
||
204 | $options = ''; |
||
205 | |||
206 | if ($caseInsensitive) { |
||
207 | $options .= 'i'; |
||
208 | } |
||
209 | |||
210 | $expression['$options'] = $options; |
||
211 | |||
212 | // query |
||
213 | return $this->where($field, $expression); |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Find documents where the value of a field is an array |
||
218 | * that contains all the specified elements. |
||
219 | * This is equivalent of logical AND. |
||
220 | * |
||
221 | * @link http://docs.mongodb.org/manual/reference/operator/query/all/ |
||
222 | * |
||
223 | * @param string $field point-delimited field name |
||
224 | * @param array $values |
||
225 | * @return Expression |
||
226 | */ |
||
227 | public function whereAll($field, array $values) |
||
228 | { |
||
229 | return $this->where($field, array('$all' => $values)); |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Find documents where the value of a field is an array |
||
234 | * that contains none of the specified elements. |
||
235 | * This is equivalent of logical AND. |
||
236 | * |
||
237 | * @link http://docs.mongodb.org/manual/reference/operator/query/all/ |
||
238 | * |
||
239 | * @param string $field point-delimited field name |
||
240 | * @param array $values |
||
241 | * @return Expression |
||
242 | */ |
||
243 | public function whereNoneOf($field, array $values) |
||
244 | { |
||
245 | return $this->where($field, array( |
||
246 | '$not' => array( |
||
247 | '$all' => $values |
||
248 | ), |
||
249 | )); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Find documents where the value of a field is an array |
||
254 | * that contains any of the specified elements. |
||
255 | * This is equivalent of logical AND. |
||
256 | * |
||
257 | * @param string $field point-delimited field name |
||
258 | * @param array $values |
||
259 | * @return Expression |
||
260 | */ |
||
261 | public function whereAny($field, array $values) |
||
262 | { |
||
263 | return $this->whereIn($field, $values); |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Matches documents in a collection that contain an array field with at |
||
268 | * least one element that matches all the specified query criteria. |
||
269 | * |
||
270 | * @param string $field point-delimited field name |
||
271 | * @param \Sokil\Mongo\Expression|callable|array $expression |
||
272 | * |
||
273 | * @return Expression |
||
274 | * |
||
275 | * @throws Exception |
||
276 | */ |
||
277 | public function whereElemMatch($field, $expression) |
||
278 | { |
||
279 | if (is_callable($expression)) { |
||
280 | $expression = call_user_func($expression, $this->expression()); |
||
281 | } |
||
282 | |||
283 | View Code Duplication | if ($expression instanceof Expression) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
284 | $expression = $expression->toArray(); |
||
285 | } elseif (!is_array($expression)) { |
||
286 | throw new Exception('Wrong expression passed'); |
||
287 | } |
||
288 | |||
289 | return $this->where($field, array('$elemMatch' => $expression)); |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Matches documents in a collection that contain an array field with elements |
||
294 | * that do not matches all the specified query criteria. |
||
295 | * |
||
296 | * @param string $field |
||
297 | * @param Expression|callable|array $expression |
||
298 | * |
||
299 | * @return Expression |
||
300 | */ |
||
301 | public function whereElemNotMatch($field, $expression) |
||
302 | { |
||
303 | return $this->whereNot($this->expression()->whereElemMatch($field, $expression)); |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Selects documents if the array field is a specified size. |
||
308 | * |
||
309 | * @param string $field |
||
310 | * @param integer $length |
||
311 | * @return Expression |
||
312 | */ |
||
313 | public function whereArraySize($field, $length) |
||
314 | { |
||
315 | return $this->where($field, array('$size' => (int) $length)); |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Selects the documents that satisfy at least one of the expressions |
||
320 | * |
||
321 | * @param array|\Sokil\Mongo\Expression $expressions Array of Expression instances or comma delimited expression list |
||
322 | * |
||
323 | * @return Expression |
||
324 | */ |
||
325 | View Code Duplication | public function whereOr($expressions = null /**, ...**/) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
326 | { |
||
327 | if ($expressions instanceof Expression) { |
||
328 | $expressions = func_get_args(); |
||
329 | } |
||
330 | |||
331 | return $this->where('$or', array_map(function (Expression $expression) { |
||
332 | return $expression->toArray(); |
||
333 | }, $expressions)); |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * Select the documents that satisfy all the expressions in the array |
||
338 | * |
||
339 | * @param array|\Sokil\Mongo\Expression $expressions Array of Expression instances or comma delimited expression list |
||
340 | * @return Expression |
||
341 | */ |
||
342 | View Code Duplication | public function whereAnd($expressions = null /**, ...**/) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
343 | { |
||
344 | if ($expressions instanceof Expression) { |
||
345 | $expressions = func_get_args(); |
||
346 | } |
||
347 | |||
348 | return $this->where('$and', array_map(function (Expression $expression) { |
||
349 | return $expression->toArray(); |
||
350 | }, $expressions)); |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * Selects the documents that fail all the query expressions in the array |
||
355 | * |
||
356 | * @param array|\Sokil\Mongo\Expression $expressions Array of Expression instances or comma delimited expression list |
||
357 | * @return Expression |
||
358 | */ |
||
359 | View Code Duplication | public function whereNor($expressions = null /**, ...**/) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
360 | { |
||
361 | if ($expressions instanceof Expression) { |
||
362 | $expressions = func_get_args(); |
||
363 | } |
||
364 | |||
365 | return $this->where( |
||
366 | '$nor', |
||
367 | array_map( |
||
368 | function (Expression $expression) { |
||
369 | return $expression->toArray(); |
||
370 | }, |
||
371 | $expressions |
||
372 | ) |
||
373 | ); |
||
374 | } |
||
375 | |||
376 | public function whereNot(Expression $expression) |
||
377 | { |
||
378 | foreach ($expression->toArray() as $field => $value) { |
||
379 | if (TypeChecker::isExpression($value) || TypeChecker::isRegex($value)) { |
||
380 | // $not acceptable only for operators-expressions or regexps |
||
381 | $this->where($field, array('$not' => $value)); |
||
382 | } else { |
||
383 | // for single values use $ne |
||
384 | $this->whereNotEqual($field, $value); |
||
385 | } |
||
386 | } |
||
387 | |||
388 | return $this; |
||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Select documents where the value of a field divided by a divisor has the specified remainder (i.e. perform a modulo operation to select documents) |
||
393 | * |
||
394 | * @param string $field |
||
395 | * @param int $divisor |
||
396 | * @param int $remainder |
||
397 | */ |
||
398 | public function whereMod($field, $divisor, $remainder) |
||
399 | { |
||
400 | $this->where($field, array( |
||
401 | '$mod' => array((int) $divisor, (int) $remainder), |
||
402 | )); |
||
403 | |||
404 | return $this; |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * Perform fulltext search |
||
409 | * |
||
410 | * @link https://docs.mongodb.org/manual/reference/operator/query/text/ |
||
411 | * @link https://docs.mongodb.org/manual/tutorial/specify-language-for-text-index/ |
||
412 | * |
||
413 | * If a collection contains documents or embedded documents that are in different languages, |
||
414 | * include a field named language in the documents or embedded documents and specify as its value the language |
||
415 | * for that document or embedded document. |
||
416 | * |
||
417 | * The specified language in the document overrides the default language for the text index. |
||
418 | * The specified language in an embedded document override the language specified in an enclosing document or |
||
419 | * the default language for the index. |
||
420 | * |
||
421 | * Case Insensitivity: |
||
422 | * @link https://docs.mongodb.org/manual/reference/operator/query/text/#text-operator-case-sensitivity |
||
423 | * |
||
424 | * Diacritic Insensitivity: |
||
425 | * @link https://docs.mongodb.org/manual/reference/operator/query/text/#text-operator-diacritic-sensitivity |
||
426 | * |
||
427 | * @param $search A string of terms that MongoDB parses and uses to query the text index. MongoDB performs a |
||
428 | * logical OR search of the terms unless specified as a phrase. |
||
429 | * @param $language Optional. The language that determines the list of stop words for the search and the |
||
430 | * rules for the stemmer and tokenizer. If not specified, the search uses the default language of the index. |
||
431 | * If you specify a language value of "none", then the text search uses simple tokenization |
||
432 | * with no list of stop words and no stemming. |
||
433 | * @param bool|false $caseSensitive Allowed from v.3.2 A boolean flag to enable or disable case |
||
434 | * sensitive search. Defaults to false; i.e. the search defers to the case insensitivity of the text index. |
||
435 | * @param bool|false $diacriticSensitive Allowed from v.3.2 A boolean flag to enable or disable diacritic |
||
436 | * sensitive search against version 3 text indexes. Defaults to false; i.e. the search defers to the diacritic |
||
437 | * insensitivity of the text index. Text searches against earlier versions of the text index are inherently |
||
438 | * diacritic sensitive and cannot be diacritic insensitive. As such, the $diacriticSensitive option has no |
||
439 | * effect with earlier versions of the text index. |
||
440 | * @return $this |
||
441 | */ |
||
442 | public function whereText( |
||
443 | $search, |
||
444 | $language = null, |
||
445 | $caseSensitive = null, |
||
446 | $diacriticSensitive = null |
||
447 | ) { |
||
448 | $this->_expression['$text'] = array( |
||
449 | '$search' => $search, |
||
450 | ); |
||
451 | |||
452 | if ($language) { |
||
453 | $this->_expression['$text']['$language'] = $language; |
||
454 | } |
||
455 | |||
456 | // Version 3.2 feature |
||
457 | if ($caseSensitive) { |
||
458 | $this->_expression['$text']['$caseSensitive'] = (bool) $caseSensitive; |
||
459 | } |
||
460 | |||
461 | // Version 3.2 feature |
||
462 | if ($diacriticSensitive) { |
||
463 | $this->_expression['$text']['$diacriticSensitive'] = (bool) $diacriticSensitive; |
||
464 | } |
||
465 | |||
466 | return $this; |
||
467 | } |
||
468 | |||
469 | /** |
||
470 | * Find document near points in flat surface |
||
471 | * |
||
472 | * @param string $field |
||
473 | * @param float $longitude |
||
474 | * @param float $latitude |
||
475 | * @param int|array $distance distance from point in meters. Array distance |
||
476 | * allowed only in MongoDB 2.6 |
||
477 | * @return Expression |
||
478 | */ |
||
479 | View Code Duplication | public function nearPoint($field, $longitude, $latitude, $distance) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
480 | { |
||
481 | $point = new \GeoJson\Geometry\Point(array( |
||
482 | (float) $longitude, |
||
483 | (float) $latitude |
||
484 | )); |
||
485 | |||
486 | $near = array( |
||
487 | '$geometry' => $point->jsonSerialize(), |
||
488 | ); |
||
489 | |||
490 | if (is_array($distance)) { |
||
491 | if (!empty($distance[0])) { |
||
492 | $near['$minDistance'] = (int) $distance[0]; |
||
493 | } |
||
494 | if (!empty($distance[1])) { |
||
495 | $near['$maxDistance'] = (int) $distance[1]; |
||
496 | } |
||
497 | } else { |
||
498 | $near['$maxDistance'] = (int) $distance; |
||
499 | } |
||
500 | |||
501 | $this->where($field, array('$near' => $near)); |
||
502 | |||
503 | return $this; |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Find document near points in spherical surface |
||
508 | * |
||
509 | * @param string $field |
||
510 | * @param float $longitude |
||
511 | * @param float $latitude |
||
512 | * @param int|array $distance distance from point in meters. Array distance |
||
513 | * allowed only in MongoDB 2.6 |
||
514 | * @return Expression |
||
515 | */ |
||
516 | View Code Duplication | public function nearPointSpherical($field, $longitude, $latitude, $distance) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
517 | { |
||
518 | $point = new Point(array( |
||
519 | (float) $longitude, |
||
520 | (float) $latitude |
||
521 | )); |
||
522 | |||
523 | $near = array( |
||
524 | '$geometry' => $point->jsonSerialize(), |
||
525 | ); |
||
526 | |||
527 | if (is_array($distance)) { |
||
528 | if (!empty($distance[0])) { |
||
529 | $near['$minDistance'] = (int) $distance[0]; |
||
530 | } |
||
531 | if (!empty($distance[1])) { |
||
532 | $near['$maxDistance'] = (int) $distance[1]; |
||
533 | } |
||
534 | } else { |
||
535 | $near['$maxDistance'] = (int) $distance; |
||
536 | } |
||
537 | |||
538 | $this->where($field, array('$nearSphere' => $near)); |
||
539 | |||
540 | return $this; |
||
541 | } |
||
542 | |||
543 | /** |
||
544 | * Selects documents whose geospatial data intersects with a specified |
||
545 | * GeoJSON object; i.e. where the intersection of the data and the |
||
546 | * specified object is non-empty. This includes cases where the data |
||
547 | * and the specified object share an edge. Uses spherical geometry. |
||
548 | * |
||
549 | * @link http://docs.mongodb.org/manual/reference/operator/query/geoIntersects/ |
||
550 | * |
||
551 | * @param string $field |
||
552 | * @param Geometry $geometry |
||
553 | * @return Expression |
||
554 | */ |
||
555 | public function intersects($field, Geometry $geometry) |
||
556 | { |
||
557 | $this->where($field, array( |
||
558 | '$geoIntersects' => array( |
||
559 | '$geometry' => $geometry->jsonSerialize(), |
||
560 | ), |
||
561 | )); |
||
562 | |||
563 | return $this; |
||
564 | } |
||
565 | |||
566 | /** |
||
567 | * Selects documents with geospatial data that exists entirely within a specified shape. |
||
568 | * |
||
569 | * @link http://docs.mongodb.org/manual/reference/operator/query/geoWithin/ |
||
570 | * @param string $field |
||
571 | * @param Geometry $geometry |
||
572 | * @return Expression |
||
573 | */ |
||
574 | public function within($field, Geometry $geometry) |
||
575 | { |
||
576 | $this->where($field, array( |
||
577 | '$geoWithin' => array( |
||
578 | '$geometry' => $geometry->jsonSerialize(), |
||
579 | ), |
||
580 | )); |
||
581 | |||
582 | return $this; |
||
583 | } |
||
584 | |||
585 | /** |
||
586 | * Select documents with geospatial data within circle defined |
||
587 | * by center point and radius in flat surface |
||
588 | * |
||
589 | * @param string $field |
||
590 | * @param float $longitude |
||
591 | * @param float $latitude |
||
592 | * @param float $radius |
||
593 | * @return Expression |
||
594 | */ |
||
595 | public function withinCircle($field, $longitude, $latitude, $radius) |
||
596 | { |
||
597 | $this->where($field, array( |
||
598 | '$geoWithin' => array( |
||
599 | '$center' => array( |
||
600 | array($longitude, $latitude), |
||
601 | $radius, |
||
602 | ), |
||
603 | ), |
||
604 | )); |
||
605 | |||
606 | return $this; |
||
607 | } |
||
608 | |||
609 | /** |
||
610 | * Select documents with geospatial data within circle defined |
||
611 | * by center point and radius in spherical surface |
||
612 | * |
||
613 | * To calculate distance in radians |
||
614 | * @see http://docs.mongodb.org/manual/tutorial/calculate-distances-using-spherical-geometry-with-2d-geospatial-indexes/ |
||
615 | * |
||
616 | * @param string $field |
||
617 | * @param float $longitude |
||
618 | * @param float $latitude |
||
619 | * @param float $radiusInRadians in radians. |
||
620 | * @return Expression |
||
621 | */ |
||
622 | public function withinCircleSpherical($field, $longitude, $latitude, $radiusInRadians) |
||
623 | { |
||
624 | $this->where($field, array( |
||
625 | '$geoWithin' => array( |
||
626 | '$centerSphere' => array( |
||
627 | array($longitude, $latitude), |
||
628 | $radiusInRadians, |
||
629 | ), |
||
630 | ), |
||
631 | )); |
||
632 | |||
633 | return $this; |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Return documents that are within the bounds of the rectangle, according |
||
638 | * to their point-based location data. |
||
639 | * |
||
640 | * Based on grid coordinates and does not query for GeoJSON shapes. |
||
641 | * |
||
642 | * Use planar geometry, so 2d index may be used but not required |
||
643 | * |
||
644 | * @param string $field |
||
645 | * @param array $bottomLeftCoordinate Bottom left coordinate of box |
||
646 | * @param array $upperRightCoordinate Upper right coordinate of box |
||
647 | * @return Expression |
||
648 | */ |
||
649 | public function withinBox($field, array $bottomLeftCoordinate, array $upperRightCoordinate) |
||
650 | { |
||
651 | $this->where($field, array( |
||
652 | '$geoWithin' => array( |
||
653 | '$box' => array( |
||
654 | $bottomLeftCoordinate, |
||
655 | $upperRightCoordinate, |
||
656 | ), |
||
657 | ), |
||
658 | )); |
||
659 | |||
660 | return $this; |
||
661 | } |
||
662 | |||
663 | /** |
||
664 | * Return documents that are within the polygon, according |
||
665 | * to their point-based location data. |
||
666 | * |
||
667 | * Based on grid coordinates and does not query for GeoJSON shapes. |
||
668 | * |
||
669 | * Use planar geometry, so 2d index may be used but not required |
||
670 | * |
||
671 | * @param string $field |
||
672 | * @param array $points array of coordinates |
||
673 | * @return Expression |
||
674 | */ |
||
675 | public function withinPolygon($field, array $points) |
||
676 | { |
||
677 | $this->where($field, array( |
||
678 | '$geoWithin' => array( |
||
679 | '$polygon' => $points, |
||
680 | ), |
||
681 | )); |
||
682 | |||
683 | return $this; |
||
684 | } |
||
685 | |||
686 | public function toArray() |
||
687 | { |
||
688 | return $this->_expression; |
||
689 | } |
||
690 | |||
691 | public function merge(Expression $expression) |
||
692 | { |
||
693 | $this->_expression = array_merge_recursive($this->_expression, $expression->toArray()); |
||
694 | return $this; |
||
695 | } |
||
696 | |||
697 | /** |
||
698 | * Transform expression in different formats to canonical array form |
||
699 | * |
||
700 | * @param callable|array|Expression $mixed |
||
701 | * |
||
702 | * @return array |
||
703 | * |
||
704 | * @throws \Sokil\Mongo\Exception |
||
705 | */ |
||
706 | public static function convertToArray($mixed) |
||
707 | { |
||
708 | // get expression from callable |
||
709 | if (is_callable($mixed)) { |
||
710 | $callable = $mixed; |
||
711 | $mixed = new self(); |
||
712 | call_user_func($callable, $mixed); |
||
713 | } |
||
714 | |||
715 | // get expression array |
||
716 | if ($mixed instanceof ArrayableInterface && $mixed instanceof self) { |
||
717 | $mixed = $mixed->toArray(); |
||
718 | } elseif (!is_array($mixed)) { |
||
719 | throw new Exception(sprintf( |
||
720 | 'Mixed must be instance of "\Sokil\Mongo\Expression", array or callable that accepts "\Sokil\Mongo\Expression", "%s" given', |
||
721 | gettype($mixed) === "object" ? get_class($mixed) : gettype($mixed) |
||
722 | )); |
||
723 | } |
||
724 | |||
725 | return $mixed; |
||
726 | } |
||
727 | } |
||
728 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.