DAOUQueries::uParseExpression()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 0
Metric Value
eloc 10
c 0
b 0
f 0
dl 0
loc 11
ccs 9
cts 10
cp 0.9
rs 9.9332
cc 3
nc 3
nop 9
crap 3.009

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\orm\OrmUtils;
6
use Ubiquity\orm\parser\ConditionParser;
7
use Ubiquity\db\Database;
8
use Ubiquity\db\SqlUtils;
9
10
/**
11
 * Ubiquity\orm\traits$DAOUQueries
12
 * This class is part of Ubiquity
13
 *
14
 * @author jc
15
 * @version 1.0.3
16
 *
17
 */
18
trait DAOUQueries {
19
	protected static $annotFieldsInRelations = [];
20
21
	abstract protected static function _getAll(Database $db, $className, ConditionParser $conditionParser, $included = true, $useCache = null);
22
23
	abstract protected static function _getOne(Database $db, $className, ConditionParser $conditionParser, $included, $useCache);
24
25 11
	protected static function uParse($db, $className, &$ucondition, $quote, &$fields = null) {
26 11
		$expressions = self::uGetExpressions($ucondition);
27 11
		$condition = "";
28 11
		$aliases = [];
29 11
		foreach ($expressions as $expression) {
30 4
			$expressionArray = \explode(".", $expression);
31 4
			self::uParseExpression($db, $className, $expression, $expressionArray, $condition, $ucondition, $aliases, $quote, $fields);
32
		}
33 11
		return $condition;
34
	}
35
36 4
	protected static function uParseExpression($db, $className, $expression, &$expressionArray, &$condition, &$ucondition, &$aliases, $quote, &$fields = null) {
37 4
		$relations = self::getAnnotFieldsInRelations($className);
38 4
		$field = \array_shift($expressionArray);
39 4
		if (isset ($relations [$field])) {
40 4
			$jSQL = OrmUtils::getUJoinSQL($db, $className, $relations [$field], $field, $aliases, $quote);
41 4
			$condition .= ' ' . $jSQL ['sql'];
42 4
			if (\count($expressionArray) === 1) {
43 4
				$ucondition = \preg_replace('/(^|\s|\()' . $expression . '/', "\$1{$jSQL['alias']}." . $expressionArray [0], $ucondition);
44 4
				$fields[$expression] = $jSQL['alias'] . '.' . $expressionArray[0];
45
			} else {
46
				self::uParseExpression($db, $jSQL ['class'], $expression, $expressionArray, $condition, $ucondition, $aliases, $quote, $fields);
47
			}
48
		}
49
	}
50
51 4
	protected static function getAnnotFieldsInRelations($className) {
52 4
		if (!isset (self::$annotFieldsInRelations [$className])) {
53 1
			return self::$annotFieldsInRelations [$className] = OrmUtils::getAnnotFieldsInRelations($className);
54
		}
55 3
		return self::$annotFieldsInRelations [$className];
56
	}
57
58 11
	protected static function uGetExpressions($condition) {
59 11
		$condition = \preg_replace('@(["\']([^"\']|""|\'\')*["\'])@', "%values%", $condition);
60 11
		\preg_match_all('@[a-zA-Z_$][a-zA-Z_$0-9]*(?:\.[a-zA-Z_$\*][a-zA-Z_$0-9\*]*)+@', $condition, $matches);
61 11
		if (\count($matches) > 0) {
62 11
			return \array_unique($matches [0]);
63
		}
64
		return [];
65
	}
66
67
	/**
68
	 * Returns an array of $className objects from the database
69
	 *
70
	 * @param string $className class name of the model to load
71
	 * @param string $ucondition UQL condition
72
	 * @param boolean|array $included if true, loads associated members with associations, if array, example : ["client.*","commands"]
73
	 * @param array|null $parameters the request parameters
74
	 * @param boolean $useCache use the active cache if true
75
	 * @return array
76
	 */
77 8
	public static function uGetAll($className, $ucondition = '', $included = true, $parameters = null, $useCache = null) {
78 8
		$db = self::getDb($className);
79 8
		$firstPart = self::uParse($db, $className, $ucondition, $db->quote);
80 8
		return self::_getAll($db, $className, new ConditionParser ($ucondition, $firstPart, $parameters), $included, $useCache);
81
	}
82
83
	/**
84
	 * Returns the number of objects of $className from the database respecting the condition possibly passed as parameter
85
	 *
86
	 * @param string $className complete classname of the model to load
87
	 * @param string $ucondition Part following the WHERE of an SQL statement
88
	 * @param array|null $parameters The query parameters
89
	 * @return int|boolean count of objects
90
	 */
91 2
	public static function uCount($className, $ucondition = '', $parameters = null) {
92 2
		$db = self::getDb($className);
93 2
		$quote = $db->quote;
94 2
		$condition = self::uParse($db, $className, $ucondition, $quote);
95 2
		$tableName = OrmUtils::getTableName($className);
96 2
		if ($ucondition != '') {
97 2
			$ucondition = SqlUtils::checkWhere($ucondition);
98
		}
99 2
		return $db->prepareAndFetchColumn("SELECT COUNT(*) FROM {$quote}{$tableName}{$quote} " . $condition . $ucondition, $parameters, 0);
100
	}
101
102
	
103
	/**
104
	 * @param string $className
105
	 * @param string $ucondition
106
	 * @param array|null $parameters
107
	 * @param array|null $groupBy
108
	 * @param string $function
109
	 * @param string $field
110
	 * @param bool $distinct
111
	 * @return array
112
	 */
113
	public static function uAggregate(string $className, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null, string $function = 'COUNT', string $field = '*', bool $distinct = false): array {
114
		$db = self::getDb($className);
115
		$quote = $db->quote;
116
117
		if (\is_array($groupBy)) {
118
			$ucondition .= ' GROUP BY ' . \implode(', ', $groupBy);
119
		}
120
		$fieldsMap = [];
121
		$firstPart = self::uParse($db, $className, $ucondition, $quote, $fieldsMap);
122
123
		$field = $fieldsMap[$field] ?? $field;
124
		if ($distinct) {
125
			$field = 'DISTINCT ' . $field;
126
		}
127
		$fieldsInSelect = $function . "($field) AS result";
128
129
		if (\is_array($groupBy)) {
130
			foreach ($groupBy as $index => $field) {
131
				if (\is_int($index)) {
132
					$fieldsInSelect .= ',' . ($fieldsMap[$field] ?? $field);
133
				} else {
134
					$fieldsInSelect .= ',' . ($fieldsMap[$field] ?? $field) . " AS {$quote}{$index}{$quote}";
135
				}
136
			}
137
		}
138
		$tableName = OrmUtils::getTableName($className);
139
		if ($ucondition != '' && !\str_starts_with($ucondition, ' GROUP BY')) {
140
			$ucondition = SqlUtils::checkWhere($ucondition);
141
		}
142
		return $db->prepareAndFetchAll("SELECT {$fieldsInSelect} FROM {$quote}{$tableName}{$quote} " . $firstPart . $ucondition, $parameters, 0);
143
	}
144
145
	/**
146
	 * @param string $className
147
	 * @param string $ucondition
148
	 * @param array|null $parameters
149
	 * @param array|null $groupBy
150
	 * @param string $countField
151
	 * @param bool $distinct
152
	 * @return array
153
	 */
154
	public static function uCountGroupBy(string $className, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null, string $countField = '*', bool $distinct = false): array {
155
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'COUNT', $countField, $distinct);
156
	}
