2121use function array_keys ;
2222use function array_merge ;
2323use function array_unique ;
24- use function array_values ;
2524use function count ;
2625use function is_array ;
2726use function is_object ;
@@ -276,9 +275,9 @@ public function populateRelation(string $name, array &$primaryModels): array
276275 $ models = $ this ->all ();
277276
278277 if (isset ($ viaModels , $ viaQuery )) {
279- $ buckets = $ this ->buildBuckets ($ models , $ this -> link , $ viaModels , $ viaQuery );
278+ $ buckets = $ this ->buildBuckets ($ models , $ viaModels , $ viaQuery );
280279 } else {
281- $ buckets = $ this ->buildBuckets ($ models, $ this -> link );
280+ $ buckets = $ this ->buildBuckets ($ models );
282281 }
283282
284283 $ this ->indexBy ($ indexBy );
@@ -363,66 +362,84 @@ private function populateInverseRelation(
363362 $ model = reset ($ models );
364363
365364 if ($ model instanceof ActiveRecordInterface) {
366- /** @var ActiveQuery $relation */
367- $ relation = $ model ->relationQuery ($ name );
368- } else {
369- /** @var ActiveQuery $relation */
370- $ relation = $ this ->getARInstance ()->relationQuery ($ name );
365+ $ this ->populateInverseRelationToModels ($ models , $ primaryModels , $ name );
366+ return ;
371367 }
372368
373- if ($ relation ->getMultiple ()) {
374- $ buckets = $ this ->buildBuckets ($ primaryModels , $ relation ->getLink (), null , null , false );
375- if ($ model instanceof ActiveRecordInterface) {
376- foreach ($ models as $ model ) {
377- $ key = $ this ->getModelKey ($ model , $ relation ->getLink ());
378- if ($ model instanceof ActiveRecordInterface) {
379- $ model ->populateRelation ($ name , $ buckets [$ key ] ?? []);
369+ $ primaryModel = reset ($ primaryModels );
370+
371+ if ($ primaryModel instanceof ActiveRecordInterface) {
372+ if ($ this ->multiple ) {
373+ foreach ($ primaryModels as $ primaryModel ) {
374+ $ models = $ primaryModel ->relation ($ primaryName );
375+ if (!empty ($ models )) {
376+ $ this ->populateInverseRelationToModels ($ models , $ primaryModels , $ name );
377+ $ primaryModel ->populateRelation ($ primaryName , $ models );
380378 }
381379 }
382380 } else {
383- foreach ($ primaryModels as $ i => $ primaryModel ) {
384- if ($ this ->multiple ) {
385- foreach ($ primaryModel as $ j => $ m ) {
386- $ key = $ this ->getModelKey ($ m , $ relation ->getLink ());
387- $ primaryModels [$ i ][$ j ][$ name ] = $ buckets [$ key ] ?? [];
388- }
389- } elseif (!empty ($ primaryModel [$ primaryName ])) {
390- $ key = $ this ->getModelKey ($ primaryModel [$ primaryName ], $ relation ->getLink ());
391- $ primaryModels [$ i ][$ primaryName ][$ name ] = $ buckets [$ key ] ?? [];
381+ foreach ($ primaryModels as $ primaryModel ) {
382+ $ model = $ primaryModel ->relation ($ primaryName );
383+ if (!empty ($ model )) {
384+ $ models = [$ model ];
385+ $ this ->populateInverseRelationToModels ($ models , $ primaryModels , $ name );
386+ $ primaryModel ->populateRelation ($ primaryName , $ models [0 ]);
392387 }
393388 }
394389 }
395- } elseif ($ this ->multiple ) {
396- foreach ($ primaryModels as $ i => $ primaryModel ) {
397- foreach ($ primaryModel [$ primaryName ] as $ j => $ m ) {
398- if ($ m instanceof ActiveRecordInterface) {
399- $ m ->populateRelation ($ name , $ primaryModel );
400- } else {
401- $ primaryModels [$ i ][$ primaryName ][$ j ][$ name ] = $ primaryModel ;
390+ } else {
391+ if ($ this ->multiple ) {
392+ foreach ($ primaryModels as &$ primaryModel ) {
393+ if (!empty ($ primaryModel [$ primaryName ])) {
394+ $ this ->populateInverseRelationToModels ($ primaryModel [$ primaryName ], $ primaryModels , $ name );
395+ }
396+ }
397+ } else {
398+ foreach ($ primaryModels as &$ primaryModel ) {
399+ if (!empty ($ primaryModel [$ primaryName ])) {
400+ $ models = [$ primaryModel [$ primaryName ]];
401+ $ this ->populateInverseRelationToModels ($ models , $ primaryModels , $ name );
402+ $ primaryModel [$ primaryName ] = $ models [0 ];
402403 }
403404 }
404405 }
406+ }
407+ }
408+
409+ private function populateInverseRelationToModels (array &$ models , array $ primaryModels , string $ name ): void
410+ {
411+ $ model = reset ($ models );
412+ $ isArray = is_array ($ model );
413+
414+ /** @var ActiveQuery $relation */
415+ $ relation = $ isArray ? $ this ->getARInstance ()->relationQuery ($ name ) : $ model ->relationQuery ($ name );
416+ $ buckets = $ relation ->buildBuckets ($ primaryModels );
417+ $ link = $ relation ->getLink ();
418+ $ default = $ relation ->getMultiple () ? [] : null ;
419+
420+ if ($ isArray ) {
421+ /** @var array $model */
422+ foreach ($ models as &$ model ) {
423+ $ key = $ this ->getModelKey ($ model , $ link );
424+ $ model [$ name ] = $ buckets [$ key ] ?? $ default ;
425+ }
405426 } else {
406- foreach ($ primaryModels as $ i => $ primaryModel ) {
407- if ($ primaryModel [$ primaryName ] instanceof ActiveRecordInterface) {
408- $ primaryModel [$ primaryName ]->populateRelation ($ name , $ primaryModel );
409- } elseif (!empty ($ primaryModel [$ primaryName ])) {
410- $ primaryModels [$ i ][$ primaryName ][$ name ] = $ primaryModel ;
411- }
427+ /** @var ActiveRecordInterface $model */
428+ foreach ($ models as $ model ) {
429+ $ key = $ this ->getModelKey ($ model , $ link );
430+ $ model ->populateRelation ($ name , $ buckets [$ key ] ?? $ default );
412431 }
413432 }
414433 }
415434
416435 private function buildBuckets (
417436 array $ models ,
418- array $ link ,
419437 array $ viaModels = null ,
420- self $ viaQuery = null ,
421- bool $ checkMultiple = true
438+ self $ viaQuery = null
422439 ): array {
423440 if ($ viaModels !== null ) {
424441 $ map = [];
425- $ linkValues = array_values ( $ link) ;
442+ $ linkValues = $ this -> link ;
426443 $ viaLink = $ viaQuery ->link ?? [];
427444 $ viaLinkKeys = array_keys ($ viaLink );
428445 $ viaVia = null ;
@@ -452,7 +469,7 @@ private function buildBuckets(
452469 }
453470
454471 $ buckets = [];
455- $ linkKeys = array_keys ($ link );
472+ $ linkKeys = array_keys ($ this -> link );
456473
457474 if (isset ($ map )) {
458475 foreach ($ models as $ model ) {
@@ -471,7 +488,7 @@ private function buildBuckets(
471488 }
472489 }
473490
474- if ($ checkMultiple && !$ this ->multiple ) {
491+ if (!$ this ->multiple ) {
475492 foreach ($ buckets as $ i => $ bucket ) {
476493 $ buckets [$ i ] = reset ($ bucket );
477494 }
0 commit comments