Completed
Push — 1.10.x ( 03aa81...621120 )
by Julito
140:19 queued 98:00
created

forumfunction.inc.php ➔ getPosts()   C

Complexity

Conditions 7
Paths 28

Size

Total Lines 82
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 56
nc 28
nop 5
dl 0
loc 82
rs 6.5492
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * These files are a complete rework of the forum. The database structure is
6
 * based on phpBB but all the code is rewritten. A lot of new functionalities
7
 * are added:
8
 * - forum categories and forums can be sorted up or down, locked or made invisible
9
 * - consistent and integrated forum administration
10
 * - forum options:     are students allowed to edit their post?
11
 *                         moderation of posts (approval)
12
 *                         reply only forums (students cannot create new threads)
13
 *                         multiple forums per group
14
 * - sticky messages
15
 * - new view option: nested view
16
 * - quoting a message
17
 *
18
 * @package chamilo.forum
19
 *
20
 * @todo several functions have to be moved to the itemmanager library
21
 * @todo displaying icons => display library
22
 * @todo complete the missing phpdoc the correct order should be
23
 */
24
25
use ChamiloSession as Session;
26
use Doctrine\Common\Collections\Criteria;
27
28
define('FORUM_NEW_POST', 0);
29
30
get_notifications_of_user();
31
32
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
33
$htmlHeadXtra[] = '<script>
34
35
function check_unzip() {
36
    if (document.upload.unzip.checked){
37
        document.upload.if_exists[0].disabled=true;
38
        document.upload.if_exists[1].checked=true;
39
        document.upload.if_exists[2].disabled=true;
40
    } else {
41
        document.upload.if_exists[0].checked=true;
42
        document.upload.if_exists[0].disabled=false;
43
        document.upload.if_exists[2].disabled=false;
44
    }
45
}
46
function setFocus() {
47
    $("#title_file").focus();
48
}
49
</script>';
50
// The next javascript script is to manage ajax upload file
51
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
52
53
// Recover Thread ID, will be used to generate delete attachment URL to do ajax
54
$threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : 0;
55
$forumId = isset($_REQUEST['forum']) ? intval($_REQUEST['forum']) : 0;
56
57
// The next javascript script is to delete file by ajax
58
$htmlHeadXtra[] = '<script>
59
$(function () {
60
    $(document).on("click", ".deleteLink", function(e) {
61
        e.preventDefault();
62
        e.stopPropagation();
63
        var l = $(this);
64
        var id = l.closest("tr").attr("id");
65
        var filename = l.closest("tr").find(".attachFilename").html();
66
        if (confirm("' . get_lang('AreYouSureToDeleteJS') . '", filename)) {
67
            $.ajax({
68
                type: "POST",
69
                url: "'.api_get_path(WEB_AJAX_PATH) . 'forum.ajax.php?'.api_get_cidreq().'&a=delete_file&attachId=" + id +"&thread='.$threadId .'&forum='.$forumId .'",
70
                dataType: "json",
71
                success: function(data) {
72
                    if (data.error == false) {
73
                        l.closest("tr").remove();
74
                        if ($(".files td").length < 1) {
75
                            $(".files").closest(".control-group").hide();
76
                        }
77
                    }
78
                }
79
            })
80
        }
81
    });
82
});
83
</script>';
84
85
/**
86
 * This function handles all the forum and forum categories actions. This is a wrapper for the
87
 * forum and forum categories. All this code code could go into the section where this function is
88
 * called but this make the code there cleaner.
89
 * @param int $lp_id Learning path Id
90
 *
91
 * @return void
92
 * @author Patrick Cool <[email protected]>, Ghent University
93
 * @author Juan Carlos Raña Trabado (return to lp_id)
94
 * @version may 2011, Chamilo 1.8.8
95
 */
96
function handle_forum_and_forumcategories($lp_id = null)
97
{
98
    $action_forum_cat = isset($_GET['action']) ? $_GET['action'] : '';
99
    $get_content = isset($_GET['content']) ? $_GET['content'] : '';
100
    $post_submit_cat = isset($_POST['SubmitForumCategory']) ? true : false;
101
    $post_submit_forum = isset($_POST['SubmitForum']) ? true : false;
102
    $get_id = isset($_GET['id']) ? intval($_GET['id']) : '';
103
    $forum_categories_list = get_forum_categories();
104
105
    //Verify if forum category exists
106
    if (empty($forum_categories_list)) {
107
        $get_content = 'forumcategory';
108
    }
109
110
    // Adding a forum category
111
    if (($action_forum_cat == 'add' && $get_content == 'forumcategory') || $post_submit_cat) {
112
        show_add_forumcategory_form(array(), $lp_id); //$lp_id when is called from learning path
113
    }
114
115
    // Adding a forum
116
    if ((($action_forum_cat == 'add' || $action_forum_cat == 'edit') && $get_content == 'forum') || $post_submit_forum) {
117
        if ($action_forum_cat == 'edit' && $get_id || $post_submit_forum) {
118
            $inputvalues = get_forums($get_id);
119
        } else {
120
            $inputvalues = array();
121
        }
122
        show_add_forum_form($inputvalues, $lp_id);
123
    }
124
125
    // Edit a forum category
126
    if (($action_forum_cat == 'edit' && $get_content == 'forumcategory') || (isset($_POST['SubmitEditForumCategory'])) ? true : false) {
127
        $forum_category = get_forum_categories($get_id);
128
        show_edit_forumcategory_form($forum_category);
129
    }
130
131
    // Delete a forum category
132
    if ($action_forum_cat == 'delete') {
133
        $id_forum = intval($get_id);
134
        $list_threads = get_threads($id_forum);
135
136
        for ($i = 0; $i < count($list_threads); $i++) {
137
            deleteForumCategoryThread('thread', $list_threads[$i]['thread_id']);
138
            $link_info = GradebookUtils::is_resource_in_course_gradebook(
139
                api_get_course_id(),
140
                5,
141
                intval($list_threads[$i]['thread_id']),
142
                api_get_session_id()
143
            );
144
            if ($link_info !== false) {
145
                GradebookUtils::remove_resource_from_course_gradebook($link_info['id']);
146
            }
147
        }
148
        $return_message = deleteForumCategoryThread($get_content, $get_id);
149
        Display::display_confirmation_message($return_message, false);
150
    }
151
152
    // Change visibility of a forum or a forum category.
153
    if ($action_forum_cat == 'invisible' || $action_forum_cat == 'visible') {
154
        $return_message = change_visibility($get_content, $get_id, $action_forum_cat);
155
        Display::display_confirmation_message($return_message, false);
156
    }
157
    // Change lock status of a forum or a forum category.
158
    if ($action_forum_cat == 'lock' || $action_forum_cat == 'unlock') {
159
        $return_message = change_lock_status($get_content, $get_id, $action_forum_cat);
160
        Display::display_confirmation_message($return_message, false);
161
    }
162
    // Move a forum or a forum category.
163
    if ($action_forum_cat == 'move' && isset($_GET['direction'])) {
164
        $return_message = move_up_down($get_content, $_GET['direction'], $get_id);
165
        Display::display_confirmation_message($return_message, false);
166
    }
167
}
168
169
/**
170
 * This function displays the form that is used to add a forum category.
171
 *
172
 * @param  array $inputvalues (deprecated, set to null when calling)
173
 * @param  int $lp_id Learning path ID
174
 *
175
 * @author Patrick Cool <[email protected]>, Ghent University
176
 * @author Juan Carlos Raña Trabado (return to lp_id)
177
 * @version may 2011, Chamilo 1.8.8
178
 */
179
function show_add_forumcategory_form($inputvalues = array(), $lp_id)
180
{
181
    // Initialize the object.
182
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
183
    // hidden field if from learning path
184
185
    $form->addElement('hidden', 'lp_id', $lp_id);
186
    // Setting the form elements.
187
    $form->addElement('header', get_lang('AddForumCategory'));
188
    $form->addElement('text', 'forum_category_title', get_lang('Title'), array('autofocus'));
189
    $form->addElement(
190
        'html_editor',
191
        'forum_category_comment',
192
        get_lang('Description'),
193
        null,
194
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
195
    );
196
    $form->addButtonCreate(get_lang('CreateCategory'), 'SubmitForumCategory');
197
198
    // Setting the rules.
199
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
200
201
    // The validation or display
202 View Code Duplication
    if ($form->validate()) {
203
        $check = Security::check_token('post');
204
        if ($check) {
205
            $values = $form->exportValues();
206
            store_forumcategory($values);
207
        }
208
        Security::clear_token();
209
    } else {
210
        $token = Security::get_token();
211
        $form->addElement('hidden', 'sec_token');
212
        $form->setConstants(array('sec_token' => $token));
213
        $form->display();
214
    }
215
}
216
217
/**
218
 * This function displays the form that is used to add a forum category.
219
 *
220
 * @param array $inputvalues
221
 * @param int $lp_id
222
 * @return void HTML
223
 *
224
 * @author Patrick Cool <[email protected]>, Ghent University
225
 * @author Juan Carlos Raña Trabado (return to lp_id)
226
 *
227
 * @version may 2011, Chamilo 1.8.8
228
 */
229
function show_add_forum_form($inputvalues = array(), $lp_id)
230
{
231
    $_course = api_get_course_info();
232
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
233
234
    // The header for the form
235
    if (!empty($inputvalues)) {
236
        $form_title = get_lang('EditForum');
237
    } else {
238
        $form_title = get_lang('AddForum');
239
    }
240
    $session_header = isset($_SESSION['session_name']) ? ' ('.$_SESSION['session_name'].') ' : '';
241
    $form->addElement('header', $form_title.$session_header);
242
243
    // We have a hidden field if we are editing.
244
    if (!empty($inputvalues) && is_array($inputvalues)) {
245
        $my_forum_id = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
246
        $form->addElement('hidden', 'forum_id', $my_forum_id);
247
    }
248
    $lp_id = intval($lp_id);
249
    // hidden field if from learning path
250
    $form->addElement('hidden', 'lp_id', $lp_id);
251
252
    // The title of the forum
253
    $form->addElement('text', 'forum_title', get_lang('Title'), array('autofocus'));
254
255
    // The comment of the forum.
256
    $form->addElement(
257
        'html_editor',
258
        'forum_comment',
259
        get_lang('Description'),
260
        null,
261
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
262
    );
263
264
    // Dropdown list: Forum categories
265
    $forum_categories = get_forum_categories();
266
    foreach ($forum_categories as $key => $value) {
267
        $forum_categories_titles[$value['cat_id']] = $value['cat_title'];
268
    }
269
    $form->addElement('select', 'forum_category', get_lang('InForumCategory'), $forum_categories_titles);
270
    $form->applyFilter('forum_category', 'html_filter');
271
272
    if ($_course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD) {
273
        // This is for horizontal
274
        $group = array();
275
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('Yes'), 1);
276
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('No'), 0);
277
        $form->addGroup($group, 'allow_anonymous_group', get_lang('AllowAnonymousPosts'), ' ');
278
    }
279
280
    $form->addButtonAdvancedSettings('advanced_params');
281
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
282
283
    $group = array();
284
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('Yes'), 1);
285
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('No'), 0);
286
    $form->addGroup($group, 'students_can_edit_group', get_lang('StudentsCanEdit'), ' ');
287
288
    $group = array();
289
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Approval'), 1);
290
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Direct'), 0);
291
292
    $group = array();
293
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('Yes'), 1);
294
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('No'), 0);
295
296
    $group = array();
297
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('Yes'), 1);
298
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('No'), 0);
299
    $form->addGroup($group, 'allow_new_threads_group', get_lang('AllowNewThreads'), ' ');
300
301
    $group = array();
302
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Flat'), 'flat');
303
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Threaded'), 'threaded');
304
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Nested'), 'nested');
305
    $form->addGroup($group, 'default_view_type_group', get_lang('DefaultViewType'), ' ');
306
307
    // Drop down list: Groups
308
    $groups = GroupManager::get_group_list();
309
    $groups_titles[0] = get_lang('NotAGroupForum');
310
    foreach ($groups as $key => $value) {
311
        $groups_titles[$value['id']] = $value['name'];
312
    }
313
    $form->addElement('select', 'group_forum', get_lang('ForGroup'), $groups_titles);
314
315
    // Public or private group forum
316
    $group = array();
317
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Public'), 'public');
318
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Private'), 'private');
319
    $form->addGroup($group, 'public_private_group_forum_group', get_lang('PublicPrivateGroupForum'), '');
320
321
    // Forum image
322
    $form->add_progress_bar();
0 ignored issues
show
Deprecated Code introduced by
The method FormValidator::add_progress_bar() has been deprecated with message: ?

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
323
    if (isset($inputvalues['forum_image']) && strlen($inputvalues['forum_image']) > 0) {
324
325
        $image_path = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$inputvalues['forum_image'];
326
        $image_size = api_getimagesize($image_path);
327
328
        $img_attributes = '';
329
        if (!empty($image_size)) {
330
            if ($image_size['width'] > 100 || $image_size['height'] > 100) {
331
                //limit display width and height to 100px
332
                $img_attributes = 'width="100" height="100"';
333
            }
334
            $show_preview_image = '<img src="'.$image_path.'" '.$img_attributes.'>';
335
            $form->addElement('label', get_lang('PreviewImage'), $show_preview_image);
336
            $form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
337
        }
338
    }
339
    $forum_image = isset($inputvalues['forum_image']) ? $inputvalues['forum_image'] : '';
340
    $form->addElement('file', 'picture', ($forum_image != '' ? get_lang('UpdateImage') : get_lang('AddImage')));
341
    $form->addRule('picture', get_lang('OnlyImagesAllowed'), 'filetype', array('jpg', 'jpeg', 'png', 'gif'));
342
    $form->addElement('html', '</div>');
343
344
    // The OK button
345
    if (isset($_GET['id']) && $_GET['action'] == 'edit') {
346
        $form->addButtonUpdate(get_lang('ModifyForum'), 'SubmitForum');
347
    } else {
348
        $form->addButtonCreate(get_lang('CreateForum'), 'SubmitForum');
349
    }
350
351
    // setting the rules
352
    $form->addRule('forum_title', get_lang('ThisFieldIsRequired'), 'required');
353
    $form->addRule('forum_category', get_lang('ThisFieldIsRequired'), 'required');
354
355
    $defaultSettingAllowNewThreads = api_get_default_tool_setting('forum', 'allow_new_threads', 0);
356
357
    // Settings the defaults
358
    if (empty($inputvalues) || !is_array($inputvalues)) {
359
        $defaults['allow_anonymous_group']['allow_anonymous'] = 0;
360
        $defaults['students_can_edit_group']['students_can_edit'] = 0;
361
        $defaults['approval_direct_group']['approval_direct'] = 0;
362
        $defaults['allow_attachments_group']['allow_attachments'] = 1;
363
        $defaults['allow_new_threads_group']['allow_new_threads'] = $defaultSettingAllowNewThreads;
364
        $defaults['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
365
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = 'public';
366
        if (isset($_GET['forumcategory'])) {
367
            $defaults['forum_category'] = Security::remove_XSS($_GET['forumcategory']);
368
        }
369
    } else {   // the default values when editing = the data in the table
370
        $defaults['forum_id'] = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
371
        $defaults['forum_title'] = prepare4display(isset($inputvalues['forum_title']) ? $inputvalues['forum_title'] : null);
372
        $defaults['forum_comment'] = prepare4display(isset($inputvalues['forum_comment']) ? $inputvalues['forum_comment'] : null);
373
        $defaults['forum_category'] = isset($inputvalues['forum_category']) ? $inputvalues['forum_category'] : null;
374
        $defaults['allow_anonymous_group']['allow_anonymous'] = isset($inputvalues['allow_anonymous']) ? $inputvalues['allow_anonymous'] : null;
375
        $defaults['students_can_edit_group']['students_can_edit'] = isset($inputvalues['allow_edit']) ? $inputvalues['allow_edit'] : null;
376
        $defaults['approval_direct_group']['approval_direct'] = isset($inputvalues['approval_direct_post']) ? $inputvalues['approval_direct_post'] : null;
377
        $defaults['allow_attachments_group']['allow_attachments'] = isset($inputvalues['allow_attachments']) ? $inputvalues['allow_attachments'] : null;
378
        $defaults['allow_new_threads_group']['allow_new_threads'] = isset($inputvalues['allow_new_threads']) ? $inputvalues['allow_new_threads'] : $defaultSettingAllowNewThreads;
379
        $defaults['default_view_type_group']['default_view_type'] = isset($inputvalues['default_view']) ? $inputvalues['default_view'] : null;
380
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
381
        $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
382
    }
383
    $form->setDefaults($defaults);
384
    // Validation or display
385 View Code Duplication
    if ($form->validate()) {
386
        $check = Security::check_token('post');
387
        if ($check) {
388
            $values = $form->exportValues();
389
            $return_message = store_forum($values);
390
            Display :: display_confirmation_message($return_message);
391
        }
392
        Security::clear_token();
393
    } else {
394
        $token = Security::get_token();
395
        $form->addElement('hidden', 'sec_token');
396
        $form->setConstants(array('sec_token' => $token));
397
        $form->display();
398
    }
399
}
400
401
/**
402
 * This function deletes the forum image if exists
403
 *
404
 * @param int forum id
405
 * @return boolean true if success
406
 * @author Julio Montoya <[email protected]>
407
 * @version february 2006, dokeos 1.8
408
 */
409
function delete_forum_image($forum_id)
410
{
411
    $table_forums = Database::get_course_table(TABLE_FORUM);
412
    $course_id = api_get_course_int_id();
413
    $forum_id = intval($forum_id);
414
415
    $sql = "SELECT forum_image FROM $table_forums
416
            WHERE forum_id = '".$forum_id."' AND c_id = $course_id";
417
    $result = Database::query($sql);
418
    $row = Database::fetch_array($result);
419
    if ($row['forum_image'] != '') {
420
        $del_file = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$row['forum_image'];
421
422
        return @unlink($del_file);
423
    } else {
424
        return false;
425
    }
426
}
427
428
/**
429
 * This function displays the form that is used to edit a forum category.
430
 * This is more or less a copy from the show_add_forumcategory_form function with the only difference that is uses
431
 * some default values. I tried to have both in one function but this gave problems with the handle_forum_and_forumcategories function
432
 * (storing was done twice)
433
 *
434
 * @param array
435
 * @return void HTML
436
 *
437
 * @author Patrick Cool <[email protected]>, Ghent University
438
 * @version february 2006, dokeos 1.8
439
 */
440
function show_edit_forumcategory_form($inputvalues = array())
441
{
442
    $categoryId = $inputvalues['cat_id'];
443
    $form = new FormValidator('forumcategory', 'post', 'index.php?'.api_get_cidreq().'&id='.$categoryId);
444
445
    // Setting the form elements.
446
    $form->addElement('header', '', get_lang('EditForumCategory'));
447
    $form->addElement('hidden', 'forum_category_id');
448
    $form->addElement('text', 'forum_category_title', get_lang('Title'));
449
450
    $form->addElement(
451
        'html_editor',
452
        'forum_category_comment',
453
        get_lang('Comment'),
454
        null,
455
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
456
    );
457
458
    $form->addButtonUpdate(get_lang('ModifyCategory'), 'SubmitEditForumCategory');
459
460
    // Setting the default values.
461
    $defaultvalues['forum_category_id'] = $inputvalues['cat_id'];
462
    $defaultvalues['forum_category_title'] = $inputvalues['cat_title'];
463
    $defaultvalues['forum_category_comment'] = $inputvalues['cat_comment'];
464
    $form->setDefaults($defaultvalues);
465
466
    // Setting the rules.
467
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
468
469
    // Validation or display
470 View Code Duplication
    if ($form->validate()) {
471
        $check = Security::check_token('post');
472
        if ($check) {
473
            $values = $form->exportValues();
474
            store_forumcategory($values);
475
        }
476
        Security::clear_token();
477
    } else {
478
        $token = Security::get_token();
479
        $form->addElement('hidden', 'sec_token');
480
        $form->setConstants(array('sec_token' => $token));
481
        $form->display();
482
    }
483
}
484
485
/**
486
 * This function stores the forum category in the database.
487
 * The new category is added to the end.
488
 *
489
 * @param array $values
490
 * @param array $courseInfo
491
 * @param bool $showMessage
492
 * @return void HMTL language variable
493
 *
494
 * @author Patrick Cool <[email protected]>, Ghent University
495
 * @version february 2006, dokeos 1.8
496
 */
497
function store_forumcategory($values, $courseInfo = array(), $showMessage = true)
498
{
499
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
500
    $course_id = $courseInfo['real_id'];
501
502
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
503
504
    // Find the max cat_order. The new forum category is added at the end => max cat_order + &
505
    $sql = "SELECT MAX(cat_order) as sort_max
506
            FROM $table_categories
507
            WHERE c_id = $course_id";
508
    $result = Database::query($sql);
509
    $row = Database::fetch_array($result);
510
    $new_max = $row['sort_max'] + 1;
511
    $session_id = api_get_session_id();
512
    $clean_cat_title = $values['forum_category_title'];
513
    $last_id = null;
514
515
    if (isset($values['forum_category_id'])) {
516
        // Storing after edition.
517
        $params = [
518
            'cat_title' => $clean_cat_title,
519
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
520
        ];
521
        Database::update(
522
            $table_categories,
523
            $params,
524
            [
525
                'c_id = ? AND cat_id = ?' => [
526
                    $course_id,
527
                    $values['forum_category_id'],
528
                ],
529
            ]
530
        );
531
532
        api_item_property_update(
533
            $courseInfo,
534
            TOOL_FORUM_CATEGORY,
535
            $values['forum_category_id'],
536
            'ForumCategoryUpdated',
537
            api_get_user_id()
538
        );
539
        $return_message = get_lang('ForumCategoryEdited');
540
    } else {
541
542
        $params = [
543
            'c_id' => $course_id,
544
            'cat_title' => $clean_cat_title,
545
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
546
            'cat_order' => $new_max,
547
            'session_id' => $session_id,
548
        ];
549
        $last_id = Database::insert($table_categories, $params);
550
551
        if ($last_id > 0) {
552
553
            $sql = "UPDATE $table_categories SET cat_id = $last_id WHERE iid = $last_id";
554
            Database::query($sql);
555
556
            api_item_property_update(
557
                $courseInfo,
558
                TOOL_FORUM_CATEGORY,
559
                $last_id,
560
                'ForumCategoryAdded',
561
                api_get_user_id()
562
            );
563
            api_set_default_visibility(
564
                $last_id,
565
                TOOL_FORUM_CATEGORY,
566
                0,
567
                $courseInfo
568
            );
569
        }
570
        $return_message = get_lang('ForumCategoryAdded');
571
    }
572
573
    if ($showMessage) {
574
        Display:: display_confirmation_message($return_message);
575
    }
576
577
    return $last_id;
578
}
579
580
/**
581
 * This function stores the forum in the database. The new forum is added to the end.
582
 *
583
 * @param array $values
584
 * @param array $courseInfo
585
 * @param bool  $returnId
586
 * @return string language variable
587
 *
588
 * @author Patrick Cool <[email protected]>, Ghent University
589
 * @version february 2006, dokeos 1.8
590
 */
591
function store_forum($values, $courseInfo = array(), $returnId = false)
592
{
593
    $now = api_get_utc_datetime();
594
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
595
    $course_id = $courseInfo['real_id'];
596
    $session_id = api_get_session_id();
597
598
    if (isset($values['group_id']) && !empty($values['group_id'])) {
599
        $group_id = $values['group_id'];
600
    } else {
601
        $group_id = api_get_group_id();
602
    }
603
604
    $table_forums = Database::get_course_table(TABLE_FORUM);
605
606
    // Find the max forum_order for the given category. The new forum is added at the end => max cat_order + &
607
    if (is_null($values['forum_category'])) {
608
        $new_max = null;
609
    } else {
610
        $sql = "SELECT MAX(forum_order) as sort_max
611
                FROM ".$table_forums."
612
                WHERE
613
                    c_id = $course_id AND
614
                    forum_category='".Database::escape_string($values['forum_category'])."'";
615
        $result = Database::query($sql);
616
        $row = Database::fetch_array($result);
617
        $new_max = $row['sort_max'] + 1;
618
    }
619
620
    // Forum images
621
    $image_moved = false;
622
    if (!empty($_FILES['picture']['name'])) {
623
        $upload_ok = process_uploaded_file($_FILES['picture']);
624
        $has_attachment = true;
625
    } else {
626
        $image_moved = true;
627
    }
628
629
    // Remove existing picture if it was requested.
630
    if (!empty($_POST['remove_picture'])) {
631
        delete_forum_image($values['forum_id']);
632
    }
633
634
    $new_file_name = '';
635
    if (isset($upload_ok)) {
636
        if ($has_attachment) {
637
            $course_dir = $courseInfo['path'].'/upload/forum/images';
638
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
639
            $updir = $sys_course_path.$course_dir;
640
            // Try to add an extension to the file if it hasn't one.
641
            $new_file_name = add_ext_on_mime(
642
                Database::escape_string($_FILES['picture']['name']),
643
                $_FILES['picture']['type']
644
            );
645
            if (!filter_extension($new_file_name)) {
646
                //Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
647
                $image_moved = false;
648
            } else {
649
                $file_extension = explode('.', $_FILES['picture']['name']);
650
                $file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
651
                $new_file_name = uniqid('').'.'.$file_extension;
652
                $new_path = $updir.'/'.$new_file_name;
653
                $result = @move_uploaded_file($_FILES['picture']['tmp_name'], $new_path);
654
                // Storing the attachments if any
655
                if ($result) {
656
                    $image_moved = true;
657
                }
658
            }
659
        }
660
    }
661
662
    if (isset($values['forum_id'])) {
663
        $sql_image = isset($sql_image) ? $sql_image : '';
0 ignored issues
show
Bug introduced by
The variable $sql_image seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
664
        $new_file_name = isset($new_file_name) ? $new_file_name : '';
665
        if ($image_moved) {
666
            if (empty($_FILES['picture']['name'])) {
667
                $sql_image = "";
668
            } else {
669
                $sql_image = $new_file_name;
670
                delete_forum_image($values['forum_id']);
671
            }
672
        }
673
674
        // Storing after edition.
675
        $params = [
676
            'forum_title'=> $values['forum_title'],
677
            'forum_image'=> $sql_image,
678
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
679
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
680
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
681
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
682
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
683
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
684
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
685
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
686
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
687
            'forum_group_public_private'=> isset($values['public_private_group_forum_group']['public_private_group_forum']) ? $values['public_private_group_forum_group']['public_private_group_forum'] : null,
688
            'forum_order'=> isset($new_max) ? $new_max : null,
689
            'session_id'=> $session_id,
690
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0
691
        ];
692
693
        Database::update(
694
            $table_forums,
695
            $params,
696
            ['c_id = ? AND forum_id = ?' => [$course_id, $values['forum_id']]]
697
        );
698
699
        api_item_property_update(
700
            $courseInfo,
701
            TOOL_FORUM,
702
            Database::escape_string($values['forum_id']),
703
            'ForumUpdated',
704
            api_get_user_id(),
705
            $group_id
706
        );
707
708
        $return_message = get_lang('ForumEdited');
709
    } else {
710
        if ($image_moved) {
711
            $new_file_name = isset($new_file_name) ? $new_file_name : '';
712
        }
713
714
        $params = [
715
            'c_id' => $course_id,
716
            'forum_title'=> $values['forum_title'],
717
            'forum_image'=> $new_file_name,
718
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
719
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
720
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
721
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
722
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
723
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
724
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
725
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
726
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
727
            'forum_group_public_private'=> isset($values['public_private_group_forum_group']['public_private_group_forum']) ? $values['public_private_group_forum_group']['public_private_group_forum'] : null,
728
            'forum_order'=> isset($new_max) ? $new_max : null,
729
            'session_id'=> $session_id,
730
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0,
731
            'locked' => 0,
732
            'forum_id' => 0
733
        ];
734
        $last_id = Database::insert($table_forums, $params);
735 View Code Duplication
        if ($last_id > 0) {
736
737
            $sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $last_id";
738
            Database::query($sql);
739
740
            api_item_property_update(
741
                $courseInfo,
742
                TOOL_FORUM,
743
                $last_id,
744
                'ForumAdded',
745
                api_get_user_id(),
746
                $group_id
747
            );
748
749
            api_set_default_visibility(
750
                $last_id,
751
                TOOL_FORUM,
752
                $group_id,
753
                $courseInfo
754
            );
755
        }
756
        $return_message = get_lang('ForumAdded');
757
        if ($returnId) {
758
759
            return $last_id;
760
        }
761
    }
762
763
    return $return_message;
764
}
765
766
/**
767
 * This function deletes a forum or a forum category
768
 * This function currently does not delete the forums inside the category,
769
 * nor the threads and replies inside these forums.
770
 * For the moment this is the easiest method and it has the advantage that it
771
 * allows to recover fora that were acidently deleted
772
 * when the forum category got deleted.
773
 *
774
 * @param $content = what we are deleting (a forum or a forum category)
775
 * @param $id The id of the forum category that has to be deleted.
776
 *
777
 * @todo write the code for the cascading deletion of the forums inside a
778
 * forum category and also the threads and replies inside these forums
779
 * @todo config setting for recovery or not
780
 * (see also the documents tool: real delete or not).
781
 * @return string
782
 * @author Patrick Cool <[email protected]>, Ghent University
783
 * @version february 2006, dokeos 1.8
784
 */
