This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | //------------------------------------------------------------------------------ |
||
4 | // |
||
5 | // eTraxis - Records tracking web-based system |
||
6 | // Copyright (C) 2005-2011 Artem Rodygin |
||
7 | // |
||
8 | // This program is free software: you can redistribute it and/or modify |
||
9 | // it under the terms of the GNU General Public License as published by |
||
10 | // the Free Software Foundation, either version 3 of the License, or |
||
11 | // (at your option) any later version. |
||
12 | // |
||
13 | // This program is distributed in the hope that it will be useful, |
||
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | // GNU General Public License for more details. |
||
17 | // |
||
18 | // You should have received a copy of the GNU General Public License |
||
19 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
20 | // |
||
21 | //------------------------------------------------------------------------------ |
||
22 | |||
23 | /** |
||
24 | * Events |
||
25 | * |
||
26 | * This module provides API to work with events of records. |
||
27 | * See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_events tbl_events} database table. |
||
28 | * |
||
29 | * @package DBO |
||
30 | * @subpackage Events |
||
31 | */ |
||
32 | |||
33 | /**#@+ |
||
34 | * Dependency. |
||
35 | */ |
||
36 | require_once('../engine/engine.php'); |
||
37 | require_once('../dbo/accounts.php'); |
||
38 | require_once('../dbo/states.php'); |
||
39 | /**#@-*/ |
||
40 | |||
41 | //------------------------------------------------------------------------------ |
||
42 | // Definitions. |
||
43 | //------------------------------------------------------------------------------ |
||
44 | |||
45 | /**#@+ |
||
46 | * Event type. |
||
47 | */ |
||
48 | define('EVENT_UNUSED', 0); |
||
49 | define('EVENT_RECORD_CREATED', 1); |
||
50 | define('EVENT_RECORD_ASSIGNED', 2); |
||
51 | define('EVENT_RECORD_MODIFIED', 3); |
||
52 | define('EVENT_RECORD_STATE_CHANGED', 4); |
||
53 | define('EVENT_RECORD_POSTPONED', 5); |
||
54 | define('EVENT_RECORD_RESUMED', 6); |
||
55 | define('EVENT_COMMENT_ADDED', 7); |
||
56 | define('EVENT_FILE_ATTACHED', 8); |
||
57 | define('EVENT_FILE_REMOVED', 9); |
||
58 | define('EVENT_RECORD_CLONED', 10); |
||
59 | define('EVENT_SUBRECORD_ADDED', 11); |
||
60 | define('EVENT_SUBRECORD_REMOVED', 12); |
||
61 | define('EVENT_CONFIDENTIAL_COMMENT', 13); |
||
62 | define('EVENT_RECORD_REOPENED', 14); |
||
63 | define('EVENT_RECORD_SUBSCRIBED', 100); |
||
64 | define('EVENT_RECORD_UNSUBSCRIBED', 101); |
||
65 | /**#@-*/ |
||
66 | |||
67 | /**#@+ |
||
68 | * Permission. |
||
69 | */ |
||
70 | define('PERMIT_CREATE_RECORD', 0x0001); |
||
71 | define('PERMIT_MODIFY_RECORD', 0x0002); |
||
72 | define('PERMIT_POSTPONE_RECORD', 0x0004); |
||
73 | define('PERMIT_RESUME_RECORD', 0x0008); |
||
74 | define('PERMIT_REASSIGN_RECORD', 0x0010); |
||
75 | define('PERMIT_REOPEN_RECORD', 0x0020); |
||
76 | define('PERMIT_ADD_COMMENTS', 0x0040); |
||
77 | define('PERMIT_ATTACH_FILES', 0x0080); |
||
78 | define('PERMIT_REMOVE_FILES', 0x0100); |
||
79 | define('PERMIT_CONFIDENTIAL_COMMENTS', 0x0200); |
||
80 | define('PERMIT_SEND_REMINDERS', 0x0400); |
||
81 | define('PERMIT_DELETE_RECORD', 0x0800); |
||
82 | define('PERMIT_ADD_SUBRECORDS', 0x1000); |
||
83 | define('PERMIT_REMOVE_SUBRECORDS', 0x2000); |
||
84 | define('PERMIT_VIEW_RECORD', 0x40000000); |
||
85 | /**#@-*/ |
||
86 | |||
87 | /**#@+ |
||
88 | * Notifications filter. |
||
89 | */ |
||
90 | define('NOTIFY_RECORD_CREATED', 0x0001); |
||
91 | define('NOTIFY_RECORD_ASSIGNED', 0x0002); |
||
92 | define('NOTIFY_RECORD_MODIFIED', 0x0004); |
||
93 | define('NOTIFY_RECORD_STATE_CHANGED', 0x0008); |
||
94 | define('NOTIFY_RECORD_POSTPONED', 0x0010); |
||
95 | define('NOTIFY_RECORD_RESUMED', 0x0020); |
||
96 | define('NOTIFY_COMMENT_ADDED', 0x0040); |
||
97 | define('NOTIFY_FILE_ATTACHED', 0x0080); |
||
98 | define('NOTIFY_FILE_REMOVED', 0x0100); |
||
99 | define('NOTIFY_RECORD_CLONED', 0x0200); |
||
100 | define('NOTIFY_SUBRECORD_ADDED', 0x0400); |
||
101 | define('NOTIFY_SUBRECORD_REMOVED', 0x0800); |
||
102 | define('NOTIFY_RECORD_REOPENED', 0x1000); |
||
103 | /**#@-*/ |
||
104 | |||
105 | // Correspondence between event types |
||
106 | // and notifications filter. |
||
107 | $notifications_filter = array |
||
108 | ( |
||
109 | EVENT_RECORD_CREATED => NOTIFY_RECORD_CREATED, |
||
110 | EVENT_RECORD_ASSIGNED => NOTIFY_RECORD_ASSIGNED, |
||
111 | EVENT_RECORD_MODIFIED => NOTIFY_RECORD_MODIFIED, |
||
112 | EVENT_RECORD_STATE_CHANGED => NOTIFY_RECORD_STATE_CHANGED, |
||
113 | EVENT_RECORD_POSTPONED => NOTIFY_RECORD_POSTPONED, |
||
114 | EVENT_RECORD_RESUMED => NOTIFY_RECORD_RESUMED, |
||
115 | EVENT_RECORD_REOPENED => NOTIFY_RECORD_REOPENED, |
||
116 | EVENT_COMMENT_ADDED => NOTIFY_COMMENT_ADDED, |
||
117 | EVENT_FILE_ATTACHED => NOTIFY_FILE_ATTACHED, |
||
118 | EVENT_FILE_REMOVED => NOTIFY_FILE_REMOVED, |
||
119 | EVENT_RECORD_CLONED => NOTIFY_RECORD_CLONED, |
||
120 | EVENT_SUBRECORD_ADDED => NOTIFY_SUBRECORD_ADDED, |
||
121 | EVENT_SUBRECORD_REMOVED => NOTIFY_SUBRECORD_REMOVED, |
||
122 | EVENT_CONFIDENTIAL_COMMENT => NOTIFY_COMMENT_ADDED, |
||
123 | ); |
||
124 | |||
125 | //------------------------------------------------------------------------------ |
||
126 | // Functions. |
||
127 | //------------------------------------------------------------------------------ |
||
128 | |||
129 | /** |
||
130 | * Finds in database and returns the information about specified event of particular record. |
||
131 | * |
||
132 | * @param int $record_id Record ID. |
||
133 | * @param int $type Type of event. |
||
134 | * @param int $time {@link http://en.wikipedia.org/wiki/Unix_time Unix timestamp} of event. |
||
135 | * @param int $param Parameter of event, depends on the event type. |
||
136 | * @return array Array with data if event is found in database, FALSE otherwise. |
||
137 | */ |
||
138 | function event_find ($record_id, $type, $time, $param) |
||
139 | { |
||
140 | debug_write_log(DEBUG_TRACE, '[event_find]'); |
||
141 | debug_write_log(DEBUG_DUMP, '[event_find] $record_id = ' . $record_id); |
||
142 | debug_write_log(DEBUG_DUMP, '[event_find] $type = ' . $type); |
||
143 | debug_write_log(DEBUG_DUMP, '[event_find] $time = ' . $time); |
||
144 | debug_write_log(DEBUG_DUMP, '[event_find] $param = ' . $param); |
||
145 | |||
146 | $rs = dal_query(is_null($param) ? 'events/fndk2.sql' : 'events/fndk.sql', |
||
147 | $record_id, |
||
148 | $_SESSION[VAR_USERID], |
||
149 | $type, |
||
150 | $time, |
||
151 | $param); |
||
152 | |||
153 | return ($rs->rows == 0 ? FALSE : $rs->fetch()); |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Creates new event for specified record. |
||
158 | * |
||
159 | * @param int $record_id Record ID. |
||
160 | * @param int $type Type of event. |
||
161 | * @param int $time {@link http://en.wikipedia.org/wiki/Unix_time Unix timestamp} of event. |
||
162 | * @param int $param Parameter of event, depends on the event type. |
||
163 | * @return array Array with data of event if it was successfully created, FALSE otherwise. |
||
164 | */ |
||
165 | function event_create ($record_id, $type, $time, $param = NULL) |
||
166 | { |
||
167 | debug_write_log(DEBUG_TRACE, '[event_create]'); |
||
168 | debug_write_log(DEBUG_DUMP, '[event_create] $record_id = ' . $record_id); |
||
169 | debug_write_log(DEBUG_DUMP, '[event_create] $type = ' . $type); |
||
170 | debug_write_log(DEBUG_DUMP, '[event_create] $time = ' . $time); |
||
171 | debug_write_log(DEBUG_DUMP, '[event_create] $param = ' . $param); |
||
172 | |||
173 | dal_query('events/create.sql', |
||
174 | $record_id, |
||
175 | $_SESSION[VAR_USERID], |
||
176 | $type, |
||
177 | $time, |
||
178 | is_null($param) ? NULL : $param); |
||
179 | |||
180 | dal_query('records/change.sql', |
||
181 | $record_id, |
||
182 | $time); |
||
183 | |||
184 | return event_find($record_id, $type, $time, is_null($param) ? NULL : $param); |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Deletes specified event. |
||
189 | * |
||
190 | * @param int $event_id ID of event to be deleted. |
||
191 | * @return int Always {@link NO_ERROR}. |
||
192 | */ |
||
193 | function event_destroy ($event_id) |
||
194 | { |
||
195 | debug_write_log(DEBUG_TRACE, '[event_destroy]'); |
||
196 | debug_write_log(DEBUG_DUMP, '[event_destroy] $event_id = ' . $event_id); |
||
197 | |||
198 | dal_query('events/delete.sql', $event_id); |
||
199 | |||
200 | return NO_ERROR; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Generates and returns string of text, describing specified event. |
||
205 | * |
||
206 | * @param int $event_id ID of event to be described. |
||
207 | * @param int $event_type Type of event. |
||
208 | * @param int $event_param Parameter of event, depends on the event type. |
||
209 | * @param int $locale ID of language. If omitted, then language of current user, or (when user is not logged in) default language will be used (see {@link LANG_DEFAULT}). |
||
210 | * @return string Event description, or NULL on failure. |
||
211 | */ |
||
212 | function get_event_string ($event_id, $event_type, $event_param, $locale = NULL) |
||
213 | { |
||
214 | debug_write_log(DEBUG_TRACE, '[get_event_string]'); |
||
215 | debug_write_log(DEBUG_DUMP, '[get_event_string] $event_id = ' . $event_id); |
||
216 | debug_write_log(DEBUG_DUMP, '[get_event_string] $event_type = ' . $event_type); |
||
217 | debug_write_log(DEBUG_DUMP, '[get_event_string] $event_param = ' . $event_param); |
||
218 | debug_write_log(DEBUG_DUMP, '[get_event_string] $locale = ' . $locale); |
||
219 | |||
220 | $res = NULL; |
||
221 | |||
222 | switch ($event_type) |
||
223 | { |
||
224 | View Code Duplication | case EVENT_RECORD_CREATED: |
|
225 | $state = state_find($event_param); |
||
226 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_CREATED_ID, $locale), ustr2html($state['state_name'])); |
||
227 | break; |
||
228 | |||
229 | case EVENT_RECORD_ASSIGNED: |
||
230 | $account = account_find($event_param); |
||
231 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_ASSIGNED_ID, $locale), ustr2html(is_null($locale) ? sprintf('%s (%s)', $account['fullname'], account_get_username($account['username'])) : $account['fullname'])); |
||
232 | break; |
||
233 | |||
234 | case EVENT_RECORD_MODIFIED: |
||
235 | $res = get_html_resource(RES_EVENT_RECORD_MODIFIED_ID, $locale); |
||
236 | break; |
||
237 | |||
238 | View Code Duplication | case EVENT_RECORD_STATE_CHANGED: |
|
239 | $state = state_find($event_param); |
||
240 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_STATE_CHANGED_ID, $locale), ustr2html($state['state_name'])); |
||
241 | break; |
||
242 | |||
243 | case EVENT_RECORD_POSTPONED: |
||
244 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_POSTPONED_ID, $locale), get_date($event_param, $locale)); |
||
245 | break; |
||
246 | |||
247 | case EVENT_RECORD_RESUMED: |
||
248 | $res = get_html_resource(RES_EVENT_RECORD_RESUMED_ID, $locale); |
||
249 | break; |
||
250 | |||
251 | View Code Duplication | case EVENT_RECORD_REOPENED: |
|
252 | $state = state_find($event_param); |
||
253 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_REOPENED_ID, $locale), ustr2html($state['state_name'])); |
||
254 | break; |
||
255 | |||
256 | case EVENT_COMMENT_ADDED: |
||
257 | $res = get_html_resource(RES_EVENT_COMMENT_ADDED_ID, $locale); |
||
258 | break; |
||
259 | |||
260 | View Code Duplication | case EVENT_FILE_ATTACHED: |
|
261 | $rs2 = dal_query('attachs/fndk.sql', $event_id); |
||
262 | $name = ($rs2->rows == 0 ? '?' : $rs2->fetch('attachment_name')); |
||
263 | $res = ustrprocess(get_html_resource(RES_EVENT_FILE_ATTACHED_ID, $locale), ustr2html($name)); |
||
264 | break; |
||
265 | |||
266 | View Code Duplication | case EVENT_FILE_REMOVED: |
|
267 | $rs2 = dal_query('attachs/fndid.sql', $event_param); |
||
268 | $name = ($rs2->rows == 0 ? '?' : $rs2->fetch('attachment_name')); |
||
269 | $res = ustrprocess(get_html_resource(RES_EVENT_FILE_REMOVED_ID, $locale), ustr2html($name)); |
||
270 | break; |
||
271 | |||
272 | case EVENT_RECORD_CLONED: |
||
273 | $res = ustrprocess(get_html_resource(RES_EVENT_RECORD_CLONED_ID, $locale), str_pad($event_param, 3, '0', STR_PAD_LEFT)); |
||
274 | break; |
||
275 | |||
276 | case EVENT_SUBRECORD_ADDED: |
||
277 | $res = ustrprocess(get_html_resource(RES_EVENT_SUBRECORD_ADDED_ID, $locale), str_pad($event_param, 3, '0', STR_PAD_LEFT)); |
||
278 | break; |
||
279 | |||
280 | case EVENT_SUBRECORD_REMOVED: |
||
281 | $res = ustrprocess(get_html_resource(RES_EVENT_SUBRECORD_REMOVED_ID, $locale), str_pad($event_param, 3, '0', STR_PAD_LEFT)); |
||
282 | break; |
||
283 | |||
284 | case EVENT_CONFIDENTIAL_COMMENT: |
||
285 | $res = get_html_resource(RES_EVENT_CONFIDENTIAL_COMMENT_ADDED_ID, $locale); |
||
286 | break; |
||
287 | |||
288 | case EVENT_RECORD_SUBSCRIBED: |
||
289 | $res = ustrprocess(get_html_resource(RES_SUBJECT_SUBSCRIBED_ID, $locale), ustr2html($event_param)); |
||
290 | break; |
||
291 | |||
292 | case EVENT_RECORD_UNSUBSCRIBED: |
||
293 | $res = ustrprocess(get_html_resource(RES_SUBJECT_UNSUBSCRIBED_ID, $locale), ustr2html($event_param)); |
||
294 | break; |
||
295 | |||
296 | default: |
||
297 | debug_write_log(DEBUG_WARNING, 'Unknown event type = ' . $event_type); |
||
298 | } |
||
299 | |||
300 | return $res; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Generates and returns message body for mail notification about specified event of particular record. |
||
305 | * |
||
306 | * @param array $record Array with data of record (e.g. how it's returned by {@link record_find}). |
||
307 | * @param array $event Array with data of event (e.g. how it's returned by {@link event_find}). |
||
308 | * @param int $locale ID of language. If omitted, then language of current user, or (when user is not logged in) default language will be used (see {@link LANG_DEFAULT}). |
||
309 | * @return string Generated message body. |
||
310 | */ |
||
311 | function generate_message ($record, $event, $locale = NULL) |
||
312 | { |
||
313 | debug_write_log(DEBUG_TRACE, '[generate_message]'); |
||
314 | debug_write_log(DEBUG_DUMP, '[generate_message] $locale = ' . $locale); |
||
315 | |||
316 | // general information |
||
317 | |||
318 | $fields = array |
||
319 | ( |
||
320 | RES_ID_ID => record_id($record['record_id'], $record['template_prefix']), |
||
321 | RES_SUBJECT_ID => update_references($record['subject'], BBCODE_MINIMUM), |
||
322 | RES_STATE_ID => ustr2html($record['state_name']), |
||
323 | RES_RESPONSIBLE_ID => is_null($record['username']) ? get_html_resource(RES_NONE_ID, $locale) |
||
324 | : ustr2html(sprintf('%s (%s)', $record['fullname'], account_get_username($record['username']))), |
||
325 | RES_AUTHOR_ID => ustr2html(sprintf('%s (%s)', $record['author_fullname'], account_get_username($record['author_username']))), |
||
326 | RES_AGE_ID => get_record_last_event($record) . '/' . get_record_age($record), |
||
327 | RES_PROJECT_ID => ustr2html($record['project_name']), |
||
328 | RES_TEMPLATE_ID => ustr2html($record['template_name']), |
||
329 | RES_EVENT_ID => get_event_string($event['event_id'], $event['event_type'], $event['event_param'], $locale), |
||
330 | ); |
||
331 | |||
332 | $message = '<html>' |
||
333 | . '<body>' |
||
334 | . '<b><font color="red">' . get_html_resource(RES_ALERT_DO_NOT_REPLY_ID, $locale) . '</font></b><br/>' |
||
335 | . '<br/><hr/>' |
||
336 | . '<b>' . get_html_resource(RES_GENERAL_INFO_ID, $locale) . '</b>' |
||
337 | . '<hr/>' |
||
338 | . '<table border="0" cellspacing="0" cellpadding="5">'; |
||
339 | |||
340 | foreach ($fields as $key => $value) |
||
341 | { |
||
342 | $message .= '<tr valign="top">' |
||
343 | . '<td><b>' . get_html_resource($key, $locale) . ':</b></td>' |
||
344 | . '<td>' . $value . '</td>' |
||
345 | . '</tr>'; |
||
346 | } |
||
347 | |||
348 | $message .= '</table>' |
||
349 | . '<br/><hr/>'; |
||
350 | |||
351 | // go through the list of all states and their fields |
||
352 | |||
353 | $states = dal_query('records/elist.sql', $record['record_id']); |
||
354 | |||
355 | while (($state = $states->fetch())) |
||
356 | { |
||
357 | $fields = dal_query('records/flist3.sql', $record['record_id'], $state['state_id']); |
||
358 | |||
359 | if ($fields->rows != 0) |
||
360 | { |
||
361 | $message .= '<b>' . ustr2html($state['state_name']) . '</b>' |
||
362 | . '<hr/>' |
||
363 | . '<table border="0" cellspacing="0" cellpadding="5">'; |
||
364 | |||
365 | while (($field = $fields->fetch())) |
||
366 | { |
||
367 | $value = value_find($field['field_type'], $field['value_id']); |
||
368 | |||
369 | if ($field['field_type'] == FIELD_TYPE_CHECKBOX) |
||
370 | { |
||
371 | $value = get_html_resource($value ? RES_YES_ID : RES_NO_ID); |
||
372 | } |
||
373 | elseif ($field['field_type'] == FIELD_TYPE_LIST) |
||
374 | { |
||
375 | $value = (is_null($value) ? NULL : value_find_listvalue($field['field_id'], $value)); |
||
376 | } |
||
377 | elseif ($field['field_type'] == FIELD_TYPE_RECORD) |
||
378 | { |
||
379 | $value = (is_null($value) ? NULL : 'rec#' . $value); |
||
380 | } |
||
381 | |||
382 | $value = is_null($value) |
||
383 | ? get_html_resource(RES_NONE_ID) |
||
384 | : str_replace('%br;', '<br/>', update_references($value, BBCODE_ALL, $field['regex_search'], $field['regex_replace'])); |
||
385 | |||
386 | $message .= '<tr valign="top">' |
||
387 | . '<td><b>' . ustr2html($field['field_name']) . ':</b></td>' |
||
388 | . '<td>' . $value . '</td>' |
||
389 | . '</tr>'; |
||
390 | } |
||
391 | |||
392 | $message .= '</table>' |
||
393 | . '<br/><hr/>'; |
||
394 | } |
||
395 | } |
||
396 | |||
397 | // if it was a comment, add its text |
||
398 | |||
399 | if (!is_null($event) && |
||
400 | ($event['event_type'] == EVENT_COMMENT_ADDED || $event['event_type'] == EVENT_CONFIDENTIAL_COMMENT)) |
||
401 | { |
||
402 | $rs = dal_query('comments/fndk.sql', $event['event_id']); |
||
403 | |||
404 | if ($rs->rows != 0) |
||
405 | { |
||
406 | $message .= '<b>' . get_html_resource(RES_COMMENT_ID, $locale) . '</b>' |
||
407 | . '<hr/>' |
||
408 | . '<table border="0" cellspacing="0" cellpadding="5">' |
||
409 | . '<tr><td>' |
||
410 | . str_replace('%br;', '<br/>', update_references($rs->fetch('comment_body'))) |
||
411 | . '</td></tr>' |
||
412 | . '</table>' |
||
413 | . '<br/><hr/>'; |
||
414 | } |
||
415 | } |
||
416 | |||
417 | // link to the record |
||
418 | |||
419 | $message .= '<a href="' . WEBROOT . 'records/view.php?id=' . $record['record_id'] . '">' . get_html_resource(RES_VIEW_RECORD_ID, $locale) . '</a>' |
||
420 | . '</body>' |
||
421 | . '</html>'; |
||
422 | |||
423 | return $message; |
||
424 | } |
||
425 | |||
426 | /** |
||
427 | * Sends mail notification about specified event to all interested parties. |
||
428 | * |
||
429 | * @param array $event Array with data of event (e.g. how it's returned by {@link event_find}). |
||
430 | * @param int $attachment_id ID of new attachment if event is about attached file, NULL otherwise. |
||
431 | * @param string $attachment_name Name of new attachment if event is about attached file, NULL otherwise. |
||
432 | * @param string $attachment_type MIME type of new attachment if event is about attached file, NULL otherwise. |
||
433 | * @param int $attachment_size Size of new attachment if event is about attached file, NULL otherwise. |
||
434 | * @return int Always {@link NO_ERROR}. |
||
435 | */ |
||
436 | function event_mail ($event, $attachment_id = NULL, $attachment_name = NULL, $attachment_type = NULL, $attachment_size = NULL) |
||
437 | { |
||
438 | debug_write_log(DEBUG_TRACE, '[event_mail]'); |
||
439 | |||
440 | global $notifications_filter; |
||
441 | global $locale_info; |
||
442 | |||
443 | // If debug mode is turned on full level, we go through the function even email notifications |
||
444 | // functionality is disabled, but don't send the email. |
||
445 | if (!EMAIL_NOTIFICATIONS_ENABLED && DEBUG_MODE != DEBUG_MODE_FULL) |
||
446 | { |
||
447 | debug_write_log(DEBUG_NOTICE, '[event_mail] Email notifications are disabled.'); |
||
448 | return NO_ERROR; |
||
449 | } |
||
450 | |||
451 | // Find info about currently logged in user, who is always an author of the event. |
||
452 | $account = account_find($_SESSION[VAR_USERID]); |
||
453 | |||
454 | if (!$account) |
||
0 ignored issues
–
show
|
|||
455 | { |
||
456 | debug_write_log(DEBUG_WARNING, '[event_mail] Account cannot be found.'); |
||
457 | return ERROR_NOT_FOUND; |
||
458 | } |
||
459 | |||
460 | // Find info about record, which the event is of. |
||
461 | $rs = dal_query('records/fndid.sql', $event['record_id'], time()); |
||
462 | |||
463 | if ($rs->rows == 0) |
||
464 | { |
||
465 | debug_write_log(DEBUG_WARNING, '[event_mail] Record not found = ' . $event['record_id']); |
||
466 | return ERROR_NOT_FOUND; |
||
467 | } |
||
468 | |||
469 | // Since sending email can takes a time, disable PHP execution timeout. |
||
470 | if (!ini_get('safe_mode')) |
||
471 | { |
||
472 | set_time_limit(0); |
||
473 | } |
||
474 | |||
475 | $record = $rs->fetch(); |
||
476 | |||
477 | $subscribes = array(); // IDs of everyone, who is subscribed to the record |
||
478 | $allowed = array(); // email addresses of everyone, who is permitted to see this event |
||
479 | |||
480 | // Enumerate IDs of everyone, who is subscribed to the record. |
||
481 | $rs = dal_query('records/subscribes.sql', $record['record_id']); |
||
482 | |||
483 | while (($row = $rs->fetch())) |
||
484 | { |
||
485 | array_push($subscribes, $row[0]); |
||
486 | } |
||
487 | |||
488 | // Enumerate email addresses of everyone, who is permitted to see this event. |
||
489 | $rs = dal_query((DATABASE_DRIVER == DRIVER_ORACLE9 ? 'groups/oracle/gplist2.sql' : 'groups/gplist2.sql'), |
||
490 | $record['record_id'], |
||
491 | ($event['event_type'] == EVENT_CONFIDENTIAL_COMMENT ? PERMIT_CONFIDENTIAL_COMMENTS : PERMIT_VIEW_RECORD)); |
||
492 | |||
493 | while (($row = $rs->fetch())) |
||
494 | { |
||
495 | array_push($allowed, $row['email']); |
||
496 | } |
||
497 | |||
498 | // Author of record and current responsible are permitted to see any event besides confidential comment. |
||
499 | if ($event['event_type'] != EVENT_CONFIDENTIAL_COMMENT) |
||
500 | { |
||
501 | $author = account_find($record['creator_id']); |
||
502 | $responsible = (is_null($record['responsible_id']) |
||
503 | ? FALSE |
||
504 | : account_find($record['responsible_id'])); |
||
505 | |||
506 | if ($author) |
||
0 ignored issues
–
show
The expression
$author of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
507 | { |
||
508 | array_push($allowed, $author['email']); |
||
509 | } |
||
510 | |||
511 | if ($responsible) |
||
0 ignored issues
–
show
The expression
$responsible of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
512 | { |
||
513 | array_push($allowed, $responsible['email']); |
||
514 | } |
||
515 | } |
||
516 | |||
517 | // Get IDs of all supported locales. |
||
518 | $supported_locales = array_keys($locale_info); |
||
519 | |||
520 | // Send separated notification for each locale in corresponding language. |
||
521 | foreach ($supported_locales as $locale) |
||
522 | { |
||
523 | $to = array(); // email addresses of recipients for TO field |
||
524 | $cc = array(); // email addresses of recipients for CC field |
||
525 | |||
526 | // Enumerate all project members with specified locale in settings. |
||
527 | $rs = dal_query('records/members.sql', $event['project_id'], $locale); |
||
528 | |||
529 | while (($row = $rs->fetch())) |
||
530 | { |
||
531 | // Skip author of event. |
||
532 | if ($row['account_id'] == $_SESSION[VAR_USERID]) |
||
533 | { |
||
534 | debug_write_log(DEBUG_TRACE, '[event_mail] User is author of event.'); |
||
535 | continue; |
||
536 | } |
||
537 | |||
538 | // Submitter of the record should receive notification of each record's event. |
||
539 | if ($row['account_id'] == $record['creator_id']) |
||
540 | { |
||
541 | debug_write_log(DEBUG_TRACE, '[event_mail] User is creator of record.'); |
||
542 | array_push($to, $row['email']); |
||
543 | } |
||
544 | // Current assignee of the record should receive notification of each record's event. |
||
545 | View Code Duplication | elseif ($row['account_id'] == $record['responsible_id']) |
|
546 | { |
||
547 | debug_write_log(DEBUG_TRACE, '[event_mail] User is responsible of record.'); |
||
548 | array_push($to, $row['email']); |
||
549 | } |
||
550 | // Subscribed to the record should receive notification of each record's event. |
||
551 | View Code Duplication | elseif (in_array($row['account_id'], $subscribes)) |
|
552 | { |
||
553 | debug_write_log(DEBUG_TRACE, '[event_mail] User is subscribed to record.'); |
||
554 | array_push($to, $row['email']); |
||
555 | } |
||
556 | else |
||
557 | { |
||
558 | debug_write_log(DEBUG_TRACE, '[event_mail] User should not recieve the notification.'); |
||
559 | } |
||
560 | } |
||
561 | |||
562 | // Enumerate all subscriptions for this template. |
||
563 | $rs = dal_query('subscriptions/enum.sql', $record['project_id'], $record['template_id'], $locale); |
||
564 | |||
565 | while (($row = $rs->fetch())) |
||
566 | { |
||
567 | // Skip author of event. |
||
568 | if ($row['account_id'] == $_SESSION[VAR_USERID]) |
||
569 | { |
||
570 | debug_write_log(DEBUG_TRACE, '[event_mail] User is author of event.'); |
||
571 | continue; |
||
572 | } |
||
573 | |||
574 | // If the event corresponds to the subscription, add owner of this subscription to recipients. |
||
575 | if (($row['subscribe_flags'] & $notifications_filter[$event['event_type']]) != 0) |
||
576 | { |
||
577 | debug_write_log(DEBUG_TRACE, '[event_mail] Event satisfies the filter.'); |
||
578 | array_push($to, $row['email']); |
||
579 | |||
580 | // If subscription contains specified carbon copy, add the address to CC. |
||
581 | if (ustrlen($row['carbon_copy']) != 0) |
||
582 | { |
||
583 | debug_write_log(DEBUG_TRACE, '[event_mail] Carbon copy is set.'); |
||
584 | $cc[$row['carbon_copy']] = $row['email']; |
||
585 | } |
||
586 | } |
||
587 | } |
||
588 | |||
589 | $to = array_intersect($to, $allowed); // remove from TO everyone who is not permitted to see this event |
||
590 | $cc = array_intersect($cc, $to); // remove from CC all carbon copies which are not in TO anymore |
||
591 | $to = array_merge($to, array_keys($cc)); // merge TO and CC |
||
592 | $to = array_unique($to); // remove all duplicates inside TO |
||
593 | |||
594 | // If we still have at least one recipient - send the mail. |
||
595 | if (count($to) != 0) |
||
596 | { |
||
597 | $recipients = implode(', ', $to); |
||
598 | $rec_id = record_id($record['record_id'], $record['template_prefix']); |
||
599 | $subject = "[{$event['project_name']}] {$rec_id}: " |
||
600 | . htmlspecialchars_decode(update_references($record['subject'], BBCODE_OFF), ENT_COMPAT); |
||
601 | $message = generate_message($record, $event, $locale); |
||
602 | |||
603 | if (EMAIL_NOTIFICATIONS_ENABLED) |
||
604 | { |
||
605 | debug_write_log(DEBUG_NOTICE, '[event_mail] Sending email.'); |
||
606 | |||
607 | sendmail($account['fullname'], |
||
608 | $account['email'], |
||
609 | $recipients, |
||
610 | $subject, |
||
611 | $message, |
||
612 | $attachment_id, |
||
613 | $attachment_name, |
||
614 | $attachment_type, |
||
615 | $attachment_size); |
||
616 | } |
||
617 | else |
||
618 | { |
||
619 | // If debug mode is turned on full level, we goes through the function even email |
||
620 | // notifications functionality is disabled, but do not send the email. |
||
621 | debug_write_log(DEBUG_NOTICE, '[event_mail] Email notifications are disabled.'); |
||
622 | } |
||
623 | } |
||
624 | } |
||
625 | |||
626 | // Restore PHP execution timeout, disabled above. |
||
627 | if (!ini_get('safe_mode')) |
||
628 | { |
||
629 | ini_restore('max_execution_time'); |
||
630 | } |
||
631 | |||
632 | return NO_ERROR; |
||
633 | } |
||
634 | |||
635 | ?> |
||
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.
Loading history...
|
|||
636 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.