Test Failed
Pull Request — master (#61)
by Jean-Christophe
16:59
created

DAO::connect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

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