activity.php 27 KB
Newer Older
1
2
<?php
/**
Francois Marier's avatar
Francois Marier committed
3
 * Mahara: Electronic portfolio, weblog, resume builder and social networking
4
 * Copyright (C) 2006-2008 Catalyst IT Ltd (http://www.catalyst.net.nz)
5
 *
Francois Marier's avatar
Francois Marier committed
6
7
8
9
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
10
 *
Francois Marier's avatar
Francois Marier committed
11
12
13
14
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
15
 *
Francois Marier's avatar
Francois Marier committed
16
17
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
20
 *
 * @package    mahara
 * @subpackage core
21
 * @author     Catalyst IT Ltd
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
23
 * @copyright  (C) 2006-2008 Catalyst IT Ltd http://catalyst.net.nz
24
25
26
27
28
29
30
31
32
33
34
35
 *
 */

defined('INTERNAL') || die();

/**
 * This is the function to call whenever anything happens
 * that is going to end up on a user's activity page.
 * 
 * @param string $activitytype type of activity
 * @param mixed $data data 
 */
36
37
function activity_occurred($activitytype, $data, $plugintype=null, $pluginname=null) {
    $at = activity_locate_typerecord($activitytype, $plugintype, $pluginname);
38
39
    if (!empty($at->delay)) {
        $delayed = new StdClass;
40
        $delayed->type = $at->id;
41
42
43
44
45
        $delayed->data = serialize($data);
        $delayed->ctime = db_format_timestamp(time());
        insert_record('activity_queue', $delayed);
    }
    else {
46
        handle_activity($at, $data);
47
    }
48
49
50
51
52
53
54
55
56
}

/** 
 * This function dispatches all the activity stuff
 * to whatever notification plugin it needs to
 * and figures out all the implications of 
 * activity and who needs to know about it.
 * 
 * @param object $activitytype record from activity_type
57
58
59
 * @param mixed $data must contain message to save.
 * it can also contain url.
 * each activity type has different requirements of $data - 
60
61
62
63
64
65
66
 *  - <b>contactus</b> must contain $message, $subject (optional), $fromname, $fromaddress, $userfrom (if a logged in user)
 *  - <b>objectionable</b> must contain $message, $view and $artefact if applicable
 *  - <b>maharamessage</b> must contain $users, an array of userids. $subject and $message (contents of message)
 *  - <b>usermessage</b> must contain $userto, id of recipient user, $userfrom, id of user from 
    -       and $subject and $message (contents of message)
 *  - <b>feedback (artefact)</b> must contain both $artefact (id) and $view (id) and $message 
 *  - <b>feedback (view)</b> must contain $view (id) and $message
67
 *  - <b>watchlist (view) </b> must contain $view (id of view) as $message
68
 *  - <b>viewaccess</b> must contain $owner userid of view owner AND $view (id of view) and $oldusers array of userids before access change was committed.
69
 */
70
function handle_activity($activitytype, $data, $cron=false) {
71
    $data = (object)$data;
72
    $activitytype = activity_locate_typerecord($activitytype);
73

74
75
76
77
78
79
80
    $classname = 'ActivityType' . ucfirst($activitytype->name);
    if (!empty($activitytype->plugintype)) {
        safe_require($activitytype->plugintype, $activitytype->pluginname);
        $classname = 'ActivityType' . 
            ucfirst($activitytype->plugintype) . 
            ucfirst($activitytype->pluginname) . 
            ucfirst($activitytype->name);
81
    }
82

83
    $activity = new $classname($data, $cron);
84
    if (!$activity->any_users()) {
85
86
        return;
    }
87

88
    $activity->notify_users();
89
90
91
}

/**
92
93
 * this function returns an array of users who subsribe to a particular activitytype 
 * including the notification method they are using to subscribe to it.
94
 *
95
 * @param int $activitytype the id of the activity type
96
97
98
 * @param array $userids an array of userids to filter by
 * @param array $userobjs an array of user objects to filterby
 * @param bool $adminonly whether to filter by admin flag
99
 * @param array $admininstitutions list of institution names to get admins for
100
101
 * @return array of users
 */
