From 1cda0b873705ec4f048b55f95e7a2ba40d6a8f9b Mon Sep 17 00:00:00 2001 From: Pedro X Date: Wed, 24 Feb 2021 15:41:05 +0000 Subject: [PATCH 1/5] implement entity validation on eager loading --- src/app/Library/CrudPanel/Traits/Read.php | 29 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/app/Library/CrudPanel/Traits/Read.php b/src/app/Library/CrudPanel/Traits/Read.php index 9c9e050caf..8d1f0c7d84 100644 --- a/src/app/Library/CrudPanel/Traits/Read.php +++ b/src/app/Library/CrudPanel/Traits/Read.php @@ -2,6 +2,8 @@ namespace Backpack\CRUD\app\Library\CrudPanel\Traits; +use Exception; + /** * Properties and methods used by the List operation. */ @@ -82,8 +84,30 @@ public function autoEagerLoadRelationshipColumns() { $relationships = $this->getColumnsRelationships(); - if (count($relationships)) { - $this->with($relationships); + foreach($relationships as $relation) { + if(strpos($relation, '.') !== false) { + + $relation_parts = explode('.', $relation); + $last_relation_part = array_pop($relation_parts); + + $last_valid_relation_method = array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) { + try { + $result = $obj->$method(); + return $result->getRelated(); + } catch (Exception $e) { + return $method; + } + }, $this->model); + + // when this keys don't match means the last part of the relation string is the attribute in the relation and + // not a nested relation. In that case, we should eager load the relation but not the attribute + if($last_valid_relation_method != $last_relation_part) { + // remove the last part of the relation string because it is the attribute in the relationship + $relation = substr($relation, 0, strrpos( $relation, '.') ); + + } + } + $this->with($relation); } } @@ -102,7 +126,6 @@ public function getEntries() foreach ($entries as $key => $entry) { $entry->addFakes($this->getFakeColumnsAsArray()); } - return $entries; } From fee6370494e0ff0a59a333006bcb6a37e55e44c7 Mon Sep 17 00:00:00 2001 From: Cristian Tabacitu Date: Wed, 24 Feb 2021 15:41:28 +0000 Subject: [PATCH 2/5] Apply fixes from StyleCI [ci skip] [skip ci] --- src/app/Library/CrudPanel/Traits/Read.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/Library/CrudPanel/Traits/Read.php b/src/app/Library/CrudPanel/Traits/Read.php index 8d1f0c7d84..cd0054a3d9 100644 --- a/src/app/Library/CrudPanel/Traits/Read.php +++ b/src/app/Library/CrudPanel/Traits/Read.php @@ -84,15 +84,15 @@ public function autoEagerLoadRelationshipColumns() { $relationships = $this->getColumnsRelationships(); - foreach($relationships as $relation) { - if(strpos($relation, '.') !== false) { - + foreach ($relationships as $relation) { + if (strpos($relation, '.') !== false) { $relation_parts = explode('.', $relation); $last_relation_part = array_pop($relation_parts); $last_valid_relation_method = array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) { try { $result = $obj->$method(); + return $result->getRelated(); } catch (Exception $e) { return $method; @@ -101,10 +101,9 @@ public function autoEagerLoadRelationshipColumns() // when this keys don't match means the last part of the relation string is the attribute in the relation and // not a nested relation. In that case, we should eager load the relation but not the attribute - if($last_valid_relation_method != $last_relation_part) { + if ($last_valid_relation_method != $last_relation_part) { // remove the last part of the relation string because it is the attribute in the relationship - $relation = substr($relation, 0, strrpos( $relation, '.') ); - + $relation = substr($relation, 0, strrpos($relation, '.')); } } $this->with($relation); @@ -126,6 +125,7 @@ public function getEntries() foreach ($entries as $key => $entry) { $entry->addFakes($this->getFakeColumnsAsArray()); } + return $entries; } From 211722ddd729bffdd96d378d7a1dd44bf7f4c2fa Mon Sep 17 00:00:00 2001 From: Pedro X Date: Thu, 25 Feb 2021 10:25:13 +0000 Subject: [PATCH 3/5] fix iteraction script --- src/app/Library/CrudPanel/Traits/Read.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/Library/CrudPanel/Traits/Read.php b/src/app/Library/CrudPanel/Traits/Read.php index cd0054a3d9..317b4337ac 100644 --- a/src/app/Library/CrudPanel/Traits/Read.php +++ b/src/app/Library/CrudPanel/Traits/Read.php @@ -87,15 +87,15 @@ public function autoEagerLoadRelationshipColumns() foreach ($relationships as $relation) { if (strpos($relation, '.') !== false) { $relation_parts = explode('.', $relation); - $last_relation_part = array_pop($relation_parts); + $last_relation_part = $last_valid_relation_method = end($relation_parts); - $last_valid_relation_method = array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) { + array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) use (&$last_valid_relation_method) { try { $result = $obj->$method(); - + $last_valid_relation_method = $method; return $result->getRelated(); } catch (Exception $e) { - return $method; + return; } }, $this->model); From 62a77ad5139ec7c5c4d347b02b077bca9981ebdb Mon Sep 17 00:00:00 2001 From: Cristian Tabacitu Date: Thu, 25 Feb 2021 10:25:29 +0000 Subject: [PATCH 4/5] Apply fixes from StyleCI [ci skip] [skip ci] --- src/app/Library/CrudPanel/Traits/Read.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/Library/CrudPanel/Traits/Read.php b/src/app/Library/CrudPanel/Traits/Read.php index 317b4337ac..504c57965e 100644 --- a/src/app/Library/CrudPanel/Traits/Read.php +++ b/src/app/Library/CrudPanel/Traits/Read.php @@ -93,6 +93,7 @@ public function autoEagerLoadRelationshipColumns() try { $result = $obj->$method(); $last_valid_relation_method = $method; + return $result->getRelated(); } catch (Exception $e) { return; From 537ed8023963a1e0b584d1d2d2d3f285d5ff3f4a Mon Sep 17 00:00:00 2001 From: Antonio Almeida Date: Sun, 7 Mar 2021 17:32:49 +0000 Subject: [PATCH 5/5] Refactor loop to check nested relations --- src/app/Library/CrudPanel/Traits/Read.php | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/app/Library/CrudPanel/Traits/Read.php b/src/app/Library/CrudPanel/Traits/Read.php index 504c57965e..3fb51336e9 100644 --- a/src/app/Library/CrudPanel/Traits/Read.php +++ b/src/app/Library/CrudPanel/Traits/Read.php @@ -86,25 +86,17 @@ public function autoEagerLoadRelationshipColumns() foreach ($relationships as $relation) { if (strpos($relation, '.') !== false) { - $relation_parts = explode('.', $relation); - $last_relation_part = $last_valid_relation_method = end($relation_parts); + $parts = explode('.', $relation); + $model = $this->model; - array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) use (&$last_valid_relation_method) { + // Iterate over each relation part to find the valid relations without attributes + // We should eager load the relation but not the attribute + foreach ($parts as $i => $part) { try { - $result = $obj->$method(); - $last_valid_relation_method = $method; - - return $result->getRelated(); + $model = $model->$part()->getRelated(); } catch (Exception $e) { - return; + $relation = join('.', array_slice($parts, 0, $i)); } - }, $this->model); - - // when this keys don't match means the last part of the relation string is the attribute in the relation and - // not a nested relation. In that case, we should eager load the relation but not the attribute - if ($last_valid_relation_method != $last_relation_part) { - // remove the last part of the relation string because it is the attribute in the relationship - $relation = substr($relation, 0, strrpos($relation, '.')); } } $this->with($relation);