From 23d46154db445556cf714284323a6c54ef838d3c Mon Sep 17 00:00:00 2001 From: Loic Masi Date: Thu, 26 Mar 2026 12:00:44 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20l'impl=C3=A9mentation=20du=20Repo?= =?UTF-8?q?=20pour=20la=20base=20de=20donn=C3=A9es=20afin=20d'afficher=20l?= =?UTF-8?q?es=20titres=20sur=20la=20page=20d'accueil.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ITtitreRepository.cs | 2 +- Webzine.Repository/ArtisteRepository.cs | 15 +++ Webzine.Repository/LocalEntityRepository.cs | 22 +++- Webzine.Repository/StyleRepository.cs | 10 ++ Webzine.Repository/TitreRepository.cs | 104 ++++++++++++++++ .../Controllers/AccueilController.cs | 23 ++-- .../Controllers/RechercheController.cs | 113 +++++++++--------- .../Controllers/TitreController.cs | 64 +++++----- Webzine.WebApplication/Program.cs | 6 +- .../Accueil/AccueilIndexViewModel.cs | 20 +++- .../Views/Accueil/Index.cshtml | 2 +- Webzine.WebApplication/appsettings.json | 1 + 12 files changed, 279 insertions(+), 103 deletions(-) create mode 100644 Webzine.Repository/ArtisteRepository.cs create mode 100644 Webzine.Repository/StyleRepository.cs create mode 100644 Webzine.Repository/TitreRepository.cs diff --git a/Webzine.Repository.Contracts/ITtitreRepository.cs b/Webzine.Repository.Contracts/ITtitreRepository.cs index c7e9fc1..d6c841a 100644 --- a/Webzine.Repository.Contracts/ITtitreRepository.cs +++ b/Webzine.Repository.Contracts/ITtitreRepository.cs @@ -12,7 +12,7 @@ namespace Webzine.Repository.Contracts Titre? Find(int idTitre); - // IEnumerable FindTitres(int offset, int limit); + IEnumerable FindTitres(int offset, int limit); IEnumerable FindAll(); diff --git a/Webzine.Repository/ArtisteRepository.cs b/Webzine.Repository/ArtisteRepository.cs new file mode 100644 index 0000000..bd864bd --- /dev/null +++ b/Webzine.Repository/ArtisteRepository.cs @@ -0,0 +1,15 @@ +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// + +namespace Webzine.Repository +{ + using Webzine.Repository.Contracts; + /// + /// Implémentation de l'interface IArtisteRepository. + /// + public class ArtisteRepository : IArtisteRepository + { + + } +} diff --git a/Webzine.Repository/LocalEntityRepository.cs b/Webzine.Repository/LocalEntityRepository.cs index f9684e7..eea462c 100644 --- a/Webzine.Repository/LocalEntityRepository.cs +++ b/Webzine.Repository/LocalEntityRepository.cs @@ -7,7 +7,7 @@ namespace Webzine.Repository; /// /// Classe qui permet d'initialiser un jeu de données -/// pour tester l'application +/// pour tester l'application. /// public class LocalEntityRepository : ITitreRepository { @@ -50,11 +50,31 @@ public class LocalEntityRepository : ITitreRepository return _titres.FirstOrDefault(t => t.IdTitre == idTitre); } + public IEnumerable FindTitres( + int offset, + int limit) + { + return this._titres + .OrderByDescending(t => t.DateCreation) + .Skip((offset - 1) * limit) + .Take(limit) + .ToList(); + } + + /// + /// Retourner tous les titres. + /// + /// IEnumerable de titre. public IEnumerable FindAll() { return _titres; } + /// + /// Rechercher les titres par style. + /// + /// Libelle du style. + /// IEnumerable de titre. public IEnumerable SearchByStyle(string libelle) { if (string.IsNullOrWhiteSpace(libelle)) diff --git a/Webzine.Repository/StyleRepository.cs b/Webzine.Repository/StyleRepository.cs new file mode 100644 index 0000000..1832f5e --- /dev/null +++ b/Webzine.Repository/StyleRepository.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Webzine.Repository +{ + internal class StyleRepository + { + } +} diff --git a/Webzine.Repository/TitreRepository.cs b/Webzine.Repository/TitreRepository.cs new file mode 100644 index 0000000..2dc0562 --- /dev/null +++ b/Webzine.Repository/TitreRepository.cs @@ -0,0 +1,104 @@ +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// + +namespace Webzine.Repository +{ + using Microsoft.EntityFrameworkCore; + using Webzine.EntitiesContext; + using Webzine.Entity; + using Webzine.Repository.Contracts; + + /// + /// Implémentation de l'interface ITitreRepository. + /// + public class TitreRepository : ITitreRepository + { + private readonly WebzineDbContext context; + + /// + /// Initializes a new instance of the class. + /// + public TitreRepository(WebzineDbContext context) + { + this.context = context; + } + + /// + /// Rechercher un titre à l'aide de son nom. + /// + /// Nom de la musique. + /// IEnumerable Titre. + public IEnumerable Search(string mot) + { + if (string.IsNullOrWhiteSpace(mot)) + { + return Enumerable.Empty(); + } + + return this.context.Titres + .Where(t => !string.IsNullOrWhiteSpace(t.Libelle) + && t.Libelle.ToLower().Contains(mot.ToLower())) + .OrderBy(t => t.Libelle) + .ToList(); + } + + /// + /// Retourne le titre demandé à partir de son identifiant. + /// + /// Id du titre cherché. + /// Un titre. + public Titre? Find(int idTitre) + { + var find = this.context.Titres + .Where(t => t.IdTitre == idTitre) + .First(); + + return find; + } + + /// + /// Retourne les titres demandés (pour la pagination) triés + /// selon la date de création(du plus récent à ancien). + /// + /// IEnumerable de Titre. + public IEnumerable FindTitres( + int offset, + int limit) + { + return this.context.Titres + .OrderByDescending(t => t.DateCreation) + .Include(t => t.Artiste) + .Skip((offset - 1) * limit) + .Take(limit) + .ToList(); + } + + /// + /// Retourne tous les titres. + /// + /// Liste de Titre. + public IEnumerable FindAll() + { + return this.context.Titres + .AsNoTracking() + .Include(t => t.Artiste) + .OrderByDescending(t => t.DateCreation) + .ToList(); + } + + /// + /// Trouver les titres correspondant à un style. + /// + /// Style de musique recherché. + /// IEnumerable Titre. + public IEnumerable SearchByStyle(string libelle) + { + return this.context.Titres + .Where(t => t.Styles.Any(s => !string.IsNullOrWhiteSpace(s.Libelle) + && s.Libelle.ToLower().Contains(libelle.ToLower()))) + .OrderBy(t => t.Libelle) + .ToList(); + } + } +} diff --git a/Webzine.WebApplication/Controllers/AccueilController.cs b/Webzine.WebApplication/Controllers/AccueilController.cs index ac7fe8d..569b93c 100644 --- a/Webzine.WebApplication/Controllers/AccueilController.cs +++ b/Webzine.WebApplication/Controllers/AccueilController.cs @@ -5,7 +5,7 @@ namespace Webzine.WebApplication.Controllers { using Microsoft.AspNetCore.Mvc; - using Webzine.Repository.Fake; + using Webzine.Repository.Contracts; using Webzine.WebApplication.ViewModels.Accueil; /// @@ -16,17 +16,22 @@ namespace Webzine.WebApplication.Controllers // Injection du logger via le constructeur private readonly ILogger logger; private readonly IConfiguration configuration; + private readonly ITitreRepository titreRepository; /// /// Initialise une nouvelle instance de la classe . /// /// Service de journalisation injecté pour enregistrer les événements et les erreurs. /// Service d'injection de configuration pour accéder aux paramètres de l'application. - public AccueilController(ILogger logger, IConfiguration configuration) + public AccueilController( + ILogger logger, + IConfiguration configuration, + ITitreRepository titreRepository) { this.logger = logger; this.configuration = configuration; this.logger.LogDebug(1, "initialisation du AccueilController"); + this.titreRepository = titreRepository; } /// @@ -38,19 +43,19 @@ namespace Webzine.WebApplication.Controllers this.logger.LogInformation("Arrivée sur la page d'accueil"); var derniereChronique = this.configuration.GetValue("Webzine:NombreDerniereChronique"); - var topTitres = this.configuration.GetValue("Webzine:NombreDeTopTitres"); - var titres = FakeDataFactory.GetTitres(); + var nbTopTitres = this.configuration.GetValue("Webzine:NombreDeTopTitres"); + + // var titres = FakeDataFactory.GetTitres(); + // var titres = this.titreRepository.FindTitres(derniereChronique, nbTopTitres); + var titres = this.titreRepository.FindAll(); var vm = new AccueilIndexViewModel { - DerniersTitres = titres - .OrderByDescending(t => t.DateCreation) - .Take(derniereChronique) - .ToList(), + DerniersTitres = titres.Take(derniereChronique).ToList(), TopTitres = titres .OrderByDescending(t => t.NbLikes) - .Take(topTitres) + .Take(nbTopTitres) .ToList(), }; diff --git a/Webzine.WebApplication/Controllers/RechercheController.cs b/Webzine.WebApplication/Controllers/RechercheController.cs index ddd9f64..004f329 100644 --- a/Webzine.WebApplication/Controllers/RechercheController.cs +++ b/Webzine.WebApplication/Controllers/RechercheController.cs @@ -1,63 +1,68 @@ -using Microsoft.AspNetCore.Mvc; -using Webzine.Repository.Contracts; -using Webzine.WebApplication.ViewModels.Recherche; -using Webzine.WebApplication.ViewModels.Titre; +// +// Copyright (c) Equipe 1 - . All rights reserved. +// -namespace Webzine.WebApplication.Controllers; - -[Route("recherche")] -public class RechercheController : Controller +namespace Webzine.WebApplication.Controllers { - private readonly ILogger _logger; - private readonly ITitreRepository _titreRepository; + using Microsoft.AspNetCore.Mvc; + using Webzine.Repository.Contracts; + using Webzine.WebApplication.ViewModels.Recherche; + using Webzine.WebApplication.ViewModels.Titre; - public RechercheController(ILogger logger, ITitreRepository titreRepository) + [Route("recherche")] + public class RechercheController : Controller { - this._logger = logger; - this._titreRepository = titreRepository; - } + private readonly ILogger logger; + private readonly ITitreRepository titreRepository; - [HttpPost("")] - public IActionResult Index(string mot) - { - this._logger.LogInformation("Recherche artistes/titres pour le mot : {Mot}.", mot); - - var titres = _titreRepository.Search(mot) - .Concat(_titreRepository.SearchByStyle(mot)) - .DistinctBy(t => t.IdTitre) - .OrderBy(t => t.Libelle) - .Select(t => new TitreStyleItem - { - IdTitre = t.IdTitre, - Libelle = t.Libelle, - ArtisteNom = t.Artiste?.Nom, - UrlJaquette = t.UrlJaquette, - Duree = t.Duree - }) - .ToList(); - - var artistes = _titreRepository.FindAll() - .Select(t => t.Artiste) - .Where(a => a != null - && !string.IsNullOrWhiteSpace(a.Nom) - && !string.IsNullOrWhiteSpace(mot) - && a.Nom.Contains(mot, StringComparison.OrdinalIgnoreCase)) - .DistinctBy(a => a!.IdArtiste) - .OrderBy(a => a!.Nom) - .Select(a => new RechercheArtisteItem - { - Nom = a!.Nom, - NombreDeTitres = a.Titres?.Count ?? 0 - }) - .ToList(); - - var vm = new RechercheIndexViewModel + public RechercheController(ILogger logger, ITitreRepository titreRepository) { - Mot = mot, - Artistes = artistes, - Titres = titres - }; + this.logger = logger; + this.titreRepository = titreRepository; + } - return View(vm); + [HttpPost("")] + public IActionResult Index(string mot) + { + this.logger.LogInformation("Recherche artistes/titres pour le mot : {Mot}.", mot); + + var titres = this.titreRepository.Search(mot) + .Concat(this.titreRepository.SearchByStyle(mot)) + .DistinctBy(t => t.IdTitre) + .OrderBy(t => t.Libelle) + .Select(t => new TitreStyleItem + { + IdTitre = t.IdTitre, + Libelle = t.Libelle, + ArtisteNom = t.Artiste?.Nom, + UrlJaquette = t.UrlJaquette, + Duree = t.Duree, + }) + .ToList(); + + var artistes = this.titreRepository.FindAll() + .Select(t => t.Artiste) + .Where(a => a != null + && !string.IsNullOrWhiteSpace(a.Nom) + && !string.IsNullOrWhiteSpace(mot) + && a.Nom.Contains(mot, StringComparison.OrdinalIgnoreCase)) + .DistinctBy(a => a!.IdArtiste) + .OrderBy(a => a!.Nom) + .Select(a => new RechercheArtisteItem + { + Nom = a!.Nom, + NombreDeTitres = a.Titres?.Count ?? 0, + }) + .ToList(); + + var vm = new RechercheIndexViewModel + { + Mot = mot, + Artistes = artistes, + Titres = titres, + }; + + return this.View(vm); + } } } diff --git a/Webzine.WebApplication/Controllers/TitreController.cs b/Webzine.WebApplication/Controllers/TitreController.cs index 3040932..beb77fa 100644 --- a/Webzine.WebApplication/Controllers/TitreController.cs +++ b/Webzine.WebApplication/Controllers/TitreController.cs @@ -13,8 +13,8 @@ namespace Webzine.WebApplication.Controllers; [Route("titre")] public class TitreController : Controller { - private readonly ILogger _logger; - private readonly ITitreRepository _titreRepository; + private readonly ILogger logger; + private readonly ITitreRepository titreRepository; /// /// Initialise une nouvelle instance du . @@ -23,10 +23,10 @@ public class TitreController : Controller /// Repository des titres injecte. public TitreController(ILogger logger, ITitreRepository titreRepository) { - this._logger = logger; - this._titreRepository = titreRepository; + this.logger = logger; + this.titreRepository = titreRepository; - this._logger.LogInformation("Initialisation du controleur TitreController."); + this.logger.LogInformation("Initialisation du controleur TitreController."); } /// @@ -37,14 +37,14 @@ public class TitreController : Controller [HttpGet("{id}")] public IActionResult Details(int id) { - this._logger.LogInformation("Demande d'affichage du detail pour le titre ID {Id}.", id); + this.logger.LogInformation("Demande d'affichage du detail pour le titre ID {Id}.", id); - var titre = this._titreRepository.Find(id); + var titre = this.titreRepository.Find(id); if (titre == null) { - this._logger.LogWarning("Titre avec ID {Id} introuvable.", id); - return RedirectToAction("Index"); + this.logger.LogWarning("Titre avec ID {Id} introuvable.", id); + return this.RedirectToAction("Index"); } var vm = new TitreDetail @@ -60,15 +60,15 @@ public class TitreController : Controller UrlEcoute = titre.UrlEcoute, ArtisteNom = titre.Artiste?.Nom, Styles = titre.Styles, - Commentaires = titre.Commentaires + Commentaires = titre.Commentaires, }, CommentForm = new TitreComment { - IdTitre = titre.IdTitre - } + IdTitre = titre.IdTitre, + }, }; - return View(vm); + return this.View(vm); } /// @@ -79,17 +79,17 @@ public class TitreController : Controller [HttpGet("style/{style}")] public IActionResult Style(string style) { - this._logger.LogInformation("Recherche des titres pour le style : {Style}.", style); + this.logger.LogInformation("Recherche des titres pour le style : {Style}.", style); - var titresFiltres = _titreRepository.SearchByStyle(style).ToList(); + var titresFiltres = this.titreRepository.SearchByStyle(style).ToList(); var vm = new TitreStyle { StyleName = style, - Titres = titresFiltres.Select(MapTitreItem).ToList() + Titres = titresFiltres.Select(MapTitreItem).ToList(), }; - return View(vm); + return this.View(vm); } /// @@ -100,19 +100,19 @@ public class TitreController : Controller [HttpPost("like")] public IActionResult Like(TitreLike model) { - this._logger.LogInformation("Ajout d'un like pour le titre ID {Id}.", model.IdTitre); + this.logger.LogInformation("Ajout d'un like pour le titre ID {Id}.", model.IdTitre); - var titre = this._titreRepository.Find(model.IdTitre); + var titre = this.titreRepository.Find(model.IdTitre); if (titre == null) { - this._logger.LogWarning("Impossible d'ajouter un like. Titre ID {Id} introuvable.", model.IdTitre); - return RedirectToAction("Index"); + this.logger.LogWarning("Impossible d'ajouter un like. Titre ID {Id} introuvable.", model.IdTitre); + return this.RedirectToAction("Index"); } titre.NbLikes++; - return RedirectToAction("Details", new { id = model.IdTitre }); + return this.RedirectToAction("Details", new { id = model.IdTitre }); } /// @@ -123,18 +123,18 @@ public class TitreController : Controller [HttpPost("comment")] public IActionResult Comment(TitreComment model) { - if (!ModelState.IsValid) + if (!this.ModelState.IsValid) { - this._logger.LogWarning("Echec de validation du modele de commentaire pour le titre ID {Id}.", model.IdTitre); - return RedirectToAction("Details", new { id = model.IdTitre }); + this.logger.LogWarning("Echec de validation du modele de commentaire pour le titre ID {Id}.", model.IdTitre); + return this.RedirectToAction("Details", new { id = model.IdTitre }); } - var titre = this._titreRepository.Find(model.IdTitre); + var titre = this.titreRepository.Find(model.IdTitre); if (titre == null) { - this._logger.LogWarning("Impossible d'ajouter le commentaire. Titre ID {Id} introuvable.", model.IdTitre); - return RedirectToAction("Index"); + this.logger.LogWarning("Impossible d'ajouter le commentaire. Titre ID {Id} introuvable.", model.IdTitre); + return this.RedirectToAction("Index"); } var commentaire = new Commentaire @@ -142,14 +142,14 @@ public class TitreController : Controller Auteur = model.Auteur, Contenu = model.Contenu, DateCreation = DateTime.Now, - IdTitre = model.IdTitre + IdTitre = model.IdTitre, }; titre.Commentaires.Add(commentaire); - this._logger.LogInformation("Commentaire ajoute avec succes au titre ID {Id}.", model.IdTitre); + this.logger.LogInformation("Commentaire ajoute avec succes au titre ID {Id}.", model.IdTitre); - return RedirectToAction("Details", new { id = model.IdTitre }); + return this.RedirectToAction("Details", new { id = model.IdTitre }); } private static TitreStyleItem MapTitreItem(Titre titre) @@ -160,7 +160,7 @@ public class TitreController : Controller Libelle = titre.Libelle, ArtisteNom = titre.Artiste?.Nom, UrlJaquette = titre.UrlJaquette, - Duree = titre.Duree + Duree = titre.Duree, }; } } diff --git a/Webzine.WebApplication/Program.cs b/Webzine.WebApplication/Program.cs index 098f724..8de038b 100644 --- a/Webzine.WebApplication/Program.cs +++ b/Webzine.WebApplication/Program.cs @@ -21,8 +21,12 @@ try // Necessite le package Nuget Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation. .AddRazorRuntimeCompilation(); + // A utiliser en mode repo - builder.Services.AddSingleton(); + // builder.Services.AddSingleton(); + + // A utiliser en mode DB + builder.Services.AddScoped(); builder.Services.AddDbContext(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"))); diff --git a/Webzine.WebApplication/ViewModels/Accueil/AccueilIndexViewModel.cs b/Webzine.WebApplication/ViewModels/Accueil/AccueilIndexViewModel.cs index a4ed303..3803f4a 100644 --- a/Webzine.WebApplication/ViewModels/Accueil/AccueilIndexViewModel.cs +++ b/Webzine.WebApplication/ViewModels/Accueil/AccueilIndexViewModel.cs @@ -1,18 +1,30 @@ namespace Webzine.WebApplication.ViewModels.Accueil { + using Webzine.Entity; + /// /// ViewModel pour la page d'accueil du webzine, affichant les derniers titres et les titres les plus populaires. /// public class AccueilIndexViewModel { /// - /// Définit la liste des derniers titres ajoutés au webzine. + /// Obtient ou définit la liste des derniers titres ajoutés au webzine. /// - public List DerniersTitres { get; set; } = []; + public List DerniersTitres { get; set; } = new List(); /// - /// Définit la liste des titres les plus populaires du webzine. + /// Obtient ou définit la liste des titres les plus populaires du webzine. /// - public List TopTitres { get; set; } = []; + public List TopTitres { get; set; } = new List(); + + /// + /// Obtient ou définit le nombre de titre disponible. + /// + // public int NombreDeTitre { get; set; } = 0; + + /// + /// Obtient ou définit le nombre de titre paginé. + /// + // public int Pagination { get; set; } = 0; } } \ No newline at end of file diff --git a/Webzine.WebApplication/Views/Accueil/Index.cshtml b/Webzine.WebApplication/Views/Accueil/Index.cshtml index 23290ad..9ae7204 100644 --- a/Webzine.WebApplication/Views/Accueil/Index.cshtml +++ b/Webzine.WebApplication/Views/Accueil/Index.cshtml @@ -86,7 +86,7 @@
- @titre.Album + @titre.Libelle
par diff --git a/Webzine.WebApplication/appsettings.json b/Webzine.WebApplication/appsettings.json index 7c147f2..54a33df 100644 --- a/Webzine.WebApplication/appsettings.json +++ b/Webzine.WebApplication/appsettings.json @@ -6,6 +6,7 @@ } }, "Webzine": { + // TODO : préciser les modes environnement et repo "NombreDerniereChronique": 3, "NombreDeTopTitres": 3 },