Paaxio 1.0
Plateforme de streaming musical - SAE IUT Bayonne
Chargement...
Recherche...
Aucune correspondance
chanson.dao.php
Aller à la documentation de ce fichier.
1<?php
2
9{
13 private ?PDO $pdo;
14
19 public function __construct(?PDO $pdo = null)
20 {
21 $this->pdo = $pdo;
22 }
23
28 public function findAll(): array
29 {
30 $sql = "SELECT * FROM chanson";
31 $pdoStatement = $this->pdo->prepare($sql);
32 $pdoStatement->execute();
33 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
34 $tableau = $pdoStatement->fetchAll();
35 $chanson = $this->hydrateMany($tableau);
36 return $chanson;
37 }
38
39 public function findId(int $id): Chanson
40 {
41 $sql = "SELECT * FROM chanson WHERE idChanson = :id";
42 $pdoStatement = $this->pdo->prepare($sql);
43 $pdoStatement->execute(array(
44 ':id' => $id
45 ));
46
47 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
48 $tableau = $pdoStatement->fetch();
49 $chanson = $this->hydrate($tableau);
50 return $chanson;
51 }
52
53 public function findTrending(int $limit = 8, int $daysAgo = 7): array
54 {
55 $sql = "SELECT
56 c.*,
57 u.pseudoUtilisateur AS artistePseudoUtilisateur,
58 -- Métriques récentes (période paramétrable)
59 COUNT(DISTINCT lc.emailUtilisateur) AS nouveaux_likes,
60 COUNT(DISTINCT cp.idPlaylist) AS nouvelles_playlists,
61 -- SCORE DE TENDANCE : 1 Like = 2 pts, 1 Playlist = 3 pts
62 (COUNT(DISTINCT lc.emailUtilisateur) * 2) +
63 (COUNT(DISTINCT cp.idPlaylist) * 3) AS score_tendance
64 FROM chanson c
65 JOIN utilisateur u ON c.emailPublicateur = u.emailUtilisateur
66 LEFT JOIN likeChanson lc
67 ON c.idChanson = lc.idChanson
68 AND lc.dateLike >= DATE_SUB(NOW(), INTERVAL :daysAgo DAY)
69 LEFT JOIN chansonPlaylist cp
70 ON c.idChanson = cp.idChanson
71 AND cp.dateAjoutChanson >= DATE_SUB(NOW(), INTERVAL :daysAgo DAY)
72 GROUP BY c.idChanson, u.pseudoUtilisateur
73 HAVING score_tendance > 0
74 ORDER BY score_tendance DESC
75 LIMIT :limit;
76 ";
77
78 if ($limit < 1) {
79 $limit = 8;
80 }
81
82 $stmt = $this->pdo->prepare($sql);
83 $stmt->bindValue(':daysAgo', $daysAgo, PDO::PARAM_INT);
84 $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
85 $stmt->execute();
86 $chansons = $stmt->fetchAll(PDO::FETCH_ASSOC);
87 $stmt->closeCursor();
88 if ($chansons) {
89 return $this->hydrateMany($chansons);
90 }
91 return [];
92 }
93
94 public function findAllFromUser(?string $email = null): array
95 {
96 if ($email) {
97 $sql = "SELECT * FROM chanson WHERE emailPublicateur = :email";
98 $stmt = $this->pdo->prepare($sql);
99 $stmt->execute([':email' => $email]);
100 $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
101 return $this->hydrateMany($results);
102 } else {
103 return [];
104 }
105 }
106
107 public function hydrate(array $tableaAssoc): chanson
108 {
109 $chanson = new chanson();
110 $chanson->setIdchanson(isset($tableaAssoc['idChanson']) ? (int)$tableaAssoc['idChanson'] : null);
111 $chanson->setTitrechanson($tableaAssoc['titreChanson'] ?? null);
112 $chanson->setDureechanson(isset($tableaAssoc['dureeChanson']) ? (int)$tableaAssoc['dureeChanson'] : null);
113
114 // Conversion sécurisée des dates SQL → objets DateTime
115 $chanson->setDateTeleversementChanson(
116 !empty($tableaAssoc['dateTeleversementChanson']) ? new DateTime($tableaAssoc['dateTeleversementChanson']) : null
117 );
118 $chanson->setNbecoutechanson(isset($tableaAssoc['nbEcouteChanson']) ? (int)$tableaAssoc['nbEcouteChanson'] : null);
119 $chanson->seturlAudioChanson($tableaAssoc['urlAudioChanson'] ?? null);
120
121 // Album : création d’un objet minimal
122 if (!empty($tableaAssoc['albumChanson'])) {
123 $albumDAO = new AlbumDAO($this->pdo);
124 $album = $albumDAO->find((int)$tableaAssoc['albumChanson']);
125
126 if ($album) {
127 $chanson->setAlbumChanson($album);
128 } else {
129 $chanson->setAlbumChanson(null);
130 }
131 }
132
133 // Genre : création d’un objet minimal
134 if (!empty($tableaAssoc['genreChanson'])) {
135 $genre = new GenreDAO($this->pdo);
136 $genre = $genre->find((int)$tableaAssoc['genreChanson']);
137 $chanson->setGenreChanson($genre);
138 } else {
139 $chanson->setGenreChanson(null);
140 }
141
142 $chanson->setEmailPublicateur($tableaAssoc['emailPublicateur'] ?? null);
143
144 return $chanson;
145 }
146
147 public function hydrateMany(array $tableauxAssoc): array
148 {
149 $chansons = [];
150 foreach ($tableauxAssoc as $tableauAssoc) {
151 $chansons[] = $this->hydrate($tableauAssoc);
152 }
153 return $chansons;
154 }
155
156 public function rechercherParTitre(string $titre): array
157 {
158 $sql = "SELECT * FROM chanson
159 WHERE titreChanson LIKE :titre
160 ORDER BY nbEcouteChanson DESC
161 LIMIT 3";
162
163 $pdoStatement = $this->pdo->prepare($sql);
164 $likeTitre = '%' . $titre . '%';
165 $pdoStatement->bindParam(':titre', $likeTitre, PDO::PARAM_STR);
166 $pdoStatement->execute();
167 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
168 $tableau = $pdoStatement->fetchAll();
169 return $this->hydrateMany($tableau);
170 }
171
172 public function rechercherParAlbum(int $idAlbum): array
173 {
174 $sql = "SELECT * FROM chanson WHERE albumChanson = :idAlbum";
175 $pdoStatement = $this->pdo->prepare($sql);
176 $pdoStatement->bindParam(':idAlbum', $idAlbum, PDO::PARAM_INT);
177 $pdoStatement->execute();
178 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
179 $tableau = $pdoStatement->fetchAll();
180 $chansons = $this->hydrateMany($tableau);
181 return $chansons;
182 }
183
184 public function filtrerChanson(?int $idGenre = null, ?int $idAlbum = null, string $colonne = 'titreChanson', string $ordre = 'ASC'): array
185 {
186 // Protection contre l'injection SQL : validation par liste blanche
187 $colonnesValides = ['titreChanson', 'dateTeleversementChanson', 'nbEcouteChanson', 'idChanson', 'dureeChanson'];
188 $ordresValides = ['ASC', 'DESC'];
189
190 $colonne = in_array($colonne, $colonnesValides, true) ? $colonne : 'titreChanson';
191 $ordre = in_array(strtoupper($ordre), $ordresValides, true) ? strtoupper($ordre) : 'ASC';
192
193 $sql = "SELECT * FROM chanson WHERE 1=1";
194
195 if ($idGenre !== null) {
196 $sql .= " AND genreChanson = :idGenre";
197 }
198 if ($idAlbum !== null) {
199 $sql .= " AND albumChanson = :idAlbum";
200 }
201
202 $sql .= " ORDER BY $colonne $ordre";
203
204 $stmt = $this->pdo->prepare($sql);
205
206 if ($idGenre !== null) {
207 $stmt->bindValue(':idGenre', $idGenre, PDO::PARAM_INT);
208 }
209 if ($idAlbum !== null) {
210 $stmt->bindValue(':idAlbum', $idAlbum, PDO::PARAM_INT);
211 }
212
213 $stmt->execute();
214 $tableau = $stmt->fetchAll(PDO::FETCH_ASSOC);
215
216 return $this->hydrateMany($tableau);
217 }
218
219 public function createChanson(Chanson $chanson): bool
220 {
221 $sql = "INSERT INTO chanson (titreChanson, dureeChanson, dateTeleversementChanson, nbEcouteChanson, albumChanson, genreChanson, emailPublicateur, urlAudioChanson)
222 VALUES (:titre, :duree, :dateTeleversement, :nbEcoute, :album, :genre, :emailPublicateur, :urlAudio)";
223
224 $pdoStatement = $this->pdo->prepare($sql);
225
226 $idAlbum = $chanson->getAlbumChanson() ? $chanson->getAlbumChanson()->getIdAlbum() : null;
227 $idGenre = $chanson->getGenreChanson() ? $chanson->getGenreChanson()->getIdGenre() : null;
228 $dateTeleversement = $chanson->getDateTeleversementChanson() ? $chanson->getDateTeleversementChanson()->format('Y-m-d H:i:s') : date('Y-m-d H:i:s');
229
230 return $pdoStatement->execute([
231 ':titre' => $chanson->getTitreChanson(),
232 ':duree' => $chanson->getDureeChanson(),
233 ':dateTeleversement' => $dateTeleversement,
234 ':nbEcoute' => $chanson->getNbEcouteChanson() ?? 0,
235 ':urlAudio' => $chanson->geturlAudioChanson(),
236 ':album' => $idAlbum,
237 ':genre' => $idGenre,
238 ':emailPublicateur' => $chanson->getEmailPublicateur()
239 ]);
240 }
241
242 // public function findByTitreExact(string $titre, int $idAlbum): ?Chanson
243 // {
244 // // Implémentation future si nécessaire pour éviter les doublons
245 // return null;
246 // }
247
248 public function updateChanson(Chanson $chanson): bool
249 {
250 $sql = "UPDATE chanson SET
251 titreChanson = :titre,
252 genreChanson = :idGenre
253 WHERE idChanson = :idChanson";
254
255 $pdoStatement = $this->pdo->prepare($sql);
256
257 $idGenre = $chanson->getGenreChanson() ? $chanson->getGenreChanson()->getIdGenre() : null;
258
259 return $pdoStatement->execute([
260 ':titre' => $chanson->getTitreChanson(),
261 ':idGenre' => $idGenre,
262 ':idChanson' => $chanson->getIdChanson()
263 ]);
264 }
265
271 public function deleteChanson(int $idChanson): bool
272 {
273 $sql = "DELETE FROM chanson WHERE idChanson = :idChanson";
274 $stmt = $this->pdo->prepare($sql);
275 return $stmt->execute([':idChanson' => $idChanson]);
276 }
277
283 public function incrementNbEcoute(int $idChanson): ?int
284 {
285 $sql = "UPDATE chanson SET nbEcouteChanson = COALESCE(nbEcouteChanson, 0) + 1 WHERE idChanson = :idChanson";
286 $stmt = $this->pdo->prepare($sql);
287 $ok = $stmt->execute([':idChanson' => $idChanson]);
288 if (!$ok) {
289 return null;
290 }
291
292 $sql2 = "SELECT nbEcouteChanson FROM chanson WHERE idChanson = :idChanson";
293 $stmt2 = $this->pdo->prepare($sql2);
294 $stmt2->execute([':idChanson' => $idChanson]);
295 $val = $stmt2->fetchColumn();
296 return $val !== false ? (int)$val : null;
297 }
298
302 public function findChansonsLikees(string $email): array
303 {
304 $sql = "
305 SELECT c.*, l.dateLike, l.emailUtilisateur
306 FROM likeChanson l
307 JOIN chanson c ON c.idChanson = l.idChanson
308 WHERE l.emailUtilisateur = :email
309 ORDER BY l.dateLike DESC
310 ";
311
312 $stmt = $this->pdo->prepare($sql);
313 $stmt->execute([':email' => $email]);
314 $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
315
316 $chansons = [];
317 foreach ($results as $row) {
318 $chansons[] = $this->hydrate($row);
319 }
320
321 return $chansons;
322 }
323
327 public function addChansonLikee(string $emailUtilisateur, int $idChanson): bool
328 {
329 $sql = "INSERT INTO likeChanson (emailUtilisateur, idChanson, dateLike)
330 VALUES (:emailUtilisateur, :idChanson, :dateLike)";
331
332 $stmt = $this->pdo->prepare($sql);
333 return $stmt->execute([
334 ':emailUtilisateur' => $emailUtilisateur,
335 ':idChanson' => $idChanson,
336 ':dateLike' => (new DateTime())->format('Y-m-d H:i:s')
337 ]);
338 }
339
343 public function updateChansonLikee(string $emailUtilisateur, int $idChanson): bool
344 {
345 $sql = "UPDATE likeChanson SET dateLike = :dateLike
346 WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
347
348 $stmt = $this->pdo->prepare($sql);
349 return $stmt->execute([
350 ':emailUtilisateur' => $emailUtilisateur,
351 ':idChanson' => $idChanson,
352 ':dateLike' => (new DateTime())->format('Y-m-d H:i:s')
353 ]);
354 }
355
359 public function toggleLike(string $emailUtilisateur, int $idChanson): bool
360 {
361 // Vérifie si la chanson est déjà likée
362 $sql = "SELECT COUNT(*) FROM likeChanson WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
363 $stmt = $this->pdo->prepare($sql);
364 $stmt->execute([
365 ':emailUtilisateur' => $emailUtilisateur,
366 ':idChanson' => $idChanson
367 ]);
368 $isLiked = $stmt->fetchColumn() > 0;
369
370 if ($isLiked) {
371 // Supprime le like
372 $sql = "DELETE FROM likeChanson WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
373 $stmt = $this->pdo->prepare($sql);
374 return $stmt->execute([
375 ':emailUtilisateur' => $emailUtilisateur,
376 ':idChanson' => $idChanson
377 ]);
378 } else {
379 // Ajoute le like
380 return $this->addChansonLikee($emailUtilisateur, $idChanson);
381 }
382 }
383
387 public function getPdo(): ?PDO
388 {
389 return $this->pdo;
390 }
391
396 public function setPdo($pdo): void
397 {
398 $this->pdo = $pdo;
399 }
400
406 public function getTotalEcoutesByArtiste(string $emailArtiste): int
407 {
408 $sql = "SELECT COALESCE(SUM(nbEcouteChanson), 0) as total
409 FROM chanson
410 WHERE emailPublicateur = :email";
411 $stmt = $this->pdo->prepare($sql);
412 $stmt->execute([':email' => $emailArtiste]);
413 return (int)$stmt->fetchColumn();
414 }
415}
rechercherParTitre(string $titre)
updateChanson(Chanson $chanson)
findAllFromUser(?string $email=null)
hydrateMany(array $tableauxAssoc)
createChanson(Chanson $chanson)
getPdo()
Get the value of pdo.
rechercherParAlbum(int $idAlbum)
findChansonsLikees(string $email)
Récupère les chansons likées par un utilisateur.
getTotalEcoutesByArtiste(string $emailArtiste)
Calcule le nombre total d'écoutes pour toutes les chansons d'un artiste.
deleteChanson(int $idChanson)
Supprime une chanson en base de données par son ID.
updateChansonLikee(string $emailUtilisateur, int $idChanson)
Met à jour un like (change la date)
findTrending(int $limit=8, int $daysAgo=7)
findId(int $id)
incrementNbEcoute(int $idChanson)
Incrémente le compteur d'écoutes d'une chanson de 1 et retourne la nouvelle valeur.
addChansonLikee(string $emailUtilisateur, int $idChanson)
Ajoute un like pour une chanson (user + chanson)
hydrate(array $tableaAssoc)
setPdo($pdo)
Set the value of pdo.
toggleLike(string $emailUtilisateur, int $idChanson)
Bascule le like d'une chanson (ajoute ou supprime)
findAll()
Récupère toutes les chansons de la base de données.
__construct(?PDO $pdo=null)
Constructeur de la classe ChansonDAO.
filtrerChanson(?int $idGenre=null, ?int $idAlbum=null, string $colonne='titreChanson', string $ordre='ASC')
getIdChanson()
Get the value of idChanson.
getGenreChanson()
Get the value of genreChanson.
getAlbumChanson()
Get the value of albumChanson.
getNbEcouteChanson()
Get the value of nbEcouteChanson.
getDateTeleversementChanson()
Get the value of dateTeleversementChanson.
getDureeChanson()
Get the value of dureeChanson.
getTitreChanson()
Get the value of titreChanson.
getEmailPublicateur()
Get the value of emailPublicateur.