activity.php 10.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
/**
 * This program is part of Mahara
 *
 *  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 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * @package    mahara
 * @subpackage core
 * @author     Penny Leach <penny@catalyst.net.nz>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @copyright  (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
 *
 */

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 
 */
function activity_occured($activitytype, $data) {
    if (!$at = get_record('activity_type', 'name', $activitytype)) {
        throw new Exception("Invalid activity type $activitytype");
    }

    if (!empty($at->delay)) {
        $delayed = new StdClass;
        $delayed->type = $activitytype;
        $delayed->data = serialize($data);
        $delayed->ctime = db_format_timestamp(time());
        insert_record('activity_queue', $delayed);
    }
    else {
        handle_activity($at, $data);
    }
}

/** 
 * 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
60
61
62
63
64
65
66
 * @param mixed $data must contain message to save.
 * it can also contain url.
 * each activity type has different requirements of $data - 
 * <b>admin types (contactus, objectionable, virusrepeat, virusrelease)</b> don't have any extra requirements
 * <b>maharamessage</b> must contain $users, an array of userids.
 * <b>usermessage</b> must contain $userto, id of recipient user.
 * <b>feedback</b> must contain either $view (id of view) or $artefact (id of artefact)
67
 * <b>watchlist</b> must contain either $view (id of view) or $artefact (id of artefact) or $community (id of community)
68
 * <b>newview</b> must contain $owner userid of view owner AND $view (id of new view)
69
70
71
 */
