@@ -17,6 +17,9 @@ class Model extends \CodeIgniter\Model
1717 // Array of tables to block from loading relations
1818 protected $ without = [];
1919
20+ // Whether to reindex results by the primary key
21+ protected $ reindex = true ;
22+
2023 // Call the CI model constructor then check for and load the schema
2124 public function __construct (ConnectionInterface &$ db = null , ValidationInterface $ validation = null )
2225 {
@@ -90,7 +93,48 @@ public function without($tables)
9093
9194 return $ this ;
9295 }
96+
97+ /**
98+ * Reset per-query variables.
99+ *
100+ * @return $this
101+ */
102+ public function resetTmp ()
103+ {
104+ unset($ this ->tmpWith , $ this ->tmpWithout , $ this ->tmpReindex );
105+
106+ return $ this ;
107+ }
93108
109+ /**
110+ * Enable/disable result reindexing.
111+ *
112+ * @param bool $bool
113+ *
114+ * @return $this
115+ */
116+ public function reindex (bool $ bool = true )
117+ {
118+ $ this ->reindex = $ bool ;
119+
120+ return $ this ;
121+ }
122+
123+ /**
124+ * Intercept join requests to disable reindexing.
125+ *
126+ * @return $this
127+ */
128+ public function join (...$ params )
129+ {
130+ $ this ->tmpReindex = false ;
131+
132+ // Pass through to the builder
133+ $ this ->builder ()->join (...$ params );
134+
135+ return $ this ;
136+ }
137+
94138 //--------------------------------------------------------------------
95139 // FINDERS EXTENSIONS
96140 //--------------------------------------------------------------------
@@ -165,14 +209,14 @@ protected function addRelated($rows): ?array
165209 // If there were no matches then reset per-query data and quit
166210 if (empty ($ rows ))
167211 {
168- unset( $ this ->tmpWith , $ this -> tmpWithout );
212+ $ this ->tmpReset ( );
169213 return $ rows ;
170214 }
171215
172216 // Likewise for empty singletons
173217 if (count ($ rows ) == 1 && reset ($ rows ) == null )
174218 {
175- unset( $ this ->tmpWith , $ this -> tmpWithout );
219+ $ this ->tmpReset ( );
176220 return $ rows ;
177221 }
178222
@@ -186,15 +230,21 @@ protected function addRelated($rows): ?array
186230 {
187231 $ this ->tmpWithout = $ this ->without ;
188232 }
233+ // If no tmpReindex was set then use this model's default
234+ if (! isset ($ this ->tmpReindex ))
235+ {
236+ $ this ->tmpReindex = $ this ->reindex ;
237+ }
189238
190239 // Remove any blocked tables from the request
191240 $ this ->tmpWith = array_diff ($ this ->tmpWith , $ this ->tmpWithout );
192241
193242 // If tmpWith ends up empty then reset and quit
194243 if (empty ($ this ->tmpWith ))
195244 {
196- unset($ this ->tmpWith , $ this ->tmpWithout );
197- return $ this ->simpleReindex ($ rows );
245+ $ rows = $ this ->tmpReindex ? $ this ->simpleReindex ($ rows ) : $ rows ;
246+ $ this ->tmpReset ();
247+ return $ rows ;
198248 }
199249
200250 // Make sure the schema is loaded
@@ -210,7 +260,7 @@ protected function addRelated($rows): ?array
210260 $ relations [$ tableName ] = $ this ->findRelated ($ tableName , $ ids );
211261 }
212262
213- // Reindex $rows by this model's primary key and inject related items
263+ // Inject related items
214264 $ return = [];
215265 foreach ($ rows as $ item )
216266 {
@@ -257,11 +307,19 @@ protected function addRelated($rows): ?array
257307 }
258308 }
259309
260- $ return [$ id ] = $ item ;
310+ if ($ this ->tmpReindex )
311+ {
312+ $ return [$ id ] = $ item ;
313+ }
314+ else
315+ {
316+ $ return [] = $ item ;
317+ }
261318 }
262319
263320 // Clear old data and reset per-query properties
264- unset($ rows , $ this ->tmpWith , $ this ->tmpWithout );
321+ unset($ rows );
322+ $ this ->resetTmp ();
265323
266324 return $ return ;
267325 }
@@ -310,6 +368,9 @@ public function findRelated($tableName, $ids): array
310368 // Check for another Relations model to prevent nesting loops
311369 if ($ builder instanceof self)
312370 {
371+ // Don't reindex (we'll do our own below)
372+ $ builder ->reindex (false );
373+
313374 // If nesting is allowed we need to disable the target table
314375 if (self ::$ config ->allowNesting )
315376 {
@@ -389,7 +450,7 @@ public function findRelated($tableName, $ids): array
389450
390451 // Clean up
391452 unset($ table , $ relation , $ builder );
392-
453+
393454 // Reindex the results by the originating ID (this model's primary key)
394455 $ return = [];
395456 if ($ returnType == 'array ' )
@@ -416,15 +477,15 @@ public function findRelated($tableName, $ids): array
416477 }
417478
418479 /**
419- * Reindexes $rows from a finder by their primary KEY_AS_FILENAME
480+ * Reindexes $rows from a finder by their primary key
420481 * Mostly used for consistent return format when no relations are requested
421482 * If multiple rows have the same primary (e.g. a join) it returns the originals
422483 *
423484 * @param array $rows Array of rows from the finder
424485 *
425486 * @return array
426487 */
427- protected function simpleReindex ($ rows ): array
488+ public function simpleReindex ($ rows ): array
428489 {
429490 if (empty ($ rows ))
430491 {
0 commit comments