Dan Brown

Added filtering to activity lists. Fixes #14.

...@@ -12,15 +12,24 @@ use Illuminate\Database\Eloquent\Model; ...@@ -12,15 +12,24 @@ use Illuminate\Database\Eloquent\Model;
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');
......
...@@ -32,7 +32,7 @@ class ActivityService ...@@ -32,7 +32,7 @@ class ActivityService
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);
...@@ -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 /**
......
...@@ -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
......