├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src └── Kim │ └── Activity │ ├── Activity.php │ ├── ActivityFacade.php │ ├── ActivityServiceProvider.php │ └── Traits │ ├── ActivitySorter.php │ ├── ActivitySupporter.php │ ├── GuestRetriever.php │ └── UserRetriever.php └── tests ├── ActivitySorterTest.php ├── GuestRetrieverTest.php └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /vendor 3 | composer.phar 4 | composer.lock 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thomas Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # See Who's Online With This Laravel Package 2 | 3 | With this package, you can easily see who's online and how many guests are viewing your site. 4 | 5 | ## Installation 6 | 7 | To install this package, just follow these quick few steps. 8 | 9 | ### Composer 10 | 11 | As always, pull this package through composer by opening `composer.json` file and adding this within `require`: 12 | 13 | ``` 14 | "kim/activity": "^1.1" 15 | ``` 16 | 17 | Note: If you are running Laravel 5.0 or 5.1, please require version "^1.0". 18 | 19 | Afterward, run either `composer update`. 20 | 21 | ### Providers and Aliases 22 | 23 | Next, open `config/app.php` and add this to your providers array: 24 | 25 | ``` 26 | Kim\Activity\ActivityServiceProvider::class 27 | ``` 28 | 29 | and this to your aliases array: 30 | 31 | ``` 32 | 'Activity' => Kim\Activity\ActivityFacade::class 33 | ``` 34 | 35 | ### Session and Database Setup 36 | 37 | Finally, you need to change your session configuration to use the database. Open the `.env` file, which should be at the root directory of your Laravel project. Then, change your session driver to database. 38 | 39 | ``` 40 | SESSION_DRIVER=database 41 | ``` 42 | 43 | If you are running L5.2, publish the default session migrations file and then migrate it by running these commands: 44 | 45 | ``` 46 | php artisan session:table 47 | 48 | php artisan migrate 49 | ``` 50 | 51 | If you are running L5.0 or L5.1, run these commands: 52 | 53 | ``` 54 | php artisan vendor:publish --provider="Kim\Activity\ActivityServiceProvider" --tag="migrations" 55 | 56 | php artisan migrate 57 | ``` 58 | 59 | ## Usage 60 | 61 | This package will automatically update a user's or guest's most recent activity. To grab the most recent users and guests though, you can use the easy-to-use built-in methods. 62 | 63 | ### Grabbing Most Recent Activities 64 | 65 | Import the Activity facade at the top and then do a simple query. 66 | 67 | ``` 68 | // Import at the top 69 | use Activity; 70 | 71 | 72 | // Find latest users 73 | $activities = Activity::users()->get(); 74 | 75 | // Loop through and echo user's name 76 | foreach ($activities as $activity) { 77 | echo $activity->user->name . '
'; 78 | } 79 | ``` 80 | 81 | The `users` method will grab the most recent activities within the past 5 minutes. You can change the default timespan by specifying the minutes. 82 | 83 | ``` 84 | $activities = Activity::users(1)->get(); // Last 1 minute 85 | $activities = Activity::users(10)->get(); // Last 10 minutes 86 | $activities = Activity::users(60)->get(); // Last 60 minutes 87 | ``` 88 | 89 | You have other methods for your convenience to grab the latest activities by seconds or even hours. 90 | 91 | ``` 92 | $activities = Activity::usersBySeconds(30)->get(); // Get active users within the last 30 seconds 93 | $activities = Activity::usersByMinutes(10)->get(); // Get active users within the last 10 minutes 94 | $activities = Activity::usersByHours(1)->get(); // Get active users within the last 1 hour 95 | 96 | $numberOfUsers = Activity::users()->count(); // Count the number of active users 97 | ``` 98 | 99 | ### Sorting Methods 100 | 101 | In order to sort the activities by most and least recent, just use the `mostRecent` and `leastRecent` methods. 102 | 103 | ``` 104 | $activities = Activity::users()->mostRecent()->get(); // Get active users and sort them by most recent 105 | $activities = Activity::users()->leastRecent()->get(); // Get active users and sort them by least recent 106 | ``` 107 | 108 | In addition to this, you can sort the user's attributes by using the `orderByUsers` method. For example, rather than ordering by the most recent activity, lets say you want to order by the users' name alphabetically. You can do this. 109 | 110 | ``` 111 | $activities = Activity::users()->orderByUsers('email')->get(); 112 | ``` 113 | 114 | ### Grabbing the Guests 115 | 116 | In order to grab the number of guests that are online, it's just as intuitive as grabbing the users. For example: 117 | 118 | ``` 119 | $numberOfGuests = Activity::guests()->count(); // Count the number of active guests 120 | ``` 121 | 122 | ## License 123 | 124 | This package is free software distributed under the terms of the MIT license. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kim/activity", 3 | "description": "Easily retrieve a list of users and guests that are online.", 4 | "keywords": [ 5 | "laravel", 6 | "php", 7 | "online activity" 8 | ], 9 | "homepage": "https://github.com/thomastkim/laravel-online-users", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Thomas Kim", 14 | "email": "thomas@thomastkim.com", 15 | "homepage": "http://thomastkim.com" 16 | } 17 | ], 18 | "require": { 19 | "illuminate/support": "^5.2", 20 | "illuminate/session": "^5.2", 21 | "illuminate/database": "^5.2", 22 | "php" : ">=5.5.9" 23 | }, 24 | "require-dev": { 25 | "phpunit/phpunit": "~4.0", 26 | "mockery/mockery": "^0.9.4" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Kim\\": "src/Kim" 31 | } 32 | }, 33 | "autoload-dev": { 34 | "classmap": ["tests"] 35 | }, 36 | "minimum-stability": "stable" 37 | } 38 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Kim/Activity/Activity.php: -------------------------------------------------------------------------------- 1 | app->bind('Activity', function($app) 17 | { 18 | return new Activity; 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Kim/Activity/Traits/ActivitySorter.php: -------------------------------------------------------------------------------- 1 | latest($column); 17 | } 18 | 19 | /** 20 | * Add an "order by" clause to retrieve least recent sessions. 21 | * 22 | * @param \Illuminate\Database\Query\Builder $query 23 | * @param string $column 24 | * @return \Illuminate\Database\Query\Builder|static 25 | */ 26 | public function scopeLeastRecent($query, $column = 'last_activity') 27 | { 28 | return $query->oldest($column); 29 | } 30 | 31 | /** 32 | * Use joins to order by the users' column attributes. 33 | * 34 | * @param \Illuminate\Database\Query\Builder $query 35 | * @param string $column 36 | * @return \Illuminate\Database\Query\Builder|static 37 | */ 38 | public function scopeOrderByUsers($query, $column, $dir = 'ASC') 39 | { 40 | $table = $this->getTable(); 41 | 42 | $userModel = config('auth.providers.users.model'); 43 | $user = new $userModel; 44 | $userTable = $user->getTable(); 45 | $userKey = $user->getKeyName(); 46 | 47 | return $query->join($userTable, "{$table}.user_id", '=', "{$userTable}.{$userKey}")->orderBy("{$userTable}.{$column}", $dir); 48 | } 49 | } -------------------------------------------------------------------------------- /src/Kim/Activity/Traits/ActivitySupporter.php: -------------------------------------------------------------------------------- 1 | belongsTo(config('auth.providers.users.model')); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Kim/Activity/Traits/GuestRetriever.php: -------------------------------------------------------------------------------- 1 | where('last_activity', '>=', time() - $seconds)->whereNull('user_id'); 18 | } 19 | 20 | /** 21 | * Alias for the `guestsByMinutes` query method. 22 | * 23 | * @param \Illuminate\Database\Query\Builder $query 24 | * @param int $minutes 25 | * @return \Illuminate\Database\Query\Builder 26 | */ 27 | public function scopeGuests($query, $minutes = 5) 28 | { 29 | return $query->guestsByMinutes($minutes); 30 | } 31 | 32 | /** 33 | * Constrain the query to retrieve only sessions of guests who 34 | * have been active within the specified number of minutes. 35 | * 36 | * @param \Illuminate\Database\Query\Builder $query 37 | * @param int $minutes 38 | * @return \Illuminate\Database\Query\Builder 39 | */ 40 | public function scopeGuestsByMinutes($query, $minutes = 5) 41 | { 42 | return $query->guestsBySeconds($minutes * 60); 43 | } 44 | 45 | /** 46 | * Constrain the query to retrieve only sessions of guests who 47 | * have been active within the specified number of hours. 48 | * 49 | * @param \Illuminate\Database\Query\Builder $query 50 | * @param int $hours 51 | * @return \Illuminate\Database\Query\Builder 52 | */ 53 | public function scopeGuestsByHours($query, $hours = 1) 54 | { 55 | return $query->guestsByMinutes($hours * 60); 56 | } 57 | } -------------------------------------------------------------------------------- /src/Kim/Activity/Traits/UserRetriever.php: -------------------------------------------------------------------------------- 1 | with(['user'])->where('last_activity', '>=', time() - $seconds)->whereNotNull('user_id'); 18 | } 19 | 20 | /** 21 | * Alias for the `usersByMinutes` query method. 22 | * 23 | * @param \Illuminate\Database\Query\Builder $query 24 | * @param int $minutes 25 | * @return \Illuminate\Database\Query\Builder 26 | */ 27 | public function scopeUsers($query, $minutes = 5) 28 | { 29 | return $query->usersByMinutes($minutes); 30 | } 31 | 32 | /** 33 | * Constrain the query to retrieve only sessions of users who 34 | * have been active within the specified number of minutes. 35 | * 36 | * @param \Illuminate\Database\Query\Builder $query 37 | * @param int $minutes 38 | * @return \Illuminate\Database\Query\Builder 39 | */ 40 | public function scopeUsersByMinutes($query, $minutes = 5) 41 | { 42 | return $query->usersBySeconds($minutes * 60); 43 | } 44 | 45 | /** 46 | * Constrain the query to retrieve only sessions of users who 47 | * have been active within the specified number of hours. 48 | * 49 | * @param \Illuminate\Database\Query\Builder $query 50 | * @param int $hours 51 | * @return \Illuminate\Database\Query\Builder 52 | */ 53 | public function scopeUsersByHours($query, $hours = 1) 54 | { 55 | return $query->usersByMinutes($hours * 60); 56 | } 57 | } -------------------------------------------------------------------------------- /tests/ActivitySorterTest.php: -------------------------------------------------------------------------------- 1 | createSession()->last_activity; 15 | } 16 | rsort($sessions); 17 | 18 | $activities = Activity::mostRecent()->get()->pluck('last_activity'); 19 | 20 | $this->assertEquals($sessions, $activities->toArray()); 21 | } 22 | 23 | /** @test */ 24 | function it_sorts_the_sessions_by_least_recent_activity() 25 | { 26 | $sessions = []; 27 | 28 | for ($i = 0; $i < 10; $i++) 29 | { 30 | $sessions[] = $this->createSession()->last_activity; 31 | } 32 | sort($sessions); 33 | 34 | $activities = Activity::leastRecent()->get()->pluck('last_activity'); 35 | 36 | $this->assertEquals($sessions, $activities->toArray()); 37 | } 38 | } -------------------------------------------------------------------------------- /tests/GuestRetrieverTest.php: -------------------------------------------------------------------------------- 1 | createSession(); 13 | } 14 | 15 | for ($i = 0; $i < 4; $i++) 16 | { 17 | $this->createSessionWithUser($i); 18 | } 19 | 20 | $activities = Activity::guests()->get(); 21 | 22 | $this->assertEquals(3, $activities->count()); 23 | } 24 | 25 | /** @test */ 26 | function it_retrieves_guests_who_were_active_within_the_last_3_seconds() 27 | { 28 | for ($i = 0; $i < 5; $i++) 29 | { 30 | $this->createSession(time() - $i); 31 | } 32 | 33 | $activities = Activity::guestsBySeconds(3)->get(); 34 | 35 | $this->assertEquals(4, $activities->count()); 36 | } 37 | 38 | /** @test */ 39 | function it_retrieves_guests_who_were_active_within_the_last_3_minutes() 40 | { 41 | $secondsPerMinute = 60; 42 | 43 | $oneMinuteAgo = $secondsPerMinute * 1; 44 | $twoMinutesAgo = $secondsPerMinute * 2; 45 | $threeMinutesAgo = $secondsPerMinute * 3; 46 | $fourMinutesAgo = $secondsPerMinute * 4; 47 | $fiveMinutesAgo = $secondsPerMinute * 5; 48 | 49 | $this->createSession(time() - $oneMinuteAgo); 50 | $this->createSession(time() - $twoMinutesAgo); 51 | $this->createSession(time() - $threeMinutesAgo); 52 | $this->createSession(time() - $fourMinutesAgo); 53 | $this->createSession(time() - $fiveMinutesAgo); 54 | 55 | $activities = Activity::guestsByMinutes(3)->get(); 56 | 57 | $this->assertEquals(3, $activities->count()); 58 | } 59 | 60 | /** @test */ 61 | function it_retrieves_guests_who_were_active_within_the_last_two_hours() 62 | { 63 | $secondsPerHour = 3600; 64 | 65 | $oneHourAgo = $secondsPerHour * 1; 66 | $twoHoursAgo = $secondsPerHour * 2; 67 | $threeHoursAgo = $secondsPerHour * 3; 68 | $fourHoursAgo = $secondsPerHour * 4; 69 | $fiveHoursAgo = $secondsPerHour * 5; 70 | 71 | $this->createSession(time() - $oneHourAgo); 72 | $this->createSession(time() - $twoHoursAgo); 73 | $this->createSession(time() - $threeHoursAgo); 74 | $this->createSession(time() - $fourHoursAgo); 75 | $this->createSession(time() - $fiveHoursAgo); 76 | 77 | $activities = Activity::guestsByHours(2)->get(); 78 | 79 | $this->assertEquals(2, $activities->count()); 80 | } 81 | } -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | setupDatabase(); 12 | $this->migrateTables(); 13 | } 14 | 15 | public function setupDatabase() 16 | { 17 | $db = new Manager; 18 | $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); 19 | $db->bootEloquent(); 20 | $db->setAsGlobal(); 21 | } 22 | 23 | protected function migrateTables() 24 | { 25 | Manager::schema()->create('users', function($table) 26 | { 27 | $table->increments('id'); 28 | $table->timestamps(); 29 | }); 30 | Manager::schema()->create('sessions', function($table) 31 | { 32 | $table->increments('id'); 33 | $table->integer('user_id')->nullable(); 34 | $table->integer('last_activity'); 35 | }); 36 | } 37 | 38 | protected function createSession($time = null) 39 | { 40 | $activity = new Activity; 41 | $activity->last_activity = (is_null($time)) ? time() : $time; 42 | $activity->save(); 43 | 44 | return $activity; 45 | } 46 | 47 | protected function createSessionWithUser($i, $time = null) 48 | { 49 | $activity = new Activity; 50 | $activity->last_activity = (is_null($time)) ? time() : $time; 51 | $activity->user_id = $i; 52 | $activity->save(); 53 | 54 | return $activity; 55 | } 56 | } 57 | 58 | class User extends Model 59 | { 60 | } --------------------------------------------------------------------------------