785
function deleteForumCategoryThread($content, $id)
786
{
787
    $_course = api_get_course_info();
788
    $table_forums = Database::get_course_table(TABLE_FORUM);
789
    $table_forums_post = Database::get_course_table(TABLE_FORUM_POST);
790
    $table_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
791
    $course_id = api_get_course_int_id();
792
    $groupId = api_get_group_id();
793
    $userId = api_get_user_id();
794
    $id = intval($id);
795
796
    // Delete all attachment file about this tread id.
797
    $sql = "SELECT post_id FROM $table_forums_post
798
            WHERE c_id = $course_id AND thread_id = '".$id."' ";
799
    $res = Database::query($sql);
800
    while ($poster_id = Database::fetch_row($res)) {
801
        delete_attachment($poster_id[0]);
802
    }
803
804
    $tool_constant = null;
805
    $return_message = '';
806
807 View Code Duplication
    if ($content == 'forumcategory') {
808
        $tool_constant = TOOL_FORUM_CATEGORY;
809
        $return_message = get_lang('ForumCategoryDeleted');
810
811
        if (!empty($forum_list)) {
0 ignored issues
show
Bug introduced by
The variable $forum_list seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
812
            $sql = "SELECT forum_id FROM ".$table_forums."
813
                    WHERE c_id = $course_id AND forum_category='".$id."'";
814
            $result = Database::query($sql);
815
            $row = Database::fetch_array($result);
816
            foreach ($row as $arr_forum) {
817
                $forum_id = $arr_forum['forum_id'];
818
                api_item_property_update(
819
                    $_course,
820
                    'forum',
821
                    $forum_id,
822
                    'delete',
823
                    api_get_user_id()
824
                );
825
            }
826
        }
827
    }
828
829 View Code Duplication
    if ($content == 'forum') {
830
        $tool_constant = TOOL_FORUM;
831
        $return_message = get_lang('ForumDeleted');
832
833
        if (!empty($number_threads)) {
0 ignored issues
show
Bug introduced by
The variable $number_threads seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
834
            $sql = "SELECT thread_id FROM".$table_forum_thread."
835
                    WHERE c_id = $course_id AND forum_id='".$id."'";
836
            $result = Database::query($sql);
837
            $row = Database::fetch_array($result);
838
            foreach ($row as $arr_forum) {
839
                $forum_id = $arr_forum['thread_id'];
840
                api_item_property_update($_course, 'forum_thread', $forum_id, 'delete', api_get_user_id());
841
            }
842
        }
843
    }
844
845
    if ($content == 'thread') {
846
        $tool_constant = TOOL_FORUM_THREAD;
847
        $return_message = get_lang('ThreadDeleted');
848
    }
849
850
    api_item_property_update(
851
        $_course,
852
        $tool_constant,
853
        $id,
854
        'delete',
855
        $userId,
856
        $groupId
857
    );
858
859
    // Check if this returns a true and if so => return $return_message, if not => return false;
860
    return $return_message;
861
}
862
863
/**
864
 * This function deletes a forum post. This separate function is needed because forum posts do not appear in the item_property table (yet)
865
 * and because deleting a post also has consequence on the posts that have this post as parent_id (they are also deleted).
866
 * an alternative would be to store the posts also in item_property and mark this post as deleted (visibility = 2).
867
 * We also have to decrease the number of replies in the thread table
868
 *
869
 * @param $post_id the id of the post that will be deleted
870
 * @todo write recursive function that deletes all the posts that have this message as parent
871
 * @return string language variable
872
 * @author Patrick Cool <[email protected]>, Ghent University
873
 * @author Hubert Borderiou Function cleanead and fixed
874
 * @version february 2006
875
 */
