Passed
Push — develop ( ef53f3...80bc53 )
by BENARD
08:34
created

MarkAsRead   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 49
c 0
b 0
f 0
dl 0
loc 81
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A __invoke() 0 69 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProjetNormandie\ForumBundle\Controller\Forum;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use ProjetNormandie\ForumBundle\Entity\Forum;
9
use ProjetNormandie\ForumBundle\Entity\ForumUserLastVisit;
10
use ProjetNormandie\ForumBundle\Entity\TopicUserLastVisit;
11
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
14
class MarkAsRead extends AbstractController
15
{
16
    private EntityManagerInterface $em;
17
18
    public function __construct(EntityManagerInterface $em)
19
    {
20
        $this->em = $em;
21
    }
22
23
    /**
24
     * Marque un forum spécifique et tous ses topics comme lus
25
     */
26
    public function __invoke(Forum $forum): JsonResponse
27
    {
28
        $user = $this->getUser();
29
        $now = new \DateTime();
30
31
        try {
32
            $this->em->beginTransaction();
33
34
            // 1. Mettre à jour ou créer la visite du forum
35
            $forumVisit = $this->em->getRepository(ForumUserLastVisit::class)
36
                ->findOneBy(['user' => $user, 'forum' => $forum]);
37
38
            if ($forumVisit) {
39
                $forumVisit->setLastVisitedAt($now);
40
            } else {
41
                $forumVisit = new ForumUserLastVisit();
42
                $forumVisit->setUser($user);
43
                $forumVisit->setForum($forum);
44
                $forumVisit->setLastVisitedAt($now);
45
                $this->em->persist($forumVisit);
46
            }
47
48
            // 2. Mettre à jour toutes les visites existantes de topics de ce forum
49
            $this->em->createQueryBuilder()
50
                ->update('ProjetNormandie\ForumBundle\Entity\TopicUserLastVisit', 'tuv')
51
                ->set('tuv.lastVisitedAt', ':now')
52
                ->where('tuv.user = :user')
53
                ->andWhere('tuv.topic IN (
54
                    SELECT t.id FROM ProjetNormandie\ForumBundle\Entity\Topic t 
55
                    WHERE t.forum = :forum
56
                )')
57
                ->setParameter('now', $now)
58
                ->setParameter('user', $user)
59
                ->setParameter('forum', $forum)
60
                ->getQuery()
61
                ->execute();
62
63
            // 3. Créer des visites pour les topics de ce forum jamais visités qui ont des messages
64
            $topicsNeverVisited = $this->em->createQueryBuilder()
65
                ->select('t')
66
                ->from('ProjetNormandie\ForumBundle\Entity\Topic', 't')
67
                ->where('t.forum = :forum')
68
                ->andWhere('t.lastMessage IS NOT NULL')
69
                ->andWhere('t.id NOT IN (
70
                    SELECT IDENTITY(tuv.topic) 
71
                    FROM ProjetNormandie\ForumBundle\Entity\TopicUserLastVisit tuv 
72
                    WHERE tuv.user = :user
73
                )')
74
                ->setParameter('forum', $forum)
75
                ->setParameter('user', $user)
76
                ->getQuery()
77
                ->getResult();
78
79
            foreach ($topicsNeverVisited as $topic) {
80
                $visit = new TopicUserLastVisit();
81
                $visit->setUser($user);
82
                $visit->setTopic($topic);
83
                $visit->setLastVisitedAt($now);
84
                $this->em->persist($visit);
85
            }
86
87
            $this->em->flush();
88
            $this->em->commit();
89
90
            return new JsonResponse(['success' => true]);
91
92
        } catch (\Exception $e) {
93
            $this->em->rollback();
94
            return new JsonResponse(['success' => false, 'error' => $e->getMessage()], 500);
95
        }
96
    }
97
}
98