ReadStatusManager::updateThreadMetaUnreadCount()   B
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 14
nc 3
nop 3
1
<?php
2
3
/*
4
 * This file is part of the MilioooMessageBundle package.
5
 *
6
 * (c) Michiel boeckaert <[email protected]>
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Miliooo\Messaging\Manager;
12
13
use Miliooo\Messaging\Repository\MessageRepositoryInterface;
14
use Miliooo\Messaging\Model\MessageInterface;
15
use Miliooo\Messaging\User\ParticipantInterface;
16
use Miliooo\Messaging\ValueObjects\ReadStatus;
17
use Miliooo\Messaging\Model\MessageMetaInterface;
18
19
/**
20
 * The read status manager is responsible for changing the read statuses of messages.
21
 *
22
 * @author Michiel Boeckaert <[email protected]>
23
 */
24
class ReadStatusManager implements ReadStatusManagerInterface
25
{
26
    /**
27
     * A message repository instance.
28
     *
29
     * @var MessageRepositoryInterface
30
     */
31
    protected $messageRepository;
32
33
    /**
34
     * Helper to only flush once.
35
     *
36
     * If there are updates this becomes true so we know we need to flush.
37
     * @var boolean defaults to false
38
     */
39
    private $needsUpdate = false;
40
41
    private $updatedMessages = [];
42
43
    /**
44
     * Constructor.
45
     *
46
     * @param MessageRepositoryInterface $messageRepository
47
     */
48
    public function __construct(MessageRepositoryInterface $messageRepository)
49
    {
50
        $this->messageRepository = $messageRepository;
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function updateReadStatusForMessageCollection(
57
        ReadStatus $updatedReadStatus,
58
        ParticipantInterface $participant,
59
        $messages = []
60
    ) {
61
        foreach ($messages as $message) {
62
            $updated = $this->maybeMarkMessageAs($updatedReadStatus, $participant, $message);
63
64
            if ($updated) {
65
                $this->messageRepository->save($message, false);
66
                $this->needsUpdate = true;
67
                $this->updatedMessages[] = $message;
68
            }
69
        }
70
        //helper to only flush once
71
        //if one message is updated the needsUpdate gets set to true, so we know we need to flush after the loop
72
        $this->maybeFlush();
73
74
        return $this->updatedMessages;
75
    }
76
77
    /**
78
     * Updates a message read status to a new read status.
79
     *
80
     * This function is protected because it does not persist the message.
81
     * We only want to flush once so this is just a helper function for updateReadStatusForMessageCollection
82
     *
83
     * @param ReadStatus           $newReadStatus The new read status
84
     * @param ParticipantInterface $participant   The participant where we check the read status for
85
     * @param MessageInterface     $message       The message where we check the read status for
86
     *
87
     * @throws \InvalidArgumentException When no message meta found for given participant
88
     *
89
     * @return boolean true if the message has been updated, false otherwise
90
     */
91
    protected function maybeMarkMessageAs(
92
        ReadStatus $newReadStatus,
93
        ParticipantInterface $participant,
94
        MessageInterface $message
95
    ) {
96
        $readStatusValue = $newReadStatus->getReadStatus();
97
        $messageMeta = $message->getMessageMetaForParticipant($participant);
98
99
        //if no message meta can happen if the logged in user is not participant of the thread
100
        if ($messageMeta === null || $messageMeta->getReadStatus() === $readStatusValue) {
101
            return false;
102
        }
103
                $messageMeta->setReadStatus($newReadStatus);
104
                $this->updateThreadMetaUnreadCount($message, $participant, $newReadStatus);
105
106
            return true;
107
    }
108
109
    /**
110
     * Helper function to only flush once
111
     */
112
    protected function maybeFlush()
113
    {
114
        if ($this->needsUpdate) {
115
            $this->messageRepository->flush();
116
            $this->needsUpdate = false;
117
        }
118
    }
119
120
121
    /**
122
     * Updates the thread meta unread count for the participant.
123
     *
124
     * @param MessageInterface     $message
125
     * @param ParticipantInterface $participant
126
     * @param ReadStatus           $newReadStatus
127
     */
128
    protected function updateThreadMetaUnreadCount(
129
        MessageInterface $message,
130
        ParticipantInterface $participant,
131
        ReadStatus $newReadStatus
132
    ) {
133
        //get the thread
134
        $thread = $message->getThread();
135
136
        //get the thread meta for the participant
137
        $threadMeta = $thread->getThreadMetaForParticipant($participant);
138
        //return if no thread meta, should not happen
139
        if (!$threadMeta) {
140
            return;
141
        }
142
143
        // gets the integer of the number of unread messages
144
        $unreadCount = $threadMeta->getUnreadMessageCount();
145
146
        //we marked a message as read so we lower the unread count with one
147
        if ($newReadStatus->getReadStatus() === MessageMetaInterface::READ_STATUS_READ) {
148
            $newUnreadCount = --$unreadCount;
149
        } else {
150
            $newUnreadCount = ++$unreadCount;
151
        }
152
153
        $threadMeta->setUnreadMessageCount($newUnreadCount);
154
    }
155
}
156