Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Query often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Query, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
70 | class Query extends DatabaseQuery implements JsonSerializable, QueryInterface |
||
71 | { |
||
72 | use QueryTrait { |
||
73 | cache as private _cache; |
||
74 | all as private _all; |
||
75 | _decorateResults as private _applyDecorators; |
||
76 | __call as private _call; |
||
77 | } |
||
78 | |||
79 | /** |
||
80 | * Indicates that the operation should append to the list |
||
81 | * |
||
82 | * @var int |
||
83 | */ |
||
84 | const APPEND = 0; |
||
85 | |||
86 | /** |
||
87 | * Indicates that the operation should prepend to the list |
||
88 | * |
||
89 | * @var int |
||
90 | */ |
||
91 | const PREPEND = 1; |
||
92 | |||
93 | /** |
||
94 | * Indicates that the operation should overwrite the list |
||
95 | * |
||
96 | * @var bool |
||
97 | */ |
||
98 | const OVERWRITE = true; |
||
99 | |||
100 | /** |
||
101 | * Whether the user select any fields before being executed, this is used |
||
102 | * to determined if any fields should be automatically be selected. |
||
103 | * |
||
104 | * @var bool|null |
||
105 | */ |
||
106 | protected $_hasFields; |
||
107 | |||
108 | /** |
||
109 | * Tracks whether or not the original query should include |
||
110 | * fields from the top level table. |
||
111 | * |
||
112 | * @var bool|null |
||
113 | */ |
||
114 | protected $_autoFields; |
||
115 | |||
116 | /** |
||
117 | * Whether to hydrate results into entity objects |
||
118 | * |
||
119 | * @var bool |
||
120 | */ |
||
121 | protected $_hydrate = true; |
||
122 | |||
123 | /** |
||
124 | * A callable function that can be used to calculate the total amount of |
||
125 | * records this query will match when not using `limit` |
||
126 | * |
||
127 | * @var callable|null |
||
128 | */ |
||
129 | protected $_counter; |
||
130 | |||
131 | /** |
||
132 | * Instance of a class responsible for storing association containments and |
||
133 | * for eager loading them when this query is executed |
||
134 | * |
||
135 | * @var \Cake\ORM\EagerLoader|null |
||
136 | */ |
||
137 | protected $_eagerLoader; |
||
138 | |||
139 | /** |
||
140 | * True if the beforeFind event has already been triggered for this query |
||
141 | * |
||
142 | * @var bool |
||
143 | */ |
||
144 | protected $_beforeFindFired = false; |
||
145 | |||
146 | /** |
||
147 | * The COUNT(*) for the query. |
||
148 | * |
||
149 | * When set, count query execution will be bypassed. |
||
150 | * |
||
151 | * @var int|null |
||
152 | */ |
||
153 | protected $_resultsCount; |
||
154 | |||
155 | /** |
||
156 | * Constructor |
||
157 | * |
||
158 | * @param \Cake\Database\Connection $connection The connection object |
||
159 | * @param \Cake\ORM\Table $table The table this query is starting on |
||
160 | */ |
||
161 | public function __construct($connection, $table) |
||
170 | |||
171 | /** |
||
172 | * Adds new fields to be returned by a `SELECT` statement when this query is |
||
173 | * executed. Fields can be passed as an array of strings, array of expression |
||
174 | * objects, a single expression or a single string. |
||
175 | * |
||
176 | * If an array is passed, keys will be used to alias fields using the value as the |
||
177 | * real field to be aliased. It is possible to alias strings, Expression objects or |
||
178 | * even other Query objects. |
||
179 | * |
||
180 | * If a callable function is passed, the returning array of the function will |
||
181 | * be used as the list of fields. |
||
182 | * |
||
183 | * By default this function will append any passed argument to the list of fields |
||
184 | * to be selected, unless the second argument is set to true. |
||
185 | * |
||
186 | * ### Examples: |
||
187 | * |
||
188 | * ``` |
||
189 | * $query->select(['id', 'title']); // Produces SELECT id, title |
||
190 | * $query->select(['author' => 'author_id']); // Appends author: SELECT id, title, author_id as author |
||
191 | * $query->select('id', true); // Resets the list: SELECT id |
||
192 | * $query->select(['total' => $countQuery]); // SELECT id, (SELECT ...) AS total |
||
193 | * $query->select(function ($query) { |
||
194 | * return ['article_id', 'total' => $query->count('*')]; |
||
195 | * }) |
||
196 | * ``` |
||
197 | * |
||
198 | * By default no fields are selected, if you have an instance of `Cake\ORM\Query` and try to append |
||
199 | * fields you should also call `Cake\ORM\Query::enableAutoFields()` to select the default fields |
||
200 | * from the table. |
||
201 | * |
||
202 | * If you pass an instance of a `Cake\ORM\Table` or `Cake\ORM\Association` class, |
||
203 | * all the fields in the schema of the table or the association will be added to |
||
204 | * the select clause. |
||
205 | * |
||
206 | * @param array|\Cake\Database\ExpressionInterface|callable|string|\Cake\ORM\Table|\Cake\ORM\Association $fields fields |
||
207 | * to be added to the list. |
||
208 | * @param bool $overwrite whether to reset fields with passed list or not |
||
209 | * @return $this |
||
210 | */ |
||
211 | public function select($fields = [], $overwrite = false) |
||
223 | |||
224 | /** |
||
225 | * All the fields associated with the passed table except the excluded |
||
226 | * fields will be added to the select clause of the query. Passed excluded fields should not be aliased. |
||
227 | * After the first call to this method, a second call cannot be used to remove fields that have already |
||
228 | * been added to the query by the first. If you need to change the list after the first call, |
||
229 | * pass overwrite boolean true which will reset the select clause removing all previous additions. |
||
230 | * |
||
231 | * |
||
232 | * |
||
233 | * @param \Cake\ORM\Table|\Cake\ORM\Association $table The table to use to get an array of columns |
||
234 | * @param string[] $excludedFields The un-aliased column names you do not want selected from $table |
||
235 | * @param bool $overwrite Whether to reset/remove previous selected fields |
||
236 | * @return Query |
||
237 | * @throws \InvalidArgumentException If Association|Table is not passed in first argument |
||
238 | */ |
||
239 | public function selectAllExcept($table, array $excludedFields, $overwrite = false) |
||
254 | |||
255 | /** |
||
256 | * Hints this object to associate the correct types when casting conditions |
||
257 | * for the database. This is done by extracting the field types from the schema |
||
258 | * associated to the passed table object. This prevents the user from repeating |
||
259 | * themselves when specifying conditions. |
||
260 | * |
||
261 | * This method returns the same query object for chaining. |
||
262 | * |
||
263 | * @param \Cake\ORM\Table $table The table to pull types from |
||
264 | * @return $this |
||
265 | */ |
||
266 | public function addDefaultTypes(Table $table) |
||
278 | |||
279 | /** |
||
280 | * Sets the instance of the eager loader class to use for loading associations |
||
281 | * and storing containments. |
||
282 | * |
||
283 | * @param \Cake\ORM\EagerLoader $instance The eager loader to use. |
||
284 | * @return $this |
||
285 | */ |
||
286 | public function setEagerLoader(EagerLoader $instance) |
||
292 | |||
293 | /** |
||
294 | * Returns the currently configured instance. |
||
295 | * |
||
296 | * @return \Cake\ORM\EagerLoader |
||
297 | */ |
||
298 | public function getEagerLoader() |
||
306 | |||
307 | /** |
||
308 | * Sets the instance of the eager loader class to use for loading associations |
||
309 | * and storing containments. If called with no arguments, it will return the |
||
310 | * currently configured instance. |
||
311 | * |
||
312 | * @deprecated 3.4.0 Use setEagerLoader()/getEagerLoader() instead. |
||
313 | * @param \Cake\ORM\EagerLoader|null $instance The eager loader to use. Pass null |
||
314 | * to get the current eagerloader. |
||
315 | * @return \Cake\ORM\EagerLoader|$this |
||
316 | */ |
||
317 | public function eagerLoader(EagerLoader $instance = null) |
||
329 | |||
330 | /** |
||
331 | * Sets the list of associations that should be eagerly loaded along with this |
||
332 | * query. The list of associated tables passed must have been previously set as |
||
333 | * associations using the Table API. |
||
334 | * |
||
335 | * ### Example: |
||
336 | * |
||
337 | * ``` |
||
338 | * // Bring articles' author information |
||
339 | * $query->contain('Author'); |
||
340 | * |
||
341 | * // Also bring the category and tags associated to each article |
||
342 | * $query->contain(['Category', 'Tag']); |
||
343 | * ``` |
||
344 | * |
||
345 | * Associations can be arbitrarily nested using dot notation or nested arrays, |
||
346 | * this allows this object to calculate joins or any additional queries that |
||
347 | * must be executed to bring the required associated data. |
||
348 | * |
||
349 | * ### Example: |
||
350 | * |
||
351 | * ``` |
||
352 | * // Eager load the product info, and for each product load other 2 associations |
||
353 | * $query->contain(['Product' => ['Manufacturer', 'Distributor']); |
||
354 | * |
||
355 | * // Which is equivalent to calling |
||
356 | * $query->contain(['Products.Manufactures', 'Products.Distributors']); |
||
357 | * |
||
358 | * // For an author query, load his region, state and country |
||
359 | * $query->contain('Regions.States.Countries'); |
||
360 | * ``` |
||
361 | * |
||
362 | * It is possible to control the conditions and fields selected for each of the |
||
363 | * contained associations: |
||
364 | * |
||
365 | * ### Example: |
||
366 | * |
||
367 | * ``` |
||
368 | * $query->contain(['Tags' => function ($q) { |
||
369 | * return $q->where(['Tags.is_popular' => true]); |
||
370 | * }]); |
||
371 | * |
||
372 | * $query->contain(['Products.Manufactures' => function ($q) { |
||
373 | * return $q->select(['name'])->where(['Manufactures.active' => true]); |
||
374 | * }]); |
||
375 | * ``` |
||
376 | * |
||
377 | * Each association might define special options when eager loaded, the allowed |
||
378 | * options that can be set per association are: |
||
379 | * |
||
380 | * - `foreignKey`: Used to set a different field to match both tables, if set to false |
||
381 | * no join conditions will be generated automatically. `false` can only be used on |
||
382 | * joinable associations and cannot be used with hasMany or belongsToMany associations. |
||
383 | * - `fields`: An array with the fields that should be fetched from the association. |
||
384 | * - `finder`: The finder to use when loading associated records. Either the name of the |
||
385 | * finder as a string, or an array to define options to pass to the finder. |
||
386 | * - `queryBuilder`: Equivalent to passing a callable instead of an options array. |
||
387 | * |
||
388 | * ### Example: |
||
389 | * |
||
390 | * ``` |
||
391 | * // Set options for the hasMany articles that will be eagerly loaded for an author |
||
392 | * $query->contain([ |
||
393 | * 'Articles' => [ |
||
394 | * 'fields' => ['title', 'author_id'] |
||
395 | * ] |
||
396 | * ]); |
||
397 | * ``` |
||
398 | * |
||
399 | * Finders can be configured to use options. |
||
400 | * |
||
401 | * ``` |
||
402 | * // Retrieve translations for the articles, but only those for the `en` and `es` locales |
||
403 | * $query->contain([ |
||
404 | * 'Articles' => [ |
||
405 | * 'finder' => [ |
||
406 | * 'translations' => [ |
||
407 | * 'locales' => ['en', 'es'] |
||
408 | * ] |
||
409 | * ] |
||
410 | * ] |
||
411 | * ]); |
||
412 | * ``` |
||
413 | * |
||
414 | * When containing associations, it is important to include foreign key columns. |
||
415 | * Failing to do so will trigger exceptions. |
||
416 | * |
||
417 | * ``` |
||
418 | * // Use a query builder to add conditions to the containment |
||
419 | * $query->contain('Authors', function ($q) { |
||
420 | * return $q->where(...); // add conditions |
||
421 | * }); |
||
422 | * // Use special join conditions for multiple containments in the same method call |
||
423 | * $query->contain([ |
||
424 | * 'Authors' => [ |
||
425 | * 'foreignKey' => false, |
||
426 | * 'queryBuilder' => function ($q) { |
||
427 | * return $q->where(...); // Add full filtering conditions |
||
428 | * } |
||
429 | * ], |
||
430 | * 'Tags' => function ($q) { |
||
431 | * return $q->where(...); // add conditions |
||
432 | * } |
||
433 | * ]); |
||
434 | * ``` |
||
435 | * |
||
436 | * If called with no arguments, this function will return an array with |
||
437 | * with the list of previously configured associations to be contained in the |
||
438 | * result. This getter part is deprecated as of 3.6.0. Use getContain() instead. |
||
439 | * |
||
440 | * If called with an empty first argument and `$override` is set to true, the |
||
441 | * previous list will be emptied. |
||
442 | * |
||
443 | * @param array|string|null $associations List of table aliases to be queried. |
||
444 | * @param callable|bool $override The query builder for the association, or |
||
445 | * if associations is an array, a bool on whether to override previous list |
||
446 | * with the one passed |
||
447 | * defaults to merging previous list with the new one. |
||
448 | * @return array|$this |
||
449 | */ |
||
450 | public function contain($associations = null, $override = false) |
||
482 | |||
483 | /** |
||
484 | * @return array |
||
485 | */ |
||
486 | public function getContain() |
||
490 | |||
491 | /** |
||
492 | * Clears the contained associations from the current query. |
||
493 | * |
||
494 | * @return $this |
||
495 | */ |
||
496 | public function clearContain() |
||
503 | |||
504 | /** |
||
505 | * Used to recursively add contained association column types to |
||
506 | * the query. |
||
507 | * |
||
508 | * @param \Cake\ORM\Table $table The table instance to pluck associations from. |
||
509 | * @param \Cake\Database\TypeMap $typeMap The typemap to check for columns in. |
||
510 | * This typemap is indirectly mutated via Cake\ORM\Query::addDefaultTypes() |
||
511 | * @param array $associations The nested tree of associations to walk. |
||
512 | * @return void |
||
513 | */ |
||
514 | protected function _addAssociationsToTypeMap($table, $typeMap, $associations) |
||
531 | |||
532 | /** |
||
533 | * Adds filtering conditions to this query to only bring rows that have a relation |
||
534 | * to another from an associated table, based on conditions in the associated table. |
||
535 | * |
||
536 | * This function will add entries in the `contain` graph. |
||
537 | * |
||
538 | * ### Example: |
||
539 | * |
||
540 | * ``` |
||
541 | * // Bring only articles that were tagged with 'cake' |
||
542 | * $query->matching('Tags', function ($q) { |
||
543 | * return $q->where(['name' => 'cake']); |
||
544 | * ); |
||
545 | * ``` |
||
546 | * |
||
547 | * It is possible to filter by deep associations by using dot notation: |
||
548 | * |
||
549 | * ### Example: |
||
550 | * |
||
551 | * ``` |
||
552 | * // Bring only articles that were commented by 'markstory' |
||
553 | * $query->matching('Comments.Users', function ($q) { |
||
554 | * return $q->where(['username' => 'markstory']); |
||
555 | * ); |
||
556 | * ``` |
||
557 | * |
||
558 | * As this function will create `INNER JOIN`, you might want to consider |
||
559 | * calling `distinct` on this query as you might get duplicate rows if |
||
560 | * your conditions don't filter them already. This might be the case, for example, |
||
561 | * of the same user commenting more than once in the same article. |
||
562 | * |
||
563 | * ### Example: |
||
564 | * |
||
565 | * ``` |
||
566 | * // Bring unique articles that were commented by 'markstory' |
||
567 | * $query->distinct(['Articles.id']) |
||
568 | * ->matching('Comments.Users', function ($q) { |
||
569 | * return $q->where(['username' => 'markstory']); |
||
570 | * ); |
||
571 | * ``` |
||
572 | * |
||
573 | * Please note that the query passed to the closure will only accept calling |
||
574 | * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to |
||
575 | * add more complex clauses you can do it directly in the main query. |
||
576 | * |
||
577 | * @param string $assoc The association to filter by |
||
578 | * @param callable|null $builder a function that will receive a pre-made query object |
||
579 | * that can be used to add custom conditions or selecting some fields |
||
580 | * @return $this |
||
581 | */ |
||
582 | public function matching($assoc, callable $builder = null) |
||
590 | |||
591 | /** |
||
592 | * Creates a LEFT JOIN with the passed association table while preserving |
||
593 | * the foreign key matching and the custom conditions that were originally set |
||
594 | * for it. |
||
595 | * |
||
596 | * This function will add entries in the `contain` graph. |
||
597 | * |
||
598 | * ### Example: |
||
599 | * |
||
600 | * ``` |
||
601 | * // Get the count of articles per user |
||
602 | * $usersQuery |
||
603 | * ->select(['total_articles' => $query->func()->count('Articles.id')]) |
||
604 | * ->leftJoinWith('Articles') |
||
605 | * ->group(['Users.id']) |
||
606 | * ->enableAutoFields(true); |
||
607 | * ``` |
||
608 | * |
||
609 | * You can also customize the conditions passed to the LEFT JOIN: |
||
610 | * |
||
611 | * ``` |
||
612 | * // Get the count of articles per user with at least 5 votes |
||
613 | * $usersQuery |
||
614 | * ->select(['total_articles' => $query->func()->count('Articles.id')]) |
||
615 | * ->leftJoinWith('Articles', function ($q) { |
||
616 | * return $q->where(['Articles.votes >=' => 5]); |
||
617 | * }) |
||
618 | * ->group(['Users.id']) |
||
619 | * ->enableAutoFields(true); |
||
620 | * ``` |
||
621 | * |
||
622 | * This will create the following SQL: |
||
623 | * |
||
624 | * ``` |
||
625 | * SELECT COUNT(Articles.id) AS total_articles, Users.* |
||
626 | * FROM users Users |
||
627 | * LEFT JOIN articles Articles ON Articles.user_id = Users.id AND Articles.votes >= 5 |
||
628 | * GROUP BY USers.id |
||
629 | * ``` |
||
630 | * |
||
631 | * It is possible to left join deep associations by using dot notation |
||
632 | * |
||
633 | * ### Example: |
||
634 | * |
||
635 | * ``` |
||
636 | * // Total comments in articles by 'markstory' |
||
637 | * $query |
||
638 | * ->select(['total_comments' => $query->func()->count('Comments.id')]) |
||
639 | * ->leftJoinWith('Comments.Users', function ($q) { |
||
640 | * return $q->where(['username' => 'markstory']); |
||
641 | * ) |
||
642 | * ->group(['Users.id']); |
||
643 | * ``` |
||
644 | * |
||
645 | * Please note that the query passed to the closure will only accept calling |
||
646 | * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to |
||
647 | * add more complex clauses you can do it directly in the main query. |
||
648 | * |
||
649 | * @param string $assoc The association to join with |
||
650 | * @param callable|null $builder a function that will receive a pre-made query object |
||
651 | * that can be used to add custom conditions or selecting some fields |
||
652 | * @return $this |
||
653 | */ |
||
654 | View Code Duplication | public function leftJoinWith($assoc, callable $builder = null) |
|
667 | |||
668 | /** |
||
669 | * Creates an INNER JOIN with the passed association table while preserving |
||
670 | * the foreign key matching and the custom conditions that were originally set |
||
671 | * for it. |
||
672 | * |
||
673 | * This function will add entries in the `contain` graph. |
||
674 | * |
||
675 | * ### Example: |
||
676 | * |
||
677 | * ``` |
||
678 | * // Bring only articles that were tagged with 'cake' |
||
679 | * $query->innerJoinWith('Tags', function ($q) { |
||
680 | * return $q->where(['name' => 'cake']); |
||
681 | * ); |
||
682 | * ``` |
||
683 | * |
||
684 | * This will create the following SQL: |
||
685 | * |
||
686 | * ``` |
||
687 | * SELECT Articles.* |
||
688 | * FROM articles Articles |
||
689 | * INNER JOIN tags Tags ON Tags.name = 'cake' |
||
690 | * INNER JOIN articles_tags ArticlesTags ON ArticlesTags.tag_id = Tags.id |
||
691 | * AND ArticlesTags.articles_id = Articles.id |
||
692 | * ``` |
||
693 | * |
||
694 | * This function works the same as `matching()` with the difference that it |
||
695 | * will select no fields from the association. |
||
696 | * |
||
697 | * @param string $assoc The association to join with |
||
698 | * @param callable|null $builder a function that will receive a pre-made query object |
||
699 | * that can be used to add custom conditions or selecting some fields |
||
700 | * @return $this |
||
701 | * @see \Cake\ORM\Query::matching() |
||
702 | */ |
||
703 | View Code Duplication | public function innerJoinWith($assoc, callable $builder = null) |
|
716 | |||
717 | /** |
||
718 | * Adds filtering conditions to this query to only bring rows that have no match |
||
719 | * to another from an associated table, based on conditions in the associated table. |
||
720 | * |
||
721 | * This function will add entries in the `contain` graph. |
||
722 | * |
||
723 | * ### Example: |
||
724 | * |
||
725 | * ``` |
||
726 | * // Bring only articles that were not tagged with 'cake' |
||
727 | * $query->notMatching('Tags', function ($q) { |
||
728 | * return $q->where(['name' => 'cake']); |
||
729 | * ); |
||
730 | * ``` |
||
731 | * |
||
732 | * It is possible to filter by deep associations by using dot notation: |
||
733 | * |
||
734 | * ### Example: |
||
735 | * |
||
736 | * ``` |
||
737 | * // Bring only articles that weren't commented by 'markstory' |
||
738 | * $query->notMatching('Comments.Users', function ($q) { |
||
739 | * return $q->where(['username' => 'markstory']); |
||
740 | * ); |
||
741 | * ``` |
||
742 | * |
||
743 | * As this function will create a `LEFT JOIN`, you might want to consider |
||
744 | * calling `distinct` on this query as you might get duplicate rows if |
||
745 | * your conditions don't filter them already. This might be the case, for example, |
||
746 | * of the same article having multiple comments. |
||
747 | * |
||
748 | * ### Example: |
||
749 | * |
||
750 | * ``` |
||
751 | * // Bring unique articles that were commented by 'markstory' |
||
752 | * $query->distinct(['Articles.id']) |
||
753 | * ->notMatching('Comments.Users', function ($q) { |
||
754 | * return $q->where(['username' => 'markstory']); |
||
755 | * ); |
||
756 | * ``` |
||
757 | * |
||
758 | * Please note that the query passed to the closure will only accept calling |
||
759 | * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to |
||
760 | * add more complex clauses you can do it directly in the main query. |
||
761 | * |
||
762 | * @param string $assoc The association to filter by |
||
763 | * @param callable|null $builder a function that will receive a pre-made query object |
||
764 | * that can be used to add custom conditions or selecting some fields |
||
765 | * @return $this |
||
766 | */ |
||
767 | View Code Duplication | public function notMatching($assoc, callable $builder = null) |
|
781 | |||
782 | /** |
||
783 | * {@inheritDoc} |
||
784 | * |
||
785 | * Populates or adds parts to current query clauses using an array. |
||
786 | * This is handy for passing all query clauses at once. The option array accepts: |
||
787 | * |
||
788 | * - fields: Maps to the select method |
||
789 | * - conditions: Maps to the where method |
||
790 | * - limit: Maps to the limit method |
||
791 | * - order: Maps to the order method |
||
792 | * - offset: Maps to the offset method |
||
793 | * - group: Maps to the group method |
||
794 | * - having: Maps to the having method |
||
795 | * - contain: Maps to the contain options for eager loading |
||
796 | * - join: Maps to the join method |
||
797 | * - page: Maps to the page method |
||
798 | * |
||
799 | * ### Example: |
||
800 | * |
||
801 | * ``` |
||
802 | * $query->applyOptions([ |
||
803 | * 'fields' => ['id', 'name'], |
||
804 | * 'conditions' => [ |
||
805 | * 'created >=' => '2013-01-01' |
||
806 | * ], |
||
807 | * 'limit' => 10 |
||
808 | * ]); |
||
809 | * ``` |
||
810 | * |
||
811 | * Is equivalent to: |
||
812 | * |
||
813 | * ``` |
||
814 | * $query |
||
815 | * ->select(['id', 'name']) |
||
816 | * ->where(['created >=' => '2013-01-01']) |
||
817 | * ->limit(10) |
||
818 | * ``` |
||
819 | */ |
||
820 | public function applyOptions(array $options) |
||
846 | |||
847 | /** |
||
848 | * Creates a copy of this current query, triggers beforeFind and resets some state. |
||
849 | * |
||
850 | * The following state will be cleared: |
||
851 | * |
||
852 | * - autoFields |
||
853 | * - limit |
||
854 | * - offset |
||
855 | * - map/reduce functions |
||
856 | * - result formatters |
||
857 | * - order |
||
858 | * - containments |
||
859 | * |
||
860 | * This method creates query clones that are useful when working with subqueries. |
||
861 | * |
||
862 | * @return \Cake\ORM\Query |
||
863 | */ |
||
864 | public function cleanCopy() |
||
880 | |||
881 | /** |
||
882 | * Object clone hook. |
||
883 | * |
||
884 | * Destroys the clones inner iterator and clones the value binder, and eagerloader instances. |
||
885 | * |
||
886 | * @return void |
||
887 | */ |
||
888 | public function __clone() |
||
895 | |||
896 | /** |
||
897 | * {@inheritDoc} |
||
898 | * |
||
899 | * Returns the COUNT(*) for the query. If the query has not been |
||
900 | * modified, and the count has already been performed the cached |
||
901 | * value is returned |
||
902 | */ |
||
903 | public function count() |
||
911 | |||
912 | /** |
||
913 | * Performs and returns the COUNT(*) for the query. |
||
914 | * |
||
915 | * @return int |
||
916 | */ |
||
917 | protected function _performCount() |
||
969 | |||
970 | /** |
||
971 | * Registers a callable function that will be executed when the `count` method in |
||
972 | * this query is called. The return value for the function will be set as the |
||
973 | * return value of the `count` method. |
||
974 | * |
||
975 | * This is particularly useful when you need to optimize a query for returning the |
||
976 | * count, for example removing unnecessary joins, removing group by or just return |
||
977 | * an estimated number of rows. |
||
978 | * |
||
979 | * The callback will receive as first argument a clone of this query and not this |
||
980 | * query itself. |
||
981 | * |
||
982 | * If the first param is a null value, the built-in counter function will be called |
||
983 | * instead |
||
984 | * |
||
985 | * @param callable|null $counter The counter value |
||
986 | * @return $this |
||
987 | */ |
||
988 | public function counter($counter) |
||
994 | |||
995 | /** |
||
996 | * Toggle hydrating entities. |
||
997 | * |
||
998 | * If set to false array results will be returned for the query. |
||
999 | * |
||
1000 | * @param bool $enable Use a boolean to set the hydration mode. |
||
1001 | * @return $this |
||
1002 | */ |
||
1003 | public function enableHydration($enable = true) |
||
1010 | |||
1011 | /** |
||
1012 | * Disable hydrating entities. |
||
1013 | * |
||
1014 | * Disabling hydration will cause array results to be returned for the query |
||
1015 | * instead of entities. |
||
1016 | * |
||
1017 | * @return $this |
||
1018 | */ |
||
1019 | public function disableHydration() |
||
1026 | |||
1027 | /** |
||
1028 | * Returns the current hydration mode. |
||
1029 | * |
||
1030 | * @return bool |
||
1031 | */ |
||
1032 | public function isHydrationEnabled() |
||
1036 | |||
1037 | /** |
||
1038 | * Toggle hydrating entities. |
||
1039 | * |
||
1040 | * If set to false array results will be returned. |
||
1041 | * |
||
1042 | * @deprecated 3.4.0 Use enableHydration()/isHydrationEnabled() instead. |
||
1043 | * @param bool|null $enable Use a boolean to set the hydration mode. |
||
1044 | * Null will fetch the current hydration mode. |
||
1045 | * @return bool|$this A boolean when reading, and $this when setting the mode. |
||
1046 | */ |
||
1047 | public function hydrate($enable = null) |
||
1059 | |||
1060 | /** |
||
1061 | * {@inheritDoc} |
||
1062 | * |
||
1063 | * @return $this |
||
1064 | * @throws \RuntimeException When you attempt to cache a non-select query. |
||
1065 | */ |
||
1066 | public function cache($key, $config = 'default') |
||
1074 | |||
1075 | /** |
||
1076 | * {@inheritDoc} |
||
1077 | * |
||
1078 | * @throws \RuntimeException if this method is called on a non-select Query. |
||
1079 | */ |
||
1080 | public function all() |
||
1090 | |||
1091 | /** |
||
1092 | * Trigger the beforeFind event on the query's repository object. |
||
1093 | * |
||
1094 | * Will not trigger more than once, and only for select queries. |
||
1095 | * |
||
1096 | * @return void |
||
1097 | */ |
||
1098 | public function triggerBeforeFind() |
||
1112 | |||
1113 | /** |
||
1114 | * {@inheritDoc} |
||
1115 | */ |
||
1116 | public function sql(ValueBinder $binder = null) |
||
1124 | |||
1125 | /** |
||
1126 | * Executes this query and returns a ResultSet object containing the results. |
||
1127 | * This will also setup the correct statement class in order to eager load deep |
||
1128 | * associations. |
||
1129 | * |
||
1130 | * @return \Cake\ORM\ResultSet |
||
1131 | */ |
||
1132 | protected function _execute() |
||
1145 | |||
1146 | /** |
||
1147 | * Applies some defaults to the query object before it is executed. |
||
1148 | * |
||
1149 | * Specifically add the FROM clause, adds default table fields if none are |
||
1150 | * specified and applies the joins required to eager load associations defined |
||
1151 | * using `contain` |
||
1152 | * |
||
1153 | * It also sets the default types for the columns in the select clause |
||
1154 | * |
||
1155 | * @see \Cake\Database\Query::execute() |
||
1156 | * @return void |
||
1157 | */ |
||
1158 | protected function _transformQuery() |
||
1174 | |||
1175 | /** |
||
1176 | * Inspects if there are any set fields for selecting, otherwise adds all |
||
1177 | * the fields for the default table. |
||
1178 | * |
||
1179 | * @return void |
||
1180 | */ |
||
1181 | protected function _addDefaultFields() |
||
1198 | |||
1199 | /** |
||
1200 | * Sets the default types for converting the fields in the select clause |
||
1201 | * |
||
1202 | * @return void |
||
1203 | */ |
||
1204 | protected function _addDefaultSelectTypes() |
||
1224 | |||
1225 | /** |
||
1226 | * {@inheritDoc} |
||
1227 | * |
||
1228 | * @see \Cake\ORM\Table::find() |
||
1229 | */ |
||
1230 | public function find($finder, array $options = []) |
||
1237 | |||
1238 | /** |
||
1239 | * Marks a query as dirty, removing any preprocessed information |
||
1240 | * from in memory caching such as previous results |
||
1241 | * |
||
1242 | * @return void |
||
1243 | */ |
||
1244 | protected function _dirty() |
||
1250 | |||
1251 | /** |
||
1252 | * Create an update query. |
||
1253 | * |
||
1254 | * This changes the query type to be 'update'. |
||
1255 | * Can be combined with set() and where() methods to create update queries. |
||
1256 | * |
||
1257 | * @param string|null $table Unused parameter. |
||
1258 | * @return $this |
||
1259 | */ |
||
1260 | public function update($table = null) |
||
1270 | |||
1271 | /** |
||
1272 | * Create a delete query. |
||
1273 | * |
||
1274 | * This changes the query type to be 'delete'. |
||
1275 | * Can be combined with the where() method to create delete queries. |
||
1276 | * |
||
1277 | * @param string|null $table Unused parameter. |
||
1278 | * @return $this |
||
1279 | */ |
||
1280 | public function delete($table = null) |
||
1289 | |||
1290 | /** |
||
1291 | * Create an insert query. |
||
1292 | * |
||
1293 | * This changes the query type to be 'insert'. |
||
1294 | * Note calling this method will reset any data previously set |
||
1295 | * with Query::values() |
||
1296 | * |
||
1297 | * Can be combined with the where() method to create delete queries. |
||
1298 | * |
||
1299 | * @param array $columns The columns to insert into. |
||
1300 | * @param array $types A map between columns & their datatypes. |
||
1301 | * @return $this |
||
1302 | */ |
||
1303 | public function insert(array $columns, array $types = []) |
||
1312 | |||
1313 | /** |
||
1314 | * {@inheritDoc} |
||
1315 | * |
||
1316 | * @throws \BadMethodCallException if the method is called for a non-select query |
||
1317 | */ |
||
1318 | public function __call($method, $arguments) |
||
1328 | |||
1329 | /** |
||
1330 | * {@inheritDoc} |
||
1331 | */ |
||
1332 | public function __debugInfo() |
||
1347 | |||
1348 | /** |
||
1349 | * Executes the query and converts the result set into JSON. |
||
1350 | * |
||
1351 | * Part of JsonSerializable interface. |
||
1352 | * |
||
1353 | * @return \Cake\Datasource\ResultSetInterface The data to convert to JSON. |
||
1354 | */ |
||
1355 | public function jsonSerialize() |
||
1359 | |||
1360 | /** |
||
1361 | * Sets whether or not the ORM should automatically append fields. |
||
1362 | * |
||
1363 | * By default calling select() will disable auto-fields. You can re-enable |
||
1364 | * auto-fields with this method. |
||
1365 | * |
||
1366 | * @param bool $value Set true to enable, false to disable. |
||
1367 | * @return $this |
||
1368 | */ |
||
1369 | public function enableAutoFields($value = true) |
||
1375 | |||
1376 | /** |
||
1377 | * Disables automatically appending fields. |
||
1378 | * |
||
1379 | * @return $this |
||
1380 | */ |
||
1381 | public function disableAutoFields() |
||
1387 | |||
1388 | /** |
||
1389 | * Gets whether or not the ORM should automatically append fields. |
||
1390 | * |
||
1391 | * By default calling select() will disable auto-fields. You can re-enable |
||
1392 | * auto-fields with enableAutoFields(). |
||
1393 | * |
||
1394 | * @return bool|null The current value. Returns null if neither enabled or disabled yet. |
||
1395 | */ |
||
1396 | public function isAutoFieldsEnabled() |
||
1400 | |||
1401 | /** |
||
1402 | * Get/Set whether or not the ORM should automatically append fields. |
||
1403 | * |
||
1404 | * By default calling select() will disable auto-fields. You can re-enable |
||
1405 | * auto-fields with this method. |
||
1406 | * |
||
1407 | * @deprecated 3.4.0 Use enableAutoFields()/isAutoFieldsEnabled() instead. |
||
1408 | * @param bool|null $value The value to set or null to read the current value. |
||
1409 | * @return bool|null|$this Either the current value or the query object. |
||
1410 | */ |
||
1411 | public function autoFields($value = null) |
||
1423 | |||
1424 | /** |
||
1425 | * Decorates the results iterator with MapReduce routines and formatters |
||
1426 | * |
||
1427 | * @param \Traversable $result Original results |
||
1428 | * @return \Cake\Datasource\ResultSetInterface |
||
1429 | */ |
||
1430 | protected function _decorateResults($result) |
||
1441 | } |
||
1442 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.