102
103
function activity_get_users($activitytype, $userids=null, $userobjs=null, $adminonly=false,
                            $admininstitutions = array()) {
104
    $values = array($activitytype);
105
106
    $sql = '
        SELECT
107
108
            u.id, u.username, u.firstname, u.lastname, u.preferredname, u.email, u.admin, u.staff, 
            p.method, ap.value AS lang
109
110
111
112
113
114
        FROM {usr} u
        LEFT JOIN {usr_activity_preference} p
            ON p.usr = u.id ' . (empty($admininstitutions) ? '' : '
        LEFT OUTER JOIN {usr_institution} ui
            ON (u.id = ui.usr
                AND ui.institution IN ('.join(',',array_map('db_quote',$admininstitutions)).'))') . '
115
116
        LEFT OUTER JOIN {usr_account_preference} ap
            ON (ap.usr = u.id AND ap.field = \'lang\')
117
        WHERE (p.activity = ? ' . ($adminonly ? '' : ' OR p.activity IS NULL') . ')';
118
119
120
121
122
123
124
125
    if (!empty($userobjs) && is_array($userobjs)) {
        $sql .= ' AND u.id IN (' . implode(',',db_array_to_ph($userobjs)) . ')';
        $values = array_merge($values, array_to_fields($userobjs));
    } 
    else if (!empty($userids) && is_array($userids)) {
        $sql .= ' AND u.id IN (' . implode(',',db_array_to_ph($userids)) . ')';
        $values = array_merge($values, $userids);
    }
126
127
128
    if (!empty($admininstitutions)) {
        $sql .= '
        GROUP BY
129
130
            u.id, u.username, u.firstname, u.lastname, u.preferredname, u.email, u.admin, u.staff,
            p.method, ap.value
131
132
133
134
        HAVING (u.admin = 1 OR SUM(ui.admin) > 0)';
    } else if ($adminonly) {
        $sql .= ' AND u.admin = 1';
    }
135
    return get_records_sql_array($sql, $values);
136
137
}

138
139
140
141
/**
 * this function inserts a default set of activity preferences for a given user
 * id
 */
142
143
function activity_set_defaults($eventdata) {
    $user_id = $eventdata['id'];
144
    $activitytypes = get_records_array('activity_type', 'admin', 0);
145
146
    $haveemail = in_array('email', array_map(create_function('$a', 'return $a->name;'),
                                             plugins_installed('notification')));
147
    foreach ($activitytypes as $type) {
148
        if ($haveemail) {
149
            $method = 'email';
150
151
        }
        else {
152
153
            $method = 'internal';
        }
154
155
        insert_record('usr_activity_preference', (object)array(
            'usr' => $user_id,
Richard Mansfield's avatar
Richard Mansfield committed
156
            'activity' => $type->id,
157
            'method' => $method,
158
        ));
159
160
161
162
    }
    
}

163
164
165
166
function activity_add_admin_defaults($userids) {
    $activitytypes = get_records_array('activity_type', 'admin', 1);
    foreach ($activitytypes as $type) {
        foreach ($userids as $id) {
167
            if (!record_exists('usr_activity_preference', 'usr', $id, 'activity', $type->id)) {
168
169
                insert_record('usr_activity_preference', (object)array(
                    'usr' => $id,
170
                    'activity' => $type->id,
171
172
173
174
175
176
177
178
                    'method' => 'internal',
                ));
            }
        }
    }
}


179
180
function activity_process_queue() {

181
    db_begin();
182
    if ($toprocess = get_records_array('activity_queue')) {
183
184
185
        // Hack to avoid duplicate watchlist notifications on the same view
        $watchlist = activity_locate_typerecord('watchlist');
        $viewsnotified = array();
186
        foreach ($toprocess as $activity) {
187
188
189
190
191
192
193
194
            $data = unserialize($activity->data);
            if ($activity->type == $watchlist->id && !empty($data->view)) {
                if (isset($viewsnotified[$data->view])) {
                    continue;
                }
                $viewsnotified[$data->view] = true;
            }
            handle_activity($activity->type, $data, true);
195
196
197
198
199
        }
        delete_records('activity_queue');
    }
    db_commit();
}
200

201
function activity_get_viewaccess_users($view, $owner, $type) {
202
    $type = activity_locate_typerecord($type);
203
    $sql = "SELECT userid, u.*, p.method, ap.value AS lang
204
205
                FROM (
                SELECT (CASE WHEN usr1 = ? THEN usr2 ELSE usr1 END) AS userid 
206
207
208
                    FROM {usr_friend} f
                    JOIN {view} v ON (v.owner = f.usr1 OR v.owner = f.usr2)
                    JOIN {view_access} vu ON vu.view = v.id
209
                        WHERE (usr1 = ? OR usr2 = ?) AND vu.accesstype = ? AND v.id = ? 
210
                UNION SELECT usr AS userid 
211
                    FROM {view_access_usr} u 
212
                        WHERE u.view = ?
213
                UNION SELECT m.member 
214
                    FROM {group_member} m
215
216
                    JOIN {view_access_group} vg ON vg.group = m.group
                    JOIN {group} g ON (g.id = vg.group AND g.deleted = 0)
217
                        WHERE vg.view = ? AND (vg.role IS NULL OR vg.role = m.role)
218
                ) AS userlist
219
                JOIN {usr} u ON u.id = userlist.userid
220
221
                LEFT JOIN {usr_activity_preference} p ON p.usr = u.id AND p.activity = ?
                LEFT JOIN {usr_account_preference} ap ON ap.usr = u.id AND ap.field = 'lang'";
222
    $values = array($owner, $owner, $owner, 'friends', $view, $view, $view, $type->id);
223
    if (!$u = get_records_sql_assoc($sql, $values)) {
224
225
226
        $u = array();
    }
    return $u;
227
228
}

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
function activity_locate_typerecord($activitytype, $plugintype=null, $pluginname=null) {
    if (is_object($activitytype)) {
        return $activitytype;
    }
    if (is_numeric($activitytype)) {
        $at = get_record('activity_type', 'id', $activitytype);
    }
    else {
        if (empty($plugintype) && empty($pluginname)) {
            $at = get_record_select('activity_type', 
                'name = ? AND plugintype IS NULL AND pluginname IS NULL', 
                array($activitytype));
        } 
        else {
            $at = get_record('activity_type', 'name', $activitytype, 'plugintype', $plugintype, 'pluginname', $pluginname);
        }
    }
    if (empty($at)) {
        throw new Exception("Invalid activity type $activitytype");
    }
    return $at;
}
251
252
253
254
255
256
257
258

/** activity type classes **/
abstract class ActivityType {
    
    protected $subject;
    protected $message;
    protected $users = array();
    protected $url;
259
    protected $id;
260
261
    protected $type;
    protected $activityname;
262
    protected $cron;
263
264
265
266
267
268
269
270
   
    public function get_id() {
        if (!isset($this->id)) {
            $tmp = activity_locate_typerecord($this->get_type());
            $this->id = $tmp->id;
        }
        return $this->id;
    }
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    
    public function get_type() {
        $prefix = 'ActivityType';
        return strtolower(substr(get_class($this), strlen($prefix)));
    }

    public function any_users() {
        return (is_array($this->users) && count($this->users) > 0);
    }

    public function get_users() {
        return $this->users;
    }

285
286
    public function __construct($data, $cron=false) {
        $this->cron = $cron;
287
288
        $this->set_parameters($data);
        $this->ensure_parameters();
289
        $this->activityname = strtolower(substr(get_class($this), strlen('ActivityType')));
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    }

    private function set_parameters($data) {
        foreach ($data as $key => $value) {
            if (property_exists($this, $key)) {
                $this->{$key} = $value;
            }
        }   
    }

    private function ensure_parameters() {
        foreach ($this->get_required_parameters() as $param) {
            if (!isset($this->{$param})) {
                throw new ParamOutOfRangeException(get_string('missingparam', 'activity', $param, $this->get_type()));
            }
        }
    }

    public function to_stdclass() {
       return (object)get_object_vars($this); 
    }
311
312
313
314

    public function get_message($user) {
        return $this->message;
    }
315
        
316
317
318
    public function get_subject($user) {
        return $this->subject;
    }
319
320

    abstract function get_required_parameters();
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

    public function notify_user($user) {
        $userdata = $this->to_stdclass();
        // some stuff gets overridden by user specific stuff
        if (!empty($user->url)) {
            $userdata->url = $user->url;
        }
        if (empty($user->lang) || $user->lang == 'default') {
            $user->lang = get_config('lang');
        }
        $userdata->message = $this->get_message($user);
        $userdata->subject = $this->get_subject($user);
        if (empty($user->method)) {
            $user->method = 'internal';
        }
        if ($user->method != 'internal') {
            $method = $user->method;
            safe_require('notification', $method, 'lib.php', 'require_once');
            try {
                call_static_method(generate_class_name('notification', $method), 'notify_user', $user, $userdata);
                $user->markasread = true; // if we're doing something else, don't generate unread internal ones.
            }
            catch (Exception $e) {
                $user->markasread = false; // if we fail (eg email falls over), don't mark it as read...
345
                // @todo Catalyst IT Ltd
346
347
348
349
350
351
352
353
354
355
356
357
358
359
            }
        }
        // always do internal
        call_static_method('PluginNotificationInternal', 'notify_user', $user, $userdata);
    }

    public function notify_users() {
        safe_require('notification', 'internal', 'lib.php', 'require_once');
        $this->type = $this->get_id();

        foreach ($this->get_users() as $user) {
            $this->notify_user($user);
        }
    }
360
361
362
363
364
}


abstract class ActivityTypeAdmin extends ActivityType { 

365
366
    public function __construct($data, $cron=false) {
        parent::__construct($data, $cron);
367
        $this->users = activity_get_users($this->get_id(), null, null, true);
368
369
370
371
372
373
374
375
376
    }
}

class ActivityTypeContactus extends ActivityTypeAdmin {
    
    protected $fromname;
    protected $fromemail;
    protected $userfrom;

377
378
    function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
379
380
381
382
        if (!empty($this->userfrom)) {
            $this->url = get_config('wwwroot') . 'user/view.php?id=' . $this->userfrom;
        }
    }
383
384
385
386
387
388
389
390
391
392
393

    function get_subject($user) {
        return get_string_from_language($user->lang, 'newcontactus', 'activity');
    }

    function get_message($user) {
        return get_string_from_language($user->lang, 'newcontactusfrom', 'activity') . ' ' . $this->fromname 
            . '<' . $this->fromemail .'>' . (isset($this->subject) ? ': ' . $this->subject : '')
            . "\n\n" . $this->message;
    }

394
395
396
397
398
399
400
401
402
    public function get_required_parameters() {
        return array('message', 'fromname', 'fromemail');
    }
}

