Test Failed
Push — master ( e0ce72...f60d90 )
by Jean-Christophe
12:21
created

DAO::connect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 6
c 2
b 0
f 0
dl 0
loc 7
rs 10
ccs 3
cts 3
cp 1
cc 2
nc 2
nop 10
crap 2

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;
4
5
use Ubiquity\db\Database;
6
use Ubiquity\log\Logger;
7
use Ubiquity\orm\parser\ManyToManyParser;
8
use Ubiquity\db\SqlUtils;
9
use Ubiquity\orm\traits\DAOUpdatesTrait;
10
use Ubiquity\orm\traits\DAORelationsTrait;
11
use Ubiquity\orm\parser\ConditionParser;
12
use Ubiquity\orm\traits\DAOUQueries;
13
use Ubiquity\orm\traits\DAOCoreTrait;
14
use Ubiquity\orm\traits\DAORelationsPrepareTrait;
15
use Ubiquity\exceptions\DAOException;
16
use Ubiquity\orm\traits\DAORelationsAssignmentsTrait;
17
use Ubiquity\orm\parser\Reflexion;
18
use Ubiquity\orm\traits\DAOTransactionsTrait;
19
use Ubiquity\controllers\Startup;
20
use Ubiquity\cache\CacheManager;
21
use Ubiquity\orm\traits\DAOPooling;
22
23
/**
24
 * Gateway class between database and object model.
25
 * This class is part of Ubiquity
26
 *
27
 * @author jcheron <[email protected]>
28
 * @version 1.2.1
29
 *
30
 */
