Blog Post Id

This commit is contained in:
Paul Schneider 2026-09-19 21:08:10 +01:00
commit 67da921bce
Signed by: notazof
GPG key ID: 1DD5D838E5343B06
22 changed files with 4869 additions and 96 deletions

View file

@ -13,6 +13,10 @@ all:
clean: clean:
dotnet clean -c $(CONFIG) dotnet clean -c $(CONFIG)
brutal_clean:
@find -name "obj" -exec rm -rf {} \;
@find -name "bin" -exec rm -rf {} \;
src/Yavsc/bin/output/wwwroot: src/Yavsc/bin/output/wwwroot:
dotnet --project src/Yavsc.Org/Yavsc.Org.csproj publish dotnet --project src/Yavsc.Org/Yavsc.Org.csproj publish

View file

@ -17,8 +17,8 @@ namespace Yavsc.Helpers
if (string.IsNullOrWhiteSpace(text)) return; if (string.IsNullOrWhiteSpace(text)) return;
try try
{ {
if (context.AllAttributes.ContainsName("summary")) if (context.AllAttributes.ContainsName("summary"))
{ {

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class blogPostId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_blogSpotPublications_BlogSpot_BlogpostId",
table: "blogSpotPublications");
migrationBuilder.RenameColumn(
name: "BlogpostId",
table: "blogSpotPublications",
newName: "PostId");
migrationBuilder.AddForeignKey(
name: "FK_blogSpotPublications_BlogSpot_PostId",
table: "blogSpotPublications",
column: "PostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_blogSpotPublications_BlogSpot_PostId",
table: "blogSpotPublications");
migrationBuilder.RenameColumn(
name: "PostId",
table: "blogSpotPublications",
newName: "BlogpostId");
migrationBuilder.AddForeignKey(
name: "FK_blogSpotPublications_BlogSpot_BlogpostId",
table: "blogSpotPublications",
column: "BlogpostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View file

@ -1693,10 +1693,10 @@ namespace Yavsc.Migrations
modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b => modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b =>
{ {
b.Property<long>("BlogpostId") b.Property<long>("PostId")
.HasColumnType("bigint"); .HasColumnType("bigint");
b.HasKey("BlogpostId"); b.HasKey("PostId");
b.ToTable("blogSpotPublications"); b.ToTable("blogSpotPublications");
}); });
@ -3958,13 +3958,13 @@ namespace Yavsc.Migrations
modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b => modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b =>
{ {
b.HasOne("Yavsc.Models.Blog.BlogPost", "BlogPost") b.HasOne("Yavsc.Models.Blog.BlogPost", "Post")
.WithMany() .WithMany()
.HasForeignKey("BlogpostId") .HasForeignKey("PostId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("BlogPost"); b.Navigation("Post");
}); });
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b => modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>

View file

@ -3,7 +3,7 @@
ViewBag.Title=Model.Title; ViewBag.Title=Model.Title;
} }
@section scripts { @section scripts {
<script src="~/js/comment.js" asp-append-version="true"></script> <script src="~/js/comment.js" asp-append-version="true"></script>
<script> <script>
$.psc.blogcomment.prototype.options.lang = '@System.Globalization.CultureInfo.CurrentUICulture.Name'; $.psc.blogcomment.prototype.options.lang = '@System.Globalization.CultureInfo.CurrentUICulture.Name';
@ -18,8 +18,8 @@
type: 'POST', type: 'POST',
method: 'POST', method: 'POST',
contentType: "application/json", contentType: "application/json",
data: JSON.stringify({ data: JSON.stringify({
Article: $('#Comment').val(), Article: $('#Comment').val(),
ReceiverId: @Model.Id ReceiverId: @Model.Id
}), }),
error: function(xhr,data) { error: function(xhr,data) {
@ -36,7 +36,7 @@ $('#commentValidation').html(
) )
} }
} }
}, },
success: function (data) { success: function (data) {
var comment = $('#Comment').val(); var comment = $('#Comment').val();
@ -65,12 +65,12 @@ $('#commentValidation').html(
<div class="float-left"> <div class="float-left">
<img class="photo" src="@Model.Photo" > <img class="photo" src="@Model.Photo" >
</div> </div>
<h1 ismarkdown>@Model.Title</h1> <h1 ismarkdown>@Model.Title</h1>
@Html.DisplayFor(m=>m.Author) @Html.DisplayFor(m=>m.Author)
<asciidoc>@Html.DisplayFor(m=>m.Article)</asciidoc> <markdown>@Html.DisplayFor(m=>m.Article)</markdown>
</div> </div>
<div id="comments"> <div id="comments">
@ -89,7 +89,7 @@ $('#commentValidation').html(
<input type="button" value="Comment" class="btn btn-secondary" <input type="button" value="Comment" class="btn btn-secondary"
data-receiverId="@Model.Id" id="cmtBtn" data-receiverId="@Model.Id" id="cmtBtn"
/> />
</span> </span>
</div> </div>
<span asp-validation-for="Article" class="text-danger" ></span> <span asp-validation-for="Article" class="text-danger" ></span>
</div> </div>
@ -97,7 +97,7 @@ $('#commentValidation').html(
else { else {
<p><i>Vous devez être identifié pour commenter.</i> </p> <p><i>Vous devez être identifié pour commenter.</i> </p>
} }
@if ((await AuthorizationService.AuthorizeAsync(User, Model, new EditPermission())).Succeeded) { @if ((await AuthorizationService.AuthorizeAsync(User, Model, new EditPermission())).Succeeded) {
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-link">Edit</a> <a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-link">Edit</a>
} }

View file

@ -58,11 +58,11 @@
</a> </a>
<div> <div>
<a asp-action="Details" asp-route-id="@post.Id"> <a asp-action="Details" asp-route-id="@post.Id">
<asciidoc summary="@maxTextLen">@post.Article</asciidoc></a> <markdown summary="@maxTextLen">@post.Article</markdown></a>
<span style="font-size:x-small;">@Html.DisplayFor(m => post.Author)</span> <span style="font-size:x-small;">@Html.DisplayFor(m => post.Author)</span>
<span style="font-size:xx-small;"> <span style="font-size:xx-small;">
posté le @post.DateCreated.ToString("dddd d MMM yyyy à H:mm") posté le @post.DateCreated.ToString("dddd d MMM yyyy à H:mm")
@if ((post.DateModified - post.DateCreated).Minutes > 0){  @if ((post.DateModified - post.DateCreated).Minutes > 0){
@:- Modifié le @post.DateModified.ToString("dddd d MMM yyyy à H:mm") @:- Modifié le @post.DateModified.ToString("dddd d MMM yyyy à H:mm")
} }
</span> </span>

View file

@ -8,23 +8,23 @@
</p> </p>
<table class="table"> <table class="table">
@foreach (var item in Model) { @foreach (var item in Model) {
<tr> <tr>
<td><a asp-action="Details" asp-route-id="@item.Id" class="bloglink"> <td><a asp-action="Details" asp-route-id="@item.Id" class="bloglink">
<img src="@item.Photo" class="blogphoto"></a> <img src="@item.Photo" class="blogphoto"></a>
</td> </td>
<td> <td>
<asciidoc>@((item.Article?.Length > 256) ? item.Article.Substring(0, 256) + " ..." : item.Article)</asciidoc> <markdown>@((item.Article?.Length > 256) ? item.Article.Substring(0, 256) + " ..." : item.Article)</markdown>
<span style="font-size:x-small;">(@item.Author.UserName </span>, <span style="font-size:x-small;">(@item.Author.UserName </span>,
<span style="font-size:xx-small;"> <span style="font-size:xx-small;">
posté le @item.DateCreated.ToString("dddd d MMM yyyy à H:mm") posté le @item.DateCreated.ToString("dddd d MMM yyyy à H:mm")
@if ((item.DateModified - item.DateCreated).Minutes > 0){  @if ((item.DateModified - item.DateCreated).Minutes > 0){
@:- Modifié le @item.DateModified.ToString("dddd d MMM yyyy à H:mm") @:- Modifié le @item.DateModified.ToString("dddd d MMM yyyy à H:mm")
}) })
</span> </span>
</td> </td>
<td> <td>
<ul class="actiongroup"> <ul class="actiongroup">
@if ((await AuthorizationService.AuthorizeAsync(User, item, new ReadPermission())).Succeeded) { @if ((await AuthorizationService.AuthorizeAsync(User, item, new ReadPermission())).Succeeded) {
<li> <li>

View file

@ -1,13 +1,13 @@
@{ @{
ViewBag.Title = "Conditions Générales de Vente"; ViewBag.Title = "Conditions Générales de Vente";
} }
<h2>@ViewBag.Title</h2> <h2>@ViewBag.Title</h2>
<asciidoc> <markdown>
Le paiement intervient à la commande, quelque soit la date d'intervention. Le paiement intervient à la commande, quelque soit la date d'intervention.
Vous pouvez annuler votre commande depuis la [liste de vos commande en cours](/HairCutCommand/), Vous pouvez annuler votre commande depuis la [liste de vos commande en cours](/HairCutCommand/),
Vous pouvez demander le remboursement d'un paiement, dans le cadre d'une réclamation sur l'execution Vous pouvez demander le remboursement d'un paiement, dans le cadre d'une réclamation sur l'execution
de votre commande, en nous contactant via courrier éléctronique ou postal, [que vour retrouverez sur la page de contact](/Home/Contact), votre demande sera rapidement traitée. de votre commande, en nous contactant via courrier éléctronique ou postal, [que vour retrouverez sur la page de contact](/Home/Contact), votre demande sera rapidement traitée.
</asciidoc> </markdown>

View file

@ -5,7 +5,7 @@
<h1>@SiteSettings.Value.Title - objetivo</h1> <h1>@SiteSettings.Value.Title - objetivo</h1>
<environment names="freefield,Development"> <environment names="freefield,Development">
<asciidoc> <markdown>
= O objetivo = O objetivo
Esta aplicação é construída para conectar artistas Esta aplicação é construída para conectar artistas
@ -87,51 +87,51 @@ que imediatamente desativa as publicações associadas às suas informações,
e planeia a eliminação completa desta informação no prazo de quinze dias e planeia a eliminação completa desta informação no prazo de quinze dias
do aplicativo, a menos que seja um pedido contraditório. do aplicativo, a menos que seja um pedido contraditório.
A operação é anulável até duas semanas após a sua programação. A operação é anulável até duas semanas após a sua programação.
</asciidoc> </markdown>
</environment> </environment>
<environment names="Lua,Development"> <environment names="Lua,Development">
<asciidoc>Este é o meu site perso, uma configuração de _Yavsc_ (outro negócio muito pequeno). <markdown>Este é o meu site perso, uma configuração de _Yavsc_ (outro negócio muito pequeno).
* [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md) * [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md)
* [licença: GNU GPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE) * [licença: GNU GPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE)
Outras instalações: Outras instalações:
</asciidoc> </markdown>
<asciidoc> <markdown>
* [Coiffure](http://coiffure.pschneider.fr) * [Coiffure](http://coiffure.pschneider.fr)
* [ZicMoove](http://linkmuse.pschneider.fr) * [ZicMoove](http://linkmuse.pschneider.fr)
* [Yavsc](http://yavsc.pschneider.fr) * [Yavsc](http://yavsc.pschneider.fr)
</asciidoc> </markdown>
</environment> </environment>
<environment names="Yavsc"> <environment names="Yavsc">
<asciidoc> <markdown>
Yet Another Very Small Company ... Yet Another Very Small Company ...
* [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md) * [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md)
* [license: GNU FPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE) * [license: GNU FPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE)
</asciidoc> </markdown>
</environment> </environment>
<environment names="YavscPre"> <environment names="YavscPre">
<asciidoc> <markdown>
## Yet Another Very Small Company : ## Yet Another Very Small Company :
* [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md) * [README](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/README.md)
* [license: GNU FPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE) * [license: GNU FPL v3](https://forgejo.pschneider.fr/notazof/yavsc/blob/vnext/LICENSE)
En production: En production:
* [Lua](https://lua.pschneider.fr) * [Lua](https://lua.pschneider.fr)
* [Yavsc](https://yavsc.pschneider.fr) * [Yavsc](https://yavsc.pschneider.fr)
</asciidoc> </markdown>
</environment> </environment>
<environment names="coiffure"> <environment names="coiffure">
<asciidoc> <markdown>
Você está no site da ordem em cabeleireiro em casa de Soraya Boudjouraf, Você está no site da ordem em cabeleireiro em casa de Soraya Boudjouraf,
um ás de cabeleireiro, que trabalha na região de Paris. um ás de cabeleireiro, que trabalha na região de Paris.
@ -139,11 +139,11 @@ Ao validar um formulário de pedido aqui, é para ela que você notifica sua sol
Você pode [Deixe-lhe o seu número de telefone] (/ HairCutCommand / HairCut? ActivityCode = Brush & performerId = 1bd841ab-c305-4971-940d-7ddca818310c) Você pode [Deixe-lhe o seu número de telefone] (/ HairCutCommand / HairCut? ActivityCode = Brush & performerId = 1bd841ab-c305-4971-940d-7ddca818310c)
e / ou detalhes sobre o seu pedido, e / ou detalhes sobre o seu pedido,
ela vai ligar de volta.</asciidoc> ela vai ligar de volta.</markdown>
</environment> </environment>
<environment names="Development"> <environment names="Development">
<asciidoc> <markdown>
## Este é um site de desenvolvimento. ## Este é um site de desenvolvimento.
Este recurso só diz respeito ao desenvolvimento do software que o implementa. Este recurso só diz respeito ao desenvolvimento do software que o implementa.
@ -156,7 +156,7 @@ A "pré-produção" exibe os seguintes sites:
* [Yavsc](https://yavsc.pschneider.fr) * [Yavsc](https://yavsc.pschneider.fr)
* [Lua](https://lua.pschneider.fr) * [Lua](https://lua.pschneider.fr)
</asciidoc> </markdown>
</environment> </environment>
<p>@Model</p> <p>@Model</p>

View file

@ -3,13 +3,13 @@
} }
<h1>@ViewBag.Title</h1> <h1>@ViewBag.Title</h1>
<asciidoc> <markdown>
# Blog et fichiers utilisateurs # Blog et fichiers utilisateurs
Par défaut, un envoi à destination du serveur est privé, visible seulement pour son possesseur (et l'administration). Par défaut, un envoi à destination du serveur est privé, visible seulement pour son possesseur (et l'administration).
L'utilisateur peu publier chacun de ces derniers à l'adresse : L'utilisateur peu publier chacun de ces derniers à l'adresse :
* de tout le monde, * de tout le monde,
* ou d'une liste de cercles d'utilisateurs, * ou d'une liste de cercles d'utilisateurs,
@ -17,8 +17,8 @@ L'utilisateur peu publier chacun de ces derniers à l'adresse :
Quand il s'agit d'un fichier, son adresse permanente relative à la racine du serveur web est: `/UserFiles/(Nom Utilisateur)/(cheminVersLeFichier)` Quand il s'agit d'un fichier, son adresse permanente relative à la racine du serveur web est: `/UserFiles/(Nom Utilisateur)/(cheminVersLeFichier)`
Les restrictions d'accès à ce fichier sont celles associées à tous les fichiers du même dossier. Les restrictions d'accès à ce fichier sont celles associées à tous les fichiers du même dossier.
Il n'y a pas de regle assiciée à chaque fichier individuellement, Il n'y a pas de regle assiciée à chaque fichier individuellement,
elles appartiennent au dossier qui les contient. elles appartiennent au dossier qui les contient.
Les billet de blog sont regroupés par utilisateur, à l'Url Les billet de blog sont regroupés par utilisateur, à l'Url
@ -35,6 +35,6 @@ Et ils possèdent une addresse permanente de la forme :
</asciidoc> </markdown>

View file

@ -3,7 +3,7 @@
} }
<h1>@ViewBag.Title</h1> <h1>@ViewBag.Title</h1>
<asciidoc> <markdown>
Quelques extensions à un Markdown de base : Quelques extensions à un Markdown de base :
* les video et audio: `![video: Ep. 28 - La France en commun - Une invitation à écrire un nouveau projet d'émancipation humaine](/images/testVideo.mp4)` * les video et audio: `![video: Ep. 28 - La France en commun - Une invitation à écrire un nouveau projet d'émancipation humaine](/images/testVideo.mp4)`
@ -16,4 +16,4 @@ Quelques extensions à un Markdown de base :
* le tag "Titre d'article": "#1_great_title" * le tag "Titre d'article": "#1_great_title"
* le tag "User" = "@@(John Doe)" ou "@@jdoe" * le tag "User" = "@@(John Doe)" ou "@@jdoe"
</asciidoc> </markdown>

View file

@ -1,13 +1,13 @@
@{ @{
ViewBag.Title = "Conditions Générales de Vente"; ViewBag.Title = "Conditions Générales de Vente";
} }
<h2>@ViewBag.Title</h2> <h2>@ViewBag.Title</h2>
<asciidoc> <markdown>
Le paiement intervient à la commande, quelque soit la date d'intervention. Le paiement intervient à la commande, quelque soit la date d'intervention.
Vous pouvez annuler votre commande depuis la [liste de vos commande en cours](/HairCutCommand/), Vous pouvez annuler votre commande depuis la [liste de vos commande en cours](/HairCutCommand/),
Vous pouvez demander le remboursement d'un paiement, dans le cadre d'une réclamation sur l'execution Vous pouvez demander le remboursement d'un paiement, dans le cadre d'une réclamation sur l'execution
de votre commande, en nous contactant via courrier éléctronique ou postal, [que vour retrouverez sur la page de contact](/Home/Contact), votre demande sera rapidement traitée. de votre commande, en nous contactant via courrier éléctronique ou postal, [que vour retrouverez sur la page de contact](/Home/Contact), votre demande sera rapidement traitée.
</asciidoc> </markdown>

View file

@ -2,9 +2,9 @@
ViewBag.Title = Localizer["Home"]; ViewBag.Title = Localizer["Home"];
} }
<asciidoc> <markdown>
= La confidentialité = La confidentialité
:hide-uri-scheme: :hide-uri-scheme:
xref:Contact[Get Report] xref:Contact[Get Report]
@ -13,4 +13,4 @@ ne sont transmis à personne. Seul le système et son link:Contact[possesseur] o
De plus, le droit de retrait est permanent et sa mise en oeuvre link:/Account/Delete[immédiate]. De plus, le droit de retrait est permanent et sa mise en oeuvre link:/Account/Delete[immédiate].
</asciidoc> </markdown>

View file

@ -4,14 +4,14 @@
<h1>@ViewBag.Title</h1> <h1>@ViewBag.Title</h1>
<em>Linkmuse(trox)</em> <em>Linkmuse(trox)</em>
<asciidoc> <markdown>
Les tags. Les tags.
La librairie, les lives. La librairie, les lives.
</asciidoc> </markdown>
@{ @{
ViewBag.Title = @Localizer["TODO"]; ViewBag.Title = @Localizer["TODO"];
} }
<h1>@ViewBag.Title</h1> <h1>@ViewBag.Title</h1>
<em>Faster, stronger, shorter</em> <em>Faster, stronger, shorter</em>
<asciidoc> <markdown>
</asciidoc> </markdown>

View file

@ -1,12 +1,12 @@
@model Comment @model Comment
<div data-type="blogcomment" data-id="@Model.Id" data-receiver-id="@Model.ReceiverId" data-allow-edit="@(User.GetUserId()==Model.AuthorId?"true":"false")" <div data-type="blogcomment" data-id="@Model.Id" data-receiver-id="@Model.ReceiverId" data-allow-edit="@(User.GetUserId()==Model.AuthorId?"true":"false")"
data-allow-moderate="@ViewBag.moderatoFlag" data-date="@Model.DateCreated.ToString("yyyy-MM-dd hh:mm:ss")" data-username="@Model.Author.UserName" > data-allow-moderate="@ViewBag.moderatoFlag" data-date="@Model.DateCreated.ToString("yyyy-MM-dd hh:mm:ss")" data-username="@Model.Author.UserName" >
<asciidoc>@Model.Article</asciidoc> <markdown>@Model.Article</markdown>
@if (Model.Children!=null) { @if (Model.Children!=null) {
<div class="subcomments"> <div class="subcomments">
@foreach (var comment in Model.Children) @foreach (var comment in Model.Children)
{ {
@await this.Component.InvokeAsync("Comment", new { id = comment.Id}); @await this.Component.InvokeAsync("Comment", new { id = comment.Id});
} }

View file

@ -31,7 +31,7 @@
<h2 markdown="@n.title"></h2> <h2 markdown="@n.title"></h2>
<a class="close" data-dismiss="alert" aria-label="close" onclick="notifClick(@n.Id)">@((n.click_action == null) ? <a class="close" data-dismiss="alert" aria-label="close" onclick="notifClick(@n.Id)">@((n.click_action == null) ?
Localizer["Fermer"] : Localizer[n.click_action])</a> Localizer["Fermer"] : Localizer[n.click_action])</a>
<asciidoc>@n.body</asciidoc> <markdown>@n.body</markdown>
</div> </div>
} }
} }

View file

@ -14,9 +14,9 @@ namespace Yavsc.Server.Helpers
if (readerId == null) if (readerId == null)
{ {
var userPosts = dbContext.blogSpotPublications.Include( var userPosts = dbContext.blogSpotPublications.Include(
b => b.BlogPost b => b.Post
).Where(x => x.BlogPost.AuthorId == posterId) ).Where(x => x.Post.AuthorId == posterId)
.Select(x => x.BlogPost).ToArray(); .Select(x => x.Post).ToArray();
return userPosts; return userPosts;
} }
else else

View file

@ -96,6 +96,9 @@ namespace Yavsc.Models.Blog
[InverseProperty("Post")] [InverseProperty("Post")]
public virtual List<Comment> Comments { get; set; } public virtual List<Comment> Comments { get; set; }
[InverseProperty("Post")]
public virtual BlogSpotPublication Publication { get; set; }
/// <summary> /// <summary>
/// Whether this post is published. Not a column: the /// Whether this post is published. Not a column: the
/// existence of a row in <c>BlogSpotPublication</c> /// existence of a row in <c>BlogSpotPublication</c>
@ -147,5 +150,7 @@ namespace Yavsc.Models.Blog
}).ToList() ?? new List<CircleAuthorization>(); }).ToList() ?? new List<CircleAuthorization>();
} }
} }
} }
} }

