// // Copyright (c) Equipe 1 - BOBIN, MASI, NODON, VETU. All rights reserved. // namespace Webzine.WebApplication.Controllers { using Microsoft.AspNetCore.Mvc; using Webzine.Entity; using Webzine.Repository.Contracts; using Webzine.WebApplication.ViewModels.Titre; /// /// Controleur responsable de la gestion des titres musicaux : /// affichage des details, filtrage par style, /// ajout de likes, commentaires et recherche. /// public class TitreController : Controller { private readonly ILogger logger; private readonly ITitreRepository titreRepository; /// /// Initializes a new instance of the class. /// Initialise une nouvelle instance de la classe . /// /// Service de journalisation injecte. /// Repository des titres injecte. public TitreController(ILogger logger, ITitreRepository titreRepository) { this.logger = logger; this.titreRepository = titreRepository; this.logger.LogInformation("Initialisation du controleur TitreController."); } /// /// Affiche le detail d'un titre specifique. /// /// Identifiant du titre. /// Model de donnée pour un commentaire. /// Vue des details ou 404 si introuvable. public IActionResult Index(int id) { this.logger.LogInformation("Demande d'affichage du detail pour le titre ID {Id}.", id); var titre = this.titreRepository.Find(id); if (titre == null) { this.logger.LogWarning("Titre avec ID {Id} introuvable.", id); return this.RedirectToAction("Index", "Accueil"); } this.titreRepository.IncrementNbLectures(titre); return this.View(this.BuildTitreDetailViewModel(titre)); } /// /// Affiche les titres correspondant a un style musical donne. /// /// Nom du style musical. /// Vue contenant la liste filtree. public IActionResult Style(string style) { this.logger.LogInformation("Recherche des titres pour le style : {Style}.", style); var titresFiltres = this.titreRepository.SearchByStyle(style).ToList(); var vm = new TitreStyle { StyleName = style, Titres = titresFiltres.Select(MapTitreItem).ToList(), }; return this.View(vm); } /// /// Ajoute un like a un titre. /// /// Identifiant du titre a liker. /// Redirection vers la page detail. [HttpPost] public IActionResult Like(int id) { var titre = this.titreRepository.Find(id); if (titre != null) { this.titreRepository.IncrementNbLikes(titre); } return this.RedirectToAction("Index", new { id }); } /// /// Ajoute un commentaire a un titre. /// /// Donnees du commentaire. /// Redirection vers la page detail. [HttpPost] public IActionResult Comment([Bind(Prefix = "CommentForm")] TitreComment model) { if (!this.ModelState.IsValid) { var titre = this.titreRepository.Find(model.IdTitre); if (titre == null) { this.logger.LogWarning("Titre avec ID {Id} introuvable pour ajout de commentaire.", model.IdTitre); return this.RedirectToAction("Index", "Accueil"); } return this.View("Index", this.BuildTitreDetailViewModel(titre, model)); } var titreToUpdate = this.titreRepository.Find(model.IdTitre); if (titreToUpdate != null) { var commentaire = new Commentaire { Auteur = model.Auteur, Contenu = model.Contenu, DateCreation = DateTime.Now, IdTitre = model.IdTitre, }; titreToUpdate.Commentaires.Add(commentaire); this.titreRepository.Update(titreToUpdate); } return this.RedirectToAction("Index", new { id = model.IdTitre }); } private TitreDetail BuildTitreDetailViewModel(Titre titre, TitreComment? commentForm = null) { return new TitreDetail { Details = new TitreContent { IdTitre = titre.IdTitre, Libelle = titre.Libelle, Chronique = titre.Chronique, DateSortie = titre.DateSortie, NbLikes = titre.NbLikes, UrlJaquette = titre.UrlJaquette, UrlEcoute = titre.UrlEcoute, UrlEmbedEcoute = BuildSpotifyEmbedUrl(titre.UrlEcoute), ArtisteNom = titre.Artiste.Nom, Styles = titre.Styles, Commentaires = titre.Commentaires, }, CommentForm = commentForm ?? new TitreComment { IdTitre = titre.IdTitre, }, }; } /// /// Mappe une entite Titre vers un item de la liste de titres pour l'affichage dans la vue de style. /// /// Le titre à mapper. /// L'item de la liste de titres. private static TitreStyleItem MapTitreItem(Titre titre) { return new TitreStyleItem { IdTitre = titre.IdTitre, Libelle = titre.Libelle, ArtisteNom = titre.Artiste?.Nom, UrlJaquette = titre.UrlJaquette, Duree = titre.Duree, }; } /// /// Construit une URL d'intégration Spotify à partir de l'URL d'écoute d'un titre. /// /// L'URL d'écoute du titre. /// L'URL d'intégration Spotify ou null si l'URL n'est pas valide. private static string? BuildSpotifyEmbedUrl(string? urlEcoute) { if (string.IsNullOrWhiteSpace(urlEcoute)) { return null; } var trackId = urlEcoute.Split('/').LastOrDefault(); return string.IsNullOrWhiteSpace(trackId) ? null : $"https://open.spotify.com/embed/track/{trackId}"; } } }