157
158
	/**
159
	 * @param string $className
160
	 * @param string $avgField
161
	 * @param string $ucondition
162
	 * @param array|null $parameters
163
	 * @param array|null $groupBy
164
	 * @return array
165
	 */
166
	public static function uAvgGroupBy(string $className, string $avgField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
167
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'AVG', $avgField, false);
168
	}
169
170
	/**
171
	 * @param string $className
172
	 * @param string $sumField
173
	 * @param string $ucondition
174
	 * @param array|null $parameters
175
	 * @param array|null $groupBy
176
	 * @return array
177
	 */
178
	public static function uSumGroupBy(string $className, string $sumField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
179
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'SUM', $sumField, false);
180
	}
181
182
	/**
183
	 * @param string $className
184
	 * @param string $minField
185
	 * @param string $ucondition
186
	 * @param array|null $parameters
187
	 * @param array|null $groupBy
188
	 * @return array
189
	 */
190
	public static function uMinGroupBy(string $className, string $minField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
191
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'MIN', $minField, false);
192
	}
193
194
	/**
195
	 * @param string $className
196
	 * @param string $maxField
197
	 * @param string $ucondition
198
	 * @param array|null $parameters
199
	 * @param array|null $groupBy
200
	 * @return array
201
	 */
202
	public static function uMaxGroupBy(string $className, string $maxField, string $ucondition = '', ?array $parameters = null, ?array $groupBy = null) {
203
		return self::uAggregate($className, $ucondition, $parameters, $groupBy, 'MAX', $maxField, false);
204
	}
205
206
	/**
207
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key
208
	 *
209
	 * @param String $className complete classname of the model to load
210
	 * @param Array|string $ucondition primary key values or condition (UQL)
211
	 * @param boolean|array $included if true, charges associated members with association
212
	 * @param array|null $parameters the request parameters
213
	 * @param boolean $useCache use cache if true
214
	 * @return object the instance loaded or null if not found
215
	 */
216 1
	public static function uGetOne($className, $ucondition, $included = true, $parameters = null, $useCache = null) {
217 1
		$db = self::getDb($className);
218 1
		$condition = self::uParse($db, $className, $ucondition, $db->quote);
219 1
		$conditionParser = new ConditionParser ($ucondition, $condition);
220 1
		if (\is_array($parameters)) {
221 1
			$conditionParser->setParams($parameters);
222
		}
223 1
		return self::_getOne($db, $className, $conditionParser, $included, $useCache);
224
	}
225
}
226
227