876
function delete_post($post_id)
877
{
878
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
879
    $post_id = intval($post_id);
880
    $course_id = api_get_course_int_id();
881
    $em = Database::getManager();
882
883
    $post = $em
884
        ->getRepository('ChamiloCourseBundle:CForumPost')
885
        ->findOneBy(['cId' => $course_id, 'postId' => $post_id]);
886
887
    if ($post) {
888
        $em
889
            ->createQuery('
890
                UPDATE ChamiloCourseBundle:CForumPost p
891
                SET p.postParentId = :parent_of_deleted_post
892
                WHERE
893
                    p.cId = :course AND
894
                    p.postParentId = :post AND
895
                    p.threadId = :thread_of_deleted_post AND
896
                    p.forumId = :forum_of_deleted_post
897
            ')
898
            ->execute([
899
                'parent_of_deleted_post' => $post->getPostParentId(),
900
                'course' => $course_id,
901
                'post' => $post->getPostId(),
902
                'thread_of_deleted_post' => $post->getThreadId(),
903
                'forum_of_deleted_post' => $post->getForumId()
904
            ]);
905
906
        $em->remove($post);
907
        $em->flush();
908
909
        // Delete attachment file about this post id.
910
        delete_attachment($post_id);
911
    }
912
913
    $last_post_of_thread = check_if_last_post_of_thread($_GET['thread']);
914
915
    if (is_array($last_post_of_thread)) {
916
        // Decreasing the number of replies for this thread and also changing the last post information.
917
        $sql = "UPDATE $table_threads
918
                SET
919
                    thread_replies=thread_replies-1,
920
                    thread_last_post = ".intval($last_post_of_thread['post_id']).",
921
                    thread_date='".Database::escape_string($last_post_of_thread['post_date'])."'
922
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
923
        Database::query($sql);
924
925
        return 'PostDeleted';
926
    }
927
    if (!$last_post_of_thread) {
928
        // We deleted the very single post of the thread so we need to delete the entry in the thread table also.
929
        $sql = "DELETE FROM $table_threads
930
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
931
        Database::query($sql);
932
933
        return 'PostDeletedSpecial';
934
    }
935
}
936
937
/**
938
 * This function gets the all information of the last (=most recent) post of the thread
939
 * This can be done by sorting the posts that have the field thread_id=$thread_id and sort them by post_date
940
 *
941
 * @param $thread_id the id of the thread we want to know the last post of.
942
 * @return an array or bool if there is a last post found, false if there is
943
 * no post entry linked to that thread => thread will be deleted
944
 *
945
 * @author Patrick Cool <[email protected]>, Ghent University
946
 * @version february 2006, dokeos 1.8
947
 */
948
function check_if_last_post_of_thread($thread_id)
949
{
950
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
951
    $course_id = api_get_course_int_id();
952
    $sql = "SELECT * FROM $table_posts
953
            WHERE c_id = $course_id AND thread_id = ".intval($thread_id)."
954
            ORDER BY post_date DESC";
955
    $result = Database::query($sql);
956
    if (Database::num_rows($result) > 0) {
957
        $row = Database::fetch_array($result);
958
959
        return $row;
960
    } else {
961
        return false;
962
    }
963
}
964
965
/**
966
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
967
 * @param $id the id of the content we want to make invisible
968
 * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
969
 * @param array $additional_url_parameters
970
 *
971
 * @return string HTML
972
 */
973
function return_visible_invisible_icon($content, $id, $current_visibility_status, $additional_url_parameters = '')
974
{
975
    $html = '';
976
    $id = Security::remove_XSS($id);
977 View Code Duplication
    if ($current_visibility_status == '1') {
978
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
979
        if (is_array($additional_url_parameters)) {
980
            foreach ($additional_url_parameters as $key => $value) {
981
                $html .= $key . '=' . $value . '&';
982
            }
983
        }
984
        $html.='action=invisible&content='.$content.'&id='.$id.'">'.
985
            Display::return_icon('visible.png', get_lang('MakeInvisible'), array(), ICON_SIZE_SMALL).'</a>';
986
    }
987 View Code Duplication
    if ($current_visibility_status == '0') {
988
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
989
        if (is_array($additional_url_parameters)) {
990
            foreach ($additional_url_parameters as $key => $value) {
991
                $html .= $key . '=' . $value . '&';
992
            }
993
        }
994
        $html .= 'action=visible&content=' . $content . '&id=' . $id . '">' .
995
            Display::return_icon('invisible.png', get_lang('MakeVisible'), array(), ICON_SIZE_SMALL) . '</a>';
996
    }
997
    return $html;
998
}
999
1000
/**
1001
 * @param $content
1002
 * @param $id
1003
 * @param $current_lock_status
1004
 * @param string $additional_url_parameters
1005
 * @return string
1006
 */
1007
function return_lock_unlock_icon($content, $id, $current_lock_status, $additional_url_parameters = '')
1008
{
1009
    $html = '';
1010
    $id = intval($id);
1011
    //check if the forum is blocked due
1012
    if ($content == 'thread') {
1013
        if (api_resource_is_locked_by_gradebook($id, LINK_FORUM_THREAD)) {
1014
            $html .= Display::return_icon('lock_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
1015
1016
            return $html;
1017
        }
1018
    }
1019 View Code Duplication
    if ($current_lock_status == '1') {
1020
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1021
        if (is_array($additional_url_parameters)) {
1022
            foreach ($additional_url_parameters as $key => $value) {
1023
                $html .= $key . '=' . $value . '&';
1024
            }
1025
        }
1026
        $html.= 'action=unlock&content='.$content.'&id='.$id.'">'.
1027
            Display::return_icon('lock.png', get_lang('Unlock'), array(), ICON_SIZE_SMALL).'</a>';
1028
    }
1029 View Code Duplication
    if ($current_lock_status == '0') {
1030
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1031
        if (is_array($additional_url_parameters)) {
1032
            foreach ($additional_url_parameters as $key => $value) {
1033
                $html .= $key . '=' . $value . '&';
1034
            }
1035
        }
1036
        $html .= 'action=lock&content=' . $content . '&id=' . $id . '">' .
1037
            Display::return_icon('unlock.png', get_lang('Lock'), array(), ICON_SIZE_SMALL) . '</a>';
1038
    }
1039
    return $html;
1040
}
1041
1042
/**
1043
 * This function takes care of the display of the up and down icon
1044
 *
1045
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1046
 * @param $id is the id of the item we want to display the icons for
1047
 * @param $list is an array of all the items. All items in this list should have
1048
 * an up and down icon except for the first (no up icon) and the last (no down icon)
1049
 *          The key of this $list array is the id of the item.
1050
 *
1051
 * @return string HTML
1052
 **/
1053
function return_up_down_icon($content, $id, $list)
1054
{
1055
    $id = strval(intval($id));
1056
    $total_items = count($list);
1057
    $position = 0;
1058
    $internal_counter = 0;
1059
    $forumCategory = isset($_GET['forumcategory']) ? Security::remove_XSS($_GET['forumcategory']) : null;
1060
1061
    if (is_array($list)) {
1062
        foreach ($list as $key => $listitem) {
1063
            $internal_counter++;
1064
            if ($id == $key) {
1065
                $position = $internal_counter;
1066
            }
1067
        }
1068
    }
1069
1070
    if ($position > 1) {
1071
        $return_value = '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=up&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveUp').'">'.
1072
            Display::return_icon('up.png', get_lang('MoveUp'), array(), ICON_SIZE_SMALL).'</a>';
1073
    } else {
1074
        $return_value = Display::return_icon('up_na.png', '-', array(), ICON_SIZE_SMALL);
1075
    }
1076
1077
    if ($position < $total_items) {
1078
        $return_value .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=down&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveDown').'" >'.
1079
            Display::return_icon('down.png', get_lang('MoveDown'), array(), ICON_SIZE_SMALL).'</a>';
1080
    } else {
1081
        $return_value .= Display::return_icon('down_na.png', '-', array(), ICON_SIZE_SMALL);
1082
    }
1083
    return $return_value;
1084
}
1085
1086
/**
1087
 * This function changes the visibility in the database (item_property)
1088
 *
1089
 * @param string $content what is it that we want to make (in)visible: forum category, forum, thread, post
1090
 * @param int $id the id of the content we want to make invisible
1091
 * @param string $target_visibility what is the current status of the visibility (0 = invisible, 1 = visible)
1092
 *
1093
 * @todo change the get parameter so that it matches the tool constants.
1094
 * @todo check if api_item_property_update returns true or false => returnmessage depends on it.
1095
 * @todo move to itemmanager
1096
 *
1097
 * @return string language variable
1098
 *
1099
 * @author Patrick Cool <[email protected]>, Ghent University
1100
 * @version february 2006, dokeos 1.8
1101
 */
1102
function change_visibility($content, $id, $target_visibility)
1103
{
1104
    $_course = api_get_course_info();
1105
    $constants = array(
1106
        'forumcategory' => TOOL_FORUM_CATEGORY,
1107
        'forum' => TOOL_FORUM,
1108
        'thread' => TOOL_FORUM_THREAD,
1109
    );
1110
    api_item_property_update(
1111
        $_course,
1112
        $constants[$content],
1113
        $id,
1114
        $target_visibility,
1115
        api_get_user_id()
1116
    );
1117
1118
    if ($target_visibility == 'visible') {
1119
        handle_mail_cue($content, $id);
1120
    }
1121
    return get_lang('VisibilityChanged');
1122
}
1123
1124
/**
1125
 * This function changes the lock status in the database
1126
 *
1127
 * @param $content what is it that we want to (un)lock: forum category, forum, thread, post
1128
 * @param $id the id of the content we want to (un)lock
1129
 * @param $action do we lock (=>locked value in db = 1) or unlock (=> locked value in db = 0)
1130
 * @return string, language variable
0 ignored issues
show
Documentation introduced by
The doc-type string, could not be parsed: Expected "|" or "end of type", but got "," at position 6. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1131
 *
1132
 * @todo move to item manager
1133
 *
1134
 * @author Patrick Cool <[email protected]>, Ghent University
1135
 * @version february 2006, dokeos 1.8
1136
 */
1137
function change_lock_status($content, $id, $action)
1138
{
1139
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1140
    $table_forums = Database :: get_course_table(TABLE_FORUM);
1141
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1142
1143
    // Determine the relevant table.
1144
    if ($content == 'forumcategory') {
1145
        $table = $table_categories;
1146
        $id_field = 'cat_id';
1147
    } elseif ($content == 'forum') {
1148
        $table = $table_forums;
1149
        $id_field = 'forum_id';
1150
    } elseif ($content == 'thread') {
1151
        $table = $table_threads;
1152
        $id_field = 'thread_id';
1153
    } else {
1154
        return get_lang('Error');
1155
    }
1156
1157
    // Determine what we are doing => defines the value for the database and the return message.
1158
    if ($action == 'lock') {
1159
        $db_locked = 1;
1160
        $return_message = get_lang('Locked');
1161
    } elseif ($action == 'unlock') {
1162
        $db_locked = 0;
1163
        $return_message = get_lang('Unlocked');
1164
    } else {
1165
        return get_lang('Error');
1166
    }
1167
1168
    $course_id = api_get_course_int_id();
1169
1170
    // Doing the change in the database
1171
    $sql = "UPDATE $table SET locked='".Database::escape_string($db_locked)."'
1172
            WHERE c_id = $course_id AND $id_field='".Database::escape_string($id)."'";
1173
    if (Database::query($sql)) {
1174
        return $return_message;
1175
    } else {
1176
        return get_lang('Error');
1177
    }
1178
}
1179
1180
/**
1181
 * This function moves a forum or a forum category up or down
1182
 *
1183
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1184
 * @param $direction do we want to move it up or down.
1185
 * @param $id the id of the content we want to make invisible
1186
 * @todo consider removing the table_item_property calls here but this can
1187
 * prevent unwanted side effects when a forum does not have an entry in
1188
 * the item_property table but does have one in the forum table.
1189
 * @return string language variable
1190
 *
1191
 * @author Patrick Cool <[email protected]>, Ghent University
1192
 * @version february 2006, dokeos 1.8
1193
 */
1194
function move_up_down($content, $direction, $id)
1195
{
1196
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1197
    $table_forums = Database :: get_course_table(TABLE_FORUM);
1198
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1199
    $course_id = api_get_course_int_id();
1200
    $id = intval($id);
1201
1202
    // Determine which field holds the sort order.
1203
    if ($content == 'forumcategory') {
1204
        $table = $table_categories;
1205
        $sort_column = 'cat_order';
1206
        $id_column = 'cat_id';
1207
        $sort_column = 'cat_order';
1208
    } elseif ($content == 'forum') {
1209
        $table = $table_forums;
1210
        $sort_column = 'forum_order';
1211
        $id_column = 'forum_id';
1212
        $sort_column = 'forum_order';
1213
        // We also need the forum_category of this forum.
1214
        $sql = "SELECT forum_category FROM $table_forums
1215
                WHERE c_id = $course_id AND forum_id = ".intval($id);
1216
        $result = Database::query($sql);
1217
        $row = Database::fetch_array($result);
1218
        $forum_category = $row['forum_category'];
1219
    } else {
1220
        return get_lang('Error');
1221
    }
1222
1223
    // Determine the need for sorting ascending or descending order.
1224
    if ($direction == 'down') {
1225
        $sort_direction = 'ASC';
1226
    } elseif ($direction == 'up') {
1227
        $sort_direction = 'DESC';
1228
    } else {
1229
        return get_lang('Error');
1230
    }
1231
1232
    // The SQL statement
1233
    if ($content == 'forumcategory') {
1234
        $sql = "SELECT *
1235
                FROM $table_categories forum_categories, $table_item_property item_properties
1236
                WHERE
1237
                    forum_categories.c_id = $course_id AND
1238
                    item_properties.c_id = $course_id AND
1239
                    forum_categories.cat_id=item_properties.ref AND
1240
                    item_properties.tool='" . TOOL_FORUM_CATEGORY . "'
1241
                ORDER BY forum_categories.cat_order $sort_direction";
1242
    }
1243
    if ($content == 'forum') {
1244
        $sql = "SELECT *
1245
            FROM $table
1246
            WHERE
1247
                c_id = $course_id AND
1248
                forum_category='" . Database::escape_string($forum_category) . "'
1249
            ORDER BY forum_order $sort_direction";
1250
    }
1251
    // Finding the items that need to be switched.
1252
    $result = Database::query($sql);
1253
    $found = false;
1254
    while ($row = Database::fetch_array($result)) {
1255
        //echo $row[$id_column].'-';
1256
        if ($found) {
1257
            $next_id = $row[$id_column];
1258
            $next_sort = $row[$sort_column];
1259
            $found = false;
1260
        }
1261
        if ($id == $row[$id_column]) {
1262
            $this_id = $id;
1263
            $this_sort = $row[$sort_column];
1264
            $found = true;
1265
        }
1266
    }
1267
1268
    // Committing the switch.
1269
    // We do an extra check if we do not have illegal values. If your remove this if statment you will
1270
    // be able to mess with the sorting by refreshing the page over and over again.
1271
    if ($this_sort != '' && $next_sort != '' && $next_id != '' && $this_id != '') {
1272
        $sql = "UPDATE $table SET $sort_column='".Database::escape_string($this_sort)."'
1273
                WHERE c_id = $course_id AND $id_column='".Database::escape_string($next_id)."'";
1274
        Database::query($sql);
1275
1276
        $sql = "UPDATE $table SET $sort_column='".Database::escape_string($next_sort)."'
1277
                WHERE c_id = $course_id AND $id_column='".Database::escape_string($this_id)."'";
1278
        Database::query($sql);
1279
    }
1280
1281
    return get_lang(ucfirst($content).'Moved');
1282
}
1283
1284
/**
1285
 * This function returns a piece of html code that make the links grey (=invisible for the student)
1286
 *
1287
 * @param int 0 = invisible, 1 = visible
1288
 * @return string language variable
1289
 *
1290
 * @author Patrick Cool <[email protected]>, Ghent University
1291
 * @version february 2006, dokeos 1.8
1292
 */
1293
function class_visible_invisible($current_visibility_status)
1294
{
1295
    $current_visibility_status = intval($current_visibility_status);
1296
    if ($current_visibility_status == 0) {
1297
        return 'class="invisible"';
1298
    }
1299
}
1300
1301
function return_visible_invisible($current_visibility_status)
1302
{
1303
    $current_visibility_status = intval($current_visibility_status);
1304
    if ($current_visibility_status == 0) {
1305
        $status='invisible';
1306
        return $status;
1307
    }
1308
}
1309
/**
1310
 * Retrieve all the information off the forum categories (or one specific) for the current course.
1311
 * The categories are sorted according to their sorting order (cat_order
1312
 *
1313
 * @param int $id default ''. When an id is passed we only find the information
1314
 * about that specific forum category. If no id is passed we get all the forum categories.
1315
 * @return array containing all the information about all the forum categories
1316
 *
1317
 * @author Patrick Cool <[email protected]>, Ghent University
1318
 * @version february 2006, dokeos 1.8
1319
 */
1320
function get_forum_categories($id = '')
1321
{
1322
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1323
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1324
1325
    // Condition for the session
1326
    $session_id = api_get_session_id();
1327
    $course_id = api_get_course_int_id();
1328
1329
    $condition_session = api_get_session_condition($session_id, true, true, 'forum_categories.session_id');
1330
    $condition_session .= " AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id";
1331
1332
    if (empty($id)) {
1333
        $sql = "SELECT *
1334
                FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
1335
                WHERE
1336
                    forum_categories.cat_id=item_properties.ref AND
1337
                    item_properties.visibility=1 AND
1338
                    item_properties.tool = '".TOOL_FORUM_CATEGORY."'
1339
                    $condition_session
1340
                ORDER BY forum_categories.cat_order ASC";
1341 View Code Duplication
        if (api_is_allowed_to_edit()) {
1342
            $sql = "SELECT *
1343
                    FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
1344
                    WHERE
1345
                        forum_categories.cat_id=item_properties.ref AND
1346
                        item_properties.visibility<>2 AND
1347
                        item_properties.tool='".TOOL_FORUM_CATEGORY."'
1348
                        $condition_session
1349
                    ORDER BY forum_categories.cat_order ASC";
1350
        }
1351 View Code Duplication
    } else {
1352
        $sql = "SELECT *
1353
                FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties
1354
                WHERE
1355
                    forum_categories.cat_id=item_properties.ref AND
1356
                    item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
1357
                    forum_categories.cat_id = ".intval($id)."
1358
                    $condition_session
1359
                ORDER BY forum_categories.cat_order ASC";
1360
    }
1361
    $result = Database::query($sql);
1362
    $forum_categories_list = array();
1363
1364
    while ($row = Database::fetch_array($result)) {
1365
        if (empty($id)) {
1366
            $forum_categories_list[$row['cat_id']] = $row;
1367
        } else {
1368
            $forum_categories_list = $row;
1369
        }
1370
    }
1371
1372
    return $forum_categories_list;
1373
}
1374
1375
/**
1376
 * This function retrieves all the fora in a given forum category
1377
 *
1378
 * @param int $cat_id the id of the forum category
1379
 * @return array containing all the information about the forums (regardless of their category)
1380
 *
1381
 * @author Patrick Cool <[email protected]>, Ghent University
1382
 * @version february 2006, dokeos 1.8
1383
 */
1384
function get_forums_in_category($cat_id)
1385
{
1386
    $table_forums = Database::get_course_table(TABLE_FORUM);
1387
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1388
1389
    $forum_list = array();
1390
    $course_id = api_get_course_int_id();
1391
1392
    $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
1393
            WHERE
1394
                forum.forum_category='".Database::escape_string($cat_id)."' AND
1395
                forum.forum_id=item_properties.ref AND
1396
                item_properties.visibility = 1 AND
1397
                item_properties.c_id = $course_id AND
1398
                item_properties.tool='".TOOL_FORUM."' AND
1399
                forum.c_id = $course_id
1400
            ORDER BY forum.forum_order ASC";
1401
    if (api_is_allowed_to_edit()) {
1402
        $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
1403
                WHERE
1404
                    forum.forum_category = '".Database::escape_string($cat_id)."' AND
1405
                    forum.forum_id = item_properties.ref AND
1406
                    item_properties.visibility <> 2 AND
1407
                    item_properties.tool = '".TOOL_FORUM."' AND
1408
                    item_properties.c_id = $course_id AND
1409
                    forum.c_id = $course_id
1410
                ORDER BY forum_order ASC";
1411
    }
1412
    $result = Database::query($sql);
1413
    while ($row = Database::fetch_array($result)) {
1414
        $forum_list[$row['forum_id']] = $row;
1415
    }
1416
1417
    return $forum_list;
1418
}
1419
1420
/**
1421
 * Retrieve all the forums (regardless of their category) or of only one.
1422
 * The forums are sorted according to the forum_order.
1423
 * Since it does not take the forum category into account there probably
1424
 * will be two or more forums that have forum_order=1, ...
1425
 * @param int $id forum id
1426
 * @param string $course_code
1427
 * @param bool $includeGroupsForum
1428
 * @param int $sessionId
1429
 * @return array an array containing all the information about the forums (regardless of their category)
1430
 * @todo check $sql4 because this one really looks fishy.
1431
 *
1432
 * @author Patrick Cool <[email protected]>, Ghent University
1433
 * @version february 2006, dokeos 1.8
1434
 */
1435
function get_forums(
1436
    $id = '',
1437
    $course_code = '',
1438
    $includeGroupsForum = true,
1439
    $sessionId = 0
1440
) {
1441
    $course_info = api_get_course_info($course_code);
1442
1443
    $table_forums = Database :: get_course_table(TABLE_FORUM);
1444
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1445
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1446
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1447
1448
    // Condition for the session
1449
    if (empty($sessionId)) {
1450
        $session_id = api_get_session_id();
1451
    } else {
1452
        $session_id = $sessionId;
1453
    }
1454
1455
    $sessionIdLink = ($session_id === 0) ? '' : 'AND threads.session_id = item_properties.session_id';
1456
1457
    $condition_session = api_get_session_condition(
1458
        $session_id,
1459
        true,
1460
        false,
1461
        'item_properties.session_id'
1462
    );
1463
    $course_id = $course_info['real_id'];
1464
1465
    $forum_list = array();
1466
    $includeGroupsForumSelect = "";
1467
    if (!$includeGroupsForum) {
1468
        $includeGroupsForumSelect = " AND forum_of_group = 0 ";
1469
    }
1470
1471
    if ($id == '') {
1472
        // Student
1473
        // Select all the forum information of all forums (that are visible to students).
1474
        $sql = "SELECT * FROM $table_forums forum
1475
                INNER JOIN ".$table_item_property." item_properties
1476
                ON (
1477
                    forum.forum_id = item_properties.ref AND
1478
                    forum.c_id = item_properties.c_id
1479
                )
1480
                WHERE
1481
                    item_properties.visibility=1 AND
1482
                    item_properties.tool = '".TOOL_FORUM."'
1483
                    $condition_session AND
1484
                    forum.c_id = $course_id AND
1485
                    item_properties.c_id = $course_id
1486
                    $includeGroupsForumSelect
1487
                ORDER BY forum.forum_order ASC";
1488
1489
        // Select the number of threads of the forums (only the threads that are visible).
1490
        $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1491
                FROM $table_threads threads
1492
                INNER JOIN ".$table_item_property." item_properties
1493
                ON (
1494
                    threads.thread_id=item_properties.ref AND
1495
                    threads.c_id = item_properties.c_id
1496
                    $sessionIdLink
1497
                )
1498
                WHERE
1499
                    item_properties.visibility=1 AND
1500
                    item_properties.tool='".TOOL_FORUM_THREAD."' AND
1501
                    threads.c_id = $course_id AND
1502
                    item_properties.c_id = $course_id
1503
                GROUP BY threads.forum_id";
1504
1505
1506
        // Course Admin
1507
        if (api_is_allowed_to_edit()) {
1508
            // Select all the forum information of all forums (that are not deleted).
1509
            $sql = "SELECT * FROM ".$table_forums." forum
1510
                    INNER JOIN ".$table_item_property." item_properties
1511
                    ON (
1512
                        forum.forum_id = item_properties.ref AND
1513
                        forum.c_id = item_properties.c_id
1514
                    )
1515
                    WHERE
1516
                        item_properties.visibility <> 2 AND
1517
                        item_properties.tool='".TOOL_FORUM."'
1518
                        $condition_session AND
1519
                        forum.c_id = $course_id AND
1520
                        item_properties.c_id = $course_id
1521
                        $includeGroupsForumSelect
1522
                    ORDER BY forum_order ASC";
1523
1524
            // Select the number of threads of the forums (only the threads that are not deleted).
1525
            $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1526
                    FROM $table_threads threads
1527
                    INNER JOIN ".$table_item_property." item_properties
1528
                    ON (
1529
                        threads.thread_id=item_properties.ref AND
1530
                        threads.c_id = item_properties.c_id
1531
                        $sessionIdLink
1532
                    )
1533
                    WHERE
1534
                        item_properties.visibility<>2 AND
1535
                        item_properties.tool='".TOOL_FORUM_THREAD."' AND
1536
                        threads.c_id = $course_id AND
1537
                        item_properties.c_id = $course_id
1538
                    GROUP BY threads.forum_id";
1539
        }
1540
    } else {
1541
        // GETTING ONE SPECIFIC FORUM
1542
        /* We could do the splitup into student and course admin also but we want
1543
        to have as much as information about a certain forum as possible
1544
        so we do not take too much information into account. This function
1545
         (or this section of the function) is namely used to fill the forms
1546
        when editing a forum (and for the moment it is the only place where
1547
        we use this part of the function) */
1548
1549
        // Select all the forum information of the given forum (that is not deleted).
1550
        $sql = "SELECT * FROM $table_forums forum, ".$table_item_property." item_properties
1551
                WHERE
1552
                    forum.forum_id=item_properties.ref AND
1553
                    forum_id = ".intval($id)." AND
1554
                    item_properties.visibility<>2 AND
1555
                    item_properties.tool='".TOOL_FORUM."'
1556
                    $condition_session AND
1557
                    forum.c_id = $course_id AND
1558
                    item_properties.c_id = $course_id
1559
                ORDER BY forum_order ASC";
1560
1561
        // Select the number of threads of the forum.
1562
        $sql2 = "SELECT count(*) AS number_of_threads, forum_id
1563
                FROM $table_threads
1564
                WHERE
1565
                    forum_id = ".intval($id)." AND
1566
                    c_id = $course_id
1567
                GROUP BY forum_id";
1568
    }
1569
1570
    // Handling all the forum information.
1571
1572
    $result = Database::query($sql);
1573
    while ($row = Database::fetch_array($result)) {
1574
        if ($id == '') {
1575
            $forum_list[$row['forum_id']] = $row;
1576
        } else {
1577
            $forum_list = $row;
1578
        }
1579
    }
1580
1581
    // Handling the thread count information.
1582
    $result2 = Database::query($sql2);
1583
    while ($row2 = Database::fetch_array($result2)) {
1584
        if ($id == '') {
1585
            $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
1586
        } else {
1587
            $forum_list['number_of_threads'] = $row2['number_of_threads'];
1588
        }
1589
    }
1590
1591
    /* Finding the last post information
1592
    (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)*/
1593
    if ($id == '') {
1594
        if (is_array($forum_list)) {
1595 View Code Duplication
            foreach ($forum_list as $key => $value) {
1596
                $last_post_info_of_forum = get_last_post_information(
1597
                    $key,
1598
                    api_is_allowed_to_edit(),
1599
                    $course_id
1600
                );
1601
                $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1602
                $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1603
                $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1604
                $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1605
                $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1606
                $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1607
            }
1608
        } else {
1609
            $forum_list = array();
1610
        }
1611
    } else {
1612
        $last_post_info_of_forum = get_last_post_information(
1613
            $id,
1614
            api_is_allowed_to_edit(),
1615
            $course_id
1616
        );
1617
        $forum_list['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1618
        $forum_list['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1619
        $forum_list['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1620
        $forum_list['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1621
        $forum_list['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1622
        $forum_list['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1623
    }
1624
1625
    return $forum_list;
1626
}
1627
1628
/**
1629
 * @param int $course_id
1630
 * @param int $thread_id
1631
 * @param int $forum_id
1632
 * @param bool $show_visible
1633
 * @return array|bool
1634
 */
1635
function get_last_post_by_thread($course_id, $thread_id, $forum_id, $show_visible = true)
1636
{
1637
    if (empty($thread_id) || empty($forum_id) || empty($course_id)) {
1638
        return false;
1639
    }
1640
1641
    $thread_id = intval($thread_id);
1642
    $forum_id = intval($forum_id);
1643
    $course_id = intval($course_id);
1644
1645
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1646
    $sql = "SELECT * FROM $table_posts
1647
            WHERE c_id = $course_id AND thread_id = $thread_id AND forum_id = $forum_id";
1648
1649
    if ($show_visible == false) {
1650
        $sql .= " AND visible = 1 ";
1651
    }
1652
1653
    $sql .= " ORDER BY post_id DESC LIMIT 1";
1654
    $result = Database::query($sql);
1655
    if (Database::num_rows($result)) {
1656
        return Database::fetch_array($result, 'ASSOC');
1657
    } else {
1658
        return false;
1659
    }
1660
}
1661
1662
/**
1663
 * This function gets all the last post information of a certain forum
1664
 *
1665
 * @param int   $forum_id the id of the forum we want to know the last post information of.
1666
 * @param bool  $show_invisibles
1667
 * @param string course db name
1668
 * @return array containing all the information about the last post
1669
 * (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)
1670
 *
1671
 * @author Patrick Cool <[email protected]>, Ghent University
1672
 * @version february 2006, dokeos 1.8
1673
 */
1674
function get_last_post_information($forum_id, $show_invisibles = false, $course_id = null)
1675
{
1676
    if (!isset($course_id)) {
1677
        $course_id = api_get_course_int_id();
1678
    } else {
1679
        $course_id = intval($course_id);
1680
    }
1681
1682
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1683
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1684
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1685
1686
    $sql = "SELECT
1687
                post.post_id,
1688
                post.forum_id,
1689
                post.poster_id,
1690
                post.poster_name,
1691
                post.post_date,
1692
                users.lastname,
1693
                users.firstname,
1694
                post.visible,
1695
                thread_properties.visibility AS thread_visibility,
1696
                forum_properties.visibility AS forum_visibility
1697
            FROM
1698
                $table_posts post,
1699
                $table_users users,
1700
                $table_item_property thread_properties,
1701
                $table_item_property forum_properties
1702
            WHERE
1703
                post.forum_id = ".intval($forum_id)."
1704
                AND post.poster_id=users.user_id
1705
                AND post.thread_id=thread_properties.ref
1706
                AND thread_properties.tool='".TOOL_FORUM_THREAD."'
1707
                AND post.forum_id=forum_properties.ref
1708
                AND forum_properties.tool='".TOOL_FORUM."'
1709
                AND post.c_id = $course_id AND
1710
                thread_properties.c_id = $course_id AND
1711
                forum_properties.c_id = $course_id
1712
            ORDER BY post.post_id DESC";
1713
    $result = Database::query($sql);
1714
1715
    if ($show_invisibles) {
1716
        $row = Database::fetch_array($result);
1717
        $return_array['last_post_id'] = $row['post_id'];
1718
        $return_array['last_poster_id'] = $row['poster_id'];
1719
        $return_array['last_post_date'] = $row['post_date'];
1720
        $return_array['last_poster_name'] = $row['poster_name'];
1721
        $return_array['last_poster_lastname'] = $row['lastname'];
1722
        $return_array['last_poster_firstname'] = $row['firstname'];
1723
1724
        return $return_array;
1725
    } else {
1726
        // We have to loop through the results to find the first one that is
1727
        // actually visible to students (forum_category, forum, thread AND post are visible).
1728
        while ($row = Database::fetch_array($result)) {
1729
            if ($row['visible'] == '1' && $row['thread_visibility'] == '1' && $row['forum_visibility'] == '1') {
1730
                $return_array['last_post_id'] = $row['post_id'];
1731
                $return_array['last_poster_id'] = $row['poster_id'];
1732
                $return_array['last_post_date'] = $row['post_date'];
1733
                $return_array['last_poster_name'] = $row['poster_name'];
1734
                $return_array['last_poster_lastname'] = $row['lastname'];
1735
                $return_array['last_poster_firstname'] = $row['firstname'];
1736
1737
                return $return_array;
1738
            }
1739
        }
1740
    }
1741
}
1742
1743
/**
1744
 * Retrieve all the threads of a given forum
1745
 *
1746
 * @param int   forum id
1747
 * @param string course db name
1748
 * @return an array containing all the information about the threads
1749
 *
1750
 * @author Patrick Cool <[email protected]>, Ghent University
1751
 * @version february 2006, dokeos 1.8
1752
 */
1753
function get_threads($forum_id, $course_code = null)
1754
{
1755
    $course_info = api_get_course_info($course_code);
1756
    if (empty($course_info)) {
1757
        return array();
1758
    }
1759
1760
    $course_id = $course_info['real_id'];
1761
    $groupId = api_get_group_id();
1762
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1763
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1764
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1765
1766
    // important note:  it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
1767
    // because we also have thread.* in it. This is because thread has a field locked and post also has the same field
1768
    // since we are merging these we would have the post.locked value but in fact we want the thread.locked value
1769
    // This is why it is added to the end of the field selection
1770
    $groupCondition = api_get_group_id() != 0 ? " AND item_properties.to_group_id = '$groupId' " : "";
1771
1772
    $sql = "SELECT DISTINCT
1773
                thread.*,
1774
                item_properties.*,
1775
                users.firstname,
1776
                users.lastname,
1777
                users.user_id,
1778
                thread.locked as locked
1779
            FROM $table_threads thread
1780
            INNER JOIN $table_item_property item_properties
1781
            ON
1782
                thread.thread_id = item_properties.ref AND
1783
                item_properties.c_id = thread.c_id AND
1784
                item_properties.c_id = $course_id AND
1785
                item_properties.tool = '".TABLE_FORUM_THREAD."' $groupCondition
1786
            LEFT JOIN $table_users users
1787
                ON thread.thread_poster_id=users.user_id
1788
            WHERE
1789
                item_properties.visibility='1' AND
1790
                thread.forum_id = ".intval($forum_id)."
1791
            ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1792
1793
    if (api_is_allowed_to_edit()) {
1794
1795
        $sql = "SELECT DISTINCT
1796
                    thread.*,
1797
                    item_properties.*,
1798
                    users.firstname,
1799
                    users.lastname,
1800
                    users.user_id,
1801
                    thread.locked as locked
1802
                FROM $table_threads thread
1803
                INNER JOIN $table_item_property item_properties
1804
                ON
1805
                    thread.thread_id = item_properties.ref AND
1806
                    item_properties.c_id = $course_id AND
1807
                    thread.c_id = $course_id AND
1808
                    item_properties.tool = '".TABLE_FORUM_THREAD."'
1809
                    $groupCondition
1810
                LEFT JOIN $table_users users
1811
                    ON thread.thread_poster_id=users.user_id
1812
                WHERE
1813
                    item_properties.visibility<>2 AND
1814
                    thread.forum_id = ".intval($forum_id)."
1815
                ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1816
    }
1817
1818
    $result = Database::query($sql);
1819
    $list = array();
1820
    $alreadyAdded = array();
1821 View Code Duplication
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1822
        if (in_array($row['thread_id'], $alreadyAdded)) {
1823
            continue;
1824
        }
1825
        $list[] = $row;
1826
        $alreadyAdded[] = $row['thread_id'];
1827
    }
1828
1829
    return $list;
1830
}
1831
1832
/**
1833
 * Get a thread by Id and course id
1834
 *
1835
 * @param int $threadId the thread Id
1836
 * @param int $cId the course id
1837
 * @return array containing all the information about the thread
1838
 */
1839
function getThreadInfo($threadId, $cId)
1840
{
1841
    $em = Database::getManager();
1842
    $forumThread = $em->getRepository('ChamiloCourseBundle:CForumThread')->findOneBy(['threadId' => $threadId, 'cId' => $cId]);
1843
1844
    $thread = [];
1845
1846
    if ($forumThread) {
1847
        $thread['threadId'] = $forumThread->getThreadId();
1848
        $thread['threadTitle'] = $forumThread->getThreadTitle();
1849
        $thread['forumId'] = $forumThread->getForumId();
1850
        $thread['sessionId'] = $forumThread->getSessionId();
1851
        $thread['threadSticky'] = $forumThread->getThreadSticky();
1852
        $thread['locked'] = $forumThread->getLocked();
1853
        $thread['threadTitleQualify'] = $forumThread->getThreadTitleQualify();
1854
        $thread['threadQualifyMax'] = $forumThread->getThreadQualifyMax();
1855
        $thread['threadCloseDate'] = $forumThread->getThreadCloseDate();
1856
        $thread['threadWeight'] = $forumThread->getThreadWeight();
1857
        $thread['threadPeerQualify'] = $forumThread->isThreadPeerQualify();
1858
    }
1859
1860
    return $thread;
1861
}
1862
1863
/**
1864
 * Retrieve all posts of a given thread
1865
 * @param int $threadId The thread ID
1866
 * @param string $orderDirection Optional. The direction for sort the posts
1867
 * @param boolean $recursive Optional. If the list is recursive
1868
 * @param int $postId Optional. The post ID for recursive list
1869
 * @param int $depth Optional. The depth to indicate the indent
1870
 * @todo move to a repository
1871
 *
1872
 * @return array containing all the information about the posts of a given thread
1873
 */
1874
function getPosts($threadId, $orderDirection = 'ASC', $recursive = false, $postId = null, $depth = -1)
1875
{
1876
    $list = [];
1877
1878
    $em = Database::getManager();
1879
1880
    if (api_is_allowed_to_edit(false, true)) {
1881
        $visibleCriteria = Criteria::expr()->neq('visible', 2);
1882
    } else {
1883
        $visibleCriteria = Criteria::expr()->eq('visible', 1);
1884
    }
1885
1886
    $criteria = Criteria::create();
1887
    $criteria
1888
        ->where(Criteria::expr()->eq('threadId', $threadId))
1889
        ->andWhere(Criteria::expr()->eq('cId', api_get_course_int_id()))
1890
        ->andWhere($visibleCriteria)
1891
    ;
1892
1893
    if ($recursive) {
1894
        $criteria->andWhere(Criteria::expr()->eq('postParentId', $postId));
1895
    }
1896
1897
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
1898
    $qb->select('p')
1899
        ->addCriteria($criteria)
1900
        ->addOrderBy('p.postId', $orderDirection);
1901
1902
    $posts = $qb->getQuery()->getResult();
1903
1904
    $depth++;
1905
    /** @var \Chamilo\CourseBundle\Entity\CForumPost $post */
1906
    foreach ($posts as $post) {
1907
        $postInfo = [
1908
            'c_id' => $post->getCId(),
1909
            'post_id' => $post->getPostId(),
1910
            'post_title' => $post->getPostTitle(),
1911
            'post_text' => $post->getPostText(),
1912
            'thread_id' => $post->getThreadId(),
1913
            'forum_id' => $post->getForumId(),
1914
            'poster_id' => $post->getPosterId(),
1915
            'poster_name' => $post->getPosterName(),
1916
            'post_date' => $post->getPostDate(),
1917
            'post_notification' => $post->getPostNotification(),
1918
            'post_parent_id' => $post->getPostParentId(),
1919
            'visible' => $post->getVisible(),
1920
            'indent_cnt' => $depth
1921
        ];
1922
1923
        $posterId = $post->getPosterId();
1924
        if (!empty($posterId)) {
1925
            $user = $em->find('ChamiloUserBundle:User', $posterId);
1926
1927
            if ($user) {
1928
                $postInfo['user_id'] = $user->getUserId();
1929
                $postInfo['username'] = $user->getUsername();
1930
                $postInfo['username_canonical'] = $user->getUsernameCanonical();
1931
                $postInfo['lastname'] = $user->getLastname();
1932
                $postInfo['firstname'] = $user->getFirstname();
1933
            }
1934
        }
1935
1936
        $list[$post->getPostId()] = $postInfo;
1937
1938
        if (!$recursive) {
1939
            continue;
1940
        }
1941
1942
        $list = array_merge(
1943
            $list,
1944
            getPosts(
1945
                $threadId,
1946
                $orderDirection,
1947
                $recursive,
1948
                $post->getPostId(),
1949
                $depth
1950
            )
1951
        );
1952
    }
1953
1954
    return $list;
1955
}
1956
1957
/**
1958
 * This function retrieves all the information of a post
1959
 *
1960
 * @param int $post_id integer that indicates the forum
1961
 *
1962
 * @return array returns
1963
 *
1964
 * @author Patrick Cool <[email protected]>, Ghent University
1965
 * @version february 2006, dokeos 1.8
1966
 */
1967
function get_post_information($post_id)
1968
{
1969
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1970
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1971
    $course_id = api_get_course_int_id();
1972
1973
    $sql = "SELECT * FROM ".$table_posts." posts, ".$table_users." users
1974
            WHERE
1975
                c_id = $course_id AND
1976
                posts.poster_id=users.user_id AND
1977
                posts.post_id = ".intval($post_id)."";
1978
    $result = Database::query($sql);
1979
    $row = Database::fetch_array($result);
1980
1981
    return $row;
1982
}
1983
1984
/**
1985
 * This function retrieves all the information of a thread
1986
 *
1987
 * @param $thread_id integer that indicates the forum
1988
 *
1989
 * @return array returns
1990
 *
1991
 * @author Patrick Cool <[email protected]>, Ghent University
1992
 * @version february 2006, dokeos 1.8
1993
 */
1994
function get_thread_information($thread_id)
1995
{
1996
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1997
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1998
    $course_id = api_get_course_int_id();
1999
    $thread_id = intval($thread_id);
2000
2001
    $sql = "SELECT * FROM ".$table_threads." threads, ".$table_item_property." item_properties
2002
            WHERE
2003
                item_properties.tool= '".TOOL_FORUM_THREAD."' AND
2004
                item_properties.c_id = $course_id AND
2005
                item_properties.ref = ".$thread_id." AND
2006
                threads.thread_id   = ".$thread_id." AND
2007
                threads.c_id = $course_id
2008
            ";
2009
    $result = Database::query($sql);
2010
    $row = Database::fetch_array($result);
2011
2012
    return $row;
2013
}
2014
2015
/**
2016
 * This function retrieves forum thread users details
2017
 * @param   int Thread ID
2018
 * @param   string  Course DB name (optional)
2019
 * @return  Doctrine\DBAL\Driver\Statement|null array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2020
 * @author Christian Fasanando <[email protected]>,
2021
 * @todo     this function need to be improved
2022
 * @version octubre 2008, dokeos 1.8
2023
 */
2024
function get_thread_users_details($thread_id)
2025
{
2026
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2027
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2028
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2029
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2030
2031
    $course_id = api_get_course_int_id();
2032
2033
    $is_western_name_order = api_is_western_name_order();
2034
    if ($is_western_name_order) {
2035
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2036
    } else {
2037
        $orderby = 'ORDER BY user.lastname, user.firstname';
2038
    }
2039
2040 View Code Duplication
    if (api_get_session_id()) {
2041
        $session_info = api_get_session_info(api_get_session_id());
2042
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2043
        //not showing coaches
2044
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2045
                  FROM $t_posts p, $t_users user, $t_session_rel_user session_rel_user_rel_course
2046
                  WHERE p.poster_id = user.id AND
2047
                  user.id = session_rel_user_rel_course.user_id AND
2048
                  session_rel_user_rel_course.status<>'2' AND
2049
                  session_rel_user_rel_course.user_id NOT IN ($user_to_avoid) AND
2050
                  p.thread_id = ".intval($thread_id)." AND
2051
                  session_id = ".api_get_session_id()." AND
2052
                  p.c_id = $course_id AND
2053
                  session_rel_user_rel_course.c_id = ".$course_id." $orderby ";
2054
    } else {
2055
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2056
                  FROM $t_posts p, $t_users user, $t_course_user course_user
2057
                  WHERE p.poster_id = user.id
2058
                  AND user.id = course_user.user_id
2059
                  AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2060
                  AND p.thread_id = ".intval($thread_id)."
2061
                  AND course_user.status NOT IN('1') AND
2062
                  p.c_id = $course_id AND
2063
                  course_user.c_id = ".$course_id." $orderby";
2064
    }
2065
    $result = Database::query($sql);
2066
2067
    return $result;
2068
}
2069
2070
/**
2071
 * This function retrieves forum thread users qualify
2072
 * @param   int Thread ID
2073
 * @param   string  Course DB name (optional)
2074
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2075
 * @author Jhon Hinojosa
2076
 * @todo     this function need to be improved
2077
 */
2078
function get_thread_users_qualify($thread_id)
2079
{
2080
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2081
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2082
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2083
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2084
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2085
2086
    $course_id = api_get_course_int_id();
2087
2088
    $is_western_name_order = api_is_western_name_order();
2089
    if ($is_western_name_order) {
2090
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2091
    } else {
2092
        $orderby = 'ORDER BY user.lastname, user.firstname';
2093
    }
2094
2095
    if (api_get_session_id()) {
2096
        $session_info = api_get_session_info(api_get_session_id());
2097
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2098
        //not showing coaches
2099
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2100
                FROM $t_posts post , $t_users user, $t_session_rel_user scu, $t_qualify qualify
2101
                WHERE poster_id = user.id
2102
                    AND post.poster_id = qualify.user_id
2103
                    AND user.id = session_rel_user_rel_course.user_id
2104
                    AND scu.status<>'2'
2105
                    AND scu.user_id NOT IN ($user_to_avoid)
2106
                    AND qualify.thread_id = ".intval($thread_id)."
2107
                    AND post.thread_id = ".intval($thread_id)."
2108
                    AND session_id = ".api_get_session_id()."
2109
                    AND scu.c_id = ".$course_id." AND
2110
                    qualify.c_id = $course_id AND
2111
                    post.c_id = $course_id
2112
                $orderby ";
2113
    } else {
2114
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2115
                FROM $t_posts post,
2116
                     $t_qualify qualify,
2117
                     $t_users user,
2118
                     $t_course_user course_user
2119
                WHERE
2120
                     post.poster_id = user.id
2121
                     AND post.poster_id = qualify.user_id
2122
                     AND user.id = course_user.user_id
2123
                     AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2124
                     AND qualify.thread_id = ".intval($thread_id)."
2125
                     AND post.thread_id = ".intval($thread_id)."
2126
                     AND course_user.status not in('1')
2127
                     AND course_user.c_id = $course_id
2128
                     AND qualify.c_id = $course_id
2129
                     AND post.c_id = $course_id
2130
                 $orderby ";
2131
    }
2132
    $result = Database::query($sql);
2133
2134
    return $result;
2135
}
2136
2137
/**
2138
 * This function retrieves forum thread users not qualify
2139
 * @param   int Thread ID
2140
 * @param   string  Course DB name (optional)
2141
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2142
 * @author   Jhon Hinojosa<[email protected]>,
2143
 * @version oct 2008, dokeos 1.8
2144
 */
2145
function get_thread_users_not_qualify($thread_id)
2146
{
2147
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2148
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2149
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2150
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2151
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2152
2153
    $is_western_name_order = api_is_western_name_order();
2154
    if ($is_western_name_order) {
2155
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2156
    } else {
2157
        $orderby = 'ORDER BY user.lastname, user.firstname';
2158
    }
2159
2160
    $course_id = api_get_course_int_id();
2161
2162
    $sql1 = "SELECT user_id FROM  $t_qualify
2163
             WHERE c_id = $course_id AND thread_id = '".$thread_id."'";
2164
    $result1 = Database::query($sql1);
2165
    $cad = '';
2166
    while ($row = Database::fetch_array($result1)) {
2167
        $cad .= $row['user_id'].',';
2168
    }
2169
    if ($cad == '') {
2170
        $cad = '0';
2171
    } else {
2172
        $cad = substr($cad, 0, strlen($cad) - 1);
2173
    }
2174
2175 View Code Duplication
    if (api_get_session_id()) {
2176
        $session_info = api_get_session_info(api_get_session_id());
2177
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2178
        //not showing coaches
2179
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2180
                FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course
2181
                WHERE poster_id = user.id
2182
                    AND user.id NOT IN (".$cad.")
2183
                    AND user.id = session_rel_user_rel_course.user_id
2184
                    AND session_rel_user_rel_course.status<>'2'
2185
                    AND session_rel_user_rel_course.user_id NOT IN ($user_to_avoid)
2186
                    AND post.thread_id = ".intval($thread_id)."
2187
                    AND session_id = ".api_get_session_id()."
2188
                    AND session_rel_user_rel_course.c_id = $course_id AND post.c_id = $course_id $orderby ";
2189
    } else {
2190
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2191
                FROM $t_posts post, $t_users user,$t_course_user course_user
2192
                WHERE post.poster_id = user.id
2193
                AND user.id NOT IN (".$cad.")
2194
                AND user.id = course_user.user_id
2195
                AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2196
                AND post.thread_id = ".intval($thread_id)."
2197
                AND course_user.status not in('1')
2198
                AND course_user.c_id = $course_id AND post.c_id = $course_id  $orderby";
2199
    }
2200
    $result = Database::query($sql);
2201
2202
    return $result;
2203
}
2204
2205
/**
2206
 * This function retrieves all the information of a given forum_id
2207
 *
2208
 * @param $forum_id integer that indicates the forum
2209
 * @return array returns
2210
 *
2211
 * @author Patrick Cool <[email protected]>, Ghent University
2212
 * @version february 2006, dokeos 1.8
2213
 *
2214
 * @deprecated this functionality is now moved to get_forums($forum_id)
2215
 */
2216
function get_forum_information($forum_id, $courseId = 0)
2217
{
2218
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2219
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2220
    $courseId = empty($courseId) ? api_get_course_int_id(): intval($courseId);
2221
    $forum_id = intval($forum_id);
2222
2223
    $sql = "SELECT *
2224
            FROM $table_forums forums
2225
            INNER JOIN $table_item_property item_properties
2226
            ON (forums.c_id = item_properties.c_id)
2227
            WHERE
2228
                item_properties.tool = '".TOOL_FORUM."' AND
2229
                item_properties.ref = '".$forum_id."' AND
2230
                forums.forum_id = '".$forum_id."' AND
2231
                forums.c_id = ".$courseId."
2232
            ";
2233
2234
    $result = Database::query($sql);
2235
    $row = Database::fetch_array($result, 'ASSOC');
2236
    $row['approval_direct_post'] = 0;
2237
    // We can't anymore change this option, so it should always be activated.
2238
2239
    return $row;
2240
}
2241
2242
/**
2243
 * This function retrieves all the information of a given forumcategory id
2244
 *
2245
 * @param $cat_id integer that indicates the forum
2246
 *
2247
 * @return array returns if there are category or bool returns if there aren't category
2248
 * @author Patrick Cool <[email protected]>, Ghent University
2249
 * @version february 2006, dokeos 1.8
2250
 */
2251
function get_forumcategory_information($cat_id)
2252
{
2253
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
2254
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2255
2256
    $course_id = api_get_course_int_id();
2257
    $sql = "SELECT *
2258
            FROM ".$table_categories." forumcategories, ".$table_item_property." item_properties
2259
            WHERE
2260
                forumcategories.c_id = $course_id AND
2261
                item_properties.c_id = $course_id AND
2262
                item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
2263
                item_properties.ref='".Database::escape_string($cat_id)."' AND
2264
                forumcategories.cat_id='".Database::escape_string($cat_id)."'";
2265
    $result = Database::query($sql);
2266
    $row = Database::fetch_array($result);
2267
2268
    return $row;
2269
}
2270
2271
/**
2272
 * This function counts the number of forums inside a given category
2273
 *
2274
 * @param int $cat_id the id of the forum category
2275
 * @todo an additional parameter that takes the visibility into account. For instance $countinvisible=0 would return the number
2276
 *      of visible forums, $countinvisible=1 would return the number of visible and invisible forums
2277
 * @return int the number of forums inside the given category
2278
 *
2279
 * @author Patrick Cool <[email protected]>, Ghent University
2280
 * @version february 2006, dokeos 1.8
2281
 */
2282
function count_number_of_forums_in_category($cat_id)
2283
{
2284
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2285
    $course_id = api_get_course_int_id();
2286
    $sql = "SELECT count(*) AS number_of_forums
2287
            FROM ".$table_forums."
2288
            WHERE c_id = $course_id AND forum_category='".Database::escape_string($cat_id)."'";
2289
    $result = Database::query($sql);
2290
    $row = Database::fetch_array($result);
2291
2292
    return $row['number_of_forums'];
2293
}
2294
2295
/**
2296
 * This function update a thread
2297
 *
2298
 * @param array $values - The form Values
2299
 * @return void HTML
2300
 *
2301
 */
2302
function updateThread($values)
2303
{
2304
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
2305
    $courseId = api_get_course_int_id();
2306
2307
    $params = [
2308
        'thread_title' => $values['thread_title'],
2309
        'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
2310
        'thread_title_qualify' => $values['calification_notebook_title'],
2311
        'thread_qualify_max' => $values['numeric_calification'],
2312
        'thread_weight' => $values['weight_calification'],
2313
        'thread_peer_qualify' => $values['thread_peer_qualify'],
2314
    ];
2315
    $where = ['c_id = ? AND thread_id = ?' => [$courseId, $values['thread_id']]];
2316
    Database::update($threadTable, $params, $where);
2317
2318
    if (api_is_course_admin() == true) {
2319
        $option_chek = isset($values['thread_qualify_gradebook']) ? $values['thread_qualify_gradebook'] : false; // values 1 or 0
2320
        if ($option_chek) {
2321
            $id = $values['thread_id'];
2322
            $titleGradebook = Security::remove_XSS(stripslashes($values['calification_notebook_title']));
2323
            $valueCalification = isset($values['numeric_calification']) ? intval($values['numeric_calification']) : 0;
2324
            $weightCalification = isset($values['weight_calification']) ? floatval($values['weight_calification']) : 0;
2325
            $description = '';
2326
            $sessionId = api_get_session_id();
2327
            $courseId = api_get_course_id();
2328
2329
            $linkInfo = GradebookUtils::is_resource_in_course_gradebook(
2330
                $courseId,
2331
                LINK_FORUM_THREAD,
2332
                $id,
2333
                $sessionId
2334
            );
2335
            $linkId = $linkInfo['id'];
2336
2337
            if (!$linkInfo) {
2338
                GradebookUtils::add_resource_to_course_gradebook(
2339
                    $values['category_id'],
2340
                    $courseId,
2341
                    LINK_FORUM_THREAD,
2342
                    $id,
2343
                    $titleGradebook,
2344
                    $weightCalification,
2345
                    $valueCalification,
2346
                    $description,
2347
                    1,
2348
                    $sessionId
2349
                );
2350
            } else {
2351
                $em = Database::getManager();
2352
                $gradebookLink = $em->getRepository('ChamiloCoreBundle:GradebookLink')->find($linkId);
2353
                $gradebookLink->setWeight($weightCalification);
2354
                $em->persist($gradebookLink);
0 ignored issues
show
Bug introduced by
It seems like $gradebookLink defined by $em->getRepository('Cham...okLink')->find($linkId) on line 2352 can also be of type null; however, Doctrine\ORM\EntityManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2355
                $em->flush();
2356
            }
2357
        }
2358
    }
2359
2360
    $message = get_lang('EditPostStored').'<br />';
2361
    Display :: display_confirmation_message($message, false);
2362
}
2363
2364
/**
2365
 * This function stores a new thread. This is done through an entry in the forum_thread table AND
2366
 * in the forum_post table because. The threads are also stored in the item_property table. (forum posts are not (yet))
2367
 *
2368
 * @param array $current_forum
2369
 * @param array $values
2370
 * @param array $courseInfo
2371
 * @param bool $showMessage
2372
 * @return void HTML
2373
 *
2374
 * @author Patrick Cool <[email protected]>, Ghent University
2375
 * @version february 2006, dokeos 1.8
2376
 */
2377
function store_thread($current_forum, $values, $courseInfo = array(), $showMessage = true)
2378
{
2379
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo ;
2380
    $_user = api_get_user_info();
2381
    $course_id = $courseInfo['real_id'];
2382
    $courseCode = $courseInfo['code'];
2383
2384
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
2385
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
2386
2387
    $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2388
    $upload_ok = 1;
2389
    $has_attachment = false;
2390
2391 View Code Duplication
    if (!empty($_FILES['user_upload']['name'])) {
2392
        $upload_ok = process_uploaded_file($_FILES['user_upload']);
2393
        $has_attachment = true;
2394
    }
2395
2396
    if ($upload_ok) {
2397
2398
        $post_date = api_get_utc_datetime();
2399
2400 View Code Duplication
        if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2401
            $visible = 0; // The post has not been approved yet.
2402
        } else {
2403
            $visible = 1;
2404
        }
2405
2406
        $clean_post_title = $values['post_title'];
2407
2408
        // We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
2409
        $last_thread_id = Database::insert(
2410
            $table_threads,
2411
            [
2412
                'c_id' => $course_id,
2413
                'thread_title' => $clean_post_title,
2414
                'forum_id' => $values['forum_id'],
2415
                'thread_poster_id' => $_user['user_id'],
2416
                'thread_poster_name' => stripslashes(isset($values['poster_name']) ? $values['poster_name'] : ''),
2417
                'thread_date' => $post_date,
2418
                'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : '',
2419
                'thread_title_qualify' => isset($values['calification_notebook_title']) ? $values['calification_notebook_title'] : '',
2420
                'thread_qualify_max' => isset($values['numeric_calification']) ? $values['numeric_calification'] : '',
2421
                'thread_weight' => isset($values['weight_calification']) ? $values['weight_calification'] : '',
2422
                'thread_peer_qualify' => isset($values['thread_peer_qualify']) ? $values['thread_peer_qualify'] : '',
2423
                'session_id' => api_get_session_id(),
2424
                'lp_item_id' => isset($values['lp_item_id']) ? intval($values['lp_item_id']) : 0
2425
            ]
2426
        );
2427
2428
        // Add option gradebook qualify.
2429
2430
        if (isset($values['thread_qualify_gradebook']) &&
2431
            1 == $values['thread_qualify_gradebook']
2432
        ) {
2433
            // Add function gradebook.
2434
            $resourcetype = 5;
2435
            $resourceid = $last_thread_id;
2436
            $resourcename = stripslashes($values['calification_notebook_title']);
2437
            $maxqualify = $values['numeric_calification'];
2438
            $weigthqualify = $values['weight_calification'];
2439
            $resourcedescription = '';
2440
            GradebookUtils::add_resource_to_course_gradebook(
2441
                $values['category_id'],
2442
                $courseCode,
2443
                $resourcetype,
2444
                $resourceid,
2445
                $resourcename,
2446
                $weigthqualify,
2447
                $maxqualify,
2448
                $resourcedescription,
2449
                0,
2450
                api_get_session_id()
2451
            );
2452
        }
2453
2454
        if ($last_thread_id) {
2455
2456
            $sql = "UPDATE $table_threads SET thread_id = $last_thread_id
2457
                    WHERE iid = $last_thread_id";
2458
            Database::query($sql);
2459
2460
            api_item_property_update(
2461
                $courseInfo,
2462
                TOOL_FORUM_THREAD,
2463
                $last_thread_id,
2464
                'ForumThreadAdded',
2465
                api_get_user_id(),
2466
                api_get_group_id(),
2467
                null,
2468
                null,
2469
                null,
2470
                api_get_session_id()
2471
            );
2472
2473
            // If the forum properties tell that the posts have to be approved
2474
            // we have to put the whole thread invisible,
2475
            // because otherwise the students will see the thread and not the post
2476
            // in the thread.
2477
            // We also have to change $visible because the post itself has to be
2478
            // visible in this case (otherwise the teacher would have
2479
            // to make the thread visible AND the post.
2480
            // Default behaviour
2481
            api_set_default_visibility(
2482
                $last_thread_id,
2483
                TOOL_FORUM_THREAD,
2484
                api_get_group_id(),
2485
                $courseInfo
2486
            );
2487
2488
            if ($visible == 0) {
2489
                api_item_property_update(
2490
                    $courseInfo,
2491
                    TOOL_FORUM_THREAD,
2492
                    $last_thread_id,
2493
                    'invisible',
2494
                    api_get_user_id(),
2495
                    api_get_group_id()
2496
2497
                );
2498
                $visible = 1;
2499
            }
2500
        }
2501
2502
        // We now store the content in the table_post table.
2503
        $params = [
2504
            'c_id' => $course_id,
2505
            'post_title' => $clean_post_title,
2506
            'post_text' => $values['post_text'],
2507
            'thread_id' => $last_thread_id,
2508
            'forum_id' => $values['forum_id'],
2509
            'poster_id' => $_user['user_id'],
2510
            'poster_name' => isset($values['poster_name']) ? $values['poster_name'] : '',
2511
            'post_date' => $post_date,
2512
            'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
2513
            'post_parent_id' => null,
2514
            'visible' => $visible,
2515
        ];
2516
        $last_post_id = Database::insert($table_posts, $params);
2517
2518
        if ($last_post_id) {
2519
            $sql = "UPDATE $table_posts SET post_id = $last_post_id
2520
                    WHERE iid = $last_post_id";
2521
            Database::query($sql);
2522
        }
2523
2524
        // Update attached files
2525 View Code Duplication
        if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
2526
            foreach ($_POST['file_ids'] as $key => $id) {
2527
                editAttachedFile(
2528
                    array(
2529
                        'comment' => $_POST['file_comments'][$key],
2530
                        'post_id' => $last_post_id,
2531
                    ),
2532
                    $id
2533
                );
2534
            }
2535
        }
2536
2537
        // Now we have to update the thread table to fill the thread_last_post
2538
        // field (so that we know when the thread has been updated for the last time).
2539
        $sql = "UPDATE $table_threads
2540
                SET thread_last_post = '".Database::escape_string($last_post_id)."'
0 ignored issues
show
Security Bug introduced by
It seems like $last_post_id defined by \Database::insert($table_posts, $params) on line 2516 can also be of type false; however, Database::escape_string() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2541
                WHERE
2542
                    c_id = $course_id AND
2543
                    thread_id='".Database::escape_string($last_thread_id)."'";
0 ignored issues
show
Security Bug introduced by
It seems like $last_thread_id defined by \Database::insert($table...es['lp_item_id']) : 0)) on line 2409 can also be of type false; however, Database::escape_string() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2544
        $result = Database::query($sql);
2545
        $message = get_lang('NewThreadStored');
2546
        // Storing the attachments if any.
2547
        if ($has_attachment) {
2548
2549
            // Try to add an extension to the file if it hasn't one.
2550
            $new_file_name = add_ext_on_mime(
2551
                stripslashes($_FILES['user_upload']['name']),
2552
                $_FILES['user_upload']['type']
2553
            );
2554
2555
            if (!filter_extension($new_file_name)) {
2556
                if ($showMessage) {
2557
                    Display:: display_error_message(
2558
                        get_lang('UplUnableToSaveFileFilteredExtension')
2559
                    );
2560
                }
2561
            } else {
2562
                if ($result) {
2563
                    add_forum_attachment_file(
2564
                        isset($values['file_comment']) ? $values['file_comment'] : null,
2565
                        $last_post_id
2566
                    );
2567
                }
2568
            }
2569
        } else {
2570
            $message .= '<br />';
2571
        }
2572
2573
        if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2574
            $message .= get_lang('MessageHasToBeApproved').'<br />';
2575
            $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.get_lang('Forum').'</a><br />';
2576
        } else {
2577
            $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.get_lang('Forum').'</a><br />';
2578
            $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'&gradebook='.$gradebook.'&thread='.$last_thread_id.'">'.get_lang('Message').'</a>';
2579
        }
2580
        $reply_info['new_post_id'] = $last_post_id;
2581
        $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
2582
2583
        if ($my_post_notification == 1) {
2584
            set_notification('thread', $last_thread_id, true);
2585
        }
2586
2587
        send_notification_mails($last_thread_id, $reply_info);
2588
2589
        Session::erase('formelements');
2590
        Session::erase('origin');
2591
        Session::erase('breadcrumbs');
2592
        Session::erase('addedresource');
2593
        Session::erase('addedresourceid');
2594
        if ($showMessage) {
2595
            Display:: display_confirmation_message($message, false);
2596
        }
2597
    } else {
2598
        if ($showMessage) {
2599
            Display::display_error_message(get_lang('UplNoFileUploaded'));
2600
        }
2601
    }
2602
}
2603
2604
/**
2605
 * This function displays the form that is used to UPDATE a Thread.
2606
 * @param array $currentForum
2607
 * @param array $forumSetting
2608
 * @param array $formValues
2609
 * @return void HMTL
2610
 * @author José Loguercio <[email protected]>
2611
 * @version february 2016, chamilo 1.10.4
2612
 */
2613
function showUpdateThreadForm($currentForum, $forumSetting, $formValues = '')
2614
{
2615
    $userInfo = api_get_user_info();
2616
2617
    $myThread = isset($_GET['thread']) ? intval($_GET['thread']) : '';
2618
    $myForum = isset($_GET['forum']) ? intval($_GET['forum']) : '';
2619
    $myGradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2620
    $form = new FormValidator(
2621
        'thread',
2622
        'post',
2623
        api_get_self() . '?' . http_build_query([
2624
            'forum' => $myForum,
2625
            'gradebook' => $myGradebook,
2626
            'thread' => $myThread,
2627
        ]) . '&' . api_get_cidreq()
2628
    );
2629
2630
    $form->addElement('header', get_lang('EditThread'));
2631
    $form->setConstants(array('forum' => '5'));
2632
    $form->addElement('hidden', 'forum_id', $myForum);
2633
    $form->addElement('hidden', 'thread_id', $myThread);
2634
    $form->addElement('hidden', 'gradebook', $myGradebook);
2635
    $form->addElement('text', 'thread_title', get_lang('Title'));
2636
    $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2637
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2638
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && ($myThread)) {
2639
        // Thread qualify
2640
        if (Gradebook::is_active()) {
2641
            //Loading gradebook select
2642
            GradebookUtils::load_gradebook_select_in_tool($form);
2643
            $form->addElement(
2644
                'checkbox',
2645
                'thread_qualify_gradebook',
2646
                '',
2647
                get_lang('QualifyThreadGradebook'),
2648
                [
2649
                    'id' => 'thread_qualify_gradebook'
2650
                ]
2651
            );
2652
        } else {
2653
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2654
        }
2655
2656
        $form->addElement('html', '<div id="options_field" style="display:none">');
2657
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2658
        $form->applyFilter('numeric_calification', 'html_filter');
2659
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2660
        $form->applyFilter('calification_notebook_title', 'html_filter');
2661
        $form->addElement(
2662
            'text',
2663
            'weight_calification',
2664
            get_lang('QualifyWeight'),
2665
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2666
        );
2667
        $form->applyFilter('weight_calification', 'html_filter');
2668
        $group = array();
2669
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2670
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2671
        $form->addGroup(
2672
            $group,
2673
            '',
2674
            [
2675
                get_lang('ForumThreadPeerScoring'),
2676
                get_lang('ForumThreadPeerScoringComment'),
2677
            ],
2678
            ' '
2679
        );
2680
        $form->addElement('html', '</div>');
2681
    }
2682
2683 View Code Duplication
    if ($forumSetting['allow_sticky'] && api_is_allowed_to_edit(null, true)) {
2684
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2685
    }
2686
2687
    $form->addElement('html', '</div>');
2688
2689
    if (!empty($formValues)) {
2690
        $defaults['thread_qualify_gradebook'] = ($formValues['threadQualifyMax'] > 0 && empty($_POST)) ? 1 : 0 ;
2691
        $defaults['thread_title'] = prepare4display($formValues['threadTitle']);
2692
        $defaults['thread_sticky'] = strval(intval($formValues['threadSticky']));
2693
        $defaults['thread_peer_qualify'] = intval($formValues['threadPeerQualify']);
2694
        $defaults['numeric_calification'] = $formValues['threadQualifyMax'];
2695
        $defaults['calification_notebook_title'] = $formValues['threadTitleQualify'];
2696
        $defaults['weight_calification'] = $formValues['threadWeight'];
2697
    } else {
2698
        $defaults['thread_qualify_gradebook'] = 0;
2699
        $defaults['numeric_calification'] = 0;
2700
        $defaults['calification_notebook_title'] = '';
2701
        $defaults['weight_calification'] = 0;
2702
        $defaults['thread_peer_qualify'] = 0;
2703
    }
2704
    $form->setDefaults(isset($defaults) ? $defaults : null);
2705
2706
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
2707
2708
    if ($form->validate()) {
2709
        $check = Security::check_token('post');
2710
        if ($check) {
2711
            $values = $form->exportValues();
2712
            if (isset($values['thread_qualify_gradebook']) &&
2713
                $values['thread_qualify_gradebook'] == '1' &&
2714
                empty($values['weight_calification'])
2715
            ) {
2716
                Display::display_error_message(
2717
                    get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.
2718
                    get_lang('Back').'</a>',
2719
                    false
2720
                );
2721
                return false;
2722
            }
2723
            Security::clear_token();
2724
            return $values;
2725
        }
2726
    } else {
2727
        $token = Security::get_token();
2728
        $form->addElement('hidden', 'sec_token');
2729
        $form->setConstants(array('sec_token' => $token));
2730
2731
2732
        $form->display();
2733
    }
2734
}
2735
2736
/**
2737
 * This function displays the form that is used to add a post. This can be a new thread or a reply.
2738
 * @param array $current_forum
2739
 * @param array $forum_setting
2740
 * @param string $action is the parameter that determines if we are
2741
 *  1. newthread: adding a new thread (both empty) => No I-frame
2742
 *  2. replythread: Replying to a thread ($action = replythread) => I-frame with the complete thread (if enabled)
2743
 *  3. replymessage: Replying to a message ($action =replymessage) => I-frame with the complete thread (if enabled) (I first thought to put and I-frame with the message only)
2744
 *  4. quote: Quoting a message ($action= quotemessage) => I-frame with the complete thread (if enabled). The message will be in the reply. (I first thought not to put an I-frame here)
2745
 * @return void HMTL
2746
 * @author Patrick Cool <[email protected]>, Ghent University
2747
 * @version february 2006, dokeos 1.8
2748
 */
