Passed
Push — master ( 64da0c...c6d718 )
by Jean-Christophe
11:31
created

DAOUpdatesTrait::insertOrUpdateManyToMany()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

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