class ActivityTypeObjectionable extends ActivityTypeAdmin {

    protected $view;
    protected $artefact;
403
    protected $reporter;
404

405
406
    function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
407
408
409
410
411
412
413
414
415
        if (empty($this->artefact)) {
            $this->url = get_config('wwwroot') . 'view/view.php?id=' . $this->view;
        }
        else {
            $this->url = get_config('wwwroot') . 'view/artefact.php?artefact=' . $this->artefact . '&view=' . $this->view;
        }
    }

    function get_subject($user) {
416
417
418
419
        if (!$viewtitle = get_field('view', 'title', 'id', $this->view)) {
            throw new ViewNotFoundException(get_string('viewnotfound', 'error', $this->view));
        }
        if (empty($this->artefact)) {
420
421
            return get_string_from_language($user->lang, 'objectionablecontentview', 'activity',
                                            $viewtitle, display_name($this->reporter, $user));
422
423
424
425
426
        }
        else {
            if (!$artefacttitle = get_field('artefact', 'title', 'id', $this->artefact)) {
                throw new ArtefactNotFoundException(get_string('artefactnotfound', 'error', $this->artefact));
            }
427
428
            return get_string_from_language($user->lang, 'objectionablecontentartefact', 'activity',
                                            $artefacttitle, display_name($this->reporter, $user));
429
430
431
432
        }
    }

    public function get_required_parameters() {
433
        return array('message', 'view', 'reporter');
434
435
436
437
438
439
440
441
442
443
    }

}

