Passed
Push — master ( caa32e...4f267a )
by Jean-Christophe
09:15
created

DAOUpdatesTrait   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 234
Duplicated Lines 0 %

Test Coverage

Coverage 52.31%

Importance

Changes 4
Bugs 0 Features 1
Metric Value
wmc 31
eloc 122
c 4
b 0
f 1
dl 0
loc 234
ccs 68
cts 130
cp 0.5231
rs 9.92

10 Methods

Rating   Name   Duplication   Size   Complexity  
A remove() 0 5 1
A save() 0 5 2
B insert() 0 36 6
A deleteAll() 0 3 1
A remove_() 0 12 3
A removeByKey_() 0 14 3
A insertOrUpdateAllManyToMany() 0 6 3
A update() 0 26 5
A delete() 0 8 2
A insertOrUpdateManyToMany() 0 30 5
1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\db\SqlUtils;
6
use Ubiquity\events\DAOEvents;
7
use Ubiquity\events\EventsManager;
8
use Ubiquity\log\Logger;
9
use Ubiquity\orm\OrmUtils;
10
use Ubiquity\orm\parser\ManyToManyParser;
11
use Ubiquity\orm\parser\Reflexion;
12
13
/**
14
 * Trait for DAO Updates (Create, Update, Delete)
15
 * Ubiquity\orm\traits$DAOUpdatesTrait
16
 * This class is part of Ubiquity
17
 *
18
 * @author jcheron <[email protected]>
19
 * @version 1.1.0
20
 * @property \Ubiquity\db\Database $db
21
 *
22
 */
