Skip to content

Commit

Permalink
Adjust scopes to account for default ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
Torann committed Dec 12, 2023
1 parent 23f0e67 commit e861809
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
- `Torann\LaravelRepository\Repositories\AbstractRepository` renamed to `Torann\LaravelRepository\Repository`
- `Torann\LaravelRepository\Traits\Cacheable` renamed to `Torann\LaravelRepository\Concerns\Cacheable`
- Updated existing and added missing type declarations
- `orderBy()` can only be applied once (intended limitation)
58 changes: 45 additions & 13 deletions src/Concerns/Ordering.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,32 @@ trait Ordering
protected array $orderBy = [];

/**
* One time skip of ordering. This is done when the
* ordering is overwritten by the orderBy method.
* Override of default order by column and direction pairs.
*/
protected bool $skipOrderingOnce = false;
protected array|null $orderByOverride = null;

/**
* {@inheritDoc}
*/
public function orderBy(mixed $column, string|null $direction): static
{
// Ensure the sort is valid
if (in_array($column, $this->getOrderableKeys()) === false) {
return $this;
if (in_array($column, $this->getOrderableKeys())) {
$this->orderByOverride = [];

$this->orderByOverride[$column] = in_array(strtolower($direction ?? ''), ['desc', 'asc'])
? $direction
: 'asc';
}

/** @var Scope|null $scope */
if ($scope = $this->resolveScope('order_by')) {
$this->skipOrderingOnce = true;
return $this;
}

$this->addScopeQuery($scope::make(
Arr::get($this->getOrderable(), $column, $column), $direction
));
}
/**
* @return static
*/
public function resetOrderBy(): static
{
$this->orderByOverride = null;

return $this;
}
Expand All @@ -64,6 +67,16 @@ public function setOrderBy(array $order_by): static
* @return array
*/
public function getOrderBy(): array
{
return $this->orderByOverride ?? $this->getDefaultOrderBy();
}

/**
* Return the default order by array.
*
* @return array
*/
public function getDefaultOrderBy(): array
{
return $this->orderBy;
}
Expand Down Expand Up @@ -117,6 +130,25 @@ public function getOrderableKeys(): array
}, $return, array_keys($return)));
}

/**
* @param string $column
* @param string $direction
*
* @return $this
*/
protected function applyOrderableScope(string $column, string $direction): static
{
/** @var Scope|null $scope */
if ($scope = $this->resolveScope('order_by')) {
$this->addScopeQuery($scope::make(
Arr::get($this->getOrderable(), $column, $column),
$direction
), 'order_by');
}

return $this;
}

/**
* Add aa order by join to the query.
*
Expand Down
14 changes: 12 additions & 2 deletions src/Concerns/Scopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,22 @@ public function getScopeQuery(): array
* Add query scope.
*
* @param Closure|Scope $scope
* @param string|null $key
*
* @return static
*/
public function addScopeQuery(Closure|Scope $scope): static
public function addScopeQuery(Closure|Scope $scope, string $key = null): static
{
$this->scopeQuery[] = $scope;
if ($scope instanceof Scope && $scope->shouldSkip()) {
return $this;
}

// Prevent dupes when using some scopes
if ($key) {
$this->scopeQuery[$key] = $scope;
} else {
$this->scopeQuery[] = $scope;
}

return $this;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Concerns/Searching.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ public function search(string|array|null $queries): static
];
}

if (is_array($queries)) {
if (is_array($queries) && empty($queries) === false) {
/** @var Scope|null $scope */
if ($scope = $this->resolveScope('search')) {
$this->addScopeQuery($scope::make($queries));
$this->addScopeQuery($scope::make($queries), 'search');
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/Contracts/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ interface Scope
*/
public static function make(...$arguments): static;

/**
* Determine if the scope be skipped
*
* @return bool
*/
public function shouldSkip(): bool;

/**
* Apply the scope
*
Expand Down
14 changes: 7 additions & 7 deletions src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ public function newQuery(bool $skipOrdering = false): static

$this->query = $this->getNew()->newQuery();

// Apply order by
if ($skipOrdering === false && $this->skipOrderingOnce === false) {
foreach ($this->getOrderBy() as $column => $dir) {
$this->query->orderBy($column, $dir);
// Apply order by scope. Only one order by is allowed, for more create a
// new scope or override the method.
if ($skipOrdering === false) {
if (empty($order_by = $this->getOrderBy()) === false) {
$this->applyOrderableScope(
key($order_by), reset($order_by)
);
}
}

// Reset the one time skip
$this->skipOrderingOnce = false;

$this->applyScope();

return $this;
Expand Down
8 changes: 8 additions & 0 deletions src/Scopes/OrderBy.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ public function __construct(mixed $column, string|null $direction)
$this->setDirection($direction);
}

/**
* {@inheritDoc}
*/
public function shouldSkip(): bool
{
return false;
}

/**
* {@inheritDoc}
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Scopes/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public function __construct(array $queries)
});
}

/**
* {@inheritDoc}
*/
public function shouldSkip(): bool
{
return empty($this->queries);
}

/**
* {@inheritDoc}
*/
Expand Down

0 comments on commit e861809

Please sign in to comment.