class ActivityTypeVirusRepeat extends ActivityTypeAdmin {

    protected $username;
    protected $fullname;
    protected $userid;

444
445
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
446
447
448
    }

    public function get_subject($user) {
449
        $userstring = $this->username . ' (' . $this->fullname . ') (userid:' . $this->userid . ')' ;
450
451
452
453
454
        return get_string_from_language($user->lang, 'virusrepeatsubject', 'mahara', $userstring);
    }

    public function get_message($user) {
        return get_string_from_language($user->lang, 'virusrepeatmessage');
455
456
457
458
459
460
461
462
463
    }

    public function get_required_parameters() {
        return array('username', 'fullname', 'userid');
    }
}

class ActivityTypeVirusRelease extends ActivityTypeAdmin {

464
465
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
466
467
468
469
470
471
472
473
474
    }

    public function get_required_parameters() {
        return array();
    }
}

class ActivityTypeMaharamessage extends ActivityType {

475
476
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
477
        $this->users = activity_get_users($this->get_id(), $this->users);
478
479
480
481
482
483
484
    }

    public function get_required_parameters() {
        return array('message', 'subject', 'users');
    }
}

485
486
487
488
489
490
491
class ActivityTypeInstitutionmessage extends ActivityType {

    protected $messagetype;
    protected $institution;
    protected $username;
    protected $fullname;

492
493
    public function __construct($data, $cron=false) {
        parent::__construct($data, $cron);
494
495
496
497
498
        if ($this->messagetype == 'request') {
            $this->url = get_config('wwwroot') . 'admin/users/institutionusers.php';
            $this->users = activity_get_users($this->get_id(), null, null, null,
                                              array($this->institution->name));
        } else if ($this->messagetype == 'invite') {
499
            $this->url = get_config('wwwroot') . 'account/institutions.php';
500
501
502
503
            $this->users = activity_get_users($this->get_id(), $this->users);
        }
    }

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
    public function get_subject($user) {
        if ($this->messagetype == 'request') {
            $userstring = $this->fullname . ' (' . $this->username . ')';
            return get_string_from_language($user->lang, 'institutionrequestsubject', 'activity', $userstring, 
                                            $this->institution->displayname);
        } else if ($this->messagetype == 'invite') {
            return get_string_from_language($user->lang, 'institutioninvitesubject', 'activity', 
                                            $this->institution->displayname);
        }
    }

