OrderByBuilder::addOrder()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
namespace Kir\MySQL\Builder\Traits;
3
4
use Kir\MySQL\Builder\Expr\OrderBySpecification;
5
6
trait OrderByBuilder {
7
	use AbstractDB;
8
9
	/** @var array<int, array{string, string}> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<int, array{string, string}> at position 6 could not be parsed: Expected ':' at position 6, but found 'string'.
Loading history...
10
	private $orderBy = [];
11
12
	/**
13
	 * @param string|OrderBySpecification $expression
14
	 * @param string&('ASC'|'DESC') $direction
0 ignored issues
show
Documentation Bug introduced by
The doc comment string&('ASC'|'DESC') at position 3 could not be parsed: Unknown type name ''ASC'' at position 3 in string&('ASC'|'DESC').
Loading history...
15
	 * @return $this
16
	 */
17
	public function orderBy($expression, string $direction = 'ASC') {
18
		if($expression instanceof OrderBySpecification) {
19
			foreach($expression->getFields() as $field) {
20
				$this->addOrder($field[0], $field[1]);
21
			}
22
			return $this;
23
		}
24
		$this->addOrder($expression, $direction);
25
		return $this;
26
	}
27
28
	/**
29
	 * @param string $fieldName
30
	 * @param array<int, int|float|string> $values
31
	 * @return $this
32
	 */
33
	public function orderByValues(string $fieldName, array $values) {
34
		$expr = [];
35
		foreach(array_values($values) as $idx => $value) {
36
			$expr[] = $this->db()->quoteExpression("WHEN ? THEN ?", [$value, $idx]);
37
		}
38
		$this->orderBy[] = [sprintf("CASE %s\n\t\t%s\n\tEND", $this->db()->quoteField($fieldName), implode("\n\t\t", $expr)), 'ASC'];
39
		return $this;
40
	}
41
42
	/**
43
	 * @return array<int, array{string, string}>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<int, array{string, string}> at position 6 could not be parsed: Expected ':' at position 6, but found 'string'.
Loading history...
44
	 */
45
	public function getOrderBy() {
46
		return $this->orderBy;
47
	}
48
49
	/**
50
	 * Removed all order information from the current layer. This dies not affect sub-selects.
51
	 *
52
	 * @return $this
53
	 */
54
	public function resetOrderBy() {
55
		$this->orderBy = [];
56
		return $this;
57
	}
58
59
	/**
60
	 * @param string $query
61
	 * @return string
62
	 */
63
	protected function buildOrder(string $query): string {
64
		if(!count($this->orderBy)) {
65
			return $query;
66
		}
67
		$query .= "ORDER BY\n";
68
		$arr = [];
69
		foreach($this->orderBy as [$expression, $direction]) {
70
			$arr[] = sprintf("\t%s %s", $expression, strtoupper($direction));
71
		}
72
		return $query.implode(",\n", $arr)."\n";
73
	}
74
75
	/**
76
	 * @param string|array<int, mixed> $expression
77
	 * @param string&('ASC'|'DESC') $direction
0 ignored issues
show
Documentation Bug introduced by
The doc comment string&('ASC'|'DESC') at position 3 could not be parsed: Unknown type name ''ASC'' at position 3 in string&('ASC'|'DESC').
Loading history...
78
	 */
79
	private function addOrder($expression, string $direction): void {
80
		$direction = $this->fixDirection($direction);
81
		if(is_array($expression)) {
82
			if(count($expression) < 1) {
83
				return;
84
			}
85
			$expr = (string) $expression[0];
86
			$expression = $this->db()->quoteExpression($expr, array_slice($expression, 1));
87
		}
88
		$this->orderBy[] = [$expression, $direction];
89
	}
90
91
	/**
92
	 * @param string $direction
93
	 * @return string&('ASC'|'DESC')
0 ignored issues
show
Documentation Bug introduced by
The doc comment string&('ASC'|'DESC') at position 3 could not be parsed: Unknown type name ''ASC'' at position 3 in string&('ASC'|'DESC').
Loading history...
94
	 */
95
	private function fixDirection(string $direction): string {
96
		return strtoupper($direction) !== 'ASC' ? 'DESC' : 'ASC';
97
	}
98
}
99