From dc05f4a95fd01c2c7363cb19ad183593823cce82 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:44:57 +0100 Subject: [PATCH 1/8] Updating .gitignore & .gitattributes --- .gitattributes | 2 ++ .gitignore | 7 ++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitattributes b/.gitattributes index feb4c02..a1bf466 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,6 @@ +/_docs export-ignore /tests export-ignore +/.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.scrutinizer.yml export-ignore diff --git a/.gitignore b/.gitignore index 5afd7ba..cb1299f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ -/.idea/ -/_arcanedev/ /build/ -/storage/ /vendor/ -composer.phar -composer.lock +/composer.lock +/composer.phar From 4478daf3871a3f7ebb5359bb84c936c9728de441 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:52:10 +0100 Subject: [PATCH 2/8] Updating Travis CI and Scrutinizer config files --- .scrutinizer.yml | 4 ++-- .travis.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index bf778c9..14f267b 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -22,8 +22,8 @@ checks: tools: external_code_coverage: - timeout: 600 - runs: 8 + timeout: 900 + runs: 9 php_code_sniffer: enabled: true config: diff --git a/.travis.yml b/.travis.yml index 4ef332b..33c2196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,9 @@ language: php sudo: false php: - - 5.5.9 - - 5.5 - 5.6 - 7.0 + - 7.1 - nightly - hhvm @@ -17,6 +16,7 @@ matrix: env: - TESTBENCH_VERSION=3.1.* - TESTBENCH_VERSION=3.2.* + - TESTBENCH_VERSION=3.3.* before_script: - travis_retry composer self-update From b35fd6e14c3bec7bd456317fee5aee0b83a3c4ce Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:54:24 +0100 Subject: [PATCH 3/8] Updating the Discussion Model --- src/Models/Discussion.php | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Models/Discussion.php b/src/Models/Discussion.php index c202335..a0665ac 100644 --- a/src/Models/Discussion.php +++ b/src/Models/Discussion.php @@ -4,6 +4,7 @@ use Arcanedev\LaravelMessenger\Contracts\Discussion as DiscussionContract; use Arcanedev\LaravelMessenger\Contracts\Message as MessageContract; use Arcanedev\LaravelMessenger\Contracts\Participant as ParticipantContract; +use Arcanedev\Support\Collection as ArcanedevCollection; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletes; @@ -260,14 +261,19 @@ public static function getBySubject($subject, $strict = false) * * @param int|null $userId * - * @return \Illuminate\Support\Collection + * @return \Arcanedev\Support\Collection */ public function participantsUserIds($userId = null) { /** @var \Illuminate\Support\Collection $usersIds */ - $usersIds = $this->participants()->withTrashed()->lists('user_id'); + $usersIds = $this->participants()->withTrashed()->get() + ->map(function (ParticipantContract $participant) { + return $participant->user_id; + }); + + if ($userId !== null) $usersIds->push($userId); - return $usersIds->push($userId)->filter()->unique(); + return ArcanedevCollection::make($usersIds)->unique(); } /** @@ -390,9 +396,7 @@ public function getParticipantByUserId($userId) */ public function getTrashedParticipants() { - return $this->participants() - ->onlyTrashed() - ->get(); + return $this->participants()->onlyTrashed()->get(); } /** @@ -404,10 +408,11 @@ public function getTrashedParticipants() */ public function restoreAllParticipants($reload = true) { - $participants = $this->getTrashedParticipants(); - $restored = $participants->filter(function (ParticipantContract $participant) { - return $participant->restore(); - })->count(); + $restored = $this->getTrashedParticipants() + ->filter(function (ParticipantContract $participant) { + return $participant->restore(); + }) + ->count(); if ($reload) $this->load(['participants']); @@ -435,9 +440,11 @@ public function participantsString($ignoredUserId = null, $callback = null, $glu }; } - return $participants->filter(function (ParticipantContract $participant) use ($ignoredUserId) { + $participants = $participants->filter(function (ParticipantContract $participant) use ($ignoredUserId) { return $participant->user_id !== $ignoredUserId; - })->map($callback)->implode($glue); + })->map($callback); + + return $participants->implode($glue); } /** From 88d365345d627a7fdac69f5180c3098a69db2281 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:54:38 +0100 Subject: [PATCH 4/8] Updating the Messagable Trait --- src/Traits/Messagable.php | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/Traits/Messagable.php b/src/Traits/Messagable.php index 2b5b95c..8651648 100644 --- a/src/Traits/Messagable.php +++ b/src/Traits/Messagable.php @@ -3,6 +3,7 @@ use Arcanedev\LaravelMessenger\Contracts\Discussion as DiscussionContract; use Arcanedev\LaravelMessenger\Contracts\Participant as ParticipantContract; use Arcanedev\LaravelMessenger\Models; +use Illuminate\Database\Eloquent\Builder; /** * Trait Messagable @@ -77,32 +78,25 @@ public function messages() */ public function newMessagesCount() { - return count($this->discussionsWithNewMessages()); + return $this->discussionsWithNewMessages()->count(); } /** * Returns all discussions IDs with new messages. * - * @return array + * @return \Illuminate\Database\Eloquent\Collection */ public function discussionsWithNewMessages() { - /** @var \Illuminate\Database\Eloquent\Collection $participants */ - $participants = app(ParticipantContract::class) - ->where('user_id', $this->id) - ->get() - ->pluck('last_read', 'discussion_id'); + $participantsTable = $this->getTableFromConfig('participants', 'participants'); + $discussionsTable = $this->getTableFromConfig('discussions', 'discussions'); - if ($participants->isEmpty()) return []; - - /** @var \Illuminate\Database\Eloquent\Collection $discussions */ - $discussions = app(DiscussionContract::class) - ->whereIn('id', $participants->keys()->toArray()) - ->get(); - - return $discussions->filter(function (Models\Discussion $discussion) use ($participants) { - return $discussion->updated_at > $participants->get($discussion->id); - })->pluck('id')->toArray(); + return $this->discussions()->where(function (Builder $query) use ($participantsTable, $discussionsTable) { + $query->whereNull("$participantsTable.last_read"); + $query->orWhere( + "$discussionsTable.updated_at", '>', $this->getConnection()->raw("$participantsTable.last_read") + ); + })->get(); } /* ------------------------------------------------------------------------------------------------ From 6d53528fb4f189693a9399545b7e76d66798f7b5 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:54:49 +0100 Subject: [PATCH 5/8] Fixing the tests --- tests/Traits/MessagableTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Traits/MessagableTest.php b/tests/Traits/MessagableTest.php index 87999e1..fed6fe6 100644 --- a/tests/Traits/MessagableTest.php +++ b/tests/Traits/MessagableTest.php @@ -50,7 +50,7 @@ public function it_should_get_all_discussions_with_new_messages() $discussions = $user->discussionsWithNewMessages(); - $this->assertSame(1, $discussions[0]); + $this->assertSame(1, $discussions->first()->id); $this->assertSame(1, $user->newMessagesCount()); } From 6c6d4470d70f18a9ec4750a6dd2b3bcaf16efc32 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:55:01 +0100 Subject: [PATCH 6/8] Updating composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a9a4228..a4674e9 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "type": "library", "license": "MIT", "require": { - "php": ">=5.5.9", + "php": ">=5.6", "arcanedev/support": "~3.0" }, "require-dev": { From 6093e4104d69409f30435cd4ecf05d1e568339f6 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sun, 4 Sep 2016 21:55:27 +0100 Subject: [PATCH 7/8] Updating README.md and docs --- README.md | 5 +- _docs/0.Home.md | 2 +- _docs/1.Requirements.md | 2 +- _docs/4.Usage.md | 416 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 418 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 13afbd8..90f35be 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ This Laravel Messenger will allow you to add a messaging system into your Larave * Easy setup & configuration. * Well documented & IDE Friendly. * Well tested with maximum code quality. - * Laravel `5.1 | 5.2` are supported. + * Laravel `5.1 | 5.2 | 5.3` are supported. * Made with :heart: & :coffee:. ## Table of contents @@ -36,7 +36,6 @@ This Laravel Messenger will allow you to add a messaging system into your Larave ## TODOS - [ ] Documentation. - - [ ] Laravel 5.3 support. ## Contribution @@ -52,7 +51,7 @@ If you discover any security related issues, please email arcanedev.maroc@gmail. - [All Contributors][link-contributors] - [cmgmyr/laravel-messenger](https://github.com/cmgmyr/laravel-messenger) -[badge_laravel]: https://img.shields.io/badge/For-Laravel%205.1|5.2-orange.svg?style=flat-square +[badge_laravel]: https://img.shields.io/badge/For-Laravel%205.1|5.2|5.3-orange.svg?style=flat-square [badge_license]: https://img.shields.io/packagist/l/arcanedev/laravel-messenger.svg?style=flat-square [badge_build]: https://img.shields.io/travis/ARCANEDEV/LaravelMessenger.svg?style=flat-square [badge_hhvm]: https://img.shields.io/hhvm/arcanedev/laravel-messenger.svg?style=flat-square diff --git a/_docs/0.Home.md b/_docs/0.Home.md index 23de3e5..80f4804 100644 --- a/_docs/0.Home.md +++ b/_docs/0.Home.md @@ -8,7 +8,7 @@ This Laravel Messenger will allow you to add a messaging system into your Larave * Easy setup & configuration. * Well documented & IDE Friendly. * Well tested with maximum code quality. - * Laravel `5.1 | 5.2` are supported. + * Laravel `5.1 | 5.2 | 5.3` are supported. * Made with :heart: & :coffee:. ## Table of contents diff --git a/_docs/1.Requirements.md b/_docs/1.Requirements.md index e5cf2c7..f384322 100644 --- a/_docs/1.Requirements.md +++ b/_docs/1.Requirements.md @@ -13,5 +13,5 @@ The Laravel Messenger package has a few system requirements: ``` -- PHP >= 5.5.9 +- PHP >= 5.6 ``` diff --git a/_docs/4.Usage.md b/_docs/4.Usage.md index 8c1cbea..37e1129 100644 --- a/_docs/4.Usage.md +++ b/_docs/4.Usage.md @@ -6,6 +6,418 @@ 1. [Requirements](1-Requirements.md) 2. [Installation and Setup](2-Installation-and-Setup.md) 3. [Configuration](3-Configuration.md) - 4. [Usage](4-Usage.md) + 4. [Usage](4-Usage.md) -### Coming Soon… +After publishing the package files, you need to update first the `config/laravel-messenger.php` config file to reference your User Model. + +Don't forget to create a `users` table if you do not have one already. + +Now you can run the `php artisan migrate` command to your database. + +And add the `Arcanedev\LaravelMessenger\Traits\Messagable` trait to your `User` model like this: + +```php + + * + * @property int id + * @property string subject + * @property \Carbon\Carbon created_at + * @property \Carbon\Carbon updated_at + * @property \Carbon\Carbon deleted_at + * + * @property \Illuminate\Database\Eloquent\Model creator + * @property \Illuminate\Database\Eloquent\Collection messages + * @property \Illuminate\Database\Eloquent\Collection participants + * @property \Arcanedev\LaravelMessenger\Models\Message latest_message + * + * @method static \Illuminate\Database\Eloquent\Builder subject(string $subject, bool $strict) + * @method static \Illuminate\Database\Eloquent\Builder between(array $usersIds) + * @method static \Illuminate\Database\Eloquent\Builder forUser(int $userId) + * @method static \Illuminate\Database\Eloquent\Builder forUserWithNewMessages(int $userId) + */ +interface Discussion +{ + /* ------------------------------------------------------------------------------------------------ + | Relationships + | ------------------------------------------------------------------------------------------------ + */ + /** + * Participants relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function participants(); + + /** + * Messages relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function messages(); + + /** + * Get the user that created the first message. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function creator(); + + /* ------------------------------------------------------------------------------------------------ + | Scopes + | ------------------------------------------------------------------------------------------------ + */ + /** + * Scope discussions that the user is associated with. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param int $userId + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeForUser(Builder $query, $userId); + + /** + * Scope discussions with new messages that the user is associated with. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param int $userId + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeForUserWithNewMessages(Builder $query, $userId); + + /** + * Scope discussions between given user ids. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $userIds + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeBetween(Builder $query, array $userIds); + + /** + * Scope the query by the subject. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $subject + * @param bool $strict + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeSubject(Builder $query, $subject, $strict = false); + + /* ------------------------------------------------------------------------------------------------ + | Getters & Setters + | ------------------------------------------------------------------------------------------------ + */ + /** + * Get the latest_message attribute. + * + * @return \Arcanedev\LaravelMessenger\Models\Message + */ + public function getLatestMessageAttribute(); + + /* ------------------------------------------------------------------------------------------------ + | Main Functions + | ------------------------------------------------------------------------------------------------ + */ + /** + * Returns all of the latest discussions by `updated_at` date. + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public static function getLatest(); + + /** + * Returns all discussions by subject. + * + * @param string $subject + * @param bool $strict + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public static function getBySubject($subject, $strict = false); + + /** + * Returns an array of user ids that are associated with the discussion. + * + * @param int|null $userId + * + * @return \Illuminate\Support\Collection + */ + public function participantsUserIds($userId = null); + + /** + * Add a user to discussion as a participant. + * + * @param int $userId + * + * @return \Arcanedev\LaravelMessenger\Models\Participant + */ + public function addParticipant($userId); + + /** + * Add users to discussion as participants. + * + * @param array $userIds + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public function addParticipants(array $userIds); + + /** + * Remove a participant from discussion. + * + * @param int $userId + * @param bool $reload + * + * @return int + */ + public function removeParticipant($userId, $reload = true); + + /** + * Remove participants from discussion. + * + * @param array $userIds + * @param bool $reload + * + * @return int + */ + public function removeParticipants(array $userIds, $reload = true); + + /** + * Mark a discussion as read for a user. + * + * @param int $userId + * + * @return bool|int + */ + public function markAsRead($userId); + + /** + * See if the current thread is unread by the user. + * + * @param int $userId + * + * @return bool + */ + public function isUnread($userId); + + /** + * Finds the participant record from a user id. + * + * @param int $userId + * + * @return \Arcanedev\LaravelMessenger\Models\Participant + */ + public function getParticipantByUserId($userId); + + /** + * Get the trashed participants. + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getTrashedParticipants(); + + /** + * Restores all participants within a discussion. + * + * @param bool $reload + * + * @return int + */ + public function restoreAllParticipants($reload = true); + + /** + * Generates a participant information as a string. + * + * @param int|null $ignoredUserId + * @param \Closure|null $callback + * @param string $glue + * + * @return string + */ + public function participantsString($ignoredUserId = null, $callback = null, $glue = ', '); + + /** + * Checks to see if a user is a current participant of the discussion. + * + * @param int $userId + * + * @return bool + */ + public function hasParticipant($userId); + + /** + * Returns array of unread messages in discussion for given user. + * + * @param int $userId + * + * @return \Illuminate\Support\Collection + */ + public function userUnreadMessages($userId); +} +``` + +#### Participants + +```php + + * + * @property int id + * @property int discussion_id + * @property \Arcanedev\LaravelMessenger\Models\Discussion discussion + * @property int user_id + * @property \Illuminate\Database\Eloquent\Model user + * @property \Carbon\Carbon last_read + * @property \Carbon\Carbon created_at + * @property \Carbon\Carbon updated_at + * @property \Carbon\Carbon deleted_at + */ +interface Participant +{ + /* ------------------------------------------------------------------------------------------------ + | Relationships + | ------------------------------------------------------------------------------------------------ + */ + /** + * Discussion relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function discussion(); + + /** + * User relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user(); + + /* ------------------------------------------------------------------------------------------------ + | Getters & Setters + | ------------------------------------------------------------------------------------------------ + */ + /** + * Get the participant string info. + * + * @return string + */ + public function stringInfo(); + + /* ------------------------------------------------------------------------------------------------ + | Main Functions + | ------------------------------------------------------------------------------------------------ + */ + /** + * Restore a soft-deleted model instance. + * + * @return bool|null + */ + public function restore(); +} +``` + +#### Messages + +```php + + * + * @property int id + * @property int discussion_id + * @property \Arcanedev\LaravelMessenger\Models\Discussion discussion + * @property int user_id + * @property \Illuminate\Database\Eloquent\Model user + * @property \Illuminate\Database\Eloquent\Model author + * @property int body + * @property \Carbon\Carbon created_at + * @property \Carbon\Carbon updated_at + * @property \Illuminate\Database\Eloquent\Collection participants + * @property \Illuminate\Database\Eloquent\Collection recipients + */ +interface Message +{ + /* ------------------------------------------------------------------------------------------------ + | Relationships + | ------------------------------------------------------------------------------------------------ + */ + /** + * Discussion relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function discussion(); + + /** + * User/Author relationship (alias). + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function author(); + + /** + * User/Author relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user(); + + /** + * Participants relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function participants(); + + /* ------------------------------------------------------------------------------------------------ + | Getters & Setters + | ------------------------------------------------------------------------------------------------ + */ + /** + * Recipients of this message. + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getRecipientsAttribute(); +} +``` From 3caae42df3602ca8b2eac4be6858cf860d75ce6c Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Mon, 5 Sep 2016 00:41:29 +0100 Subject: [PATCH 8/8] Dropping HHVM Support --- .travis.yml | 5 ++--- README.md | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 33c2196..34a54d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ php: - 7.0 - 7.1 - nightly - - hhvm matrix: allow_failures: @@ -28,5 +27,5 @@ script: - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover after_script: - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ] && [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ] && [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi + - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi + - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/README.md b/README.md index 90f35be..89e88fc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Laravel Messenger [![Packagist License][badge_license]](LICENSE.md) [![For Laravel 5][badge_laravel]][link-github-repo] [![Travis Status][badge_build]][link-travis] -[![HHVM Status][badge_hhvm]][link-hhvm] [![Coverage Status][badge_coverage]][link-scrutinizer] [![Scrutinizer Code Quality][badge_quality]][link-scrutinizer] [![SensioLabs Insight][badge_insight]][link-insight] @@ -54,7 +53,6 @@ If you discover any security related issues, please email arcanedev.maroc@gmail. [badge_laravel]: https://img.shields.io/badge/For-Laravel%205.1|5.2|5.3-orange.svg?style=flat-square [badge_license]: https://img.shields.io/packagist/l/arcanedev/laravel-messenger.svg?style=flat-square [badge_build]: https://img.shields.io/travis/ARCANEDEV/LaravelMessenger.svg?style=flat-square -[badge_hhvm]: https://img.shields.io/hhvm/arcanedev/laravel-messenger.svg?style=flat-square [badge_coverage]: https://img.shields.io/scrutinizer/coverage/g/ARCANEDEV/LaravelMessenger.svg?style=flat-square [badge_quality]: https://img.shields.io/scrutinizer/g/ARCANEDEV/LaravelMessenger.svg?style=flat-square [badge_insight]: https://img.shields.io/sensiolabs/i/0fe62754-1219-409a-9d05-b6ae7e3e342f.svg?style=flat-square @@ -69,6 +67,5 @@ If you discover any security related issues, please email arcanedev.maroc@gmail. [link-contributors]: https://github.com/ARCANEDEV/LaravelMessenger/graphs/contributors [link-packagist]: https://packagist.org/packages/arcanedev/laravel-messenger [link-travis]: https://travis-ci.org/ARCANEDEV/LaravelMessenger -[link-hhvm]: http://hhvm.h4cc.de/package/arcanedev/laravel-messenger [link-scrutinizer]: https://scrutinizer-ci.com/g/ARCANEDEV/LaravelMessenger/?branch=master [link-insight]: https://insight.sensiolabs.com/projects/0fe62754-1219-409a-9d05-b6ae7e3e342f