This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Classe mère de tous les modèles |
||
5 | * @version 1.0 |
||
6 | * @todo deprecate this. Model is not MVC compliant |
||
7 | */ |
||
8 | abstract class Model |
||
0 ignored issues
–
show
|
|||
9 | { |
||
10 | public static $is_logue = false; |
||
11 | protected static $dbInstance = null; |
||
12 | protected $errors = array(); |
||
13 | protected $nombre_ligne; // pour l'affichage du nombre de lignes des listes (utilisés dans les Xobjets) |
||
14 | protected $log_id; |
||
15 | private static $session; |
||
16 | public $requete; |
||
17 | |||
18 | public function getIsLogue() |
||
19 | { |
||
20 | return (bool)self::$is_logue; |
||
21 | } |
||
22 | |||
23 | public function setIsLogue($bool = false) |
||
24 | { |
||
25 | self::$is_logue = (bool)$bool; |
||
26 | return $this; |
||
27 | } |
||
28 | |||
29 | /* ********** |
||
30 | * Créateur * |
||
31 | ********** */ |
||
32 | /** |
||
33 | * Crée une instance de classe avec les paramètres transmis |
||
34 | * Typiquement $_REQUEST d'un formulaire |
||
35 | **/ |
||
36 | public function __construct($params = array()) |
||
37 | { |
||
38 | $this->initialisationVariablesAvantContructeur(); |
||
39 | foreach (array_keys(get_object_vars($this)) as $attribute) { |
||
40 | if (isset($params[$attribute])) { |
||
41 | $this->setAttribute($attribute, $params[$attribute]); |
||
42 | } |
||
43 | } |
||
44 | return $this; |
||
0 ignored issues
–
show
|
|||
45 | } |
||
46 | |||
47 | public function getAttributes() |
||
48 | { |
||
49 | return array_keys(get_object_vars($this)); |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * cette fonction est appelée au tout début du constructeur. |
||
54 | * elle est principalement utilisée pour la gestion des cases à cocher qui doivent être décochée |
||
55 | * si elles ne sont pas envoyée dans le $_POST du formulaire. |
||
56 | */ |
||
57 | public function initialisationVariablesAvantContructeur() |
||
58 | { |
||
59 | /* fonction à redéfinir dans le modèle au besoin */ |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Retourne le nom du controller associé à la classe appelante |
||
64 | * @return string : Le nom du controleur |
||
65 | */ |
||
66 | public static function getControllerName() |
||
67 | { |
||
68 | $classe_appelante = get_called_class(); |
||
69 | if (substr($classe_appelante, 0, 4) == 'Base') { |
||
70 | $classe_appelante = substr($classe_appelante, 4); |
||
71 | } |
||
72 | return \FMUP\StringHandling::toCamelCase($classe_appelante); |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * transforme un objet en tableau |
||
77 | */ |
||
78 | public function objectToTable($objet) |
||
79 | { |
||
80 | $tableau = array(); |
||
81 | foreach ($objet as $attribute => $value) { |
||
82 | $tableau[$attribute] = $value; |
||
83 | } |
||
84 | return $tableau; |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * transforme un objet en tableau sans recupérer l'id |
||
89 | */ |
||
90 | public function objectToTableSansId($objet) |
||
91 | { |
||
92 | $tableau = array(); |
||
93 | foreach ($objet as $attribute => $value) { |
||
94 | if ($attribute != "id") { |
||
95 | $tableau[$attribute] = $value; |
||
96 | } |
||
97 | } |
||
98 | return $tableau; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * Crée une instance d'un modèle avec les paramètres transmis |
||
103 | * Typiquement le résultat d'une requète |
||
104 | * @param array $params : Données de l'objet |
||
105 | * @param string $class_name : Type d'objet |
||
106 | * @return Object |
||
107 | */ |
||
108 | protected static function create($params, $class_name) |
||
109 | { |
||
110 | $class = new $class_name(); |
||
111 | foreach ($params as $attribut => $value) { |
||
112 | $class->$attribut = $value; |
||
113 | } |
||
114 | return $class; |
||
115 | } |
||
116 | |||
117 | /* ************************* |
||
118 | * Affichage et convertion * |
||
119 | ************************* */ |
||
120 | /** |
||
121 | * Retourne une classe sous forme de chaîne |
||
122 | **/ |
||
123 | public function __toString() |
||
124 | { |
||
125 | ob_start(); |
||
126 | var_dump($this); |
||
0 ignored issues
–
show
|
|||
127 | return ob_get_clean(); |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Convertit une collection en tableau |
||
132 | * @param {Array} La collection |
||
133 | * @param {Integer} L'attribut à mettre dans les index du tableau |
||
134 | * @param {Integer} L'attribut ou les attributs (tableau) à mettre dans les valeurs du tableau |
||
135 | **/ |
||
136 | public static function arrayFromCollection($collection, $element_value, $element_text) |
||
137 | { |
||
138 | $array = array(); |
||
139 | foreach ($collection as $element) { |
||
140 | if (is_array($element_text)) { |
||
141 | $liste_attributs = array(); |
||
142 | foreach ($element_text as $attribut) { |
||
143 | $liste_attributs[] = $element->getAttribute($attribut); |
||
144 | } |
||
145 | $array[$element->getAttribute($element_value)] = implode(' - ', $liste_attributs); |
||
146 | } else { |
||
147 | $array[$element->getAttribute($element_value)] = $element->getAttribute($element_text); |
||
148 | } |
||
149 | } |
||
150 | return $array; |
||
151 | } |
||
152 | |||
153 | /** |
||
154 | * Convertit un objet en tableau |
||
155 | * @param {Array} La collection |
||
156 | **/ |
||
157 | public function arrayFromObject() |
||
158 | { |
||
159 | $array = array(); |
||
160 | foreach (array_keys(get_object_vars($this)) as $attribute) { |
||
161 | $array[$attribute] = $this->getAttribute($attribute); |
||
162 | } |
||
163 | return $array; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Crée des objets à partir d'une matrice (typiquement le résultat d'une requète) |
||
168 | */ |
||
169 | protected static function objectsFromMatrix($matrix, $class_name, $modeIterator = true) |
||
170 | { |
||
171 | if ($modeIterator) { |
||
172 | if (!$matrix instanceof \Iterator && is_array($matrix)) { |
||
173 | $matrix = new \ArrayIterator($matrix); |
||
174 | } |
||
175 | return new \ArrayToObjectIterator($matrix, $class_name); |
||
176 | } |
||
177 | $liste = array(); |
||
178 | if ($matrix instanceof Traversable || is_array($matrix)) { |
||
179 | foreach ($matrix as $array) { |
||
180 | array_push($liste, $class_name::create($array, $class_name)); |
||
181 | } |
||
182 | } |
||
183 | return $liste; |
||
184 | } |
||
185 | |||
186 | public static function objectsFromArray($array, $class_name) |
||
187 | { |
||
188 | return $class_name::create($array, $class_name); |
||
189 | } |
||
190 | |||
191 | protected static function objectsFromMatrixByAttribute($matrix, $class_name, $attribute = 'id') |
||
192 | { |
||
193 | $liste = array(); |
||
194 | if (!empty($matrix) && (is_array($matrix) || $matrix instanceof Traversable)) { |
||
195 | foreach ($matrix as $array) { |
||
196 | $objet = $class_name::create($array, $class_name); |
||
197 | $liste[$objet->getAttribute($attribute)] = $objet; |
||
198 | } |
||
199 | } |
||
200 | return $liste; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Retourne tous les éléments éventuellement filtrés de la table |
||
205 | * @param array $where : [OPT] Un tableau de tous les filtres éventuels |
||
206 | * @param array $options : [OPT] Options disponibles : |
||
207 | * - order : Tri sur la requête |
||
208 | * - findOne : Utilisé pour déterminer qu'on ne recherche qu'un résultat |
||
209 | * (TODO pour afficher les objets supprimés, ça ressemble à un doublon, fonctionnement ésotérique...) |
||
210 | * - afficher_supprimes : TODO vérifier si c'est vraiment utilisé, apparement non |
||
211 | * Seulement MySQL |
||
212 | * - limit : Pagination |
||
213 | * Seulement MSSQL |
||
214 | * - top : Semi-pagination qui ne passe pas par la sous-vue |
||
215 | * - paging : C'est un tableau composé de numero_page et nb_element |
||
216 | * Utilisé pour simuler une pagination grace à une sous-vue |
||
217 | * @return array[object] |
||
0 ignored issues
–
show
The doc-type
array[object] could not be parsed: Expected "]" at position 2, but found "object". (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
218 | */ |
||
219 | public static function findAll($where = array(), $options = array()) |
||
220 | { |
||
221 | $classe_appelante = get_called_class(); |
||
222 | |||
223 | //si on appelle depuis un object complexe, on recupere la requete correspondante |
||
224 | if (call_user_func(array($classe_appelante, 'afficherParDefautNonSupprimes'))) { |
||
225 | if (!isset($where['supprime']) && |
||
226 | (!isset($options['fonction']) || $options['fonction'] != 'findOne') |
||
227 | ) { |
||
228 | $where['supprime'] = 'supprime = 0'; |
||
229 | } |
||
230 | } |
||
231 | //sinon appelle de l'objet de Base généré par le génératOR |
||
232 | $result = Model::findAllFromTable( |
||
233 | call_user_func(array($classe_appelante, 'getTableName')), |
||
234 | $where, |
||
235 | $options |
||
236 | ); |
||
237 | |||
238 | // Création d'un tableau d'objets |
||
239 | return Model::objectsFromMatrix($result, $classe_appelante); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Retourne un élément grâce à son ID |
||
244 | * @param int $id : Un identifiant |
||
245 | * @return null|object |
||
246 | */ |
||
247 | public static function findOne($id) |
||
248 | { |
||
249 | $classe_appelante = get_called_class(); |
||
250 | |||
251 | $return = call_user_func( |
||
252 | array($classe_appelante, 'findAll'), |
||
253 | array('id = ' . Sql::secureId($id)), |
||
254 | array('fonction' => 'findOne') |
||
255 | ); |
||
256 | if (count($return) > 0) { |
||
257 | return $return[0]; |
||
258 | } else { |
||
259 | return null; |
||
260 | } |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Retourne le premier élément d'un findAll |
||
265 | * @param array $where : [OPT] Un tableau de tous les filtres éventuels |
||
266 | * @param string $order : [OPT] Le champ sur lequel ordonner |
||
267 | * @return false|object |
||
268 | */ |
||
269 | public static function findFirst($where = array(), $order = '') |
||
270 | { |
||
271 | $classe_appelante = get_called_class(); |
||
272 | |||
273 | $return = call_user_func( |
||
274 | array($classe_appelante, 'findAll'), |
||
275 | $where, |
||
276 | array('order' => $order, 'limit' => '0, 1', 'top' => '1') |
||
277 | ); |
||
278 | if (count($return)) { |
||
279 | return $return[0]; |
||
280 | } else { |
||
281 | return false; |
||
282 | } |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * Retourne le nombre d'éléments d'une requête |
||
287 | * @param array $where : Un tableau de clauses pour la requête |
||
288 | * @return int : Le nombre d'éléments |
||
289 | */ |
||
290 | public static function count($where = array()) |
||
291 | { |
||
292 | $classe_appelante = get_called_class(); |
||
293 | return Model::countFromTable(call_user_func(array($classe_appelante, 'getTableName')), $where); |
||
294 | } |
||
295 | |||
296 | |||
297 | /** |
||
298 | * Supprime l'objet dans la base de données |
||
299 | * @return bool : Le résultat du traitement, VRAI si suppression |
||
300 | * @todo : Supprimer les objets liés |
||
301 | */ |
||
302 | public function delete() |
||
303 | { |
||
304 | $classe_appelante = get_called_class(); |
||
305 | $retour = $this->deleteFromTable(call_user_func(array($classe_appelante, 'getTableName'))); |
||
306 | return $retour; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * si la table de l'objet contient un champ date_suppression, |
||
311 | * et qu'il ne faut afficher que les données non supprimées par défaut |
||
312 | * alors réécrire cette fonction dans l'objet avec return true |
||
313 | * @return bool |
||
314 | */ |
||
315 | public static function afficherParDefautNonSupprimes() |
||
316 | { |
||
317 | return false; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * si la table de l'objet contient un champ visible, et qu'il ne faut afficher que les données visibles par défaut |
||
322 | * alors réécrire cette fonction dans l'objet avec return true |
||
323 | * @return bool |
||
324 | */ |
||
325 | public static function afficherParDefautDataVisibles() |
||
326 | { |
||
327 | return false; |
||
328 | } |
||
329 | |||
330 | |||
331 | /* ************************** |
||
332 | * Requète et SQL générique * |
||
333 | ************************** */ |
||
334 | /** |
||
335 | * Trouve tous les enregistrements d'une table donnée |
||
336 | * @param string $table : Le nom de la table |
||
337 | * @param array $where :Un tableau de conditions |
||
338 | * @param array $options : L'ordre, le limit, ... |
||
339 | * @return array : Tableau contenant les objets |
||
340 | */ |
||
341 | protected static function findAllFromTable($table, $where = array(), $options = array()) |
||
342 | { |
||
343 | $SQL = "SELECT * FROM $table"; |
||
344 | $SQL .= Sql::parseWhere($where); |
||
345 | $isIterator = (!isset($options["iterator"]) || $options["iterator"]); |
||
346 | if (isset($options["group_by"]) && $options["group_by"]) { |
||
347 | $SQL .= " group by " . $options["group_by"]; |
||
348 | } |
||
349 | if (isset($options["order"]) && $options["order"]) { |
||
350 | $SQL .= " ORDER BY " . $options["order"]; |
||
351 | } |
||
352 | |||
353 | if (isset($options["top"]) && $options["top"]) { |
||
354 | $SQL .= " LIMIT " . $options["top"]; |
||
355 | } elseif (!empty($options['limit'])) { |
||
356 | $SQL .= " LIMIT " . $options["limit"]; |
||
357 | } |
||
358 | |||
359 | // Exécution de la requète |
||
360 | $db = \Model::getDb(); |
||
361 | $result = $isIterator ? $db->getIterator($SQL) : $db->fetchAll($SQL); |
||
0 ignored issues
–
show
The method
FMUP\Db::fetchAll() has been deprecated with message: use self::getIterator() instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
362 | return $result; |
||
363 | } |
||
364 | |||
365 | /** |
||
366 | * Retourne un tableau avec l'ID de la DMD et un attribut |
||
367 | * --> utilsié pour alléger les menus déroulant de l'application |
||
368 | * @param {Array} un tableau de tous les filtres éventuels |
||
369 | * @param {string} le champ sur lequel ordonner |
||
370 | **/ |
||
371 | View Code Duplication | public static function findAllAttributeFromTable($table, $attribute, $where = array(), $options = array()) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
372 | { |
||
373 | $SQL = "SELECT id\n"; |
||
374 | if ($attribute != 'id') { |
||
375 | $SQL .= "," . $attribute . "\n"; |
||
376 | } |
||
377 | $SQL .= "FROM $table "; |
||
378 | $SQL .= Sql::parseWhere($where); |
||
379 | |||
380 | if (isset($options["order"]) && $options["order"]) { |
||
381 | $SQL .= " ORDER BY " . $options["order"]; |
||
382 | } |
||
383 | if (isset($options["limit"]) && $options["limit"]) { |
||
384 | $SQL .= " LIMIT " . $options["limit"]; |
||
385 | } |
||
386 | //echo($SQL); |
||
387 | // Exécution de la requète |
||
388 | $db = \Model::getDb(); |
||
389 | $result = $db->fetchAll($SQL); |
||
0 ignored issues
–
show
The method
FMUP\Db::fetchAll() has been deprecated with message: use self::getIterator() instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
390 | return $result; |
||
391 | } |
||
392 | |||
393 | View Code Duplication | public static function findAllAttributeFromLeftJoinTable( |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
394 | $table, |
||
395 | $left_table, |
||
396 | $link_table, |
||
397 | $attribute, |
||
398 | $where = array(), |
||
399 | $options = array() |
||
400 | ) |
||
401 | { |
||
402 | $SQL = "SELECT $attribute \n"; |
||
403 | $SQL .= " FROM $table \n LEFT JOIN $left_table \n"; |
||
404 | $SQL .= " ON $link_table \n"; |
||
405 | $SQL .= Sql::parseWhere($where); |
||
406 | |||
407 | if (isset($options["order"]) && $options["order"]) { |
||
408 | $SQL .= " ORDER BY " . $options["order"] . " \n"; |
||
409 | } |
||
410 | if (isset($options["limit"]) && $options["limit"]) { |
||
411 | $SQL .= " LIMIT " . $options["limit"]; |
||
412 | } |
||
413 | //debug::output($SQL); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
414 | // Exécution de la requète |
||
415 | $db = \Model::getDb(); |
||
416 | $result = $db->getIterator($SQL); |
||
417 | return $result; |
||
418 | } |
||
419 | |||
420 | /** |
||
421 | * Retourne le nombre d'éléments d'une requéte pour une table donnée |
||
422 | * @param {string} Le nom de la table |
||
423 | * @param {Array} un tableau de condititions |
||
424 | **/ |
||
425 | protected static function countFromTable($table, $where = array(), $options = array()) |
||
426 | { |
||
427 | $SQL = "SELECT COUNT(*) AS nb FROM $table"; |
||
428 | $SQL .= sql::ParseWhere($where); |
||
429 | if (!empty($options["group_by"])) { |
||
430 | $SQL .= " group by " . $options["group_by"]; |
||
431 | } |
||
432 | // Exécution de la requète |
||
433 | $db = \Model::getDb(); |
||
434 | $result = $db->fetchRow($SQL); |
||
435 | return $result["nb"]; |
||
436 | } |
||
437 | |||
438 | /** |
||
439 | * Retourne la somme des valeurs d'une colonne pour une table et une colonne donnée |
||
440 | * @param {string} Le nom de la table |
||
441 | * @param {string} le nom de la colonne à sommer |
||
442 | * @param {Array} un tableau de condition |
||
443 | * @param {Array} un tableau d'options |
||
444 | * @return mixed La somme si pas de group by en option, un tableau de couple somme / valeur de la colonne sinon |
||
445 | **/ |
||
446 | protected static function sumFromTable($table, $colonne, $where = array(), $options = array()) |
||
447 | { |
||
448 | $select = "SUM($colonne) as somme"; |
||
449 | $group_by = ""; |
||
450 | if (isset($options["group_by"]) && $options["group_by"]) { |
||
451 | $select .= ", $table.$colonne"; |
||
452 | $group_by = " GROUP BY " . $options["group_by"]; |
||
453 | } |
||
454 | $sql = "SELECT $select FROM $table"; |
||
455 | $sql .= sql::ParseWhere($where); |
||
456 | $sql .= $group_by; |
||
457 | // Exécution de la requête |
||
458 | $db = \Model::getDb(); |
||
459 | return ($group_by != "") ? $db->fetchAll($sql) : $db->fetchRow($sql)["somme"]; |
||
0 ignored issues
–
show
The method
FMUP\Db::fetchAll() has been deprecated with message: use self::getIterator() instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
460 | } |
||
461 | |||
462 | /** |
||
463 | * Supprime l'objet dans la base de données |
||
464 | * Place le champ supprime à 1 à la place si le champ est présent dans la table |
||
465 | * @param string $table : Le nom de la table |
||
466 | * @return bool : VRAI si la suppression est effectuée |
||
467 | */ |
||
468 | protected function deleteFromTable($table) |
||
469 | { |
||
470 | if (($this->id > 0) && ($this->canBeDeleted())) { |
||
471 | // Cas ou le champ de suppression existe |
||
472 | if (property_exists($this, 'supprime')) { |
||
473 | $this->supprime = true; |
||
0 ignored issues
–
show
The property
supprime does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
474 | $infos_suppression = ''; |
||
475 | if (property_exists($this, 'date_suppression')) { |
||
476 | $infos_suppression .= ', date_suppression = CURRENT_TIMESTAMP()'; |
||
477 | $this->date_suppression = date('Y-m-d H:i:s'); |
||
0 ignored issues
–
show
The property
date_suppression does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
478 | } |
||
479 | if (property_exists($this, 'id_suppresseur')) { |
||
480 | if (self::getSession()->has('id_utilisateur')) { |
||
481 | $id_utilisateur = self::getSession()->get('id_utilisateur'); |
||
482 | } |
||
483 | $infos_suppression .= ', id_suppresseur = ' . Sql::secureId($id_utilisateur); |
||
0 ignored issues
–
show
The variable
$id_utilisateur does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
484 | $this->id_suppresseur = $id_utilisateur; |
||
0 ignored issues
–
show
The property
id_suppresseur does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
485 | } |
||
486 | // Loger le changement |
||
487 | $this->logerChangement("delete"); |
||
488 | $SQL = "UPDATE $table |
||
489 | SET supprime = 1 |
||
490 | $infos_suppression |
||
491 | WHERE id = " . $this->id; |
||
0 ignored issues
–
show
The property
id does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
492 | $db = Model::getDb(); |
||
493 | return (bool)$db->execute($SQL); |
||
0 ignored issues
–
show
The method
execute() does not seem to exist on object<FMUP\Db> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||
494 | // Cas de la suppression physique |
||
495 | } else { |
||
496 | // Loger le changement |
||
497 | $this->logerChangement("delete"); |
||
498 | $SQL = "DELETE FROM $table WHERE id = " . $this->id; |
||
499 | $db = Model::getDb(); |
||
500 | $return = (bool)$db->query($SQL); |
||
501 | if ($return) { |
||
502 | $this->id = ""; |
||
503 | return true; |
||
504 | } else { |
||
505 | return false; |
||
506 | } |
||
507 | } |
||
508 | } else { |
||
509 | return false; |
||
510 | } |
||
511 | } |
||
512 | |||
513 | /** |
||
514 | * Retourne l'instance de base de données du controlleur actif |
||
515 | * @return \FMUP\Db |
||
516 | */ |
||
517 | public static function getDb() |
||
518 | { |
||
519 | if (!self::$dbInstance) { |
||
520 | self::$dbInstance = \FMUP\Db\Manager::getInstance()->get(); |
||
521 | } |
||
522 | return self::$dbInstance; |
||
523 | } |
||
524 | |||
525 | public static function setDb($dbInstance) |
||
526 | { |
||
527 | self::$dbInstance = $dbInstance; |
||
528 | } |
||
529 | |||
530 | /* ************************ |
||
531 | * Sauvegarde des données * |
||
532 | ************************ */ |
||
533 | /** |
||
534 | * Sauvegarde ou met à jour l'objet dans la base de donnée |
||
535 | * @param bool $force_enregistrement |
||
536 | * si TRUE, alors le système contrepasse le VALIDATE et enregistre quand même l'objet |
||
537 | * (ATTENTION à l'utilisation de ce paramètre) |
||
538 | * @return bool |
||
539 | * VRAI si une action a eu lieu en base (si la requête ne change rien ou le validate bloque, retourne FAUX) |
||
540 | * @throws \FMUP\Exception |
||
541 | */ |
||
542 | public function save($force_enregistrement = false) |
||
543 | { |
||
544 | // debug::output($this, true); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
64% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
545 | if ($force_enregistrement || $this->validate(true)) { |
||
0 ignored issues
–
show
The call to
Model::validate() has too many arguments starting with true .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
546 | if (Is::id($this->id)) { |
||
547 | /* Loger le changement */ |
||
548 | $this->logerChangement("update"); |
||
549 | if ($this->update() !== false) { |
||
550 | $this->comparerDifferences(); |
||
551 | } else { |
||
552 | throw new \FMUP\Exception("Erreur pendant l'enregistrement"); |
||
553 | } |
||
554 | } else { |
||
555 | /* Loger le changement */ |
||
556 | $this->id = $this->insert(); |
||
557 | $this->logerChangement("insert"); |
||
558 | } |
||
559 | //appel de la fonction post SAVE, si l'enregistrement a fonctionné |
||
560 | if ($this->id) { |
||
561 | $this->setValeursDefautPostSave(); |
||
562 | } |
||
563 | return $this->id; |
||
564 | } else { |
||
565 | return false; |
||
566 | } |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * Insertion d'un objet en base |
||
571 | * @return bool |
||
572 | */ |
||
573 | abstract protected function insert(); |
||
574 | |||
575 | /** |
||
576 | * Mise à jour d'un objet en base |
||
577 | * @return bool |
||
578 | */ |
||
579 | abstract protected function update(); |
||
580 | |||
581 | /** |
||
582 | * Le message affiché à l'update |
||
583 | */ |
||
584 | public static function getMessageUpdateOK() |
||
585 | { |
||
586 | return "Mise à jour réalisée avec succès."; |
||
587 | } |
||
588 | |||
589 | /** |
||
590 | * Le message affiché à la suppression |
||
591 | */ |
||
592 | public static function getMessageSuppressionOK() |
||
593 | { |
||
594 | return "Suppression réalisée avec succès."; |
||
595 | } |
||
596 | |||
597 | /* *************************************** |
||
598 | * gestion des créateur et modificateurs * |
||
599 | * d'objet en base * |
||
600 | *************************************** */ |
||
601 | |||
602 | /** |
||
603 | * Retourne le createur de l'objet |
||
604 | * @return Utilisateur |
||
605 | */ |
||
606 | public function getCreateur() |
||
607 | { |
||
608 | $createur = Utilisateur::findOne($this->id_createur); |
||
0 ignored issues
–
show
The property
id_createur does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
609 | if (!$createur) { |
||
610 | $createur = new Utilisateur(); |
||
611 | } |
||
612 | return $createur; |
||
613 | } |
||
614 | |||
615 | /** |
||
616 | * Retourne le dernier modificateur de l'objet |
||
617 | * @return Utilisateur |
||
618 | */ |
||
619 | public function getModificateur() |
||
620 | { |
||
621 | $modificateur = Utilisateur::findOne($this->id_modificateur); |
||
0 ignored issues
–
show
The property
id_modificateur does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
622 | if (!$modificateur) { |
||
623 | $modificateur = new Utilisateur(); |
||
624 | } |
||
625 | return $modificateur; |
||
626 | } |
||
627 | |||
628 | /** |
||
629 | * Modifie le champ date_creation par la date actuelle |
||
630 | **/ |
||
631 | public function setDateCreation($value = null) |
||
632 | { |
||
633 | $creationDate = null; |
||
634 | try { |
||
635 | $creationDate = new \DateTime($value); |
||
636 | } catch (\Exception $e) { |
||
637 | $creationDate = \DateTime::createFromFormat('d/m/Y H:i:s', $value); |
||
638 | } |
||
639 | $this->date_creation = $creationDate->format('Y-m-d H:i:s'); |
||
0 ignored issues
–
show
The property
date_creation does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
640 | return true; |
||
641 | } |
||
642 | |||
643 | /** |
||
644 | * Modifie le champ createur par la personne connectée |
||
645 | **/ |
||
646 | public function setIdCreateur($value = 0) |
||
647 | { |
||
648 | $sessionIdUser = self::getSession()->get('id_utilisateur'); |
||
649 | if ($value) { |
||
650 | $this->id_createur = $value; |
||
651 | } elseif (!empty($sessionIdUser)) { |
||
652 | $this->id_createur = $sessionIdUser; |
||
653 | } else { |
||
654 | $this->id_createur = -1; |
||
655 | } |
||
656 | return true; |
||
657 | } |
||
658 | |||
659 | /** |
||
660 | * Modifie le champ date de dernière modification par la date actuelle |
||
661 | **/ |
||
662 | public function setDateModification($value = null) |
||
663 | { |
||
664 | $this->date_modification = date('Y-m-d H:i:s', $value ? strtotime($value) : null); |
||
0 ignored issues
–
show
The property
date_modification does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
665 | return true; |
||
666 | } |
||
667 | |||
668 | /** |
||
669 | * Modifie le champ dernier modificateur par la personne connectée |
||
670 | **/ |
||
671 | public function setIdModificateur($value = 0) |
||
672 | { |
||
673 | if ($value === 'null') { |
||
0 ignored issues
–
show
|
|||
674 | $this->id_modificateur = ''; |
||
675 | } elseif ($value) { |
||
676 | $this->id_modificateur = $value; |
||
677 | } elseif (self::getSession()->has('id_utilisateur')) { |
||
678 | $this->id_modificateur = self::getSession()->get('id_utilisateur'); |
||
679 | } else { |
||
680 | // ce cas ne peut arriver que si l'on modifie l'objet dans une page où personne n'est connecté |
||
681 | // (ex: page de première connexion) |
||
682 | $this->id_modificateur = 1; |
||
683 | } |
||
684 | return true; |
||
685 | } |
||
686 | |||
687 | /* ****************************** |
||
688 | * Affichage d'infos et erreurs * |
||
689 | ****************************** */ |
||
690 | |||
691 | /** |
||
692 | * Réinitialise le tableau d'erreurs |
||
693 | */ |
||
694 | public function initialiseErrors() |
||
695 | { |
||
696 | $this->errors = array(); |
||
697 | } |
||
698 | |||
699 | /** |
||
700 | * Retourne les erreurs de validation d'un objet |
||
701 | * @param string $attribute : [OPT] Pour vérifier les erreurs sur un atribut en particulier |
||
702 | * @return array |
||
703 | */ |
||
704 | public function getErrors($attribute = false) |
||
705 | { |
||
706 | if ($attribute) { |
||
0 ignored issues
–
show
The expression
$attribute of type false|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
707 | $tab_error = $this->errors; |
||
708 | if (isset($tab_error[$attribute])) { |
||
709 | return $tab_error[$attribute]; |
||
710 | } else { |
||
711 | return false; |
||
0 ignored issues
–
show
The return type of
return false; (false ) is incompatible with the return type documented by Model::getErrors of type array .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
712 | } |
||
713 | } else { |
||
714 | return $this->errors; |
||
715 | } |
||
716 | } |
||
717 | |||
718 | /* |
||
719 | * Fonction utilisée par les demandes et commandes afin de trouver les différences |
||
720 | * par rapport a une version modifiée |
||
721 | */ |
||
722 | public function compareVersion() |
||
723 | { |
||
724 | return array(); |
||
725 | } |
||
726 | |||
727 | |||
728 | /** |
||
729 | * Met à jour le tableau des erreurs d'un objet. |
||
730 | * @param {Array} $errors Le tableau d'erreurs à ajouter. |
||
0 ignored issues
–
show
The doc-type
{Array} could not be parsed: Unknown type name "{Array}" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
731 | * @return true |
||
732 | */ |
||
733 | public function setErrors($errors) |
||
734 | { |
||
735 | $this->errors = array_merge($errors, $this->errors); |
||
736 | return true; |
||
737 | } |
||
738 | |||
739 | /* ********************* |
||
740 | * Accesseurs généraux * |
||
741 | ********************* */ |
||
742 | /** |
||
743 | * Retourne la valeur d'un attribut si il existe |
||
744 | * @param {String} l'attribut auquel accéder |
||
745 | **/ |
||
746 | public function getAttribute($attribute) |
||
747 | { |
||
748 | return call_user_func(array($this, 'get' . \FMUP\StringHandling::toCamelCase($attribute))); |
||
749 | } |
||
750 | |||
751 | /** |
||
752 | * Modifie la valeur d'un attribut si il existe |
||
753 | * @param {String} l'attribut auquel accéder |
||
754 | * @param {string} la valeur à enregistrer |
||
755 | **/ |
||
756 | public function setAttribute($attribute, $value) |
||
757 | { |
||
758 | call_user_func(array($this, 'set' . \FMUP\StringHandling::toCamelCase($attribute)), $value); |
||
759 | return true; |
||
760 | } |
||
761 | |||
762 | /** |
||
763 | * Met à jour un objet (*sans* l'enregistrer dans la base de données) avec de |
||
764 | * nouveaux paramètres |
||
765 | * @param {Array} un tableau de nouvelles valeurs |
||
766 | **/ |
||
767 | public function modify($params) |
||
768 | { |
||
769 | foreach ($params as $attribute => $value) { |
||
770 | $this->setAttribute($attribute, $value); |
||
771 | } |
||
772 | } |
||
773 | |||
774 | /** |
||
775 | * Retourne ou modifie la valeur d'un attribut |
||
776 | * @param string $function : L'attribut auquel accéder |
||
777 | * @param string $argument : [OPT] La valeur à affecter dans le cas d'une affectation |
||
778 | * @return mixed|bool|null : L'argument demandée pour une lecture, VRAI si affectation réussie, null sinon |
||
779 | */ |
||
780 | public function __call($function, $argument = array()) |
||
781 | { |
||
782 | $attribut = \FMUP\StringHandling::toCamelCase(substr($function, 3)); |
||
783 | if (property_exists($this, $attribut)) { |
||
784 | if (preg_match('#^get#i', $function)) { |
||
785 | return $this->$attribut; |
||
786 | } |
||
787 | |||
788 | if (preg_match('#^set#i', $function) && count($argument)) { |
||
789 | $this->$attribut = $argument[0]; |
||
790 | return true; |
||
791 | } |
||
792 | } else { |
||
793 | if (preg_match('#^get#i', $function) || preg_match('#^set#i', $function)) { |
||
794 | $message = "Attribut inexistant $attribut dans l'objet " . get_called_class(); |
||
795 | } else { |
||
796 | $message = "Fonction inexistante $function dans l'objet " . get_called_class(); |
||
797 | } |
||
798 | throw new \FMUP\Exception($message); |
||
799 | } |
||
800 | return null; |
||
801 | } |
||
802 | |||
803 | /** |
||
804 | * Retourne l'id de l'objet |
||
805 | **/ |
||
806 | /*public function getId() |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
56% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
807 | { |
||
808 | return $this->id; |
||
809 | }*/ |
||
810 | |||
811 | /** |
||
812 | * Retourne le code langue de l'utilisateur |
||
813 | **/ |
||
814 | public function getCodeLangue() |
||
815 | { |
||
816 | return $this->code_langue; |
||
0 ignored issues
–
show
The property
code_langue does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
817 | } |
||
818 | |||
819 | /* ********************* |
||
820 | * Sécurisation des * |
||
821 | * éditions * |
||
822 | ***********************/ |
||
823 | |||
824 | /** |
||
825 | * Renvoi le tableau des champs autorisés |
||
826 | * pour l'utilisateur en cours |
||
827 | * |
||
828 | * @return tableau des champs autorisés |
||
829 | */ |
||
830 | public function listeChampsModifiable() |
||
831 | { |
||
832 | return array(); |
||
833 | } |
||
834 | |||
835 | /** |
||
836 | * Donne le droit à modifier l'objet mais par une méthode différente (non directe par l'attribut) |
||
837 | **/ |
||
838 | public function setIdNew($valeur = '') |
||
839 | { |
||
840 | $this->id = $valeur; |
||
841 | } |
||
842 | |||
843 | /** |
||
844 | * Renvoi l'autorisation d'un champ pour l'utilisateur en cours |
||
845 | * |
||
846 | * @param champ à vérifier |
||
847 | * @return booléen d'autorisation |
||
848 | */ |
||
849 | public function isChampModifiable($champ) |
||
850 | { |
||
851 | $liste = $this->listeChampsModifiable(); |
||
852 | if (isset($liste[$champ])) { |
||
853 | return true; |
||
854 | } else { |
||
855 | return false; |
||
856 | } |
||
857 | } |
||
858 | |||
859 | /** |
||
860 | * @param Tableau des valeurs de l'objet typiquement $_POST |
||
861 | * @return l'objet |
||
0 ignored issues
–
show
The doc-type
l'objet could not be parsed: Unknown type name "l'objet" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
862 | */ |
||
863 | public function setAttributesSecure($attributes) |
||
864 | { |
||
865 | //Sécurisation de l'id |
||
866 | $identifiant = (isset($attributes['id']) && Is::id($attributes['id'])) ? $attributes['id'] : 0; |
||
867 | //Récupération de l'objet en base (inutile de charger s'il n'y a pas d'ID) |
||
868 | if ($identifiant) { |
||
869 | $object = call_user_func(array(get_class($this), 'FindOne'), $identifiant); |
||
870 | } |
||
871 | if (!$identifiant || !$object) { |
||
0 ignored issues
–
show
The variable
$object does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
872 | $object = $this; |
||
873 | } |
||
874 | // récuperation des champs modifiable pour l'utilisateur courant |
||
875 | $editable_fields = $object->listeChampsModifiable(); |
||
876 | //Si on fournit une donnée et si l'on peut la modifier |
||
877 | // dans le cas de POST, il faut gérer les checkbox non cochées |
||
878 | $object->initialisationVariablesAvantContructeur(); |
||
879 | foreach ($editable_fields as $field) { |
||
880 | if (isset($attributes[$field])) { |
||
881 | $object->setAttribute($field, $attributes[$field]); |
||
882 | } |
||
883 | } |
||
884 | |||
885 | return $object; |
||
886 | } |
||
887 | |||
888 | public function setValeursDefautPostSave() |
||
889 | { |
||
890 | } |
||
891 | |||
892 | /* ********************* |
||
893 | * Logs * |
||
894 | ********************* */ |
||
895 | |||
896 | /** |
||
897 | * fonction utilisée pour récupérer la liste des champs (dans l'ordre) de la table pour les requete de log |
||
898 | * /!\ la clef primaire ID doit s'appeler 'id_objet_log' !!! |
||
899 | * @return string |
||
900 | */ |
||
901 | public static function listeChampsObjet() |
||
902 | { |
||
903 | return 'id_objet_log'; |
||
904 | } |
||
905 | |||
906 | /** |
||
907 | * Spécifie les champs de la table à comparer |
||
908 | * Retourne un taleau vide si tous les champs de la table à comparer |
||
909 | * @return Array $array |
||
910 | */ |
||
911 | public function fieldsToCompare() |
||
912 | { |
||
913 | $array = array(); |
||
914 | return $array; |
||
915 | } |
||
916 | |||
917 | /** |
||
918 | * Spécifie les champs à ne pas prendre en compte pour la comparaison |
||
919 | * Tableau non vide contenant tout le temps, au moins le champ id |
||
920 | * @return Array $array |
||
921 | */ |
||
922 | public function fieldsInException() |
||
923 | { |
||
924 | $array = array(); |
||
925 | $array['id'] = 'Id'; |
||
926 | return $array; |
||
927 | } |
||
928 | |||
929 | /** |
||
930 | * fonction de log |
||
931 | * @param $type_action |
||
932 | */ |
||
933 | public function logerChangement($type_action) |
||
934 | { |
||
935 | if ($this->getIsLogue() && $this->tableToLog() && $this->id) { |
||
0 ignored issues
–
show
The method
tableToLog does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
936 | $default_id = ""; |
||
937 | $tab = call_user_func(array(get_class($this), 'listeChampsObjet')); |
||
938 | $tab = explode(', ', $tab); |
||
939 | |||
940 | if (isset($tab[0]) && trim($tab[0]) == '') { |
||
941 | unset($tab[0]); |
||
942 | } |
||
943 | |||
944 | View Code Duplication | if (isset($tab[0]) && (trim($tab[0]) == 'id')) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
945 | $tab[0] = 'id_objet_log'; |
||
946 | } elseif (isset($tab[1]) && (trim($tab[1]) == 'id')) { |
||
947 | $tab[1] = 'id_objet_log'; |
||
948 | } |
||
949 | $liste_champ = implode(', ', $tab); |
||
950 | |||
951 | View Code Duplication | if (isset($tab[0]) && (trim($tab[0]) == 'id_objet_log')) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
952 | $tab[0] = 'id'; |
||
953 | } elseif (isset($tab[1]) && (trim($tab[1]) == 'id_objet_log')) { |
||
954 | $tab[1] = 'id'; |
||
955 | } |
||
956 | $liste_champ_valeur = implode(', ', $tab); |
||
957 | |||
958 | $id_utilisateur = self::getSession()->has('id_utilisateur') |
||
959 | ? self::getSession()->get('id_utilisateur') |
||
960 | : -1; |
||
961 | |||
962 | $SQL = 'INSERT INTO log__' . $this->getTableName() . ' |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
963 | (' . $liste_champ . ' |
||
964 | , libelle_historisation |
||
965 | , contenu_log |
||
966 | , id_utilisateur_log |
||
967 | , date_action_log |
||
968 | , action_log |
||
969 | ) |
||
970 | SELECT ' . $default_id . ' |
||
971 | ' . $liste_champ_valeur . ', |
||
972 | \'\', |
||
973 | \'\', |
||
974 | ' . Sql::secureId($id_utilisateur) . ', |
||
975 | ' . Sql::secureDate(date('Y-m-d H:i:s')) . ', |
||
976 | ' . Sql::secure($type_action) . ' |
||
977 | FROM ' . $this->getTableName() . ' T |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
978 | WHERE id = ' . Sql::secureId($this->id) . ' |
||
979 | '; |
||
980 | $db = Model::getDb(); |
||
981 | $db->query($SQL); |
||
982 | $this->log_id = $db->lastInsertId(); |
||
983 | } |
||
984 | } |
||
985 | |||
986 | /** |
||
987 | * fonction permettant de comparer 2 tableaux de données d'un objet et sa sauvegarde en log |
||
988 | * et d'enregistrer les modifications effectuées |
||
989 | */ |
||
990 | public function comparerDifferences() |
||
991 | { |
||
992 | $tab_champs_comparaison = $this->fieldsToCompare(); |
||
993 | $tab_champs_exception = $this->fieldsInException(); |
||
994 | $tab_champs_base = array(); |
||
995 | $tab_champs_log = array(); |
||
996 | $tab_contenu = array(); |
||
997 | |||
998 | $champs_specifiques = false; |
||
999 | if (!empty($tab_champs_comparaison)) { |
||
1000 | $champs_specifiques = true; |
||
1001 | } |
||
1002 | |||
1003 | if (empty($tab_champs_exception)) { |
||
1004 | $tab_champs_exception["#exception#"] = "Exception"; |
||
1005 | } |
||
1006 | |||
1007 | |||
1008 | if ($this->getIsLogue() && $this->tableToLog()) { |
||
0 ignored issues
–
show
The method
tableToLog does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1009 | // données de la table courante |
||
1010 | $sql = $this->getSqlLog(); |
||
1011 | $db = Model::getDb(); |
||
1012 | $res = $db->fetchRow($sql); |
||
1013 | |||
1014 | if ($res) { |
||
0 ignored issues
–
show
The expression
$res of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
1015 | foreach ($res as $index => $value) { |
||
1016 | if ($champs_specifiques) { |
||
1017 | if (array_key_exists($index, $tab_champs_comparaison)) { |
||
1018 | $tab_champs_base[$index] = $value; |
||
1019 | } |
||
1020 | } else { |
||
1021 | if (!array_key_exists($index, $tab_champs_exception)) { |
||
1022 | $tab_champs_base[$index] = $value; |
||
1023 | } |
||
1024 | } |
||
1025 | } |
||
1026 | } |
||
1027 | // données de la table de log |
||
1028 | $sql = $this->getSqlLog('log'); |
||
1029 | $res = $db->fetchRow($sql); |
||
1030 | |||
1031 | if ($res) { |
||
0 ignored issues
–
show
The expression
$res of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
1032 | foreach ($res as $index => $value) { |
||
1033 | if (!array_key_exists($index, $tab_champs_exception)) { |
||
1034 | if ($index == "id_objet_log") { |
||
1035 | $index = "id"; |
||
1036 | } |
||
1037 | |||
1038 | if (array_key_exists($index, $tab_champs_base)) { |
||
1039 | $tab_champs_log[$index] = $value; |
||
1040 | } |
||
1041 | } |
||
1042 | } |
||
1043 | } |
||
1044 | $tab_diff = array_diff_assoc($tab_champs_base, $tab_champs_log); |
||
1045 | // insertion de la différence dans la table de log |
||
1046 | if (count($tab_diff) > 0) { |
||
1047 | $libelle = ""; |
||
1048 | |||
1049 | foreach ($tab_diff as $index => $value) { |
||
1050 | $field = ($champs_specifiques) ? $tab_champs_comparaison[$index] : $index; |
||
1051 | $libelle .= "Le champ '" . $field . "' a été modifié : '" |
||
1052 | . $field . "' a été remplacé par '" . $value . "'\n"; |
||
1053 | |||
1054 | $tab_contenu[$index] = array( |
||
1055 | "old_value" => isset($tab_champs_log[$index]) ? $tab_champs_log[$index] : null, |
||
1056 | "new_value" => ($value) |
||
1057 | ); |
||
1058 | } |
||
1059 | |||
1060 | $contenu = serialize($tab_contenu); |
||
1061 | //$contenu = json_encode($tab_contenu); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
56% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
1062 | |||
1063 | $sql = "UPDATE log__" . $this->getTableName() . " |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1064 | SET libelle_historisation = " . Sql::secure(($libelle)) . " |
||
1065 | , contenu_log = " . Sql::secure($contenu) . " |
||
1066 | WHERE id = " . Sql::secureId($this->log_id); |
||
1067 | $db = Model::getDb(); |
||
1068 | $db->query($sql); |
||
1069 | } |
||
1070 | } |
||
1071 | } |
||
1072 | |||
1073 | /** |
||
1074 | * formate les requetes de log |
||
1075 | */ |
||
1076 | public function getSqlLog($from = "") |
||
1077 | { |
||
1078 | if ($from == 'log') { |
||
1079 | $table = 'log__' . $this->getTableName(); |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1080 | $condition = " T.id = " . Sql::secureId($this->log_id); |
||
1081 | } else { |
||
1082 | $table = $this->getTableName(); |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1083 | $condition = " T.id = " . Sql::secureId($this->id); |
||
1084 | } |
||
1085 | |||
1086 | $sql = "SELECT T.* |
||
1087 | FROM " . $table . " T |
||
1088 | WHERE " . $condition; |
||
1089 | return $sql; |
||
1090 | } |
||
1091 | |||
1092 | /** |
||
1093 | * fonction permettant de récupérer sous forme de tableau les différences |
||
1094 | */ |
||
1095 | public static function returnArrayByJson($string = "") |
||
1096 | { |
||
1097 | return json_decode($string, true); |
||
1098 | } |
||
1099 | |||
1100 | /** |
||
1101 | * fonction permettant de récupérer les historiques tableau d'un objet |
||
1102 | */ |
||
1103 | public function getHistoriqueSurObjetDiffArray() |
||
1104 | { |
||
1105 | $array = array(); |
||
1106 | $sql = "SELECT id, contenu_log, id_utilisateur_log, date_action_log, action_log |
||
1107 | FROM log__" . $this->getTableName() . " |
||
0 ignored issues
–
show
The method
getTableName does not exist on object<Model> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1108 | WHERE id_objet_log = " . Sql::secureId($this->id) . " |
||
1109 | ORDER BY id"; |
||
1110 | $db = \Model::getDb(); |
||
1111 | $res = $db->getIterator($sql); |
||
1112 | |||
1113 | foreach ($res as $rs) { |
||
1114 | $array[$rs["id"]] = array( |
||
1115 | "id_utilisateur_log" => $rs["id_utilisateur_log"] |
||
1116 | , "date_action_log" => $rs["date_action_log"] |
||
1117 | , "action_log" => $rs["action_log"] |
||
1118 | , "contenu_log" => unserialize($rs["contenu_log"]) |
||
1119 | ); |
||
1120 | } |
||
1121 | return $array; |
||
1122 | } |
||
1123 | |||
1124 | /* ************ |
||
1125 | * Validation * |
||
1126 | ************ */ |
||
1127 | /** |
||
1128 | * L'objet est-il enregistrable en base de données |
||
1129 | * @return bool |
||
1130 | */ |
||
1131 | abstract public function validate(); |
||
1132 | |||
1133 | /** |
||
1134 | * L'objet est-il effaçable |
||
1135 | * @return bool |
||
1136 | */ |
||
1137 | abstract public function canBeDeleted(); |
||
1138 | |||
1139 | /** |
||
1140 | * Détermine si notre objet est unique par rapport aux attributs donnés |
||
1141 | * @param mixed $attribut : Attribut (ou liste d'attribut, dans ce cas tableau) à comparer |
||
1142 | * @param array $where : [OPT] Clauses supplémentaires à prendre en compte pour notre recherche |
||
1143 | * @return bool : VRAI si aucun doublon est trouvé |
||
1144 | */ |
||
1145 | public function isUniqueAttribute($attribut, $where = array()) |
||
1146 | { |
||
1147 | if (is_array($attribut)) { |
||
1148 | foreach ($attribut as $current_attribut) { |
||
1149 | $where[$current_attribut] = 'IFnull(' . $current_attribut . ', 0) = ' |
||
1150 | . 'IFnull(' . sql::Secure($this->$current_attribut) . ', 0)'; |
||
1151 | } |
||
1152 | } else { |
||
1153 | $where[$attribut] = 'IFnull(' . $attribut . ', 0) = IFnull(' . sql::Secure($this->$attribut) . ', 0)'; |
||
1154 | } |
||
1155 | $where['id'] = "IFnull(id, 0) <> IFnull(" . sql::secureId($this->id) . ", 0)"; |
||
1156 | $doublon = $this->findFirst($where); |
||
1157 | |||
1158 | return !$doublon; |
||
1159 | } |
||
1160 | |||
1161 | /** |
||
1162 | * @param \FMUP\Session $session |
||
1163 | */ |
||
1164 | public static function setSession(\FMUP\Session $session) |
||
1165 | { |
||
1166 | self::$session = $session; |
||
1167 | } |
||
1168 | |||
1169 | /** |
||
1170 | * @return \FMUP\Session |
||
1171 | */ |
||
1172 | public static function getSession() |
||
1173 | { |
||
1174 | if (!self::$session) { |
||
1175 | self::setSession(\FMUP\Session::getInstance()); |
||
1176 | } |
||
1177 | return self::$session; |
||
1178 | } |
||
1179 | |||
1180 | public static function hasSession() |
||
1181 | { |
||
1182 | return \FMUP\Sapi::getInstance() && \FMUP\Sapi::getInstance()->is(\FMUP\Sapi::CGI) && (bool)self::$session; |
||
1183 | } |
||
1184 | } |
||
1185 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.