    public function get_message($user) {
        if ($this->messagetype == 'request') {
            return get_string_from_language($user->lang, 'institutionrequestmessage', 'activity');
        } else if ($this->messagetype == 'invite') {
            return get_string_from_language($user->lang, 'institutioninvitemessage', 'activity');
        }
    }

523
524
525
526
527
    public function get_required_parameters() {
        return array('messagetype', 'institution');
    }
}

528
529
530
531
532
class ActivityTypeUsermessage extends ActivityType { 

    protected $userto;
    protected $userfrom;

533
534
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
535
        $this->users = activity_get_users($this->get_id(), array($this->userto));
536
537
538
539
540
        if (empty($this->url)) {
            $this->url = get_config('wwwroot') . 'user/view.php?id=' . $this->userfrom;
        }
    } 

541
542
    public function get_subject($user) {
        if (empty($this->subject)) {
Clare Lenihan's avatar
Clare Lenihan committed
543
            return get_string_from_language($user->lang, 'newusermessage', 'group',
544
545
546
547
548
                                            display_name($this->userfrom));
        }
        return $this->subject;
    }

549
550
551
552
553
554
555
556
557
558
559
    public function get_required_parameters() {
        return array('message', 'userto', 'userfrom');
    }
    
}

class ActivityTypeFeedback extends ActivityType { 

