Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added two functions for unread messages in thread #110

Merged
merged 5 commits into from
Feb 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 111 additions & 14 deletions src/Cmgmyr/Messenger/Models/Thread.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public static function getAllLatest()
* Returns an array of user ids that are associated with the thread.
*
* @param null $userId
*
* @return array
*/
public function participantsUserIds($userId = null)
Expand All @@ -114,13 +115,15 @@ public function participantsUserIds($userId = null)
*
* @param $query
* @param $userId
*
* @return mixed
*/
public function scopeForUser($query, $userId)
{
$participantsTable = Models::table('participants');
$threadsTable = Models::table('threads');


return $query->join($participantsTable, $this->getQualifiedKeyName(), '=', $participantsTable . '.thread_id')
->where($participantsTable . '.user_id', $userId)
->where($participantsTable . '.deleted_at', null)
Expand All @@ -132,6 +135,7 @@ public function scopeForUser($query, $userId)
*
* @param $query
* @param $userId
*
* @return mixed
*/
public function scopeForUserWithNewMessages($query, $userId)
Expand All @@ -154,22 +158,22 @@ public function scopeForUserWithNewMessages($query, $userId)
*
* @param $query
* @param $participants
*
* @return mixed
*/
public function scopeBetween($query, array $participants)
{
$query->whereHas('participants', function ($query) use ($participants) {
$query->whereIn('user_id', $participants)
->groupBy('thread_id')
->havingRaw('COUNT(thread_id)=' . count($participants));
->havingRaw('COUNT(thread_id)='.count($participants));
});
}

/**
* Adds users to this thread.
*
* @param array $participants list of all participants
* @return void
*/
public function addParticipants(array $participants)
{
Expand All @@ -186,13 +190,13 @@ public function addParticipants(array $participants)
/**
* Mark a thread as read for a user.
*
* @param integer $userId
* @param int $userId
*/
public function markAsRead($userId)
{
try {
$participant = $this->getParticipantFromUser($userId);
$participant->last_read = new Carbon;
$participant->last_read = new Carbon();
$participant->save();
} catch (ModelNotFoundException $e) {
// do nothing
Expand All @@ -202,7 +206,8 @@ public function markAsRead($userId)
/**
* See if the current thread is unread by the user.
*
* @param integer $userId
* @param int $userId
*
* @return bool
*/
public function isUnread($userId)
Expand All @@ -223,7 +228,9 @@ public function isUnread($userId)
* Finds the participant record from a user id.
*
* @param $userId
*
* @return mixed
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function getParticipantFromUser($userId)
Expand All @@ -245,8 +252,9 @@ public function activateAllParticipants()
/**
* Generates a string of participant information.
*
* @param null $userId
* @param null $userId
* @param array $columns
*
* @return string
*/
public function participantsString($userId = null, $columns = ['name'])
Expand All @@ -262,10 +270,10 @@ public function participantsString($userId = null, $columns = ['name'])
->select($this->getConnection()->raw($selectString));

if ($userId !== null) {
$participantNames->where($usersTable . '.id', '!=', $userId);
$participantNames->where($usersTable.'.id', '!=', $userId);
}

$userNames = $participantNames->lists($usersTable . '.name');
$userNames = $participantNames->lists($usersTable.'.name');

return implode(', ', $userNames);
}
Expand All @@ -274,6 +282,7 @@ public function participantsString($userId = null, $columns = ['name'])
* Checks to see if a user is a current participant of the thread.
*
* @param $userId
*
* @return bool
*/
public function hasParticipant($userId)
Expand All @@ -290,6 +299,7 @@ public function hasParticipant($userId)
* Generates a select string used in participantsString().
*
* @param $columns
*
* @return string
*/
protected function createSelectString($columns)
Expand All @@ -301,18 +311,105 @@ protected function createSelectString($columns)
switch ($dbDriver) {
case 'pgsql':
case 'sqlite':
$columnString = implode(" || ' ' || " . $tablePrefix . $usersTable . '.', $columns);
$selectString = '(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
$columnString = implode(" || ' ' || ".$tablePrefix.$usersTable.'.', $columns);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line indented incorrectly; expected at least 16 spaces, found 12

$selectString = '('.$tablePrefix.$usersTable.'.'.$columnString.') as name';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line indented incorrectly; expected at least 16 spaces, found 12

break;
case 'sqlsrv':
$columnString = implode(" + ' ' + " . $tablePrefix . $usersTable . '.', $columns);
$selectString = '(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
$columnString = implode(" + ' ' + ".$tablePrefix.$usersTable.'.', $columns);
$selectString = '('.$tablePrefix.$usersTable.'.'.$columnString.') as name';
break;
default:
$columnString = implode(", ' ', " . $tablePrefix . $usersTable . '.', $columns);
$selectString = 'concat(' . $tablePrefix . $usersTable . '.' . $columnString . ') as name';
$columnString = implode(", ' ', ".$tablePrefix.$usersTable.'.', $columns);
$selectString = 'concat('.$tablePrefix.$usersTable.'.'.$columnString.') as name';
}

return $selectString;
}
/**
* Returns array of unread messages in thread for given user.
*
* @param $user_id
*
* @return array
*/
public function userUnreadMessages($user_id)
{
$messages = $this->messages()->get();
$participant = $this->getParticipantFromUser($user_id);
if (!$participant) {
return [];
}
$unread = array();
$i = count($messages) - 1;
while ($i) {
if ($messages[$i]->updated_at->gt($participant->last_read)) {
array_push($unread, $messages[$i]);
} else {
break;
}
--$i;
}

return $unread;
}

/**
* Returns count of unread messages in thread for given user.
*
* @param $user_id
*
* @return int
*/
public function userUnreadMessagesCount($user_id)
{
$messages = $this->messages()->get();
$participant = $this->getParticipantFromUser($user_id);
if (!$participant) {
return 0;
}
$count = 0;
$i = count($messages) - 1;
while ($i) {
if ($messages[$i]->updated_at->gt($participant->last_read)) {
++$count;
} else {
break;
}
--$i;
}

return $count;
}

/**
* Returns the "participant" table name to use in manual queries.
*
* @return string
*/
private function getParticipantTable()
{
if ($this->participantTable !== null) {
return $this->participantTable;
}

$participantModel = Config::get('messenger.participant_model');

return $this->participantTable = (new $participantModel())->getTable();
}

/**
* Returns the "users" table name to use in manual queries.
*
* @return string
*/
private function getUsersTable()
{
if ($this->usersTable !== null) {
return $this->usersTable;
}

$userModel = Config::get('messenger.user_model');

return $this->usersTable = (new $userModel())->getTable();
}
}
57 changes: 57 additions & 0 deletions tests/EloquentThreadTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,61 @@ public function it_should_check_users_and_participants()
$this->assertTrue($thread->hasParticipant(2));
$this->assertFalse($thread->hasParticipant(3));
}

