Test Failed
Push — master ( 4c5444...c0dc60 )
by Jean-Christophe
10:38
created

DAO   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Test Coverage

Coverage 81.13%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 42
eloc 100
c 3
b 0
f 0
dl 0
loc 272
ccs 86
cts 106
cp 0.8113
rs 9.0399

16 Methods

Rating   Name   Duplication   Size   Complexity  
A affectsManyToManys() 0 6 3
A getConditionParser() 0 9 2
A getAll() 0 2 1
A startDatabase() 0 4 2
A paginate() 0 5 2
A isConnected() 0 2 3
A getById() 0 2 1
A closeDb() 0 2 1
A getManyToOne() 0 21 6
A setTransformerOp() 0 2 1
A getOne() 0 11 3
A connect() 0 7 2
A count() 0 5 2
A getRownum() 0 11 2
A getManyToMany() 0 17 5
A getOneToMany() 0 17 6

How to fix   Complexity   

Complex Class

Complex classes like DAO often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DAO, and based on these observations, apply Extract Interface, too.

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