Remplace le système de notifications stockées par un système de providers qui dérivent les notifications des données existantes (commentaires, réponses, demandes de projet, demandes de rendez-vous, validations de brief). - Ajout du NotificationCollector et de l'interface NotificationProvider - Création de 5 providers : Comment, Reply, ProjectRequest, AppointmentRequest, Content - Métadonnées de notifications stockées directement sur les entités source - Nouvelles routes mark-as-read et mark-all-read - Mise à jour du frontend pour le nouveau système - Route de migration pour les données existantes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
128 lines
3.7 KiB
PHP
128 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace adrienpayet\notifications\providers;
|
|
|
|
use adrienpayet\notifications\NotificationProvider;
|
|
use Kirby\Cms\Page;
|
|
use Kirby\Cms\User;
|
|
use Kirby\Data\Yaml;
|
|
|
|
/**
|
|
* Provider pour les notifications de type "content".
|
|
* Dérivé depuis les briefs validés (isValidated = true).
|
|
*/
|
|
class ContentProvider implements NotificationProvider
|
|
{
|
|
public function getType(): string
|
|
{
|
|
return 'content';
|
|
}
|
|
|
|
public function collect(Page $project, User $user): array
|
|
{
|
|
$notifications = [];
|
|
$userUuid = (string) $user->uuid();
|
|
|
|
// Chercher les briefs validés (client-brief et extended-brief)
|
|
$briefTemplates = ['client-brief', 'extended-brief'];
|
|
|
|
foreach ($project->children() as $step) {
|
|
if (!in_array($step->intendedTemplate()->name(), $briefTemplates)) {
|
|
continue;
|
|
}
|
|
|
|
// Pas de notification si le brief n'est pas validé
|
|
if ($step->isValidated()->isFalse()) {
|
|
continue;
|
|
}
|
|
|
|
// Vérifier que les champs requis existent
|
|
if ($step->validatedBy()->isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
$authorUuid = $step->validatedBy()->value();
|
|
|
|
// Ne pas notifier l'auteur de sa propre validation
|
|
if ($authorUuid === $userUuid) {
|
|
continue;
|
|
}
|
|
|
|
$readby = $step->validationReadby()->isNotEmpty()
|
|
? Yaml::decode($step->validationReadby()->value())
|
|
: [];
|
|
|
|
if (!is_array($readby)) {
|
|
$readby = [];
|
|
}
|
|
|
|
$stepLabel = $step->intendedTemplate()->name() === 'client-brief'
|
|
? 'Brief client'
|
|
: 'Brief étendu';
|
|
|
|
$notifications[] = [
|
|
'id' => 'content-' . (string) $step->uuid(),
|
|
'type' => 'content',
|
|
'text' => "Nouveau $stepLabel validé",
|
|
'author' => [
|
|
'uuid' => $authorUuid,
|
|
'name' => $step->validatedByName()->value() ?? '',
|
|
'email' => $step->validatedByEmail()->value() ?? '',
|
|
'role' => 'client',
|
|
],
|
|
'date' => $step->validatedAt()->value() ?? '',
|
|
'location' => [
|
|
'page' => [
|
|
'uri' => $step->uri(),
|
|
'title' => (string) $step->title(),
|
|
'template' => $step->intendedTemplate()->name(),
|
|
],
|
|
'project' => [
|
|
'uri' => $project->uri(),
|
|
'title' => (string) $project->title(),
|
|
]
|
|
],
|
|
'readby' => $readby,
|
|
'isRead' => in_array($userUuid, $readby),
|
|
'_briefUri' => $step->uri(),
|
|
];
|
|
}
|
|
|
|
return $notifications;
|
|
}
|
|
|
|
public function markAsRead(string $id, array $location, User $user): bool
|
|
{
|
|
$briefUri = $location['_briefUri'] ?? null;
|
|
if (!$briefUri) {
|
|
return false;
|
|
}
|
|
|
|
$brief = page($briefUri);
|
|
if (!$brief) {
|
|
return false;
|
|
}
|
|
|
|
$readby = $brief->validationReadby()->isNotEmpty()
|
|
? Yaml::decode($brief->validationReadby()->value())
|
|
: [];
|
|
|
|
if (!is_array($readby)) {
|
|
$readby = [];
|
|
}
|
|
|
|
$userUuid = (string) $user->uuid();
|
|
|
|
if (in_array($userUuid, $readby)) {
|
|
return true;
|
|
}
|
|
|
|
$readby[] = $userUuid;
|
|
|
|
$brief->update([
|
|
'validationReadby' => array_unique($readby)
|
|
]);
|
|
|
|
return true;
|
|
}
|
|
}
|