From ff14091476a35de16a9ea3208501040cfae93a06 Mon Sep 17 00:00:00 2001 From: polo Date: Wed, 14 Dec 2022 12:55:46 +0100 Subject: MODEL + reorganisation --- src/model/CESU.php | 46 ++++++++++++ src/model/Clients.php | 50 +++++++++++++ src/model/DB.php | 48 +++++++++++++ src/model/DevisFactures.php | 98 ++++++++++++++++++++++++++ src/model/Locations.php | 74 ++++++++++++++++++++ src/model/Model.php | 162 +++++++++++++++++++++++++++++++++++++++++++ src/model/Prestations.php | 62 +++++++++++++++++ src/model/StructTablesDB.php | 35 ++++++++++ 8 files changed, 575 insertions(+) create mode 100644 src/model/CESU.php create mode 100644 src/model/Clients.php create mode 100644 src/model/DB.php create mode 100644 src/model/DevisFactures.php create mode 100644 src/model/Locations.php create mode 100644 src/model/Model.php create mode 100644 src/model/Prestations.php create mode 100644 src/model/StructTablesDB.php (limited to 'src/model') diff --git a/src/model/CESU.php b/src/model/CESU.php new file mode 100644 index 0000000..4679da2 --- /dev/null +++ b/src/model/CESU.php @@ -0,0 +1,46 @@ +table = self::TABLE; // => Model::$table + } + + // setters + public function setID(int $value) + { + $this->ID = $value; + return($this); + } + public function setIDPresta(int $value) + { + $this->ID_presta = $value; + return($this); + } + public function setTaches(string $value) + { + $this->taches = $value; + return($this); + } + public function setDureeTravail(string $value) + { + $this->duree_travail = $value; + return($this); + } + public function setSalaire(float $value) + { + $this->salaire = $value; + return($this); + } +} diff --git a/src/model/Clients.php b/src/model/Clients.php new file mode 100644 index 0000000..1256458 --- /dev/null +++ b/src/model/Clients.php @@ -0,0 +1,50 @@ +table = strtolower(__CLASS__); // simple parce que la classe a le nom de la table + } + + //~ public function set(string $variable, $value) + //~ { + //~ $this->$variable = $value; + //~ return($this); + //~ } + + // setters + public function setID(int $value) // inutile? il s'autoincrémente + { + $this->ID = $value; + return($this); + } + public function setPrenom_nom(string $value) + { + $this->prenom_nom = $value; + return($this); + } + public function setAdresse(string $value) + { + $this->adresse = $value; + return($this); + } + public function setCode_client(string $value) + { + $this->code_client = $value; + return($this); + } + public function setCommentaires(string $value) + { + $this->commentaires = $value; + return($this); + } +} diff --git a/src/model/DB.php b/src/model/DB.php new file mode 100644 index 0000000..381623b --- /dev/null +++ b/src/model/DB.php @@ -0,0 +1,48 @@ + PDO::$dsn + //$this->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); // pour mysql/mariadb + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // $this pour la méthode du parent PDO + $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // pour PDO:fetch() et PDO::fetchAll() + // avec PDO::FETCH_ASSOC on obtient un tableau associatif, marche très bien puisqu'on utilise déjà des ID avec incrémentation automatique + // avec PDO::FETCH_BOTH (par défaut) on récupère les données en double (identifiants partant de 0 + tableau associatif) + } + catch(PDOException $e) + { + die("Impossible de se connecter à la base de données.\n" . $e->getMessage()); + } + } + + // créer son objet avec: $Bdd = parent::getInstance(); + public static function getInstance(): self + { + if(self::$Instance === null) + { + self::$Instance = new self(); + } + return self::$Instance; + } +} diff --git a/src/model/DevisFactures.php b/src/model/DevisFactures.php new file mode 100644 index 0000000..be733dd --- /dev/null +++ b/src/model/DevisFactures.php @@ -0,0 +1,98 @@ +table = strtolower(__CLASS__); + } + + // setters + public function setID(int $value) + { + $this->ID = $value; + return($this); + } + public function setIDPresta(int $value) + { + $this->ID_presta = $value; + return($this); + } + public function setValiditeDdevis(string $value) + { + $this->validite_devis = $value; + return($this); + } + public function setSignatureDevis(string $value) + { + $this->signature_devis = $value; + return($this); + } + public function setTaches(string $value) + { + $this->taches = $value; + return($this); + } + public function setMachine(string $value) + { + $this->machine = $value; + return($this); + } + public function setOS(string $value) + { + $this->OS = $value; + return($this); + } + public function setDonnees(string $value) + { + $this->donnees = $value; + return($this); + } + public function setClesLicences(string $value) + { + $this->cles_licences = $value; + return($this); + } + public function setTotalMainDOeuvre(float $value) + { + $this->total_main_d_oeuvre = $value; + return($this); + } + public function setPieces(string $value) + { + $this->pieces = $value; + return($this); + } + public function setTotalPieces(float $value) + { + $this->total_pieces = $value; + return($this); + } + public function setDeplacement(float $value) + { + $this->deplacement = $value; + return($this); + } + public function setTotalHT(float $value) + { + $this->total_HT = $value; + return($this); + } +} diff --git a/src/model/Locations.php b/src/model/Locations.php new file mode 100644 index 0000000..2aa175a --- /dev/null +++ b/src/model/Locations.php @@ -0,0 +1,74 @@ +table = strtolower(__CLASS__); + } + + // setters + public function setID(int $value) + { + $this->ID = $value; + return($this); + } + public function setIDPresta(int $value) + { + $this->ID_presta = $value; + return($this); + } + public function setNatureBien(string $value) + { + $this->nature_bien = $value; + return($this); + } + public function setModele(string $value) + { + $this->modele = $value; + return($this); + } + public function setValeur(float $value) + { + $this->valeur = $value; + return($this); + } + public function setEtatDesLieuxDebut(string $value) + { + $this->etat_des_lieux_debut = $value; + return($this); + } + public function setEtatDesLieuxFin(string $value) + { + $this->etat_des_lieux_fin = $value; + return($this); + } + public function setDureeLocation(string $value) + { + $this->duree_location = $value; + return($this); + } + public function setlLyerMensuel(float $value) + { + $this->loyer_mensuel = $value; + return($this); + } + public function setTotalHT(float $value) + { + $this->total_HT = $value; + return($this); + } +} 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 @@ +db = parent::getInstance(); // connexion + } + + + // setters (plusieurs en même temps) + public function hydrate(array $data) // $data = tableau associatif en entrée: nom_du_champ => valeur + { + foreach($data as $key => $value) + { + // nom d'un setter, forme "setMachin()" + $setterName = 'set' . ucfirst($key); // ucfirst met la première lettre en majuscule + // détection + if(method_exists($this, $setterName)) // on trouve aussi la méthode is_callable() + { + // on renseigne les propriétés des l'instance + $this->$setterName($value); // nom d'une méthode dans une variable + } + } + return($this); + } + + + // exécuter le SQL + // les attributs correspondent aux ? dans les requêtes préparées + // ne pas surcharger la méthode PDO::query() qui n'est pas compatible + protected function execQuery(string $sql, array $attributes = null) + { + $this->db = parent::getInstance(); // connexion + + if($attributes !== null) // requête préparée + { + $query = $this->db->prepare($sql); + $query->execute($attributes); + return $query; + } + else // requête simple + { + return $this->db->query($sql); + } + } + + + // méthodes CRUD qui marchent (les spécifiques sont dans les classes enfant) + + // create INSERT + public function create() // = write + { + $fields = []; + $question_marks = []; // ? + $values = []; + foreach($this as $field => $value) + { + // champs non renseignées et variables de l'objet qui ne sont pas des champs + // note: avec le !== (au lieu de !=) une valeur 0 passe le filtre + if($value !== null && $field != 'db' && $field != 'table') + { + $fields[] = $field; // push + $question_marks[] = '?'; + $values[] = $value; + } + } + $field_list = implode(', ', $fields); + $question_mark_list = implode(', ', $question_marks); + + // INSERT INTO annonces (titre, description, actif) VALUES (?, ?, ?) + return($this->execQuery('INSERT INTO ' . $this->table . ' (' . $field_list . ') VALUES (' . $question_mark_list . ')', $values)); + } + + + // read SELECT + public function readAll() + { + $query = $this->execQuery('SELECT * FROM ' . $this->table . ';'); // fonctionne aussi sans le point virgule dans le SQL!! + return($query->fetchAll()); + } + public function findById(int $id) + { + return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $id)->fetch()); + } + + public function find(array $criteria) + { + $fields = []; + $values = []; + + // change "'ID' => 2" en "'ID' = ?" et "2" + foreach($criteria as $field => $value) + { + $fields[] = "$field = ?"; // même chose que: $field . " = ?" + $values[] = $value; + } + $field_list = implode(' AND ', $fields); // créer une chaîne reliant les morceaux avec le morceau AND en paramètre: 'adresse = ? AND ID = ?' + + // SELECT * FROM annonces WHERE actif = 1; + return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field_list, $values)->fetchAll()); + } + + + // update UPDATE + public function update(int $id) + { + $fields = []; + $values = []; + foreach($this as $field => $value) + { + if($value !== null && $field != 'db' && $field != 'table') // champs non renseignées et variables de l'objet qui ne sont pas des champs + { + $fields[] = $field . ' = ?'; + $values[] = $value; + } + } + $values[] = $id; + $field_list = implode(', ', $fields); + + // UPDATE annonces SET titre = ?, description = ?, actif = ? WHERE id= ? + return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field_list . ' WHERE id = ?', $values)); + } + + + // delete DELETE + public function delete(int $id) + { + 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 + } + + + // fonction appelée une seule fois pour chaque table + // 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 + // DBStructure::${self::$tableStructure} permet de nommer une variable statique de classe + static public function createTables() + { + //~ var_dump(StructTablesDB::$structureOfTables); + foreach(StructTablesDB::$structureOfTables as $tableName => $oneTable) + { + //var_dump(StructTablesDB::${self::$tableStructure}); => propriété statique de classe dans une variable + $fields_and_types = []; + $query = 'CREATE TABLE IF NOT EXISTS ' . $tableName . ' ('; + foreach($oneTable as $key => $value) + { + $fields_and_types[] = $key . ' ' . $value; + } + $query .= implode(', ', $fields_and_types); // implode() convertit un tableau en une chaîne avec un séparateur entre chaque élément + $query .= ', PRIMARY KEY(ID AUTOINCREMENT));'; + //echo($query . "\n\n"); + + parent::getInstance()->exec($query); // merci singleton! + } + + + } +} diff --git a/src/model/Prestations.php b/src/model/Prestations.php new file mode 100644 index 0000000..4f58d70 --- /dev/null +++ b/src/model/Prestations.php @@ -0,0 +1,62 @@ +table = strtolower(__CLASS__); + } + + // setters + public function setID(int $value) + { + $this->ID = $value; + return($this); + } + public function setIDClient(int $value) + { + $this->ID_client = $value; + return($this); + } + public function setCombientiemeFois(int $value) + { + $this->combientieme_fois = $value; + return($this); + } + public function setCodePresta(string $value) + { + $this->code_presta = $value; + return($this); + } + public function setDate(int $value) + { + $this->date = $value; + return($this); + } + public function setType(string $value) + { + $this->type = $value; + return($this); + } + public function setModePaiement(string $value) + { + $this->mode_paiement = $value; + return($this); + } + public function setCommentaires(string $value) + { + $this->commentaires = $value; + return($this); + } +} diff --git a/src/model/StructTablesDB.php b/src/model/StructTablesDB.php new file mode 100644 index 0000000..cf6de5d --- /dev/null +++ b/src/model/StructTablesDB.php @@ -0,0 +1,35 @@ + ['ID' => 'INTEGER', 'prenom_nom' => 'TEXT', 'adresse' => 'TEXT', 'code_client' => 'TEXT', 'commentaires' => 'TEXT'], + 'prestations' => ['ID' => 'INTEGER', 'ID_client' => 'INTEGER', 'combientieme_fois' => 'INTEGER', 'code_presta' => 'TEXT', 'date' => 'INTEGER', 'type' => 'TEXT', 'mode_paiement' => 'TEXT', 'commentaires' => 'TEXT'], + 'devisfactures' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'validite_devis' => 'TEXT', 'signature_devis' => 'TEXT', 'taches' => 'TEXT', 'machine' => 'TEXT', 'OS' => 'TEXT', 'donnees' => 'TEXT', 'cles_licences' => 'TEXT', 'total_main_d_oeuvre' => 'REAL', 'pieces' => 'TEXT', 'total_pieces' => 'REAL', 'deplacement' => 'REAL', 'total_HT' => 'REAL'], + 'cesu' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'taches' => 'TEXT', 'duree_travail' => 'TEXT', 'salaire' => 'REAL'], + 'locations' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'nature_bien' => 'TEXT', 'modele' => 'TEXT', 'valeur' => 'REAL', 'etat_des_lieux_debut' => 'TEXT', 'etat_des_lieux_fin' => 'TEXT', 'duree_location' => 'TEXT', 'loyer_mensuel' => 'REAL', 'total_HT' => 'REAL'] + ]; + + // les types de variables de sqlite sont peu nombreux et autorisent un typage automatique + // le "type indiqué" est indiqué dans l'instruction CREATE TABLE + // https://www.leppf.com/site/spip.php?article89 + + // || type indiqué || type choisi automatiquement || autre types possibles || + // --------------------------------------------------------------------------- + // || TEXT || TEXT || BLOB, NULL || + // || INTEGER || INTEGER (de 1 à 8 octets) || REAL, TEXT, BLOB, NULL || + // || REAL || REAL (flottant sur 9 octets) || TEXT, BLOB, NULL || + // || NUMERIC || INTEGER ou REAL || TEXT, BLOB, NULL || + // || NONE || indéfini || dépend des données || + + // du code SQL écrit pour d'autres SGBD devrait fonctionner, + // sqlite fera des conversions dans ses propres types avec les problèmes qu'on peut imaginer + + // pour les dates, on stockera à priori le timestamp +} -- cgit v1.2.3