View file

@ -7,9 +7,9 @@ namespace Yavsc.Models
public class BlogSpotPublication public class BlogSpotPublication
{ {
[Key] [Key]
public long BlogpostId { get; set; } public long PostId { get; set; }
[ForeignKey("BlogpostId")] [ForeignKey("PostId")]
public virtual BlogPost BlogPost{ get; set; } public virtual BlogPost Post{ get; set; }
} }
} }

View file

@ -61,7 +61,7 @@ public class BlogSpotService
blogFilesSubdir); blogFilesSubdir);
var di = new DirectoryInfo(destDir); var di = new DirectoryInfo(destDir);
if (!di.Exists) if (!di.Exists)
{ {
logger.LogInformation("Creating directory for blog attachments: {destDir}", destDir); logger.LogInformation("Creating directory for blog attachments: {destDir}", destDir);
di.Create(); di.Create();
@ -126,7 +126,7 @@ public class BlogSpotService
if (!auth.Succeeded) if (!auth.Succeeded)
throw new AuthorizationFailureException(auth); throw new AuthorizationFailureException(auth);
var pub = await _context.blogSpotPublications.AnyAsync(x => x.BlogpostId == blog.Id); var pub = await _context.blogSpotPublications.AnyAsync(x => x.PostId == blog.Id);
ScrubAclForViewer(blog, user); ScrubAclForViewer(blog, user);
return new BlogPostEditViewModel(blog, pub); return new BlogPostEditViewModel(blog, pub);
@ -146,7 +146,7 @@ public class BlogSpotService
// Hydrate le flag [NotMapped] depuis la table de publication. // Hydrate le flag [NotMapped] depuis la table de publication.
blog.IsPublished = await _context.blogSpotPublications blog.IsPublished = await _context.blogSpotPublications
.AnyAsync(pub => pub.BlogpostId == blogPostId); .AnyAsync(pub => pub.PostId == blogPostId);
var auth = await _authorizationService.AuthorizeAsync(user, blog, new ReadPermission()); var auth = await _authorizationService.AuthorizeAsync(user, blog, new ReadPermission());
if (!auth.Succeeded) if (!auth.Succeeded)
@ -176,7 +176,7 @@ public class BlogSpotService
_context.Update(blog); _context.Update(blog);
var publication = await _context.blogSpotPublications var publication = await _context.blogSpotPublications
.SingleOrDefaultAsync(p => p.BlogpostId == blogEdit.Id); .SingleOrDefaultAsync(p => p.PostId == blogEdit.Id);
if (publication != null) if (publication != null)
{ {
@ -185,7 +185,7 @@ public class BlogSpotService
} }
else if (blogEdit.Publish) else if (blogEdit.Publish)
{ {
_context.blogSpotPublications.Add(new BlogSpotPublication { BlogpostId = blogEdit.Id }); _context.blogSpotPublications.Add(new BlogSpotPublication { PostId = blogEdit.Id });
} }
_context.SaveChanges(user.GetUserId()); _context.SaveChanges(user.GetUserId());
@ -231,21 +231,19 @@ public class BlogSpotService
.Include(p => p.ACL) .Include(p => p.ACL)
.Include(p => p.Tags) .Include(p => p.Tags)
.Include(p => p.Comments) .Include(p => p.Comments)
.Where(p => p.ACL == null .Include(p => p.Publication)
|| p.ACL.Count == 0 .Where(p => p.Publication != null
|| p.AuthorId == viewerId
|| (userCircles != null && p.ACL.Any(a => userCircles.Contains(a.CircleId)))); || (userCircles != null && p.ACL.Any(a => userCircles.Contains(a.CircleId))));
} }
else else
{ {
posts = _context.blogSpotPublications posts = _context.blogSpotPublications
.Include(p => p.BlogPost) .Include(p => p.Post)
.Include(b => b.BlogPost.Author) .Include(b => b.Post.Author)
.Include(p => p.BlogPost.ACL) .Include(p => p.Post.ACL)
.Include(p => p.BlogPost.Tags) .Include(p => p.Post.Tags)
.Include(p => p.BlogPost.Comments) .Include(p => p.Post.Comments)
.Where(p => p.BlogPost.ACL == null || p.BlogPost.ACL.Count == 0) .Select(p => p.Post)
.Select(p => p.BlogPost)
.ToArray(); .ToArray();
} }
@ -255,8 +253,8 @@ public class BlogSpotService
if (postIds.Count > 0) if (postIds.Count > 0)
{ {
var publishedIds = await _context.blogSpotPublications var publishedIds = await _context.blogSpotPublications
.Where(pub => postIds.Contains(pub.BlogpostId)) .Where(pub => postIds.Contains(pub.PostId))
.Select(pub => pub.BlogpostId) .Select(pub => pub.PostId)
.ToListAsync(); .ToListAsync();
var publishedSet = publishedIds.ToHashSet(); var publishedSet = publishedIds.ToHashSet();
@ -323,11 +321,11 @@ public class BlogSpotService
if (!auth.Succeeded) if (!auth.Succeeded)
throw new AuthorizationFailureException(auth); throw new AuthorizationFailureException(auth);
var existing = await _context.blogSpotPublications.SingleOrDefaultAsync(p => p.BlogpostId == postId); var existing = await _context.blogSpotPublications.SingleOrDefaultAsync(p => p.PostId == postId);
if (publish) if (publish)
{ {
if (existing == null) if (existing == null)
_context.blogSpotPublications.Add(new BlogSpotPublication { BlogpostId = postId }); _context.blogSpotPublications.Add(new BlogSpotPublication { PostId = postId });
} }
else else
{ {

View file

@ -59,7 +59,7 @@ public class PermissionHandler : IAuthorizationHandler
{ {
return return
applicationDbContext.blogSpotPublications applicationDbContext.blogSpotPublications
.Any(p=>p.BlogpostId == blogPost.Id); .Any(p=>p.PostId == blogPost.Id);
} }
return false; return false;
} }