Skip to content

Commit

Permalink
feat(Database): Add OrderByValuesScope for ordering by values in give…
Browse files Browse the repository at this point in the history
…n order
  • Loading branch information
pionl committed Jul 8, 2023
1 parent fbf2937 commit 0583ac8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/Database/Scopes/OrderByValuesScope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Database\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class OrderByValuesScope extends AbstractScope
{
/**
* @param array<string|int> $values
*/
public function __construct(
private readonly array $values,
private readonly string $column
) {
}

public function apply(Builder $builder, Model $model): void
{
$placeholders = array_map(static fn () => '?', $this->values);

$builder->orderByRaw(
'FIELD(`' . $this->column . '`, ' . implode(', ', $placeholders) . ') DESC',
$this->values
);
}
}
27 changes: 27 additions & 0 deletions tests/Feature/Database/Scopes/OrderByValuesScopeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Database\Scopes;

use Illuminate\Database\Eloquent\SoftDeletingScope;
use LaraStrict\Database\Scopes\OrderByValuesScope;
use Tests\LaraStrict\Feature\Database\Models\Test;
use Tests\LaraStrict\Feature\TestCase;

class OrderByValuesScopeTest extends TestCase
{
public function testApply(): void
{
$query = Test::query()
->withoutGlobalScope(new SoftDeletingScope())
->withGlobalScope('test', new OrderByValuesScope(['1', 2, 's33'], Test::AttributeTest));

$this->assertEquals(
expected: 'select * from "tests" order by FIELD(`test`, ?, ?, ?) DESC',
actual: $query->toSql()
);

$this->assertEquals(expected: ['1', 2, 's33'], actual: $query->getBindings());
}
}

0 comments on commit 0583ac8

Please sign in to comment.