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 //albumChanson et genreChanson sont des objets, il faut les récupérer via leur DAO respectif
122 // Album : création d’un objet minimal
123 if (!empty($tableaAssoc['albumChanson'])) {
124 $albumDAO = new AlbumDAO($this->pdo);
125 $album = $albumDAO->find((int)$tableaAssoc['albumChanson']);
126 $chanson->setAlbumChanson($album);
127 } else {
128 $chanson->setAlbumChanson(null);
129 }
130
131 // Genre : création d’un objet minimal
132 if (!empty($tableaAssoc['genreChanson'])) {
133 $genre = new GenreDAO($this->pdo);
134 $genre = $genre->find((int)$tableaAssoc['genreChanson']);
135 $chanson->setGenreChanson($genre);
136 } else {
137 $chanson->setGenreChanson(null);
138 }
139
140 $chanson->setEmailPublicateur($tableaAssoc['emailPublicateur'] ?? null);
141
142 return $chanson;
143 }
144
145 public function hydrateMany(array $tableauxAssoc): array
146 {
147 $chansons = [];
148 foreach ($tableauxAssoc as $tableauAssoc) {
149 $chansons[] = $this->hydrate($tableauAssoc);
150 }
151 return $chansons;
152 }
153
154 public function rechercherParTitre(string $titre): array
155 {
156 $sql = "SELECT * FROM chanson WHERE titreChanson LIKE :titre";
157 $pdoStatement = $this->pdo->prepare($sql);
158 $likeTitre = '%' . $titre . '%';
159 $pdoStatement->bindParam(':titre', $likeTitre, PDO::PARAM_STR);
160 $pdoStatement->execute();
161 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
162 $tableau = $pdoStatement->fetchAll();
163 $chansons = $this->hydrateMany($tableau);
164 return $chansons;
165 }
166
167 public function rechercherParAlbum(int $idAlbum): array
168 {
169 $sql = "SELECT * FROM chanson WHERE albumChanson = :idAlbum";
170 $pdoStatement = $this->pdo->prepare($sql);
171 $pdoStatement->bindParam(':idAlbum', $idAlbum, PDO::PARAM_INT);
172 $pdoStatement->execute();
173 $pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
174 $tableau = $pdoStatement->fetchAll();
175 $chansons = $this->hydrateMany($tableau);
176 return $chansons;
177 }
178
179 public function filtrerChanson(?int $idGenre = null, ?int $idAlbum = null, string $colonne = 'titreChanson', string $ordre = 'ASC'): array
180 {
181 // Protection contre l'injection SQL : validation par liste blanche
182 $colonnesValides = ['titreChanson', 'dateTeleversementChanson', 'nbEcouteChanson', 'idChanson', 'dureeChanson'];
183 $ordresValides = ['ASC', 'DESC'];
184
185 $colonne = in_array($colonne, $colonnesValides, true) ? $colonne : 'titreChanson';
186 $ordre = in_array(strtoupper($ordre), $ordresValides, true) ? strtoupper($ordre) : 'ASC';
187
188 $sql = "SELECT * FROM chanson WHERE 1=1";
189
190 if ($idGenre !== null) {
191 $sql .= " AND genreChanson = :idGenre";
192 }
193 if ($idAlbum !== null) {
194 $sql .= " AND albumChanson = :idAlbum";
195 }
196
197 $sql .= " ORDER BY $colonne $ordre";
198
199 $stmt = $this->pdo->prepare($sql);
200
201 if ($idGenre !== null) {
202 $stmt->bindValue(':idGenre', $idGenre, PDO::PARAM_INT);
203 }
204 if ($idAlbum !== null) {
205 $stmt->bindValue(':idAlbum', $idAlbum, PDO::PARAM_INT);
206 }
207
208 $stmt->execute();
209 $tableau = $stmt->fetchAll(PDO::FETCH_ASSOC);
210
211 return $this->hydrateMany($tableau);
212 }
213
214 public function createChanson(Chanson $chanson): bool
215 {
216 $sql = "INSERT INTO chanson (titreChanson, dureeChanson, dateTeleversementChanson, nbEcouteChanson, albumChanson, genreChanson, emailPublicateur, urlAudioChanson)
217 VALUES (:titre, :duree, :dateTeleversement, :nbEcoute, :album, :genre, :emailPublicateur, :urlAudio)";
218
219 $pdoStatement = $this->pdo->prepare($sql);
220
221 $idAlbum = $chanson->getAlbumChanson() ? $chanson->getAlbumChanson()->getIdAlbum() : null;
222 $idGenre = $chanson->getGenreChanson() ? $chanson->getGenreChanson()->getIdGenre() : null;
223 $dateTeleversement = $chanson->getDateTeleversementChanson() ? $chanson->getDateTeleversementChanson()->format('Y-m-d H:i:s') : date('Y-m-d H:i:s');
224
225 return $pdoStatement->execute([
226 ':titre' => $chanson->getTitreChanson(),
227 ':duree' => $chanson->getDureeChanson(),
228 ':dateTeleversement' => $dateTeleversement,
229 ':nbEcoute' => $chanson->getNbEcouteChanson() ?? 0,
230 ':urlAudio' => $chanson->geturlAudioChanson(),
231 ':album' => $idAlbum,
232 ':genre' => $idGenre,
233 ':emailPublicateur' => $chanson->getEmailPublicateur()
234 ]);
235 }
236
237 public function findByTitreExact(string $titre, int $idAlbum): ?Chanson
238 {
239 // Implémentation future si nécessaire pour éviter les doublons
240 return null;
241 }
242
243 public function updateChanson(Chanson $chanson): bool
244 {
245 $sql = "UPDATE chanson SET
246 titreChanson = :titre,
247 genreChanson = :idGenre
248 WHERE idChanson = :idChanson";
249
250 $pdoStatement = $this->pdo->prepare($sql);
251
252 $idGenre = $chanson->getGenreChanson() ? $chanson->getGenreChanson()->getIdGenre() : null;
253
254 return $pdoStatement->execute([
255 ':titre' => $chanson->getTitreChanson(),
256 ':idGenre' => $idGenre,
257 ':idChanson' => $chanson->getIdChanson()
258 ]);
259 }
260
266 public function deleteChanson(int $idChanson): bool
267 {
268 $sql = "DELETE FROM chanson WHERE idChanson = :idChanson";
269 $stmt = $this->pdo->prepare($sql);
270 return $stmt->execute([':idChanson' => $idChanson]);
271 }
272
278 public function incrementNbEcoute(int $idChanson): ?int
279 {
280 $sql = "UPDATE chanson SET nbEcouteChanson = COALESCE(nbEcouteChanson, 0) + 1 WHERE idChanson = :idChanson";
281 $stmt = $this->pdo->prepare($sql);
282 $ok = $stmt->execute([':idChanson' => $idChanson]);
283 if (!$ok) {
284 return null;
285 }
286
287 $sql2 = "SELECT nbEcouteChanson FROM chanson WHERE idChanson = :idChanson";
288 $stmt2 = $this->pdo->prepare($sql2);
289 $stmt2->execute([':idChanson' => $idChanson]);
290 $val = $stmt2->fetchColumn();
291 return $val !== false ? (int)$val : null;
292 }
293
297 public function findChansonsLikees(string $email): array
298 {
299 $sql = "
300 SELECT c.*, l.dateLike, l.emailUtilisateur
301 FROM likeChanson l
302 JOIN chanson c ON c.idChanson = l.idChanson
303 WHERE l.emailUtilisateur = :email
304 ORDER BY l.dateLike DESC
305 ";
306
307 $stmt = $this->pdo->prepare($sql);
308 $stmt->execute([':email' => $email]);
309 $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
310
311 $chansons = [];
312 foreach ($results as $row) {
313 $chansons[] = $this->hydrate($row);
314 }
315
316 return $chansons;
317 }
318
322 public function addChansonLikee(string $emailUtilisateur, int $idChanson): bool
323 {
324 $sql = "INSERT INTO likeChanson (emailUtilisateur, idChanson, dateLike)
325 VALUES (:emailUtilisateur, :idChanson, :dateLike)";
326
327 $stmt = $this->pdo->prepare($sql);
328 return $stmt->execute([
329 ':emailUtilisateur' => $emailUtilisateur,
330 ':idChanson' => $idChanson,
331 ':dateLike' => (new DateTime())->format('Y-m-d H:i:s')
332 ]);
333 }
334
338 public function updateChansonLikee(string $emailUtilisateur, int $idChanson): bool
339 {
340 $sql = "UPDATE likeChanson SET dateLike = :dateLike
341 WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
342
343 $stmt = $this->pdo->prepare($sql);
344 return $stmt->execute([
345 ':emailUtilisateur' => $emailUtilisateur,
346 ':idChanson' => $idChanson,
347 ':dateLike' => (new DateTime())->format('Y-m-d H:i:s')
348 ]);
349 }
350
354 public function toggleLike(string $emailUtilisateur, int $idChanson): bool
355 {
356 // Vérifie si la chanson est déjà likée
357 $sql = "SELECT COUNT(*) FROM likeChanson WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
358 $stmt = $this->pdo->prepare($sql);
359 $stmt->execute([
360 ':emailUtilisateur' => $emailUtilisateur,
361 ':idChanson' => $idChanson
362 ]);
363 $isLiked = $stmt->fetchColumn() > 0;
364
365 if ($isLiked) {
366 // Supprime le like
367 $sql = "DELETE FROM likeChanson WHERE emailUtilisateur = :emailUtilisateur AND idChanson = :idChanson";
368 $stmt = $this->pdo->prepare($sql);
369 return $stmt->execute([
370 ':emailUtilisateur' => $emailUtilisateur,
371 ':idChanson' => $idChanson
372 ]);
373 } else {
374 // Ajoute le like
375 return $this->addChansonLikee($emailUtilisateur, $idChanson);
376 }
377 }
378
382 public function getPdo(): ?PDO
383 {
384 return $this->pdo;
385 }
386
391 public function setPdo($pdo): void
392 {
393 $this->pdo = $pdo;
394 }
395
401 public function getTotalEcoutesByArtiste(string $emailArtiste): int
402 {
403 $sql = "SELECT COALESCE(SUM(nbEcouteChanson), 0) as total
404 FROM chanson
405 WHERE emailPublicateur = :email";
406 $stmt = $this->pdo->prepare($sql);
407 $stmt->execute([':email' => $emailArtiste]);
408 return (int)$stmt->fetchColumn();
409 }
410}
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.
findByTitreExact(string $titre, int $idAlbum)
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.