diff options
Diffstat (limited to 'src/model/Model.php')
| -rw-r--r-- | src/model/Model.php | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/model/Model.php b/src/model/Model.php new file mode 100644 index 0000000..ad9e6c7 --- /dev/null +++ b/src/model/Model.php | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | <?php | ||
| 2 | // php/Model.php | ||
| 3 | |||
| 4 | class Model extends DB | ||
| 5 | { | ||
| 6 | private $db; // instance de PDO | ||
| 7 | protected $table; // <= enfant | ||
| 8 | //static protected $tableStructure; | ||
| 9 | |||
| 10 | public function __construct() | ||
| 11 | { | ||
| 12 | $this->db = parent::getInstance(); // connexion | ||
| 13 | } | ||
| 14 | |||
| 15 | |||
| 16 | // setters (plusieurs en même temps) | ||
| 17 | public function hydrate(array $data) // $data = tableau associatif en entrée: nom_du_champ => valeur | ||
| 18 | { | ||
| 19 | foreach($data as $key => $value) | ||
| 20 | { | ||
| 21 | // nom d'un setter, forme "setMachin()" | ||
| 22 | $setterName = 'set' . ucfirst($key); // ucfirst met la première lettre en majuscule | ||
| 23 | // détection | ||
| 24 | if(method_exists($this, $setterName)) // on trouve aussi la méthode is_callable() | ||
| 25 | { | ||
| 26 | // on renseigne les propriétés des l'instance | ||
| 27 | $this->$setterName($value); // nom d'une méthode dans une variable | ||
| 28 | } | ||
| 29 | } | ||
| 30 | return($this); | ||
| 31 | } | ||
| 32 | |||
| 33 | |||
| 34 | // exécuter le SQL | ||
| 35 | // les attributs correspondent aux ? dans les requêtes préparées | ||
| 36 | // ne pas surcharger la méthode PDO::query() qui n'est pas compatible | ||
| 37 | protected function execQuery(string $sql, array $attributes = null) | ||
| 38 | { | ||
| 39 | $this->db = parent::getInstance(); // connexion | ||
| 40 | |||
| 41 | if($attributes !== null) // requête préparée | ||
| 42 | { | ||
| 43 | $query = $this->db->prepare($sql); | ||
| 44 | $query->execute($attributes); | ||
| 45 | return $query; | ||
| 46 | } | ||
| 47 | else // requête simple | ||
| 48 | { | ||
| 49 | return $this->db->query($sql); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | // méthodes CRUD qui marchent (les spécifiques sont dans les classes enfant) | ||
| 55 | |||
| 56 | // create INSERT | ||
| 57 | public function create() // = write | ||
| 58 | { | ||
| 59 | $fields = []; | ||
| 60 | $question_marks = []; // ? | ||
| 61 | $values = []; | ||
| 62 | foreach($this as $field => $value) | ||
| 63 | { | ||
| 64 | // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
| 65 | // note: avec le !== (au lieu de !=) une valeur 0 passe le filtre | ||
| 66 | if($value !== null && $field != 'db' && $field != 'table') | ||
| 67 | { | ||
| 68 | $fields[] = $field; // push | ||
| 69 | $question_marks[] = '?'; | ||
| 70 | $values[] = $value; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | $field_list = implode(', ', $fields); | ||
| 74 | $question_mark_list = implode(', ', $question_marks); | ||
| 75 | |||
| 76 | // INSERT INTO annonces (titre, description, actif) VALUES (?, ?, ?) | ||
| 77 | return($this->execQuery('INSERT INTO ' . $this->table . ' (' . $field_list . ') VALUES (' . $question_mark_list . ')', $values)); | ||
| 78 | } | ||
| 79 | |||
| 80 | |||
| 81 | // read SELECT | ||
| 82 | public function readAll() | ||
| 83 | { | ||
| 84 | $query = $this->execQuery('SELECT * FROM ' . $this->table . ';'); // fonctionne aussi sans le point virgule dans le SQL!! | ||
| 85 | return($query->fetchAll()); | ||
| 86 | } | ||
| 87 | public function findById(int $id) | ||
| 88 | { | ||
| 89 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $id)->fetch()); | ||
| 90 | } | ||
| 91 | |||
| 92 | public function find(array $criteria) | ||
| 93 | { | ||
| 94 | $fields = []; | ||
| 95 | $values = []; | ||
| 96 | |||
| 97 | // change "'ID' => 2" en "'ID' = ?" et "2" | ||
| 98 | foreach($criteria as $field => $value) | ||
| 99 | { | ||
| 100 | $fields[] = "$field = ?"; // même chose que: $field . " = ?" | ||
| 101 | $values[] = $value; | ||
| 102 | } | ||
| 103 | $field_list = implode(' AND ', $fields); // créer une chaîne reliant les morceaux avec le morceau AND en paramètre: 'adresse = ? AND ID = ?' | ||
| 104 | |||
| 105 | // SELECT * FROM annonces WHERE actif = 1; | ||
| 106 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field_list, $values)->fetchAll()); | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | // update UPDATE | ||
| 111 | public function update(int $id) | ||
| 112 | { | ||
| 113 | $fields = []; | ||
| 114 | $values = []; | ||
| 115 | foreach($this as $field => $value) | ||
| 116 | { | ||
| 117 | if($value !== null && $field != 'db' && $field != 'table') // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
| 118 | { | ||
| 119 | $fields[] = $field . ' = ?'; | ||
| 120 | $values[] = $value; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | $values[] = $id; | ||
| 124 | $field_list = implode(', ', $fields); | ||
| 125 | |||
| 126 | // UPDATE annonces SET titre = ?, description = ?, actif = ? WHERE id= ? | ||
| 127 | return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field_list . ' WHERE id = ?', $values)); | ||
| 128 | } | ||
| 129 | |||
| 130 | |||
| 131 | // delete DELETE | ||
| 132 | public function delete(int $id) | ||
| 133 | { | ||
| 134 | 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 | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | // fonction appelée une seule fois pour chaque table | ||
| 139 | // le tableau nécessaire n'est pas copié en mémoire à l'instanciation (pas de fuite de mémoire), mais uniquement à l'appel de cette fonction statique, à la fin de la fonction la mémoire est libérée | ||
| 140 | // DBStructure::${self::$tableStructure} permet de nommer une variable statique de classe | ||
| 141 | static public function createTables() | ||
| 142 | { | ||
| 143 | //~ var_dump(StructTablesDB::$structureOfTables); | ||
| 144 | foreach(StructTablesDB::$structureOfTables as $tableName => $oneTable) | ||
| 145 | { | ||
| 146 | //var_dump(StructTablesDB::${self::$tableStructure}); => propriété statique de classe dans une variable | ||
| 147 | $fields_and_types = []; | ||
| 148 | $query = 'CREATE TABLE IF NOT EXISTS ' . $tableName . ' ('; | ||
| 149 | foreach($oneTable as $key => $value) | ||
| 150 | { | ||
| 151 | $fields_and_types[] = $key . ' ' . $value; | ||
| 152 | } | ||
| 153 | $query .= implode(', ', $fields_and_types); // implode() convertit un tableau en une chaîne avec un séparateur entre chaque élément | ||
| 154 | $query .= ', PRIMARY KEY(ID AUTOINCREMENT));'; | ||
| 155 | //echo($query . "\n\n"); | ||
| 156 | |||
| 157 | parent::getInstance()->exec($query); // merci singleton! | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | } | ||
| 162 | } | ||
