OrderByBuilder::buildOrder()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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