Passed
Push — master ( 08d2f1...651967 )
by Jean-Christophe
06:00
created

DAO::getManyToMany()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.0113

Importance

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