Skip to content

Commit 0f22de4

Browse files
committed
Merge pull request #110 from Kenny11CZ/master
Added functions for unread messages in thread model
2 parents a257f3e + b8113ff commit 0f22de4

File tree

2 files changed

+168
-14
lines changed

2 files changed

+168
-14
lines changed

src/Cmgmyr/Messenger/Models/Thread.php

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public static function getAllLatest()
9696
* Returns an array of user ids that are associated with the thread.
9797
*
9898
* @param null $userId
99+
*
99100
* @return array
100101
*/
101102
public function participantsUserIds($userId = null)
@@ -114,13 +115,15 @@ public function participantsUserIds($userId = null)
114115
*
115116
* @param $query
116117
* @param $userId
118+
*
117119
* @return mixed
118120
*/
119121
public function scopeForUser($query, $userId)
120122
{
121123
$participantsTable = Models::table('participants');
122124
$threadsTable = Models::table('threads');
123125

126+
124127
return $query->join($participantsTable, $this->getQualifiedKeyName(), '=', $participantsTable . '.thread_id')
125128
->where($participantsTable . '.user_id', $userId)
126129
->where($participantsTable . '.deleted_at', null)
@@ -132,6 +135,7 @@ public function scopeForUser($query, $userId)
132135
*
133136
* @param $query
134137
* @param $userId
138+
*
135139
* @return mixed
136140
*/
137141
public function scopeForUserWithNewMessages($query, $userId)
@@ -154,22 +158,22 @@ public function scopeForUserWithNewMessages($query, $userId)
154158
*
155159
* @param $query
156160
* @param $participants
161+
*
157162
* @return mixed
158163
*/
159164
public function scopeBetween($query, array $participants)
160165
{
161166
$query->whereHas('participants', function ($query) use ($participants) {
162167
$query->whereIn('user_id', $participants)
163168
->groupBy('thread_id')
164-
->havingRaw('COUNT(thread_id)=' . count($participants));
169+
->havingRaw('COUNT(thread_id)='.count($participants));
165170
});
166171
}
167172

168173
/**
169174
* Adds users to this thread.
170175
*
171176
* @param array $participants list of all participants
172-
* @return void
173177
*/
174178
public function addParticipants(array $participants)
175179
{
@@ -186,13 +190,13 @@ public function addParticipants(array $participants)
186190
/**
187191
* Mark a thread as read for a user.
188192
*
189-
* @param integer $userId
193+
* @param int $userId
190194
*/
191195
public function markAsRead($userId)
192196
{
193197
try {
194198
$participant = $this->getParticipantFromUser($userId);
195-
$participant->last_read = new Carbon;
199+
$participant->last_read = new Carbon();
196200
$participant->save();
197201
} catch (ModelNotFoundException $e) {
198202
// do nothing
@@ -202,7 +206,8 @@ public function markAsRead($userId)
202206
/**
203207
* See if the current thread is unread by the user.
204208
*
205-
* @param integer $userId
209+
* @param int $userId
210+
*
206211
* @return bool
207212
*/
208213
public function isUnread($userId)
@@ -223,7 +228,9 @@ public function isUnread($userId)
223228
* Finds the participant record from a user id.
224229
*
225230
* @param $userId
231+
*
226232
* @return mixed
233+
*
227234
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
228235
*/
229236
public function getParticipantFromUser($userId)
@@ -245,8 +252,9 @@ public function activateAllParticipants()
245252
/**
246253
* Generates a string of participant information.
247254
*
248-
* @param null $userId
255+
* @param null $userId
249256
* @param array $columns
257+
*
250258
* @return string
251259
*/
252260
public function participantsString($userId = null, $columns = ['name'])
@@ -262,10 +270,10 @@ public function participantsString($userId = null, $columns = ['name'])
262270
->select($this->getConnection()->raw($selectString));
263271

264272
if ($userId !== null) {
265-
$participantNames->where($usersTable . '.id', '!=', $userId);
273+
$participantNames->where($usersTable.'.id', '!=', $userId);
266274
}
267275

268-
$userNames = $participantNames->lists($usersTable . '.name');
276+
$userNames = $participantNames->lists($usersTable.'.name');
269277

270278
return implode(', ', $userNames);
271279
}
@@ -274,6 +282,7 @@ public function participantsString($userId = null, $columns = ['name'])
274282
* Checks to see if a user is a current participant of the thread.
275283
*
276284
* @param $userId
285+
*
277286
* @return bool
278287
*/
279288
public function hasParticipant($userId)
@@ -290,6 +299,7 @@ public function hasParticipant($userId)
290299
* Generates a select string used in participantsString().
291300
*
292301
* @param $columns
302+
*
293303
* @return string
294304
*/
295305
protected function createSelectString($columns)
@@ -301,18 +311,105 @@ protected function createSelectString($columns)
301311
switch ($dbDriver) {
302312
case 'pgsql':
303313
case 'sqlite':
304-
$columnString = implode(" || ' ' || " . $tablePrefix . $usersTable . '.', $columns);
305-
$selectString = '(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
314+
$columnString = implode(" || ' ' || ".$tablePrefix.$usersTable.'.', $columns);
315+
$selectString = '('.$tablePrefix.$usersTable.'.'.$columnString.') as name';
306316
break;
307317
case 'sqlsrv':
308-
$columnString = implode(" + ' ' + " . $tablePrefix . $usersTable . '.', $columns);
309-
$selectString = '(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
318+
$columnString = implode(" + ' ' + ".$tablePrefix.$usersTable.'.', $columns);
319+
$selectString = '('.$tablePrefix.$usersTable.'.'.$columnString.') as name';
310320
break;
311321
default:
312-
$columnString = implode(", ' ', " . $tablePrefix . $usersTable . '.', $columns);
313-
$selectString = 'concat(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
322+
$columnString = implode(", ' ', ".$tablePrefix.$usersTable.'.', $columns);
323+
$selectString = 'concat('.$tablePrefix.$usersTable.'.'.$columnString.') as name';
314324
}
315325

316326
return $selectString;
317327
}
328+
/**
329+
* Returns array of unread messages in thread for given user.
330+
*
331+
* @param $user_id
332+
*
333+
* @return array
334+
*/
335+
public function userUnreadMessages($user_id)
336+
{
337+
$messages = $this->messages()->get();
338+
$participant = $this->getParticipantFromUser($user_id);
339+
if (!$participant) {
340+
return [];
341+
}
342+
$unread = array();
343+
$i = count($messages) - 1;
344+
while ($i) {
345+
if ($messages[$i]->updated_at->gt($participant->last_read)) {
346+
array_push($unread, $messages[$i]);
347+
} else {
348+
break;
349+
}
350+
--$i;
351+
}
352+
353+
return $unread;
354+
}
355+
356+
/**
357+
* Returns count of unread messages in thread for given user.
358+
*
359+
* @param $user_id
360+
*
361+
* @return int
362+
*/
363+
public function userUnreadMessagesCount($user_id)
364+
{
365+
$messages = $this->messages()->get();
366+
$participant = $this->getParticipantFromUser($user_id);
367+
if (!$participant) {
368+
return 0;
369+
}
370+
$count = 0;
371+
$i = count($messages) - 1;
372+
while ($i) {
373+
if ($messages[$i]->updated_at->gt($participant->last_read)) {
374+
++$count;
375+
} else {
376+
break;
377+
}
378+
--$i;
379+
}
380+
381+
return $count;
382+
}
383+
384+
/**
385+
* Returns the "participant" table name to use in manual queries.
386+
*
387+
* @return string
388+
*/
389+
private function getParticipantTable()
390+
{
391+
if ($this->participantTable !== null) {
392+
return $this->participantTable;
393+
}
394+
395+
$participantModel = Config::get('messenger.participant_model');
396+
397+
return $this->participantTable = (new $participantModel())->getTable();
398+
}
399+
400+
/**
401+
* Returns the "users" table name to use in manual queries.
402+
*
403+
* @return string
404+
*/
405+
private function getUsersTable()
406+
{
407+
if ($this->usersTable !== null) {
408+
return $this->usersTable;
409+
}
410+
411+
$userModel = Config::get('messenger.user_model');
412+
413+
return $this->usersTable = (new $userModel())->getTable();
414+
}
318415
}

tests/EloquentThreadTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,61 @@ public function it_should_check_users_and_participants()
285285
$this->assertTrue($thread->hasParticipant(2));
286286
$this->assertFalse($thread->hasParticipant(3));
287287
}
288+
289+
public function it_should_get_all_unread_messages_for_user()
290+
{
291+
$thread = $this->faktory->create('thread');
292+
293+
$participant_1 = $this->faktory->build('participant');
294+
$participant_2 = $this->faktory->build('participant', ['user_id' => 2]);
295+
296+
$message_1 = $this->faktory->build('message', [
297+
'created_at' => Carbon::now(),
298+
'body' => "Message 1",
299+
]);
300+
301+
302+
$thread->participants()->saveMany([$participant_1, $participant_2]);
303+
$thread->messages()->saveMany([$message_1]);
304+
305+
$thread->markAsRead($participant_2->user_id);
306+
307+
$message_2 = $this->faktory->build('message', [
308+
'created_at' => Carbon::now(),
309+
'body' => "Message 2",
310+
]);
311+
312+
$thread->messages()->saveMany([$message_2]);
313+
314+
$this->assertEquals("Message 2", $thread->userUnreadMessages(2)->first()->body);
315+
$this->assertCount(1, $thread->userUnreadMessages(2)->count());
316+
}
317+
318+
public function it_should_get_count_of_all_unread_messages_for_user()
319+
{
320+
$thread = $this->faktory->create('thread');
321+
322+
$participant_1 = $this->faktory->build('participant');
323+
$participant_2 = $this->faktory->build('participant', ['user_id' => 2]);
324+
325+
$message_1 = $this->faktory->build('message', [
326+
'created_at' => Carbon::now(),
327+
'body' => "Message 1",
328+
]);
329+
330+
331+
$thread->participants()->saveMany([$participant_1, $participant_2]);
332+
$thread->messages()->saveMany([$message_1]);
333+
334+
$thread->markAsRead($participant_2->user_id);
335+
336+
$message_2 = $this->faktory->build('message', [
337+
'created_at' => Carbon::now(),
338+
'body' => "Message 2",
339+
]);
340+
341+
$thread->messages()->saveMany([$message_2]);
342+
343+
$this->assertEquals(1, $thread->userUnreadMessagesCount(2));
344+
}
288345
}

0 commit comments

Comments
 (0)