    protected $view;
    protected $artefact;

560
561
562
    private $viewrecord;
    private $artefactinstance;

563
564
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
565

566
        if (!empty($this->artefact)) { // feedback on artefact
567
            $userid = null;
568
569
570
571
            require_once(get_config('docroot') . 'artefact/lib.php');
            $this->artefactinstance = artefact_instance_from_id($this->artefact);
            if ($this->artefactinstance->feedback_notify_owner()) {
                $userid = $this->artefactinstance->get('owner');
572
573
            }
            if (empty($this->url)) {
574
575
                $this->url = get_config('wwwroot') . 'view/artefact.php?artefact=' 
                    . $this->artefact . '&view=' . $this->view;
576
577
578
            }
        } 
        else { // feedback on view.
579
            if (!$this->viewrecord = get_record('view', 'id', $this->view)) {
580
581
                throw new ViewNotFoundException(get_string('viewnotfound', 'error', $this->view));
            }
582
            $userid = $this->viewrecord->owner;
583
584
585
586
587
            if (empty($this->url)) {
                $this->url = get_config('wwwroot') . 'view/view.php?id=' . $this->view;
            }
        }
        if ($userid) {
588
            $this->users = activity_get_users($this->get_id(), array($userid));
589
590
591
        } 
    }

592
593
594
595
596
597
598
599
600
601
602
    public function get_subject($user) {
        if (!empty($this->artefact)) { // feedback on artefact
            return get_string_from_language($user->lang, 'newfeedbackonartefact', 'activity')
                . ' ' . $this->artefactinstance->get('title');
        }
        else {
            return get_string_from_language($user->lang, 'newfeedbackonview', 'activity')
                . ' ' . $this->viewrecord->title;
        }
    }

603
604
605
606
607
608
609
610
611
    public function get_required_parameters() {
        return array('message', 'view');
    }
}

class ActivityTypeWatchlist extends ActivityType { 