23
trait DAOUpdatesTrait {
24
25
	/**
26
	 * Deletes the object $instance from the database
27
	 *
28
	 * @param object $instance instance à supprimer
29
	 */
30 8
	public static function remove($instance) {
31 8
		$className = \get_class ( $instance );
32 8
		$tableName = OrmUtils::getTableName ( $className );
33 8
		$keyAndValues = OrmUtils::getKeyFieldsAndValues ( $instance );
34 8
		return self::removeByKey_ ( $className, $tableName, $keyAndValues );
35
	}
36
37
	/**
38
	 *
39
	 * @param string $className
40
	 * @param string $tableName
41
	 * @param array $keyAndValues
42
	 * @return int the number of rows that were modified or deleted by the SQL statement you issued
43
	 */
44 8
	private static function removeByKey_($className, $tableName, $keyAndValues) {
45 8
		$db = self::getDb ( $className );
46 8
		$sql = "DELETE FROM " . $db->quote . $tableName . $db->quote . " WHERE " . SqlUtils::getWhere ( $keyAndValues );
47 8
		Logger::info ( "DAOUpdates", $sql, "delete" );
48 8
		$statement = $db->prepareStatement ( $sql );
49
		try {
50 8
			if ($statement->execute ( $keyAndValues )) {
51 7
				return $statement->rowCount ();
52
			}
53 1
		} catch ( \PDOException $e ) {
54 1
			Logger::warn ( "DAOUpdates", $e->getMessage (), "delete" );
55 1
			return;
56
		}
57
		return;
58
	}
59
60
	/**
61
	 *
62
	 * @param string $className
63
	 * @param string $tableName
64
	 * @param string $where
65
	 * @return boolean|int the number of rows that were modified or deleted by the SQL statement you issued
66
	 */
67
	private static function remove_($className, $tableName, $where) {
68
		$db = self::getDb ( $className );
69
		$sql = "DELETE FROM " . $db->quote . $tableName . $db->quote . " " . SqlUtils::checkWhere ( $where );
70
		Logger::info ( "DAOUpdates", $sql, "delete" );
71
		$statement = $db->prepareStatement ( $sql );
72
		try {
73
			if ($statement->execute ()) {
74
				return $statement->rowCount ();
75
			}
76
		} catch ( \PDOException $e ) {
77
			Logger::warn ( "DAOUpdates", $e->getMessage (), "delete" );
78
			return false;
79
		}
80
	}
81
82
	/**
83
	 * Deletes all instances from $modelName matching the condition $where
84
	 *
85
	 * @param string $modelName
86
	 * @param string $where
87
	 * @return int|boolean
88
	 */
89
	public static function deleteAll($modelName, $where) {
90
		$tableName = OrmUtils::getTableName ( $modelName );
91
		return self::remove_ ( $modelName, $tableName, $where );
92
	}
93
94
	/**
95
	 * Deletes all instances from $modelName corresponding to $ids
96
	 *
97
	 * @param string $modelName
98
	 * @param array|int $ids
99
	 * @return int|boolean
100
	 */
101
	public static function delete($modelName, $ids) {
102
		$tableName = OrmUtils::getTableName ( $modelName );
103
		$pk = OrmUtils::getFirstKey ( $modelName );
104
		if (! \is_array ( $ids )) {
105
			$ids = [ $ids ];
106
		}
107
		$where = SqlUtils::getMultiWhere ( $ids, $pk );
108
		return self::remove_ ( $modelName, $tableName, $where );
109
	}
110
111
	/**
112
	 * Inserts a new instance $instance into the database
113
	 *
114
	 * @param object $instance the instance to insert
115
	 * @param boolean $insertMany if true, save instances related to $instance by a ManyToMany association
116
	 */
117 11
	public static function insert($instance, $insertMany = false) {
118 11
		EventsManager::trigger ( 'dao.before.insert', $instance );
119 11
		$className = \get_class ( $instance );
120 11
		$db = self::getDb ( $className );
121 11
		$quote = $db->quote;
122 11
		$tableName = OrmUtils::getTableName ( $className );
123 11
		$keyAndValues = Reflexion::getPropertiesAndValues ( $instance );
124 11
		$keyAndValues = array_merge ( $keyAndValues, OrmUtils::getManyToOneMembersAndValues ( $instance ) );
125 11
		$sql = "INSERT INTO " . $quote . $tableName . $quote . " (" . SqlUtils::getInsertFields ( $keyAndValues ) . ") VALUES(" . SqlUtils::getInsertFieldsValues ( $keyAndValues ) . ")";
126 11
		if (Logger::isActive ()) {
127 11
			Logger::info ( "DAOUpdates", $sql, "insert" );
128 11
			Logger::info ( "DAOUpdates", \json_encode ( $keyAndValues ), "Key and values" );
129
		}
130
131 11
		$statement = $db->getUpdateStatement ( $sql );
132
		try {
133 11
			$result = $statement->execute ( $keyAndValues );
134 11
			if ($result) {
135 11
				$pk = OrmUtils::getFirstKey ( $className );
136 11
				$accesseurId = "set" . \ucfirst ( $pk );
137 11
				$lastId = $db->lastInserId ();
138 11
				if ($lastId != 0) {
139 11
					$instance->$accesseurId ( $lastId );
140 11
					$instance->_rest = $keyAndValues;
141 11
					$instance->_rest [$pk] = $lastId;
142
				}
143 11
				if ($insertMany) {
144 1
					self::insertOrUpdateAllManyToMany ( $instance );
145
				}
146
			}
147 11
			EventsManager::trigger ( DAOEvents::AFTER_INSERT, $instance, $result );
148 11
			return $result;
149 1
		} catch ( \Exception $e ) {
150 1
			Logger::warn ( "DAOUpdates", $e->getMessage (), "insert" );
151
		}
152 1
		return false;
153
	}
154
155
	/**
156
	 * Updates manyToMany members
157
	 *
158
	 * @param object $instance
159
	 */
160 1
	public static function insertOrUpdateAllManyToMany($instance) {
161 1
		$members = OrmUtils::getAnnotationInfo ( get_class ( $instance ), "#manyToMany" );
162 1
		if ($members !== false) {
163
			$members = \array_keys ( $members );
164
			foreach ( $members as $member ) {
165
				self::insertOrUpdateManyToMany ( $instance, $member );
166
			}
167
		}
168 1
	}
169
170
	/**
171
	 * Updates the $member member of $instance annotated by a ManyToMany
172
	 *
173
	 * @param Object $instance
174
	 * @param String $member
175
	 */
176
	public static function insertOrUpdateManyToMany($instance, $member) {
177
		$parser = new ManyToManyParser ( $instance, $member );
178
		if ($parser->init ()) {
179
			$className = $parser->getTargetEntityClass ();
180
			$db = self::getDb ( $className );
181
			$quote = $db->quote;
182
			$myField = $parser->getMyFkField ();
183
			$field = $parser->getFkField ();
184
			$sql = "INSERT INTO {$quote}" . $parser->getJoinTable () . "{$quote}({$quote}" . $myField . "{$quote},{$quote}" . $field . "{$quote}) VALUES (:" . $myField . ",:" . $field . ");";
185
			$memberAccessor = "get" . ucfirst ( $member );
186
			$memberValues = $instance->$memberAccessor ();
187
			$myKey = $parser->getMyPk ();
188
			$myAccessorId = "get" . ucfirst ( $myKey );
189
			$accessorId = "get" . ucfirst ( $parser->getPk () );
190
			$id = $instance->$myAccessorId ();
191
			if (! is_null ( $memberValues )) {
192
				$db->execute ( "DELETE FROM {$quote}" . $parser->getJoinTable () . "{$quote} WHERE {$quote}{$myField}{$quote}='{$id}'" );
193
				$statement = $db->prepareStatement ( $sql );
194
				foreach ( $memberValues as $targetInstance ) {
195
					$foreignId = $targetInstance->$accessorId ();
196
					$foreignInstances = self::getAll ( $parser->getTargetEntity (), $quote . $parser->getPk () . $quote . "='{$foreignId}'" );
197
					if (! OrmUtils::exists ( $targetInstance, $parser->getPk (), $foreignInstances )) {
198
						self::insert ( $targetInstance, false );
199
						$foreignId = $targetInstance->$accessorId ();
200
						Logger::info ( "DAOUpdates", "Insertion d'une instance de " . get_class ( $instance ), "InsertMany" );
201
					}
202
					$db->bindValueFromStatement ( $statement, $myField, $id );
203
					$db->bindValueFromStatement ( $statement, $field, $foreignId );
204
					$statement->execute ();
205
					Logger::info ( "DAOUpdates", "Insertion des valeurs dans la table association '" . $parser->getJoinTable () . "'", "InsertMany" );
206
				}
207
			}
208
		}
209
	}
210
211
	/**
212
	 * Updates an existing $instance in the database.
213
	 * Be careful not to modify the primary key
214
	 *
215
	 * @param object $instance instance to modify
216
	 * @param boolean $updateMany Adds or updates ManyToMany members
217
	 */
218 3
	public static function update($instance, $updateMany = false) {
219 3
		EventsManager::trigger ( "dao.before.update", $instance );
220 3
		$className = \get_class ( $instance );
221 3
		$db = self::getDb ( $className );
222 3
		$quote = $db->quote;
223 3
		$tableName = OrmUtils::getTableName ( $className );
224 3
		$ColumnskeyAndValues = Reflexion::getPropertiesAndValues ( $instance );
225 3
		$ColumnskeyAndValues = array_merge ( $ColumnskeyAndValues, OrmUtils::getManyToOneMembersAndValues ( $instance ) );
226 3
		$keyFieldsAndValues = OrmUtils::getKeyFieldsAndValues ( $instance );
227 3
		$sql = "UPDATE {$quote}{$tableName}{$quote} SET " . SqlUtils::getUpdateFieldsKeyAndValues ( $ColumnskeyAndValues ) . " WHERE " . SqlUtils::getWhere ( $keyFieldsAndValues );
228 3
		if (Logger::isActive ()) {
229 3
			Logger::info ( "DAOUpdates", $sql, "update" );
230 3
			Logger::info ( "DAOUpdates", json_encode ( $ColumnskeyAndValues ), "Key and values" );
231
		}
232 3
		$statement = $db->getUpdateStatement ( $sql );
233
		try {
234 3
			$result = $statement->execute ( $ColumnskeyAndValues );
235 3
			if ($result && $updateMany)
236 1
				self::insertOrUpdateAllManyToMany ( $instance );
237 3
			EventsManager::trigger ( DAOEvents::AFTER_UPDATE, $instance, $result );
238 3
			$instance->_rest = array_merge ( $instance->_rest, $ColumnskeyAndValues );
239 3
			return $result;
240
		} catch ( \PDOException $e ) {
241
			Logger::warn ( "DAOUpdates", $e->getMessage (), "update" );
242
		}
243
		return false;
244
	}
245
246
	/**
247
	 *
248
	 * @param object $instance
249
	 * @param boolean $updateMany
250
	 * @return boolean|int
251
	 */
252
	public static function save($instance, $updateMany = false) {
253
		if (isset ( $instance->_rest )) {
254
			return self::update ( $instance, $updateMany );
255
		}
256
		return self::insert ( $instance, $updateMany );
257
	}
258
}
259