diff options
| author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
| commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
| tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /src/model/Model.php | |
| parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
| download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.gz AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.bz2 AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip | |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'src/model/Model.php')
| -rw-r--r-- | src/model/Model.php | 313 |
1 files changed, 0 insertions, 313 deletions
diff --git a/src/model/Model.php b/src/model/Model.php deleted file mode 100644 index b3d157d..0000000 --- a/src/model/Model.php +++ /dev/null | |||
| @@ -1,313 +0,0 @@ | |||
| 1 | <?php | ||
| 2 | // src/model/Model.php | ||
| 3 | |||
| 4 | abstract class Model extends DB | ||
| 5 | { | ||
| 6 | protected $db; // instance de PDO | ||
| 7 | protected $table; // <= enfant | ||
| 8 | |||
| 9 | //~ protected function __construct() // pour appel avec parent::__construct() | ||
| 10 | //~ {} | ||
| 11 | |||
| 12 | // getters | ||
| 13 | public function getTable(): string | ||
| 14 | { | ||
| 15 | return $this->table; | ||
| 16 | } | ||
| 17 | |||
| 18 | public function getAll(): array // à améliorer pour ne pas renvoyer $db et $table | ||
| 19 | { | ||
| 20 | return get_object_vars($this); // retourne les propriétés de l'objet | ||
| 21 | } | ||
| 22 | |||
| 23 | // setters | ||
| 24 | public function setId(int $value = 0) | ||
| 25 | { | ||
| 26 | if($value === 0) | ||
| 27 | { | ||
| 28 | $this->id = $this->db->lastInsertId(); // méthode de PDO, attention lastInsertId() ne gère pas la concurence | ||
| 29 | } | ||
| 30 | else | ||
| 31 | { | ||
| 32 | $this->id = $value; | ||
| 33 | } | ||
| 34 | return $this; | ||
| 35 | } | ||
| 36 | public function setTable(string $value) | ||
| 37 | { | ||
| 38 | $this->table = $value; | ||
| 39 | return($this); | ||
| 40 | } | ||
| 41 | |||
| 42 | public function hydrate(array $data): bool // $data = tableau associatif en entrée: nom_du_champ => valeur | ||
| 43 | { | ||
| 44 | foreach($data as $key => $value) | ||
| 45 | { | ||
| 46 | // nom du setter | ||
| 47 | // nom_propriete => setPropriete | ||
| 48 | // on sépare les mots par des espaces, ucwords met la première lettre de chaque mot en majuscule, puis on supprime les espaces | ||
| 49 | $setter_name = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); // ucwords: première lettre de chaque mot en majuscule | ||
| 50 | if(method_exists($this, $setter_name)) | ||
| 51 | { | ||
| 52 | $this->$setter_name($value); | ||
| 53 | } | ||
| 54 | else | ||
| 55 | { | ||
| 56 | echo "debug: la méthode $setter_name n'existe pas\n"; | ||
| 57 | return false; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | // cette fonction reçoit des données d'un tableau simple, permettant d'associer des champs de formulaires aux noms différents des champs de la BDD | ||
| 64 | // méthode lancée par des objets de type enfants | ||
| 65 | function hydrateFromForm(string $data_string, Object $Presta = NULL): bool // quand l'objet est $Details, on hydrate aussi $Presta | ||
| 66 | { | ||
| 67 | $data_string = $this->cleanSpecialChars($data_string); // possibilité que $data_string devienne une chaine vide | ||
| 68 | if($data_string !== '') | ||
| 69 | { | ||
| 70 | $data_array = explode('|', $data_string); // array | ||
| 71 | $check = false; | ||
| 72 | switch($this->getTable()) | ||
| 73 | { | ||
| 74 | case 'clients'; | ||
| 75 | if($data_array[0] == '') | ||
| 76 | { | ||
| 77 | echo "debug: données insuffisantes, le nom du client doit au minimum être renseigné\n"; | ||
| 78 | return false; | ||
| 79 | } | ||
| 80 | else | ||
| 81 | { | ||
| 82 | $check = $this->hydrate(['prenom_nom' => $data_array[0], 'code_client' => $data_array[1], 'adresse' => $data_array[2], 'code_postal' => $data_array[3], 'ville' => $data_array[4], 'telephone' => $data_array[5], 'courriel' => $data_array[6], 'apropos' => $data_array[7]]); | ||
| 83 | } | ||
| 84 | break; | ||
| 85 | case 'prestations'; // inutilisé | ||
| 86 | break; | ||
| 87 | case 'devis'; | ||
| 88 | $check = $this->hydrate(['taches' => $data_array[0], 'total_main_d_oeuvre' => $data_array[1], 'pieces' => $data_array[2], 'total_pieces' => $data_array[3], 'deplacement' => $data_array[4], 'prix_devis' => $data_array[5], 'total_HT' => $data_array[6], 'delai_livraison' => $data_array[7], 'validite_devis' => $data_array[8]]); | ||
| 89 | break; | ||
| 90 | case 'factures'; | ||
| 91 | if(count($data_array) === 11) | ||
| 92 | { | ||
| 93 | $check = $Presta->hydrate(['mode_paiement' => $data_array[10]]); | ||
| 94 | if($check) | ||
| 95 | { | ||
| 96 | $check = $this->hydrate(['taches' => $data_array[0], 'machine' => $data_array[1], 'OS' => $data_array[2], 'donnees' => $data_array[3], 'cles_licences' => $data_array[4], 'total_main_d_oeuvre' => $data_array[5], 'pieces' => $data_array[6], 'total_pieces' => $data_array[7], 'deplacement' => $data_array[8], 'total_HT' => $data_array[9]]); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | elseif(count($data_array) === 5) // facture à partir d'un devis | ||
| 100 | { | ||
| 101 | $check = $this->hydrate(['machine' => $data_array[0], 'OS' => $data_array[1], 'donnees' => $data_array[2], 'cles_licences' => $data_array[3]]); | ||
| 102 | if($check) | ||
| 103 | { | ||
| 104 | $check = $Presta->hydrate(['mode_paiement' => $data_array[4]]); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | else | ||
| 108 | { | ||
| 109 | echo "debug: le tableau \$data_array n'a pas la taille attendue.\n"; | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | break; | ||
| 113 | case 'cesu'; | ||
| 114 | $check = $Presta->hydrate(['mode_paiement' => $data_array[3]]); | ||
| 115 | if($check) | ||
| 116 | { | ||
| 117 | $check = $this->hydrate(['taches' => $data_array[0], 'duree_travail' => $data_array[1], 'salaire' => $data_array[2]]); | ||
| 118 | } | ||
| 119 | break; | ||
| 120 | case 'locations'; | ||
| 121 | $check = $this->hydrate(['designation' => $data_array[0], 'modele_description' => $data_array[1], 'valeur' => $data_array[2], 'etat_des_lieux_debut' => $data_array[3], 'etat_des_lieux_fin' => $data_array[4], 'duree_location' => $data_array[5], 'loyer_mensuel' => $data_array[6], 'loyers_payes' => $data_array[7], 'caution' => $data_array[8]]); | ||
| 122 | break; | ||
| 123 | default: // inutilisé | ||
| 124 | echo "debug: table inconnue hydrateFromForm()"; | ||
| 125 | return false; | ||
| 126 | } | ||
| 127 | return $check; | ||
| 128 | } | ||
| 129 | else | ||
| 130 | { | ||
| 131 | echo "debug: annulation lors du formulaire\n"; | ||
| 132 | return false; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | protected function cleanSpecialChars(string $data): string | ||
| 137 | { | ||
| 138 | $search = ['"']; | ||
| 139 | return str_replace($search, '', $data); | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 143 | // exécuter le SQL | ||
| 144 | // les $attributs correspondent aux ? dans les requêtes préparées | ||
| 145 | // ne pas surcharger la méthode PDO::query() qui n'est pas compatible | ||
| 146 | protected function execQuery(string $sql, array $attributes = null) | ||
| 147 | { | ||
| 148 | $this->db = parent::getInstance(); // parent::, self:: et DB:: sont équivalents | ||
| 149 | |||
| 150 | if($attributes !== null) // requête préparée | ||
| 151 | { | ||
| 152 | //~ var_dump($sql); | ||
| 153 | //~ var_dump($attributes); | ||
| 154 | $query = $this->db->prepare($sql); | ||
| 155 | $query->execute($attributes); | ||
| 156 | return $query; | ||
| 157 | } | ||
| 158 | else // requête simple | ||
| 159 | { | ||
| 160 | return $this->db->query($sql); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | // méthodes CRUD | ||
| 166 | |||
| 167 | // create INSERT | ||
| 168 | public function create() // = write | ||
| 169 | { | ||
| 170 | $fields = []; | ||
| 171 | $question_marks = []; // ? | ||
| 172 | $values = []; | ||
| 173 | //~ var_dump($this); | ||
| 174 | foreach($this as $field => $value) | ||
| 175 | { | ||
| 176 | //~ var_dump($field); var_dump($value); | ||
| 177 | // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
| 178 | // note: avec le !== (au lieu de !=) une valeur 0 est différente de null | ||
| 179 | if($value !== null && $field != 'db' && $field != 'table') | ||
| 180 | { | ||
| 181 | $value = $this->clean_for_bash($value); // pour la BDD | ||
| 182 | $this->$field = $value; // pour latex | ||
| 183 | |||
| 184 | $fields[] = $field; // push | ||
| 185 | $question_marks[] = '?'; | ||
| 186 | $values[] = $value; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | $field_list = implode(', ', $fields); | ||
| 190 | $question_mark_list = implode(', ', $question_marks); | ||
| 191 | |||
| 192 | // INSERT INTO annonces (titre, description, actif) VALUES (?, ?, ?) | ||
| 193 | return($this->execQuery('INSERT INTO ' . $this->table . ' (' . $field_list . ') VALUES (' . $question_mark_list . ')', $values)); | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | // read SELECT | ||
| 198 | protected function readAll(): array // obtenir une table | ||
| 199 | { | ||
| 200 | return($this->execQuery('SELECT * FROM ' . $this->table)->fetchAll()); // fonctionne aussi sans le point virgule dans le SQL!! | ||
| 201 | } | ||
| 202 | |||
| 203 | public function findById() // obtenir une entrée grace à son ID | ||
| 204 | { | ||
| 205 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $this->id)->fetch()); | ||
| 206 | } | ||
| 207 | public function getDetailsByIdPresta() | ||
| 208 | { | ||
| 209 | if($this->table == 'prestations') | ||
| 210 | { | ||
| 211 | // à l'occaz, créer une classe NonVendue et rendre Prestations abstraite | ||
| 212 | echo 'erreur: ne pas appeler Model::getDetailsByIdPresta() si la table ciblée est "prestations".'; | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | else | ||
| 216 | { | ||
| 217 | return $this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id_Presta = ' . $this->id_presta)->fetch(); // type array | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | protected function find(array $criteria): array // obtenir une entrée avec un tableau associatif 'champ' => 'valeur' | ||
| 222 | { | ||
| 223 | $fields = []; | ||
| 224 | $values = []; | ||
| 225 | |||
| 226 | // change "'id' => 2" en "'id' = ?" et "2" | ||
| 227 | foreach($criteria as $field => $value) | ||
| 228 | { | ||
| 229 | $fields[] = "$field = ?"; // même chose que: $field . " = ?" | ||
| 230 | $values[] = $value; | ||
| 231 | } | ||
| 232 | $field_list = implode(' AND ', $fields); // créer une chaîne reliant les morceaux avec le morceau AND en paramètre: 'adresse = ? AND id = ?' | ||
| 233 | |||
| 234 | // SELECT * FROM annonces WHERE actif = 1; | ||
| 235 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field_list, $values)->fetchAll()); | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | // update UPDATE | ||
| 240 | public function update() | ||
| 241 | { | ||
| 242 | $fields = []; | ||
| 243 | $values = []; | ||
| 244 | foreach($this as $field => $value) | ||
| 245 | { | ||
| 246 | if($value !== null && $field != 'db' && $field != 'table') // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
| 247 | { | ||
| 248 | $value = $this->clean_for_bash($value); // pour la BDD | ||
| 249 | $this->$field = $value; // pour latex | ||
| 250 | |||
| 251 | $fields[] = $field . ' = ?'; | ||
| 252 | $values[] = $value; | ||
| 253 | } | ||
| 254 | } | ||
| 255 | $values[] = $this->id; // cette syntaxe ajoute une valeur au tableau | ||
| 256 | $field_list = implode(', ', $fields); | ||
| 257 | |||
| 258 | // UPDATE annonces SET titre = ?, description = ?, actif = ? WHERE id = ? | ||
| 259 | return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field_list . ' WHERE id = ?', $values)); | ||
| 260 | } | ||
| 261 | |||
| 262 | public function updateOneValue(string $field, $value) | ||
| 263 | { | ||
| 264 | return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field . ' = ? WHERE id = ?', [$value, $this->id])); | ||
| 265 | } | ||
| 266 | |||
| 267 | |||
| 268 | // delete DELETE | ||
| 269 | protected function delete(int $id) | ||
| 270 | { | ||
| 271 | return($this->execQuery("DELETE FROM {$this->table} WHERE id = ?", [$id])); // double quotes "" pour insertion de variable, paramètre [$id] parce qu'on veut un tableau | ||
| 272 | } | ||
| 273 | |||
| 274 | |||
| 275 | private function clean_for_bash($value) | ||
| 276 | { | ||
| 277 | if(is_string($value) && $value != '') | ||
| 278 | { | ||
| 279 | do | ||
| 280 | { | ||
| 281 | $value = trim($value); | ||
| 282 | $value = preg_replace('#^-#','' , $value); // en bash une chaîne commençant par un tiret est un paramètre | ||
| 283 | } while($value[0] == ' '|| $value[0] == '-'); // chaîne commençant par un tiret puis un espace, ou même - - - - - | ||
| 284 | } | ||
| 285 | return $value; | ||
| 286 | } | ||
| 287 | |||
| 288 | |||
| 289 | static public function createTables() | ||
| 290 | { | ||
| 291 | static $first_time = true; | ||
| 292 | |||
| 293 | if($first_time) // fonction normallement appelée qu'une seule fois | ||
| 294 | { | ||
| 295 | foreach(StructTablesDB::$structureOfTables as $tableName => $oneTable) | ||
| 296 | { | ||
| 297 | $query = 'CREATE TABLE IF NOT EXISTS ' . $tableName . ' ('; | ||
| 298 | foreach($oneTable as $key => $value) | ||
| 299 | { | ||
| 300 | $query .= $key . ' ' . $value . ', '; | ||
| 301 | } | ||
| 302 | $query .= 'PRIMARY KEY(ID AUTOINCREMENT));'; | ||
| 303 | parent::getInstance()->exec($query); | ||
| 304 | } | ||
| 305 | |||
| 306 | $first_time = false; | ||
| 307 | } | ||
| 308 | else | ||
| 309 | { | ||
| 310 | echo "Model::createTables() a déjà été appelée et ne fera rien.\n"; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } | ||