    protected $view;

612
613
    private $viewinfo;

614
615
    public function __construct($data, $cron) { 
        parent::__construct($data, $cron); 
616
617
        //$oldsubject = $this->subject;
        if (!$this->viewinfo = get_record_sql('SELECT u.*, v.title FROM {usr} u
618
619
                                         JOIN {view} v ON v.owner = u.id
                                         WHERE v.id = ?', array($this->view))) {
620
            if (!empty($this->cron)) { // probably deleted already
621
622
623
624
                return;
            }
            throw new ViewNotFoundException(get_string('viewnotfound', 'error', $this->view));
        }
625
626
627
628
629
        // mysql compatibility (sigh...)
        $casturl = 'CAST(? AS TEXT)';
        if (get_config('dbtype') == 'mysql') {
            $casturl = 'CAST(? AS CHAR)'; // note, NOT varchar
        }
630
        $sql = 'SELECT u.*, p.method, ap.value AS lang, ' . $casturl . ' AS url
631
632
633
634
635
                    FROM {usr_watchlist_view} wv
                    JOIN {usr} u
                        ON wv.usr = u.id
                    LEFT JOIN {usr_activity_preference} p
                        ON p.usr = u.id
636
637
                    LEFT OUTER JOIN {usr_account_preference} ap
                        ON (ap.usr = u.id AND ap.field = \'lang\')
638
639
640
641
642
                    WHERE (p.activity = ? OR p.activity IS NULL)
                    AND wv.view = ?
               ';
        $this->users = get_records_sql_array($sql, 
                                       array(get_config('wwwroot') . 'view/view.php?id=' 
643
                                             . $this->view, $this->get_id(), $this->view));
644
645
646
647
648
649
650
    }

    public function get_subject($user) {
        return get_string_from_language($user->lang, 'newwatchlistmessage', 'activity');
    }

    public function get_message($user) {
651
652
        return get_string_from_language($user->lang, 'newwatchlistmessageview', 'activity', 
                                        display_name($this->viewinfo, $user), $this->viewinfo->title);
653
654
655
    }

    public function get_required_parameters() {
656
        return array('view');
657
658
659
660
661
662
663
664
    }
}

class ActivityTypeNewview extends ActivityType { 

    protected $owner;
    protected $view;

665
666
    private $viewinfo;

667
668
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
669
        if (!$this->viewinfo = get_record_sql('SELECT u.*, v.title FROM {usr} u
670
671
                                         JOIN {view} v ON v.owner = u.id
                                         WHERE v.id = ?', array($this->view))) {
672
            if (!empty($this->cron)) { //probably deleted already
673
674
675
676
677
678
679
680
                return;
            }
            throw new ViewNotFoundException(get_string('viewnotfound', 'error', $this->view));
        }

        $this->url = get_config('wwwroot') . 'view/view.php?id=' . $this->view;

        // add users on friendslist or userlist...
681
        $this->users = activity_get_viewaccess_users($this->view, $this->owner, $this->get_id()); 
682
683
684
685
686
687
688
    }

    public function get_subject($user) {
        return get_string_from_language($user->lang, 'newviewsubject', 'activity');
    }
    
    public function get_message($user) {
689
690
        return get_string_from_language($user->lang, 'newviewmessage', 'activity', 
                                        display_name($this->viewinfo, $user), $this->viewinfo->title);
691
692
693
694
695
696
697
698
699
700
701
702
703
    }
    
    public function get_required_parameters() {
        return array('owner', 'view');
    }
}

class ActivityTypeViewaccess extends ActivityType { 

    protected $view;
    protected $owner;
    protected $oldusers; // this can be empty though

704
705
    private $viewinfo;

706
707
    public function __construct($data, $cron=false) { 
        parent::__construct($data, $cron);
708
        if (!$this->viewinfo = get_record_sql('SELECT u.*, v.title FROM {usr} u
709
710
                                         JOIN {view} v ON v.owner = u.id
                                         WHERE v.id = ?', array($this->view))) {
711
            if (!empty($this->cron)) { // probably deleted already
712
713
714
715
716
717
                return;
            }
            throw new ViewNotFoundException(get_string('viewnotfound', 'error', $this->view));
        }
        $this->url = get_config('wwwroot') . 'view/view.php?id=' . $this->view;
        $this->users = array_diff_key(
718
            activity_get_viewaccess_users($this->view, $this->owner, $this->get_id()),
719
720
            $this->oldusers
        );
721
    }
722

723
724
725
726
727
    public function get_subject($user) {
        return get_string('newviewaccesssubject', 'activity');
    }
    
    public function get_message($user) {
728
729
        return get_string_from_language($user->lang, 'newviewaccessmessage', 'activity',
                                        $this->viewinfo->title, display_name($this->viewinfo, $user));
730
731
    }
    
732
733
734
735
736
    public function get_required_parameters() {
        return array('view', 'owner', 'oldusers');
    }
}

737
738
739
740
741
742
abstract class ActivityTypePlugin extends ActivityType {

    abstract public function get_plugintype();

    abstract public function get_pluginname();

743
744
745
746
747
    public function get_type() {
        $prefix = 'ActivityType' . $this->get_plugintype() . $this->get_pluginname();
        return strtolower(substr(get_class($this), strlen($prefix)));
    }

748
749
750
751
752
753
754
755
756
    public function get_id() {
        if (!isset($this->id)) {
            $tmp = activity_locate_typerecord($this->get_type(), $this->get_plugintype(), $this->get_pluginname());
            $this->id = $tmp->id;
        }
        return $this->id;
    }
}

757
?>