31
class DAO {
32
	use DAOCoreTrait,DAOUpdatesTrait,DAORelationsTrait,DAORelationsPrepareTrait,DAORelationsAssignmentsTrait,
33
	DAOUQueries,DAOTransactionsTrait,DAOPooling;
34
35
	/**
36
	 *
37
	 * @var Database
38
	 */
39
	public static $db;
40
	public static $useTransformers = false;
41
	public static $transformerOp = 'transform';
42
	private static $conditionParsers = [ ];
43
	protected static $modelsDatabase = [ ];
44 76
45 76
	protected static function getDb($model) {
46
		return self::getDatabase ( self::$modelsDatabase [$model] ?? 'default');
47
	}
48
49
	/**
50
	 * Loads member associated with $instance by a ManyToOne relationship
51
	 *
52
	 * @param object|array $instance The instance object or an array with [classname,id]
53
	 * @param string $member The member to load
54
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
55
	 * @param boolean|null $useCache
56
	 */
57
	public static function getManyToOne($instance, $member, $included = false, $useCache = NULL) {
58
		$classname = self::getClass_ ( $instance );
59
		if (is_array ( $instance )) {
60
			$instance = self::getById ( $classname, $instance [1], false, $useCache );
61
		}
62
		$fieldAnnot = OrmUtils::getMemberJoinColumns ( $classname, $member );
63
		if ($fieldAnnot !== null) {
64
			$annotationArray = $fieldAnnot [1];
65
			$member = $annotationArray ["member"];
66
			$value = Reflexion::getMemberValue ( $instance, $member );
67
			$key = OrmUtils::getFirstKey ( $annotationArray ["className"] );
68
			$kv = array ($key => $value );
69
			$obj = self::getById ( $annotationArray ["className"], $kv, $included, $useCache );
70
			if ($obj !== null) {
71
				Logger::info ( "DAO", "Loading the member " . $member . " for the object " . $classname, "getManyToOne" );
72
				$accesseur = "set" . ucfirst ( $member );
73
				if (is_object ( $instance ) && method_exists ( $instance, $accesseur )) {
74
					$instance->$accesseur ( $obj );
75
					$instance->_rest [$member] = $obj->_rest;
76
				}
77
				return $obj;
78 5
			}
79 5
		}
80 5
	}
81 1
82
	/**
83 5
	 * Assign / load the child records in the $member member of $instance.
84 5
	 *
85 5
	 * @param object|array $instance The instance object or an array with [classname,id]
86 5
	 * @param string $member Member on which a oneToMany annotation must be present
87 5
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
88 5
	 * @param boolean $useCache
89 5
	 * @param array $annot used internally
90 5
	 */
91 5
	public static function getOneToMany($instance, $member, $included = true, $useCache = NULL, $annot = null) {
92 5
		$ret = array ();
93 5
		$class = self::getClass_ ( $instance );
94 5
		if (! isset ( $annot )) {
95 5
			$annot = OrmUtils::getAnnotationInfoMember ( $class, "#oneToMany", $member );
96 5
		}
97
		if ($annot !== false) {
98 5
			$fkAnnot = OrmUtils::getAnnotationInfoMember ( $annot ["className"], "#joinColumn", $annot ["mappedBy"] );
99
			if ($fkAnnot !== false) {
100
				$fkv = self::getFirstKeyValue_ ( $instance );
101
				$db = self::getDb ( $annot ["className"] );
102
				$ret = self::_getAll ( $db, $annot ["className"], ConditionParser::simple ( $db->quote . $fkAnnot ["name"] . $db->quote . "= ?", $fkv ), $included, $useCache );
103
				if (is_object ( $instance ) && $modifier = self::getAccessor ( $member, $instance, 'getOneToMany' )) {
104
					self::setToMember ( $member, $instance, $ret, $modifier );
105
				}
106
			}
107
		}
108
		return $ret;
109
	}
110
111
	/**
112 8
	 * Assigns / loads the child records in the $member member of $instance.
113 8
	 * If $array is null, the records are loaded from the database
114 8
	 *
115 8
	 * @param object|array $instance The instance object or an array with [classname,id]
116 8
	 * @param string $member Member on which a ManyToMany annotation must be present
117
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
118 8
	 * @param array $array optional parameter containing the list of possible child records
119 8
	 * @param boolean $useCache
120 8
	 */
121 8
	public static function getManyToMany($instance, $member, $included = false, $array = null, $useCache = NULL) {
122 8
		$ret = [ ];
123 8
		$class = self::getClass_ ( $instance );
124 8
		$parser = new ManyToManyParser ( $class, $member );
125 7
		if ($parser->init ()) {
126
			if (is_null ( $array )) {
127
				$pk = self::getFirstKeyValue_ ( $instance );
128
				$quote = SqlUtils::$quote;
129 8
				$condition = " INNER JOIN " . $quote . $parser->getJoinTable () . $quote . " on " . $quote . $parser->getJoinTable () . $quote . "." . $quote . $parser->getFkField () . $quote . "=" . $quote . $parser->getTargetEntityTable () . $quote . "." . $quote . $parser->getPk () . $quote . " WHERE " . $quote . $parser->getJoinTable () . $quote . "." . $quote . $parser->getMyFkField () . $quote . "= ?";
130
				$targetEntityClass = $parser->getTargetEntityClass ();
131
				$ret = self::_getAll ( self::getDb ( $targetEntityClass ), $targetEntityClass, ConditionParser::simple ( $condition, $pk ), $included, $useCache );
132
			} else {
133
				$ret = self::getManyToManyFromArray ( $instance, $array, $class, $parser );
134
			}
135
			if (is_object ( $instance ) && $modifier = self::getAccessor ( $member, $instance, 'getManyToMany' )) {
136
				self::setToMember ( $member, $instance, $ret, $modifier );
137
			}
138
		}
139
		return $ret;
140
	}
141
142 5
	/**
143 5
	 *
144 5
	 * @param object $instance
145 5
	 * @param array $array
146 5
	 * @param boolean $useCache
147 5
	 */
148 5
	public static function affectsManyToManys($instance, $array = NULL, $useCache = NULL) {
149 5
		$metaDatas = OrmUtils::getModelMetadata ( \get_class ( $instance ) );
150 5
		$manyToManyFields = $metaDatas ["#manyToMany"];
151 5
		if (\sizeof ( $manyToManyFields ) > 0) {
152 5
			foreach ( $manyToManyFields as $member ) {
153
				self::getManyToMany ( $instance, $member, false, $array, $useCache );
154
			}
155
		}
156 5
	}
157 4
158
	/**
159
	 * Returns an array of $className objects from the database
160 5
	 *
161
	 * @param string $className class name of the model to load
162
	 * @param string $condition Part following the WHERE of an SQL statement
163
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
164
	 * @param array|null $parameters
165
	 * @param boolean $useCache use the active cache if true
166
	 * @return array
167
	 */
168
	public static function getAll($className, $condition = '', $included = true, $parameters = null, $useCache = NULL) {
169
		return self::_getAll ( self::getDb ( $className ), $className, new ConditionParser ( $condition, null, $parameters ), $included, $useCache );
170
	}
171
172
	public static function paginate($className, $page = 1, $rowsPerPage = 20, $condition = null, $included = true) {
173
		if (! isset ( $condition )) {
174
			$condition = "1=1";
175
		}
176
		return self::getAll ( $className, $condition . " LIMIT " . $rowsPerPage . " OFFSET " . (($page - 1) * $rowsPerPage), $included );
177
	}
178
179
	public static function getRownum($className, $ids) {
180
		$tableName = OrmUtils::getTableName ( $className );
181
		$db = self::getDb ( $className );
182
		$quote = $db->quote;
183
		self::parseKey ( $ids, $className, $quote );
184
		$condition = SqlUtils::getCondition ( $ids, $className );
185
		$keyFields = OrmUtils::getKeyFields ( $className );
186
		if (is_array ( $keyFields )) {
187
			$keys = implode ( ",", $keyFields );
188
		} else {
189 25
			$keys = "1";
190 25
		}
191
192
		return $db->queryColumn ( "SELECT num FROM (SELECT *, @rownum:=@rownum + 1 AS num FROM {$quote}{$tableName}{$quote}, (SELECT @rownum:=0) r ORDER BY {$keys}) d WHERE " . $condition );
193 3
	}
194 3
195 1
	/**
196
	 * Returns the number of objects of $className from the database respecting the condition possibly passed as parameter
197 3
	 *
198
	 * @param string $className complete classname of the model to load
199
	 * @param string $condition Part following the WHERE of an SQL statement
200 4
	 * @param array|null $parameters The query parameters
201 4
	 * @return int|false count of objects
202 4
	 */
203 4
	public static function count($className, $condition = '', $parameters = null) {
204 4
		$tableName = OrmUtils::getTableName ( $className );
205 4
		if ($condition != '') {
206 4
			$condition = " WHERE " . $condition;
207 4
		}
208 4
		$db = self::getDb ( $className );
209
		$quote = $db->quote;
210
		return $db->prepareAndFetchColumn ( "SELECT COUNT(*) FROM " . $quote . $tableName . $quote . $condition, $parameters );
211
	}
212
213 4
	/**
214
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key or with a condition
215
	 *
216
	 * @param String $className complete classname of the model to load
217
	 * @param Array|string $condition condition or primary key values
218
	 * @param boolean|array $included if true, charges associate members with association
219
	 * @param array|null $parameters the request parameters
220
	 * @param boolean|null $useCache use cache if true
221
	 * @return object the instance loaded or null if not found
222
	 */
223
	public static function getOne($className, $condition, $included = true, $parameters = null, $useCache = NULL) {
224 21
		$conditionParser = new ConditionParser ();
225 21
		if (! isset ( $parameters )) {
226 21
			$conditionParser->addKeyValues ( $condition, $className );
227 9
		} elseif (! is_array ( $condition )) {
228
			$conditionParser->setCondition ( $condition );
229 21
			$conditionParser->setParams ( $parameters );
230 21
		} else {
231 21
			throw new DAOException ( "The \$keyValues parameter should not be an array if \$parameters is not null" );
232
		}
233
		return self::_getOne ( self::getDb ( $className ), $className, $conditionParser, $included, $useCache );
234
	}
235
236
	/**
237
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key
238
	 *
239
	 * @param String $className complete classname of the model to load
240
	 * @param Array|string $keyValues primary key values or condition
241
	 * @param boolean|array $included if true, charges associate members with association
242
	 * @param array|null $parameters the request parameters
243
	 * @param boolean|null $useCache use cache if true
244 20
	 * @return object the instance loaded or null if not found
245 20
	 */
246 20
	public static function getById($className, $keyValues, $included = true, $useCache = NULL) {
247 20
		return self::_getOne ( self::getDb ( $className ), $className, self::getConditionParser ( $className, $keyValues ), $included, $useCache );
248
	}
249
250
	protected static function getConditionParser($className, $keyValues) {
251
		if (! isset ( self::$conditionParsers [$className] )) {
252
			$conditionParser = new ConditionParser ();
253
			$conditionParser->addKeyValues ( $keyValues, $className );
254 20
			self::$conditionParsers [$className] = $conditionParser;
255
		} else {
256
			self::$conditionParsers [$className]->setKeyValues ( $keyValues );
257
		}
258
		return self::$conditionParsers [$className];
259
	}
260
261
	/**
262
	 * Establishes the connection to the database using the past parameters
263
	 *
264
	 * @param string $offset
265
	 * @param string $wrapper
266
	 * @param string $dbType
267 23
	 * @param string $dbName
268 23
	 * @param string $serverName
269
	 * @param string $port
270
	 * @param string $user
271 23
	 * @param string $password
272 23
	 * @param array $options
273 14
	 * @param boolean $cache
274 14
	 */
275 14
	public static function connect($offset, $wrapper, $dbType, $dbName, $serverName = '127.0.0.1', $port = '3306', $user = 'root', $password = '', $options = [], $cache = false) {
276
		self::$db [$offset] = new Database ( $wrapper, $dbType, $dbName, $serverName, $port, $user, $password, $options, $cache, self::$pool );
277 11
		try {
278
			self::$db [$offset]->connect ();
279 23
		} catch ( \Exception $e ) {
280
			Logger::error ( "DAO", $e->getMessage () );
281
			throw new DAOException ( $e->getMessage (), $e->getCode (), $e->getPrevious () );
282
		}
283
	}
284
285
	/**
286
	 * Establishes the connection to the database using the $config array
287
	 *
288
	 * @param array $config the config array (Startup::getConfig())
289
	 */
290
	public static function startDatabase(&$config, $offset = null) {
291
		$db = $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
292
		if ($db ['dbName'] !== '') {
293
			self::connect ( $offset ?? 'default', $db ['wrapper'] ?? \Ubiquity\db\providers\pdo\PDOWrapper::class, $db ['type'], $db ['dbName'], $db ['serverName'] ?? '127.0.0.1', $db ['port'] ?? 3306, $db ['user'] ?? 'root', $db ['password'] ?? '', $db ['options'] ?? [ ], $db ['cache'] ?? false);
294
		}
295
	}
296 74
297 74
	public static function getDbOffset(&$config, $offset = null) {
298
		return $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
299 74
	}
300
301
	/**
302
	 * Returns true if the connection to the database is established
303
	 *
304 74
	 * @return boolean
305
	 */
306
	public static function isConnected($offset = 'default') {
307
		$db = self::$db [$offset] ?? false;
308
		return $db && ($db instanceof Database) && $db->isConnected ();
309
	}
310
311 21
	/**
312 21
	 * Sets the transformer operation
313 21
	 *
314 21
	 * @param string $op
315
	 */
316 21
	public static function setTransformerOp($op) {
317
		self::$transformerOp = $op;
318 119
	}
319 119
320
	/**
321
	 * Closes the active pdo connection to the database
322
	 */
323
	public static function closeDb($offset = 'default') {
324
		$db = self::$db [$offset] ?? false;
325
		if ($db !== false) {
326
			$db->close ();
327 5
		}
328 5
	}
329 5
330
	/**
331
	 * Defines the database connection to use for $model class
332
	 *
333
	 * @param string $model a model class
334
	 * @param string $database a database connection defined in config.php
335
	 */
336
	public static function setModelDatabase($model, $database = 'default') {
337
		self::$modelsDatabase [$model] = $database;
338
	}
339
340
	/**
341
	 * Defines the database connections to use for models classes
342
	 *
343
	 * @param array $modelsDatabase
344 32
	 */
345 32
	public static function setModelsDatabases($modelsDatabase) {
346 32
		self::$modelsDatabase = $modelsDatabase;
347 32
	}
348
349 32
	/**
350
	 * Returns the database instance defined at $offset key in config
351
	 *
352
	 * @param string $offset
353
	 * @return \Ubiquity\db\Database
354
	 */
355
	public static function getDatabase($offset = 'default') {
356
		if (! isset ( self::$db [$offset] )) {
357
			self::startDatabase ( Startup::$config, $offset );
358
		}
359
		SqlUtils::$quote = self::$db [$offset]->quote;
360
		return self::$db [$offset];
361
	}
362
363
	public static function getDatabases() {
364
		$config = Startup::getConfig ();
365
		if (isset ( $config ['database'] )) {
366 9
			if (isset ( $config ['database'] ['dbName'] )) {
367 9
				return [ 'default' ];
368 9
			} else {
369
				return \array_keys ( $config ['database'] );
370
			}
371
		}
372
		return [ ];
373
	}
374
375
	public static function updateDatabaseParams(array &$config, array $parameters, $offset = 'default') {
376 76
		if ($offset === 'default') {
377 76
			if (isset ( $config ['database'] [$offset] )) {
378 20
				foreach ( $parameters as $k => $param ) {
379
					$config ['database'] [$offset] [$k] = $param;
380 76
				}
381 76
			} else {
382
				foreach ( $parameters as $k => $param ) {
383
					$config ['database'] [$k] = $param;
384 4
				}
385 4
			}
386 4
		} else {
387 4
			if (isset ( $config ['database'] [$offset] )) {
388 4
				foreach ( $parameters as $k => $param ) {
389
					$config ['database'] [$offset] [$k] = $param;
390
				}
391
			}
392
		}
393
	}
394
395
	public static function start() {
396
		self::$modelsDatabase = CacheManager::getModelsDatabases ();
397
	}
398
}
399