Dan Brown

Added filtering to activity lists. Fixes #14.

...@@ -5,22 +5,31 @@ namespace Oxbow; ...@@ -5,22 +5,31 @@ namespace Oxbow;
5 use Illuminate\Database\Eloquent\Model; 5 use Illuminate\Database\Eloquent\Model;
6 6
7 /** 7 /**
8 - * @property string key 8 + * @property string key
9 - * @property \User user 9 + * @property \User user
10 * @property \Entity entity 10 * @property \Entity entity
11 - * @property string extra 11 + * @property string extra
12 */ 12 */
13 class Activity extends Model 13 class Activity extends Model
14 { 14 {
15 +
16 + /**
17 + * Get the entity for this activity.
18 + * @return bool
19 + */
15 public function entity() 20 public function entity()
16 { 21 {
17 - if($this->entity_id) { 22 + if ($this->entity_id) {
18 return $this->morphTo('entity')->first(); 23 return $this->morphTo('entity')->first();
19 } else { 24 } else {
20 return false; 25 return false;
21 } 26 }
22 } 27 }
23 28
29 + /**
30 + * Get the user this activity relates to.
31 + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
32 + */
24 public function user() 33 public function user()
25 { 34 {
26 return $this->belongsTo('Oxbow\User'); 35 return $this->belongsTo('Oxbow\User');
...@@ -35,4 +44,13 @@ class Activity extends Model ...@@ -35,4 +44,13 @@ class Activity extends Model
35 return trans('activities.' . $this->key); 44 return trans('activities.' . $this->key);
36 } 45 }
37 46
47 + /**
48 + * Checks if another Activity matches the general information of another.
49 + * @param $activityB
50 + * @return bool
51 + */
52 + public function isSimilarTo($activityB) {
53 + return [$this->key, $this->entitiy_type, $this->entitiy_id] === [$activityB->key, $activityB->entitiy_type, $activityB->entitiy_id];
54 + }
55 +
38 } 56 }
......
...@@ -37,15 +37,4 @@ class Book extends Entity ...@@ -37,15 +37,4 @@ class Book extends Entity
37 return $pages->sortBy('priority'); 37 return $pages->sortBy('priority');
38 } 38 }
39 39
40 - /**
41 - * Gets only the most recent activity for this book
42 - * @param int $limit
43 - * @param int $page
44 - * @return mixed
45 - */
46 - public function recentActivity($limit = 20, $page=0)
47 - {
48 - return $this->hasMany('Oxbow\Activity')->orderBy('created_at', 'desc')->skip($limit*$page)->take($limit)->get();
49 - }
50 -
51 } 40 }
......
...@@ -44,15 +44,4 @@ class Entity extends Model ...@@ -44,15 +44,4 @@ class Entity extends Model
44 return $this->morphMany('Oxbow\Activity', 'entity')->orderBy('created_at', 'desc'); 44 return $this->morphMany('Oxbow\Activity', 'entity')->orderBy('created_at', 'desc');
45 } 45 }
46 46
47 - /**
48 - * Gets only the most recent activity
49 - * @param int $limit
50 - * @param int $page
51 - * @return mixed
52 - */
53 - public function recentActivity($limit = 20, $page=0)
54 - {
55 - return $this->activity()->skip($limit*$page)->take($limit)->get();
56 - }
57 -
58 } 47 }
......
1 <?php 1 <?php
2 2
3 -/* 3 +// Authenticated routes...
4 -|--------------------------------------------------------------------------
5 -| Application Routes
6 -|--------------------------------------------------------------------------
7 -|
8 -| Here is where you can register all of the routes for an application.
9 -| It's a breeze. Simply tell Laravel the URIs it should respond to
10 -| and give it the controller to call when that URI is requested.
11 -|
12 -*/
13 -
14 -Route::get('/test', function () {
15 - return Auth::user()->can('users-edit');
16 -});
17 -
18 -// Authentication routes...
19 Route::group(['middleware' => 'auth'], function () { 4 Route::group(['middleware' => 'auth'], function () {
20 5
21 Route::group(['prefix' => 'books'], function () { 6 Route::group(['prefix' => 'books'], function () {
...@@ -40,6 +25,7 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -40,6 +25,7 @@ Route::group(['middleware' => 'auth'], function () {
40 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete'); 25 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
41 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update'); 26 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
42 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy'); 27 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy');
28 +
43 //Revisions 29 //Revisions
44 Route::get('/{bookSlug}/page/{pageSlug}/revisions', 'PageController@showRevisions'); 30 Route::get('/{bookSlug}/page/{pageSlug}/revisions', 'PageController@showRevisions');
45 Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}', 'PageController@showRevision'); 31 Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}', 'PageController@showRevision');
......
...@@ -23,16 +23,16 @@ class ActivityService ...@@ -23,16 +23,16 @@ class ActivityService
23 /** 23 /**
24 * Add activity data to database. 24 * Add activity data to database.
25 * @param Entity $entity 25 * @param Entity $entity
26 - * @param $activityKey 26 + * @param $activityKey
27 - * @param int $bookId 27 + * @param int $bookId
28 - * @param bool $extra 28 + * @param bool $extra
29 */ 29 */
30 public function add(Entity $entity, $activityKey, $bookId = 0, $extra = false) 30 public function add(Entity $entity, $activityKey, $bookId = 0, $extra = false)
31 { 31 {
32 $this->activity->user_id = $this->user->id; 32 $this->activity->user_id = $this->user->id;
33 $this->activity->book_id = $bookId; 33 $this->activity->book_id = $bookId;
34 $this->activity->key = strtolower($activityKey); 34 $this->activity->key = strtolower($activityKey);
35 - if($extra !== false) { 35 + if ($extra !== false) {
36 $this->activity->extra = $extra; 36 $this->activity->extra = $extra;
37 } 37 }
38 $entity->activity()->save($this->activity); 38 $entity->activity()->save($this->activity);
...@@ -41,8 +41,8 @@ class ActivityService ...@@ -41,8 +41,8 @@ class ActivityService
41 41
42 /** 42 /**
43 * Adds a activity history with a message & without binding to a entitiy. 43 * Adds a activity history with a message & without binding to a entitiy.
44 - * @param $activityKey 44 + * @param $activityKey
45 - * @param int $bookId 45 + * @param int $bookId
46 * @param bool|false $extra 46 * @param bool|false $extra
47 */ 47 */
48 public function addMessage($activityKey, $bookId = 0, $extra = false) 48 public function addMessage($activityKey, $bookId = 0, $extra = false)
...@@ -50,7 +50,7 @@ class ActivityService ...@@ -50,7 +50,7 @@ class ActivityService
50 $this->activity->user_id = $this->user->id; 50 $this->activity->user_id = $this->user->id;
51 $this->activity->book_id = $bookId; 51 $this->activity->book_id = $bookId;
52 $this->activity->key = strtolower($activityKey); 52 $this->activity->key = strtolower($activityKey);
53 - if($extra !== false) { 53 + if ($extra !== false) {
54 $this->activity->extra = $extra; 54 $this->activity->extra = $extra;
55 } 55 }
56 $this->activity->save(); 56 $this->activity->save();
...@@ -68,7 +68,7 @@ class ActivityService ...@@ -68,7 +68,7 @@ class ActivityService
68 public function removeEntity(Entity $entity) 68 public function removeEntity(Entity $entity)
69 { 69 {
70 $activities = $entity->activity; 70 $activities = $entity->activity;
71 - foreach($activities as $activity) { 71 + foreach ($activities as $activity) {
72 $activity->extra = $entity->name; 72 $activity->extra = $entity->name;
73 $activity->entity_id = 0; 73 $activity->entity_id = 0;
74 $activity->entity_type = null; 74 $activity->entity_type = null;
...@@ -85,7 +85,45 @@ class ActivityService ...@@ -85,7 +85,45 @@ class ActivityService
85 public function latest($count = 20, $page = 0) 85 public function latest($count = 20, $page = 0)
86 { 86 {
87 return $this->activity->orderBy('created_at', 'desc') 87 return $this->activity->orderBy('created_at', 'desc')
88 + ->skip($count * $page)->take($count)->get();
89 + }
90 +
91 + /**
92 + * Gets the latest activity for an entitiy, Filtering out similar
93 + * items to prevent a message activity list.
94 + * @param Entity $entity
95 + * @param int $count
96 + * @param int $page
97 + * @return array
98 + */
99 + function entityActivity($entity, $count = 20, $page = 0)
100 + {
101 + $activity = $entity->hasMany('Oxbow\Activity')->orderBy('created_at', 'desc')
88 ->skip($count*$page)->take($count)->get(); 102 ->skip($count*$page)->take($count)->get();
103 +
104 + return $this->filterSimilar($activity);
105 + }
106 +
107 + /**
108 + * Filters out similar acitivity.
109 + * @param Activity[] $activity
110 + * @return array
111 + */
112 + protected function filterSimilar($activity) {
113 + $newActivity = [];
114 + $previousItem = false;
115 + foreach($activity as $activityItem) {
116 + if($previousItem === false) {
117 + $previousItem = $activityItem;
118 + $newActivity[] = $activityItem;
119 + continue;
120 + }
121 + if(!$activityItem->isSimilarTo($previousItem)) {
122 + $newActivity[] = $activityItem;
123 + }
124 + $previousItem = $activityItem;
125 + }
126 + return $newActivity;
89 } 127 }
90 128
91 /** 129 /**
......
...@@ -8,31 +8,31 @@ return [ ...@@ -8,31 +8,31 @@ return [
8 */ 8 */
9 9
10 // Pages 10 // Pages
11 - 'page_create' => 'created page', 11 + 'page_create' => 'created page',
12 - 'page_create_notification' => 'Page Successfully Created', 12 + 'page_create_notification' => 'Page Successfully Created',
13 - 'page_update' => 'updated page', 13 + 'page_update' => 'updated page',
14 - 'page_update_notification' => 'Page Successfully Updated', 14 + 'page_update_notification' => 'Page Successfully Updated',
15 - 'page_delete' => 'deleted page', 15 + 'page_delete' => 'deleted page',
16 - 'page_delete_notification' => 'Page Successfully Created', 16 + 'page_delete_notification' => 'Page Successfully Created',
17 - 'page_restore' => 'restored page', 17 + 'page_restore' => 'restored page',
18 - 'page_restore_notification' => 'Page Successfully Restored', 18 + 'page_restore_notification' => 'Page Successfully Restored',
19 19
20 // Chapters 20 // Chapters
21 - 'chapter_create' => 'created chapter', 21 + 'chapter_create' => 'created chapter',
22 'chapter_create_notification' => 'Chapter Successfully Created', 22 'chapter_create_notification' => 'Chapter Successfully Created',
23 - 'chapter_update' => 'updated chapter', 23 + 'chapter_update' => 'updated chapter',
24 'chapter_update_notification' => 'Chapter Successfully Updated', 24 'chapter_update_notification' => 'Chapter Successfully Updated',
25 - 'chapter_delete' => 'deleted chapter', 25 + 'chapter_delete' => 'deleted chapter',
26 'chapter_delete_notification' => 'Chapter Successfully Deleted', 26 'chapter_delete_notification' => 'Chapter Successfully Deleted',
27 27
28 // Books 28 // Books
29 - 'book_create' => 'created book', 29 + 'book_create' => 'created book',
30 - 'book_create_notification' => 'Book Successfully Created', 30 + 'book_create_notification' => 'Book Successfully Created',
31 - 'book_update' => 'updated book', 31 + 'book_update' => 'updated book',
32 - 'book_update_notification' => 'Book Successfully Updated', 32 + 'book_update_notification' => 'Book Successfully Updated',
33 - 'book_delete' => 'deleted book', 33 + 'book_delete' => 'deleted book',
34 - 'book_delete_notification' => 'Book Successfully Deleted', 34 + 'book_delete_notification' => 'Book Successfully Deleted',
35 - 'book_sort' => 'sorted book', 35 + 'book_sort' => 'sorted book',
36 - 'book_sort_notification' => 'Book Successfully Re-sorted', 36 + 'book_sort_notification' => 'Book Successfully Re-sorted',
37 37
38 ]; 38 ];
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
73 <div class="col-md-3 col-md-offset-1"> 73 <div class="col-md-3 col-md-offset-1">
74 <div class="margin-top large"><br></div> 74 <div class="margin-top large"><br></div>
75 <h3>Recent Activity</h3> 75 <h3>Recent Activity</h3>
76 - @include('partials/activity-list', ['activity' => $book->recentActivity()]) 76 + @include('partials/activity-list', ['activity' => Activity::entityActivity($book, 20, 0)])
77 </div> 77 </div>
78 </div> 78 </div>
79 79
......