2749
function show_add_post_form($current_forum, $forum_setting, $action = '', $id = '', $form_values = '')
2750
{
2751
    $_user = api_get_user_info();
2752
    $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
2753
2754
    // Initialize the object.
2755
    $myThread = isset($_GET['thread']) ? $_GET['thread'] : '';
2756
    $my_forum = isset($_GET['forum']) ? $_GET['forum'] : '';
2757
    $my_post = isset($_GET['post']) ? $_GET['post'] : '';
2758
    $my_gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2759
    $form = new FormValidator(
2760
        'thread',
2761
        'post',
2762
        api_get_self() . '?' . http_build_query([
2763
            'forum' => intval($my_forum),
2764
            'gradebook' => $my_gradebook,
2765
            'thread' => intval($myThread),
2766
            'post' => intval($my_post),
2767
            'action' => $action,
2768
        ]) . '&' . api_get_cidreq()
2769
    );
2770
    $form->setConstants(array('forum' => '5'));
2771
2772
    // Setting the form elements.
2773
    $form->addElement('hidden', 'forum_id', intval($my_forum));
2774
    $form->addElement('hidden', 'thread_id', intval($myThread));
2775
    $form->addElement('hidden', 'gradebook', $my_gradebook);
2776
2777
    // If anonymous posts are allowed we also display a form to allow the user to put his name or username in.
2778
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2779
        $form->addElement('text', 'poster_name', get_lang('Name'));
2780
        $form->applyFilter('poster_name', 'html_filter');
2781
    }
2782
2783
    $form->addElement('text', 'post_title', get_lang('Title'));
2784
    $form->addHtmlEditor(
2785
        'post_text',
2786
        get_lang('Text'),
2787
        true,
2788
        false,
2789
        api_is_allowed_to_edit(null, true) ? array(
2790
            'ToolbarSet' => 'Forum',
2791
            'Width' => '100%',
2792
            'Height' => '300',
2793
        ) : array(
2794
            'ToolbarSet' => 'ForumStudent',
2795
            'Width' => '100%',
2796
            'Height' => '300',
2797
            'UserStatus' => 'student',
2798
        )
2799
    );
2800
2801
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
2802
    $iframe = null;
2803
    $myThread = Security::remove_XSS($myThread);
2804
    if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
2805
        $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?".api_get_cidreq()."&forum=".Security::remove_XSS($my_forum)."&thread=".$myThread."#".Security::remove_XSS($my_post)."\" width=\"100%\"></iframe>";
2806
    }
2807
    if (!empty($iframe)) {
2808
        $form->addElement('label', get_lang('Thread'), $iframe);
2809
    }
2810
2811
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && !($myThread)) {
2812
2813
        $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2814
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2815
2816
        // Thread qualify
2817
        if (Gradebook::is_active()) {
2818
            //Loading gradebook select
2819
            GradebookUtils::load_gradebook_select_in_tool($form);
2820
            $form->addElement(
2821
                'checkbox',
2822
                'thread_qualify_gradebook',
2823
                '',
2824
                get_lang('QualifyThreadGradebook'),
2825
                'onclick="javascript:if(this.checked==true){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
2826
            );
2827
        } else {
2828
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2829
        }
2830
2831
        $form->addElement('html', '<div id="options_field" style="display:none">');
2832
2833
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2834
        $form->applyFilter('numeric_calification', 'html_filter');
2835
2836
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2837
        $form->applyFilter('calification_notebook_title', 'html_filter');
2838
2839
        $form->addElement(
2840
            'text',
2841
            'weight_calification',
2842
            get_lang('QualifyWeight'),
2843
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2844
        );
2845
        $form->applyFilter('weight_calification', 'html_filter');
2846
2847
        $group = array();
2848
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2849
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2850
        $form->addGroup(
2851
            $group,
2852
            '',
2853
            [
2854
                get_lang('ForumThreadPeerScoring'),
2855
                get_lang('ForumThreadPeerScoringComment'),
2856
            ],
2857
            ' '
2858
        );
2859
2860
        $form->addElement('html', '</div>');
2861
        $form->addElement('html', '</div>');
2862
    }
2863
2864 View Code Duplication
    if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
2865
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2866
    }
2867
2868
    if ($current_forum['allow_attachments'] == '1' || api_is_allowed_to_edit(null, true)) {
2869
        $values = $form->exportValues();
2870
    }
2871
2872
    if (in_array($action, ['quote', 'replymessage'])) {
2873
        $form->addFile('user_upload[]', get_lang('Attachment'));
2874
        $form->addButton(
2875
            'add_attachment',
2876
            get_lang('AddAttachment'),
2877
            'paperclip',
2878
            'default',
2879
            'default',
2880
            null,
2881
            ['id' => 'reply-add-attachment']
2882
        );
2883
    } else {
2884
        $form->addFile('user_upload', get_lang('Attachment'));
2885
    }
