summaryrefslogtreecommitdiff
path: root/old/model version 0.1
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2024-08-14 17:20:10 +0200
committerpolo <ordipolo@gmx.fr>2024-08-14 17:20:10 +0200
commit5fb0a2785718160317069c87496d1602e32ea3d6 (patch)
tree3225c81385576a2ece5fdefa54d3fb7059115b71 /old/model version 0.1
parentbf6655a534a6775d30cafa67bd801276bda1d98d (diff)
downloadAppliGestionPHP-5fb0a2785718160317069c87496d1602e32ea3d6.zip
autoload avec composer
Diffstat (limited to 'old/model version 0.1')
-rw-r--r--old/model version 0.1/CESU.php66
-rw-r--r--old/model version 0.1/Clients.php168
-rw-r--r--old/model version 0.1/DB.php48
-rw-r--r--old/model version 0.1/DevisFactures.php215
-rw-r--r--old/model version 0.1/Locations.php127
-rw-r--r--old/model version 0.1/Model.php313
-rw-r--r--old/model version 0.1/Prestations.php159
-rw-r--r--old/model version 0.1/StructTablesDB.php36
8 files changed, 1132 insertions, 0 deletions
diff --git a/old/model version 0.1/CESU.php b/old/model version 0.1/CESU.php
new file mode 100644
index 0000000..2768b8f
--- /dev/null
+++ b/old/model version 0.1/CESU.php
@@ -0,0 +1,66 @@
1<?php
2// src/model/CESU.php
3
4class CESU extends Model
5{
6 //~ const TABLE = 'cesu';
7
8 // lecture des données ou hydratation
9 protected $id;
10 protected $id_presta;
11 protected $taches;
12 protected $duree_travail;
13 protected $salaire;
14
15 public function __construct()
16 {
17 $this->table = strtolower(__CLASS__); // cesu
18 }
19
20 public function getAllWithWindowFields(): array // différent de Model::getAll() qui retourne get_object_vars($this)
21 {
22 return [
23 "Tâche effectuée:" => $this->taches,
24 "Durée du travail:" => $this->duree_travail,
25 "Salaire:" => $this->salaire];
26 }
27 public function set(string $entry, string $input)
28 {
29 $input = $this->cleanSpecialChars($input); // possibilité que $input devienne une chaine vide
30 switch($entry)
31 {
32 case "Tâche effectuée:":
33 $this->setTaches($input);
34 break;
35 case "Durée du travail:":
36 $this->setDureeTravail($input);
37 break;
38 case "Salaire:":
39 $this->setSalaire($input);
40 break;
41 }
42 }
43
44 // setters
45 public function setIdPresta(int $value)
46 {
47 $this->id_presta = $value;
48 return($this);
49 }
50 public function setTaches(string $value)
51 {
52 $this->taches = $value;
53 return($this);
54 }
55 public function setDureeTravail(string $value)
56 {
57 $this->duree_travail = $value;
58 return($this);
59 }
60 public function setSalaire($value)
61 {
62 $value = str_replace(',', '.', $value);
63 $this->salaire = (float) $value;
64 return($this);
65 }
66}
diff --git a/old/model version 0.1/Clients.php b/old/model version 0.1/Clients.php
new file mode 100644
index 0000000..32cf0c5
--- /dev/null
+++ b/old/model version 0.1/Clients.php
@@ -0,0 +1,168 @@
1<?php
2// src/model/Clients.php
3
4class Clients extends Model
5{
6 // lecture des données ou hydratation
7 protected $id; // auto-incrémentée
8 protected $prenom_nom;
9 protected $code_client;
10 protected $adresse;
11 protected $code_postal;
12 protected $ville;
13 protected $telephone;
14 protected $courriel;
15 protected $apropos;
16 protected $type = 'prospect';
17
18 public function __construct()
19 {
20 $this->table = strtolower(__CLASS__); // clients
21 }
22
23 // getters
24 public function getId(): int
25 {
26 return $this->id;
27 }
28 public function getCodeClient(): string
29 {
30 return $this->code_client;
31 }
32 public function getAllWithWindowFields(): array // différent de Model::getAll() qui retourne get_object_vars($this)
33 {
34 return [
35 "Prénom Nom:" => $this->prenom_nom,
36 "Code client (J.C.Dusse):" => $this->code_client,
37 "Adresse:" => $this->adresse,
38 "Code postal:" => $this->code_postal,
39 "Ville:" => $this->ville,
40 "Telephone:" => $this->telephone,
41 "Courriel:" => $this->courriel,
42 "À propos:" => $this->apropos,
43 "Client ou Prospect?" => $this->type];
44 }
45 public function set(string $entry, string $input)
46 {
47 $input = $this->cleanSpecialChars($input); // possibilité que $input devienne une chaine vide
48 switch($entry)
49 {
50 case "Prénom Nom:":
51 $this->setPrenomNom($input);
52 break;
53 case "Code client (J.C.Dusse):":
54 $this->setCodeClient($input);
55 break;
56 case "Adresse:":
57 $this->setAdresse($input);
58 break;
59 case "Code postal:":
60 $this->setCodePostal($input);
61 break;
62 case "Ville:":
63 $this->setVille($input);
64 break;
65 case "Telephone:":
66 $this->setTelephone($input);
67 break;
68 case "Courriel:":
69 $this->setCourriel($input);
70 break;
71 case "À propos:":
72 $this->setApropos($input);
73 break;
74 case "Client ou Prospect?":
75 $this->setType($input);
76 break;
77 }
78 }
79
80 // setters
81 public function setPrenomNom($value)
82 {
83 $this->prenom_nom = (string) $value;
84 return $this;
85 }
86 public function setCodeClient($value)
87 {
88 $this->code_client = (string) $value;
89 return $this;
90 }
91 public function setAdresse($value)
92 {
93 $this->adresse = (string) $value;
94 return $this;
95 }
96 public function setCodePostal($value)
97 {
98 $this->code_postal = (string) $value;
99 return $this;
100 }
101 public function setVille($value)
102 {
103 $this->ville = (string) $value;
104 return $this;
105 }
106 public function setTelephone($value)
107 {
108 // type string parce que:
109 // - zenity renvoie une chaine
110 // - permet de garder le 0 au début et d'inscrire plusieurs numéros
111 $this->telephone = (string) $value;
112 return $this;
113 }
114 public function setCourriel($value)
115 {
116 $this->courriel = (string) $value;
117 return $this;
118 }
119 public function setApropos($value)
120 {
121 $this->apropos = (string) $value;
122 return $this;
123 }
124 public function setType($value)
125 {
126 $this->type = (string) $value;
127 return $this;
128 }
129
130 public function typeToClient(): bool
131 {
132 if($this->type != 'client')
133 {
134 $this->type = 'client';
135 return true;
136 }
137 else
138 {
139 return false;
140 }
141 }
142
143 public function findByKeywords(array $keywords, string $field): array // n'hydrate pas les variables, on doit choisir un client et hydrater ensuite
144 {
145 $result = [];
146 for($i = 0; $i < count($keywords); $i++)
147 {
148 // tableau à deux dimensions obtenu pour un mot clé
149 $query_result = $this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field . ' LIKE "%' . $keywords[$i] . '%"')->fetchAll();
150 foreach($query_result as $one_array) // pour chaque sous tableau
151 {
152 $already_exist = false;
153 for($j = 0; $j < count($result); $j++) // pour chaque tableau déjà enregistré dans le tableau $result
154 {
155 if($result[$j]['id'] === $one_array['id'])
156 {
157 $already_exist = true;
158 }
159 }
160 if(!$already_exist)
161 {
162 $result[] = $one_array;
163 }
164 }
165 }
166 return $result;
167 }
168}
diff --git a/old/model version 0.1/DB.php b/old/model version 0.1/DB.php
new file mode 100644
index 0000000..47407ba
--- /dev/null
+++ b/old/model version 0.1/DB.php
@@ -0,0 +1,48 @@
1<?php
2// src/model/DB.php
3
4// cette classe applique le pattern "singleton", il empêche la classe PDO d'être instanciée plusieurs fois
5// l'instance est récupérable partout mais sans les inconvénients d'une variable globale
6
7// comment?
8// - le constructeur est privé, c'est à cette condition que l'instanciation devient contrôlable
9// - notre instance unique est stockée dans un attribut privé et statique
10// - une méthode statique appele le contructeur si l'instance unique n'existe pas encore, puis retourne l'instance
11
12class DB extends PDO
13{
14 // paramètres du constructeur de PDO
15 public static $dsn = ''; // Data Source Name = préfixe + hôte + port + nom de la base + encodage
16 //~ public static $user = '';
17 //~ public static $password = '';
18 //~ public static $options = '';
19
20 private static $Instance;
21
22 private function __construct() // exécuté une seul fois à cause du "if" dans getInstance()
23 {
24 try
25 {
26 parent::__construct(self::$dsn); // => PDO::$dsn
27 //$this->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); // pour mysql/mariadb
28 $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // $this pour la méthode du parent PDO
29 $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // pour PDO:fetch() et PDO::fetchAll()
30 // avec PDO::FETCH_ASSOC on obtient un tableau associatif, marche très bien puisqu'on utilise déjà des ID avec incrémentation automatique
31 // avec PDO::FETCH_BOTH (par défaut) on récupère les données en double (identifiants partant de 0 + tableau associatif)
32 }
33 catch(PDOException $e)
34 {
35 die("Impossible de se connecter à la base de données.\n" . $e->getMessage());
36 }
37 }
38
39 // créer son objet depuis Model avec: $db = parent::getInstance();
40 public static function getInstance(): self
41 {
42 if(self::$Instance === null)
43 {
44 self::$Instance = new self;
45 }
46 return self::$Instance;
47 }
48}
diff --git a/old/model version 0.1/DevisFactures.php b/old/model version 0.1/DevisFactures.php
new file mode 100644
index 0000000..06a0a59
--- /dev/null
+++ b/old/model version 0.1/DevisFactures.php
@@ -0,0 +1,215 @@
1<?php
2// src/model/DevisFactures.php
3
4class DevisFactures extends Model
5{
6 //~ public $type = ''; // deux tables séparées devis ou factures
7
8 // lecture des données ou hydratation
9 protected $id; // auto-incrémentée
10 protected $id_presta;
11 protected $taches;
12 protected $machine;
13 protected $OS;
14 protected $donnees;
15 protected $cles_licences;
16 protected $total_main_d_oeuvre;
17 protected $pieces;
18 protected $total_pieces;
19 protected $deplacement;
20 protected $prix_devis;
21 protected $total_HT;
22 protected $delai_livraison;
23 protected $validite_devis;
24 protected $signature_devis;
25
26 public function __construct(string $table)
27 {
28 $this->table = $table; // deux tables séparées devis et factures
29 }
30
31 public function getAllWithWindowFields(): array // différent de Model::getAll() qui retourne get_object_vars($this)
32 {
33 $taches = ["Tâches:" => $this->taches];
34 $champs_communs = [
35 "Total Main d'oeuvre:" => $this->total_main_d_oeuvre,
36 "Pièces:" => $this->pieces,
37 "Total des pièces:" => $this->total_pieces,
38 "Déplacement:" => $this->deplacement,
39 "Total HT:" => $this->total_HT];
40
41 if($this->table === 'factures')
42 {
43 $champs_facture = [
44 "PC:" => $this->machine,
45 "OS:" => $this->OS,
46 "Données:" => $this->donnees,
47 "Clés de licences:" => $this->cles_licences];
48
49 return $taches + $champs_facture + $champs_communs;
50 }
51 elseif($this->table === 'devis')
52 {
53 $champs_devis = [
54 "Delai de livraison:" => $this->delai_livraison,
55 "Durée de validité:" => $this->validite_devis,
56 "Devis signé:" => $this->signature_devis];
57
58 return $champs_communs + $champs_devis;
59 }
60 else
61 {
62 return [];
63 }
64 }
65
66 public function set(string $entry, string $input) // trouve la bonne méthode
67 {
68 $input = $this->cleanSpecialChars($input); // possibilité que $input devienne une chaine vide
69 switch($entry)
70 {
71 case "Tâches:":
72 $this->setTaches($input);
73 break;
74 case "PC:":
75 $this->setMachine($input);
76 break;
77 case "OS:":
78 $this->setOS($input);
79 break;
80 case "Données:":
81 $this->setDonnees($input);
82 break;
83 case "Clés de licences:":
84 $this->setClesLicences($input);
85 break;
86 case "Total Main d'oeuvre:":
87 $this->setTotalMainDOeuvre($input);
88 break;
89 case "Pièces:":
90 $this->setPieces($input);
91 break;
92 case "Total des pièces:":
93 $this->setTotalPieces($input);
94 break;
95 case "Déplacement:":
96 $this->setDeplacement($input);
97 break;
98 case "Prix du devis:":
99 $this->setPrixDevis($input);
100 break;
101 case "Total HT:":
102 $this->setTotalHT($input);
103 break;
104 case "Delai de livraison:":
105 $this->setDelaiLivraison($input);
106 break;
107 case "Durée de validité:":
108 $this->setValiditedevis($input);
109 break;
110 case "Devis signé:":
111 $this->setSignatureDevis($input);
112 break;
113 }
114 }
115
116 // setters
117 //~ public function setId(int $value = 0)
118 //~ {
119 //~ $this->id = $value;
120 //~ return($this);
121 //~ }
122 public function setIdPresta(int $value)
123 {
124 $this->id_presta = $value;
125 return($this);
126 }
127 public function setTaches(string $value)
128 {
129 $this->taches = $value;
130 return($this);
131 }
132 public function setMachine(string $value)
133 {
134 $this->machine = $value;
135 return($this);
136 }
137 public function setOS(string $value)
138 {
139 $this->OS = $value;
140 return($this);
141 }
142 public function setDonnees(string $value)
143 {
144 $this->donnees = $value;
145 return($this);
146 }
147 public function setClesLicences(string $value)
148 {
149 $this->cles_licences = $value;
150 return($this);
151 }
152 public function setTotalMainDOeuvre($value)
153 {
154 $value = str_replace(',', '.', $value);
155 $this->total_main_d_oeuvre = (float) $value; // float "nettoie" tous les caractères après le dernier chiffre trouvé (ex: 50€ => 50, abc => 0)
156 return($this);
157 }
158 public function setPieces(string $value)
159 {
160 $this->pieces = $value;
161 return($this);
162 }
163 public function setTotalPieces($value)
164 {
165 $value = str_replace(',', '.', $value);
166 $this->total_pieces = (float) $value;
167 return($this);
168 }
169 public function setDeplacement($value)
170 {
171 $value = str_replace(',', '.', $value);
172 $this->deplacement = (float) $value;
173 return($this);
174 }
175 public function setTotalHT($value)
176 {
177 $value = str_replace(',', '.', $value);
178 $this->total_HT = (float) $value;
179 return($this);
180 }
181 public function setPrixDevis($value)
182 {
183 $value = str_replace(',', '.', $value);
184 $this->prix_devis = (float) $value;
185 return($this);
186 }
187 public function setDelaiLivraison(string $value)
188 {
189 $this->delai_livraison = $value;
190 return($this);
191 }
192 public function setValiditedevis(string $value)
193 {
194 $this->validite_devis = $value;
195 return($this);
196 }
197 public function setSignatureDevis(string $value)
198 {
199 $this->signature_devis = $value;
200 return($this);
201 }
202
203 // création d'une facture à partir d'un devis
204 public function hydrateReceiptWithQuotation($ReceiptDetails)
205 {
206 $ReceiptDetails->hydrate([
207 'taches' => $this->taches,
208 'total_main_d_oeuvre' => $this->total_main_d_oeuvre,
209 'pieces' => $this->pieces,
210 'total_pieces' => $this->total_pieces,
211 'deplacement' => $this->deplacement,
212 'total_HT' => $this->total_HT
213 ]);
214 }
215}
diff --git a/old/model version 0.1/Locations.php b/old/model version 0.1/Locations.php
new file mode 100644
index 0000000..c6b8deb
--- /dev/null
+++ b/old/model version 0.1/Locations.php
@@ -0,0 +1,127 @@
1<?php
2// src/model/Locations.php
3
4class Locations extends Model
5{
6 // lecture des données ou hydratation
7 protected $id;
8 protected $id_presta;
9 protected $designation;
10 protected $modele_description;
11 protected $valeur;
12 protected $etat_des_lieux_debut;
13 protected $etat_des_lieux_fin;
14 protected $duree_location;
15 protected $loyer_mensuel;
16 protected $loyers_payes;
17 protected $caution;
18
19 public function __construct()
20 {
21 $this->table = strtolower(__CLASS__); // locations
22 }
23
24 public function getAllWithWindowFields(): array // différent de Model::getAll() qui retourne get_object_vars($this)
25 {
26 return [
27 "Désignation:" => $this->designation,
28 "Description du modèle:" => $this->modele_description,
29 "Valeur:" => $this->valeur,
30 "État des lieux de début:" => $this->etat_des_lieux_debut,
31 "État des lieux de fin:" => $this->etat_des_lieux_fin,
32 "Durée de la location:" => $this->duree_location,
33 "Loyer Mensuel:" => $this->loyer_mensuel,
34 "Loyers Payés:" => $this->loyers_payes,
35 "Caution:" => $this->caution];
36 }
37 public function set(string $entry, string $input)
38 {
39 $input = $this->cleanSpecialChars($input); // possibilité que $input devienne une chaine vide
40 switch($entry)
41 {
42 case "Désignation:":
43 $this->setDesignation($input);
44 break;
45 case "Description du modèle:":
46 $this->setModeleDescription($input);
47 break;
48 case "Valeur:":
49 $this->setValeur($input);
50 break;
51 case "État des lieux de début:":
52 $this->setEtatDesLieuxDebut($input);
53 break;
54 case "État des lieux de fin:":
55 $this->setEtatDesLieuxFin($input);
56 break;
57 case "Durée de la location:":
58 $this->setDureeLocation($input);
59 break;
60 case "Loyer Mensuel:":
61 $this->setLoyerMensuel($input);
62 break;
63 case "Loyers Payés:":
64 $this->setLoyersPayes($input);
65 break;
66 case "Caution:":
67 $this->setCaution($input);
68 break;
69 }
70 }
71
72 // setters
73 public function setIdPresta(int $value)
74 {
75 $this->id_presta = $value;
76 return($this);
77 }
78 public function setDesignation(string $value)
79 {
80 $this->designation = $value;
81 return($this);
82 }
83 public function setModeleDescription(string $value)
84 {
85 $this->modele_description = $value;
86 return($this);
87 }
88 public function setValeur($value)
89 {
90 $value = str_replace(',', '.', $value);
91 $this->valeur = (float) $value;
92 return($this);
93 }
94 public function setEtatDesLieuxDebut(string $value)
95 {
96 $this->etat_des_lieux_debut = $value;
97 return($this);
98 }
99 public function setEtatDesLieuxFin(string $value)
100 {
101 $this->etat_des_lieux_fin = $value;
102 return($this);
103 }
104 public function setDureeLocation(string $value)
105 {
106 $this->duree_location = $value;
107 return($this);
108 }
109 public function setLoyerMensuel($value)
110 {
111 $value = str_replace(',', '.', $value);
112 $this->loyer_mensuel = (float) $value;
113 return($this);
114 }
115 public function setLoyersPayes($value)
116 {
117 $value = str_replace(',', '.', $value);
118 $this->loyers_payes = (float) $value;
119 return($this);
120 }
121 public function setCaution($value)
122 {
123 $value = str_replace(',', '.', $value);
124 $this->caution = (float) $value;
125 return($this);
126 }
127}
diff --git a/old/model version 0.1/Model.php b/old/model version 0.1/Model.php
new file mode 100644
index 0000000..b3d157d
--- /dev/null
+++ b/old/model version 0.1/Model.php
@@ -0,0 +1,313 @@
1<?php
2// src/model/Model.php
3
4abstract 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}
diff --git a/old/model version 0.1/Prestations.php b/old/model version 0.1/Prestations.php
new file mode 100644
index 0000000..18bc787
--- /dev/null
+++ b/old/model version 0.1/Prestations.php
@@ -0,0 +1,159 @@
1<?php
2// src/model/Prestations.php
3
4class Prestations extends Model
5{
6 // lecture des données ou hydratation
7 protected $id; // auto-incrémentée
8 protected $id_client = 0;
9 protected $code_presta = '';
10 protected $date = 0; // timestamp unix
11 protected $type_presta = '';
12 protected $mode_paiement = '';
13 protected $commentaires = '';
14 //protected $numero_presta = 0;
15
16 public function __construct(int $id_client)
17 { $this->id_client = $id_client;
18 $this->table = strtolower(__CLASS__); // prestations
19 }
20
21 // getters
22 public function getId(): int
23 {
24 return $this->id;
25 }
26 public function getIdClient(): int
27 {
28 return $this->id_client;
29 }
30 public function getIdsByIdClient() // obtenir une entrée avec son id_client, comportement différent si le type est connu
31 {
32 $sql = 'SELECT id FROM ' . $this->table . ' WHERE id_client = ' . $this->id_client;
33 if($this->type_presta != '')
34 {
35 $sql .= " AND type_presta = '" . $this->type_presta . "'";
36 }
37 $data = $this->execQuery($sql)->fetchAll(); // tableau de tableaux
38
39 $IDs = []; // si $IDs reste vide, ne pas être de type NULL
40 for($i = 0; $i < count($data); $i++)
41 {
42 $IDs[$i] = $data[$i]['id']; // tableau simple
43 }
44 return($IDs);
45 }
46 public function getCodePresta(): string
47 {
48 return $this->code_presta;
49 }
50 public function getDate(): int // timestamp unix
51 {
52 return $this->date;
53 }
54 public function getTypePresta(): string
55 {
56 return $this->type_presta;
57 }
58 public function getAllWithWindowFields(): array // différent de Model::getAll() qui retourne get_object_vars($this)
59 {
60 $code_presta_tableau = explode('-', $this->code_presta);
61 $Date = new Dates($this->date);
62
63 return [
64 "Numéro prestation:" => end($code_presta_tableau), // dernière case
65 "Date:" => $Date->getDate(),
66 //"Type de Presta:" => $this->type_presta, // choix impossible pour le moment
67 "Mode de paiement:" => $this->mode_paiement, // non pertinent pour un devis
68 "Commentaires:" => $this->commentaires];
69 }
70 public function set(string $entry, string $input)
71 {
72 $input = $this->cleanSpecialChars($input); // possibilité que $input devienne une chaine vide
73 switch($entry)
74 {
75 case "Numéro prestation:":
76 $this->setNumeroPresta($input);
77 break;
78 //~ case "Date:": // inutile, setDate() est appelé directement après choix fenêtre calendrier
79 //~ $this->setDate($input);
80 //~ break;
81 //~ case "Type de Presta:": // choix impossible pour le moment
82 //~ $this->setTypePresta($input);
83 //~ break;
84 case "Mode de paiement:":
85 $this->setModePaiement($input);
86 break;
87 case "Commentaires:":
88 $this->setCommentaires($input);
89 break;
90 }
91 }
92
93 // setters
94 public function setIdClient(int $value)
95 {
96 $this->id_client = $value;
97 return $this;
98 }
99 //~ public function setCombientiemeFois(int $value)
100 //~ {
101 //~ $this->combientieme_fois = $value;
102 //~ return($this);
103 //~ }
104 public function setCodePresta(string $value)
105 {
106 $this->code_presta = $value;
107 return $this;
108 }
109 public function setDate($value, bool $set_code_presta = false) // attend un timestamp
110 {
111 $this->date = (int) $value;
112
113 if($set_code_presta)
114 {
115 $code_presta_tableau = explode('-', $this->code_presta);
116 $Date = new Dates($value);
117 $code_presta_tableau[0] = $Date->getYear();
118 $code_presta_tableau[1] = $Date->getMonth();
119 $code_presta_tableau[2] = $Date->getDay();
120 $this->code_presta = implode('-', $code_presta_tableau);
121 }
122
123 return $this;
124 }
125 public function setTypePresta(string $value)
126 {
127 $this->type_presta = $value;
128 return $this;
129 }
130 public function setModePaiement(string $value)
131 {
132 $this->mode_paiement = $value;
133 return $this;
134 }
135 public function setCommentaires(string $value)
136 {
137 $this->commentaires = $this->cleanSpecialChars($value); // nettoyage ici parce que pas possible ailleurs
138 return $this;
139 }
140 public function setNumeroPresta($value)
141 {
142 // modifier le code presta, on pourrait aussi utiliser une regex
143 $code_presta_tableau = explode('-', $this->code_presta);
144 $code_presta_tableau[count($code_presta_tableau) - 1] = (int) $value;
145 $this->code_presta = implode('-', $code_presta_tableau);
146 return $this;
147 }
148
149 // code presta = année-mois-jour-codeclient-typedepresta-combientièmefois
150 public function makeCodePresta(Dates $Date, string $code_client)
151 {
152 // on récupère un tableau contenant toutes les prestations d'un client tous types confondus (devis, facture, cesu, location, enregistrement sans vente)
153 // inconvénient: il peut y avoir plusieurs prestations avec le même numéro au compteur, à améliorer
154 $combientieme_fois = count($this->find(['id_client' => $this->id_client])) + 1;
155
156 $array_code = [$Date->getYear(), $Date->getMonth(), $Date->getDay(), $code_client, $this->type_presta, $combientieme_fois];
157 $this->code_presta = implode('-', $array_code);
158 }
159}
diff --git a/old/model version 0.1/StructTablesDB.php b/old/model version 0.1/StructTablesDB.php
new file mode 100644
index 0000000..303af46
--- /dev/null
+++ b/old/model version 0.1/StructTablesDB.php
@@ -0,0 +1,36 @@
1<?php
2// src/model/StructTablesDB.php
3
4// structure de données façon C
5// créer les requêtes avec implode(', ', $DbStructure)
6class StructTablesDB
7{
8 // possibilité de lire un fichier JSON
9 static public $structureOfTables = [
10 // la table prestations est liée à la table clients
11 // les tables devis_factures, cesu et locations sont liées à la table prestations
12 'clients' => ['id' => 'INTEGER', 'prenom_nom' => 'TEXT', 'code_client' => 'TEXT', 'adresse' => 'TEXT', 'code_postal' => 'TEXT', 'ville' => 'TEXT', 'telephone' => 'TEXT', 'courriel' => 'TEXT', 'apropos' => 'TEXT', 'type' => 'TEXT DEFAULT prospect'],
13 'prestations' => ['id' => 'INTEGER', 'id_client' => 'INTEGER', 'code_presta' => 'TEXT', 'date' => 'INTEGER', 'type_presta' => 'TEXT', 'mode_paiement' => 'TEXT', 'commentaires' => 'TEXT'],
14 'devis' => ['id' => 'INTEGER', 'id_presta' => 'INTEGER', 'taches' => 'TEXT', 'total_main_d_oeuvre' => 'REAL', 'pieces' => 'TEXT', 'total_pieces' => 'REAL', 'deplacement' => 'REAL', 'prix_devis' => 'REAL', 'total_HT' => 'REAL', 'delai_livraison' => 'TEXT', 'validite_devis' => 'TEXT', 'signature_devis' => 'TEXT DEFAULT non'],
15 'factures' => ['id' => 'INTEGER', 'id_presta' => 'INTEGER', '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'],
16 'cesu' => ['id' => 'INTEGER', 'id_presta' => 'INTEGER', 'taches' => 'TEXT', 'duree_travail' => 'TEXT', 'salaire' => 'REAL'],
17 'locations' => ['id' => 'INTEGER', 'id_presta' => 'INTEGER', 'designation' => 'TEXT', 'modele_description' => 'TEXT', 'valeur' => 'REAL', 'etat_des_lieux_debut' => 'TEXT', 'etat_des_lieux_fin' => 'TEXT', 'duree_location' => 'TEXT', 'loyer_mensuel' => 'REAL', 'loyers_payes' => 'INTEGER', 'caution' => 'INTEGER']
18 ];
19
20 // les types de variables de sqlite sont peu nombreux et autorisent un typage automatique
21 // le "type indiqué" est indiqué dans l'instruction CREATE TABLE
22 // https://www.leppf.com/site/spip.php?article89
23
24 // || type indiqué || type choisi automatiquement || autre types possibles ||
25 // ---------------------------------------------------------------------------
26 // || TEXT || TEXT || BLOB, NULL ||
27 // || INTEGER || INTEGER (de 1 à 8 octets) || REAL, TEXT, BLOB, NULL ||
28 // || REAL || REAL (flottant sur 9 octets) || TEXT, BLOB, NULL ||
29 // || NUMERIC || INTEGER ou REAL || TEXT, BLOB, NULL ||
30 // || NONE || indéfini || dépend des données ||
31
32 // du code SQL écrit pour d'autres SGBD devrait fonctionner,
33 // sqlite fera des conversions dans ses propres types avec les problèmes qu'on peut imaginer
34
35 // pour les dates, on stockera à priori le timestamp
36}