function handle_activity($activitytype, $data) {

72
73
74
75
    $data = (object)$data;
    if (empty($data->message)) {
        throw new InvalidArgumentException("message was empty for $activitytype!");
    }
76
77
78
79
80
81
82
83
84

    if (is_string($activitytype)) {
        $activitytype = get_record('activity_type', 'name', $activitytype);
    }
    
    if (!is_object($activitytype)) {
        throw new InvalidArgumentException("Invalid activitytype $activitytype");
    }

85
86
87
88
89
90
91
92
93
94
    $users = array();
    $prefix = get_config('dbprefix');

    if (!empty($activitytype->admin)) {
        $users = activity_get_users($activitytype->name, null, null, true);
    }
    else {
        switch ($activitytype->name) {
            // easy ones first :)
            case 'maharamessage':
95
                $users = activity_get_users($activitytype->name, $data->users);
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
                break;
            case 'usermessage':
                $users = activity_get_users($activitytype->name, array($data->userto));
                break;
            case 'feedback':
                if ($data->view) {
                    $userid = get_field('view', 'owner', 'id', $data->view);
                } 
                else if ($data->artefact) {
                    $userid = get_field('artefact', 'owner', 'id', $data->artefact);
                }
                $users = activity_get_users($activitytype->name, array($userid));
                break;
            // and now the harder ones
            case 'watchlist':
111
112
                if (!empty($data->view)) {
                    $sql = 'SELECT u.*, p.method, ? AS url
113
                                FROM ' . $prefix . 'usr_watchlist_view wv
114
                                JOIN ' . $prefix . 'usr u
115
116
                                    ON wa.usr = u.id
                                JOIN ' . $prefix . 'usr_activity_preference p
117
                                    ON p.usr = u.id
118
                                WHERE p.activity = ?
119
120
                                AND wv.view = ?
                           ';
121
122
123
                    $users = get_records_sql_array($sql, 
                                                   array(get_config('wwwroot') . 'view/view.php?id=' 
                                                         . $data->view, 'watchlist', $data->view));
124
                } 
125
126
                else if (!empty($data->artefact)) {
                    $sql = 'SELECT DISTINCT u.*, p.method, ?||wa.view as url
127
                                FROM ' . $prefix . 'usr_watchlist_artefact wa
128
                                LEFT JOIN ' . $prefix . 'artefact_parent_cache pc
129
130
                                    ON (pc.parent = wa.artefact OR pc.artefact = wa.artefact)
                                JOIN ' . $prefix . 'usr u 
131
132
                                    ON wa.usr = u.id
                                JOIN ' . $prefix . 'usr_activity_preference p
133
                                    ON p.usr = u.id
134
                                WHERE p.activity = ?
135
136
                                AND (pc.parent = ? OR wa.artefact = ?)
                            ';
137
138
139
140
                    $users = get_records_sql_array($sql, 
                                                   array(get_config('wwwroot') . 'view/artefact.php?id=' 
                                                         . $data->artefact . '&view=', 'watchlist', 
                                                         $data->artefact, $data->artefact));
141
                }
142
143
                else if (!empty($data->community)) {
                    $sql = 'SELECT DISTINCT u.*, p.method, ? AS url, 
144
145
146
                                FROM ' . $prefix . 'usr_watchlist_community c
                                JOIN ' . $prefix . 'usr u
                                    ON c.usr = u.id
147
                                JOIN ' . $prefix . 'usr_activity_preference p
148
                                    ON p.usr = u.id
149
                                WHERE p.activity = ?
150
151
                                AND c.community = ?
                            ';
152
153
154
                    $users = get_records_sql_array($sql, 
                                                   array(getconfig('wwwroot') . 'community/view.php?id='
                                                         . $data->community, 'watchlist', $data->community));
155
                }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
                else {
                    throw new InvalidArgumentException("Invalid watchlist type");
                }
                break;
            case 'newview':
                // add users on friendslist, userlist or grouplist...
                $sql = 'SELECT userid, u.*, p.method
                        FROM (
                            SELECT (CASE WHEN usr1 = ? THEN usr2 ELSE usr1 END) AS userid 
                                FROM ' . $prefix . 'usr_friend 
                                WHERE (usr1 = ? OR usr2 = ?)
                            UNION SELECT member AS userid 
                                FROM ' . $prefix . 'usr_group_member m
                                JOIN ' . $prefix . 'view_access_group g ON m.group = g.group 
                            WHERE g.view = ?
                            UNION SELECT usr AS userid 
                                  FROM ' . $prefix . 'view_access_usr u 
                                  WHERE u.view = ?
                        ) AS userlist
                            JOIN ' . $prefix . 'usr u ON u.id = userlist.userid
                            JOIN ' . $prefix . 'usr_activity_preference p ON p.usr = u.id';
177
                $users = get_records_sql_array($sql, array($data->owner, $data->owner, $data->owner,  
178
179
180
181
                                                     $data->view, $data->view));
                break;
        }
    }
182
183
184
    if (empty($users)) {
        return;
    }
185
    safe_require('notification', 'internal', 'lib.php', 'require_once');
186
    $data->type = $activitytype->name;
187
    foreach ($users as $user) {
188
189
190
        if (!empty($user->url) && empty($data->url)) {
            $data->url = $user->url;
        }
191
192
193
        if ($user->method != 'internal') {
            safe_require('notification', $method, 'lib.php', 'require_once');
            call_static_method(generate_class_name('notification', $method), 'notify_user', $user, $data);
194
            $user->markasread = true; // if we're doing something else, don't generate unread internal ones.
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
        }
        // always do internal
        call_static_method('PluginNotificationInternal', 'notify_user', $user, $data);
    }
}

/**
 * this function returns an array of users
 * for a particular activitytype
 * including the notification method.
 *
 * @param string $activitytype the name of the activity type
 * @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
 * @return array of users
 */
function activity_get_users($activitytype, $userids=null, $userobjs=null, $adminonly=false) {
    $values = array($activitytype);
    $sql = 'SELECT u.*, p.method
                FROM ' . get_config('dbprefix') .'usr u
                JOIN ' . get_config('dbprefix') . 'usr_activity_preference p
217
                    ON p.usr = u.id
218
219
220
221
222
223
224
225
226
227
228
229
230
                WHERE p.activity = ? ';
    if (!empty($adminonly)) {
        $sql .= ' AND u.admin = ? ';
        $values[] = 1;
    }
    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);
    }
231
    return get_records_sql_array($sql, $values);
232
233
234
235
}


?>