2886
2887
    // Setting the class and text of the form title and submit button.
2888
    if ($action == 'quote') {
2889
        $form->addButtonCreate(get_lang('QuoteMessage'), 'SubmitPost');
2890
    } elseif ($action == 'replythread') {
2891
        $form->addButtonCreate(get_lang('ReplyToThread'), 'SubmitPost');
2892
    } elseif ($action == 'replymessage') {
2893
        $form->addButtonCreate(get_lang('ReplyToMessage'), 'SubmitPost');
2894
    } else {
2895
        $form->addButtonCreate(get_lang('CreateThread'), 'SubmitPost');
2896
    }
2897
2898
    if (!empty($form_values)) {
2899
        $defaults['post_title'] = prepare4display($form_values['post_title']);
2900
        $defaults['post_text'] = prepare4display($form_values['post_text']);
2901
        $defaults['post_notification'] = strval(intval($form_values['post_notification']));
2902
        $defaults['thread_sticky'] = strval(intval($form_values['thread_sticky']));
2903
        $defaults['thread_peer_qualify'] = intval($form_values['thread_peer_qualify']);
2904
    } else {
2905
        $defaults['thread_peer_qualify'] = 0;
2906
    }
2907
2908
    // If we are quoting a message we have to retrieve the information of the post we are quoting so that
2909
    // we can add this as default to the textarea.
2910
2911
    if (($action == 'quote' || $action == 'replymessage') && isset($my_post)) {
2912
        // We also need to put the parent_id of the post in a hidden form when
2913
        // we are quoting or replying to a message (<> reply to a thread !!!)
2914
        $form->addElement('hidden', 'post_parent_id', intval($my_post));
2915
2916
        // If we are replying or are quoting then we display a default title.
2917
        $values = get_post_information($my_post);
2918
        $defaults['post_title'] = get_lang('ReplyShort').api_html_entity_decode($values['post_title'], ENT_QUOTES);
2919
        // When we are quoting a message then we have to put that message into the wysiwyg editor.
2920
        // Note: The style has to be hardcoded here because using class="quote" didn't work.
2921
        if ($action == 'quote') {
2922
            $defaults['post_text'] = '<div>&nbsp;</div><div style="margin: 5px;"><div style="font-size: 90%; font-style: italic;">'.get_lang('Quoting').' '.api_get_person_name($values['firstname'], $values['lastname']).':</div><div style="color: #006600; font-size: 90%;  font-style: italic; background-color: #FAFAFA; border: #D1D7DC 1px solid; padding: 3px;">'.prepare4display($values['post_text']).'</div></div><div>&nbsp;</div><div>&nbsp;</div>';
2923
        }
2924
    }
2925
2926
    $form->setDefaults(isset($defaults) ? $defaults : null);
2927
2928
    // The course admin can make a thread sticky (=appears with special icon and always on top).
2929
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
2930
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2931
        $form->addRule('poster_name', get_lang('ThisFieldIsRequired'), 'required');
2932
    }
2933
2934
    // Validation or display
2935
    if ($form->validate()) {
2936
        $check = Security::check_token('post');
2937
        if ($check) {
2938
            $values = $form->exportValues();
2939
            if (isset($values['thread_qualify_gradebook']) &&
2940
                $values['thread_qualify_gradebook'] == '1' &&
2941
                empty($values['weight_calification'])
2942
            ) {
2943
                Display::display_error_message(
2944
                    get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.
2945
                    get_lang('Back').'</a>',
2946
                    false
2947
                );
2948
2949
                return false;
2950
            }
2951
            Security::clear_token();
2952
2953
            return $values;
2954
        }
2955
    } else {
2956
        $token = Security::get_token();
2957
        $form->addElement('hidden', 'sec_token');
2958
        $form->setConstants(array('sec_token' => $token));
2959
2960
        // Delete from $_SESSION forum attachment from other posts
2961
        // and keep only attachments for new post
2962
        clearAttachedFiles(FORUM_NEW_POST);
2963
        // Get forum attachment ajax table to add it to form
2964
        $attachmentAjaxTable = getAttachmentsAjaxTable(0, $current_forum['forum_id']);
2965
        $ajaxHtml = $attachmentAjaxTable;
2966
        $form->addElement('html', $ajaxHtml);
2967
        $form->display();
2968
    }
2969
}
2970
2971
/**
2972
 * @param array $threadInfo
2973
 * @param integer $user_id
2974
 * @param integer $thread_id
2975
 * @param integer $thread_qualify
2976
 * @param integer $qualify_time
2977
 * @param integer $session_id
2978
 * @return Array() optional
0 ignored issues
show
Documentation introduced by
The doc-type Array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
2979
 * @author Isaac Flores <[email protected]>, U.N.A.S University
2980
 * @version October 2008, dokeos  1.8.6
2981
 */
2982
function saveThreadScore(
2983
    $threadInfo,
2984
    $user_id,
2985
    $thread_id,
2986
    $thread_qualify = 0,
2987
    $qualify_time,
2988
    $session_id = 0
2989
) {
2990
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2991
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
2992
2993
    $course_id = api_get_course_int_id();
2994
    $session_id = intval($session_id);
2995
    $currentUserId = api_get_user_id();
2996
2997
    if ($user_id == strval(intval($user_id)) &&
2998
        $thread_id == strval(intval($thread_id)) &&
2999
        $thread_qualify == strval(floatval($thread_qualify))
3000
    ) {
3001
        // Testing
3002
        $sql = "SELECT thread_qualify_max FROM $table_threads
3003
                WHERE c_id = $course_id AND thread_id=".$thread_id;
3004
        $res_string = Database::query($sql);
3005
        $row_string = Database::fetch_array($res_string);
3006
        if ($thread_qualify <= $row_string[0]) {
3007
3008
            if ($threadInfo['thread_peer_qualify'] == 0) {
3009
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3010
                        WHERE
3011
                            c_id = $course_id AND
3012
                            user_id = $user_id AND
3013
                            thread_id = ".$thread_id;
3014
            } else {
3015
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3016
                        WHERE
3017
                            c_id = $course_id AND
3018
                            user_id = $user_id AND
3019
                            qualify_user_id = $currentUserId AND
3020
                            thread_id = ".$thread_id;
3021
            }
3022
3023
            $result = Database::query($sql);
3024
            $row = Database::fetch_array($result);
3025
3026
            if ($row[0] == 0) {
3027
                $sql = "INSERT INTO $table_threads_qualify (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
3028
                        VALUES (".$course_id.", '".$user_id."','".$thread_id."',".(float)$thread_qualify.", '".$currentUserId."','".$qualify_time."','".$session_id."')";
3029
                Database::query($sql);
3030
3031
                $insertId = Database::insert_id();
3032
                if ($insertId) {
3033
                    $sql = "UPDATE $table_threads_qualify SET id = iid
3034
                            WHERE iid = $insertId";
3035
                    Database::query($sql);
3036
                }
3037
3038
                return 'insert';
3039
            } else {
3040
3041
                saveThreadScoreHistory(
3042
                    '1',
3043
                    $course_id,
3044
                    $user_id,
3045
                    $thread_id
3046
                );
3047
3048
3049
                // Update
3050
                $sql = "UPDATE $table_threads_qualify
3051
                        SET
3052
                            qualify = '".$thread_qualify."',
3053
                            qualify_time = '".$qualify_time."'
3054
                        WHERE
3055
                            c_id = $course_id AND
3056
                            user_id=".$user_id." AND
3057
                            thread_id=".$thread_id." AND
3058
                            qualify_user_id = $currentUserId
3059
                        ";
3060
                Database::query($sql);
3061
3062
                return 'update';
3063
            }
3064
3065
        } else {
3066
            return null;
3067
        }
3068
    }
3069
}
3070
3071
/**
3072
 * This function shows qualify.
3073
 * @param string $option contains the information of option to run
3074
 * @param integer $user_id contains the information the current user id
3075
 * @param integer $thread_id contains the information the current thread id
3076
 * @return integer qualify
3077
 * <code> $option=1 obtained the qualification of the current thread</code>
3078
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3079
 * @version October 2008, dokeos  1.8.6
3080
 */
3081
function showQualify($option, $user_id, $thread_id)
3082
{
3083
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3084
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3085
3086
    $course_id = api_get_course_int_id();
3087
    $user_id = intval($user_id);
3088
    $thread_id = intval($thread_id);
3089
3090
    if (empty($user_id) || empty($thread_id)) {
3091
        return false;
3092
    }
3093
3094
    $sql = '';
3095
    switch ($option) {
3096
        case 1:
3097
            $sql = "SELECT qualify FROM $table_threads_qualify
3098
                    WHERE
3099
                        c_id = $course_id AND
3100
                        user_id=".$user_id." AND
3101
                        thread_id=".$thread_id;
3102
            break;
3103
        case 2:
3104
            $sql = "SELECT thread_qualify_max FROM $table_threads
3105
                    WHERE c_id = $course_id AND thread_id=".$thread_id;
3106
            break;
3107
    }
3108
3109
    if (!empty($sql)) {
3110
        $rs = Database::query($sql);
3111
        $row = Database::fetch_array($rs);
3112
3113
        return $row[0];
3114
    }
3115
3116
    return array();
3117
}
3118
3119
/**
3120
 * This function gets qualify historical.
3121
 * @param integer $user_id contains the information the current user id
3122
 * @param integer $thread_id contains the information the current thread id
3123
 * @param boolean $opt contains the information of option to run
3124
 * @return array()
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
3125
 * @author Christian Fasanando <[email protected]>,
3126
 * @author Isaac Flores <[email protected]>,
3127
 * @version October 2008, dokeos  1.8.6
3128
 */
3129
function getThreadScoreHistory($user_id, $thread_id, $opt)
3130
{
3131
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3132
    $course_id = api_get_course_int_id();
3133
3134
    if ($opt == 'false') {
3135
        $sql = "SELECT * FROM ".$table_threads_qualify_log."
3136
                WHERE
3137
                    c_id = $course_id AND
3138
                    thread_id='".Database::escape_string($thread_id)."' AND
3139
                    user_id='".Database::escape_string($user_id)."'
3140
                ORDER BY qualify_time";
3141
    } else {
3142
        $sql = "SELECT * FROM ".$table_threads_qualify_log."
3143
                WHERE
3144
                    c_id = $course_id AND
3145
                    thread_id='".Database::escape_string($thread_id)."' AND
3146
                    user_id='".Database::escape_string($user_id)."'
3147
                ORDER BY qualify_time DESC";
3148
    }
3149
    $rs = Database::query($sql);
3150
    $log = array();
3151
    while ($row = Database::fetch_array($rs, 'ASSOC')) {
3152
        $log[] = $row;
3153
    }
3154
3155
    return $log;
3156
}
3157
3158
/**
3159
 * This function stores qualify historical.
3160
 * @param boolean contains the information of option to run
3161
 * @param string contains the information the current course id
3162
 * @param integer contains the information the current forum id
3163
 * @param integer contains the information the current user id
3164
 * @param integer contains the information the current thread id
3165
 * @param integer contains the information the current qualify
3166
 * @param string $option
3167
 * @param integer $course_id
3168
 * @param integer $user_id
3169
 * @param integer $thread_id
3170
 * @return void
3171
 * <code>$option=1 obtained the qualification of the current thread</code>
3172
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3173
 * @version October 2008, dokeos  1.8.6
3174
 */
3175
function saveThreadScoreHistory(
3176
    $option,
3177
    $course_id,
3178
    $user_id,
3179
    $thread_id
3180
) {
3181
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3182
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3183
3184
    $course_id = intval($course_id);
3185
    $qualify_user_id = api_get_user_id();
3186
3187
    if ($user_id == strval(intval($user_id)) &&
3188
        $thread_id == strval(intval($thread_id)) && $option == 1
3189
    ) {
3190
3191
        // Extract information of thread_qualify.
3192
        $sql = "SELECT qualify, qualify_time
3193
                FROM $table_threads_qualify
3194
                WHERE
3195
                    c_id = $course_id AND
3196
                    user_id = ".$user_id." AND
3197
                    thread_id = ".$thread_id." AND
3198
                    qualify_user_id = $qualify_user_id
3199
                ";
3200
        $rs = Database::query($sql);
3201
        $row = Database::fetch_array($rs);
3202
3203
        // Insert thread_historical.
3204
        $sql = "INSERT INTO $table_threads_qualify_log (c_id, user_id, thread_id, qualify, qualify_user_id,qualify_time,session_id)
3205
                VALUES(".$course_id.", '".$user_id."','".$thread_id."',".(float) $row[0].", '".$qualify_user_id."','".$row[1]."','')";
3206
        Database::query($sql);
3207
3208
        $insertId = Database::insert_id();
3209
        if ($insertId) {
3210
            $sql = "UPDATE $table_threads_qualify_log SET id = iid
3211
                    WHERE iid = $insertId";
3212
            Database::query($sql);
3213
        }
3214
    }
3215
}
3216
3217
/**
3218
 * This function shows current thread qualify .
3219
 * @param integer $threadId
3220
 * @param integer $sessionId
3221
 * @param integer $userId
3222
 *
3223
 * @return array or null if is empty
3224
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3225
 * @version December 2008, dokeos  1.8.6
3226
 */
3227 View Code Duplication
function current_qualify_of_thread($threadId, $sessionId, $userId)
3228
{
3229
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3230
3231
    $course_id = api_get_course_int_id();
3232
    $currentUserId = api_get_user_id();
3233
    $sessionId = intval($sessionId);
3234
    $threadId = intval($threadId);
3235
3236
    $sql = "SELECT qualify FROM $table_threads_qualify
3237
            WHERE
3238
                c_id = $course_id AND
3239
                thread_id = $threadId AND
3240
                session_id = $sessionId AND
3241
                qualify_user_id = $currentUserId AND
3242
                user_id = $userId
3243
            ";
3244
    $res = Database::query($sql);
3245
    $row = Database::fetch_array($res, 'ASSOC');
3246
3247
    return $row['qualify'];
3248
}
3249
3250
/**
3251
 * This function stores a reply in the forum_post table.
3252
 * It also updates the forum_threads table (thread_replies +1 , thread_last_post, thread_date)
3253
 * @param array $current_forum
3254
 * @param array $values
3255
 * @author Patrick Cool <[email protected]>, Ghent University
3256
 * @version february 2006, dokeos 1.8
3257
 */
3258
function store_reply($current_forum, $values)
3259
{
3260
    $_course = api_get_course_info();
3261
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3262
    $post_date = api_get_utc_datetime();
3263
3264 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' &&
3265
        !api_is_allowed_to_edit(null, true)
3266
    ) {
3267
        $visible = 0;
3268
    } else {
3269
        $visible = 1;
3270
    }
3271
3272
    $upload_ok = 1;
3273
3274
    $return = array();
3275
3276
    if ($upload_ok) {
3277
        // We first store an entry in the forum_post table.
3278
        $new_post_id = Database::insert(
3279
            $table_posts,
3280
            [
3281
                'c_id' => api_get_course_int_id(),
3282
                'post_title' => $values['post_title'],
3283
                'post_text' => isset($values['post_text']) ? ($values['post_text']) : null,
3284
                'thread_id' => $values['thread_id'],
3285
                'forum_id' => $values['forum_id'],
3286
                'poster_id' => api_get_user_id(),
3287
                'post_id' => 0,
3288
                'post_date' => $post_date,
3289
                'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : null,
3290
                'post_parent_id' => isset($values['post_parent_id']) ? $values['post_parent_id'] : null,
3291
                'visible' => $visible,
3292
            ]
3293
        );
3294
3295
        if ($new_post_id) {
3296
            $sql = "UPDATE $table_posts SET post_id = iid WHERE iid = $new_post_id";
3297
            Database::query($sql);
3298
3299
            $values['new_post_id'] = $new_post_id;
3300
            $message = get_lang('ReplyAdded');
3301
3302 View Code Duplication
            if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3303
                foreach ($_POST['file_ids'] as $key => $id) {
3304
                    editAttachedFile(
3305
                        array(
3306
                            'comment' => $_POST['file_comments'][$key],
3307
                            'post_id' => $new_post_id,
3308
                        ),
3309
                        $id
3310
                    );
3311
                }
3312
            }
3313
3314
            // Update the thread.
3315
            updateThreadInfo($values['thread_id'], $new_post_id, $post_date);
3316
3317
            // Update the forum.
3318
            api_item_property_update(
3319
                $_course,
3320
                TOOL_FORUM,
3321
                $values['forum_id'],
3322
                'NewMessageInForum',
3323
                api_get_user_id()
3324
            );
3325
3326
            // Insert post
3327
            api_item_property_update(
3328
                $_course,
3329
                TOOL_FORUM_POST,
3330
                $new_post_id,
3331
                'NewPost',
3332
                api_get_user_id()
3333
            );
3334
3335
            if ($current_forum['approval_direct_post'] == '1' &&
3336
                !api_is_allowed_to_edit(null, true)
3337
            ) {
3338
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3339
            }
3340
3341
            // Setting the notification correctly.
3342
            $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
3343
            if ($my_post_notification == 1) {
3344
                set_notification('thread', $values['thread_id'], true);
3345
            }
3346
3347
            send_notification_mails($values['thread_id'], $values);
3348
            add_forum_attachment_file('', $new_post_id);
3349
        }
3350
3351
        Session::erase('formelements');
3352
        Session::erase('origin');
3353
        Session::erase('breadcrumbs');
3354
        Session::erase('addedresource');
3355
        Session::erase('addedresourceid');
3356
        $return['msg'] = $message;
3357
        $return['type'] = 'confirmation';
3358
3359
    } else {
3360
        $return['msg'] = get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst');
3361
        $return['type'] = 'error';
3362
    }
3363
3364
    return $return;
3365
}
3366
3367
/**
3368
 * This function displays the form that is used to edit a post. This can be a new thread or a reply.
3369
 * @param array contains all the information about the current post
3370
 * @param array contains all the information about the current thread
3371
 * @param array contains all info about the current forum (to check if attachments are allowed)
3372
 * @param array contains the default values to fill the form
3373
 * @return void
3374
 *
3375
 * @author Patrick Cool <[email protected]>, Ghent University
3376
 * @version february 2006, dokeos 1.8
3377
 */
