Passed
Push — master ( c4282d...8835f1 )
by Jean-Christophe
10:25
created

DAOUpdatesTrait::removeByKey_()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0067

Importance

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