33namespace Backpack \CRUD \app \Library \CrudPanel \Traits ;
44
55use Illuminate \Database \Eloquent \Builder ;
6- use Illuminate \Support \Str ;
76
87trait Query
98{
@@ -183,69 +182,6 @@ public function orderByWithPrefix($column_name, $column_direction = 'ASC')
183182 return $ this ->query ->orderBy ($ column_name , $ column_direction );
184183 }
185184
186- /**
187- * Return the nested query columns.
188- *
189- * @param \Illuminate\Database\Eloquent\Builder $query
190- * @return array
191- */
192- private function getNestedQueryColumns ($ query )
193- {
194- return $ this ->getQueryColumnsFromWheres ($ query , true );
195- }
196-
197- /**
198- * We want to select the minimum possible columns respecting the clauses in the query, so that the count is accurate.
199- * for that to happen we will traverse the query `wheres` (Basic, Exists, Nested or Column) to get the correct
200- * column that we need to select in the main model for that "sub query" to work.
201- *
202- * For example a base query of: `SELECT * FROM table WHERE (someColumn, smtValue)`, we would return only the `someColumn`
203- * with the objective of replacing the `*` for the specific columns needed, avoiding the selection of
204- * columns that would not have impact in the counting process.
205- *
206- * @param \Illuminate\Database\Eloquent\Builder $query
207- * @param bool $nested used to prevent multiple level nesting as we only need the first level columns
208- * @return array
209- */
210- private function getQueryColumnsFromWheres ($ query , $ nested = false )
211- {
212- // if there is a raw where we are better not touching the columns, otherwise we
213- // would need to parse the raw sql wheres and that can get messy very quick.
214- if (in_array ('raw ' , array_column ($ query ->wheres , 'type ' ))) {
215- return $ query ->columns ;
216- }
217-
218- $ wheresColumns = [];
219- foreach ($ query ->wheres as $ where ) {
220- switch ($ where ['type ' ]) {
221- // case it's a basic where, we just want to select that column.
222- case 'Basic ' :
223- $ wheresColumns [] = $ where ['column ' ];
224- break ;
225- // when it's a nested query we will get the columns that link
226- // to the main table from the nested query wheres.
227- case 'Nested ' :
228- $ wheresColumns = $ nested ?: array_merge ($ wheresColumns , $ this ->getNestedQueryColumns ($ where ['query ' ]));
229- break ;
230- // when Column get the "first" key that represent the base table column to link with
231- case 'Column ' :
232- $ wheresColumns [] = $ where ['first ' ];
233- break ;
234- // in case of Exists, we will find in the subquery the query type Column where it links to the main table
235- case 'Exists ' :
236- $ wheres = $ where ['query ' ]->wheres ;
237- foreach ($ wheres as $ subWhere ) {
238- if ($ subWhere ['type ' ] === 'Column ' ) {
239- $ wheresColumns [] = $ subWhere ['first ' ];
240- }
241- }
242- break ;
243- }
244- }
245-
246- return $ wheresColumns ;
247- }
248-
249185 /**
250186 * Get the entries count from `totalQuery`.
251187 *
@@ -297,19 +233,7 @@ private function getCountFromQuery(Builder $query)
297233 }
298234
299235 $ crudQuery = $ query ->toBase ()->clone ();
300- $ crudQueryColumns = $ this ->getQueryColumnsFromWheres ($ crudQuery );
301-
302- // merge the model key in the columns array if needed
303- $ crudQueryColumns = $ this ->addModelKeyToColumnsArray ($ crudQueryColumns );
304-
305- // remove table prefix from select columns
306- $ crudQueryColumns = array_map (function ($ item ) {
307- return Str::afterLast ($ item , '. ' );
308- }, $ crudQueryColumns );
309-
310- // remove possible column name duplicates (when using the column name in combination with table.column name in some other constrain
311- // for example `where('table.column', smt') and in other place where('column', 'smt').
312- $ crudQueryColumns = array_unique ($ crudQueryColumns );
236+ $ modelTable = $ this ->model ->getTableWithPrefix ();
313237
314238 // create an "outer" query, the one that is responsible to do the count of the "crud query".
315239 $ outerQuery = $ crudQuery ->newQuery ();
@@ -323,24 +247,8 @@ private function getCountFromQuery(Builder $query)
323247 // - orders/limit/offset because we want the "full query count" where orders don't matter and limit/offset would break the total count
324248 $ subQuery = $ crudQuery ->cloneWithout (['columns ' , 'orders ' , 'limit ' , 'offset ' ]);
325249
326- $ outerQuery = $ outerQuery ->fromSub ($ subQuery ->select ($ this ->model ->getKeyName ()), $ this -> model -> getTableWithPrefix () );
250+ $ outerQuery = $ outerQuery ->fromSub ($ subQuery ->select ($ modelTable . ' . ' . $ this ->model ->getKeyName ()), $ modelTable . ' _aggregator ' );
327251
328252 return $ outerQuery ->cursor ()->first ()->total_rows ;
329253 }
330-
331- /**
332- * Adds the model key into the selection columns array.
333- * When using `*` as column selector it's assumed the model key would be selected.
334- *
335- * @param array $columns
336- * @return array
337- */
338- private function addModelKeyToColumnsArray (array $ columns )
339- {
340- if (! in_array ($ this ->model ->getKeyName (), $ columns ) && ! in_array ('* ' , $ columns )) {
341- return array_merge ($ columns , [$ this ->model ->getKeyName ()]);
342- }
343-
344- return $ columns ;
345- }
346254}
0 commit comments