From 43ebb3b673854c1135a483444d17bad6e6716ae7 Mon Sep 17 00:00:00 2001 From: mahmoudmohamedramadan Date: Thu, 31 Oct 2024 14:00:14 +0300 Subject: [PATCH 1/5] Add new exception class --- .../InvalidOrderableRelationship.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Exceptions/InvalidOrderableRelationship.php diff --git a/src/Exceptions/InvalidOrderableRelationship.php b/src/Exceptions/InvalidOrderableRelationship.php new file mode 100644 index 0000000..b947363 --- /dev/null +++ b/src/Exceptions/InvalidOrderableRelationship.php @@ -0,0 +1,19 @@ + Date: Thu, 31 Oct 2024 14:00:38 +0300 Subject: [PATCH 2/5] Remove the TODO comment --- src/Concerns/HasModel.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Concerns/HasModel.php b/src/Concerns/HasModel.php index 5a25937..d906ca5 100644 --- a/src/Concerns/HasModel.php +++ b/src/Concerns/HasModel.php @@ -156,7 +156,6 @@ protected function resolveModel() */ public function usingScopes(array $scopes) { - // TODO: Add the ability to pass additional arguments to local scopes. $localScopes = []; foreach ($scopes as $scope) { From 730e1b3b87e90ae2f5071465d6f04a1cb02bb904 Mon Sep 17 00:00:00 2001 From: mahmoudmohamedramadan Date: Thu, 31 Oct 2024 21:46:58 +0300 Subject: [PATCH 3/5] formatting --- src/Concerns/Orderable.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Concerns/Orderable.php b/src/Concerns/Orderable.php index 6745c33..4c6143e 100644 --- a/src/Concerns/Orderable.php +++ b/src/Concerns/Orderable.php @@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Ramadan\EasyModel\Exceptions\InvalidArrayStructure; +use Ramadan\EasyModel\Exceptions\InvalidOrderableRelationship; trait Orderable { @@ -20,6 +21,7 @@ trait Orderable * * @throws \Ramadan\EasyModel\Exceptions\InvalidSearchableModel * @throws \Ramadan\EasyModel\Exceptions\InvalidArrayStructure + * @throws \Ramadan\EasyModel\Exceptions\InvalidOrderableRelationship */ public function addOrderBy(array $orders, Builder $query = null) { @@ -49,6 +51,7 @@ public function addOrderBy(array $orders, Builder $query = null) * @return array * * @throws \Ramadan\EasyModel\Exceptions\InvalidArrayStructure + * @throws \Ramadan\EasyModel\Exceptions\InvalidOrderableRelationship */ protected function prepareParamtersForOrderBy(string|array $order, $queryBuilder) { @@ -74,8 +77,8 @@ protected function prepareParamtersForOrderBy(string|array $order, $queryBuilder } if (count($parts) > 1) { - // In case the order is related to the model relationships, we need to get - // the relationships and the column that needs to be ordered (e.g., "posts.created_at"). + // In case the order is related to the model relationships, we need to get the last + // relationship and the column that needs to be ordered (e.g., "post.comments.created_at"). $column = $this->performJoinsForOrderByRelationships($parts, $queryBuilder); } @@ -95,6 +98,8 @@ protected function prepareParamtersForOrderBy(string|array $order, $queryBuilder * @param array $relationships * @param \Illuminate\Database\Query\Builder $queryBuilder * @return string + * + * @throws \Ramadan\EasyModel\Exceptions\InvalidOrderableRelationship */ protected function performJoinsForOrderByRelationships($relationships, $queryBuilder) { @@ -104,10 +109,10 @@ protected function performJoinsForOrderByRelationships($relationships, $queryBui $currentRelationship = $currentModel->{$relationships[$i]}(); $relatedModel = $currentRelationship->getModel(); - // At first let's pretend that the current model is "App\Models\User" which is the parent and he has - // one or many child models (e.g., "post", "comments") in this case, the foreign key of the current + // At first let's pretend that the current model is "App\Models\User" which is the parent and it has + // one or many child models (e.g., "profile", "accounts") in this case, the foreign key of the current // model is "user_id" and must be exists in the child table(s). - if (in_array(get_class($currentRelationship), [HasMany::class, HasOne::class])) { + if (in_array(get_class($currentRelationship), [HasOne::class, HasMany::class])) { $currentTableName = $currentModel->getTable(); $relatedTableName = $relatedModel->getTable(); @@ -115,9 +120,9 @@ protected function performJoinsForOrderByRelationships($relationships, $queryBui $currentTablePrimaryKey = $currentModel->getKeyName(); } - // But, in case the current model is "App\Models\Post" which is the child and it belongs to - // a parent model (e.g., "user") the foreign key "user_id" must exists in the table of the - // current related model "posts". + // But, in case the current model is "App\Models\Comment" which is the child and it belongs to a + // parent model (e.g., "App\Models\Post") the foreign key "post_id" must exists in the table of the + // current related model "comments". elseif (in_array(get_class($currentRelationship), [BelongsTo::class, BelongsToMany::class])) { $currentTableName = $relatedModel->getTable(); $relatedTableName = $currentModel->getTable(); @@ -126,6 +131,12 @@ protected function performJoinsForOrderByRelationships($relationships, $queryBui $currentTablePrimaryKey = $currentModel->getKeyName(); } + if (empty($currentTableName) || empty($relatedTableName)) { + throw new InvalidOrderableRelationship( + sprintf('The orderable relationship [%s] is unsupported.', get_class($currentRelationship)) + ); + } + // Perform the join $queryBuilder->join( table: $relatedModel->getTable(), From 7802e42d33314cb9a1028f718be548439fcade0d Mon Sep 17 00:00:00 2001 From: mahmoudmohamedramadan Date: Thu, 31 Oct 2024 23:34:04 +0300 Subject: [PATCH 4/5] Extend the "scopes" to accept parameters --- src/Concerns/HasModel.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Concerns/HasModel.php b/src/Concerns/HasModel.php index d906ca5..65d2949 100644 --- a/src/Concerns/HasModel.php +++ b/src/Concerns/HasModel.php @@ -158,18 +158,18 @@ public function usingScopes(array $scopes) { $localScopes = []; - foreach ($scopes as $scope) { - if (is_a($scope, Scope::class, true)) { - $identifier = is_string($scope) ? $scope : get_class($scope); - $scope = is_string($scope) ? new $scope : $scope; - $this->getEloquentBuilder()->withGlobalScope($identifier, $scope); + foreach ($scopes as $scope => $parameters) { + if (is_a($parameters, Scope::class, true)) { + $identifier = is_string($parameters) ? $parameters : get_class($parameters); + $scope = is_string($parameters) ? new $parameters : $parameters; + $this->eloquentBuilder = $this->getEloquentBuilder()->withGlobalScope($identifier, $scope); } else { - $localScopes[] = $scope; + $localScopes[$scope] = $parameters; } } if (!empty($localScopes)) { - $this->getEloquentBuilder()->scopes($localScopes); + $this->eloquentBuilder = $this->getEloquentBuilder()->scopes($localScopes); } return $this; From 79d841f30f6de64ad9121ab7209fc7d7d9e0e41a Mon Sep 17 00:00:00 2001 From: mahmoudmohamedramadan Date: Thu, 31 Oct 2024 23:04:52 +0200 Subject: [PATCH 5/5] Update `README.md` --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 58b54cb..9d1cecc 100644 --- a/README.md +++ b/README.md @@ -290,7 +290,8 @@ public function index() ->usingScopes([ // new EmailVerifiedScope, // Global Scope in object EmailVerifiedScope::class, // Global Scope in string - 'isAdmin' // Local Scope + // 'isAdmin', // Local Scope + 'isAdmin' => [false], // Local Scope With Parameters ]) ->execute() ->get();