3378
function show_edit_post_form(
3379
    $forum_setting,
3380
    $current_post,
3381
    $current_thread,
3382
    $current_forum,
3383
    $form_values = '',
3384
    $id_attach = 0
3385
) {
3386
    // Initialize the object.
3387
    $form = new FormValidator(
3388
        'edit_post',
3389
        'post',
3390
        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
3391
    );
3392
    $form->addElement('header', get_lang('EditPost'));
3393
    // Setting the form elements.
3394
    $form->addElement('hidden', 'post_id', $current_post['post_id']);
3395
    $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
3396
    $form->addElement('hidden', 'id_attach', $id_attach);
3397
3398
    if (empty($current_post['post_parent_id'])) {
3399
        $form->addElement('hidden', 'is_first_post_of_thread', '1');
3400
    }
3401
3402
    $form->addElement('text', 'post_title', get_lang('Title'));
3403
    $form->applyFilter('post_title', 'html_filter');
3404
    $form->addElement(
3405
        'html_editor',
3406
        'post_text',
3407
        get_lang('Text'),
3408
        null,
3409
        api_is_allowed_to_edit(null, true) ? array(
3410
            'ToolbarSet' => 'Forum',
3411
            'Width' => '100%',
3412
            'Height' => '400',
3413
        ) : array(
3414
            'ToolbarSet' => 'ForumStudent',
3415
            'Width' => '100%',
3416
            'Height' => '400',
3417
            'UserStatus' => 'student',
3418
        )
3419
    );
3420
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
3421
3422
    $form->addButtonAdvancedSettings('advanced_params');
3423
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
3424
3425
    if (!isset($_GET['edit'])) {
3426
        if (Gradebook::is_active()) {
3427
            $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
3428
            $form->addElement('checkbox', 'thread_qualify_gradebook', '', get_lang('QualifyThreadGradebook'), 'onclick="javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"');
3429
3430
            $link_info = GradebookUtils::is_resource_in_course_gradebook(api_get_course_id(), 5, $_GET['thread'], api_get_session_id());
3431
            if (!empty($link_info)) {
3432
                $defaults['thread_qualify_gradebook'] = true;
3433
                $defaults['category_id'] = $link_info['category_id'];
3434
            } else {
3435
                $defaults['thread_qualify_gradebook'] = false;
3436
                $defaults['category_id'] = '';
3437
            }
3438
        } else {
3439
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
3440
            $defaults['thread_qualify_gradebook'] = false;
3441
        }
3442
3443
        if (!empty($defaults['thread_qualify_gradebook'])) {
3444
            $form->addElement('html', '<div id="options_field" style="display:block">');
3445
        } else {
3446
            $form->addElement('html', '<div id="options_field" style="display:none">');
3447
        }
3448
3449
        // Loading gradebook select
3450
        GradebookUtils::load_gradebook_select_in_tool($form);
3451
3452
        $form->addElement(
3453
            'text',
3454
            'numeric_calification',
3455
            get_lang('QualificationNumeric'),
3456
            array(
3457
                'value' => $current_thread['thread_qualify_max'],
3458
                'style' => 'width:40px',
3459
            )
3460
        );
3461
        $form->applyFilter('numeric_calification', 'html_filter');
3462
3463
        $form->addElement(
3464
            'text',
3465
            'calification_notebook_title',
3466
            get_lang('TitleColumnGradebook'),
3467
            array('value' => $current_thread['thread_title_qualify'])
3468
        );
3469
        $form->applyFilter('calification_notebook_title', 'html_filter');
3470
3471
        $form->addElement(
3472
            'text',
3473
            'weight_calification',
3474
            array(get_lang('QualifyWeight'), null, ''),
3475
            array(
3476
                'value' => $current_thread['thread_weight'],
3477
                'style' => 'width:40px',
3478
            )
3479
        );
3480
        $form->applyFilter('weight_calification', 'html_filter');
3481
3482
        $group = array();
3483
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
3484
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
3485
        $form->addGroup(
3486
            $group,
3487
            '',
3488
            [
3489
                get_lang('ForumThreadPeerScoring'),
3490
                get_lang('ForumThreadPeerScoringComment'),
3491
            ],
3492
            ' '
3493
        );
3494
3495
        $form->addElement('html', '</div>');
3496
    }
3497
3498
    if ($forum_setting['allow_sticky'] &&
3499
        api_is_allowed_to_edit(null, true) &&
3500
        empty($current_post['post_parent_id'])
3501
    ) {
3502
        // The sticky checkbox only appears when it is the first post of a thread.
3503
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3504
        if ($current_thread['thread_sticky'] == 1) {
3505
            $defaults['thread_sticky'] = true;
3506
        }
3507
    }
3508
3509
    if ($current_forum['allow_attachments'] == '1' || api_is_allowed_to_edit(null, true)) {
3510
        if (empty($form_values) && !isset($_POST['SubmitPost'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3511
            //edit_added_resources('forum_post', $current_post['post_id']);
3512
        }
3513
    }
3514
3515
    $form->addElement('html', '</div>');
3516
3517
    $form->addFile('user_upload[]', get_lang('Attachment'));
3518
    $form->addButton(
3519
        'add_attachment',
3520
        get_lang('AddAttachment'),
3521
        'paperclip',
3522
        'default',
3523
        'default',
3524
        null,
3525
        ['id' => 'reply-add-attachment']
3526
    );
3527
3528
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
3529
3530
    // Setting the default values for the form elements.
3531
    $defaults['post_title'] = $current_post['post_title'];
3532
    $defaults['post_text'] = $current_post['post_text'];
3533
    if ($current_post['post_notification'] == 1) {
3534
        $defaults['post_notification'] = true;
3535
    }
3536
3537
    if (!empty($form_values)) {
3538
        $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
3539
        $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
3540
    }
3541
3542
    $defaults['thread_peer_qualify'] = intval($current_thread['thread_peer_qualify']);
3543
3544
    $form->setDefaults($defaults);
3545
3546
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3547
3548
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3549
3550
    // Validation or display
3551
    if ($form->validate()) {
3552
        $values = $form->exportValues();
3553
3554
        if (isset($values['thread_qualify_gradebook']) && $values['thread_qualify_gradebook'] == '1' &&
3555
            empty($values['weight_calification'])
3556
        ) {
3557
            Display::display_error_message(get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>', false);
3558
            return false;
3559
        }
3560
        return $values;
3561
    } else {
3562
        // Delete from $_SESSION forum attachment from other posts
3563
        clearAttachedFiles($current_post['post_id']);
3564
        // Get forum attachment ajax table to add it to form
3565
        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
3566
        $form->addElement('html', $fileData);
3567
        $form->display();
3568
    }
3569
}
3570
3571
/**
3572
 * This function stores the edit of a post in the forum_post table.
3573
 *
3574
 * @param array
3575
 * @return void HTML
3576
 *
3577
 * @author Patrick Cool <[email protected]>, Ghent University
3578
 * @version february 2006, dokeos 1.8
3579
 */
3580
function store_edit_post($values)
3581
{
3582
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
3583
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3584
    $gradebook = Security::remove_XSS($_GET['gradebook']);
3585
    $course_id = api_get_course_int_id();
3586
3587
    //check if this post is the first of the thread
3588
    // First we check if the change affects the thread and if so we commit
3589
    // the changes (sticky and post_title=thread_title are relevant).
3590
3591
    $posts = getPosts($values['thread_id']);
3592
    $first_post = null;
3593
    if (!empty($posts) && count($posts) > 0 && isset($posts[0])) {
3594
        $first_post = $posts[0];
3595
    }
3596
3597
    if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
3598
        $params = [
3599
            'thread_title' => $values['post_title'],
3600
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
3601
            'thread_title_qualify' => $values['calification_notebook_title'],
3602
            'thread_qualify_max' => $values['numeric_calification'],
3603
            'thread_weight' => $values['weight_calification'],
3604
            'thread_peer_qualify' => $values['thread_peer_qualify'],
3605
        ];
3606
        $where = ['c_id = ? AND thread_id = ?' => [$course_id, $values['thread_id']]];
3607
3608
        Database::update($threadTable, $params, $where);
3609
    }
3610
3611
    // Update the post_title and the post_text.
3612
    $params = [
3613
        'post_title' => $values['post_title'],
3614
        'post_text' => $values['post_text'],
3615
        'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
3616
    ];
3617
    $where = ['c_id = ? AND post_id = ?' => [$course_id, $values['post_id']]];
3618
3619
    Database::update($table_posts, $params, $where);
3620
3621
    // Update attached files
3622 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3623
        foreach ($_POST['file_ids'] as $key => $id) {
3624
            editAttachedFile(array('comment' => $_POST['file_comments'][$key], 'post_id' => $values['post_id']), $id);
3625
        }
3626
    }
3627
3628
    if (!empty($values['remove_attach'])) {
3629
        delete_attachment($values['post_id']);
3630
    }
3631
3632
    if (empty($values['id_attach'])) {
3633
        add_forum_attachment_file(
3634
            isset($values['file_comment']) ? $values['file_comment'] : null,
3635
            $values['post_id']
3636
        );
3637
    } else {
3638
        edit_forum_attachment_file(
3639
            isset($values['file_comment']) ? $values['file_comment'] : null,
3640
            $values['post_id'],
3641
            $values['id_attach']
3642
        );
3643
    }
3644
3645
    // Storing the attachments if any.
3646
    //update_added_resources('forum_post', $values['post_id']);
3647
3648
    $message = get_lang('EditPostStored').'<br />';
3649
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&">'.get_lang('Forum').'</a><br />';
3650
    $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.$values['thread_id'].'&post='.Security::remove_XSS($_GET['post']).'">'.get_lang('Message').'</a>';
3651
3652
    Session::erase('formelements');
3653
    Session::erase('origin');
3654
    Session::erase('breadcrumbs');
3655
    Session::erase('addedresource');
3656
    Session::erase('addedresourceid');
3657
3658
    Display :: display_confirmation_message($message, false);
3659
}
3660
3661
/**
3662
 * This function displays the firstname and lastname of the user as a link to the user tool.
3663
 *
3664
 * @param string names
3665
 * @ in_title : title tootip
3666
 * @return string HTML
3667
 *
3668
 * @author Patrick Cool <[email protected]>, Ghent University
3669
 * @version february 2006, dokeos 1.8
3670
 */
3671
function display_user_link($user_id, $name, $origin = '', $in_title = '')
3672
{
3673
    if ($user_id != 0) {
3674
        $userInfo = api_get_user_info($user_id);
3675
3676
        return '<a href="'.$userInfo['profile_url'].'">'.Security::remove_XSS($userInfo['complete_name']).'</a>';
3677
    } else {
3678
        return $name.' ('.get_lang('Anonymous').')';
3679
    }
3680
}
3681
3682
/**
3683
 * This function displays the user image from the profile, with a link to the user's details.
3684
 * @param   int     User's database ID
3685
 * @param   string  User's name
3686
 * @param   string  the origin where the forum is called (example : learnpath)
3687
 * @return  string  An HTML with the anchor and the image of the user
3688
 * @author Julio Montoya <[email protected]>
3689
 */
3690
function display_user_image($user_id, $name, $origin = '')
3691
{
3692
    $userInfo = api_get_user_info($user_id);
3693
3694
    $link = '<a href="'.(!empty($origin) ? '#' : $userInfo['profile_url']).'" '.(!empty($origin) ? 'target="_self"' : '').'>';
3695
3696
    if ($user_id != 0) {
3697
        return $link.'<img src="'.$userInfo['avatar'].'"  alt="'.$name.'"  title="'.$name.'" /></a>';
3698
    } else {
3699
        return $link.Display::return_icon('unknown.jpg', $name).'</a>';
3700
    }
3701
}
3702
3703
/**
3704
 * The thread view counter gets increased every time someone looks at the thread
3705
 *
3706
 * @param int
3707
 * @return void
3708
 *
3709
 * @author Patrick Cool <[email protected]>, Ghent University
3710
 * @version february 2006, dokeos 1.8
3711
 */
3712
function increase_thread_view($thread_id)
3713
{
3714
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3715
    $course_id = api_get_course_int_id();
3716
3717
    $sql = "UPDATE $table_threads SET thread_views=thread_views+1
3718
            WHERE c_id = $course_id AND  thread_id='".Database::escape_string($thread_id)."'"; // This needs to be cleaned first.
3719
    Database::query($sql);
3720
}
3721
3722
/**
3723
 * The relies counter gets increased every time somebody replies to the thread
3724
 *
3725
 * @author Patrick Cool <[email protected]>, Ghent University
3726
 * @version february 2006, dokeos 1.8
3727
 * @param string $last_post_id
3728
 * @param string $post_date
3729
 */
3730
function updateThreadInfo($thread_id, $last_post_id, $post_date)
3731
{
3732
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3733
    $course_id = api_get_course_int_id();
3734
    $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1,
3735
            thread_last_post='".Database::escape_string($last_post_id)."',
3736
            thread_date='".Database::escape_string($post_date)."'
3737
            WHERE c_id = $course_id AND  thread_id='".Database::escape_string($thread_id)."'"; // this needs to be cleaned first
3738
    Database::query($sql);
3739
}
3740
3741
/**
3742
 * This function is called when the user is not allowed in this forum/thread/...
3743
 * @return bool display message of "not allowed"
3744
 *
3745
 * @author Patrick Cool <[email protected]>, Ghent University
3746
 * @version february 2006, dokeos 1.8
3747
 */
3748
function forum_not_allowed_here()
3749
{
3750
    Display :: display_error_message(get_lang('NotAllowedHere'));
3751
    Display :: display_footer();
3752
3753
    return false;
3754
}
3755
3756
/**
3757
 * This function is used to find all the information about what's new in the forum tool
3758
 * @return void
3759
 *
3760
 * @author Patrick Cool <[email protected]>, Ghent University
3761
 * @version february 2006, dokeos 1.8
3762
 */
3763
function get_whats_new()
3764
{
3765
    $_user = api_get_user_info();
3766
    $_course = api_get_course_info();
3767
3768
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3769
    $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
3770
3771
    // Note: This has to be replaced by the tool constant later. But temporarily bb_forum is used since this is the only thing that is in the tracking currently.
3772
    //$tool = TOOL_FORUM;
3773
    $tool = TOOL_FORUM; //
3774
    // to do: Remove this. For testing purposes only.
3775
    //Session::erase('last_forum_access');
3776
    //Session::erase('whatsnew_post_info');
3777
3778
    $course_id = api_get_course_int_id();
3779
    $lastForumAccess = Session::read('last_forum_access');
3780
3781
    if (!$lastForumAccess) {
3782
        $sql = "SELECT * FROM ".$tracking_last_tool_access."
3783
                WHERE
3784
                    access_user_id='".Database::escape_string($_user['user_id'])."' AND
3785
                    c_id ='".$course_id."' AND
3786
                    access_tool='".Database::escape_string($tool)."'";
3787
        $result = Database::query($sql);
3788
        $row = Database::fetch_array($result);
3789
        $_SESSION['last_forum_access'] = $row['access_date'];
3790
    }
3791
3792
    $whatsNew = Session::read('whatsnew_post_info');
3793
3794
    if (!$whatsNew) {
3795
        if ($lastForumAccess != '') {
3796
            $whatsnew_post_info = array();
3797
            $sql = "SELECT * FROM $table_posts
3798
                    WHERE
3799
                        c_id = $course_id AND
3800
                        post_date >'".Database::escape_string($_SESSION['last_forum_access'])."'"; // note: check the performance of this query.
3801
            $result = Database::query($sql);
3802
            while ($row = Database::fetch_array($result)) {
3803
                $whatsnew_post_info[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
3804
            }
3805
            $_SESSION['whatsnew_post_info'] = $whatsnew_post_info;
3806
        }
3807
    }
3808
}
3809
3810
/**
3811
 * With this function we find the number of posts and topics in a given forum.
3812
 *
3813
 * @todo consider to call this function only once and let it return an array where the key is the forum id and the value is an array with number_of_topics and number of post
3814
 * as key of this array and the value as a value. This could reduce the number of queries needed (especially when there are more forums)
3815
 * @todo consider merging both in one query.
3816
 *
3817
 * @author Patrick Cool <[email protected]>, Ghent University
3818
 * @version february 2006, dokeos 1.8
3819
 *
3820
 * @deprecated the counting mechanism is now inside the function get_forums
3821
 */
3822
function get_post_topics_of_forum($forum_id)
3823
{
3824
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3825
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3826
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
3827
3828
    $course_id = api_get_course_int_id();
3829
3830 View Code Duplication
    if (api_is_allowed_to_edit(null, true)) {
3831
        $sql = "SELECT count(*) as number_of_posts
3832
                FROM $table_posts posts, $table_threads threads, $table_item_property item_property
3833
                WHERE
3834
                posts.c_id = $course_id AND
3835
                item_property.c_id = $course_id AND
3836
                posts.forum_id='".Database::escape_string($forum_id)."'
3837
                AND posts.thread_id=threads.thread_id
3838
                AND item_property.ref=threads.thread_id
3839
                AND item_property.visibility<>2
3840
                AND item_property.tool='".TOOL_FORUM_THREAD."'
3841
                ";
3842
    } else {
3843
        $sql = "SELECT count(*) as number_of_posts
3844
                FROM $table_posts posts, $table_threads threads, $table_item_property item_property
3845
                WHERE
3846
                posts.c_id = $course_id AND
3847
                item_property.c_id = $course_id AND
3848
                posts.forum_id='".Database::escape_string($forum_id)."'
3849
                AND posts.thread_id=threads.thread_id
3850
                AND item_property.ref=threads.thread_id
3851
                AND item_property.visibility=1
3852
                AND posts.visible=1
3853
                AND item_property.tool='".TOOL_FORUM_THREAD."'
3854
                ";
3855
    }
3856
    $result = Database::query($sql);
3857
    $row = Database::fetch_array($result);
3858
    $number_of_posts = $row['number_of_posts'];
3859
3860
    // We could loop through the result array and count the number of different group_ids, but I have chosen to use a second sql statement.
3861 View Code Duplication
    if (api_is_allowed_to_edit(null, true)) {
3862
        $sql = "SELECT count(*) as number_of_topics
3863
                FROM $table_threads threads, $table_item_property item_property
3864
                WHERE
3865
                threads.c_id = $course_id AND
3866
                item_property.c_id = $course_id AND
3867
                threads.forum_id='".Database::escape_string($forum_id)."'
3868
                AND item_property.ref=threads.thread_id
3869
                AND item_property.visibility<>2
3870
                AND item_property.tool='".TOOL_FORUM_THREAD."'
3871
                ";
3872
    } else {
3873
        $sql = "SELECT count(*) as number_of_topics
3874
                FROM $table_threads threads, $table_item_property item_property
3875
                WHERE
3876
                threads.c_id = $course_id AND
3877
                item_property.c_id = $course_id AND
3878
                threads.forum_id='".Database::escape_string($forum_id)."'
3879
                AND item_property.ref=threads.thread_id
3880
                AND item_property.visibility=1
3881
                AND item_property.tool='".TOOL_FORUM_THREAD."'
3882
                ";
3883
    }
3884
    $result = Database::query($sql);
3885
    $row = Database::fetch_array($result);
3886
    $number_of_topics = $row['number_of_topics'];
3887
    if ($number_of_topics == '') {
3888
        $number_of_topics = 0; // Due to the nature of the group by this can result in an empty string.
3889
    }
3890
3891
    $return = array(
3892
        'number_of_topics' => $number_of_topics,
3893
        'number_of_posts' => $number_of_posts,
3894
    );
3895
3896
    return $return;
3897
}
3898
3899
/**
3900
 * This function approves a post = change
3901
 *
3902
 * @param int $post_id the id of the post that will be deleted
3903
 * @param string $action make the post visible or invisible
3904
 * @return string language variable
3905
 *
3906
 * @author Patrick Cool <[email protected]>, Ghent University
3907
 * @version february 2006, dokeos 1.8
3908
 */
3909
function approve_post($post_id, $action)
3910
{
3911
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3912
    $course_id = api_get_course_int_id();
3913
3914
    if ($action == 'invisible') {
3915
        $visibility_value = 0;
3916
    }
3917
3918
    if ($action == 'visible') {
3919
        $visibility_value = 1;
3920
        handle_mail_cue('post', $post_id);
3921
    }
3922
3923
    $sql = "UPDATE $table_posts SET
3924
            visible='".Database::escape_string($visibility_value)."'
3925
            WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
3926
    $return = Database::query($sql);
3927
3928
    if ($return) {
3929
        return 'PostVisibilityChanged';
3930
    }
3931
}
3932
3933
/**
3934
 * This function retrieves all the unapproved messages for a given forum
3935
 * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
3936
 *
3937
 * @param $forum_id the forum where we want to know the unapproved messages of
3938
 * @return array returns
3939
 *
3940
 * @author Patrick Cool <[email protected]>, Ghent University
3941
 * @version february 2006, dokeos 1.8
3942
 */
3943
function get_unaproved_messages($forum_id)
3944
{
3945
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3946
    $course_id = api_get_course_int_id();
3947
3948
    $return_array = array();
3949
    $sql = "SELECT DISTINCT thread_id FROM $table_posts
3950
            WHERE c_id = $course_id AND forum_id='".Database::escape_string($forum_id)."' AND visible='0'";
3951
    $result = Database::query($sql);
3952
    while ($row = Database::fetch_array($result)) {
3953
        $return_array[] = $row['thread_id'];
3954
    }
3955
3956
    return $return_array;
3957
}
3958
3959
/**
3960
 * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
3961
 * was added to a given thread.
3962
 *
3963
 * @param array reply information
3964
 * @return void
3965
 *
3966
 * @author Patrick Cool <[email protected]>, Ghent University
3967
 * @version february 2006, dokeos 1.8
3968
 */
3969
function send_notification_mails($thread_id, $reply_info)
3970
{
3971
    $table = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
3972
3973
    // First we need to check if
3974
    // 1. the forum category is visible
3975
    // 2. the forum is visible
3976
    // 3. the thread is visible
3977
    // 4. the reply is visible (=when there is)
3978
    $current_thread = get_thread_information($thread_id);
3979
    $current_forum = get_forum_information($current_thread['forum_id']);
3980
3981
    $current_forum_category = null;
3982
    if (isset($current_forum['forum_category'])) {
3983
        $current_forum_category = get_forumcategory_information(
3984
            $current_forum['forum_category']
3985
        );
3986
    }
3987
3988
    if ($current_thread['visibility'] == '1' &&
3989
        $current_forum['visibility'] == '1' &&
3990
        ($current_forum_category && $current_forum_category['visibility'] == '1') &&
3991
        $current_forum['approval_direct_post'] != '1'
3992
    ) {
3993
        $send_mails = true;
3994
    } else {
3995
        $send_mails = false;
3996
    }
3997
3998
    // The forum category, the forum, the thread and the reply are visible to the user
3999
    if ($send_mails) {
4000
        if (isset($current_thread['forum_id'])) {
4001
            send_notifications($current_thread['forum_id'], $thread_id);
4002
        }
4003
    } else {
4004
        $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
4005
        if (isset($current_forum['forum_id'])) {
4006
            $sql = "SELECT * FROM $table_notification
4007
                    WHERE
4008
                        c_id = ".api_get_course_int_id()." AND
4009
                        (
4010
                            forum_id = '".intval($current_forum['forum_id'])."' OR
4011
                            thread_id = '".intval($thread_id)."'
4012
                        ) ";
4013
4014
            $result = Database::query($sql);
4015
            $user_id = api_get_user_id();
4016
            while ($row = Database::fetch_array($result)) {
4017
                $sql = "INSERT INTO $table (c_id, thread_id, post_id, user_id)
4018
                        VALUES (".api_get_course_int_id().", '".intval($thread_id)."', '".intval($reply_info['new_post_id'])."', '$user_id' )";
4019
                Database::query($sql);
4020
            }
4021
        }
4022
    }
4023
}
4024
4025
/**
4026
 * This function is called whenever something is made visible because there might
4027
 * be new posts and the user might have indicated that (s)he wanted to be
4028
 * informed about the new posts by mail.
4029
 *
4030
 * @param string  Content type (post, thread, forum, forum_category)
4031
 * @param int     Item DB ID
4032
 * @param string $content
4033
 * @param integer $id
4034
 * @return string language variable
4035
 * @author Patrick Cool <[email protected]>, Ghent University
4036
 * @version february 2006, dokeos 1.8
4037
 */
4038
function handle_mail_cue($content, $id)
4039
{
4040
    $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
4041
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4042
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4043
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4044
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
4045
4046
    $course_id = api_get_course_int_id();
4047
4048
    /* If the post is made visible we only have to send mails to the people
4049
     who indicated that they wanted to be informed for that thread.*/
4050
    if ($content == 'post') {
4051
        // Getting the information about the post (need the thread_id).
4052
        $post_info = get_post_information($id);
4053
        $thread_id = intval($post_info['thread_id']);
4054
4055
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4056
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4057
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4058
                WHERE
4059
                    posts.c_id = $course_id AND
4060
                    mailcue.c_id = $course_id AND
4061
                    posts.thread_id='$thread_id'
4062
                    AND posts.post_notification='1'
4063
                    AND mailcue.thread_id='$thread_id'
4064
                    AND users.user_id=posts.poster_id
4065
                    AND users.active=1
4066
                GROUP BY users.email";
4067
4068
        $result = Database::query($sql);
4069
        while ($row = Database::fetch_array($result)) {
4070
            send_mail($row, get_thread_information($post_info['thread_id']));
4071
        }
4072
    } elseif ($content == 'thread') {
4073
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4074
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4075
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4076
                WHERE
4077
                    posts.c_id = $course_id AND
4078
                    mailcue.c_id = $course_id AND
4079
                    posts.thread_id = ".intval($id)."
4080
                    AND posts.post_notification='1'
4081
                    AND mailcue.thread_id = ".intval($id)."
4082
                    AND users.user_id=posts.poster_id
4083
                    AND users.active=1
4084
                GROUP BY users.email";
4085
        $result = Database::query($sql);
4086
        while ($row = Database::fetch_array($result)) {
4087
            send_mail($row, get_thread_information($id));
4088
        }
4089
4090
        // Deleting the relevant entries from the mailcue.
4091
        $sql = "DELETE FROM $table_mailcue
4092
                WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
4093
        Database::query($sql);
4094
    } elseif ($content == 'forum') {
4095
        $sql = "SELECT thread_id FROM $table_threads
4096
                WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
4097
        $result = Database::query($sql);
4098
        while ($row = Database::fetch_array($result)) {
4099
            handle_mail_cue('thread', $row['thread_id']);
4100
        }
4101
    } elseif ($content == 'forum_category') {
4102
        $sql = "SELECT forum_id FROM $table_forums
4103
                WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
4104
        $result = Database::query($sql);
4105
        while ($row = Database::fetch_array($result)) {
4106
            handle_mail_cue('forum', $row['forum_id']);
4107
        }
4108
    } else {
4109
        return get_lang('Error');
4110
    }
4111
}
4112
4113
/**
4114
 * This function sends the mails for the mail notification
4115
 *
4116
 * @param array
4117
 * @param array
4118
 * @return void
4119
 *
4120
 * @author Patrick Cool <[email protected]>, Ghent University
4121
 * @version february 2006, dokeos 1.8
4122
 */
4123
function send_mail($user_info = array(), $thread_information = array())
4124
{
4125
    $_course = api_get_course_info();
4126
    $user_id = api_get_user_id();
4127
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
4128 View Code Duplication
    if (isset($thread_information) && is_array($thread_information)) {
4129
        $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$thread_information['forum_id'].'&thread='.$thread_information['thread_id'];
4130
    }
4131
    $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
4132
    $email_body .= get_lang('NewForumPost')."\n";
4133
    $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
4134
    $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
4135
    $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
4136
4137
    if ($user_info['user_id'] <> $user_id) {
4138
        MessageManager::send_message($user_info['user_id'], $subject, $email_body, [], [], null, null, null, null, $user_id);
4139
    }
4140
}
4141
4142
/**
4143
 * This function displays the form for moving a thread to a different (already existing) forum
4144
 * @return void HTML
4145
 *
4146
 * @author Patrick Cool <[email protected]>, Ghent University
4147
 * @version february 2006, dokeos 1.8
4148
 */
4149
function move_thread_form()
4150
{
4151
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4152
    $form = new FormValidator(
4153
        'movepost',
4154
        'post',
4155
        api_get_self().'?forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
4156
    );
4157
    // The header for the form
4158
    $form->addElement('header', get_lang('MoveThread'));
4159
    // Invisible form: the thread_id
4160
    $form->addElement('hidden', 'thread_id', intval($_GET['thread']));
4161
    // the fora
4162
    $forum_categories = get_forum_categories();
4163
    $forums = get_forums();
4164
4165
    $htmlcontent = '<div class="row">
4166
        <div class="label">
4167
            <span class="form_required">*</span>'.get_lang('MoveTo').'
4168
        </div>
4169
        <div class="formw">';
4170
    $htmlcontent .= '<select name="forum">';
4171
    foreach ($forum_categories as $key => $category) {
4172
        $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
4173
        foreach ($forums as $key => $forum) {
4174
            if (isset($forum['forum_category'])) {
4175
                if ($forum['forum_category'] == $category['cat_id']) {
4176
                    $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
4177
                }
4178
            }
4179
        }
4180
        $htmlcontent .= '</optgroup>';
4181
    }
4182
    $htmlcontent .= "</select>";
4183
    $htmlcontent .= '   </div>
4184
                    </div>';
4185
4186
    $form->addElement('html', $htmlcontent);
4187
4188
    // The OK button
4189
    $form->addButtonSave(get_lang('MoveThread'), 'SubmitForum');
4190
4191
    // Validation or display
4192
    if ($form->validate()) {
4193
        $values = $form->exportValues();
4194
        if (isset($_POST['forum'])) {
4195
            store_move_thread($values);
4196
        }
4197
    } else {
4198
        $form->display();
4199
    }
4200
}
4201
4202
/**
4203
 * This function displays the form for moving a post message to a different (already existing) or a new thread.
4204
 * @return void HTML
4205
 *
4206
 * @author Patrick Cool <[email protected]>, Ghent University
4207
 * @version february 2006, dokeos 1.8
4208
 */
4209
function move_post_form()
4210
{
4211
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4212
    // initiate the object
4213
    $form = new FormValidator('movepost', 'post', api_get_self().'?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&thread='.Security::remove_XSS($_GET['thread']).'&gradebook='.$gradebook.'&post='.Security::remove_XSS($_GET['post']).'&action='.Security::remove_XSS($_GET['action']).'&post='.Security::remove_XSS($_GET['post']));
4214
    // The header for the form
4215
    $form->addElement('header', '', get_lang('MovePost'));
4216
4217
    // Invisible form: the post_id
4218
    $form->addElement('hidden', 'post_id', intval($_GET['post']));
4219
4220
    // Dropdown list: Threads of this forum
4221
    $threads = get_threads($_GET['forum']);
4222
    //my_print_r($threads);
4223
    $threads_list[0] = get_lang('ANewThread');
4224
    foreach ($threads as $key => $value) {
4225
        $threads_list[$value['thread_id']] = $value['thread_title'];
4226
    }
4227
    $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
4228
    $form->applyFilter('thread', 'html_filter');
4229
4230
    // The OK button
4231
    $form->addButtonSave(get_lang('MovePost'), 'submit');
4232
4233
    // Setting the rules
4234
    $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
4235
4236
    // Validation or display
4237
    if ($form->validate()) {
4238
        $values = $form->exportValues();
4239
        store_move_post($values);
4240
    } else {
4241
        $form->display();
4242
    }
4243
}
4244
4245
/**
4246
 *
4247
 * @param array
4248
 * @return string HTML language variable
4249
 *
4250
 * @author Patrick Cool <[email protected]>, Ghent University
4251
 * @version february 2006, dokeos 1.8
4252
 */
4253
function store_move_post($values)
4254
{
4255
    $_course = api_get_course_info();
4256
    $course_id = api_get_course_int_id();
4257
4258
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4259
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4260
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4261
4262
    if ($values['thread'] == '0') {
4263
        $current_post = get_post_information($values['post_id']);
4264
4265
        // Storing a new thread.
4266
        $params = [
4267
            'c_id' => $course_id,
4268
            'thread_title' => $current_post['post_title'],
4269
            'forum_id' => $current_post['forum_id'],
4270
            'thread_poster_id' => $current_post['poster_id'],
4271
            'thread_poster_name' => $current_post['poster_name'],
4272
            'thread_last_post' => $values['post_id'],
4273
            'thread_date' => $current_post['post_date'],
4274
        ];
4275
4276
        $new_thread_id = Database::insert($table_threads, $params);
4277
4278
        api_item_property_update(
4279
            $_course,
4280
            TOOL_FORUM_THREAD,
4281
            $new_thread_id,
4282
            'visible',
4283
            $current_post['poster_id']
4284
        );
4285
4286
        // Moving the post to the newly created thread.
4287
        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
4288
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4289
        Database::query($sql);
4290
4291
        // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
4292
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4293
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4294
        Database::query($sql);
4295
4296
        // Updating updating the number of threads in the forum.
4297
        $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
4298
                WHERE c_id = $course_id AND forum_id='".intval($current_post['forum_id'])."'";
4299
        Database::query($sql);
4300
4301
        // Resetting the last post of the old thread and decreasing the number of replies and the thread.
4302
        $sql = "SELECT * FROM $table_posts
4303
                WHERE c_id = $course_id AND thread_id='".intval($current_post['thread_id'])."'
4304
                ORDER BY post_id DESC";
4305
        $result = Database::query($sql);
4306
        $row = Database::fetch_array($result);
4307
        $sql = "UPDATE $table_threads SET
4308
                    thread_last_post='".$row['post_id']."',
4309
                    thread_replies=thread_replies-1
4310
                WHERE
4311
                    c_id = $course_id AND
4312
                    thread_id='".intval($current_post['thread_id'])."'";
4313
        Database::query($sql);
4314
    } else {
4315
        // Moving to the chosen thread.
4316
4317
        $sql = "SELECT thread_id FROM ".$table_posts."
4318
                WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
4319
        $result = Database::query($sql);
4320
        $row = Database::fetch_array($result);
4321
4322
        $original_thread_id = $row['thread_id'];
4323
4324
        $sql = "SELECT thread_last_post FROM ".$table_threads."
4325
                WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4326
4327
        $result = Database::query($sql);
4328
        $row = Database::fetch_array($result);
4329
        $thread_is_last_post = $row['thread_last_post'];
4330
        // If is this thread, update the thread_last_post with the last one.
4331
4332
        if ($thread_is_last_post == $values['post_id']) {
4333
            $sql = "SELECT post_id FROM ".$table_posts."
4334
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."'
4335
                    ORDER BY post_date DESC LIMIT 1";
4336
            $result = Database::query($sql);
4337
4338
            $row = Database::fetch_array($result);
4339
            $thread_new_last_post = $row['post_id'];
4340
4341
            $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."'
4342
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4343
            Database::query($sql);
4344
        }
4345
4346
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
4347
                WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
4348
        Database::query($sql);
4349
4350
        // moving to the chosen thread
4351
        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
4352
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4353
        Database::query($sql);
4354
4355
        // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
4356
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4357
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4358
        Database::query($sql);
4359
4360
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
4361
                WHERE c_id = $course_id AND thread_id='".intval($_POST['thread'])."'";
4362
        Database::query($sql);
4363
    }
4364
4365
    return get_lang('ThreadMoved');
4366
}
4367
4368
/**
4369
 *
4370
 * @param array
4371
 * @return string HTML language variable
4372
 *
4373
 * @author Patrick Cool <[email protected]>, Ghent University
4374
 * @version february 2006, dokeos 1.8
4375
 */
4376
function store_move_thread($values)
4377
{
4378
    $table_threads = Database:: get_course_table(TABLE_FORUM_THREAD);
4379
    $table_posts = Database:: get_course_table(TABLE_FORUM_POST);
4380
4381
    $courseId = api_get_course_int_id();
4382
    $sessionId = api_get_session_id();
4383
4384
    $forumId = intval($_POST['forum']);
4385
    $threadId = intval($_POST['thread_id']);
4386
    $forumInfo = get_forums($forumId);
4387
4388
    // Change the thread table: Setting the forum_id to the new forum.
4389
    $sql = "UPDATE $table_threads SET forum_id = $forumId
4390
            WHERE c_id = $courseId AND thread_id = $threadId";
4391
    Database::query($sql);
4392
4393
    // Changing all the posts of the thread: setting the forum_id to the new forum.
4394
    $sql = "UPDATE $table_posts SET forum_id = $forumId
4395
            WHERE c_id = $courseId AND thread_id= $threadId";
4396
    Database::query($sql);
4397
    // Fix group id, if forum is moved to a different group
4398
    if (!empty($forumInfo['to_group_id'])) {
4399
        $groupId = $forumInfo['to_group_id'];
4400
        $item = api_get_item_property_info($courseId, TABLE_FORUM_THREAD, $threadId, $sessionId, $groupId);
4401
        $table = Database:: get_course_table(TABLE_ITEM_PROPERTY);
4402
        $sessionCondition = api_get_session_condition($sessionId);
4403
4404
        if (!empty($item)) {
4405
            if ($item['to_group_id'] != $groupId) {
4406
                $sql = "UPDATE $table
4407
                    SET to_group_id = $groupId
4408
                    WHERE
4409
                      tool = '".TABLE_FORUM_THREAD."' AND
4410
                      c_id = $courseId AND
4411
                      ref = ".$item['ref']."
4412
                      $sessionCondition
4413
                ";
4414
                Database::query($sql);
4415
            }
4416
        } else {
4417
            $sql = "UPDATE $table
4418
                    SET to_group_id = $groupId
4419
                    WHERE
4420
                      tool = '".TABLE_FORUM_THREAD."' AND
4421
                      c_id = $courseId AND
4422
                      ref = ".$threadId."
4423
                      $sessionCondition
4424
            ";
4425
            Database::query($sql);
4426
        }
4427
    }
4428
4429
    return get_lang('ThreadMoved');
4430
}
4431
4432
/**
4433
 * Prepares a string for displaying by highlighting the search results inside, if any.
4434
 * @param string $input    The input string.
4435
 * @return string          The same string with highlighted hits inside.
4436
 *
4437
 * @author Patrick Cool <[email protected]>, Ghent University, February 2006 - the initial version.
4438
 * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
4439
 */
4440
function prepare4display($input)
4441
{
4442
    static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
4443
    static $search;
4444
4445
    if (!isset($search)) {
4446
        if (isset($_POST['search_term'])) {
4447
            $search = $_POST['search_term']; // No html at all.
4448
        } elseif (isset($_GET['search'])) {
4449
            $search = $_GET['search'];
4450
        } else {
4451
            $search = '';
4452
        }
4453
    }
4454
4455
    if (!empty($search)) {
4456
        if (strstr($search, '+')) {
4457
            $search_terms = explode('+', $search);
4458
        } else {
4459
            $search_terms[] = trim($search);
4460
        }
4461
        $counter = 0;
4462
        foreach ($search_terms as $key => $search_term) {
4463
            $input = api_preg_replace('/'.preg_quote(trim($search_term), '/').'/i', '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>', $input);
4464
            $counter++;
4465
        }
4466
    }
4467
4468
    // TODO: Security should be implemented outside this function.
4469
    // Change this to COURSEMANAGERLOWSECURITY or COURSEMANAGER to lower filtering and allow more styles (see comments of Security::remove_XSS() method to learn about other levels).
4470
4471
    return Security::remove_XSS($input, STUDENT, true);
4472
}
4473
4474
/**
4475
 * Display the search form for the forum and display the search results
4476
 * @return void display an HTML search results
4477
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4478
 * @version march 2008, dokeos 1.8.5
4479
 */
4480
function forum_search()
4481
{
4482
    // Initialize the object.
4483
    $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?'.api_get_cidreq());
4484
4485
    // Setting the form elements.
4486
    $form->addElement('header', '', get_lang('ForumSearch'));
4487
    $form->addElement('text', 'search_term', get_lang('SearchTerm'), array('autofocus'));
4488
    $form->applyFilter('search_term', 'html_filter');
4489
    $form->addElement('static', 'search_information', '', get_lang('ForumSearchInformation'));
4490
    $form->addButtonSearch(get_lang('Search'));
4491
4492
    // Setting the rules.
4493
    $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
4494
    $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
4495
4496
    // Validation or display.
4497
    if ($form->validate()) {
4498
        $values = $form->exportValues();
4499
        $form->setDefaults($values);
4500
        $form->display();
4501
        // Display the search results.
4502
        display_forum_search_results(stripslashes($values['search_term']));
4503
    } else {
4504
        $form->display();
4505
    }
4506
}
4507
4508
/**
4509
 * Display the search results
4510
 * @param string
4511
 * @param string $search_term
4512
 * @return void display the results
4513
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4514
 * @version march 2008, dokeos 1.8.5
4515
 */
4516
function display_forum_search_results($search_term)
4517
{
4518
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4519
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4520
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
4521
    $session_id = api_get_session_id();
4522
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4523
    $course_id = api_get_course_int_id();
4524
4525
    // Defining the search strings as an array.
4526
    if (strstr($search_term, '+')) {
4527
        $search_terms = explode('+', $search_term);
4528
    } else {
4529
        $search_terms[] = $search_term;
4530
    }
4531
4532
    // Search restriction.
4533
    foreach ($search_terms as $value) {
4534
        $search_restriction[] = "
4535
        (posts.post_title LIKE '%".Database::escape_string(trim($value))."%'
4536
        OR posts.post_text LIKE '%".Database::escape_string(trim($value))."%')";
4537
    }
4538
4539
    $sql = "SELECT posts.*
4540
            FROM $table_posts posts, $table_threads threads, $table_item_property item_property
4541
            WHERE
4542
                posts.c_id = $course_id
4543
                AND item_property.c_id = $course_id
4544
                AND posts.thread_id = threads.thread_id
4545
                AND item_property.ref = threads.thread_id
4546
                AND item_property.visibility = 1
4547
                AND item_property.session_id = $session_id
4548
                AND posts.visible = 1
4549
                AND item_property.tool = '".TOOL_FORUM_THREAD."'
4550
                AND ".implode(' AND ', $search_restriction)."
4551
                GROUP BY posts.post_id";
4552
4553
    // Getting all the information of the forum categories.
4554
    $forum_categories_list = get_forum_categories();
4555
4556
    // Getting all the information of the forums.
4557
    $forum_list = get_forums();
4558
4559
    $result = Database::query($sql);
4560
    $search_results = [];
4561
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4562
        $display_result = false;
4563
        /*
4564
          We only show it when
4565
          1. forum category is visible
4566
          2. forum is visible
4567
          3. thread is visible (to do)
4568
          4. post is visible
4569
         */
4570
        if (!api_is_allowed_to_edit(null, true)) {
4571
            if ($forum_categories_list[$forum_list[$row['forum_id']]['forum_category']]['visibility'] == '1' AND
4572
                $forum_list[$row['forum_id']]['visibility'] == '1' AND $row['visible'] == '1'
4573
            ) {
4574
                $display_result = true;
4575
            }
4576
        } else {
4577
            $display_result = true;
4578
        }
4579
4580
        if ($display_result) {
4581
            $search_results_item = '<li><a href="viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.$forum_list[$row['forum_id']]['forum_category'].'&search='.urlencode($search_term).'">'.
4582
                prepare4display($forum_categories_list[$row['forum_id']['forum_category']]['cat_title']).'</a> &gt; ';
4583
            $search_results_item .= '<a href="viewforum.php?'.api_get_cidreq().'&forum='.$row['forum_id'].'&search='.urlencode($search_term).'">'.
4584
                prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
4585
            //$search_results_item .= '<a href="">THREAD</a> &gt; ';
4586
            $search_results_item .= '<a href="viewthread.php?'.api_get_cidreq().'&forum='.$row['forum_id'].'&gradebook='.$gradebook.'&thread='.$row['thread_id'].'&search='.urlencode($search_term).'">'.
4587
                prepare4display($row['post_title']).'</a>';
4588
            $search_results_item .= '<br />';
4589
            if (api_strlen($row['post_title']) > 200) {
4590
                $search_results_item .= prepare4display(api_substr(strip_tags($row['post_title']), 0, 200)).'...';
0 ignored issues
show
Security Bug introduced by
It seems like api_substr(strip_tags($r...'post_title']), 0, 200) targeting api_substr() can also be of type false; however, prepare4display() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
4591
            } else {
4592
                $search_results_item .= prepare4display($row['post_title']);
4593
            }
4594
            $search_results_item .= '</li>';
4595
            $search_results[] = $search_results_item;
4596
        }
4597
    }
4598
    echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
4599
    echo '<ol>';
4600
    if ($search_results) {
4601
        echo implode($search_results);
4602
    }
4603
    echo '</ol>';
4604
}
4605
4606
/**
4607
 * Return the link to the forum search page
4608
 *
4609
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4610
 * @version April 2008, dokeos 1.8.5
4611
 */