public function it_should_get_all_unread_messages_for_user()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method name EloquentThreadTest::it_should_get_all_unread_messages_for_user is not in camel caps format

{
$thread = $this->faktory->create('thread');

$participant_1 = $this->faktory->build('participant');
$participant_2 = $this->faktory->build('participant', ['user_id' => 2]);

$message_1 = $this->faktory->build('message', [
'created_at' => Carbon::now(),
'body' => "Message 1",
]);


$thread->participants()->saveMany([$participant_1, $participant_2]);
$thread->messages()->saveMany([$message_1]);

$thread->markAsRead($participant_2->user_id);

$message_2 = $this->faktory->build('message', [
'created_at' => Carbon::now(),
'body' => "Message 2",
]);

$thread->messages()->saveMany([$message_2]);

$this->assertEquals("Message 2", $thread->userUnreadMessages(2)->first()->body);
$this->assertCount(1, $thread->userUnreadMessages(2)->count());
}

public function it_should_get_count_of_all_unread_messages_for_user()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method name EloquentThreadTest::it_should_get_count_of_all_unread_messages_for_user is not in camel caps format

{
$thread = $this->faktory->create('thread');

$participant_1 = $this->faktory->build('participant');
$participant_2 = $this->faktory->build('participant', ['user_id' => 2]);

$message_1 = $this->faktory->build('message', [
'created_at' => Carbon::now(),
'body' => "Message 1",
]);


$thread->participants()->saveMany([$participant_1, $participant_2]);
$thread->messages()->saveMany([$message_1]);

$thread->markAsRead($participant_2->user_id);

$message_2 = $this->faktory->build('message', [
'created_at' => Carbon::now(),
'body' => "Message 2",
]);

$thread->messages()->saveMany([$message_2]);

$this->assertEquals(1, $thread->userUnreadMessagesCount(2));
}
}