1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* ownCloud - Activity App |
5
|
|
|
* |
6
|
|
|
* @author Frank Karlitschek |
7
|
|
|
* @author Joas Schilling |
8
|
|
|
* @copyright 2013 Frank Karlitschek [email protected] |
9
|
|
|
* |
10
|
|
|
* This library is free software; you can redistribute it and/or |
11
|
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
12
|
|
|
* License as published by the Free Software Foundation; either |
13
|
|
|
* version 3 of the License, or any later version. |
14
|
|
|
* |
15
|
|
|
* This library is distributed in the hope that it will be useful, |
16
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
17
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18
|
|
|
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. |
19
|
|
|
* |
20
|
|
|
* You should have received a copy of the GNU Affero General Public |
21
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
22
|
|
|
* |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
namespace OCA\Activity; |
26
|
|
|
|
27
|
|
|
use OCP\Activity\IEvent; |
28
|
|
|
use OCP\Activity\IExtension; |
29
|
|
|
use OCP\Activity\IManager; |
30
|
|
|
use OCP\IDBConnection; |
31
|
|
|
use OCP\IL10N; |
32
|
|
|
use OCP\IUser; |
33
|
|
|
use OCP\IUserSession; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @brief Class for managing the data in the activities |
37
|
|
|
*/ |
38
|
|
|
class Data { |
39
|
|
|
/** @var IManager */ |
40
|
|
|
protected $activityManager; |
41
|
|
|
|
42
|
|
|
/** @var IDBConnection */ |
43
|
|
|
protected $connection; |
44
|
|
|
|
45
|
|
|
/** @var IUserSession */ |
46
|
|
|
protected $userSession; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @param IManager $activityManager |
50
|
|
|
* @param IDBConnection $connection |
51
|
|
|
* @param IUserSession $userSession |
52
|
|
|
*/ |
53
|
62 |
|
public function __construct(IManager $activityManager, IDBConnection $connection, IUserSession $userSession) { |
54
|
62 |
|
$this->activityManager = $activityManager; |
55
|
62 |
|
$this->connection = $connection; |
56
|
62 |
|
$this->userSession = $userSession; |
57
|
62 |
|
} |
58
|
|
|
|
59
|
|
|
protected $notificationTypes = array(); |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param IL10N $l |
63
|
|
|
* @return array Array "stringID of the type" => "translated string description for the setting" |
64
|
|
|
* or Array "stringID of the type" => [ |
65
|
|
|
* 'desc' => "translated string description for the setting" |
66
|
|
|
* 'methods' => [\OCP\Activity\IExtension::METHOD_*], |
67
|
|
|
* ] |
68
|
|
|
*/ |
69
|
7 |
|
public function getNotificationTypes(IL10N $l) { |
70
|
7 |
|
if (isset($this->notificationTypes[$l->getLanguageCode()])) { |
71
|
1 |
|
return $this->notificationTypes[$l->getLanguageCode()]; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
// Allow apps to add new notification types |
75
|
7 |
|
$notificationTypes = $this->activityManager->getNotificationTypes($l->getLanguageCode()); |
76
|
7 |
|
$this->notificationTypes[$l->getLanguageCode()] = $notificationTypes; |
77
|
7 |
|
return $notificationTypes; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Send an event into the activity stream |
82
|
|
|
* |
83
|
|
|
* @param IEvent $event |
84
|
|
|
* @return bool |
85
|
|
|
*/ |
86
|
4 |
|
public function send(IEvent $event) { |
87
|
4 |
|
if ($event->getAffectedUser() === '' || $event->getAffectedUser() === null) { |
88
|
2 |
|
return false; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
// store in DB |
92
|
2 |
|
$queryBuilder = $this->connection->getQueryBuilder(); |
93
|
2 |
|
$queryBuilder->insert('activity') |
94
|
2 |
|
->values([ |
95
|
2 |
|
'app' => $queryBuilder->createParameter('app'), |
96
|
2 |
|
'subject' => $queryBuilder->createParameter('subject'), |
97
|
2 |
|
'subjectparams' => $queryBuilder->createParameter('subjectparams'), |
98
|
2 |
|
'message' => $queryBuilder->createParameter('message'), |
99
|
2 |
|
'messageparams' => $queryBuilder->createParameter('messageparams'), |
100
|
2 |
|
'file' => $queryBuilder->createParameter('object_name'), |
101
|
2 |
|
'link' => $queryBuilder->createParameter('link'), |
102
|
2 |
|
'user' => $queryBuilder->createParameter('user'), |
103
|
2 |
|
'affecteduser' => $queryBuilder->createParameter('affecteduser'), |
104
|
2 |
|
'timestamp' => $queryBuilder->createParameter('timestamp'), |
105
|
2 |
|
'priority' => $queryBuilder->createParameter('priority'), |
106
|
2 |
|
'type' => $queryBuilder->createParameter('type'), |
107
|
2 |
|
'object_type' => $queryBuilder->createParameter('object_type'), |
108
|
2 |
|
'object_id' => $queryBuilder->createParameter('object_id'), |
109
|
2 |
|
]) |
110
|
2 |
|
->setParameters([ |
111
|
2 |
|
'app' => $event->getApp(), |
112
|
2 |
|
'type' => $event->getType(), |
113
|
2 |
|
'affecteduser' => $event->getAffectedUser(), |
114
|
2 |
|
'user' => $event->getAuthor(), |
115
|
2 |
|
'timestamp' => (int) $event->getTimestamp(), |
116
|
2 |
|
'subject' => $event->getSubject(), |
117
|
2 |
|
'subjectparams' => json_encode($event->getSubjectParameters()), |
118
|
2 |
|
'message' => $event->getMessage(), |
119
|
2 |
|
'messageparams' => json_encode($event->getMessageParameters()), |
120
|
2 |
|
'priority' => IExtension::PRIORITY_MEDIUM, |
121
|
2 |
|
'object_type' => $event->getObjectType(), |
122
|
2 |
|
'object_id' => (int) $event->getObjectId(), |
123
|
2 |
|
'object_name' => $event->getObjectName(), |
124
|
2 |
|
'link' => $event->getLink(), |
125
|
2 |
|
]) |
126
|
2 |
|
->execute(); |
127
|
|
|
|
128
|
2 |
|
return true; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Send an event as email |
133
|
|
|
* |
134
|
|
|
* @param IEvent $event |
135
|
|
|
* @param int $latestSendTime Activity $timestamp + batch setting of $affectedUser |
136
|
|
|
* @return bool |
137
|
|
|
*/ |
138
|
4 |
|
public function storeMail(IEvent $event, $latestSendTime) { |
139
|
4 |
|
if ($event->getAffectedUser() === '' || $event->getAffectedUser() === null) { |
140
|
2 |
|
return false; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
// store in DB |
144
|
2 |
|
$queryBuilder = $this->connection->getQueryBuilder(); |
145
|
2 |
|
$queryBuilder->insert('activity_mq') |
146
|
2 |
|
->values([ |
147
|
2 |
|
'amq_appid' => $queryBuilder->createParameter('app'), |
148
|
2 |
|
'amq_subject' => $queryBuilder->createParameter('subject'), |
149
|
2 |
|
'amq_subjectparams' => $queryBuilder->createParameter('subjectparams'), |
150
|
2 |
|
'amq_affecteduser' => $queryBuilder->createParameter('affecteduser'), |
151
|
2 |
|
'amq_timestamp' => $queryBuilder->createParameter('timestamp'), |
152
|
2 |
|
'amq_type' => $queryBuilder->createParameter('type'), |
153
|
2 |
|
'amq_latest_send' => $queryBuilder->createParameter('latest_send'), |
154
|
2 |
|
]) |
155
|
2 |
|
->setParameters([ |
156
|
2 |
|
'app' => $event->getApp(), |
157
|
2 |
|
'subject' => $event->getSubject(), |
158
|
2 |
|
'subjectparams' => json_encode($event->getSubjectParameters()), |
159
|
2 |
|
'affecteduser' => $event->getAffectedUser(), |
160
|
2 |
|
'timestamp' => (int) $event->getTimestamp(), |
161
|
2 |
|
'type' => $event->getType(), |
162
|
2 |
|
'latest_send' => $latestSendTime, |
163
|
2 |
|
]) |
164
|
2 |
|
->execute(); |
165
|
|
|
|
166
|
2 |
|
return true; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* @brief Read a list of events from the activity stream |
171
|
|
|
* @param GroupHelper $groupHelper Allows activities to be grouped |
172
|
|
|
* @param UserSettings $userSettings Gets the settings of the user |
173
|
|
|
* @param int $start The start entry |
174
|
|
|
* @param int $count The number of statements to read |
175
|
|
|
* @param string $filter Filter the activities |
176
|
|
|
* @param string $user User for whom we display the stream |
177
|
|
|
* @param string $objectType |
178
|
|
|
* @param int $objectId |
179
|
|
|
* @return array |
180
|
|
|
*/ |
181
|
15 |
|
public function read(GroupHelper $groupHelper, UserSettings $userSettings, $start, $count, $filter = 'all', $user = '', $objectType = '', $objectId = 0) { |
182
|
|
|
// get current user |
183
|
15 |
|
if ($user === '') { |
184
|
14 |
|
$user = $this->userSession->getUser(); |
185
|
14 |
|
if ($user instanceof IUser) { |
|
|
|
|
186
|
13 |
|
$user = $user->getUID(); |
187
|
13 |
|
} else { |
188
|
|
|
// No user given and not logged in => no activities |
189
|
1 |
|
return []; |
190
|
|
|
} |
191
|
13 |
|
} |
192
|
14 |
|
$groupHelper->setUser($user); |
193
|
|
|
|
194
|
14 |
|
$enabledNotifications = $userSettings->getNotificationTypes($user, 'stream'); |
195
|
14 |
|
$enabledNotifications = $this->activityManager->filterNotificationTypes($enabledNotifications, $filter); |
196
|
14 |
|
$parameters = array_unique($enabledNotifications); |
197
|
|
|
|
198
|
|
|
// We don't want to display any activities |
199
|
14 |
|
if (empty($parameters)) { |
200
|
2 |
|
return array(); |
201
|
|
|
} |
202
|
|
|
|
203
|
12 |
|
$placeholders = implode(',', array_fill(0, sizeof($parameters), '?')); |
204
|
12 |
|
$limitActivities = " AND `type` IN (" . $placeholders . ")"; |
205
|
12 |
|
array_unshift($parameters, $user); |
206
|
|
|
|
207
|
12 |
|
if ($filter === 'self') { |
208
|
1 |
|
$limitActivities .= ' AND `user` = ?'; |
209
|
1 |
|
$parameters[] = $user; |
210
|
12 |
|
} else if ($filter === 'by' || $filter === 'all' && !$userSettings->getUserSetting($user, 'setting', 'self')) { |
211
|
2 |
|
$limitActivities .= ' AND `user` <> ?'; |
212
|
2 |
|
$parameters[] = $user; |
213
|
11 |
|
} else if ($filter === 'filter') { |
214
|
2 |
|
if (!$userSettings->getUserSetting($user, 'setting', 'self')) { |
215
|
1 |
|
$limitActivities .= ' AND `user` <> ?'; |
216
|
1 |
|
$parameters[] = $user; |
217
|
1 |
|
} |
218
|
2 |
|
$limitActivities .= ' AND `object_type` = ?'; |
219
|
2 |
|
$parameters[] = $objectType; |
220
|
2 |
|
$limitActivities .= ' AND `object_id` = ?'; |
221
|
2 |
|
$parameters[] = $objectId; |
222
|
2 |
|
} |
223
|
|
|
|
224
|
12 |
|
list($condition, $params) = $this->activityManager->getQueryForFilter($filter); |
225
|
12 |
|
if (!is_null($condition)) { |
226
|
2 |
|
$limitActivities .= ' '; |
227
|
2 |
|
$limitActivities .= $condition; |
228
|
2 |
|
if (is_array($params)) { |
229
|
1 |
|
$parameters = array_merge($parameters, $params); |
230
|
1 |
|
} |
231
|
2 |
|
} |
232
|
|
|
|
233
|
12 |
|
return $this->getActivities($count, $start, $limitActivities, $parameters, $groupHelper); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Process the result and return the activities |
238
|
|
|
* |
239
|
|
|
* @param int $count |
240
|
|
|
* @param int $start |
241
|
|
|
* @param string $limitActivities |
242
|
|
|
* @param array $parameters |
243
|
|
|
* @param \OCA\Activity\GroupHelper $groupHelper |
244
|
|
|
* @return array |
245
|
|
|
*/ |
246
|
4 |
|
protected function getActivities($count, $start, $limitActivities, $parameters, GroupHelper $groupHelper) { |
247
|
4 |
|
$query = $this->connection->prepare( |
248
|
|
|
'SELECT * ' |
249
|
|
|
. ' FROM `*PREFIX*activity` ' |
250
|
4 |
|
. ' WHERE `affecteduser` = ? ' . $limitActivities |
251
|
4 |
|
. ' ORDER BY `timestamp` DESC', |
252
|
4 |
|
$count, $start); |
253
|
4 |
|
$query->execute($parameters); |
254
|
|
|
|
255
|
4 |
|
while ($row = $query->fetch()) { |
256
|
3 |
|
$groupHelper->addActivity($row); |
257
|
3 |
|
} |
258
|
4 |
|
$query->closeCursor(); |
259
|
|
|
|
260
|
4 |
|
return $groupHelper->getActivities(); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Verify that the filter is valid |
265
|
|
|
* |
266
|
|
|
* @param string $filterValue |
267
|
|
|
* @return string |
268
|
|
|
*/ |
269
|
6 |
|
public function validateFilter($filterValue) { |
270
|
6 |
|
if (!isset($filterValue)) { |
271
|
1 |
|
return 'all'; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
switch ($filterValue) { |
275
|
5 |
|
case 'by': |
276
|
5 |
|
case 'self': |
277
|
5 |
|
case 'all': |
278
|
5 |
|
case 'filter': |
279
|
3 |
|
return $filterValue; |
280
|
2 |
|
default: |
281
|
2 |
|
if ($this->activityManager->isFilterValid($filterValue)) { |
282
|
1 |
|
return $filterValue; |
283
|
|
|
} |
284
|
1 |
|
return 'all'; |
285
|
2 |
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Delete old events |
290
|
|
|
* |
291
|
|
|
* @param int $expireDays Minimum 1 day |
292
|
|
|
* @return null |
293
|
|
|
*/ |
294
|
2 |
|
public function expire($expireDays = 365) { |
295
|
2 |
|
$ttl = (60 * 60 * 24 * max(1, $expireDays)); |
296
|
|
|
|
297
|
2 |
|
$timelimit = time() - $ttl; |
298
|
2 |
|
$this->deleteActivities(array( |
299
|
2 |
|
'timestamp' => array($timelimit, '<'), |
300
|
2 |
|
)); |
301
|
2 |
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* Delete activities that match certain conditions |
305
|
|
|
* |
306
|
|
|
* @param array $conditions Array with conditions that have to be met |
307
|
|
|
* 'field' => 'value' => `field` = 'value' |
308
|
|
|
* 'field' => array('value', 'operator') => `field` operator 'value' |
309
|
|
|
* @return null |
310
|
|
|
*/ |
311
|
11 |
|
public function deleteActivities($conditions) { |
312
|
11 |
|
$sqlWhere = ''; |
313
|
11 |
|
$sqlParameters = $sqlWhereList = array(); |
314
|
11 |
|
foreach ($conditions as $column => $comparison) { |
315
|
11 |
|
$sqlWhereList[] = " `$column` " . ((is_array($comparison) && isset($comparison[1])) ? $comparison[1] : '=') . ' ? '; |
316
|
11 |
|
$sqlParameters[] = (is_array($comparison)) ? $comparison[0] : $comparison; |
317
|
11 |
|
} |
318
|
|
|
|
319
|
11 |
|
if (!empty($sqlWhereList)) { |
320
|
11 |
|
$sqlWhere = ' WHERE ' . implode(' AND ', $sqlWhereList); |
321
|
11 |
|
} |
322
|
|
|
|
323
|
11 |
|
$query = $this->connection->prepare( |
324
|
11 |
|
'DELETE FROM `*PREFIX*activity`' . $sqlWhere); |
325
|
11 |
|
$query->execute($sqlParameters); |
326
|
11 |
|
} |
327
|
|
|
} |
328
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.