4612
function search_link()
4613
{
4614
    $return = '';
4615
    $origin = api_get_origin();
4616
    if ($origin != 'learnpath') {
4617
        $return = '<a href="forumsearch.php?'.api_get_cidreq().'&action=search"> ';
4618
        $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
4619
4620
        if (!empty($_GET['search'])) {
4621
            $return .= ': '.Security::remove_XSS($_GET['search']).' ';
4622
            $url = api_get_self().'?';
4623
            $url_parameter = array();
4624
            foreach ($_GET as $key => $value) {
4625
                if ($key != 'search') {
4626
                    $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
4627
                }
4628
            }
4629
            $url = $url.implode('&', $url_parameter);
4630
            $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
4631
        }
4632
    }
4633
4634
    return $return;
4635
}
4636
4637
/**
4638
 * This function adds an attachment file into a forum
4639
 * @param string $file_comment  a comment about file
4640
 * @param int $last_id from forum_post table
4641
 * @return false|null
4642
 */
4643
function add_forum_attachment_file($file_comment, $last_id)
4644
{
4645
    $_course = api_get_course_info();
4646
    $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4647
4648
    if (!isset($_FILES['user_upload'])) {
4649
        return false;
4650
    }
4651
4652
    $fileCount = count($_FILES['user_upload']['name']);
4653
4654
    $filesData = [];
4655
4656 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4657
        $filesData[] = $_FILES['user_upload'];
4658
    } else {
4659
        $fileKeys = array_keys($_FILES['user_upload']);
4660
4661
        for ($i = 0; $i < $fileCount; $i++) {
4662
            foreach ($fileKeys as $key) {
4663
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4664
            }
4665
        }
4666
    }
4667
4668
    foreach ($filesData as $attachment) {
4669
        if (empty($attachment['name'])) {
4670
            continue;
4671
        }
4672
4673
        $upload_ok = process_uploaded_file($attachment);
4674
4675
        if (!$upload_ok) {
4676
            continue;
4677
        }
4678
4679
        $course_dir = $_course['path'] . '/upload/forum';
4680
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4681
        $updir = $sys_course_path . $course_dir;
4682
4683
        // Try to add an extension to the file if it hasn't one.
4684
        $new_file_name = add_ext_on_mime(
4685
            stripslashes($attachment['name']),
4686
            $attachment['type']
4687
        );
4688
        // User's file name
4689
        $file_name = $attachment['name'];
4690
4691
        if (!filter_extension($new_file_name)) {
4692
            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
4693
4694
            return;
4695
        }
4696
4697
        $new_file_name = uniqid('');
4698
        $new_path = $updir . '/' . $new_file_name;
4699
        $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4700
        $safe_file_comment = Database::escape_string($file_comment);
4701
        $safe_file_name = Database::escape_string($file_name);
4702
        $safe_new_file_name = Database::escape_string($new_file_name);
4703
        $last_id = intval($last_id);
4704
        // Storing the attachments if any.
4705
        if (!$result) {
4706
            return;
4707
        }
4708
4709
        $last_id_file = Database::insert(
4710
            $agenda_forum_attachment,
4711
            [
4712
                'c_id' => api_get_course_int_id(),
4713
                'filename' => $safe_file_name,
4714
                'comment' => $safe_file_comment,
4715
                'path' => $safe_new_file_name,
4716
                'post_id' => $last_id,
4717
                'size' => intval($attachment['size']),
4718
            ]
4719
        );
4720
4721
        api_item_property_update(
4722
            $_course,
4723
            TOOL_FORUM_ATTACH,
4724
            $last_id_file,
4725
            'ForumAttachmentAdded',
4726
            api_get_user_id()
4727
        );
4728
    }
4729
}
4730
4731
/**
4732
 * This function edits an attachment file into a forum
4733
 * @param string $file_comment  a comment about file
4734
 * @param int $post_id
4735
 * @param int $id_attach attachment file Id
4736
 * @return void
4737
 */
4738
function edit_forum_attachment_file($file_comment, $post_id, $id_attach)
4739
{
4740
    $_course = api_get_course_info();
4741
    $table_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4742
    $course_id = api_get_course_int_id();
4743
4744
    $fileCount = count($_FILES['user_upload']['name']);
4745
4746
    $filesData = [];
4747
4748 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4749
        $filesData[] = $_FILES['user_upload'];
4750
    } else {
4751
        $fileKeys = array_keys($_FILES['user_upload']);
4752
4753
        for ($i = 0; $i < $fileCount; $i++) {
4754
            foreach ($fileKeys as $key) {
4755
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4756
            }
4757
        }
4758
    }
4759
4760
    foreach ($filesData as $attachment) {
4761
        if (empty($attachment['name'])) {
4762
            continue;
4763
        }
4764
4765
        $upload_ok = process_uploaded_file($attachment);
4766
4767
        if (!$upload_ok) {
4768
            continue;
4769
        }
4770
4771
        $course_dir = $_course['path'].'/upload/forum';
4772
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4773
        $updir = $sys_course_path.$course_dir;
4774
4775
        // Try to add an extension to the file if it hasn't one.
4776
        $new_file_name = add_ext_on_mime(stripslashes($attachment['name']), $attachment['type']);
4777
        // User's file name
4778
        $file_name = $attachment['name'];
4779
4780
        if (!filter_extension($new_file_name)) {
4781
            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
4782
        } else {
4783
            $new_file_name = uniqid('');
4784
            $new_path = $updir.'/'.$new_file_name;
4785
            $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4786
            $safe_file_comment = Database::escape_string($file_comment);
4787
            $safe_file_name = Database::escape_string($file_name);
4788
            $safe_new_file_name = Database::escape_string($new_file_name);
4789
            $safe_post_id = (int) $post_id;
4790
            $safe_id_attach = (int) $id_attach;
4791
            // Storing the attachments if any.
4792 View Code Duplication
            if ($result) {
4793
                $sql = "UPDATE $table_forum_attachment SET filename = '$safe_file_name', comment = '$safe_file_comment', path = '$safe_new_file_name', post_id = '$safe_post_id', size ='".$attachment['size']."'
4794
                       WHERE c_id = $course_id AND id = '$safe_id_attach'";
4795
                Database::query($sql);
4796
                api_item_property_update($_course, TOOL_FORUM_ATTACH, $safe_id_attach, 'ForumAttachmentUpdated', api_get_user_id());
4797
            }
4798
        }
4799
    }
4800
}
4801
4802
/**
4803
 * Show a list with all the attachments according to the post's id
4804
 * @param int $post_id
4805
 * @return array with the post info
4806
 * @author Julio Montoya Dokeos
4807
 * @version avril 2008, dokeos 1.8.5
4808
 */
4809
function get_attachment($post_id)
4810
{
4811
    $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4812
    $course_id = api_get_course_int_id();
4813
    $row = array();
4814
    $post_id = intval($post_id);
4815
    $sql = "SELECT iid, path, filename,comment FROM $forum_table_attachment
4816
            WHERE c_id = $course_id AND post_id = $post_id";
4817
    $result = Database::query($sql);
4818
    if (Database::num_rows($result) != 0) {
4819
        $row = Database::fetch_array($result);
4820
    }
4821
4822
    return $row;
4823
}
4824
4825
function getAllAttachment($postId)
4826
{
4827
    $forumAttachmentTable = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4828
    $courseId = api_get_course_int_id();
4829
    $postId = intval($postId);
4830
    $columns = array('iid', 'path', 'filename', 'comment');
4831
    $conditions = array(
4832
        'where' => array(
4833
            'c_id = ? AND post_id = ?' => array($courseId, $postId),
4834
        ),
4835
    );
4836
    $array = Database::select(
4837
        $columns,
4838
        $forumAttachmentTable,
4839
        $conditions,
4840
        'all',
4841
        'ASSOC'
4842
    );
4843
4844
    return $array;
4845
}
4846
4847
/**
4848
 * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
4849
 * @param post id
4850
 * @param int $id_attach
4851
 * @param bool $display to show or not result message
4852
 * @return integer
4853
 * @author Julio Montoya Dokeos
4854
 * @version october 2014, chamilo 1.9.8
4855
 */
4856
function delete_attachment($post_id, $id_attach = 0, $display = true)
4857
{
4858
    $_course = api_get_course_info();
4859
4860
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4861
    $course_id = api_get_course_int_id();
4862
4863
    $cond = (!empty($id_attach)) ? " iid = " . (int) $id_attach . "" : " post_id = " . (int) $post_id . "";
4864
    $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
4865
    $res = Database::query($sql);
4866
    $row = Database::fetch_array($res);
4867
4868
    $course_dir = $_course['path'] . '/upload/forum';
4869
    $sys_course_path = api_get_path(SYS_COURSE_PATH);
4870
    $updir = $sys_course_path . $course_dir;
4871
    $my_path = isset($row['path']) ? $row['path'] : null;
4872
    $file = $updir . '/' . $my_path;
4873
    if (Security::check_abs_path($file, $updir)) {
4874
        @unlink($file);
4875
    }
4876
4877
    // Delete from forum_attachment table.
4878
    $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
4879
    $result = Database::query($sql);
4880
    if ($result !== false) {
4881
        $affectedRows = Database::affected_rows($result);
4882
    } else {
4883
        $affectedRows = 0;
4884
    }
4885
4886
    // Update item_property.
4887
    api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
4888
4889
    if (!empty($result) && !empty($id_attach) && $display) {
4890
        $message = get_lang('AttachmentFileDeleteSuccess');
4891
        Display::display_confirmation_message($message);
4892
    }
4893
4894
    return $affectedRows;
4895
}
4896
4897
/**
4898
 * This function gets all the forum information of the all the forum of the group
4899
 *
4900
 * @param integer $group_id the id of the group we need the fora of (see forum.forum_of_group)
4901
 * @return array
4902
 *
4903
 * @todo this is basically the same code as the get_forums function. Consider merging the two.
4904
 */
4905
function get_forums_of_group($group_id)
4906
{
4907
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4908
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4909
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4910
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
4911
    $course_id = api_get_course_int_id();
4912
4913
    // Student
4914
    // Select all the forum information of all forums (that are visible to students).
4915
4916
    $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties
4917
            WHERE
4918
                forum.forum_of_group = '".Database::escape_string($group_id)."' AND
4919
                forum.c_id = $course_id AND
4920
                item_properties.c_id = $course_id AND
4921
                forum.forum_id = item_properties.ref AND
4922
                item_properties.visibility = 1 AND
4923
                item_properties.tool = '".TOOL_FORUM."'
4924
            ORDER BY forum.forum_order ASC";
4925
    // Select the number of threads of the forums (only the threads that are visible).
4926
    $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
4927
            FROM $table_threads threads, ".$table_item_property." item_properties
4928
            WHERE
4929
                threads.thread_id = item_properties.ref AND
4930
                threads.c_id = $course_id AND
4931
                item_properties.c_id = $course_id AND
4932
                item_properties.visibility = 1 AND
4933
                item_properties.tool='".TOOL_FORUM_THREAD."'
4934
            GROUP BY threads.forum_id";
4935
    // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
4936
    $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id
4937
            FROM $table_posts posts, $table_threads threads, ".$table_item_property." item_properties
4938
            WHERE posts.visible=1 AND
4939
                posts.c_id = $course_id AND
4940
                item_properties.c_id = $course_id AND
4941
                threads.c_id = $course_id
4942
                AND posts.thread_id=threads.thread_id
4943
                AND threads.thread_id=item_properties.ref
4944
                AND item_properties.visibility = 1
4945
                AND item_properties.tool='".TOOL_FORUM_THREAD."'
4946
            GROUP BY threads.forum_id";
4947
4948
    // Course Admin
4949
    if (api_is_allowed_to_edit()) {
4950
        // Select all the forum information of all forums (that are not deleted).
4951
        $sql = "SELECT *
4952
                FROM ".$table_forums." forum , ".$table_item_property." item_properties
4953
                WHERE
4954
                    forum.forum_of_group = '".Database::escape_string($group_id)."' AND
4955
                    forum.c_id = $course_id AND
4956
                    item_properties.c_id = $course_id AND
4957
                    forum.forum_id = item_properties.ref AND
4958
                    item_properties.visibility <> 2 AND
4959
                    item_properties.tool = '".TOOL_FORUM."'
4960
                ORDER BY forum_order ASC";
4961
4962
        // Select the number of threads of the forums (only the threads that are not deleted).
4963
        $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
4964
                 FROM $table_threads threads, ".$table_item_property." item_properties
4965
                 WHERE
4966
                    threads.thread_id=item_properties.ref AND
4967
                    threads.c_id = $course_id AND
4968
                    item_properties.c_id = $course_id AND
4969
                    item_properties.visibility <> 2 AND
4970
                    item_properties.tool='".TOOL_FORUM_THREAD."'
4971
                GROUP BY threads.forum_id";
4972
        // Select the number of posts of the forum.
4973
        $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id
4974
                FROM $table_posts
4975
                WHERE c_id = $course_id GROUP BY forum_id";
4976
4977
    }
4978
4979
    // Handling all the forum information.
4980
4981
    $result = Database::query($sql);
4982
    $forum_list = array();
4983
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4984
        $forum_list[$row['forum_id']] = $row;
4985
    }
4986
4987
    // Handling the thread count information.
4988
    $result2 = Database::query($sql2);
4989 View Code Duplication
    while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
4990
        if (is_array($forum_list)) {
4991
            if (array_key_exists($row2['forum_id'], $forum_list)) {
4992
                $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
4993
            }
4994
        }
4995
    }
4996
4997
    // Handling the post count information.
4998
    $result3 = Database::query($sql3);
4999 View Code Duplication
    while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
5000
        if (is_array($forum_list)) {
5001
            if (array_key_exists($row3['forum_id'], $forum_list)) {
5002
                // This is needed because sql3 takes also the deleted forums into account.
5003
                $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
5004
            }
5005
        }
5006
    }
5007
5008
    // Finding the last post information (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
5009
    if (!empty($forum_list)) {
5010 View Code Duplication
        foreach ($forum_list as $key => $value) {
5011
            $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit());
5012
            $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
5013
            $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
5014
            $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
5015
            $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
5016
            $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
5017
            $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
5018
        }
5019
    }
5020
5021
    return $forum_list;
5022
}
5023
5024
/**
5025
 * This function stores which users have to be notified of which forums or threads
5026
 *
5027
 * @param string $content does the user want to be notified about a forum or about a thread
5028
 * @param integer $id the id of the forum or thread
5029
 * @return string language variable
5030
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5031
 * @version May 2008, dokeos 1.8.5
5032
 * @since May 2008, dokeos 1.8.5
5033
 */
5034
function set_notification($content, $id, $add_only = false)
5035
{
5036
    $_user = api_get_user_info();
5037
5038
    // Database table definition
5039
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5040
5041
    $course_id = api_get_course_int_id();
5042
5043
    // Which database field do we have to store the id in?
5044
    if ($content == 'forum') {
5045
        $database_field = 'forum_id';
5046
    } else {
5047
        $database_field = 'thread_id';
5048
    }
5049
5050
    // First we check if the notification is already set for this.
5051
    $sql = "SELECT * FROM $table_notification
5052
            WHERE
5053
                c_id = $course_id AND
5054
                $database_field = '".Database::escape_string($id)."' AND
5055
                user_id = '".intval($_user['user_id'])."'";
5056
    $result = Database::query($sql);
5057
    $total = Database::num_rows($result);
5058
5059
    // If the user did not indicate that (s)he wanted to be notified already
5060
    // then we store the notification request (to prevent double notification requests).
5061
    if ($total <= 0) {
5062
        $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id)
5063
                VALUES (".$course_id.", '".Database::escape_string($id)."','".intval($_user['user_id'])."')";
5064
        Database::query($sql);
5065
        Session::erase('forum_notification');
5066
        get_notifications_of_user(0, true);
5067
5068
        return get_lang('YouWillBeNotifiedOfNewPosts');
5069
    } else {
5070
        if (!$add_only) {
5071
            $sql = "DELETE FROM $table_notification
5072
                    WHERE
5073
                        c_id = $course_id AND
5074
                        $database_field = '".Database::escape_string($id)."' AND
5075
                        user_id = '".intval($_user['user_id'])."'";
5076
            Database::query($sql);
5077
            Session::erase('forum_notification');
5078
            get_notifications_of_user(0, true);
5079
5080
            return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
5081
        }
5082
    }
5083
}
5084
5085
/**
5086
 * This function retrieves all the email adresses of the users who wanted to be notified
5087
 * about a new post in a certain forum or thread
5088
 *
5089
 * @param string $content does the user want to be notified about a forum or about a thread
5090
 * @param integer $id the id of the forum or thread
5091
 * @return array returns
5092
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5093
 * @version May 2008, dokeos 1.8.5
5094
 * @since May 2008, dokeos 1.8.5
5095
 */
5096
function get_notifications($content, $id)
5097
{
5098
    // Database table definition
5099
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5100
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5101
5102
    $course_id = api_get_course_int_id();
5103
5104
    // Which database field contains the notification?
5105
    if ($content == 'forum') {
5106
        $database_field = 'forum_id';
5107
    } else {
5108
        $database_field = 'thread_id';
5109
    }
5110
5111
    $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
5112
            FROM $table_users user, $table_notification notification
5113
            WHERE notification.c_id = $course_id AND user.active = 1 AND
5114
            user.user_id = notification.user_id AND
5115
            notification.$database_field= '".Database::escape_string($id)."'";
5116
5117
    $result = Database::query($sql);
5118
    $return = array();
5119
5120
    while ($row = Database::fetch_array($result)) {
5121
        $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
5122
    }
5123
5124
    return $return;
5125
}
5126
5127
/**
5128
 * Get all the users who need to receive a notification of a new post (those subscribed to
5129
 * the forum or the thread)
5130
 *
5131
 * @param integer $forum_id the id of the forum
5132
 * @param integer $thread_id the id of the thread
5133
 * @param integer $post_id the id of the post
5134
 * @return false|null
5135
 *
5136
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5137
 * @version May 2008, dokeos 1.8.5
5138
 * @since May 2008, dokeos 1.8.5
5139
 */
