designtopack/public/site/plugins/notifications/src/providers/CommentProvider.php

173 lines
6 KiB
PHP
Raw Permalink Normal View History

<?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 "comment".
* Collecte les commentaires depuis les fichiers des étapes du projet.
*/
class CommentProvider implements NotificationProvider
{
public function getType(): string
{
return 'comment';
}
public function collect(Page $project, User $user): array
{
$notifications = [];
$userUuid = (string) $user->uuid();
// Parcourir toutes les étapes du projet
foreach ($project->children() as $step) {
// Parcourir tous les fichiers de chaque étape
foreach ($step->files() as $file) {
if ($file->comments()->isEmpty()) {
continue;
}
$comments = Yaml::decode($file->comments()->value());
if (!is_array($comments)) {
continue;
}
foreach ($comments as $comment) {
// Ignorer les commentaires de type reply (gérés par ReplyProvider)
if (($comment['type'] ?? 'comment') === 'comment-reply') {
continue;
}
// Ne pas notifier l'auteur de son propre commentaire
$authorUuid = $comment['author']['uuid'] ?? '';
if ($authorUuid === $userUuid) {
continue;
}
$readby = $comment['readby'] ?? [];
$location = $comment['location'] ?? [];
// Assurer que location.project existe toujours
if (!isset($location['project'])) {
$location['project'] = [
'uri' => $project->uri(),
'title' => (string) $project->title(),
];
}
$notifications[] = [
'id' => $comment['id'],
'type' => 'comment',
'text' => $comment['text'] ?? '',
'author' => $comment['author'] ?? [],
'date' => $comment['date'] ?? '',
'location' => $location,
'position' => $comment['position'] ?? [],
'readby' => $readby,
'isRead' => in_array($userUuid, $readby),
// Métadonnées pour markAsRead
'_file' => (string) $file->uuid(),
'_stepUri' => $step->uri(),
];
}
}
// Parcourir aussi les sous-pages (ex: tracks dans virtual-sample)
foreach ($step->children() as $subPage) {
foreach ($subPage->files() as $file) {
if ($file->comments()->isEmpty()) {
continue;
}
$comments = Yaml::decode($file->comments()->value());
if (!is_array($comments)) {
continue;
}
foreach ($comments as $comment) {
if (($comment['type'] ?? 'comment') === 'comment-reply') {
continue;
}
$authorUuid = $comment['author']['uuid'] ?? '';
if ($authorUuid === $userUuid) {
continue;
}
$readby = $comment['readby'] ?? [];
$location = $comment['location'] ?? [];
// Assurer que location.project existe toujours
if (!isset($location['project'])) {
$location['project'] = [
'uri' => $project->uri(),
'title' => (string) $project->title(),
];
}
$notifications[] = [
'id' => $comment['id'],
'type' => 'comment',
'text' => $comment['text'] ?? '',
'author' => $comment['author'] ?? [],
'date' => $comment['date'] ?? '',
'location' => $location,
'position' => $comment['position'] ?? [],
'readby' => $readby,
'isRead' => in_array($userUuid, $readby),
'_file' => (string) $file->uuid(),
'_stepUri' => $subPage->uri(),
];
}
}
}
}
return $notifications;
}
public function markAsRead(string $id, array $location, User $user): bool
{
$fileUuid = $location['_file'] ?? null;
if (!$fileUuid) {
return false;
}
// Trouver le fichier par UUID (peut être avec ou sans préfixe file://)
$fileUri = str_starts_with($fileUuid, 'file://') ? $fileUuid : 'file://' . $fileUuid;
$file = kirby()->file($fileUri);
if (!$file) {
return false;
}
$comments = Yaml::decode($file->comments()->value());
if (!is_array($comments)) {
return false;
}
$userUuid = (string) $user->uuid();
$updated = false;
foreach ($comments as &$comment) {
if ($comment['id'] === $id) {
$comment['readby'] = $comment['readby'] ?? [];
if (!in_array($userUuid, $comment['readby'])) {
$comment['readby'][] = $userUuid;
$updated = true;
}
break;
}
}
if ($updated) {
$file->update(['comments' => $comments]);
}
return $updated;
}
}