]> BookStack Code Mirror - bookstack/blob - app/Actions/ActivityService.php
Update some postpositional particles
[bookstack] / app / Actions / ActivityService.php
1 <?php namespace BookStack\Actions;
2
3 use BookStack\Auth\Permissions\PermissionService;
4 use BookStack\Entities\Book;
5 use BookStack\Entities\Entity;
6
7 class ActivityService
8 {
9     protected $activity;
10     protected $user;
11     protected $permissionService;
12
13     /**
14      * ActivityService constructor.
15      * @param Activity $activity
16      * @param PermissionService $permissionService
17      */
18     public function __construct(Activity $activity, PermissionService $permissionService)
19     {
20         $this->activity = $activity;
21         $this->permissionService = $permissionService;
22         $this->user = user();
23     }
24
25     /**
26      * Add activity data to database.
27      * @param \BookStack\Entities\Entity $entity
28      * @param string $activityKey
29      * @param int $bookId
30      */
31     public function add(Entity $entity, string $activityKey, int $bookId = null)
32     {
33         $activity = $this->newActivityForUser($activityKey, $bookId);
34         $entity->activity()->save($activity);
35         $this->setNotification($activityKey);
36     }
37
38     /**
39      * Adds a activity history with a message, without binding to a entity.
40      * @param string $activityKey
41      * @param string $message
42      * @param int $bookId
43      */
44     public function addMessage(string $activityKey, string $message, int $bookId = null)
45     {
46         $this->newActivityForUser($activityKey, $bookId)->forceFill([
47             'extra' => $message
48         ])->save();
49
50         $this->setNotification($activityKey);
51     }
52
53     /**
54      * Get a new activity instance for the current user.
55      * @param string $key
56      * @param int|null $bookId
57      * @return Activity
58      */
59     protected function newActivityForUser(string $key, int $bookId = null)
60     {
61         return $this->activity->newInstance()->forceFill([
62             'key' => strtolower($key),
63             'user_id' => $this->user->id,
64             'book_id' => $bookId ?? 0,
65         ]);
66     }
67
68     /**
69      * Removes the entity attachment from each of its activities
70      * and instead uses the 'extra' field with the entities name.
71      * Used when an entity is deleted.
72      * @param \BookStack\Entities\Entity $entity
73      * @return mixed
74      */
75     public function removeEntity(Entity $entity)
76     {
77         // TODO - Rewrite to db query.
78         $activities = $entity->activity;
79         foreach ($activities as $activity) {
80             $activity->extra = $entity->name;
81             $activity->entity_id = 0;
82             $activity->entity_type = null;
83             $activity->save();
84         }
85         return $activities;
86     }
87
88     /**
89      * Gets the latest activity.
90      * @param int $count
91      * @param int $page
92      * @return array
93      */
94     public function latest($count = 20, $page = 0)
95     {
96         $activityList = $this->permissionService
97             ->filterRestrictedEntityRelations($this->activity, 'activities', 'entity_id', 'entity_type')
98             ->orderBy('created_at', 'desc')
99             ->with('user', 'entity')
100             ->skip($count * $page)
101             ->take($count)
102             ->get();
103
104         return $this->filterSimilar($activityList);
105     }
106
107     /**
108      * Gets the latest activity for an entity, Filtering out similar
109      * items to prevent a message activity list.
110      * @param \BookStack\Entities\Entity $entity
111      * @param int $count
112      * @param int $page
113      * @return array
114      */
115     public function entityActivity($entity, $count = 20, $page = 1)
116     {
117         if ($entity->isA('book')) {
118             $query = $this->activity->where('book_id', '=', $entity->id);
119         } else {
120             $query = $this->activity->where('entity_type', '=', $entity->getMorphClass())
121                 ->where('entity_id', '=', $entity->id);
122         }
123         
124         $activity = $this->permissionService
125             ->filterRestrictedEntityRelations($query, 'activities', 'entity_id', 'entity_type')
126             ->orderBy('created_at', 'desc')
127             ->with(['entity', 'user.avatar'])
128             ->skip($count * ($page - 1))
129             ->take($count)
130             ->get();
131
132         return $this->filterSimilar($activity);
133     }
134
135     /**
136      * Get latest activity for a user, Filtering out similar
137      * items.
138      * @param $user
139      * @param int $count
140      * @param int $page
141      * @return array
142      */
143     public function userActivity($user, $count = 20, $page = 0)
144     {
145         $activityList = $this->permissionService
146             ->filterRestrictedEntityRelations($this->activity, 'activities', 'entity_id', 'entity_type')
147             ->orderBy('created_at', 'desc')->where('user_id', '=', $user->id)->skip($count * $page)->take($count)->get();
148         return $this->filterSimilar($activityList);
149     }
150
151     /**
152      * Filters out similar activity.
153      * @param Activity[] $activities
154      * @return array
155      */
156     protected function filterSimilar($activities)
157     {
158         $newActivity = [];
159         $previousItem = false;
160         foreach ($activities as $activityItem) {
161             if ($previousItem === false) {
162                 $previousItem = $activityItem;
163                 $newActivity[] = $activityItem;
164                 continue;
165             }
166             if (!$activityItem->isSimilarTo($previousItem)) {
167                 $newActivity[] = $activityItem;
168             }
169             $previousItem = $activityItem;
170         }
171         return $newActivity;
172     }
173
174     /**
175      * Flashes a notification message to the session if an appropriate message is available.
176      * @param $activityKey
177      */
178     protected function setNotification($activityKey)
179     {
180         $notificationTextKey = 'activities.' . $activityKey . '_notification';
181         if (trans()->has($notificationTextKey)) {
182             $message = trans($notificationTextKey);
183             session()->flash('success', $message);
184         }
185     }
186 }