5140
function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
5141
{
5142
    $_course = api_get_course_info();
5143
5144
    // The content of the mail
5145
    $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forum_id.'&thread='.$thread_id;
5146
5147
    // Users who subscribed to the forum
5148
    if ($forum_id != 0) {
5149
        $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
5150
    } else {
5151
        return false;
5152
    }
5153
5154
    $current_thread = get_thread_information($thread_id);
5155
    $current_forum = get_forum_information($current_thread['forum_id']);
5156
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
5157
5158
    // User who subscribed to the thread
5159
    if ($thread_id != 0) {
5160
        $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
5161
    }
5162
5163
    // Merging the two
5164
    $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
5165
    $sender_id = api_get_user_id();
5166
5167
    if (is_array($users_to_be_notified)) {
5168
        foreach ($users_to_be_notified as $value) {
5169
5170
            $user_info = api_get_user_info($value['user_id']);
5171
            $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
5172
            $email_body .= get_lang('NewForumPost').": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
5173
            $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."]  <br />\n";
5174
            $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
5175
            $email_body .= get_lang('ThreadCanBeFoundHere').': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
5176
5177
            MessageManager::send_message_simple(
5178
                $value['user_id'], $subject, $email_body, $sender_id
5179
            );
5180
        }
5181
    }
5182
}
5183
5184
/**
5185
 * Get all the notification subscriptions of the user
5186
 * = which forums and which threads does the user wants to be informed of when a new
5187
 * post is added to this thread
5188
 *
5189
 * @param integer $user_id the user_id of a user (default = 0 => the current user)
5190
 * @param boolean $force force get the notification subscriptions (even if the information is already in the session
5191
 * @return array returns
5192
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5193
 * @version May 2008, dokeos 1.8.5
5194
 * @since May 2008, dokeos 1.8.5
5195
 */
5196
function get_notifications_of_user($user_id = 0, $force = false)
5197
{
5198
    // Database table definition
5199
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5200
    $course_id = api_get_course_int_id();
5201
    if (empty($course_id) || $course_id == -1) {
5202
        return null;
5203
    }
5204
    if ($user_id == 0) {
5205
        $user_id = api_get_user_id();
5206
    }
5207
5208
    if (!isset($_SESSION['forum_notification']) ||
5209
        $_SESSION['forum_notification']['course'] != $course_id ||
5210
        $force = true
5211
    ) {
5212
        $_SESSION['forum_notification']['course'] = $course_id;
5213
5214
        $sql = "SELECT * FROM $table_notification
5215
                WHERE c_id = $course_id AND user_id='".intval($user_id)."'";
5216
        $result = Database::query($sql);
5217
        while ($row = Database::fetch_array($result)) {
5218
            if (!is_null($row['forum_id'])) {
5219
                $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
5220
            }
5221
            if (!is_null($row['thread_id'])) {
5222
                $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
5223
            }
5224
        }
5225
    }
5226
}
5227
5228
/**
5229
 * This function counts the number of post inside a thread
5230
 * @param   int $thread_id
5231
 * @return  int the number of post inside a thread
5232
 * @author Jhon Hinojosa <[email protected]>,
5233
 * @version octubre 2008, dokeos 1.8
5234
 */
5235
function count_number_of_post_in_thread($thread_id)
5236
{
5237
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5238
    $course_id = api_get_course_int_id();
5239
    if (empty($course_id)) {
5240
        return 0;
5241
    }
5242
    $sql = "SELECT * FROM $table_posts
5243
            WHERE c_id = $course_id AND thread_id='".intval($thread_id)."' ";
5244
    $result = Database::query($sql);
5245
5246
    return count(Database::store_result($result));
5247
}
5248
5249
/**
5250
 * This function counts the number of post inside a thread user
5251
 * @param   int $thread_id
5252
 * @param   int $user_id
5253
 *
5254
 * @return  int the number of post inside a thread user
5255
 */
5256
function count_number_of_post_for_user_thread($thread_id, $user_id)
5257
{
5258
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5259
    $course_id = api_get_course_int_id();
5260
    $sql = "SELECT count(*) as count FROM $table_posts
5261
            WHERE c_id = $course_id AND
5262
                  thread_id=".intval($thread_id)." AND
5263
                  poster_id = ".intval($user_id)." AND visible = 1 ";
5264
    $result = Database::query($sql);
5265
    $count = 0;
5266 View Code Duplication
    if (Database::num_rows($result) > 0) {
5267
        $count = Database::fetch_array($result);
5268
        $count = $count['count'];
5269
    }
5270
5271
    return $count;
5272
}
5273
5274
/**
5275
 * This function counts the number of user register in course
5276
 * @param   int $course_id Course ID
5277
 *
5278
 * @return  int the number of user register in course
5279
 * @author Jhon Hinojosa <[email protected]>,
5280
 * @version octubre 2008, dokeos 1.8
5281
 */
5282
function count_number_of_user_in_course($course_id)
5283
{
5284
    $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5285
5286
    $sql = "SELECT * FROM $table
5287
            WHERE c_id ='".intval($course_id)."' ";
5288
    $result = Database::query($sql);
5289
5290
    return count(Database::store_result($result));
5291
}
5292
5293
/**
5294
 * This function retrieves information of statistical
5295
 * @param   int $thread_id
5296
 * @param   int $user_id
5297
 * @param   int $course_id
5298
 *
5299
 * @return  array the information of statistical
5300
 * @author Jhon Hinojosa <[email protected]>,
5301
 * @version octubre 2008, dokeos 1.8
5302
 */
5303
function get_statistical_information($thread_id, $user_id, $course_id)
5304
{
5305
    $result = array();
5306
    $result['user_course'] = count_number_of_user_in_course($course_id);
5307
    $result['post'] = count_number_of_post_in_thread($thread_id);
5308
    $result['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
5309
5310
    return $result;
5311
}
5312
5313
/**
5314
 * This function return the posts inside a thread from a given user
5315
 * @param   string $course_code
5316
 * @param   int $thread_id
5317
 * @param   int $user_id
5318
 *
5319
 * @return  int the number of post inside a thread
5320
 * @author Jhon Hinojosa <[email protected]>,
5321
 * @version octubre 2008, dokeos 1.8
5322
 */
5323
function get_thread_user_post($course_code, $thread_id, $user_id)
5324
{
5325
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5326
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5327
    $thread_id = intval($thread_id);
5328
    $user_id = intval($user_id);
5329
    $course_info = api_get_user_info($course_code);
5330
    $course_id = $course_info['real_id'];
5331
5332
    if (empty($course_id)) {
5333
        $course_id = api_get_course_int_id();
5334
    }
5335
    $sql = "SELECT * FROM $table_posts posts
5336
            LEFT JOIN  $table_users users
5337
                ON posts.poster_id=users.user_id
5338
            WHERE
5339
                posts.c_id = $course_id AND
5340
                posts.thread_id='$thread_id'
5341
                AND posts.poster_id='$user_id'
5342
            ORDER BY posts.post_id ASC";
5343
5344
    $result = Database::query($sql);
5345
    $post_list = array();
5346 View Code Duplication
    while ($row = Database::fetch_array($result)) {
5347
        $row['status'] = '1';
5348
        $post_list[] = $row;
5349
        $sql = "SELECT * FROM $table_posts posts
5350
                LEFT JOIN  $table_users users
5351
                    ON posts.poster_id=users.user_id
5352
                WHERE
5353
                    posts.c_id = $course_id AND
5354
                    posts.thread_id='$thread_id'
5355
                    AND posts.post_parent_id='".$row['post_id']."'
5356
                ORDER BY posts.post_id ASC";
5357
        $result2 = Database::query($sql);
5358
        while ($row2 = Database::fetch_array($result2)) {
5359
            $row2['status'] = '0';
5360
            $post_list[] = $row2;
5361
        }
5362
    }
5363
5364
    return $post_list;
5365
}
5366
5367
/**
5368
 * This function get the name of an thread by id
5369
 * @param int thread_id
5370
 * @return String
5371
 * @author Christian Fasanando
5372
 * @author Julio Montoya <[email protected]> Adding security
5373
 */
5374 View Code Duplication
function get_name_thread_by_id($thread_id)
5375
{
5376
    $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
5377
    $course_id = api_get_course_int_id();
5378
    $sql = "SELECT thread_title FROM ".$t_forum_thread."
5379
            WHERE c_id = $course_id AND thread_id = '".intval($thread_id)."' ";
5380
    $result = Database::query($sql);
5381
    $row = Database::fetch_array($result);
5382
5383
    return $row[0];
5384
}
5385
5386
/**
5387
 * This function gets all the post written by an user
5388
 * @param int $user_id
5389
 * @param string $course_code
5390
 *
5391
 * @return string
5392
 */
5393
function get_all_post_from_user($user_id, $course_code)
5394
{
5395
    $j = 0;
5396
    $forums = get_forums('', $course_code);
5397
    krsort($forums);
5398
    $forum_results = '';
5399
5400
    foreach ($forums as $forum) {
5401
        if ($forum['visibility'] == 0) {
5402
            continue;
5403
        }
5404
        if ($j <= 4) {
5405
            $threads = get_threads($forum['forum_id'], $course_code);
5406
5407
            if (is_array($threads)) {
5408
                $i = 0;
5409
                $hand_forums = '';
5410
                $post_counter = 0;
5411
5412
                foreach ($threads as $thread) {
5413
                    if ($thread['visibility'] == 0) {
5414
                        continue;
5415
                    }
5416
                    if ($i <= 4) {
5417
                        $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
5418
                        $post_counter = count($post_list);
5419
                        if (is_array($post_list) && count($post_list) > 0) {
5420
                            $hand_forums.= '<div id="social-thread">';
5421
                            $hand_forums.= Display::return_icon('thread.png', get_lang('Thread'), '', ICON_SIZE_MEDIUM);
5422
                            $hand_forums.= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
5423
                            $hand_forums.= '</div>';
5424
5425
                            foreach ($post_list as $posts) {
5426
                                $hand_forums.= '<div id="social-post">';
5427
                                $hand_forums.= '<strong>'.Security::remove_XSS($posts['post_title'], STUDENT).'</strong>';
5428
                                $hand_forums.= '<br / >';
5429
                                $hand_forums.= Security::remove_XSS($posts['post_text'], STUDENT);
5430
                                $hand_forums.= '</div>';
5431
                                $hand_forums.= '<br / >';
5432
                            }
5433
                        }
5434
                    }
5435
                    $i++;
5436
                }
5437
                $forum_results .='<div id="social-forum">';
5438
                $forum_results .='<div class="clear"></div><br />';
5439
                $forum_results .='<div id="social-forum-title">'.
5440
                    Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS($forum['forum_title'], STUDENT).
5441
                    '<div style="float:right;margin-top:-35px">
5442
                                        <a href="../forum/viewforum.php?cidReq='.$course_code.'&gidReq=&forum='.$forum['forum_id'].' " >'.get_lang('SeeForum').'</a>
5443
                                    </div></div>';
5444
                $forum_results .='<br / >';
5445
                if ($post_counter > 0) {
5446
                    $forum_results .=$hand_forums;
5447
                }
5448
                $forum_results .='</div>';
5449
            }$j++;
5450
        }
5451
    }
5452
5453
    return $forum_results;
5454
}
5455
5456
/**
5457
 * @param string $course_code
5458
 * @param int $thread_id
5459
 * @param int $user_id
5460
 * @param int $limit
5461
 *
5462
 * @return array
5463
 */
5464
function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
5465
{
5466
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5467
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5468
5469
    $course_info = api_get_course_info($course_code);
5470
    $course_id = $course_info['real_id'];
5471
5472
    $sql = "SELECT * FROM $table_posts posts
5473
            LEFT JOIN  $table_users users
5474
                ON posts.poster_id=users.user_id
5475
            WHERE
5476
                posts.c_id = $course_id AND
5477
                posts.thread_id='".Database::escape_string($thread_id)."'
5478
                AND posts.poster_id='".Database::escape_string($user_id)."'
5479
            ORDER BY posts.post_id DESC LIMIT $limit ";
5480
    $result = Database::query($sql);
5481
    $post_list = array();
5482
    while ($row = Database::fetch_array($result)) {
5483
        $row['status'] = '1';
5484
        $post_list[] = $row;
5485
    }
5486
5487
    return $post_list;
5488
}
5489
5490
/**
5491
 * @param string $user_id
5492
 * @param int $courseId
5493
 * @param int $sessionId
5494
 *
5495
 * @return array
5496
 */
5497
function getForumCreatedByUser($user_id, $courseId, $sessionId)
5498
{
5499
    $items = api_get_item_property_list_by_tool_by_user(
5500
        $user_id,
5501
        'forum',
5502
        $courseId,
5503
        $sessionId
5504
    );
5505
5506
    $courseInfo = api_get_course_info_by_id($courseId);
5507
5508
    $forumList = array();
5509 View Code Duplication
    if (!empty($items)) {
5510
        foreach ($items as $forum) {
5511
            $forumInfo = get_forums(
5512
                $forum['ref'],
5513
                $courseInfo['code'],
5514
                true,
5515
                $sessionId
5516
            );
5517
5518
            $forumList[] = array(
5519
                $forumInfo['forum_title'],
5520
                api_get_local_time($forum['insert_date']),
5521
                api_get_local_time($forum['lastedit_date']),
5522
            );
5523
        }
5524
    }
5525
5526
    return $forumList;
5527
}
5528
5529
/**
5530
 * This function builds an array of all the posts in a given thread
5531
 * where the key of the array is the post_id
5532
 * It also adds an element children to the array which itself is an array
5533
 * that contains all the id's of the first-level children
5534
 * @return array $rows containing all the information on the posts of a thread
5535
 * @author Patrick Cool <[email protected]>, Ghent University
5536
 */
5537
function calculate_children($rows)
5538
{
5539
    $sorted_rows = array(0 => array());
5540
    if (!empty($rows)) {
5541
        foreach ($rows as $row) {
5542
            $rows_with_children[$row['post_id']] = $row;
5543
            $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
5544
        }
5545
5546
        $rows = $rows_with_children;
5547
        forumRecursiveSort($rows, $sorted_rows);
5548
        unset($sorted_rows[0]);
5549
    }
5550
5551
    return $sorted_rows;
5552
}
5553
5554
/**
5555
 * @param $rows
5556
 * @param $threads
5557
 * @param int $seed
5558
 * @param int $indent
5559
 */
5560
function forumRecursiveSort($rows, &$threads, $seed = 0, $indent = 0)
5561
{
5562
    if ($seed > 0) {
5563
        $threads[$rows[$seed]['post_id']] = $rows[$seed];
5564
        $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
5565
        $indent++;
5566
    }
5567
5568
    if (isset($rows[$seed]['children'])) {
5569
        foreach ($rows[$seed]['children'] as $child) {
5570
            forumRecursiveSort($rows, $threads, $child, $indent);
5571
        }
5572
    }
5573
}
5574
5575
/**
5576
 * Update forum attachment data, used to update comment and post ID.
5577
 * @param $array Array (field => value) to update forum attachment row.
5578
 * @param $id Attach ID to find row to update.
5579
 * @param null $courseId Course ID to find row to update.
5580
 * @return int Number of affected rows.
5581
 */
5582
function editAttachedFile($array, $id, $courseId = null) {
5583
    // Init variables
5584
    $setString = '';
5585
    $id = intval($id);
5586
    $courseId = intval($courseId);
5587
    if (empty($courseId)) {
5588
        // $courseId can be null, use api method
5589
        $courseId= api_get_course_int_id();
5590
    }
5591
    /*
5592
     * Check if Attachment ID and Course ID are greater than zero
5593
     * and array of field values is not empty
5594
     */
5595
    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
5596
        foreach($array as $key => &$item) {
5597
            $item = Database::escape_string($item);
5598
            $setString .= $key . ' = "' .$item . '", ';
5599
        }
5600
        // Delete last comma
5601
        $setString = substr($setString, 0, strlen($setString) - 2);
5602
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5603
        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
5604
        $result = Database::query($sql);
5605
        if ($result !== false) {
5606
            $affectedRows = Database::affected_rows($result);
5607 View Code Duplication
            if ($affectedRows > 0) {
5608
                /*
5609
                 * If exist in $_SESSION variable, then delete them from it
5610
                 * because they would be deprecated
5611
                 */
5612
                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
5613
                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
5614
                }
5615
            }
5616
5617
            return $affectedRows;
5618
        }
5619
    }
5620
5621
    return 0;
5622
}
5623
5624
/**
5625
 * Return a form to upload asynchronously attachments to forum post.
5626
 * @param int $forumId Forum ID from where the post are
5627
 * @param int $threadId Thread ID where forum post are
5628
 * @param int $postId Post ID to identify Post
5629
 * @deprecated this function seems to never been used
5630
 * @return string The Forum Attachment Ajax Form
5631
 *
5632
 */
5633
function getAttachmentAjaxForm($forumId, $threadId, $postId)
5634
{
5635
    $forumId = intval($forumId);
5636
    $postId = intval($postId);
5637
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5638
    if ($forumId === 0) {
5639
        // Forum Id must be defined
5640
5641
        return '';
5642
    }
5643
5644
    $url = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq().'&forum=' . $forumId . '&thread=' . $threadId . '&postId=' . $postId . '&a=upload_file';
5645
5646
    $multipleForm = new FormValidator('post');
5647
    $multipleForm->addMultipleUpload($url);
5648
5649
    return $multipleForm->returnForm();
5650
}
5651
5652
/**
5653
 * Return a table where the attachments will be set
5654
 * @param int $postId Forum Post ID
5655
 *
5656
 * @return string The Forum Attachments Ajax Table
5657
 */
5658
function getAttachmentsAjaxTable($postId = null)
5659
{
5660
    // Init variables
5661
    $postId = intval($postId);
5662
    $courseId = api_get_course_int_id();
5663
    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5664
    $fileDataContent = '';
5665
    // Update comment to show if form did not pass validation
5666
    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
5667
        // 'file_ids is the name from forum attachment ajax form
5668
        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
5669
            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) &&
5670
                is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])
5671
            ) {
5672
                // If exist forum attachment then update into $_SESSION data
5673
                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
5674
            }
5675
        }
5676
    }
5677
    // Get data to fill into attachment files table
5678
    if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5679
        is_array($_SESSION['forum']['upload_file'][$courseId])
5680
    ) {
5681
        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
5682
        foreach ($uploadedFiles as $k => $uploadedFile) {
5683
            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
5684
                // Buil html table including an input with attachmentID
5685
                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
5686
                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
5687
                    $uploadedFile['delete'] . '</td>' .
5688
                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
5689
            } else {
5690
                /*
5691
                 * If attachment data is empty, then delete it from $_SESSION
5692
                 * because could generate and empty row into html table
5693
                 */
5694
                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
5695
            }
5696
        }
5697
    }
5698
    $style = empty($fileDataContent) ? 'display: none;' : '';
5699
    // Forum attachment Ajax table
5700
    $fileData = '
5701
    <div class="control-group " style="'. $style . '">
5702
        <label class="control-label">'.get_lang('AttachmentList').'</label>
5703
        <div class="controls">
5704
            <table id="attachmentFileList" class="files data_table span10">
5705
                <tr>
5706
                    <th>'.get_lang('FileName').'</th>
5707
                    <th>'.get_lang('Size').'</th>
5708
                    <th>'.get_lang('Status').'</th>
5709
                    <th>'.get_lang('Comment').'</th>
5710
                    <th>'.get_lang('Delete').'</th>
5711
                </tr>
5712
                '.$fileDataContent.'
5713
            </table>
5714
        </div>
5715
    </div>';
5716
5717
    return $fileData;
5718
}
5719
5720
/**
5721
 * Return an array of prepared attachment data to build forum attachment table
5722
 * Also, save this array into $_SESSION to do available the attachment data
5723
 * @param int $forumId
5724
 * @param int $threadId
5725
 * @param int $postId
5726
 * @param int $attachId
5727
 * @param int $courseId
5728
 *
5729
 * @return array
5730
 */
5731
function getAttachedFiles($forumId, $threadId, $postId = null, $attachId = null, $courseId = null)
5732
{
5733
    $forumId = intval($forumId);
5734
    $courseId = intval($courseId);
5735
    $attachId = intval($attachId);
5736
    $postId = intval($postId);
5737
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5738
    if (empty($courseId)) {
5739
        // $courseId can be null, use api method
5740
        $courseId = api_get_course_int_id();
5741
    }
5742
    if (empty($forumId)) {
5743
        if (!empty($_REQUEST['forum'])) {
5744
            $forumId = intval($_REQUEST['forum']);
5745
        } else {
5746
            // if forum ID is empty, cannot generate delete url
5747
5748
            return array();
5749
        }
5750
    }
5751
    // Check if exist at least one of them to filter forum attachment select query
5752
    if (empty($postId) && empty($attachId)) {
5753
5754
        return array();
5755
    } elseif (empty($postId)) {
5756
        $filter = "AND iid = $attachId";
5757
    } elseif (empty($attachId)) {
5758
        $filter = "AND post_id = $postId";
5759
    } else {
5760
        $filter = "AND post_id = $postId AND iid = $attachId";
5761
    }
5762
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5763
    $sql = "SELECT iid, comment, filename, path, size
5764
            FROM $forumAttachmentTable
5765
            WHERE c_id = $courseId $filter";
5766
    $result = Database::query($sql);
5767
    $json = array();
5768
    if ($result !== false && Database::num_rows($result) > 0) {
5769
        while ($row = Database::fetch_array($result, 'ASSOC')) {
5770
            // name contains an URL to download attachment file and its filename
5771
            $json['name'] = Display::url(
5772
                api_htmlentities($row['filename']),
5773
                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'].'&'.api_get_cidreq(),
5774
                array('target'=>'_blank', 'class' => 'attachFilename')
5775
            );
5776
            $json['id'] = $row['iid'];
5777
            $json['comment'] = $row['comment'];
5778
            // Format file size
5779
            $json['size'] = format_file_size($row['size']);
5780
            // Check if $row is consistent
5781
            if (!empty($row) && is_array($row)) {
5782
                // Set result as success and bring delete URL
5783
                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
5784
                $url = api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php?' . api_get_cidreq() . '&action=delete_attach&forum=' . $forumId . '&thread=' . $threadId.'&id_attach=' . $row['iid'];
5785
                $json['delete'] = Display::url(
5786
                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL),
5787
                    $url,
5788
                    array('class' => 'deleteLink')
5789
                );
5790
            } else {
5791
                // If not, set an exclamation result
5792
                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
5793
            }
5794
            // Store array data into $_SESSION
5795
            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
5796
        }
5797
    }
5798
5799
    return $json;
5800
}
5801
5802
/**
5803
 * Clear forum attachment data stored in $_SESSION,
5804
 * If is not defined post, it will clear all forum attachment data from course
5805
 * @param int $postId -1 : Clear all attachments from course stored in $_SESSION
5806
 *                      0 : Clear attachments from course, except from temporal post "0"
5807
 *                          but without delete them from file system and database
5808
 *                     Other values : Clear attachments from course except specified post
5809
 *                          and delete them from file system and database
5810
 * @param int $courseId : Course ID, if it is null, will use api_get_course_int_id()
5811
 *
5812
 * @return array
5813
 */
5814
function clearAttachedFiles($postId = null, $courseId = null) {
5815
    // Init variables
5816
    $courseId = intval($courseId);
5817
    $postId = intval($postId);
5818
    $array = array();
5819
    if (empty($courseId)) {
5820
        // $courseId can be null, use api method
5821
        $courseId = api_get_course_int_id();
5822
    }
5823
    if ($postId === -1) {
5824
        // If post ID is -1 then delete course's attachment data from $_SESSION
5825 View Code Duplication
        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
5826
            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
5827
            unset($_SESSION['forum']['upload_file'][$courseId]);
5828
        }
5829
    } else {
5830
        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5831
        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5832
            is_array($_SESSION['forum']['upload_file'][$courseId])) {
5833
            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
5834
                if (!in_array($attachId, $attachIds)) {
5835
                    // If attach ID is not into specified post, delete attachment
5836
                    // Save deleted attachment ID
5837
                    $array[] = $attachId;
5838
                    if ($postId !== 0) {
5839
                        // Post 0 is temporal, delete them from file system and DB
5840
                        delete_attachment(0, $attachId, false);
5841
                    }
5842
                    // Delete attachment data from $_SESSION
5843
                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
5844
                }
5845
            }
5846
        }
5847
    }
5848
5849
    return $array;
5850
}
5851
5852
/**
5853
 * Returns an array of forum attachment ids into a course and forum post
5854
 * @param int $postId
5855
 * @param int $courseId
5856
 *
5857
 * @return array
5858
 */
5859
function getAttachmentIdsByPostId($postId, $courseId = null)
5860
{
5861
5862
    $array = array();
5863
    $courseId = intval($courseId);
5864
    $postId = intval($postId);
5865
    if (empty($courseId)) {
5866
        // $courseId can be null, use api method
5867
        $courseId = api_get_course_int_id();
5868
    }
5869
    if ($courseId > 0) {
5870
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5871
        $sql = "SELECT id FROM $forumAttachmentTable
5872
                WHERE c_id = $courseId AND post_id = $postId";
5873
        $result = Database::query($sql);
5874
        if ($result !== false && Database::num_rows($result) > 0) {
5875
            while ($row = Database::fetch_array($result,'ASSOC')) {
5876
                $array[] = $row['id'];
5877
            }
5878
        }
5879
    }
5880
    return $array;
5881
}
5882
5883
/**
5884
 * Check if the forum category exists looking for its title
5885
 * @param string $title The forum category title
5886
 * @param int $courseId The course ID
5887
 * @param int $sessionId Optional. The session ID
5888
 * @return boolean
5889
 */
5890
function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
5891
{
5892
    $sessionId = intval($sessionId);
5893
5894
    $forumCategoryTable = Database::get_course_table(TABLE_FORUM_CATEGORY);
5895
    $itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
5896
5897
    $fakeFrom = "$forumCategoryTable fc
5898
        INNER JOIN $itemProperty ip ";
5899
5900
    if ($sessionId === 0) {
5901
        $fakeFrom .= "
5902
            ON (
5903
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND (fc.session_id = ip.session_id OR ip.session_id IS NULL)
5904
            )
5905
        ";
5906
    } else {
5907
        $fakeFrom .= "
5908
            ON (
5909
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND fc.session_id = ip.session_id
5910
            )
5911
        ";
5912
    }
5913
5914
    $resultData = Database::select(
5915
        'fc.*',
5916
        $fakeFrom,
5917
        [
5918
            'where' => [
5919
                'ip.visibility != ? AND ' => 2,
5920
                'ip.tool = ? AND ' => TOOL_FORUM_CATEGORY,
5921
                'fc.session_id = ? AND ' => $sessionId,
5922
                'fc.cat_title = ? AND ' => $title,
5923
                'fc.c_id = ?' => intval($courseId)
5924
            ]
5925
        ],
5926
        'first'
5927
    );
5928
5929
    if (empty($resultData)) {
5930
        return false;
5931
    }
5932
5933
    return $resultData;
5934
}
5935