@@ -56,30 +56,6 @@ public function createCommand($db = null)
5656 return parent ::createCommand ($ db );
5757 }
5858
59- /**
60- * {@inheritdoc}
61- */
62- public function all ($ db = null )
63- {
64- return parent ::all ($ db );
65- }
66-
67- /**
68- * {@inheritdoc}
69- * @throws InvalidConfigException
70- */
71- public function one ($ db = null )
72- {
73- $ row = parent ::one ($ db );
74- if ($ row !== false ) {
75- $ models = $ this ->populate (isset ($ row [0 ]) ? $ row : [$ row ]);
76-
77- return reset ($ models ) ?: null ;
78- }
79-
80- return null ;
81- }
82-
8359 /**
8460 * {@inheritdoc}
8561 * @throws InvalidConfigException
@@ -134,46 +110,6 @@ public function prepare($builder)
134110 return $ query ;
135111 }
136112
137- /**
138- * Joins with the specified relations.
139- *
140- * This method allows you to reuse existing relation definitions to perform JOIN queries.
141- * Based on the definition of the specified relation(s), the method will append one or multiple
142- * JOIN statements to the current query.
143- *
144- * @param string|array $with the relations to be joined. This can either be a string, representing a relation name or
145- * an array with the following semantics:
146- *
147- * - Each array element represents a single relation.
148- * - You may specify the relation name as the array key and provide an anonymous functions that
149- * can be used to modify the relation queries on-the-fly as the array value.
150- * - If a relation query does not need modification, you may use the relation name as the array value.
151- *
152- * Sub-relations can also be specified, see [[with()]] for the syntax.
153- *
154- * In the following you find some examples:
155- *
156- * ```php
157- * // find all orders that contain books, and eager loading "books"
158- * Order::find()->joinWith('books')->all();
159- * // find all orders, eager loading "books", and sort the orders and books by the book names.
160- * Order::find()->joinWith([
161- * 'books' => function (\simialbi\yii2\rest\ActiveQuery $query) {
162- * $query->orderBy('item.name');
163- * }
164- * ])->all();
165- * // find all orders that contain books of the category 'Science fiction', using the alias "b" for the books table
166- * Order::find()->joinWith(['books b'])->where(['b.category' => 'Science fiction'])->all();
167- * ```
168- *
169- * @return $this the query object itself
170- */
171- public function joinWith ($ with )
172- {
173- $ this ->joinWith [] = (array )$ with ;
174- return $ this ;
175- }
176-
177113 /**
178114 * Builds join with clauses
179115 */
@@ -196,7 +132,6 @@ private function buildJoinWith()
196132 }
197133 }
198134
199-
200135 /**
201136 * Modifies the current query by adding join fragments based on the given relations.
202137 * @param ActiveRecord $model the primary model
@@ -224,6 +159,7 @@ protected function joinWithRelations($model, $with)
224159 }
225160 }
226161 }
162+
227163 /**
228164 * Joins a parent query with a child query.
229165 * The current query object will be modified accordingly.
@@ -240,6 +176,31 @@ private function joinWithRelation($parent, $child)
240176 }
241177 }
242178
179+ /**
180+ * {@inheritdoc}
181+ */
182+ public function all ($ db = null )
183+ {
184+ return parent ::all ($ db );
185+ }
186+
187+ /**
188+ * {@inheritdoc}
189+ * @throws InvalidConfigException
190+ */
191+ public function one ($ db = null )
192+ {
193+ $ row = parent ::one ($ db );
194+ if ($ row !== false ) {
195+ $ models = $ this ->populate (isset ($ row [0 ]) ? $ row : [$ row ]);
196+
197+ return reset ($ models ) ?: null ;
198+ }
199+
200+ return null ;
201+ }
202+
203+
243204 /**
244205 * {@inheritdoc}
245206 * @throws InvalidConfigException
@@ -268,14 +229,46 @@ public function populate($rows)
268229 return $ models ;
269230 }
270231
232+ /**
233+ * {@inheritDoc}
234+ */
235+ protected function createModels ($ rows )
236+ {
237+ if ($ this ->asArray ) {
238+ return $ rows ;
239+ } else {
240+ $ models = [];
241+ /* @var $class ActiveRecord */
242+ $ class = $ this ->modelClass ;
243+ foreach ($ rows as $ row ) {
244+ $ model = $ class ::instantiate ($ row );
245+ /** @var $modelClass ActiveRecord */
246+ $ modelClass = get_class ($ model );
247+ $ modelClass ::populateRecord ($ model , $ row );
248+ if (!empty ($ this ->join )) {
249+ foreach ($ this ->join as $ join ) {
250+ if (isset ($ join [1 ], $ row [$ join [1 ]])) {
251+ $ relation = $ model ->getRelation ($ join [1 ]);
252+ $ rows = (ArrayHelper::isAssociative ($ row [$ join [1 ]])) ? [$ row [$ join [1 ]]] : $ row [$ join [1 ]];
253+ $ relations = $ relation ->populate ($ rows );
254+ $ model ->populateRelation ($ join [1 ], $ relation ->multiple ? $ relations : $ relations [0 ]);
255+ }
256+ }
257+ }
258+ $ models [] = $ model ;
259+ }
260+ return $ models ;
261+ }
262+ }
263+
271264 /**
272265 * Removes duplicated models by checking their primary key values.
273266 * This method is mainly called when a join query is performed, which may cause duplicated rows being returned.
274267 *
275268 * @param array $models the models to be checked
276269 *
277- * @throws InvalidConfigException if model primary key is empty
278270 * @return array the distinctive models
271+ * @throws InvalidConfigException if model primary key is empty
279272 */
280273 private function removeDuplicatedModels ($ models )
281274 {
@@ -303,6 +296,7 @@ private function removeDuplicatedModels($models)
303296 }
304297 }
305298 } elseif (empty ($ pks )) {
299+ /** @var $class string */
306300 throw new InvalidConfigException ("Primary key of ' {$ class }' can not be empty. " );
307301 } else {
308302 // single column primary key
@@ -323,4 +317,44 @@ private function removeDuplicatedModels($models)
323317
324318 return array_values ($ models );
325319 }
320+
321+ /**
322+ * Joins with the specified relations.
323+ *
324+ * This method allows you to reuse existing relation definitions to perform JOIN queries.
325+ * Based on the definition of the specified relation(s), the method will append one or multiple
326+ * JOIN statements to the current query.
327+ *
328+ * @param string|array $with the relations to be joined. This can either be a string, representing a relation name or
329+ * an array with the following semantics:
330+ *
331+ * - Each array element represents a single relation.
332+ * - You may specify the relation name as the array key and provide an anonymous functions that
333+ * can be used to modify the relation queries on-the-fly as the array value.
334+ * - If a relation query does not need modification, you may use the relation name as the array value.
335+ *
336+ * Sub-relations can also be specified, see [[with()]] for the syntax.
337+ *
338+ * In the following you find some examples:
339+ *
340+ * ```php
341+ * // find all orders that contain books, and eager loading "books"
342+ * Order::find()->joinWith('books')->all();
343+ * // find all orders, eager loading "books", and sort the orders and books by the book names.
344+ * Order::find()->joinWith([
345+ * 'books' => function (\simialbi\yii2\rest\ActiveQuery $query) {
346+ * $query->orderBy('item.name');
347+ * }
348+ * ])->all();
349+ * // find all orders that contain books of the category 'Science fiction', using the alias "b" for the books table
350+ * Order::find()->joinWith(['books b'])->where(['b.category' => 'Science fiction'])->all();
351+ * ```
352+ *
353+ * @return $this the query object itself
354+ */
355+ public function joinWith ($ with )
356+ {
357+ $ this ->joinWith [] = (array )$ with ;
358+ return $ this ;
359+ }
326360}
0 commit comments