51 lines
1.3 KiB
PHP
51 lines
1.3 KiB
PHP
<?php
|
|
|
|
namespace Ulmus\Query;
|
|
|
|
class OrderBy extends Fragment {
|
|
public int $order = 85;
|
|
|
|
public array $orderBy = [];
|
|
|
|
const SQL_TOKEN = "ORDER BY";
|
|
const SQL_COLLATE = "COLLATE";
|
|
|
|
# const 'NULLS LAST|FIRST' must be handlded
|
|
|
|
public function set(array $order) : self
|
|
{
|
|
$this->orderBy = $order;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function add(string|\Stringable $field, string|\Stringable|null $direction = null) : self
|
|
{
|
|
$this->validateDirectionType($direction);
|
|
|
|
$this->orderBy[] = [ $field, $direction ];
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function render() : string
|
|
{
|
|
$list = array_map(function($item) {
|
|
list($field, $direction) = $item;
|
|
|
|
return implode(' ', array_filter([ $field , $direction ?? null ] ));
|
|
}, $this->orderBy);
|
|
|
|
return $this->renderSegments([
|
|
static::SQL_TOKEN, implode(", ", $list)
|
|
]);
|
|
}
|
|
|
|
protected function validateDirectionType(mixed $direction) {
|
|
# Could be coming from user-input, we must whitelist
|
|
if (is_string($direction) && ! in_array(strtoupper($direction), [ 'ASC', 'DESC' ])) {
|
|
throw new \Ulmus\Exception\InvalidFieldType(sprintf("Validation of string `%s` failed from query `%s`", $direction, get_class($this)));
|
|
}
|
|
}
|
|
}
|