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: |
|
0 ignored issues
–
show
|
|||
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: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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) |
||
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) |
||
507 | { |
||
508 | array_push($allowed, $author['email']); |
||
509 | } |
||
510 | |||
511 | if ($responsible) |
||
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']) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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)) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
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 | ?> |
||
636 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.