Skip to content

Commit

Permalink
API Create sortRaw() method to handle raw SQL
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Nov 30, 2022
1 parent 7860e46 commit ed5a005
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
38 changes: 34 additions & 4 deletions src/ORM/DataList.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,35 @@ public function distinct($value)
* @param string|array Escaped SQL statement. If passed as array, all keys and values are assumed to be escaped.
* @return static
*/
public function sort()
public function sort(...$args)
{
$count = func_num_args();
return $this->sortInner(false, $args);
}

/**
* The same as sort(), though allows raw SQL to be used for sorting
*
* Return a new DataList instance as a copy of this data list with the sort
* order set.
*
* @see SS_List::sort()
* @see SQLSelect::orderby
* @example $list = $list->sort('Name'); // default ASC sorting
* @example $list = $list->sort('Mod(ID, 3) ASC, Name ASC'); // Raw SQL sort
* @example $list = $list->sort('Name', 'ASC');
* @example $list = $list->sort(array('Name'=>'ASC', 'Age'=>'DESC'));
*
* @param string|array Escaped SQL statement. If passed as array, all keys and values are assumed to be escaped.
* @return static
*/
public function sortRaw(...$args)
{
return $this->sortInner(true, $args);
}

private function sortInner(bool $allowRawSql, array $args)
{
$count = count($args);

if ($count == 0) {
return $this;
Expand All @@ -336,7 +362,7 @@ public function sort()
if ($count == 2) {
$col = null;
$dir = null;
list($col, $dir) = func_get_args();
list($col, $dir) = $args;

// Validate direction
if (!in_array(strtolower($dir ?? ''), ['desc', 'asc'])) {
Expand All @@ -345,12 +371,16 @@ public function sort()

$sort = [$col => $dir];
} else {
$sort = func_get_arg(0);
$sort = $args[0];
}

return $this->alterDataQuery(function (DataQuery $query, DataList $list) use ($sort) {

if (is_string($sort) && $sort) {
// TODO:
// this is raw sql - validate it matches "Name ASC, ID DESC" style if !$allowRawSql
// also validate that column exists - note: "This is a - (legit) column name" so
// regex will not work for validation
if (false !== stripos($sort ?? '', ' asc') || false !== stripos($sort ?? '', ' desc')) {
$query->sort($sort);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/ORM/DataQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ public function whereAny($filter)
* @param string $direction Direction ("ASC" or "DESC", escaped SQL statement)
* @param bool $clear Clear existing values
* @return $this
*
*/
public function sort($sort = null, $direction = null, $clear = true)
{
Expand Down

0 comments on commit ed5a005

Please sign in to comment.