Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

forumfunction.inc.php ➔ store_edit_post()   F

Complexity

Conditions 18
Paths 576

Size

Total Lines 97
Code Lines 63

Duplication

Lines 5
Ratio 5.15 %

Importance

Changes 0
Metric Value
cc 18
eloc 63
nc 576
nop 2
dl 5
loc 97
rs 2.4991
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
use ChamiloSession as Session;
5
use Doctrine\Common\Collections\Criteria;
6
use Chamilo\CourseBundle\Entity\CForumPost;
7
use Chamilo\CourseBundle\Entity\CForumThread;
8
9
/**
10
 * These files are a complete rework of the forum. The database structure is
11
 * based on phpBB but all the code is rewritten. A lot of new functionalities
12
 * are added:
13
 * - forum categories and forums can be sorted up or down, locked or made invisible
14
 * - consistent and integrated forum administration
15
 * - forum options:     are students allowed to edit their post?
16
 *                         moderation of posts (approval)
17
 *                         reply only forums (students cannot create new threads)
18
 *                         multiple forums per group
19
 * - sticky messages
20
 * - new view option: nested view
21
 * - quoting a message
22
 *
23
 * @package chamilo.forum
24
 *
25
 * @todo several functions have to be moved to the itemmanager library
26
 * @todo displaying icons => display library
27
 * @todo complete the missing phpdoc the correct order should be
28
 * @todo convert into a class
29
 */
30
31
get_notifications_of_user();
32
33
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
34
$htmlHeadXtra[] = '<script>
35
36
function check_unzip() {
37
    if (document.upload.unzip.checked){
38
        document.upload.if_exists[0].disabled=true;
39
        document.upload.if_exists[1].checked=true;
40
        document.upload.if_exists[2].disabled=true;
41
    } else {
42
        document.upload.if_exists[0].checked=true;
43
        document.upload.if_exists[0].disabled=false;
44
        document.upload.if_exists[2].disabled=false;
45
    }
46
}
47
function setFocus() {
48
    $("#title_file").focus();
49
}
50
</script>';
51
// The next javascript script is to manage ajax upload file
52
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
53
54
// Recover Thread ID, will be used to generate delete attachment URL to do ajax
55
$threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : 0;
56
$forumId = isset($_REQUEST['forum']) ? intval($_REQUEST['forum']) : 0;
57
58
// The next javascript script is to delete file by ajax
59
$htmlHeadXtra[] = '<script>
60
$(function () {
61
    $(document).on("click", ".deleteLink", function(e) {
62
        e.preventDefault();
63
        e.stopPropagation();
64
        var l = $(this);
65
        var id = l.closest("tr").attr("id");
66
        var filename = l.closest("tr").find(".attachFilename").html();
67
        if (confirm("' . get_lang('AreYouSureToDeleteJS') . '", filename)) {
68
            $.ajax({
69
                type: "POST",
70
                url: "'.api_get_path(WEB_AJAX_PATH) . 'forum.ajax.php?'.api_get_cidreq().'&a=delete_file&attachId=" + id +"&thread='.$threadId .'&forum='.$forumId .'",
71
                dataType: "json",
72
                success: function(data) {
73
                    if (data.error == false) {
74
                        l.closest("tr").remove();
75
                        if ($(".files td").length < 1) {
76
                            $(".files").closest(".control-group").hide();
77
                        }
78
                    }
79
                }
80
            })
81
        }
82
    });
83
});
84
</script>';
85
86
/**
87
 * This function handles all the forum and forum categories actions. This is a wrapper for the
88
 * forum and forum categories. All this code code could go into the section where this function is
89
 * called but this make the code there cleaner.
90
 * @param int $lp_id Learning path Id
91
 *
92
 * @return void
93
 * @author Patrick Cool <[email protected]>, Ghent University
94
 * @author Juan Carlos Raña Trabado (return to lp_id)
95
 * @version may 2011, Chamilo 1.8.8
96
 */
97
function handle_forum_and_forumcategories($lp_id = null)
98
{
99
    $action_forum_cat = isset($_GET['action']) ? $_GET['action'] : '';
100
    $get_content = isset($_GET['content']) ? $_GET['content'] : '';
101
    $post_submit_cat = isset($_POST['SubmitForumCategory']) ? true : false;
102
    $post_submit_forum = isset($_POST['SubmitForum']) ? true : false;
103
    $get_id = isset($_GET['id']) ? intval($_GET['id']) : '';
104
    $forum_categories_list = get_forum_categories();
105
106
    //Verify if forum category exists
107
    if (empty($forum_categories_list)) {
108
        $get_content = 'forumcategory';
109
    }
110
111
    // Adding a forum category
112
    if (($action_forum_cat == 'add' && $get_content == 'forumcategory') || $post_submit_cat) {
113
        show_add_forumcategory_form(array(), $lp_id); //$lp_id when is called from learning path
114
    }
115
116
    // Adding a forum
117
    if ((($action_forum_cat == 'add' || $action_forum_cat == 'edit') && $get_content == 'forum') || $post_submit_forum) {
118
        if ($action_forum_cat == 'edit' && $get_id || $post_submit_forum) {
119
            $inputvalues = get_forums($get_id);
120
        } else {
121
            $inputvalues = array();
122
        }
123
        show_add_forum_form($inputvalues, $lp_id);
124
    }
125
126
    // Edit a forum category
127
    if (($action_forum_cat == 'edit' && $get_content == 'forumcategory') || (isset($_POST['SubmitEditForumCategory'])) ? true : false) {
128
        $forum_category = get_forum_categories($get_id);
129
        show_edit_forumcategory_form($forum_category);
130
    }
131
132
    // Delete a forum category
133
    if ($action_forum_cat == 'delete') {
134
        $id_forum = intval($get_id);
135
        $list_threads = get_threads($id_forum);
136
137
        for ($i = 0; $i < count($list_threads); $i++) {
138
            deleteForumCategoryThread('thread', $list_threads[$i]['thread_id']);
139
            $link_info = GradebookUtils::isResourceInCourseGradebook(
140
                api_get_course_int_id(),
141
                5,
142
                $list_threads[$i]['thread_id'],
143
                api_get_session_id()
144
            );
145
            if ($link_info !== false) {
146
                GradebookUtils::remove_resource_from_course_gradebook($link_info['id']);
147
            }
148
        }
149
        $return_message = deleteForumCategoryThread($get_content, $get_id);
150
        echo Display::return_message($return_message, 'confirmation', false);
151
    }
152
153
    // Change visibility of a forum or a forum category.
154
    if ($action_forum_cat == 'invisible' || $action_forum_cat == 'visible') {
155
        $return_message = change_visibility($get_content, $get_id, $action_forum_cat);
156
        echo Display::return_message($return_message, 'confirmation', false);
157
    }
158
    // Change lock status of a forum or a forum category.
159
    if ($action_forum_cat == 'lock' || $action_forum_cat == 'unlock') {
160
        $return_message = change_lock_status($get_content, $get_id, $action_forum_cat);
161
        echo Display::return_message($return_message, 'confirmation', false);
162
    }
163
    // Move a forum or a forum category.
164
    if ($action_forum_cat == 'move' && isset($_GET['direction'])) {
165
        $return_message = move_up_down($get_content, $_GET['direction'], $get_id);
166
        echo Display::return_message($return_message, 'confirmation', false);
167
    }
168
}
169
170
/**
171
 * This function displays the form that is used to add a forum category.
172
 *
173
 * @param  array $inputvalues (deprecated, set to null when calling)
174
 * @param  int $lp_id Learning path ID
175
 *
176
 * @author Patrick Cool <[email protected]>, Ghent University
177
 * @author Juan Carlos Raña Trabado (return to lp_id)
178
 * @version may 2011, Chamilo 1.8.8
179
 */
180
function show_add_forumcategory_form($inputvalues = array(), $lp_id)
181
{
182
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
183
    // hidden field if from learning path
184
    $form->addElement('hidden', 'lp_id', $lp_id);
185
    // Setting the form elements.
186
    $form->addElement('header', get_lang('AddForumCategory'));
187
    $form->addElement('text', 'forum_category_title', get_lang('Title'), array('autofocus'));
188
    $form->addElement(
189
        'html_editor',
190
        'forum_category_comment',
191
        get_lang('Description'),
192
        null,
193
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
194
    );
195
    $form->addButtonCreate(get_lang('CreateCategory'), 'SubmitForumCategory');
196
197
    // Setting the rules.
198
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
199
200
    // The validation or display
201 View Code Duplication
    if ($form->validate()) {
202
        $check = Security::check_token('post');
203
        if ($check) {
204
            $values = $form->exportValues();
205
            store_forumcategory($values);
206
        }
207
        Security::clear_token();
208
    } else {
209
        $token = Security::get_token();
210
        $form->addElement('hidden', 'sec_token');
211
        $form->setConstants(array('sec_token' => $token));
212
        $form->display();
213
    }
214
}
215
216
/**
217
 * This function displays the form that is used to add a forum category.
218
 *
219
 * @param array $inputvalues
220
 * @param int $lp_id
221
 * @return void HTML
222
 *
223
 * @author Patrick Cool <[email protected]>, Ghent University
224
 * @author Juan Carlos Raña Trabado (return to lp_id)
225
 *
226
 * @version may 2011, Chamilo 1.8.8
227
 */
228
function show_add_forum_form($inputvalues = array(), $lp_id)
229
{
230
    $_course = api_get_course_info();
231
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
232
233
    // The header for the form
234
    if (!empty($inputvalues)) {
235
        $form_title = get_lang('EditForum');
236
    } else {
237
        $form_title = get_lang('AddForum');
238
    }
239
240
    $form->addElement('header', $form_title);
241
242
    // We have a hidden field if we are editing.
243
    if (!empty($inputvalues) && is_array($inputvalues)) {
244
        $my_forum_id = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
245
        $form->addElement('hidden', 'forum_id', $my_forum_id);
246
    }
247
    $lp_id = intval($lp_id);
248
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
    $form->addDateTimePicker(
284
        'start_time',
285
        array(get_lang('ForumStartDate'), get_lang('ForumStartDateComment')),
286
        array('id' => 'start_time')
287
    );
288
289
    $form->addDateTimePicker(
290
        'end_time',
291
        array(get_lang('ForumEndDate'), get_lang('ForumEndDateComment')),
292
        array('id' => 'end_time')
293
    );
294
295
    $form->addRule(
296
        array('start_time', 'end_time'),
297
        get_lang('StartDateMustBeBeforeTheEndDate'),
298
        'compare_datetime_text',
299
        '< allow_empty'
300
    );
301
302
    $group = array();
303
    $group[] = $form->createElement('radio', 'moderated', null, get_lang('Yes'), 1);
304
    $group[] = $form->createElement('radio', 'moderated', null, get_lang('No'), 0);
305
    $form->addGroup($group, 'moderated', get_lang('ModeratedForum'));
306
307
    $group = array();
308
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('Yes'), 1);
309
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('No'), 0);
310
    $form->addGroup($group, 'students_can_edit_group', get_lang('StudentsCanEdit'));
311
312
    $group = array();
313
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Approval'), 1);
314
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Direct'), 0);
315
316
    $group = array();
317
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('Yes'), 1);
318
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('No'), 0);
319
320
    $group = array();
321
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('Yes'), 1);
322
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('No'), 0);
323
    $form->addGroup($group, 'allow_new_threads_group', get_lang('AllowNewThreads'));
324
325
    $group = array();
326
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Flat'), 'flat');
327
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Threaded'), 'threaded');
328
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Nested'), 'nested');
329
    $form->addGroup($group, 'default_view_type_group', get_lang('DefaultViewType'));
330
331
    // Drop down list: Groups
332
    $groups = GroupManager::get_group_list();
333
    $groups_titles[0] = get_lang('NotAGroupForum');
334
    foreach ($groups as $key => $value) {
335
        $groups_titles[$value['id']] = $value['name'];
336
    }
337
    $form->addElement('select', 'group_forum', get_lang('ForGroup'), $groups_titles);
338
339
    // Public or private group forum
340
    $group = array();
341
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Public'), 'public');
342
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Private'), 'private');
343
    $form->addGroup($group, 'public_private_group_forum_group', get_lang('PublicPrivateGroupForum'));
344
345
    // Forum image
346
    $form->addProgress();
347
    if (!empty($inputvalues['forum_image'])) {
348
        $baseImagePath = api_get_course_path() . '/upload/forum/images/' . $inputvalues['forum_image'];
349
        $image_path = api_get_path(WEB_COURSE_PATH) . $baseImagePath;
350
        $sysImagePath = api_get_path(SYS_COURSE_PATH) . $baseImagePath;
351
352
        if (file_exists($sysImagePath)) {
353
            $show_preview_image = Display::img($image_path, null, ['class' => 'img-responsive']);
354
            $form->addElement('label', get_lang('PreviewImage'), $show_preview_image);
355
            $form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
356
        }
357
    }
358
    $forum_image = isset($inputvalues['forum_image']) ? $inputvalues['forum_image'] : '';
359
    $form->addElement('file', 'picture', ($forum_image != '' ? get_lang('UpdateImage') : get_lang('AddImage')));
360
    $form->addRule('picture', get_lang('OnlyImagesAllowed'), 'filetype', array('jpg', 'jpeg', 'png', 'gif'));
361
    $form->addElement('html', '</div>');
362
363
    // The OK button
364
    if (isset($_GET['id']) && $_GET['action'] == 'edit') {
365
        $form->addButtonUpdate(get_lang('ModifyForum'), 'SubmitForum');
366
    } else {
367
        $form->addButtonCreate(get_lang('CreateForum'), 'SubmitForum');
368
    }
369
370
    // setting the rules
371
    $form->addRule('forum_title', get_lang('ThisFieldIsRequired'), 'required');
372
    $form->addRule('forum_category', get_lang('ThisFieldIsRequired'), 'required');
373
374
    $defaultSettingAllowNewThreads = api_get_default_tool_setting('forum', 'allow_new_threads', 0);
375
376
    // Settings the defaults
377
    if (empty($inputvalues) || !is_array($inputvalues)) {
378
        $defaults['moderated']['moderated'] = 0;
379
        $defaults['allow_anonymous_group']['allow_anonymous'] = 0;
380
        $defaults['students_can_edit_group']['students_can_edit'] = 0;
381
        $defaults['approval_direct_group']['approval_direct'] = 0;
382
        $defaults['allow_attachments_group']['allow_attachments'] = 1;
383
        $defaults['allow_new_threads_group']['allow_new_threads'] = $defaultSettingAllowNewThreads;
384
        $defaults['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
385
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = 'public';
386
        if (isset($_GET['forumcategory'])) {
387
            $defaults['forum_category'] = Security::remove_XSS($_GET['forumcategory']);
388
        }
389
    } else {
390
        // the default values when editing = the data in the table
391
        $defaults['forum_id'] = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
392
        $defaults['forum_title'] = prepare4display(isset($inputvalues['forum_title']) ? $inputvalues['forum_title'] : null);
393
        $defaults['forum_comment'] = prepare4display(isset($inputvalues['forum_comment']) ? $inputvalues['forum_comment'] : null);
394
        $defaults['start_time'] = isset($inputvalues['start_time']) ? api_get_local_time($inputvalues['start_time']) : null;
395
        $defaults['end_time'] = isset($inputvalues['end_time']) ? api_get_local_time($inputvalues['end_time']) : null;
396
        $defaults['moderated']['moderated'] = isset($inputvalues['moderated']) ? $inputvalues['moderated'] : 0;
397
        $defaults['forum_category'] = isset($inputvalues['forum_category']) ? $inputvalues['forum_category'] : null;
398
        $defaults['allow_anonymous_group']['allow_anonymous'] = isset($inputvalues['allow_anonymous']) ? $inputvalues['allow_anonymous'] : null;
399
        $defaults['students_can_edit_group']['students_can_edit'] = isset($inputvalues['allow_edit']) ? $inputvalues['allow_edit'] : null;
400
        $defaults['approval_direct_group']['approval_direct'] = isset($inputvalues['approval_direct_post']) ? $inputvalues['approval_direct_post'] : null;
401
        $defaults['allow_attachments_group']['allow_attachments'] = isset($inputvalues['allow_attachments']) ? $inputvalues['allow_attachments'] : null;
402
        $defaults['allow_new_threads_group']['allow_new_threads'] = isset($inputvalues['allow_new_threads']) ? $inputvalues['allow_new_threads'] : $defaultSettingAllowNewThreads;
403
        $defaults['default_view_type_group']['default_view_type'] = isset($inputvalues['default_view']) ? $inputvalues['default_view'] : null;
404
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
405
        $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
406
    }
407
    $form->setDefaults($defaults);
408
    // Validation or display
409 View Code Duplication
    if ($form->validate()) {
410
        $check = Security::check_token('post');
411
        if ($check) {
412
            $values = $form->getSubmitValues();
413
            $return_message = store_forum($values);
414
            echo Display::return_message($return_message, 'confirmation');
0 ignored issues
show
Security Bug introduced by
It seems like $return_message defined by store_forum($values) on line 413 can also be of type false; however, Display::return_message() 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...
415
        }
416
        Security::clear_token();
417
    } else {
418
        $token = Security::get_token();
419
        $form->addElement('hidden', 'sec_token');
420
        $form->setConstants(array('sec_token' => $token));
421
        $form->display();
422
    }
423
}
424
425
/**
426
 * This function deletes the forum image if exists
427
 *
428
 * @param int forum id
429
 * @return boolean true if success
430
 * @author Julio Montoya <[email protected]>
431
 * @version february 2006, dokeos 1.8
432
 */
433
function delete_forum_image($forum_id)
434
{
435
    $table_forums = Database::get_course_table(TABLE_FORUM);
436
    $course_id = api_get_course_int_id();
437
    $forum_id = intval($forum_id);
438
439
    $sql = "SELECT forum_image FROM $table_forums
440
            WHERE forum_id = $forum_id AND c_id = $course_id";
441
    $result = Database::query($sql);
442
    $row = Database::fetch_array($result);
443
    if ($row['forum_image'] != '') {
444
        $file = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$row['forum_image'];
445
        if (file_exists($file)) {
446
            unlink($file);
447
        }
448
449
        return true;
450
    } else {
451
        return false;
452
    }
453
}
454
455
/**
456
 * This function displays the form that is used to edit a forum category.
457
 * This is more or less a copy from the show_add_forumcategory_form function with the only difference that is uses
458
 * some default values. I tried to have both in one function but this gave problems with the handle_forum_and_forumcategories function
459
 * (storing was done twice)
460
 *
461
 * @param array
462
 * @return void HTML
463
 *
464
 * @author Patrick Cool <[email protected]>, Ghent University
465
 * @version february 2006, dokeos 1.8
466
 */
467
function show_edit_forumcategory_form($inputvalues = array())
468
{
469
    $categoryId = $inputvalues['cat_id'];
470
    $form = new FormValidator('forumcategory', 'post', 'index.php?'.api_get_cidreq().'&id='.$categoryId);
471
472
    // Setting the form elements.
473
    $form->addElement('header', '', get_lang('EditForumCategory'));
474
    $form->addElement('hidden', 'forum_category_id');
475
    $form->addElement('text', 'forum_category_title', get_lang('Title'));
476
477
    $form->addElement(
478
        'html_editor',
479
        'forum_category_comment',
480
        get_lang('Comment'),
481
        null,
482
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
483
    );
484
485
    $form->addButtonUpdate(get_lang('ModifyCategory'), 'SubmitEditForumCategory');
486
487
    // Setting the default values.
488
    $defaultvalues['forum_category_id'] = $inputvalues['cat_id'];
489
    $defaultvalues['forum_category_title'] = $inputvalues['cat_title'];
490
    $defaultvalues['forum_category_comment'] = $inputvalues['cat_comment'];
491
    $form->setDefaults($defaultvalues);
492
493
    // Setting the rules.
494
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
495
496
    // Validation or display
497 View Code Duplication
    if ($form->validate()) {
498
        $check = Security::check_token('post');
499
        if ($check) {
500
            $values = $form->exportValues();
501
            store_forumcategory($values);
502
        }
503
        Security::clear_token();
504
    } else {
505
        $token = Security::get_token();
506
        $form->addElement('hidden', 'sec_token');
507
        $form->setConstants(array('sec_token' => $token));
508
        $form->display();
509
    }
510
}
511
512
/**
513
 * This function stores the forum category in the database.
514
 * The new category is added to the end.
515
 *
516
 * @param array $values
517
 * @param array $courseInfo
518
 * @param bool $showMessage
519
 * @return void HMTL language variable
520
 *
521
 * @author Patrick Cool <[email protected]>, Ghent University
522
 * @version february 2006, dokeos 1.8
523
 */
524
function store_forumcategory($values, $courseInfo = array(), $showMessage = true)
525
{
526
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
527
    $course_id = $courseInfo['real_id'];
528
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
529
530
    // Find the max cat_order. The new forum category is added at the end => max cat_order + &
531
    $sql = "SELECT MAX(cat_order) as sort_max
532
            FROM $table_categories
533
            WHERE c_id = $course_id";
534
    $result = Database::query($sql);
535
    $row = Database::fetch_array($result);
536
    $new_max = $row['sort_max'] + 1;
537
    $session_id = api_get_session_id();
538
    $clean_cat_title = $values['forum_category_title'];
539
    $last_id = null;
540
541
    if (isset($values['forum_category_id'])) {
542
        // Storing after edition.
543
        $params = [
544
            'cat_title' => $clean_cat_title,
545
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
546
        ];
547
548
        Database::update(
549
            $table_categories,
550
            $params,
551
            [
552
                'c_id = ? AND cat_id = ?' => [
553
                    $course_id,
554
                    $values['forum_category_id'],
555
                ],
556
            ]
557
        );
558
559
        api_item_property_update(
560
            $courseInfo,
561
            TOOL_FORUM_CATEGORY,
562
            $values['forum_category_id'],
563
            'ForumCategoryUpdated',
564
            api_get_user_id()
565
        );
566
        $return_message = get_lang('ForumCategoryEdited');
567
    } else {
568
        $params = [
569
            'c_id' => $course_id,
570
            'cat_title' => $clean_cat_title,
571
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
572
            'cat_order' => $new_max,
573
            'session_id' => $session_id,
574
            'locked' => 0,
575
            'cat_id' => 0
576
        ];
577
        $last_id = Database::insert($table_categories, $params);
578
579
        if ($last_id > 0) {
580
            $sql = "UPDATE $table_categories SET cat_id = $last_id WHERE iid = $last_id";
581
            Database::query($sql);
582
583
            api_item_property_update(
584
                $courseInfo,
585
                TOOL_FORUM_CATEGORY,
586
                $last_id,
587
                'ForumCategoryAdded',
588
                api_get_user_id()
589
            );
590
            api_set_default_visibility(
591
                $last_id,
592
                TOOL_FORUM_CATEGORY,
593
                0,
594
                $courseInfo
595
            );
596
        }
597
        $return_message = get_lang('ForumCategoryAdded');
598
    }
599
600
    if ($showMessage) {
601
        echo Display::return_message($return_message, 'confirmation');
602
    }
603
604
    return $last_id;
605
}
606
607
/**
608
 * This function stores the forum in the database. The new forum is added to the end.
609
 *
610
 * @param array $values
611
 * @param array $courseInfo
612
 * @param bool  $returnId
613
 * @return string language variable
614
 *
615
 * @author Patrick Cool <[email protected]>, Ghent University
616
 * @version february 2006, dokeos 1.8
617
 */
618
function store_forum($values, $courseInfo = array(), $returnId = false)
619
{
620
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
621
    $course_id = $courseInfo['real_id'];
622
    $session_id = api_get_session_id();
623
624
    if (isset($values['group_id']) && !empty($values['group_id'])) {
625
        $group_id = $values['group_id'];
626
    } else {
627
        $group_id = api_get_group_id();
628
    }
629
630
    $table_forums = Database::get_course_table(TABLE_FORUM);
631
632
    // Find the max forum_order for the given category. The new forum is added at the end => max cat_order + &
633
    if (is_null($values['forum_category'])) {
634
        $new_max = null;
635
    } else {
636
        $sql = "SELECT MAX(forum_order) as sort_max
637
                FROM $table_forums
638
                WHERE
639
                    c_id = $course_id AND
640
                    forum_category='".Database::escape_string($values['forum_category'])."'";
641
        $result = Database::query($sql);
642
        $row = Database::fetch_array($result);
643
        $new_max = $row['sort_max'] + 1;
644
    }
645
646
    // Forum images
647
    $image_moved = false;
648
    $has_attachment = false;
649
    if (!empty($_FILES['picture']['name'])) {
650
        $upload_ok = process_uploaded_file($_FILES['picture']);
651
        $has_attachment = true;
652
    } else {
653
        $image_moved = true;
654
    }
655
656
    // Remove existing picture if it was requested.
657
    if (!empty($_POST['remove_picture'])) {
658
        delete_forum_image($values['forum_id']);
659
    }
660
661
    $new_file_name = '';
662
    if (isset($upload_ok)) {
663
        if ($has_attachment) {
664
            $course_dir = $courseInfo['path'].'/upload/forum/images';
665
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
666
            $updir = $sys_course_path.$course_dir;
667
            // Try to add an extension to the file if it hasn't one.
668
            $new_file_name = add_ext_on_mime(
669
                Database::escape_string($_FILES['picture']['name']),
670
                $_FILES['picture']['type']
671
            );
672
            if (!filter_extension($new_file_name)) {
673
                //Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error'));
674
                $image_moved = false;
675
            } else {
676
                $file_extension = explode('.', $_FILES['picture']['name']);
677
                $file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
678
                $new_file_name = uniqid('').'.'.$file_extension;
679
                $new_path = $updir.'/'.$new_file_name;
680
                $result = @move_uploaded_file($_FILES['picture']['tmp_name'], $new_path);
681
                // Storing the attachments if any
682
                if ($result) {
683
                    $image_moved = true;
684
                }
685
            }
686
        }
687
    }
688
689
    if (isset($values['forum_id'])) {
690
        // Storing after edition.
691
        $params = [
692
            'forum_title'=> $values['forum_title'],
693
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
694
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
695
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
696
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
697
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
698
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
699
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
700
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
701
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
702
            '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,
703
            'moderated'=> $values['moderated']['moderated'],
704
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
705
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
706
            'session_id'=> $session_id,
707
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0
708
        ];
709
710
        if (isset($upload_ok)) {
711
            if ($has_attachment) {
712
                $params['forum_image'] = $new_file_name;
713
            }
714
        }
715
716
        if (isset($values['remove_picture']) && $values['remove_picture'] == 1) {
717
            $params['forum_image'] = '';
718
            delete_forum_image($values['forum_id']);
719
        }
720
721
        Database::update(
722
            $table_forums,
723
            $params,
724
            ['c_id = ? AND forum_id = ?' => [$course_id, $values['forum_id']]]
725
        );
726
727
        api_item_property_update(
728
            $courseInfo,
729
            TOOL_FORUM,
730
            Database::escape_string($values['forum_id']),
731
            'ForumUpdated',
732
            api_get_user_id(),
733
            $group_id
734
        );
735
736
        $return_message = get_lang('ForumEdited');
737
    } else {
738
        if ($image_moved) {
739
            $new_file_name = isset($new_file_name) ? $new_file_name : '';
740
        }
741
        $params = [
742
            'c_id' => $course_id,
743
            'forum_title'=> $values['forum_title'],
744
            'forum_image'=> $new_file_name,
745
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
746
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
747
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
748
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
749
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
750
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
751
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
752
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
753
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
754
            '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,
755
            'moderated'=> isset($values['moderated']['moderated']) ? (int) $values['moderated']['moderated'] : 0,
756
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
757
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
758
            'forum_order'=> isset($new_max) ? $new_max : null,
759
            'session_id'=> $session_id,
760
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0,
761
            'locked' => 0,
762
            'forum_id' => 0
763
        ];
764
765
        $last_id = Database::insert($table_forums, $params);
766 View Code Duplication
        if ($last_id > 0) {
767
            $sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $last_id";
768
            Database::query($sql);
769
770
            api_item_property_update(
771
                $courseInfo,
772
                TOOL_FORUM,
773
                $last_id,
774
                'ForumAdded',
775
                api_get_user_id(),
776
                $group_id
777
            );
778
779
            api_set_default_visibility(
780
                $last_id,
781
                TOOL_FORUM,
782
                $group_id,
783
                $courseInfo
784
            );
785
        }
786
        $return_message = get_lang('ForumAdded');
787
        if ($returnId) {
788
            return $last_id;
789
        }
790
    }
791
792
    return $return_message;
793
}
794
795
/**
796
 * This function deletes a forum or a forum category
797
 * This function currently does not delete the forums inside the category,
798
 * nor the threads and replies inside these forums.
799
 * For the moment this is the easiest method and it has the advantage that it
800
 * allows to recover fora that were acidently deleted
801
 * when the forum category got deleted.
802
 *
803
 * @param $content = what we are deleting (a forum or a forum category)
804
 * @param $id The id of the forum category that has to be deleted.
805
 *
806
 * @todo write the code for the cascading deletion of the forums inside a
807
 * forum category and also the threads and replies inside these forums
808
 * @todo config setting for recovery or not
809
 * (see also the documents tool: real delete or not).
810
 * @return string
811
 * @author Patrick Cool <[email protected]>, Ghent University
812
 * @version february 2006, dokeos 1.8
813
 */
814
function deleteForumCategoryThread($content, $id)
815
{
816
    $_course = api_get_course_info();
817
    $table_forums = Database::get_course_table(TABLE_FORUM);
818
    $table_forums_post = Database::get_course_table(TABLE_FORUM_POST);
819
    $table_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
820
    $course_id = api_get_course_int_id();
821
    $groupId = api_get_group_id();
822
    $userId = api_get_user_id();
823
    $id = intval($id);
824
825
    // Delete all attachment file about this tread id.
826
    $sql = "SELECT post_id FROM $table_forums_post
827
            WHERE c_id = $course_id AND thread_id = '".$id."' ";
828
    $res = Database::query($sql);
829
    while ($poster_id = Database::fetch_row($res)) {
830
        delete_attachment($poster_id[0]);
831
    }
832
833
    $tool_constant = null;
834
    $return_message = '';
835
836 View Code Duplication
    if ($content == 'forumcategory') {
837
        $tool_constant = TOOL_FORUM_CATEGORY;
838
        $return_message = get_lang('ForumCategoryDeleted');
839
840
        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...
841
            $sql = "SELECT forum_id FROM $table_forums
842
                    WHERE c_id = $course_id AND forum_category='".$id."'";
843
            $result = Database::query($sql);
844
            $row = Database::fetch_array($result);
845
            foreach ($row as $arr_forum) {
846
                $forum_id = $arr_forum['forum_id'];
847
                api_item_property_update(
848
                    $_course,
849
                    'forum',
850
                    $forum_id,
851
                    'delete',
852
                    api_get_user_id()
853
                );
854
            }
855
        }
856
    }
857
858 View Code Duplication
    if ($content == 'forum') {
859
        $tool_constant = TOOL_FORUM;
860
        $return_message = get_lang('ForumDeleted');
861
862
        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...
863
            $sql = "SELECT thread_id FROM $table_forum_thread
864
                    WHERE c_id = $course_id AND forum_id = $id ";
865
            $result = Database::query($sql);
866
            $row = Database::fetch_array($result);
867
            foreach ($row as $arr_forum) {
868
                $forum_id = $arr_forum['thread_id'];
869
                api_item_property_update(
870
                    $_course,
871
                    'forum_thread',
872
                    $forum_id,
873
                    'delete',
874
                    api_get_user_id()
875
                );
876
            }
877
        }
878
    }
879
880
    if ($content == 'thread') {
881
        $tool_constant = TOOL_FORUM_THREAD;
882
        $return_message = get_lang('ThreadDeleted');
883
    }
884
885
    api_item_property_update(
886
        $_course,
887
        $tool_constant,
888
        $id,
889
        'delete',
890
        $userId,
891
        $groupId
892
    );
893
894
    // Check if this returns a true and if so => return $return_message, if not => return false;
895
    return $return_message;
896
}
897
898
/**
899
 * This function deletes a forum post. This separate function is needed because forum posts do not appear in the item_property table (yet)
900
 * and because deleting a post also has consequence on the posts that have this post as parent_id (they are also deleted).
901
 * an alternative would be to store the posts also in item_property and mark this post as deleted (visibility = 2).
902
 * We also have to decrease the number of replies in the thread table
903
 *
904
 * @param $post_id the id of the post that will be deleted
905
 * @todo write recursive function that deletes all the posts that have this message as parent
906
 * @return string language variable
907
 * @author Patrick Cool <[email protected]>, Ghent University
908
 * @author Hubert Borderiou Function cleanead and fixed
909
 * @version february 2006
910
 */
911
function delete_post($post_id)
912
{
913
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
914
    $post_id = intval($post_id);
915
    $course_id = api_get_course_int_id();
916
    $em = Database::getManager();
917
918
    $post = $em
919
        ->getRepository('ChamiloCourseBundle:CForumPost')
920
        ->findOneBy(['cId' => $course_id, 'postId' => $post_id]);
921
922
    if ($post) {
923
        $em
924
            ->createQuery('
925
                UPDATE ChamiloCourseBundle:CForumPost p
926
                SET p.postParentId = :parent_of_deleted_post
927
                WHERE
928
                    p.cId = :course AND
929
                    p.postParentId = :post AND
930
                    p.threadId = :thread_of_deleted_post AND
931
                    p.forumId = :forum_of_deleted_post
932
            ')
933
            ->execute([
934
                'parent_of_deleted_post' => $post->getPostParentId(),
935
                'course' => $course_id,
936
                'post' => $post->getPostId(),
937
                'thread_of_deleted_post' => $post->getThreadId(),
938
                'forum_of_deleted_post' => $post->getForumId()
939
            ]);
940
941
        $em->remove($post);
942
        $em->flush();
943
944
        // Delete attachment file about this post id.
945
        delete_attachment($post_id);
946
    }
947
948
    $last_post_of_thread = check_if_last_post_of_thread($_GET['thread']);
949
950
    if (is_array($last_post_of_thread)) {
951
        // Decreasing the number of replies for this thread and also changing the last post information.
952
        $sql = "UPDATE $table_threads
953
                SET
954
                    thread_replies = thread_replies - 1,
955
                    thread_last_post = ".intval($last_post_of_thread['post_id']).",
956
                    thread_date='".Database::escape_string($last_post_of_thread['post_date'])."'
957
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
958
        Database::query($sql);
959
960
        return 'PostDeleted';
961
    }
962
    if (!$last_post_of_thread) {
963
        // We deleted the very single post of the thread so we need to delete the entry in the thread table also.
964
        $sql = "DELETE FROM $table_threads
965
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
966
        Database::query($sql);
967
968
        return 'PostDeletedSpecial';
969
    }
970
}
971
972
/**
973
 * This function gets the all information of the last (=most recent) post of the thread
974
 * This can be done by sorting the posts that have the field thread_id=$thread_id and sort them by post_date
975
 *
976
 * @param $thread_id the id of the thread we want to know the last post of.
977
 * @return an array or bool if there is a last post found, false if there is
978
 * no post entry linked to that thread => thread will be deleted
979
 *
980
 * @author Patrick Cool <[email protected]>, Ghent University
981
 * @version february 2006, dokeos 1.8
982
 */
983 View Code Duplication
function check_if_last_post_of_thread($thread_id)
984
{
985
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
986
    $course_id = api_get_course_int_id();
987
    $sql = "SELECT * FROM $table_posts
988
            WHERE c_id = $course_id AND thread_id = ".intval($thread_id)."
989
            ORDER BY post_date DESC";
990
    $result = Database::query($sql);
991
    if (Database::num_rows($result) > 0) {
992
        $row = Database::fetch_array($result);
993
994
        return $row;
995
    } else {
996
        return false;
997
    }
998
}
999
1000
/**
1001
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1002
 * @param $id the id of the content we want to make invisible
1003
 * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
1004
 * @param array $additional_url_parameters
1005
 *
1006
 * @return string HTML
1007
 */
1008
function return_visible_invisible_icon($content, $id, $current_visibility_status, $additional_url_parameters = '')
1009
{
1010
    $html = '';
1011
    $id = Security::remove_XSS($id);
1012 View Code Duplication
    if ($current_visibility_status == '1') {
1013
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1014
        if (is_array($additional_url_parameters)) {
1015
            foreach ($additional_url_parameters as $key => $value) {
1016
                $html .= $key . '=' . $value . '&';
1017
            }
1018
        }
1019
        $html.='action=invisible&content='.$content.'&id='.$id.'">'.
1020
            Display::return_icon('visible.png', get_lang('MakeInvisible'), array(), ICON_SIZE_SMALL).'</a>';
1021
    }
1022 View Code Duplication
    if ($current_visibility_status == '0') {
1023
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1024
        if (is_array($additional_url_parameters)) {
1025
            foreach ($additional_url_parameters as $key => $value) {
1026
                $html .= $key . '=' . $value . '&';
1027
            }
1028
        }
1029
        $html .= 'action=visible&content=' . $content . '&id=' . $id . '">' .
1030
            Display::return_icon('invisible.png', get_lang('MakeVisible'), array(), ICON_SIZE_SMALL) . '</a>';
1031
    }
1032
    return $html;
1033
}
1034
1035
/**
1036
 * @param $content
1037
 * @param $id
1038
 * @param $current_lock_status
1039
 * @param string $additional_url_parameters
1040
 * @return string
1041
 */
1042
function return_lock_unlock_icon($content, $id, $current_lock_status, $additional_url_parameters = '')
1043
{
1044
    $html = '';
1045
    $id = intval($id);
1046
    //check if the forum is blocked due
1047
    if ($content == 'thread') {
1048
        if (api_resource_is_locked_by_gradebook($id, LINK_FORUM_THREAD)) {
1049
            $html .= Display::return_icon('lock_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
1050
1051
            return $html;
1052
        }
1053
    }
1054 View Code Duplication
    if ($current_lock_status == '1') {
1055
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1056
        if (is_array($additional_url_parameters)) {
1057
            foreach ($additional_url_parameters as $key => $value) {
1058
                $html .= $key . '=' . $value . '&';
1059
            }
1060
        }
1061
        $html.= 'action=unlock&content='.$content.'&id='.$id.'">'.
1062
            Display::return_icon('lock.png', get_lang('Unlock'), array(), ICON_SIZE_SMALL).'</a>';
1063
    }
1064 View Code Duplication
    if ($current_lock_status == '0') {
1065
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1066
        if (is_array($additional_url_parameters)) {
1067
            foreach ($additional_url_parameters as $key => $value) {
1068
                $html .= $key . '=' . $value . '&';
1069
            }
1070
        }
1071
        $html .= 'action=lock&content=' . $content . '&id=' . $id . '">' .
1072
            Display::return_icon('unlock.png', get_lang('Lock'), array(), ICON_SIZE_SMALL) . '</a>';
1073
    }
1074
1075
    return $html;
1076
}
1077
1078
/**
1079
 * This function takes care of the display of the up and down icon
1080
 *
1081
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1082
 * @param $id is the id of the item we want to display the icons for
1083
 * @param $list is an array of all the items. All items in this list should have
1084
 * an up and down icon except for the first (no up icon) and the last (no down icon)
1085
 *          The key of this $list array is the id of the item.
1086
 *
1087
 * @return string HTML
1088
 **/
1089
function return_up_down_icon($content, $id, $list)
1090
{
1091
    $id = strval(intval($id));
1092
    $total_items = count($list);
1093
    $position = 0;
1094
    $internal_counter = 0;
1095
    $forumCategory = isset($_GET['forumcategory']) ? Security::remove_XSS($_GET['forumcategory']) : null;
1096
1097
    if (is_array($list)) {
1098
        foreach ($list as $key => $listitem) {
1099
            $internal_counter++;
1100
            if ($id == $key) {
1101
                $position = $internal_counter;
1102
            }
1103
        }
1104
    }
1105
1106
    if ($position > 1) {
1107
        $return_value = '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=up&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveUp').'">'.
1108
            Display::return_icon('up.png', get_lang('MoveUp'), array(), ICON_SIZE_SMALL).'</a>';
1109
    } else {
1110
        $return_value = Display::return_icon('up_na.png', '-', array(), ICON_SIZE_SMALL);
1111
    }
1112
1113
    if ($position < $total_items) {
1114
        $return_value .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=down&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveDown').'" >'.
1115
            Display::return_icon('down.png', get_lang('MoveDown'), array(), ICON_SIZE_SMALL).'</a>';
1116
    } else {
1117
        $return_value .= Display::return_icon('down_na.png', '-', array(), ICON_SIZE_SMALL);
1118
    }
1119
    return $return_value;
1120
}
1121
1122
/**
1123
 * This function changes the visibility in the database (item_property)
1124
 *
1125
 * @param string $content what is it that we want to make (in)visible: forum category, forum, thread, post
1126
 * @param int $id the id of the content we want to make invisible
1127
 * @param string $target_visibility what is the current status of the visibility (0 = invisible, 1 = visible)
1128
 *
1129
 * @todo change the get parameter so that it matches the tool constants.
1130
 * @todo check if api_item_property_update returns true or false => returnmessage depends on it.
1131
 * @todo move to itemmanager
1132
 *
1133
 * @return string language variable
1134
 *
1135
 * @author Patrick Cool <[email protected]>, Ghent University
1136
 * @version february 2006, dokeos 1.8
1137
 */
1138
function change_visibility($content, $id, $target_visibility)
1139
{
1140
    $_course = api_get_course_info();
1141
    $constants = array(
1142
        'forumcategory' => TOOL_FORUM_CATEGORY,
1143
        'forum' => TOOL_FORUM,
1144
        'thread' => TOOL_FORUM_THREAD,
1145
    );
1146
    api_item_property_update(
1147
        $_course,
1148
        $constants[$content],
1149
        $id,
1150
        $target_visibility,
1151
        api_get_user_id()
1152
    );
1153
1154
    if ($target_visibility == 'visible') {
1155
        handle_mail_cue($content, $id);
1156
    }
1157
    return get_lang('VisibilityChanged');
1158
}
1159
1160
/**
1161
 * This function changes the lock status in the database
1162
 *
1163
 * @param string $content what is it that we want to (un)lock: forum category, forum, thread, post
1164
 * @param int $id the id of the content we want to (un)lock
1165
 * @param string $action do we lock (=>locked value in db = 1) or unlock (=> locked value in db = 0)
1166
 * @return string language variable
1167
 *
1168
 * @todo move to item manager
1169
 *
1170
 * @author Patrick Cool <[email protected]>, Ghent University
1171
 * @version february 2006, dokeos 1.8
1172
 */
1173
function change_lock_status($content, $id, $action)
1174
{
1175
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
1176
    $table_forums = Database::get_course_table(TABLE_FORUM);
1177
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1178
1179
    // Determine the relevant table.
1180
    if ($content == 'forumcategory') {
1181
        $table = $table_categories;
1182
        $id_field = 'cat_id';
1183
    } elseif ($content == 'forum') {
1184
        $table = $table_forums;
1185
        $id_field = 'forum_id';
1186
    } elseif ($content == 'thread') {
1187
        $table = $table_threads;
1188
        $id_field = 'thread_id';
1189
    } else {
1190
        return get_lang('Error');
1191
    }
1192
1193
    // Determine what we are doing => defines the value for the database and the return message.
1194
    if ($action == 'lock') {
1195
        $db_locked = 1;
1196
        $return_message = get_lang('Locked');
1197
    } elseif ($action == 'unlock') {
1198
        $db_locked = 0;
1199
        $return_message = get_lang('Unlocked');
1200
    } else {
1201
        return get_lang('Error');
1202
    }
1203
1204
    $course_id = api_get_course_int_id();
1205
1206
    // Doing the change in the database
1207
    $sql = "UPDATE $table SET locked='".Database::escape_string($db_locked)."'
1208
            WHERE c_id = $course_id AND $id_field='".Database::escape_string($id)."'";
1209
    if (Database::query($sql)) {
1210
        return $return_message;
1211
    } else {
1212
        return get_lang('Error');
1213
    }
1214
}
1215
1216
/**
1217
 * This function moves a forum or a forum category up or down
1218
 *
1219
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1220
 * @param $direction do we want to move it up or down.
1221
 * @param $id the id of the content we want to make invisible
1222
 * @todo consider removing the table_item_property calls here but this can
1223
 * prevent unwanted side effects when a forum does not have an entry in
1224
 * the item_property table but does have one in the forum table.
1225
 * @return string language variable
1226
 *
1227
 * @author Patrick Cool <[email protected]>, Ghent University
1228
 * @version february 2006, dokeos 1.8
1229
 */
1230
function move_up_down($content, $direction, $id)
1231
{
1232
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
1233
    $table_forums = Database::get_course_table(TABLE_FORUM);
1234
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1235
    $course_id = api_get_course_int_id();
1236
    $id = intval($id);
1237
1238
    // Determine which field holds the sort order.
1239
    if ($content == 'forumcategory') {
1240
        $table = $table_categories;
1241
        $sort_column = 'cat_order';
1242
        $id_column = 'cat_id';
1243
        $sort_column = 'cat_order';
1244
    } elseif ($content == 'forum') {
1245
        $table = $table_forums;
1246
        $sort_column = 'forum_order';
1247
        $id_column = 'forum_id';
1248
        $sort_column = 'forum_order';
1249
        // We also need the forum_category of this forum.
1250
        $sql = "SELECT forum_category FROM $table_forums
1251
                WHERE c_id = $course_id AND forum_id = " . intval($id);
1252
        $result = Database::query($sql);
1253
        $row = Database::fetch_array($result);
1254
        $forum_category = $row['forum_category'];
1255
    } else {
1256
        return get_lang('Error');
1257
    }
1258
1259
    // Determine the need for sorting ascending or descending order.
1260
    if ($direction == 'down') {
1261
        $sort_direction = 'ASC';
1262
    } elseif ($direction == 'up') {
1263
        $sort_direction = 'DESC';
1264
    } else {
1265
        return get_lang('Error');
1266
    }
1267
1268
    // The SQL statement
1269
    if ($content == 'forumcategory') {
1270
        $sql = "SELECT *
1271
                FROM $table_categories forum_categories, $table_item_property item_properties
1272
                WHERE
1273
                    forum_categories.c_id = $course_id AND
1274
                    item_properties.c_id = $course_id AND
1275
                    forum_categories.cat_id=item_properties.ref AND
1276
                    item_properties.tool='" . TOOL_FORUM_CATEGORY . "'
1277
                ORDER BY forum_categories.cat_order $sort_direction";
1278
    }
1279
    if ($content == 'forum') {
1280
        $sql = "SELECT *
1281
            FROM $table
1282
            WHERE
1283
                c_id = $course_id AND
1284
                forum_category='" . Database::escape_string($forum_category) . "'
1285
            ORDER BY forum_order $sort_direction";
1286
    }
1287
    // Finding the items that need to be switched.
1288
    $result = Database::query($sql);
1289
    $found = false;
1290
    while ($row = Database::fetch_array($result)) {
1291
        //echo $row[$id_column].'-';
1292
        if ($found) {
1293
            $next_id = $row[$id_column];
1294
            $next_sort = $row[$sort_column];
1295
            $found = false;
1296
        }
1297
        if ($id == $row[$id_column]) {
1298
            $this_id = $id;
1299
            $this_sort = $row[$sort_column];
1300
            $found = true;
1301
        }
1302
    }
1303
1304
    // Committing the switch.
1305
    // We do an extra check if we do not have illegal values. If your remove this if statment you will
1306
    // be able to mess with the sorting by refreshing the page over and over again.
1307
    if ($this_sort != '' && $next_sort != '' && $next_id != '' && $this_id != '') {
1308
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($this_sort) . "'
1309
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($next_id) . "'";
1310
        Database::query($sql);
1311
1312
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($next_sort) . "'
1313
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($this_id) . "'";
1314
        Database::query($sql);
1315
    }
1316
1317
    return get_lang(ucfirst($content) . 'Moved');
1318
}
1319
1320
/**
1321
 * Retrieve all the information off the forum categories (or one specific) for the current course.
1322
 * The categories are sorted according to their sorting order (cat_order
1323
 *
1324
 * @param int|string $id default ''. When an id is passed we only find the information
1325
 * about that specific forum category. If no id is passed we get all the forum categories.
1326
 * @param int $courseId Optional. The course ID
1327
 * @param int $sessionId Optional. The session ID
1328
 * @return array containing all the information about all the forum categories
1329
 *
1330
 * @author Patrick Cool <[email protected]>, Ghent University
1331
 * @version february 2006, dokeos 1.8
1332
 */
1333
function get_forum_categories($id = '', $courseId = 0, $sessionId = 0)
1334
{
1335
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
1336
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1337
1338
    // Condition for the session
1339
    $session_id = $sessionId ?: api_get_session_id();
1340
    $course_id = $courseId ?: api_get_course_int_id();
1341
1342
    $condition_session = api_get_session_condition($session_id, true, true, 'forum_categories.session_id');
1343
    $condition_session .= " AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id";
1344
1345
    if (empty($id)) {
1346
        $sql = "SELECT *
1347
                FROM $table_item_property item_properties 
1348
                INNER JOIN $table_categories forum_categories
1349
                ON (
1350
                    forum_categories.cat_id = item_properties.ref AND 
1351
                    item_properties.c_id = forum_categories.c_id
1352
                )
1353
                WHERE                    
1354
                    item_properties.visibility = 1 AND
1355
                    item_properties.tool = '".TOOL_FORUM_CATEGORY."'
1356
                    $condition_session
1357
                ORDER BY forum_categories.cat_order ASC";
1358
        if (api_is_allowed_to_edit()) {
1359
            $sql = "SELECT *
1360
                    FROM $table_item_property item_properties  
1361
                    INNER JOIN $table_categories forum_categories
1362
                    ON (
1363
                        forum_categories.cat_id = item_properties.ref AND 
1364
                        item_properties.c_id = forum_categories.c_id
1365
                    )
1366
                    WHERE                        
1367
                        item_properties.visibility<>2 AND
1368
                        item_properties.tool='".TOOL_FORUM_CATEGORY."'
1369
                        $condition_session
1370
                    ORDER BY forum_categories.cat_order ASC";
1371
        }
1372
    } else {
1373
        $sql = "SELECT *
1374
                FROM $table_item_property item_properties 
1375
                INNER JOIN $table_categories forum_categories
1376
                ON (
1377
                    forum_categories.cat_id = item_properties.ref AND 
1378
                    item_properties.c_id = forum_categories.c_id
1379
                )
1380
                WHERE                    
1381
                    item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
1382
                    forum_categories.cat_id = ".intval($id)."
1383
                    $condition_session
1384
                ORDER BY forum_categories.cat_order ASC";
1385
    }
1386
    $result = Database::query($sql);
1387
    $forum_categories_list = array();
1388
    while ($row = Database::fetch_assoc($result)) {
1389
        if (empty($id)) {
1390
            $forum_categories_list[$row['cat_id']] = $row;
1391
        } else {
1392
            $forum_categories_list = $row;
1393
        }
1394
    }
1395
1396
    return $forum_categories_list;
1397
}
1398
1399
/**
1400
 * This function retrieves all the fora in a given forum category
1401
 *
1402
 * @param int $cat_id the id of the forum category
1403
 * @param int $courseId Optional. The course ID
1404
 * @return array containing all the information about the forums (regardless of their category)
1405
 *
1406
 * @author Patrick Cool <[email protected]>, Ghent University
1407
 * @version february 2006, dokeos 1.8
1408
 */
1409
function get_forums_in_category($cat_id, $courseId = 0)
1410
{
1411
    $table_forums = Database::get_course_table(TABLE_FORUM);
1412
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1413
1414
    $forum_list = array();
1415
    $course_id = $courseId ?: api_get_course_int_id();
1416
    $cat_id = (int) $cat_id;
1417
1418
    $sql = "SELECT * FROM $table_forums forum 
1419
            INNER JOIN $table_item_property item_properties
1420
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1421
            WHERE
1422
                forum.forum_category = '".$cat_id."' AND                
1423
                item_properties.visibility = 1 AND
1424
                forum.c_id = $course_id AND
1425
                item_properties.c_id = $course_id AND
1426
                item_properties.tool = '".TOOL_FORUM."'                 
1427
            ORDER BY forum.forum_order ASC";
1428
    if (api_is_allowed_to_edit()) {
1429
        $sql = "SELECT * FROM $table_forums forum  
1430
                INNER JOIN $table_item_property item_properties
1431
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1432
                WHERE
1433
                    forum.forum_category = '".$cat_id."' AND                    
1434
                    item_properties.visibility <> 2 AND
1435
                    item_properties.tool = '".TOOL_FORUM."' AND
1436
                    item_properties.c_id = $course_id AND
1437
                    forum.c_id = $course_id
1438
                ORDER BY forum_order ASC";
1439
    }
1440
    $result = Database::query($sql);
1441
    while ($row = Database::fetch_array($result)) {
1442
        $forum_list[$row['forum_id']] = $row;
1443
    }
1444
1445
    return $forum_list;
1446
}
1447
1448
/**
1449
 * Retrieve all the forums (regardless of their category) or of only one.
1450
 * The forums are sorted according to the forum_order.
1451
 * Since it does not take the forum category into account there probably
1452
 * will be two or more forums that have forum_order=1, ...
1453
 * @param int $id forum id
1454
 * @param string $course_code
1455
 * @param bool $includeGroupsForum
1456
 * @param int $sessionId
1457
 * @return array an array containing all the information about the forums (regardless of their category)
1458
 * @todo check $sql4 because this one really looks fishy.
1459
 *
1460
 * @author Patrick Cool <[email protected]>, Ghent University
1461
 * @version february 2006, dokeos 1.8
1462
 */
1463
function get_forums(
1464
    $id = '',
1465
    $course_code = '',
1466
    $includeGroupsForum = true,
1467
    $sessionId = 0
1468
) {
1469
    $course_info = api_get_course_info($course_code);
1470
1471
    $table_forums = Database::get_course_table(TABLE_FORUM);
1472
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1473
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1474
1475
    // Condition for the session
1476
    $session_id = intval($sessionId) ?: api_get_session_id();
1477
    $sessionIdLink = $session_id === 0 ? '' : ' AND threads.session_id = item_properties.session_id';
1478
1479
    $condition_session = api_get_session_condition(
1480
        $session_id,
1481
        true,
1482
        false,
1483
        'item_properties.session_id'
1484
    );
1485
1486
    $course_id = $course_info['real_id'];
1487
1488
    $forum_list = array();
1489
    $includeGroupsForumSelect = '';
1490
    if (!$includeGroupsForum) {
1491
        $includeGroupsForumSelect = " AND forum_of_group = 0 ";
1492
    }
1493
1494
    if ($id == '') {
1495
        // Student
1496
        // Select all the forum information of all forums (that are visible to students).
1497
        $sql = "SELECT item_properties.*, forum.* 
1498
                FROM $table_forums forum
1499
                INNER JOIN $table_item_property item_properties
1500
                ON (
1501
                    forum.forum_id = item_properties.ref AND
1502
                    forum.c_id = item_properties.c_id
1503
                )
1504
                WHERE
1505
                    item_properties.visibility = 1 AND
1506
                    item_properties.tool = '".TOOL_FORUM."'
1507
                    $condition_session AND
1508
                    forum.c_id = $course_id AND
1509
                    item_properties.c_id = $course_id
1510
                    $includeGroupsForumSelect
1511
                ORDER BY forum.forum_order ASC";
1512
1513
        // Select the number of threads of the forums (only the threads that are visible).
1514
        $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1515
                FROM $table_threads threads
1516
                INNER JOIN $table_item_property item_properties
1517
                ON (
1518
                    threads.thread_id = item_properties.ref AND
1519
                    threads.c_id = item_properties.c_id
1520
                    $sessionIdLink
1521
                )
1522
                WHERE
1523
                    item_properties.visibility=1 AND
1524
                    item_properties.tool='".TOOL_FORUM_THREAD."' AND
1525
                    threads.c_id = $course_id AND
1526
                    item_properties.c_id = $course_id
1527
                GROUP BY threads.forum_id";
1528
1529
        // Course Admin
1530 View Code Duplication
        if (api_is_allowed_to_edit()) {
1531
            // Select all the forum information of all forums (that are not deleted).
1532
            $sql = "SELECT item_properties.*, forum.* 
1533
                    FROM $table_forums forum
1534
                    INNER JOIN $table_item_property item_properties
1535
                    ON (
1536
                        forum.forum_id = item_properties.ref AND
1537
                        forum.c_id = item_properties.c_id
1538
                    )
1539
                    WHERE
1540
                        item_properties.visibility <> 2 AND
1541
                        item_properties.tool = '".TOOL_FORUM."'
1542
                        $condition_session AND
1543
                        forum.c_id = $course_id AND
1544
                        item_properties.c_id = $course_id
1545
                        $includeGroupsForumSelect
1546
                    ORDER BY forum_order ASC";
1547
1548
            // Select the number of threads of the forums (only the threads that are not deleted).
1549
            $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1550
                    FROM $table_threads threads
1551
                    INNER JOIN $table_item_property item_properties
1552
                    ON (
1553
                        threads.thread_id = item_properties.ref AND
1554
                        threads.c_id = item_properties.c_id
1555
                        $sessionIdLink
1556
                    )
1557
                    WHERE
1558
                        item_properties.visibility<>2 AND
1559
                        item_properties.tool='".TOOL_FORUM_THREAD."' AND
1560
                        threads.c_id = $course_id AND
1561
                        item_properties.c_id = $course_id
1562
                    GROUP BY threads.forum_id";
1563
        }
1564
    } else {
1565
        // GETTING ONE SPECIFIC FORUM
1566
        /* We could do the splitup into student and course admin also but we want
1567
        to have as much as information about a certain forum as possible
1568
        so we do not take too much information into account. This function
1569
         (or this section of the function) is namely used to fill the forms
1570
        when editing a forum (and for the moment it is the only place where
1571
        we use this part of the function) */
1572
1573
        // Select all the forum information of the given forum (that is not deleted).
1574
        $sql = "SELECT * FROM $table_item_property item_properties 
1575
                INNER JOIN $table_forums forum
1576
                ON (forum.forum_id = item_properties.ref AND forum.c_id = item_properties.c_id)
1577
                WHERE
1578
                    forum.forum_id = " . intval($id) . " AND
1579
                    forum.c_id = $course_id AND
1580
                    item_properties.visibility != 2 AND
1581
                    item_properties.tool = '".TOOL_FORUM."'
1582
                ORDER BY forum_order ASC";
1583
1584
        // Select the number of threads of the forum.
1585
        $sql2 = "SELECT count(*) AS number_of_threads, forum_id
1586
                FROM $table_threads
1587
                WHERE
1588
                    forum_id = " . intval($id) . "
1589
                GROUP BY forum_id";
1590
    }
1591
1592
    // Handling all the forum information.
1593
    $result = Database::query($sql);
1594
    while ($row = Database::fetch_assoc($result)) {
1595
        if ($id == '') {
1596
            $forum_list[$row['forum_id']] = $row;
1597
        } else {
1598
            $forum_list = $row;
1599
        }
1600
    }
1601
1602
    // Handling the thread count information.
1603
    $result2 = Database::query($sql2);
1604
    while ($row2 = Database::fetch_array($result2)) {
1605
        if ($id == '') {
1606
            $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
1607
        } else {
1608
            $forum_list['number_of_threads'] = $row2['number_of_threads'];
1609
        }
1610
    }
1611
1612
    /* Finding the last post information
1613
    (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)*/
1614
    if ($id == '') {
1615
        if (is_array($forum_list)) {
1616 View Code Duplication
            foreach ($forum_list as $key => $value) {
1617
                $last_post_info_of_forum = get_last_post_information(
1618
                    $key,
1619
                    api_is_allowed_to_edit(),
1620
                    $course_id
1621
                );
1622
1623
                if ($last_post_info_of_forum) {
1624
                    $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1625
                    $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1626
                    $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1627
                    $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1628
                    $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1629
                    $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1630
                }
1631
            }
1632
        } else {
1633
            $forum_list = array();
1634
        }
1635
    } else {
1636
        $last_post_info_of_forum = get_last_post_information(
1637
            $id,
1638
            api_is_allowed_to_edit(),
1639
            $course_id
1640
        );
1641
        if ($last_post_info_of_forum) {
1642
            $forum_list['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1643
            $forum_list['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1644
            $forum_list['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1645
            $forum_list['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1646
            $forum_list['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1647
            $forum_list['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1648
        }
1649
    }
1650
1651
    return $forum_list;
1652
}
1653
1654
/**
1655
 * @param int $course_id
1656
 * @param int $thread_id
1657
 * @param int $forum_id
1658
 * @param bool $show_visible
1659
 * @return array|bool
1660
 */
1661
function get_last_post_by_thread($course_id, $thread_id, $forum_id, $show_visible = true)
1662
{
1663
    if (empty($thread_id) || empty($forum_id) || empty($course_id)) {
1664
        return false;
1665
    }
1666
1667
    $thread_id = intval($thread_id);
1668
    $forum_id = intval($forum_id);
1669
    $course_id = intval($course_id);
1670
1671
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
1672
    $sql = "SELECT * FROM $table_posts
1673
            WHERE 
1674
                c_id = $course_id AND 
1675
                thread_id = $thread_id AND 
1676
                forum_id = $forum_id";
1677
1678
    if ($show_visible == false) {
1679
        $sql .= " AND visible = 1 ";
1680
    }
1681
1682
    $sql .= " ORDER BY post_id DESC LIMIT 1";
1683
    $result = Database::query($sql);
1684
    if (Database::num_rows($result)) {
1685
        return Database::fetch_array($result, 'ASSOC');
1686
    } else {
1687
        return false;
1688
    }
1689
}
1690
1691
/**
1692
 * This function gets all the last post information of a certain forum
1693
 *
1694
 * @param int   $forum_id the id of the forum we want to know the last post information of.
1695
 * @param bool  $show_invisibles
1696
 * @param string course db name
1697
 * @return array containing all the information about the last post
1698
 * (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)
1699
 *
1700
 * @author Patrick Cool <[email protected]>, Ghent University
1701
 * @version february 2006, dokeos 1.8
1702
 */
1703
function get_last_post_information($forum_id, $show_invisibles = false, $course_id = null)
1704
{
1705
    if (!isset($course_id)) {
1706
        $course_id = api_get_course_int_id();
1707
    } else {
1708
        $course_id = intval($course_id);
1709
    }
1710
    $sessionId = api_get_session_id();
1711
1712
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
1713
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1714
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
1715
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1716
1717
    $forum_id = intval($forum_id);
1718
    $return_array = array();
1719
1720
    // First get the threads to make sure there is no inconsistency in the
1721
    // database between forum and thread
1722
    $sql = "SELECT thread_id FROM $table_threads 
1723
            WHERE 
1724
                forum_id = $forum_id AND 
1725
                c_id = $course_id AND 
1726
                session_id = $sessionId";
1727
    $result = Database::query($sql);
1728
    if (Database::num_rows($result) == 0) {
1729
        // If there are no threads in this forum, then there are no posts
1730
        return [];
1731
    }
1732
    $threads = array();
1733
    while ($row = Database::fetch_row($result)) {
1734
        $threads[] = $row[0];
1735
    }
1736
    $threadsList = implode(',', $threads);
1737
    // Now get the posts that are linked to these threads
1738
    $sql = "SELECT
1739
                post.post_id,
1740
                post.forum_id,
1741
                post.poster_id,
1742
                post.poster_name,
1743
                post.post_date,
1744
                users.lastname,
1745
                users.firstname,
1746
                post.visible,
1747
                thread_properties.visibility AS thread_visibility,
1748
                forum_properties.visibility AS forum_visibility
1749
            FROM
1750
                $table_posts post,
1751
                $table_users users,
1752
                $table_item_property thread_properties,
1753
                $table_item_property forum_properties
1754
            WHERE
1755
                post.forum_id = $forum_id
1756
                AND post.thread_id IN ($threadsList)
1757
                AND post.poster_id = users.user_id
1758
                AND post.thread_id = thread_properties.ref
1759
                AND thread_properties.tool='".TOOL_FORUM_THREAD."'
1760
                AND post.forum_id=forum_properties.ref
1761
                AND forum_properties.tool='".TOOL_FORUM."'
1762
                AND post.c_id = $course_id AND
1763
                thread_properties.c_id = $course_id AND
1764
                forum_properties.c_id = $course_id
1765
            ORDER BY post.post_id DESC";
1766
    $result = Database::query($sql);
1767
1768
    if ($show_invisibles) {
1769
        $row = Database::fetch_array($result);
1770
        $return_array['last_post_id'] = $row['post_id'];
1771
        $return_array['last_poster_id'] = $row['poster_id'];
1772
        $return_array['last_post_date'] = $row['post_date'];
1773
        $return_array['last_poster_name'] = $row['poster_name'];
1774
        $return_array['last_poster_lastname'] = $row['lastname'];
1775
        $return_array['last_poster_firstname'] = $row['firstname'];
1776
1777
        return $return_array;
1778
    } else {
1779
        // We have to loop through the results to find the first one that is
1780
        // actually visible to students (forum_category, forum, thread AND post are visible).
1781
        while ($row = Database::fetch_array($result)) {
1782
            if ($row['visible'] == '1' && $row['thread_visibility'] == '1' && $row['forum_visibility'] == '1') {
1783
                $return_array['last_post_id'] = $row['post_id'];
1784
                $return_array['last_poster_id'] = $row['poster_id'];
1785
                $return_array['last_post_date'] = $row['post_date'];
1786
                $return_array['last_poster_name'] = $row['poster_name'];
1787
                $return_array['last_poster_lastname'] = $row['lastname'];
1788
                $return_array['last_poster_firstname'] = $row['firstname'];
1789
1790
                return $return_array;
1791
            }
1792
        }
1793
    }
1794
}
1795
1796
/**
1797
 * Retrieve all the threads of a given forum
1798
 *
1799
 * @param int $forum_id
1800
 * @param int|null $courseId Optional If is null then it is considered the current course
1801
 * @param int|null $sessionId Optional. If is null then it is considered the current session
1802
 * @return array containing all the information about the threads
1803
 *
1804
 * @author Patrick Cool <[email protected]>, Ghent University
1805
 * @version february 2006, dokeos 1.8
1806
 */
1807
function get_threads($forum_id, $courseId = null, $sessionId = null)
1808
{
1809
    $groupId = api_get_group_id();
1810
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
1811
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1812
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1813
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
1814
1815
    $courseId = $courseId !== null ? intval($courseId) : api_get_course_int_id();
1816
    $groupInfo = GroupManager::get_group_properties($groupId);
1817
    $groupCondition = '';
1818
1819
    if (!empty($groupInfo)) {
1820
        $groupIid = $groupInfo['iid'];
1821
        $groupCondition =  " AND item_properties.to_group_id = '$groupIid' ";
1822
    }
1823
1824
    $sessionCondition = api_get_session_condition(
1825
        $sessionId,
1826
        true,
1827
        false,
1828
        'item_properties.session_id'
1829
    );
1830
1831
    // important note:  it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
1832
    // because we also have thread.* in it. This is because thread has a field locked and post also has the same field
1833
    // since we are merging these we would have the post.locked value but in fact we want the thread.locked value
1834
    // This is why it is added to the end of the field selection
1835
    $sql = "SELECT DISTINCT
1836
                item_properties.*,
1837
                users.firstname,
1838
                users.lastname,
1839
                users.user_id,
1840
                thread.locked as locked,
1841
                thread.*
1842
            FROM $table_threads thread
1843
            INNER JOIN $table_item_property item_properties
1844
            ON
1845
                thread.thread_id = item_properties.ref AND
1846
                item_properties.c_id = thread.c_id AND
1847
                item_properties.tool = '".TABLE_FORUM_THREAD."' 
1848
                $groupCondition
1849
                $sessionCondition
1850
            LEFT JOIN $table_users users
1851
                ON thread.thread_poster_id = users.user_id
1852
            WHERE
1853
                item_properties.visibility='1' AND
1854
                thread.forum_id = ".intval($forum_id)." AND
1855
                thread.c_id = $courseId 
1856
            ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1857
1858
    if (api_is_allowed_to_edit()) {
1859
        $sql = "SELECT DISTINCT
1860
                    item_properties.*,
1861
                    users.firstname,
1862
                    users.lastname,
1863
                    users.user_id,
1864
                    thread.locked as locked,
1865
                    thread.*
1866
                FROM $table_threads thread
1867
                INNER JOIN $table_item_property item_properties
1868
                ON
1869
                    thread.thread_id = item_properties.ref AND
1870
                    item_properties.c_id = thread.c_id AND
1871
                    item_properties.tool = '".TABLE_FORUM_THREAD."'
1872
                    $groupCondition
1873
                    $sessionCondition
1874
                LEFT JOIN $table_users users
1875
                    ON thread.thread_poster_id=users.user_id
1876
                WHERE
1877
                    item_properties.visibility<>2 AND
1878
                    thread.forum_id = ".intval($forum_id)." AND
1879
                    thread.c_id = $courseId 
1880
                ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1881
1882
    }
1883
    $result = Database::query($sql);
1884
    $list = array();
1885
    $alreadyAdded = array();
1886 View Code Duplication
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1887
        if (in_array($row['thread_id'], $alreadyAdded)) {
1888
            continue;
1889
        }
1890
        $list[] = $row;
1891
        $alreadyAdded[] = $row['thread_id'];
1892
    }
1893
1894
    return $list;
1895
}
1896
1897
/**
1898
 * Get a thread by Id and course id
1899
 *
1900
 * @param int $threadId the thread Id
1901
 * @param int $cId the course id
1902
 * @return array containing all the information about the thread
1903
 */
1904
function getThreadInfo($threadId, $cId)
1905
{
1906
    $em = Database::getManager();
1907
    $forumThread = $em->getRepository('ChamiloCourseBundle:CForumThread')->findOneBy(['threadId' => $threadId, 'cId' => $cId]);
1908
1909
    $thread = [];
1910
1911
    if ($forumThread) {
1912
        $thread['threadId'] = $forumThread->getThreadId();
1913
        $thread['threadTitle'] = $forumThread->getThreadTitle();
1914
        $thread['forumId'] = $forumThread->getForumId();
1915
        $thread['sessionId'] = $forumThread->getSessionId();
1916
        $thread['threadSticky'] = $forumThread->getThreadSticky();
1917
        $thread['locked'] = $forumThread->getLocked();
1918
        $thread['threadTitleQualify'] = $forumThread->getThreadTitleQualify();
1919
        $thread['threadQualifyMax'] = $forumThread->getThreadQualifyMax();
1920
        $thread['threadCloseDate'] = $forumThread->getThreadCloseDate();
1921
        $thread['threadWeight'] = $forumThread->getThreadWeight();
1922
        $thread['threadPeerQualify'] = $forumThread->isThreadPeerQualify();
1923
    }
1924
1925
    return $thread;
1926
}
1927
1928
/**
1929
 * Retrieve all posts of a given thread
1930
 * @param array $forumInfo
1931
 * @param int $threadId The thread ID
1932
 * @param string $orderDirection Optional. The direction for sort the posts
1933
 * @param boolean $recursive Optional. If the list is recursive
1934
 * @param int $postId Optional. The post ID for recursive list
1935
 * @param int $depth Optional. The depth to indicate the indent
1936
 * @todo move to a repository
1937
 *
1938
 * @return array containing all the information about the posts of a given thread
1939
 */
1940
function getPosts(
1941
    $forumInfo,
1942
    $threadId,
1943
    $orderDirection = 'ASC',
1944
    $recursive = false,
1945
    $postId = null,
1946
    $depth = -1
1947
) {
1948
    $em = Database::getManager();
1949
1950
    if (api_is_allowed_to_edit(false, true)) {
1951
        $visibleCriteria = Criteria::expr()->neq('visible', 2);
1952
    } else {
1953
        $visibleCriteria = Criteria::expr()->eq('visible', 1);
1954
    }
1955
1956
    $criteria = Criteria::create();
1957
    $criteria
1958
        ->where(Criteria::expr()->eq('threadId', $threadId))
1959
        ->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
1960
        ->andWhere($visibleCriteria)
1961
    ;
1962
1963
    $groupId = api_get_group_id();
1964
    $groupInfo = GroupManager::get_group_properties($groupId);
1965
    $filterModerated = true;
1966
1967
    if (empty($groupId)) {
1968
        if (api_is_allowed_to_edit()) {
1969
            $filterModerated = false;
1970
        }
1971
    } else {
1972
        if (GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo) || api_is_allowed_to_edit(false, true)) {
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by \GroupManager::get_group_properties($groupId) on line 1964 can also be of type null; however, GroupManager::is_tutor_of_group() does only seem to accept array, 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...
1973
            $filterModerated = false;
1974
        }
1975
    }
1976
1977
    if ($recursive) {
1978
        $criteria->andWhere(Criteria::expr()->eq('postParentId', $postId));
1979
    }
1980
1981
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
1982
    $qb->select('p')
1983
        ->addCriteria($criteria)
1984
        ->addOrderBy('p.postId', $orderDirection);
1985
1986
    if ($filterModerated && $forumInfo['moderated'] == 1) {
1987
        if (!api_is_allowed_to_edit(false, true)) {
1988
            $userId = api_get_user_id();
1989
            $qb->andWhere(
1990
                "p.status = 1 OR 
1991
                    (p.status = ".CForumPost::STATUS_WAITING_MODERATION." AND p.posterId = $userId) OR
1992
                    (p.status = ".CForumPost::STATUS_REJECTED." AND p.posterId = $userId) OR
1993
                    (p.status IS NULL AND p.posterId = $userId) 
1994
                    "
1995
            );
1996
        }
1997
    }
1998
1999
    $posts = $qb->getQuery()->getResult();
2000
    $depth++;
2001
2002
    $list = [];
2003
    /** @var CForumPost $post */
2004
    foreach ($posts as $post) {
2005
        $postInfo = [
2006
            'iid' => $post->getIid(),
2007
            'c_id' => $post->getCId(),
2008
            'post_id' => $post->getPostId(),
2009
            'post_title' => $post->getPostTitle(),
2010
            'post_text' => $post->getPostText(),
2011
            'thread_id' => $post->getThreadId(),
2012
            'forum_id' => $post->getForumId(),
2013
            'poster_id' => $post->getPosterId(),
2014
            'poster_name' => $post->getPosterName(),
2015
            'post_date' => $post->getPostDate(),
2016
            'post_notification' => $post->getPostNotification(),
2017
            'post_parent_id' => $post->getPostParentId(),
2018
            'visible' => $post->getVisible(),
2019
            'status' => $post->getStatus(),
2020
            'indent_cnt' => $depth
2021
        ];
2022
2023
        $posterId = $post->getPosterId();
2024
        if (!empty($posterId)) {
2025
            $user = $em->find('ChamiloUserBundle:User', $posterId);
2026
2027
            if ($user) {
2028
                $postInfo['user_id'] = $user->getUserId();
2029
                $postInfo['username'] = $user->getUsername();
2030
                $postInfo['username_canonical'] = $user->getUsernameCanonical();
2031
                $postInfo['lastname'] = $user->getLastname();
2032
                $postInfo['firstname'] = $user->getFirstname();
2033
            }
2034
        }
2035
2036
        $list[] = $postInfo;
2037
2038
        if (!$recursive) {
2039
            continue;
2040
        }
2041
        $list = array_merge(
2042
            $list,
2043
            getPosts(
2044
                $forumInfo,
2045
                $threadId,
2046
                $orderDirection,
2047
                $recursive,
2048
                $post->getPostId(),
2049
                $depth
2050
            )
2051
        );
2052
    }
2053
2054
    return $list;
2055
}
2056
2057
/**
2058
 * This function retrieves all the information of a post
2059
 *
2060
 * @param int $post_id integer that indicates the forum
2061
 *
2062
 * @return array returns
2063
 *
2064
 * @author Patrick Cool <[email protected]>, Ghent University
2065
 * @version february 2006, dokeos 1.8
2066
 */
2067 View Code Duplication
function get_post_information($post_id)
2068
{
2069
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
2070
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
2071
    $course_id = api_get_course_int_id();
2072
2073
    $sql = "SELECT posts.*, email FROM ".$table_posts." posts, ".$table_users." users
2074
            WHERE
2075
                c_id = $course_id AND
2076
                posts.poster_id=users.user_id AND
2077
                posts.post_id = ".intval($post_id);
2078
    $result = Database::query($sql);
2079
    $row = Database::fetch_array($result, 'ASSOC');
2080
2081
    return $row;
2082
}
2083
2084
/**
2085
 * This function retrieves all the information of a thread
2086
 *
2087
 * @param int $forumId
2088
 * @param $thread_id integer that indicates the forum
2089
 * @param int|null $sessionId Optional. If is null then it is considered the current session
2090
 * @return array returns
2091
 *
2092
 * @author Patrick Cool <[email protected]>, Ghent University
2093
 * @version february 2006, dokeos 1.8
2094
 */
2095
function get_thread_information($forumId, $thread_id, $sessionId = null)
2096
{
2097
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2098
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
2099
    $thread_id = intval($thread_id);
2100
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
2101
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'threads.session_id');
2102
    $forumCondition = '';
2103
    if (!empty($forumId)) {
2104
        $forumId = (int) $forumId;
2105
        $forumCondition = " threads.forum_id = $forumId AND ";
2106
    }
2107
    $sql = "SELECT * FROM $table_item_property item_properties
2108
            INNER JOIN
2109
            $table_threads threads
2110
            ON (item_properties.ref = threads.thread_id AND threads.c_id = item_properties.c_id)
2111
            WHERE
2112
                $forumCondition
2113
                item_properties.tool= '".TOOL_FORUM_THREAD."' AND                
2114
                threads.thread_id = $thread_id 
2115
                $sessionCondition
2116
            ";
2117
2118
    $result = Database::query($sql);
2119
    $row = Database::fetch_assoc($result);
2120
2121
    return $row;
2122
}
2123
2124
/**
2125
 * This function retrieves forum thread users details
2126
 * @param   int Thread ID
2127
 * @param   string  Course DB name (optional)
2128
 * @return  Doctrine\DBAL\Driver\Statement|null array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2129
 * @author Christian Fasanando <[email protected]>,
2130
 * @todo     this function need to be improved
2131
 * @version octubre 2008, dokeos 1.8
2132
 */
2133
function get_thread_users_details($thread_id)
2134
{
2135
    $t_posts = Database::get_course_table(TABLE_FORUM_POST);
2136
    $t_users = Database::get_main_table(TABLE_MAIN_USER);
2137
    $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2138
    $t_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2139
2140
    $course_id = api_get_course_int_id();
2141
2142
    $is_western_name_order = api_is_western_name_order();
2143
    if ($is_western_name_order) {
2144
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2145
    } else {
2146
        $orderby = 'ORDER BY user.lastname, user.firstname';
2147
    }
2148
2149 View Code Duplication
    if (api_get_session_id()) {
2150
        $session_info = api_get_session_info(api_get_session_id());
2151
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2152
        //not showing coaches
2153
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2154
                  FROM $t_posts p, $t_users user, $t_session_rel_user session_rel_user_rel_course
2155
                  WHERE p.poster_id = user.id AND
2156
                  user.id = session_rel_user_rel_course.user_id AND
2157
                  session_rel_user_rel_course.status<>'2' AND
2158
                  session_rel_user_rel_course.user_id NOT IN ($user_to_avoid) AND
2159
                  p.thread_id = ".intval($thread_id)." AND
2160
                  session_id = ".api_get_session_id()." AND
2161
                  p.c_id = $course_id AND
2162
                  session_rel_user_rel_course.c_id = ".$course_id." $orderby ";
2163
    } else {
2164
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2165
                  FROM $t_posts p, $t_users user, $t_course_user course_user
2166
                  WHERE p.poster_id = user.id
2167
                  AND user.id = course_user.user_id
2168
                  AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2169
                  AND p.thread_id = ".intval($thread_id)."
2170
                  AND course_user.status NOT IN('1') AND
2171
                  p.c_id = $course_id AND
2172
                  course_user.c_id = ".$course_id." $orderby";
2173
    }
2174
    $result = Database::query($sql);
2175
2176
    return $result;
2177
}
2178
2179
/**
2180
 * This function retrieves forum thread users qualify
2181
 * @param   int Thread ID
2182
 * @param   string  Course DB name (optional)
2183
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2184
 * @author Jhon Hinojosa
2185
 * @todo     this function need to be improved
2186
 */
2187
function get_thread_users_qualify($thread_id)
2188
{
2189
    $t_posts = Database::get_course_table(TABLE_FORUM_POST);
2190
    $t_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2191
    $t_users = Database::get_main_table(TABLE_MAIN_USER);
2192
    $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2193
    $t_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2194
2195
    $course_id = api_get_course_int_id();
2196
    $sessionId = api_get_session_id();
2197
2198
    $is_western_name_order = api_is_western_name_order();
2199
    if ($is_western_name_order) {
2200
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2201
    } else {
2202
        $orderby = 'ORDER BY user.lastname, user.firstname';
2203
    }
2204
2205
    if ($sessionId) {
2206
        $session_info = api_get_session_info($sessionId);
2207
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2208
        //not showing coaches
2209
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2210
                FROM $t_posts post , $t_users user, $t_session_rel_user scu, $t_qualify qualify
2211
                WHERE poster_id = user.id
2212
                    AND post.poster_id = qualify.user_id
2213
                    AND user.id = scu.user_id
2214
                    AND scu.status<>'2'
2215
                    AND scu.user_id NOT IN ($user_to_avoid)
2216
                    AND qualify.thread_id = ".intval($thread_id)."
2217
                    AND post.thread_id = ".intval($thread_id)."
2218
                    AND scu.session_id = $sessionId
2219
                    AND scu.c_id = ".$course_id." AND
2220
                    qualify.c_id = $course_id AND
2221
                    post.c_id = $course_id
2222
                $orderby ";
2223
    } else {
2224
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2225
                FROM $t_posts post,
2226
                     $t_qualify qualify,
2227
                     $t_users user,
2228
                     $t_course_user course_user
2229
                WHERE
2230
                     post.poster_id = user.id
2231
                     AND post.poster_id = qualify.user_id
2232
                     AND user.id = course_user.user_id
2233
                     AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2234
                     AND qualify.thread_id = ".intval($thread_id)."
2235
                     AND post.thread_id = ".intval($thread_id)."
2236
                     AND course_user.status not in('1')
2237
                     AND course_user.c_id = $course_id
2238
                     AND qualify.c_id = $course_id
2239
                     AND post.c_id = $course_id
2240
                 $orderby ";
2241
    }
2242
    $result = Database::query($sql);
2243
2244
    return $result;
2245
}
2246
2247
/**
2248
 * This function retrieves forum thread users not qualify
2249
 * @param   int Thread ID
2250
 * @param   string  Course DB name (optional)
2251
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2252
 * @author   Jhon Hinojosa<[email protected]>,
2253
 * @version oct 2008, dokeos 1.8
2254
 */
2255
function get_thread_users_not_qualify($thread_id)
2256
{
2257
    $t_posts = Database::get_course_table(TABLE_FORUM_POST);
2258
    $t_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2259
    $t_users = Database::get_main_table(TABLE_MAIN_USER);
2260
    $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2261
    $t_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2262
2263
    $is_western_name_order = api_is_western_name_order();
2264
    if ($is_western_name_order) {
2265
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2266
    } else {
2267
        $orderby = 'ORDER BY user.lastname, user.firstname';
2268
    }
2269
2270
    $course_id = api_get_course_int_id();
2271
2272
    $sql1 = "SELECT user_id FROM  $t_qualify
2273
             WHERE c_id = $course_id AND thread_id = '".$thread_id."'";
2274
    $result1 = Database::query($sql1);
2275
    $cad = '';
2276
    while ($row = Database::fetch_array($result1)) {
2277
        $cad .= $row['user_id'].',';
2278
    }
2279
    if ($cad == '') {
2280
        $cad = '0';
2281
    } else {
2282
        $cad = substr($cad, 0, strlen($cad) - 1);
2283
    }
2284
2285 View Code Duplication
    if (api_get_session_id()) {
2286
        $session_info = api_get_session_info(api_get_session_id());
2287
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2288
        //not showing coaches
2289
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2290
                FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course
2291
                WHERE poster_id = user.id
2292
                    AND user.id NOT IN (".$cad.")
2293
                    AND user.id = session_rel_user_rel_course.user_id
2294
                    AND session_rel_user_rel_course.status<>'2'
2295
                    AND session_rel_user_rel_course.user_id NOT IN ($user_to_avoid)
2296
                    AND post.thread_id = ".intval($thread_id)."
2297
                    AND session_id = ".api_get_session_id()."
2298
                    AND session_rel_user_rel_course.c_id = $course_id AND post.c_id = $course_id $orderby ";
2299
    } else {
2300
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2301
                FROM $t_posts post, $t_users user,$t_course_user course_user
2302
                WHERE post.poster_id = user.id
2303
                AND user.id NOT IN (".$cad.")
2304
                AND user.id = course_user.user_id
2305
                AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2306
                AND post.thread_id = ".intval($thread_id)."
2307
                AND course_user.status not in('1')
2308
                AND course_user.c_id = $course_id AND post.c_id = $course_id  $orderby";
2309
    }
2310
    $result = Database::query($sql);
2311
2312
    return $result;
2313
}
2314
2315
/**
2316
 * This function retrieves all the information of a given forum_id
2317
 *
2318
 * @param $forum_id integer that indicates the forum
2319
 * @return array returns
2320
 *
2321
 * @author Patrick Cool <[email protected]>, Ghent University
2322
 * @version february 2006, dokeos 1.8
2323
 *
2324
 * @deprecated this functionality is now moved to get_forums($forum_id)
2325
 */
2326
function get_forum_information($forum_id, $courseId = 0)
2327
{
2328
    $table_forums = Database::get_course_table(TABLE_FORUM);
2329
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2330
    $courseId = empty($courseId) ? api_get_course_int_id(): intval($courseId);
2331
    $forum_id = intval($forum_id);
2332
2333
    $sql = "SELECT *
2334
            FROM $table_forums forums
2335
            INNER JOIN $table_item_property item_properties
2336
            ON (forums.c_id = item_properties.c_id)
2337
            WHERE
2338
                item_properties.tool = '".TOOL_FORUM."' AND
2339
                item_properties.ref = '".$forum_id."' AND
2340
                forums.forum_id = '".$forum_id."' AND
2341
                forums.c_id = ".$courseId."
2342
            ";
2343
2344
    $result = Database::query($sql);
2345
    $row = Database::fetch_array($result, 'ASSOC');
2346
    $row['approval_direct_post'] = 0;
2347
    // We can't anymore change this option, so it should always be activated.
2348
2349
    return $row;
2350
}
2351
2352
/**
2353
 * This function retrieves all the information of a given forumcategory id
2354
 *
2355
 * @param $cat_id integer that indicates the forum
2356
 *
2357
 * @return array returns if there are category or bool returns if there aren't category
2358
 * @author Patrick Cool <[email protected]>, Ghent University
2359
 * @version february 2006, dokeos 1.8
2360
 */
2361
function get_forumcategory_information($cat_id)
2362
{
2363
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
2364
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2365
2366
    $course_id = api_get_course_int_id();
2367
    $sql = "SELECT *
2368
            FROM ".$table_categories." forumcategories, ".$table_item_property." item_properties
2369
            WHERE
2370
                forumcategories.c_id = $course_id AND
2371
                item_properties.c_id = $course_id AND
2372
                item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
2373
                item_properties.ref='".Database::escape_string($cat_id)."' AND
2374
                forumcategories.cat_id='".Database::escape_string($cat_id)."'";
2375
    $result = Database::query($sql);
2376
    $row = Database::fetch_array($result);
2377
2378
    return $row;
2379
}
2380
2381
/**
2382
 * This function counts the number of forums inside a given category
2383
 *
2384
 * @param int $cat_id the id of the forum category
2385
 * @todo an additional parameter that takes the visibility into account. For instance $countinvisible=0 would return the number
2386
 *      of visible forums, $countinvisible=1 would return the number of visible and invisible forums
2387
 * @return int the number of forums inside the given category
2388
 *
2389
 * @author Patrick Cool <[email protected]>, Ghent University
2390
 * @version february 2006, dokeos 1.8
2391
 */
2392 View Code Duplication
function count_number_of_forums_in_category($cat_id)
2393
{
2394
    $table_forums = Database::get_course_table(TABLE_FORUM);
2395
    $course_id = api_get_course_int_id();
2396
    $sql = "SELECT count(*) AS number_of_forums
2397
            FROM ".$table_forums."
2398
            WHERE c_id = $course_id AND forum_category='".Database::escape_string($cat_id)."'";
2399
    $result = Database::query($sql);
2400
    $row = Database::fetch_array($result);
2401
2402
    return $row['number_of_forums'];
2403
}
2404
2405
/**
2406
 * This function update a thread
2407
 *
2408
 * @param array $values - The form Values
2409
 * @return void HTML
2410
 *
2411
 */
2412
function updateThread($values)
2413
{
2414
    $threadTable = Database::get_course_table(TABLE_FORUM_THREAD);
2415
    $courseId = api_get_course_int_id();
2416
2417
    $params = [
2418
        'thread_title' => $values['thread_title'],
2419
        'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
2420
        'thread_title_qualify' => $values['calification_notebook_title'],
2421
        'thread_qualify_max' => api_float_val($values['numeric_calification']),
2422
        'thread_weight' => api_float_val($values['weight_calification']),
2423
        'thread_peer_qualify' => $values['thread_peer_qualify'],
2424
    ];
2425
    $where = ['c_id = ? AND thread_id = ?' => [$courseId, $values['thread_id']]];
2426
    Database::update($threadTable, $params, $where);
2427
2428
    if (api_is_course_admin() == true) {
2429
        $option_chek = isset($values['thread_qualify_gradebook']) ? $values['thread_qualify_gradebook'] : false; // values 1 or 0
2430
        if ($option_chek) {
2431
            $id = $values['thread_id'];
2432
            $titleGradebook = Security::remove_XSS(stripslashes($values['calification_notebook_title']));
2433
            $valueCalification = isset($values['numeric_calification']) ? intval($values['numeric_calification']) : 0;
2434
            $weightCalification = isset($values['weight_calification']) ? floatval($values['weight_calification']) : 0;
2435
            $description = '';
2436
            $sessionId = api_get_session_id();
2437
            $courseId = api_get_course_id();
2438
2439
            $linkInfo = GradebookUtils::isResourceInCourseGradebook(
2440
                api_get_course_int_id(),
2441
                LINK_FORUM_THREAD,
2442
                $id,
2443
                $sessionId
2444
            );
2445
            $linkId = $linkInfo['id'];
2446
2447
            if (!$linkInfo) {
2448
                GradebookUtils::add_resource_to_course_gradebook(
2449
                    $values['category_id'],
2450
                    $courseId,
2451
                    LINK_FORUM_THREAD,
2452
                    $id,
2453
                    $titleGradebook,
2454
                    $weightCalification,
2455
                    $valueCalification,
2456
                    $description,
2457
                    1,
2458
                    $sessionId
2459
                );
2460
            } else {
2461
                $em = Database::getManager();
2462
                $gradebookLink = $em->getRepository('ChamiloCoreBundle:GradebookLink')->find($linkId);
2463
                $gradebookLink->setWeight($weightCalification);
2464
                $em->persist($gradebookLink);
0 ignored issues
show
Bug introduced by
It seems like $gradebookLink defined by $em->getRepository('Cham...okLink')->find($linkId) on line 2462 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...
2465
                $em->flush();
2466
            }
2467
        }
2468
    }
2469
2470
    $message = get_lang('EditPostStored').'<br />';
2471
    Display::addFlash(Display::return_message($message, 'confirmation', false));
2472
}
2473
2474
/**
2475
 * This function stores a new thread. This is done through an entry in the forum_thread table AND
2476
 * in the forum_post table because. The threads are also stored in the item_property table. (forum posts are not (yet))
2477
 *
2478
 * @param array $current_forum
2479
 * @param array $values
2480
 * @param array $courseInfo
2481
 * @param bool $showMessage
2482
 * @param int $userId Optional. The user ID
2483
 * @param int $sessionId
2484
 * @return int
2485
 * @author Patrick Cool <[email protected]>, Ghent University
2486
 * @version february 2006, dokeos 1.8
2487
 */
2488
function store_thread($current_forum, $values, $courseInfo = array(), $showMessage = true, $userId = 0, $sessionId = 0)
2489
{
2490
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
2491
    $userId = $userId ?: api_get_user_id();
2492
    $course_id = $courseInfo['real_id'];
2493
    $courseCode = $courseInfo['code'];
2494
    $groupId = api_get_group_id();
2495
    $groupInfo = GroupManager::get_group_properties($groupId);
2496
    $groupIid = null;
2497
    if (!empty($groupInfo)) {
2498
        $groupIid = $groupInfo['iid'];
2499
    }
2500
    $sessionId = $sessionId ?: api_get_session_id();
2501
2502
    $em = Database::getManager();
2503
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
2504
2505
    $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2506
    $upload_ok = 1;
2507
    $has_attachment = false;
2508
2509 View Code Duplication
    if (!empty($_FILES['user_upload']['name'])) {
2510
        $upload_ok = process_uploaded_file($_FILES['user_upload']);
2511
        $has_attachment = true;
2512
    }
2513
2514
    if (!$upload_ok) {
2515
        if ($showMessage) {
2516
            Display::addFlash(
2517
                Display::return_message(get_lang('UplNoFileUploaded'), 'error', false)
2518
            );
2519
        }
2520
2521
        return null;
2522
    }
2523
2524
    $post_date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
2525
2526 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2527
        $visible = 0; // The post has not been approved yet.
2528
    } else {
2529
        $visible = 1;
2530
    }
2531
2532
    $clean_post_title = $values['post_title'];
2533
2534
    // We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
2535
2536
    $lastThread = new CForumThread();
2537
    $lastThread
2538
        ->setCId($course_id)
2539
        ->setThreadTitle($clean_post_title)
2540
        ->setForumId($values['forum_id'])
2541
        ->setThreadPosterId($userId)
2542
        ->setThreadPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2543
        ->setThreadDate($post_date)
2544
        ->setThreadSticky(isset($values['thread_sticky']) ? $values['thread_sticky'] : 0)
2545
        ->setThreadTitleQualify(
2546
            isset($values['calification_notebook_title']) ? $values['calification_notebook_title'] : null
2547
        )
2548
        ->setThreadQualifyMax(isset($values['numeric_calification']) ? (int) $values['numeric_calification'] : 0)
2549
        ->setThreadWeight(isset($values['weight_calification']) ? (int) $values['weight_calification'] : 0)
2550
        ->setThreadPeerQualify(isset($values['thread_peer_qualify']) ? (int) $values['thread_peer_qualify'] : 0)
2551
        ->setSessionId($sessionId)
2552
        ->setLpItemId(isset($values['lp_item_id']) ? (int) $values['lp_item_id'] : 0)
2553
        ->setThreadId(0)
2554
        ->setLocked(0)
2555
    ;
2556
2557
    $em->persist($lastThread);
2558
    $em->flush();
2559
2560
    // Add option gradebook qualify.
2561
2562
    if (isset($values['thread_qualify_gradebook']) &&
2563
        1 == $values['thread_qualify_gradebook']
2564
    ) {
2565
        // Add function gradebook.
2566
        $resourcetype = 5;
2567
        $resourceid = $lastThread->getIid();
2568
        $resourcename = stripslashes($values['calification_notebook_title']);
2569
        $maxqualify = $values['numeric_calification'];
2570
        $weigthqualify = $values['weight_calification'];
2571
        $resourcedescription = '';
2572
        GradebookUtils::add_resource_to_course_gradebook(
2573
            $values['category_id'],
2574
            $courseCode,
2575
            $resourcetype,
2576
            $resourceid,
2577
            $resourcename,
2578
            $weigthqualify,
2579
            $maxqualify,
2580
            $resourcedescription,
2581
            0,
2582
            $sessionId
2583
        );
2584
    }
2585
2586
    if ($lastThread->getIid()) {
2587
        $lastThread->setThreadId($lastThread->getIid());
2588
2589
        $em->merge($lastThread);
2590
        $em->flush();
2591
2592
        api_item_property_update(
2593
            $courseInfo,
2594
            TOOL_FORUM_THREAD,
2595
            $lastThread->getIid(),
2596
            'ForumThreadAdded',
2597
            $userId,
2598
            $groupIid,
2599
            null,
2600
            null,
2601
            null,
2602
            $sessionId
2603
        );
2604
2605
        // If the forum properties tell that the posts have to be approved
2606
        // we have to put the whole thread invisible,
2607
        // because otherwise the students will see the thread and not the post
2608
        // in the thread.
2609
        // We also have to change $visible because the post itself has to be
2610
        // visible in this case (otherwise the teacher would have
2611
        // to make the thread visible AND the post.
2612
        // Default behaviour
2613
        api_set_default_visibility(
2614
            $lastThread->getIid(),
2615
            TOOL_FORUM_THREAD,
2616
            $groupIid,
2617
            $courseInfo,
2618
            $sessionId,
2619
            $userId
2620
        );
2621
2622
        if ($visible == 0) {
2623
            api_item_property_update(
2624
                $courseInfo,
2625
                TOOL_FORUM_THREAD,
2626
                $lastThread->getIid(),
2627
                'invisible',
2628
                $userId,
2629
                $groupIid
2630
2631
            );
2632
            $visible = 1;
2633
        }
2634
    }
2635
2636
    // We now store the content in the table_post table.
2637
    $lastPost = new CForumPost();
2638
    $lastPost
2639
        ->setCId($course_id)
2640
        ->setPostTitle($clean_post_title)
2641
        ->setPostText($values['post_text'])
2642
        ->setThreadId($lastThread->getIid())
2643
        ->setForumId($values['forum_id'])
2644
        ->setPosterId($userId)
2645
        ->setPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2646
        ->setPostDate($post_date)
2647
        ->setPostNotification(isset($values['post_notification']) ? (int) $values['post_notification'] : null)
2648
        ->setPostParentId(null)
2649
        ->setVisible($visible)
2650
        ->setPostId(0)
2651
        ->setStatus(CForumPost::STATUS_VALIDATED);
2652
2653
    if ($current_forum['moderated']) {
2654
        $lastPost->setStatus(
2655
            api_is_course_admin() ? CForumPost::STATUS_VALIDATED : CForumPost::STATUS_WAITING_MODERATION
2656
        );
2657
    }
2658
2659
    $em->persist($lastPost);
2660
    $em->flush();
2661
2662
    $last_post_id = $lastPost->getIid();
2663
2664
    if ($last_post_id) {
2665
        $lastPost->setPostId($last_post_id);
2666
        $em->merge($lastPost);
2667
        $em->flush();
2668
    }
2669
2670
    // Update attached files
2671 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
2672
        foreach ($_POST['file_ids'] as $key => $id) {
2673
            editAttachedFile(
2674
                array(
2675
                    'comment' => $_POST['file_comments'][$key],
2676
                    'post_id' => $last_post_id
2677
                ),
2678
                $id
2679
            );
2680
        }
2681
    }
2682
2683
    // Now we have to update the thread table to fill the thread_last_post
2684
    // field (so that we know when the thread has been updated for the last time).
2685
    $sql = "UPDATE $table_threads
2686
            SET thread_last_post = '".Database::escape_string($last_post_id)."'
2687
            WHERE
2688
                c_id = $course_id AND
2689
                thread_id='".Database::escape_string($lastThread->getIid())."'";
2690
    $result = Database::query($sql);
2691
    $message = get_lang('NewThreadStored');
2692
    // Storing the attachments if any.
2693
    if ($has_attachment) {
2694
        // Try to add an extension to the file if it hasn't one.
2695
        $new_file_name = add_ext_on_mime(
2696
            stripslashes($_FILES['user_upload']['name']),
2697
            $_FILES['user_upload']['type']
2698
        );
2699
2700
        if (!filter_extension($new_file_name)) {
2701
            if ($showMessage) {
2702
                Display::addFlash(Display::return_message(
2703
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2704
                    'error'
2705
                ));
2706
            }
2707
        } else {
2708
            if ($result) {
2709
                add_forum_attachment_file(
2710
                    isset($values['file_comment']) ? $values['file_comment'] : null,
2711
                    $last_post_id
2712
                );
2713
            }
2714
        }
2715
    } else {
2716
        $message .= '<br />';
2717
    }
2718
2719
    if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2720
        $message .= get_lang('MessageHasToBeApproved').'<br />';
2721
        $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2722
            get_lang('Forum').'</a><br />';
2723
    } else {
2724
        $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2725
            get_lang('Forum').'</a><br />';
2726
        $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'&gradebook='.$gradebook.'&thread='.$lastThread->getIid().'">'.
2727
            get_lang('Message').'</a>';
2728
    }
2729
    $reply_info['new_post_id'] = $last_post_id;
2730
    $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
2731
2732
    if ($my_post_notification == 1) {
2733
        set_notification('thread', $lastThread->getIid(), true);
2734
    }
2735
2736
    send_notification_mails(
2737
        $current_forum['forum_id'],
2738
        $lastThread->getIid(),
2739
        $reply_info,
2740
        $courseInfo['code']
2741
    );
2742
2743
    Session::erase('formelements');
2744
    Session::erase('origin');
2745
    Session::erase('breadcrumbs');
2746
    Session::erase('addedresource');
2747
    Session::erase('addedresourceid');
2748
2749
    if ($showMessage) {
2750
        Display::addFlash(Display::return_message($message, 'success', false));
2751
    }
2752
    return $lastThread->getIid();
2753
}
2754
2755
/**
2756
 * This function displays the form that is used to add a post. This can be a new thread or a reply.
2757
 * @param array $current_forum
2758
 * @param array $forum_setting
2759
 * @param string $action is the parameter that determines if we are
2760
 *  1. newthread: adding a new thread (both empty) => No I-frame
2761
 *  2. replythread: Replying to a thread ($action = replythread) => I-frame with the complete thread (if enabled)
2762
 *  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)
2763
 *  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)
2764
 * @return FormValidator
2765
 * @author Patrick Cool <[email protected]>, Ghent University
2766
 * @version february 2006, dokeos 1.8
2767
 */
2768
function show_add_post_form($current_forum, $forum_setting, $action, $id = '', $form_values = '')
2769
{
2770
    $_user = api_get_user_info();
2771
    $action = isset($action) ? Security::remove_XSS($action) : '';
2772
    $myThread = isset($_GET['thread']) ? (int) $_GET['thread'] : '';
2773
    $forumId = isset($_GET['forum']) ? (int) $_GET['forum'] : '';
2774
    $my_post = isset($_GET['post']) ? (int) $_GET['post'] : '';
2775
    $my_gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2776
2777
    $url = api_get_self() . '?' . http_build_query([
2778
        'action' => $action,
2779
        'forum' => $forumId,
2780
        'gradebook' => $my_gradebook,
2781
        'thread' => $myThread,
2782
        'post' => $my_post
2783
    ]) . '&' . api_get_cidreq();
2784
2785
    $form = new FormValidator(
2786
        'thread',
2787
        'post',
2788
        $url
2789
    );
2790
2791
    $form->setConstants(array('forum' => '5'));
2792
2793
    // Setting the form elements.
2794
    $form->addElement('hidden', 'forum_id', $forumId);
2795
    $form->addElement('hidden', 'thread_id', $myThread);
2796
    $form->addElement('hidden', 'gradebook', $my_gradebook);
2797
    $form->addElement('hidden', 'action', $action);
2798
2799
    // If anonymous posts are allowed we also display a form to allow the user to put his name or username in.
2800
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2801
        $form->addElement('text', 'poster_name', get_lang('Name'));
2802
        $form->applyFilter('poster_name', 'html_filter');
2803
    }
2804
2805
    $form->addElement('text', 'post_title', get_lang('Title'));
2806
    $form->addHtmlEditor(
2807
        'post_text',
2808
        get_lang('Text'),
2809
        true,
2810
        false,
2811
        api_is_allowed_to_edit(null, true) ? array(
2812
            'ToolbarSet' => 'Forum',
2813
            'Width' => '100%',
2814
            'Height' => '300',
2815
        ) : array(
2816
            'ToolbarSet' => 'ForumStudent',
2817
            'Width' => '100%',
2818
            'Height' => '300',
2819
            'UserStatus' => 'student'
2820
        )
2821
    );
2822
2823
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
2824
    $iframe = null;
2825
    $myThread = Security::remove_XSS($myThread);
2826
    if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
2827
        $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?".api_get_cidreq()."&forum=".intval($forumId)."&thread=".$myThread."#".Security::remove_XSS($my_post)."\" width=\"100%\"></iframe>";
2828
    }
2829
    if (!empty($iframe)) {
2830
        $form->addElement('label', get_lang('Thread'), $iframe);
2831
    }
2832
2833
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && !($myThread)) {
2834
        $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2835
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2836
2837
        // Thread qualify
2838
        if (Gradebook::is_active()) {
2839
            //Loading gradebook select
2840
            GradebookUtils::load_gradebook_select_in_tool($form);
2841
            $form->addElement(
2842
                'checkbox',
2843
                'thread_qualify_gradebook',
2844
                '',
2845
                get_lang('QualifyThreadGradebook'),
2846
                'onclick="javascript:if(this.checked==true){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
2847
            );
2848
        } else {
2849
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2850
        }
2851
2852
        $form->addElement('html', '<div id="options_field" style="display:none">');
2853
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2854
        $form->applyFilter('numeric_calification', 'html_filter');
2855
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2856
        $form->applyFilter('calification_notebook_title', 'html_filter');
2857
2858
        $form->addElement(
2859
            'text',
2860
            'weight_calification',
2861
            get_lang('QualifyWeight'),
2862
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2863
        );
2864
        $form->applyFilter('weight_calification', 'html_filter');
2865
2866
        $group = array();
2867
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2868
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2869
        $form->addGroup(
2870
            $group,
2871
            '',
2872
            [
2873
                get_lang('ForumThreadPeerScoring'),
2874
                get_lang('ForumThreadPeerScoringComment'),
2875
            ]
2876
        );
2877
        $form->addElement('html', '</div>');
2878
        $form->addElement('html', '</div>');
2879
    }
2880
2881 View Code Duplication
    if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
2882
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2883
    }
2884
2885
    if (in_array($action, ['quote', 'replymessage'])) {
2886
        $form->addFile('user_upload[]', get_lang('Attachment'));
2887
        $form->addButton(
2888
            'add_attachment',
2889
            get_lang('AddAttachment'),
2890
            'paperclip',
2891
            'default',
2892
            'default',
2893
            null,
2894
            ['id' => 'reply-add-attachment']
2895
        );
2896
    } else {
2897
        $form->addFile('user_upload', get_lang('Attachment'));
2898
    }
2899
2900
    // Setting the class and text of the form title and submit button.
2901
    if ($action == 'quote') {
2902
        $form->addButtonCreate(get_lang('QuoteMessage'), 'SubmitPost');
2903
    } elseif ($action == 'replythread') {
2904
        $form->addButtonCreate(get_lang('ReplyToThread'), 'SubmitPost');
2905
    } elseif ($action == 'replymessage') {
2906
        $form->addButtonCreate(get_lang('ReplyToMessage'), 'SubmitPost');
2907
    } else {
2908
        $form->addButtonCreate(get_lang('CreateThread'), 'SubmitPost');
2909
    }
2910
2911
    if (!empty($form_values)) {
2912
        $defaults['post_title'] = prepare4display($form_values['post_title']);
2913
        $defaults['post_text'] = prepare4display($form_values['post_text']);
2914
        $defaults['post_notification'] = strval(intval($form_values['post_notification']));
2915
        $defaults['thread_sticky'] = strval(intval($form_values['thread_sticky']));
2916
        $defaults['thread_peer_qualify'] = intval($form_values['thread_peer_qualify']);
2917
    } else {
2918
        $defaults['thread_peer_qualify'] = 0;
2919
    }
2920
2921
    // If we are quoting a message we have to retrieve the information of the post we are quoting so that
2922
    // we can add this as default to the textarea.
2923
    if (($action == 'quote' || $action == 'replymessage') && isset($my_post)) {
2924
        // We also need to put the parent_id of the post in a hidden form when
2925
        // we are quoting or replying to a message (<> reply to a thread !!!)
2926
        $form->addHidden('post_parent_id', intval($my_post));
2927
2928
        // If we are replying or are quoting then we display a default title.
2929
        $values = get_post_information($my_post);
2930
        $posterInfo = api_get_user_info($values['poster_id']);
2931
        $posterName = '';
2932
        if ($posterInfo) {
2933
            $posterName = $posterInfo['complete_name'];
2934
        }
2935
        $defaults['post_title'] = get_lang('ReplyShort').api_html_entity_decode($values['post_title'], ENT_QUOTES);
2936
        // When we are quoting a message then we have to put that message into the wysiwyg editor.
2937
        // Note: The style has to be hardcoded here because using class="quote" didn't work.
2938
        if ($action == 'quote') {
2939
            $defaults['post_text'] = '<div>&nbsp;</div>
2940
                <div style="margin: 5px;">
2941
                    <div style="font-size: 90%; font-style: italic;">'.
2942
                        get_lang('Quoting').' '.$posterName.':</div>
2943
                        <div style="color: #006600; font-size: 90%;  font-style: italic; background-color: #FAFAFA; border: #D1D7DC 1px solid; padding: 3px;">'.
2944
                            prepare4display($values['post_text']).'
2945
                        </div>
2946
                    </div>
2947
                <div>&nbsp;</div>
2948
                <div>&nbsp;</div>
2949
            ';
2950
        }
2951
    }
2952
2953
    $form->setDefaults(isset($defaults) ? $defaults : []);
2954
2955
    // The course admin can make a thread sticky (=appears with special icon and always on top).
2956
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
2957
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2958
        $form->addRule('poster_name', get_lang('ThisFieldIsRequired'), 'required');
2959
    }
2960
2961
    // Validation or display
2962
    if ($form->validate()) {
2963
        $check = Security::check_token('post');
2964
        if ($check) {
2965
            $values = $form->exportValues();
2966 View Code Duplication
            if (isset($values['thread_qualify_gradebook']) &&
2967
                $values['thread_qualify_gradebook'] == '1' &&
2968
                empty($values['weight_calification'])
2969
            ) {
2970
                Display::addFlash(
2971
                    Display::return_message(
2972
                        get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>',
2973
                        'error',
2974
                        false
2975
                    )
2976
                );
2977
2978
                return false;
2979
            }
2980
2981
            switch ($action) {
2982
                case 'newthread':
2983
                    $myThread = store_thread($current_forum, $values);
2984
                    break;
2985
                case 'quote':
2986
                case 'replythread':
2987
                case 'replymessage':
2988
                    store_reply($current_forum, $values);
2989
2990
                    break;
2991
            }
2992
2993
            $url = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&'.http_build_query(
2994
                [
2995
                    'forum' => $forumId,
2996
                    'thread' => $myThread
2997
                ]
2998
            );
2999
3000
            Security::clear_token();
3001
            header('Location: '.$url);
3002
            exit;
3003
        }
3004
    } else {
3005
        $token = Security::get_token();
3006
        $form->addElement('hidden', 'sec_token');
3007
        $form->setConstants(array('sec_token' => $token));
3008
3009
        // Delete from $_SESSION forum attachment from other posts
3010
        // and keep only attachments for new post
3011
        clearAttachedFiles(FORUM_NEW_POST);
3012
        // Get forum attachment ajax table to add it to form
3013
        $attachmentAjaxTable = getAttachmentsAjaxTable(0, $current_forum['forum_id']);
3014
        $ajaxHtml = $attachmentAjaxTable;
3015
        $form->addElement('html', $ajaxHtml);
3016
3017
        return $form;
3018
    }
3019
}
3020
3021
/**
3022
 * @param array $threadInfo
3023
 * @param integer $user_id
3024
 * @param integer $thread_id
3025
 * @param integer $thread_qualify
3026
 * @param integer $qualify_time
3027
 * @param integer $session_id
3028
 * @return array optional
3029
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3030
 * @version October 2008, dokeos  1.8.6
3031
 */
3032
function saveThreadScore(
3033
    $threadInfo,
3034
    $user_id,
3035
    $thread_id,
3036
    $thread_qualify = 0,
3037
    $qualify_time,
3038
    $session_id = 0
3039
) {
3040
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3041
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3042
3043
    $course_id = api_get_course_int_id();
3044
    $session_id = intval($session_id);
3045
    $currentUserId = api_get_user_id();
3046
3047
    if ($user_id == strval(intval($user_id)) &&
3048
        $thread_id == strval(intval($thread_id)) &&
3049
        $thread_qualify == strval(floatval($thread_qualify))
3050
    ) {
3051
        // Testing
3052
        $sql = "SELECT thread_qualify_max FROM $table_threads
3053
                WHERE c_id = $course_id AND thread_id=".$thread_id;
3054
        $res_string = Database::query($sql);
3055
        $row_string = Database::fetch_array($res_string);
3056
        if ($thread_qualify <= $row_string[0]) {
3057
            if ($threadInfo['thread_peer_qualify'] == 0) {
3058
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3059
                        WHERE
3060
                            c_id = $course_id AND
3061
                            user_id = $user_id AND
3062
                            thread_id = ".$thread_id;
3063
            } else {
3064
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3065
                        WHERE
3066
                            c_id = $course_id AND
3067
                            user_id = $user_id AND
3068
                            qualify_user_id = $currentUserId AND
3069
                            thread_id = ".$thread_id;
3070
            }
3071
3072
            $result = Database::query($sql);
3073
            $row = Database::fetch_array($result);
3074
3075
            if ($row[0] == 0) {
3076
                $sql = "INSERT INTO $table_threads_qualify (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
3077
                        VALUES (".$course_id.", '".$user_id."','".$thread_id."',".(float)$thread_qualify.", '".$currentUserId."','".$qualify_time."','".$session_id."')";
3078
                Database::query($sql);
3079
3080
                $insertId = Database::insert_id();
3081
                if ($insertId) {
3082
                    $sql = "UPDATE $table_threads_qualify SET id = iid
3083
                            WHERE iid = $insertId";
3084
                    Database::query($sql);
3085
                }
3086
3087
                return 'insert';
3088
            } else {
3089
3090
                saveThreadScoreHistory(
3091
                    '1',
3092
                    $course_id,
3093
                    $user_id,
3094
                    $thread_id
3095
                );
3096
3097
3098
                // Update
3099
                $sql = "UPDATE $table_threads_qualify
3100
                        SET
3101
                            qualify = '".$thread_qualify."',
3102
                            qualify_time = '".$qualify_time."'
3103
                        WHERE
3104
                            c_id = $course_id AND
3105
                            user_id=".$user_id." AND
3106
                            thread_id=".$thread_id." AND
3107
                            qualify_user_id = $currentUserId
3108
                        ";
3109
                Database::query($sql);
3110
3111
                return 'update';
3112
            }
3113
3114
        } else {
3115
            return null;
3116
        }
3117
    }
3118
}
3119
3120
/**
3121
 * This function shows qualify.
3122
 * @param string $option contains the information of option to run
3123
 * @param integer $user_id contains the information the current user id
3124
 * @param integer $thread_id contains the information the current thread id
3125
 * @return integer qualify
3126
 * <code> $option=1 obtained the qualification of the current thread</code>
3127
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3128
 * @version October 2008, dokeos  1.8.6
3129
 */
3130
function showQualify($option, $user_id, $thread_id)
3131
{
3132
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3133
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3134
3135
    $course_id = api_get_course_int_id();
3136
    $user_id = intval($user_id);
3137
    $thread_id = intval($thread_id);
3138
3139
    if (empty($user_id) || empty($thread_id)) {
3140
        return false;
3141
    }
3142
3143
    $sql = '';
3144
    switch ($option) {
3145
        case 1:
3146
            $sql = "SELECT qualify FROM $table_threads_qualify
3147
                    WHERE
3148
                        c_id = $course_id AND
3149
                        user_id=".$user_id." AND
3150
                        thread_id=".$thread_id;
3151
            break;
3152
        case 2:
3153
            $sql = "SELECT thread_qualify_max FROM $table_threads
3154
                    WHERE c_id = $course_id AND thread_id=".$thread_id;
3155
            break;
3156
    }
3157
3158
    if (!empty($sql)) {
3159
        $rs = Database::query($sql);
3160
        $row = Database::fetch_array($rs);
3161
3162
        return $row[0];
3163
    }
3164
3165
    return array();
3166
}
3167
3168
/**
3169
 * This function gets qualify historical.
3170
 * @param integer $user_id contains the information the current user id
3171
 * @param integer $thread_id contains the information the current thread id
3172
 * @param boolean $opt contains the information of option to run
3173
 * @return array
3174
 * @author Christian Fasanando <[email protected]>,
3175
 * @author Isaac Flores <[email protected]>,
3176
 * @version October 2008, dokeos  1.8.6
3177
 */
3178
function getThreadScoreHistory($user_id, $thread_id, $opt)
3179
{
3180
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3181
    $course_id = api_get_course_int_id();
3182
3183
    if ($opt == 'false') {
3184
        $sql = "SELECT * FROM $table_threads_qualify_log
3185
                WHERE
3186
                    c_id = $course_id AND
3187
                    thread_id='".Database::escape_string($thread_id)."' AND
3188
                    user_id='".Database::escape_string($user_id)."'
3189
                ORDER BY qualify_time";
3190
    } else {
3191
        $sql = "SELECT * FROM $table_threads_qualify_log
3192
                WHERE
3193
                    c_id = $course_id AND
3194
                    thread_id='".Database::escape_string($thread_id)."' AND
3195
                    user_id='".Database::escape_string($user_id)."'
3196
                ORDER BY qualify_time DESC";
3197
    }
3198
    $rs = Database::query($sql);
3199
    $log = array();
3200
    while ($row = Database::fetch_array($rs, 'ASSOC')) {
3201
        $log[] = $row;
3202
    }
3203
3204
    return $log;
3205
}
3206
3207
/**
3208
 * This function stores qualify historical.
3209
 * @param boolean contains the information of option to run
3210
 * @param string contains the information the current course id
3211
 * @param integer contains the information the current forum id
3212
 * @param integer contains the information the current user id
3213
 * @param integer contains the information the current thread id
3214
 * @param integer contains the information the current qualify
3215
 * @param string $option
3216
 * @param integer $course_id
3217
 * @param integer $user_id
3218
 * @param integer $thread_id
3219
 * @return void
3220
 * <code>$option=1 obtained the qualification of the current thread</code>
3221
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3222
 * @version October 2008, dokeos  1.8.6
3223
 */
3224
function saveThreadScoreHistory(
3225
    $option,
3226
    $course_id,
3227
    $user_id,
3228
    $thread_id
3229
) {
3230
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3231
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3232
3233
    $course_id = intval($course_id);
3234
    $qualify_user_id = api_get_user_id();
3235
3236
    if ($user_id == strval(intval($user_id)) &&
3237
        $thread_id == strval(intval($thread_id)) && $option == 1
3238
    ) {
3239
3240
        // Extract information of thread_qualify.
3241
        $sql = "SELECT qualify, qualify_time
3242
                FROM $table_threads_qualify
3243
                WHERE
3244
                    c_id = $course_id AND
3245
                    user_id = ".$user_id." AND
3246
                    thread_id = ".$thread_id." AND
3247
                    qualify_user_id = $qualify_user_id
3248
                ";
3249
        $rs = Database::query($sql);
3250
        $row = Database::fetch_array($rs);
3251
3252
        // Insert thread_historical.
3253
        $sql = "INSERT INTO $table_threads_qualify_log (c_id, user_id, thread_id, qualify, qualify_user_id,qualify_time,session_id)
3254
                VALUES(".$course_id.", '".$user_id."','".$thread_id."',".(float) $row[0].", '".$qualify_user_id."','".$row[1]."','')";
3255
        Database::query($sql);
3256
3257
        $insertId = Database::insert_id();
3258
        if ($insertId) {
3259
            $sql = "UPDATE $table_threads_qualify_log SET id = iid
3260
                    WHERE iid = $insertId";
3261
            Database::query($sql);
3262
        }
3263
    }
3264
}
3265
3266
/**
3267
 * This function shows current thread qualify .
3268
 * @param integer $threadId
3269
 * @param integer $sessionId
3270
 * @param integer $userId
3271
 *
3272
 * @return array or null if is empty
3273
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3274
 * @version December 2008, dokeos  1.8.6
3275
 */
3276 View Code Duplication
function current_qualify_of_thread($threadId, $sessionId, $userId)
3277
{
3278
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3279
3280
    $course_id = api_get_course_int_id();
3281
    $currentUserId = api_get_user_id();
3282
    $sessionId = intval($sessionId);
3283
    $threadId = intval($threadId);
3284
3285
    $sql = "SELECT qualify FROM $table_threads_qualify
3286
            WHERE
3287
                c_id = $course_id AND
3288
                thread_id = $threadId AND
3289
                session_id = $sessionId AND
3290
                qualify_user_id = $currentUserId AND
3291
                user_id = $userId
3292
            ";
3293
    $res = Database::query($sql);
3294
    $row = Database::fetch_array($res, 'ASSOC');
3295
3296
    return $row['qualify'];
3297
}
3298
3299
/**
3300
 * This function stores a reply in the forum_post table.
3301
 * It also updates the forum_threads table (thread_replies +1 , thread_last_post, thread_date)
3302
 * @param array $current_forum
3303
 * @param array $values
3304
 * @param int $courseId Optional
3305
 * @param int $userId Optional
3306
 * @return array
3307
 * @author Patrick Cool <[email protected]>, Ghent University
3308
 * @version february 2006, dokeos 1.8
3309
 */
3310
function store_reply($current_forum, $values, $courseId = 0, $userId = 0)
3311
{
3312
    $courseId = !empty($courseId) ? $courseId : api_get_course_int_id();
3313
    $_course = api_get_course_info_by_id($courseId);
3314
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
3315
    $post_date = api_get_utc_datetime();
3316
    $userId = $userId ?: api_get_user_id();
3317
3318 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' &&
3319
        !api_is_allowed_to_edit(null, true)
3320
    ) {
3321
        $visible = 0;
3322
    } else {
3323
        $visible = 1;
3324
    }
3325
3326
    $upload_ok = 1;
3327
    $return = array();
3328
3329
    if ($upload_ok) {
3330
        // We first store an entry in the forum_post table.
3331
        $new_post_id = Database::insert(
3332
            $table_posts,
3333
            [
3334
                'c_id' => $courseId,
3335
                'post_title' => $values['post_title'],
3336
                'post_text' => isset($values['post_text']) ? ($values['post_text']) : null,
3337
                'thread_id' => $values['thread_id'],
3338
                'forum_id' => $values['forum_id'],
3339
                'poster_id' => $userId,
3340
                'post_id' => 0,
3341
                'post_date' => $post_date,
3342
                'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : null,
3343
                'post_parent_id' => isset($values['post_parent_id']) ? $values['post_parent_id'] : null,
3344
                'visible' => $visible,
3345
            ]
3346
        );
3347
3348
        if ($new_post_id) {
3349
            $sql = "UPDATE $table_posts SET post_id = iid WHERE iid = $new_post_id";
3350
            Database::query($sql);
3351
3352
            $values['new_post_id'] = $new_post_id;
3353
            $message = get_lang('ReplyAdded');
3354
3355 View Code Duplication
            if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3356
                foreach ($_POST['file_ids'] as $key => $id) {
3357
                    editAttachedFile(
3358
                        array(
3359
                            'comment' => $_POST['file_comments'][$key],
3360
                            'post_id' => $new_post_id,
3361
                        ),
3362
                        $id
3363
                    );
3364
                }
3365
            }
3366
3367
            // Update the thread.
3368
            updateThreadInfo($values['thread_id'], $new_post_id, $post_date);
0 ignored issues
show
Bug introduced by
It seems like $post_date defined by api_get_utc_datetime() on line 3315 can also be of type null or object<DateTime>; however, updateThreadInfo() does only seem to accept string, 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...
3369
3370
            // Update the forum.
3371
            api_item_property_update(
3372
                $_course,
3373
                TOOL_FORUM,
3374
                $values['forum_id'],
3375
                'NewMessageInForum',
3376
                $userId
3377
            );
3378
3379
            // Insert post
3380
            api_item_property_update(
3381
                $_course,
3382
                TOOL_FORUM_POST,
3383
                $new_post_id,
3384
                'NewPost',
3385
                $userId
3386
            );
3387
3388
            if ($current_forum['approval_direct_post'] == '1' &&
3389
                !api_is_allowed_to_edit(null, true)
3390
            ) {
3391
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3392
            }
3393
3394
            if ($current_forum['moderated'] &&
3395
                !api_is_allowed_to_edit(null, true)
3396
            ) {
3397
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3398
            }
3399
3400
            // Setting the notification correctly.
3401
            $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
3402
            if ($my_post_notification == 1) {
3403
                set_notification('thread', $values['thread_id'], true);
3404
            }
3405
3406
            send_notification_mails(
3407
                $values['forum_id'],
3408
                $values['thread_id'],
3409
                $values
3410
            );
3411
            add_forum_attachment_file('', $new_post_id);
3412
        }
3413
3414
        Session::erase('formelements');
3415
        Session::erase('origin');
3416
        Session::erase('breadcrumbs');
3417
        Session::erase('addedresource');
3418
        Session::erase('addedresourceid');
3419
3420
        Display::addFlash(Display::return_message($message, 'confirmation', false));
3421
    } else {
3422
        Display::addFlash(
3423
            Display::return_message(get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'), 'error')
3424
        );
3425
    }
3426
3427
    return $return;
3428
}
3429
3430
/**
3431
 * This function displays the form that is used to edit a post. This can be a new thread or a reply.
3432
 * @param array contains all the information about the current post
3433
 * @param array contains all the information about the current thread
3434
 * @param array contains all info about the current forum (to check if attachments are allowed)
3435
 * @param array contains the default values to fill the form
3436
 * @return void
3437
 *
3438
 * @author Patrick Cool <[email protected]>, Ghent University
3439
 * @version february 2006, dokeos 1.8
3440
 */
3441
function show_edit_post_form(
3442
    $forum_setting,
3443
    $current_post,
3444
    $current_thread,
3445
    $current_forum,
3446
    $form_values = '',
3447
    $id_attach = 0
3448
) {
3449
    // Initialize the object.
3450
    $form = new FormValidator(
3451
        'edit_post',
3452
        'post',
3453
        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
3454
    );
3455
    $form->addElement('header', get_lang('EditPost'));
3456
    // Setting the form elements.
3457
    $form->addElement('hidden', 'post_id', $current_post['post_id']);
3458
    $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
3459
    $form->addElement('hidden', 'id_attach', $id_attach);
3460
3461
    if (empty($current_post['post_parent_id'])) {
3462
        $form->addElement('hidden', 'is_first_post_of_thread', '1');
3463
    }
3464
3465
    $form->addElement('text', 'post_title', get_lang('Title'));
3466
    $form->applyFilter('post_title', 'html_filter');
3467
    $form->addElement(
3468
        'html_editor',
3469
        'post_text',
3470
        get_lang('Text'),
3471
        null,
3472
        api_is_allowed_to_edit(null, true) ? array(
3473
            'ToolbarSet' => 'Forum',
3474
            'Width' => '100%',
3475
            'Height' => '400',
3476
        ) : array(
3477
            'ToolbarSet' => 'ForumStudent',
3478
            'Width' => '100%',
3479
            'Height' => '400',
3480
            'UserStatus' => 'student',
3481
        )
3482
    );
3483
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
3484
3485
    $form->addButtonAdvancedSettings('advanced_params');
3486
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
3487
3488
    if (!isset($_GET['edit'])) {
3489
        if (Gradebook::is_active()) {
3490
            $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
3491
            $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\';}"');
3492
3493
            $link_info = GradebookUtils::isResourceInCourseGradebook(
3494
                api_get_course_int_id(),
3495
                5,
3496
                $_GET['thread'],
3497
                api_get_session_id()
3498
            );
3499
            if (!empty($link_info)) {
3500
                $defaults['thread_qualify_gradebook'] = true;
3501
                $defaults['category_id'] = $link_info['category_id'];
3502
            } else {
3503
                $defaults['thread_qualify_gradebook'] = false;
3504
                $defaults['category_id'] = '';
3505
            }
3506
        } else {
3507
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
3508
            $defaults['thread_qualify_gradebook'] = false;
3509
        }
3510
3511
        if (!empty($defaults['thread_qualify_gradebook'])) {
3512
            $form->addElement('html', '<div id="options_field" style="display:block">');
3513
        } else {
3514
            $form->addElement('html', '<div id="options_field" style="display:none">');
3515
        }
3516
3517
        // Loading gradebook select
3518
        GradebookUtils::load_gradebook_select_in_tool($form);
3519
3520
        $form->addElement(
3521
            'text',
3522
            'numeric_calification',
3523
            get_lang('QualificationNumeric'),
3524
            array(
3525
                'value' => $current_thread['thread_qualify_max'],
3526
                'style' => 'width:40px',
3527
            )
3528
        );
3529
        $form->applyFilter('numeric_calification', 'html_filter');
3530
3531
        $form->addElement(
3532
            'text',
3533
            'calification_notebook_title',
3534
            get_lang('TitleColumnGradebook'),
3535
            array('value' => $current_thread['thread_title_qualify'])
3536
        );
3537
        $form->applyFilter('calification_notebook_title', 'html_filter');
3538
3539
        $form->addElement(
3540
            'text',
3541
            'weight_calification',
3542
            array(get_lang('QualifyWeight'), null, ''),
3543
            array(
3544
                'value' => $current_thread['thread_weight'],
3545
                'style' => 'width:40px',
3546
            )
3547
        );
3548
        $form->applyFilter('weight_calification', 'html_filter');
3549
3550
        $group = array();
3551
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
3552
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
3553
        $form->addGroup(
3554
            $group,
3555
            '',
3556
            [
3557
                get_lang('ForumThreadPeerScoring'),
3558
                get_lang('ForumThreadPeerScoringComment'),
3559
            ]
3560
        );
3561
3562
        $form->addElement('html', '</div>');
3563
    }
3564
3565
    if ($current_forum['moderated'] && api_is_allowed_to_edit(null, true)) {
3566
        $group = array();
3567
        $group[] = $form->createElement('radio', 'status', null, get_lang('Validated'), 1);
3568
        $group[] = $form->createElement('radio', 'status', null, get_lang('WaitingModeration'), 2);
3569
        $group[] = $form->createElement('radio', 'status', null, get_lang('Rejected'), 3);
3570
        $form->addGroup($group, 'status', get_lang('Status'));
3571
    }
3572
3573
    $defaults['status']['status'] = isset($current_post['status']) && !empty($current_post['status']) ? $current_post['status'] : 2;
3574
3575
    if ($forum_setting['allow_post_notification']) {
3576
        $form->addElement('checkbox', 'post_notification', '', get_lang('NotifyByEmail').' ('.$current_post['email'].')');
3577
    }
3578
3579
    if ($forum_setting['allow_sticky'] &&
3580
        api_is_allowed_to_edit(null, true) &&
3581
        empty($current_post['post_parent_id'])
3582
    ) {
3583
        // The sticky checkbox only appears when it is the first post of a thread.
3584
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3585
        if ($current_thread['thread_sticky'] == 1) {
3586
            $defaults['thread_sticky'] = true;
3587
        }
3588
    }
3589
3590
    $form->addElement('html', '</div>');
3591
3592
    $form->addFile('user_upload[]', get_lang('Attachment'));
3593
    $form->addButton(
3594
        'add_attachment',
3595
        get_lang('AddAttachment'),
3596
        'paperclip',
3597
        'default',
3598
        'default',
3599
        null,
3600
        ['id' => 'reply-add-attachment']
3601
    );
3602
3603
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
3604
3605
    // Setting the default values for the form elements.
3606
    $defaults['post_title'] = $current_post['post_title'];
3607
    $defaults['post_text'] = $current_post['post_text'];
3608
3609
    if ($current_post['post_notification'] == 1) {
3610
        $defaults['post_notification'] = true;
3611
    }
3612
3613
    if (!empty($form_values)) {
3614
        $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
3615
        $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
3616
    }
3617
3618
    $defaults['thread_peer_qualify'] = intval($current_thread['thread_peer_qualify']);
3619
3620
    $form->setDefaults($defaults);
3621
3622
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3623
3624
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3625
3626
    // Validation or display
3627
    if ($form->validate()) {
3628
        $values = $form->exportValues();
3629
3630 View Code Duplication
        if (isset($values['thread_qualify_gradebook']) && $values['thread_qualify_gradebook'] == '1' &&
3631
            empty($values['weight_calification'])
3632
        ) {
3633
            Display::addFlash(Display::return_message(get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>', 'error', false));
3634
            return false;
3635
        }
3636
        return $values;
3637
    } else {
3638
        // Delete from $_SESSION forum attachment from other posts
3639
        clearAttachedFiles($current_post['post_id']);
3640
        // Get forum attachment ajax table to add it to form
3641
        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
3642
        $form->addElement('html', $fileData);
3643
        $form->display();
3644
    }
3645
}
3646
3647
/**
3648
 * This function stores the edit of a post in the forum_post table.
3649
 *
3650
 * @param array
3651
 * @return void HTML
3652
 *
3653
 * @author Patrick Cool <[email protected]>, Ghent University
3654
 * @version february 2006, dokeos 1.8
3655
 */
3656
function store_edit_post($forumInfo, $values)
3657
{
3658
    $threadTable = Database::get_course_table(TABLE_FORUM_THREAD);
3659
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
3660
    $gradebook = Security::remove_XSS($_GET['gradebook']);
3661
    $course_id = api_get_course_int_id();
3662
3663
    //check if this post is the first of the thread
3664
    // First we check if the change affects the thread and if so we commit
3665
    // the changes (sticky and post_title=thread_title are relevant).
3666
3667
    $posts = getPosts($forumInfo, $values['thread_id']);
3668
    $first_post = null;
3669
    if (!empty($posts) && count($posts) > 0 && isset($posts[0])) {
3670
        $first_post = $posts[0];
3671
    }
3672
3673
    if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
3674
        $params = [
3675
            'thread_title' => $values['post_title'],
3676
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
3677
            'thread_title_qualify' => $values['calification_notebook_title'],
3678
            'thread_qualify_max' => api_float_val($values['numeric_calification']),
3679
            'thread_weight' => api_float_val($values['weight_calification']),
3680
            'thread_peer_qualify' => $values['thread_peer_qualify'],
3681
        ];
3682
        $where = ['c_id = ? AND thread_id = ?' => [$course_id, $values['thread_id']]];
3683
3684
        Database::update($threadTable, $params, $where);
3685
    }
3686
3687
    $status = '';
3688
    $updateStatus = false;
3689
    if ($forumInfo['moderated']) {
3690
        if (api_is_allowed_to_edit(null, true)) {
3691
            $status = $values['status']['status'];
3692
            $updateStatus = true;
3693
        } else {
3694
            $status = CForumPost::STATUS_WAITING_MODERATION;
3695
            $updateStatus = true;
3696
        }
3697
    }
3698
3699
    // Update the post_title and the post_text.
3700
    $params = [
3701
        'post_title' => $values['post_title'],
3702
        'post_text' => $values['post_text'],
3703
        'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
3704
    ];
3705
    if ($updateStatus) {
3706
        $params['status'] = $status;
3707
    }
3708
    $where = ['c_id = ? AND post_id = ?' => [$course_id, $values['post_id']]];
3709
    Database::update($table_posts, $params, $where);
3710
3711
    // Update attached files
3712 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3713
        foreach ($_POST['file_ids'] as $key => $id) {
3714
            editAttachedFile(
3715
                array(
3716
                    'comment' => $_POST['file_comments'][$key],
3717
                    'post_id' => $values['post_id'],
3718
                ),
3719
                $id
3720
            );
3721
        }
3722
    }
3723
3724
    if (!empty($values['remove_attach'])) {
3725
        delete_attachment($values['post_id']);
3726
    }
3727
3728
    if (empty($values['id_attach'])) {
3729
        add_forum_attachment_file(
3730
            isset($values['file_comment']) ? $values['file_comment'] : null,
3731
            $values['post_id']
3732
        );
3733
    } else {
3734
        edit_forum_attachment_file(
3735
            isset($values['file_comment']) ? $values['file_comment'] : null,
3736
            $values['post_id'],
3737
            $values['id_attach']
3738
        );
3739
    }
3740
3741
    $message = get_lang('EditPostStored').'<br />';
3742
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&">'.get_lang('Forum').'</a><br />';
3743
    $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>';
3744
3745
    Session::erase('formelements');
3746
    Session::erase('origin');
3747
    Session::erase('breadcrumbs');
3748
    Session::erase('addedresource');
3749
    Session::erase('addedresourceid');
3750
3751
    echo Display::return_message($message, 'confirmation', false);
3752
}
3753
3754
/**
3755
 * This function displays the firstname and lastname of the user as a link to the user tool.
3756
 *
3757
 * @param string names
3758
 * @ in_title : title tootip
3759
 * @return string HTML
3760
 *
3761
 * @author Patrick Cool <[email protected]>, Ghent University
3762
 * @version february 2006, dokeos 1.8
3763
 */
3764
function display_user_link($user_id, $name, $origin = '', $in_title = '')
3765
{
3766
    if ($user_id != 0) {
3767
        $userInfo = api_get_user_info($user_id);
3768
3769
        return '<a href="'.$userInfo['profile_url'].'">'.Security::remove_XSS($userInfo['complete_name']).'</a>';
3770
    } else {
3771
        return $name.' ('.get_lang('Anonymous').')';
3772
    }
3773
}
3774
3775
/**
3776
 * This function displays the user image from the profile, with a link to the user's details.
3777
 * @param   int     User's database ID
3778
 * @param   string  User's name
3779
 * @param   string  the origin where the forum is called (example : learnpath)
3780
 * @return  string  An HTML with the anchor and the image of the user
3781
 * @author Julio Montoya <[email protected]>
3782
 */
3783
function display_user_image($user_id, $name, $origin = '')
3784
{
3785
    $userInfo = api_get_user_info($user_id);
3786
3787
    $link = '<a href="'.(!empty($origin) ? '#' : $userInfo['profile_url']).'" '.(!empty($origin) ? 'target="_self"' : '').'>';
3788
3789
    if ($user_id != 0) {
3790
        return $link.'<img src="'.$userInfo['avatar'].'"  alt="'.$name.'"  title="'.$name.'" /></a>';
3791
    } else {
3792
        return $link.Display::return_icon('unknown.jpg', $name).'</a>';
3793
    }
3794
}
3795
3796
/**
3797
 * The thread view counter gets increased every time someone looks at the thread
3798
 *
3799
 * @param int
3800
 * @return void
3801
 *
3802
 * @author Patrick Cool <[email protected]>, Ghent University
3803
 * @version february 2006, dokeos 1.8
3804
 */
3805 View Code Duplication
function increase_thread_view($thread_id)
3806
{
3807
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3808
    $course_id = api_get_course_int_id();
3809
3810
    $sql = "UPDATE $table_threads SET thread_views=thread_views+1
3811
            WHERE 
3812
                c_id = $course_id AND  
3813
                thread_id = '".intval($thread_id)."'";
3814
    Database::query($sql);
3815
}
3816
3817
/**
3818
 * The relies counter gets increased every time somebody replies to the thread
3819
 *
3820
 * @author Patrick Cool <[email protected]>, Ghent University
3821
 * @version february 2006, dokeos 1.8
3822
 * @param string $last_post_id
3823
 * @param string $post_date
3824
 */
3825
function updateThreadInfo($thread_id, $last_post_id, $post_date)
3826
{
3827
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3828
    $course_id = api_get_course_int_id();
3829
    $sql = "UPDATE $table_threads SET 
3830
            thread_replies = thread_replies+1,
3831
            thread_last_post = '".Database::escape_string($last_post_id)."',
3832
            thread_date = '".Database::escape_string($post_date)."'
3833
            WHERE 
3834
                c_id = $course_id AND  
3835
                thread_id='".Database::escape_string($thread_id)."'"; // this needs to be cleaned first
3836
    Database::query($sql);
3837
}
3838
3839
/**
3840
 * This function is called when the user is not allowed in this forum/thread/...
3841
 * @return bool display message of "not allowed"
3842
 *
3843
 * @deprecated use api_not_allowed()
3844
 *
3845
 * @author Patrick Cool <[email protected]>, Ghent University
3846
 * @version february 2006, dokeos 1.8
3847
 */
3848
function forum_not_allowed_here()
3849
{
3850
    Display::addFlash(Display::return_message(get_lang('NotAllowedHere'), 'error'));
3851
    Display :: display_footer();
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_footer() has been deprecated with message: See template.lib.php class documentation

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...
3852
3853
    return false;
3854
}
3855
3856
/**
3857
 * This function is used to find all the information about what's new in the forum tool
3858
 * @return void
3859
 *
3860
 * @author Patrick Cool <[email protected]>, Ghent University
3861
 * @version february 2006, dokeos 1.8
3862
 */
3863
function get_whats_new()
3864
{
3865
    $userId = api_get_user_id();
3866
    $course_id = api_get_course_int_id();
3867
3868
    if (empty($course_id) || empty($userId)) {
3869
        return false;
3870
    }
3871
3872
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
3873
    $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
3874
3875
    $tool = TOOL_FORUM;
3876
    $lastForumAccess = Session::read('last_forum_access');
3877
3878
    if (!$lastForumAccess) {
3879
        $sql = "SELECT * FROM $tracking_last_tool_access
3880
                WHERE
3881
                    access_user_id = $userId AND
3882
                    c_id = $course_id AND
3883
                    access_tool = '".Database::escape_string($tool)."'";
3884
        $result = Database::query($sql);
3885
        $row = Database::fetch_array($result);
3886
        Session::write('last_forum_access', $row['access_date']);
3887
        $lastForumAccess = $row['access_date'];
3888
    }
3889
3890
    $whatsNew = Session::read('whatsnew_post_info');
3891
3892
    if (!$whatsNew) {
3893
        if ($lastForumAccess != '') {
3894
            $postInfo = array();
3895
            $sql = "SELECT * FROM $table_posts
3896
                    WHERE
3897
                        c_id = $course_id AND
3898
                        visible = 1 AND                        
3899
                        post_date > '".Database::escape_string($lastForumAccess)."'";
3900
            $result = Database::query($sql);
3901
            while ($row = Database::fetch_array($result)) {
3902
                $postInfo[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
3903
            }
3904
            Session::write('whatsnew_post_info', $postInfo);
3905
        }
3906
    }
3907
}
3908
3909
/**
3910
 * This function approves a post = change
3911
 *
3912
 * @param int $post_id the id of the post that will be deleted
3913
 * @param string $action make the post visible or invisible
3914
 * @return string language variable
3915
 *
3916
 * @author Patrick Cool <[email protected]>, Ghent University
3917
 * @version february 2006, dokeos 1.8
3918
 */
3919
function approve_post($post_id, $action)
3920
{
3921
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
3922
    $course_id = api_get_course_int_id();
3923
3924
    if ($action == 'invisible') {
3925
        $visibility_value = 0;
3926
    }
3927
3928
    if ($action == 'visible') {
3929
        $visibility_value = 1;
3930
        handle_mail_cue('post', $post_id);
3931
    }
3932
3933
    $sql = "UPDATE $table_posts SET
3934
            visible='".Database::escape_string($visibility_value)."'
3935
            WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
3936
    $return = Database::query($sql);
3937
3938
    if ($return) {
3939
        return 'PostVisibilityChanged';
3940
    }
3941
}
3942
3943
/**
3944
 * This function retrieves all the unapproved messages for a given forum
3945
 * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
3946
 *
3947
 * @param $forum_id the forum where we want to know the unapproved messages of
3948
 * @return array returns
3949
 *
3950
 * @author Patrick Cool <[email protected]>, Ghent University
3951
 * @version february 2006, dokeos 1.8
3952
 */
3953
function get_unaproved_messages($forum_id)
3954
{
3955
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
3956
    $course_id = api_get_course_int_id();
3957
3958
    $return_array = array();
3959
    $sql = "SELECT DISTINCT thread_id FROM $table_posts
3960
            WHERE 
3961
                c_id = $course_id AND 
3962
                forum_id='".Database::escape_string($forum_id)."' AND 
3963
                visible='0' ";
3964
    $result = Database::query($sql);
3965
    while ($row = Database::fetch_array($result)) {
3966
        $return_array[] = $row['thread_id'];
3967
    }
3968
3969
    return $return_array;
3970
}
3971
3972
/**
3973
 * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
3974
 * was added to a given thread.
3975
 *
3976
 * @param array reply information
3977
 * @return void
3978
 *
3979
 * @author Patrick Cool <[email protected]>, Ghent University
3980
 * @version february 2006, dokeos 1.8
3981
 */
3982
function send_notification_mails($forumId, $thread_id, $reply_info)
3983
{
3984
    $table = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
3985
3986
    // First we need to check if
3987
    // 1. the forum category is visible
3988
    // 2. the forum is visible
3989
    // 3. the thread is visible
3990
    // 4. the reply is visible (=when there is)
3991
    $current_thread = get_thread_information($forumId, $thread_id);
3992
    $current_forum = get_forum_information($current_thread['forum_id'], $current_thread['c_id']);
3993
3994
    $current_forum_category = null;
3995
    if (isset($current_forum['forum_category'])) {
3996
        $current_forum_category = get_forumcategory_information(
3997
            $current_forum['forum_category']
3998
        );
3999
    }
4000
4001
    if ($current_thread['visibility'] == '1' &&
4002
        $current_forum['visibility'] == '1' &&
4003
        ($current_forum_category && $current_forum_category['visibility'] == '1') &&
4004
        $current_forum['approval_direct_post'] != '1'
4005
    ) {
4006
        $send_mails = true;
4007
    } else {
4008
        $send_mails = false;
4009
    }
4010
4011
    // The forum category, the forum, the thread and the reply are visible to the user
4012
    if ($send_mails) {
4013
        if (!empty($forumId)) {
4014
            send_notifications($forumId, $thread_id);
4015
        }
4016
    } else {
4017
        $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
4018
        if (isset($current_forum['forum_id'])) {
4019
            $sql = "SELECT * FROM $table_notification
4020
                    WHERE
4021
                        c_id = ".api_get_course_int_id()." AND
4022
                        (
4023
                            forum_id = '".intval($current_forum['forum_id'])."' OR
4024
                            thread_id = '".intval($thread_id)."'
4025
                        ) ";
4026
4027
            $result = Database::query($sql);
4028
            $user_id = api_get_user_id();
4029
            while ($row = Database::fetch_array($result)) {
4030
                $sql = "INSERT INTO $table (c_id, thread_id, post_id, user_id)
4031
                        VALUES (".api_get_course_int_id().", '".intval($thread_id)."', '".intval($reply_info['new_post_id'])."', '$user_id' )";
4032
                Database::query($sql);
4033
            }
4034
        }
4035
    }
4036
}
4037
4038
/**
4039
 * This function is called whenever something is made visible because there might
4040
 * be new posts and the user might have indicated that (s)he wanted to be
4041
 * informed about the new posts by mail.
4042
 *
4043
 * @param string  Content type (post, thread, forum, forum_category)
4044
 * @param int     Item DB ID
4045
 * @param string $content
4046
 * @param integer $id
4047
 * @return string language variable
4048
 * @author Patrick Cool <[email protected]>, Ghent University
4049
 * @version february 2006, dokeos 1.8
4050
 */
4051
function handle_mail_cue($content, $id)
4052
{
4053
    $table_mailcue = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
4054
    $table_forums = Database::get_course_table(TABLE_FORUM);
4055
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
4056
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
4057
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
4058
4059
    $course_id = api_get_course_int_id();
4060
4061
    /* If the post is made visible we only have to send mails to the people
4062
     who indicated that they wanted to be informed for that thread.*/
4063
    if ($content == 'post') {
4064
        // Getting the information about the post (need the thread_id).
4065
        $post_info = get_post_information($id);
4066
        $thread_id = intval($post_info['thread_id']);
4067
4068
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4069
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4070
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4071
                WHERE
4072
                    posts.c_id = $course_id AND
4073
                    mailcue.c_id = $course_id AND
4074
                    posts.thread_id='$thread_id'
4075
                    AND posts.post_notification='1'
4076
                    AND mailcue.thread_id='$thread_id'
4077
                    AND users.user_id=posts.poster_id
4078
                    AND users.active=1
4079
                GROUP BY users.email";
4080
4081
        $result = Database::query($sql);
4082
        while ($row = Database::fetch_array($result)) {
4083
            send_mail($row, get_thread_information($post_info['forum_id'], $post_info['thread_id']));
4084
        }
4085
    } elseif ($content == 'thread') {
4086
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4087
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email, posts.forum_id
4088
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4089
                WHERE
4090
                    posts.c_id = $course_id AND
4091
                    mailcue.c_id = $course_id AND
4092
                    posts.thread_id = ".intval($id)."
4093
                    AND posts.post_notification='1'
4094
                    AND mailcue.thread_id = ".intval($id)."
4095
                    AND users.user_id=posts.poster_id
4096
                    AND users.active=1
4097
                GROUP BY users.email";
4098
        $result = Database::query($sql);
4099
        while ($row = Database::fetch_array($result)) {
4100
            send_mail($row, get_thread_information($row['forum_id'], $id));
4101
        }
4102
4103
        // Deleting the relevant entries from the mailcue.
4104
        $sql = "DELETE FROM $table_mailcue
4105
                WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
4106
        Database::query($sql);
4107
    } elseif ($content == 'forum') {
4108
        $sql = "SELECT thread_id FROM $table_threads
4109
                WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
4110
        $result = Database::query($sql);
4111
        while ($row = Database::fetch_array($result)) {
4112
            handle_mail_cue('thread', $row['thread_id']);
4113
        }
4114
    } elseif ($content == 'forum_category') {
4115
        $sql = "SELECT forum_id FROM $table_forums
4116
                WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
4117
        $result = Database::query($sql);
4118
        while ($row = Database::fetch_array($result)) {
4119
            handle_mail_cue('forum', $row['forum_id']);
4120
        }
4121
    } else {
4122
        return get_lang('Error');
4123
    }
4124
}
4125
4126
/**
4127
 * This function sends the mails for the mail notification
4128
 *
4129
 * @param array
4130
 * @param array
4131
 * @return void
4132
 *
4133
 * @author Patrick Cool <[email protected]>, Ghent University
4134
 * @version february 2006, dokeos 1.8
4135
 */
4136
function send_mail($user_info = array(), $thread_information = array())
4137
{
4138
    $_course = api_get_course_info();
4139
    $user_id = api_get_user_id();
4140
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
4141 View Code Duplication
    if (isset($thread_information) && is_array($thread_information)) {
4142
        $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$thread_information['forum_id'].'&thread='.$thread_information['thread_id'];
4143
    }
4144
    $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
4145
    $email_body .= get_lang('NewForumPost')."\n";
4146
    $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
4147
    $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
4148
    $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
4149
4150
    if ($user_info['user_id'] <> $user_id) {
4151
        MessageManager::send_message($user_info['user_id'], $subject, $email_body, [], [], null, null, null, null, $user_id);
4152
    }
4153
}
4154
4155
/**
4156
 * This function displays the form for moving a thread to a different (already existing) forum
4157
 * @return void HTML
4158
 *
4159
 * @author Patrick Cool <[email protected]>, Ghent University
4160
 * @version february 2006, dokeos 1.8
4161
 */
4162
function move_thread_form()
4163
{
4164
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4165
    $form = new FormValidator(
4166
        'movepost',
4167
        'post',
4168
        api_get_self().'?forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
4169
    );
4170
    // The header for the form
4171
    $form->addElement('header', get_lang('MoveThread'));
4172
    // Invisible form: the thread_id
4173
    $form->addElement('hidden', 'thread_id', intval($_GET['thread']));
4174
    // the fora
4175
    $forum_categories = get_forum_categories();
4176
    $forums = get_forums();
4177
4178
    $htmlcontent = '<div class="row">
4179
        <div class="label">
4180
            <span class="form_required">*</span>'.get_lang('MoveTo').'
4181
        </div>
4182
        <div class="formw">';
4183
    $htmlcontent .= '<select name="forum">';
4184
    foreach ($forum_categories as $key => $category) {
4185
        $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
4186
        foreach ($forums as $key => $forum) {
4187
            if (isset($forum['forum_category'])) {
4188
                if ($forum['forum_category'] == $category['cat_id']) {
4189
                    $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
4190
                }
4191
            }
4192
        }
4193
        $htmlcontent .= '</optgroup>';
4194
    }
4195
    $htmlcontent .= "</select>";
4196
    $htmlcontent .= '   </div>
4197
                    </div>';
4198
4199
    $form->addElement('html', $htmlcontent);
4200
4201
    // The OK button
4202
    $form->addButtonSave(get_lang('MoveThread'), 'SubmitForum');
4203
4204
    // Validation or display
4205
    if ($form->validate()) {
4206
        $values = $form->exportValues();
4207
        if (isset($_POST['forum'])) {
4208
            store_move_thread($values);
4209
        }
4210
    } else {
4211
        $form->display();
4212
    }
4213
}
4214
4215
/**
4216
 * This function displays the form for moving a post message to a different (already existing) or a new thread.
4217
 * @return void HTML
4218
 *
4219
 * @author Patrick Cool <[email protected]>, Ghent University
4220
 * @version february 2006, dokeos 1.8
4221
 */
4222
function move_post_form()
4223
{
4224
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4225
    // initiate the object
4226
    $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']));
4227
    // The header for the form
4228
    $form->addElement('header', '', get_lang('MovePost'));
4229
4230
    // Invisible form: the post_id
4231
    $form->addElement('hidden', 'post_id', intval($_GET['post']));
4232
4233
    // Dropdown list: Threads of this forum
4234
    $threads = get_threads($_GET['forum']);
4235
    //my_print_r($threads);
4236
    $threads_list[0] = get_lang('ANewThread');
4237
    foreach ($threads as $key => $value) {
4238
        $threads_list[$value['thread_id']] = $value['thread_title'];
4239
    }
4240
    $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
4241
    $form->applyFilter('thread', 'html_filter');
4242
4243
    // The OK button
4244
    $form->addButtonSave(get_lang('MovePost'), 'submit');
4245
4246
    // Setting the rules
4247
    $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
4248
4249
    // Validation or display
4250
    if ($form->validate()) {
4251
        $values = $form->exportValues();
4252
        store_move_post($values);
4253
    } else {
4254
        $form->display();
4255
    }
4256
}
4257
4258
/**
4259
 *
4260
 * @param array
4261
 * @return string HTML language variable
4262
 *
4263
 * @author Patrick Cool <[email protected]>, Ghent University
4264
 * @version february 2006, dokeos 1.8
4265
 */
4266
function store_move_post($values)
4267
{
4268
    $_course = api_get_course_info();
4269
    $course_id = api_get_course_int_id();
4270
4271
    $table_forums = Database::get_course_table(TABLE_FORUM);
4272
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
4273
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
4274
4275
    if ($values['thread'] == '0') {
4276
        $current_post = get_post_information($values['post_id']);
4277
4278
        // Storing a new thread.
4279
        $params = [
4280
            'c_id' => $course_id,
4281
            'thread_title' => $current_post['post_title'],
4282
            'forum_id' => $current_post['forum_id'],
4283
            'thread_poster_id' => $current_post['poster_id'],
4284
            'thread_poster_name' => $current_post['poster_name'],
4285
            'thread_last_post' => $values['post_id'],
4286
            'thread_date' => $current_post['post_date'],
4287
        ];
4288
4289
        $new_thread_id = Database::insert($table_threads, $params);
4290
4291
        api_item_property_update(
4292
            $_course,
4293
            TOOL_FORUM_THREAD,
4294
            $new_thread_id,
4295
            'visible',
4296
            $current_post['poster_id']
4297
        );
4298
4299
        // Moving the post to the newly created thread.
4300
        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
4301
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4302
        Database::query($sql);
4303
4304
        // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
4305
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4306
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4307
        Database::query($sql);
4308
4309
        // Updating updating the number of threads in the forum.
4310
        $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
4311
                WHERE c_id = $course_id AND forum_id='".intval($current_post['forum_id'])."'";
4312
        Database::query($sql);
4313
4314
        // Resetting the last post of the old thread and decreasing the number of replies and the thread.
4315
        $sql = "SELECT * FROM $table_posts
4316
                WHERE c_id = $course_id AND thread_id='".intval($current_post['thread_id'])."'
4317
                ORDER BY post_id DESC";
4318
        $result = Database::query($sql);
4319
        $row = Database::fetch_array($result);
4320
        $sql = "UPDATE $table_threads SET
4321
                    thread_last_post='".$row['post_id']."',
4322
                    thread_replies=thread_replies-1
4323
                WHERE
4324
                    c_id = $course_id AND
4325
                    thread_id='".intval($current_post['thread_id'])."'";
4326
        Database::query($sql);
4327
    } else {
4328
        // Moving to the chosen thread.
4329
        $sql = "SELECT thread_id FROM ".$table_posts."
4330
                WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
4331
        $result = Database::query($sql);
4332
        $row = Database::fetch_array($result);
4333
4334
        $original_thread_id = $row['thread_id'];
4335
4336
        $sql = "SELECT thread_last_post FROM ".$table_threads."
4337
                WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4338
4339
        $result = Database::query($sql);
4340
        $row = Database::fetch_array($result);
4341
        $thread_is_last_post = $row['thread_last_post'];
4342
        // If is this thread, update the thread_last_post with the last one.
4343
4344
        if ($thread_is_last_post == $values['post_id']) {
4345
            $sql = "SELECT post_id FROM ".$table_posts."
4346
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."'
4347
                    ORDER BY post_date DESC LIMIT 1";
4348
            $result = Database::query($sql);
4349
4350
            $row = Database::fetch_array($result);
4351
            $thread_new_last_post = $row['post_id'];
4352
4353
            $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."'
4354
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4355
            Database::query($sql);
4356
        }
4357
4358
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
4359
                WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
4360
        Database::query($sql);
4361
4362
        // moving to the chosen thread
4363
        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
4364
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4365
        Database::query($sql);
4366
4367
        // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
4368
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4369
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4370
        Database::query($sql);
4371
4372
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
4373
                WHERE c_id = $course_id AND thread_id='".intval($_POST['thread'])."'";
4374
        Database::query($sql);
4375
    }
4376
4377
    return get_lang('ThreadMoved');
4378
}
4379
4380
/**
4381
 *
4382
 * @param array
4383
 * @return string HTML language variable
4384
 *
4385
 * @author Patrick Cool <[email protected]>, Ghent University
4386
 * @version february 2006, dokeos 1.8
4387
 */
4388
function store_move_thread($values)
4389
{
4390
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
4391
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
4392
4393
    $courseId = api_get_course_int_id();
4394
    $sessionId = api_get_session_id();
4395
4396
    $forumId = intval($_POST['forum']);
4397
    $threadId = intval($_POST['thread_id']);
4398
    $forumInfo = get_forums($forumId);
4399
4400
    // Change the thread table: Setting the forum_id to the new forum.
4401
    $sql = "UPDATE $table_threads SET forum_id = $forumId
4402
            WHERE c_id = $courseId AND thread_id = $threadId";
4403
    Database::query($sql);
4404
4405
    // Changing all the posts of the thread: setting the forum_id to the new forum.
4406
    $sql = "UPDATE $table_posts SET forum_id = $forumId
4407
            WHERE c_id = $courseId AND thread_id= $threadId";
4408
    Database::query($sql);
4409
    // Fix group id, if forum is moved to a different group
4410
    if (!empty($forumInfo['to_group_id'])) {
4411
        $groupId = $forumInfo['to_group_id'];
4412
        $item = api_get_item_property_info($courseId, TABLE_FORUM_THREAD, $threadId, $sessionId, $groupId);
4413
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
4414
        $sessionCondition = api_get_session_condition($sessionId);
4415
4416
        if (!empty($item)) {
4417
            if ($item['to_group_id'] != $groupId) {
4418
                $sql = "UPDATE $table
4419
                    SET to_group_id = $groupId
4420
                    WHERE
4421
                      tool = '".TABLE_FORUM_THREAD."' AND
4422
                      c_id = $courseId AND
4423
                      ref = ".$item['ref']."
4424
                      $sessionCondition
4425
                ";
4426
                Database::query($sql);
4427
            }
4428
        } else {
4429
            $sql = "UPDATE $table
4430
                    SET to_group_id = $groupId
4431
                    WHERE
4432
                      tool = '".TABLE_FORUM_THREAD."' AND
4433
                      c_id = $courseId AND
4434
                      ref = ".$threadId."
4435
                      $sessionCondition
4436
            ";
4437
            Database::query($sql);
4438
        }
4439
    }
4440
4441
    return get_lang('ThreadMoved');
4442
}
4443
4444
/**
4445
 * Prepares a string for displaying by highlighting the search results inside, if any.
4446
 * @param string $input    The input string.
4447
 * @return string          The same string with highlighted hits inside.
4448
 *
4449
 * @author Patrick Cool <[email protected]>, Ghent University, February 2006 - the initial version.
4450
 * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
4451
 */
4452
function prepare4display($input)
4453
{
4454
    static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
4455
    static $search;
4456
4457
    if (!isset($search)) {
4458
        if (isset($_POST['search_term'])) {
4459
            $search = $_POST['search_term']; // No html at all.
4460
        } elseif (isset($_GET['search'])) {
4461
            $search = $_GET['search'];
4462
        } else {
4463
            $search = '';
4464
        }
4465
    }
4466
4467
    if (!empty($search)) {
4468
        if (strstr($search, '+')) {
4469
            $search_terms = explode('+', $search);
4470
        } else {
4471
            $search_terms[] = trim($search);
4472
        }
4473
        $counter = 0;
4474
        foreach ($search_terms as $key => $search_term) {
4475
            $input = api_preg_replace('/'.preg_quote(trim($search_term), '/').'/i', '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>', $input);
4476
            $counter++;
4477
        }
4478
    }
4479
4480
    // TODO: Security should be implemented outside this function.
4481
    // 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).
4482
4483
    return Security::remove_XSS($input, STUDENT, true);
4484
}
4485
4486
/**
4487
 * Display the search form for the forum and display the search results
4488
 * @return void display an HTML search results
4489
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4490
 * @version march 2008, dokeos 1.8.5
4491
 */
4492
function forum_search()
4493
{
4494
    $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?'.api_get_cidreq());
4495
4496
    // Setting the form elements.
4497
    $form->addElement('header', '', get_lang('ForumSearch'));
4498
    $form->addElement('text', 'search_term', get_lang('SearchTerm'), array('autofocus'));
4499
    $form->applyFilter('search_term', 'html_filter');
4500
    $form->addElement('static', 'search_information', '', get_lang('ForumSearchInformation'));
4501
    $form->addButtonSearch(get_lang('Search'));
4502
4503
    // Setting the rules.
4504
    $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
4505
    $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
4506
4507
    // Validation or display.
4508
    if ($form->validate()) {
4509
        $values = $form->exportValues();
4510
        $form->setDefaults($values);
4511
        $form->display();
4512
        // Display the search results.
4513
        display_forum_search_results(stripslashes($values['search_term']));
4514
    } else {
4515
        $form->display();
4516
    }
4517
}
4518
4519
/**
4520
 * Display the search results
4521
 * @param string
4522
 * @param string $search_term
4523
 * @return void display the results
4524
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4525
 * @version march 2008, dokeos 1.8.5
4526
 */
4527
function display_forum_search_results($search_term)
4528
{
4529
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
4530
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
4531
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
4532
    $session_id = api_get_session_id();
4533
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4534
    $course_id = api_get_course_int_id();
4535
4536
    // Defining the search strings as an array.
4537
    if (strstr($search_term, '+')) {
4538
        $search_terms = explode('+', $search_term);
4539
    } else {
4540
        $search_terms[] = $search_term;
4541
    }
4542
4543
    // Search restriction.
4544
    foreach ($search_terms as $value) {
4545
        $search_restriction[] = "
4546
        (
4547
            posts.post_title LIKE '%".Database::escape_string(trim($value))."%' OR 
4548
            posts.post_text LIKE '%".Database::escape_string(trim($value))."%' 
4549
        )";
4550
    }
4551
4552
    $sessionCondition = api_get_session_condition($session_id, true, false, 'item_property.session_id');
4553
4554
    $sql = "SELECT posts.*
4555
            FROM $table_posts posts INNER JOIN $table_threads threads
4556
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
4557
            INNER JOIN $table_item_property item_property
4558
            ON (item_property.ref = threads.thread_id AND item_property.c_id = threads.c_id)
4559
            WHERE
4560
                posts.c_id = $course_id AND 
4561
                item_property.c_id = $course_id AND 
4562
                item_property.visibility = 1  
4563
                $sessionCondition AND
4564
                posts.visible = 1 AND 
4565
                item_property.tool = '".TOOL_FORUM_THREAD."' AND 
4566
                ".implode(' AND ', $search_restriction)."
4567
            GROUP BY posts.post_id";
4568
4569
    // Getting all the information of the forum categories.
4570
    $forum_categories_list = get_forum_categories();
4571
4572
    // Getting all the information of the forums.
4573
    $forum_list = get_forums();
4574
4575
    $result = Database::query($sql);
4576
    $search_results = [];
4577
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4578
        $forumId = $row['forum_id'];
4579
        $forumData = get_forums($forumId);
4580
        $category = isset($forum_categories_list[$forumData['forum_category']]) ? $forum_categories_list[$forumData['forum_category']] : null;
4581
        $display_result = false;
4582
        /*
4583
          We only show it when
4584
          1. forum category is visible
4585
          2. forum is visible
4586
          3. thread is visible (to do)
4587
          4. post is visible
4588
         */
4589
        if (!api_is_allowed_to_edit(null, true)) {
4590
            if (!empty($category)) {
4591
                if ($category['visibility'] == '1' && $forumData['visibility'] == '1') {
4592
                    $display_result = true;
4593
                }
4594
            } else {
4595
                if ($forumData['visible'] == '1') {
4596
                    $display_result = true;
4597
                }
4598
            }
4599
        } else {
4600
            $display_result = true;
4601
        }
4602
4603
        if ($display_result) {
4604
            $categoryName = !empty($category) ? $category['cat_title'] : '';
4605
            $search_results_item = '<li><a href="viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.$forumData['forum_category'].'&search='.urlencode($search_term).'">'.
4606
                prepare4display($categoryName).'</a> &gt; ';
4607
            $search_results_item .= '<a href="viewforum.php?'.api_get_cidreq().'&forum='.$forumId.'&search='.urlencode($search_term).'">'.
4608
                prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
4609
            $search_results_item .= '<a href="viewthread.php?'.api_get_cidreq().'&forum='.$forumId.'&gradebook='.$gradebook.'&thread='.$row['thread_id'].'&search='.urlencode($search_term).'">'.
4610
                prepare4display($row['post_title']).'</a>';
4611
            $search_results_item .= '<br />';
4612
            if (api_strlen($row['post_title']) > 200) {
4613
                $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...
4614
            } else {
4615
                $search_results_item .= prepare4display($row['post_title']);
4616
            }
4617
            $search_results_item .= '</li>';
4618
            $search_results[] = $search_results_item;
4619
        }
4620
    }
4621
    echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
4622
    echo '<ol>';
4623
    if ($search_results) {
4624
        echo implode($search_results);
4625
    }
4626
    echo '</ol>';
4627
}
4628
4629
/**
4630
 * Return the link to the forum search page
4631
 *
4632
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4633
 * @version April 2008, dokeos 1.8.5
4634
 */
4635
function search_link()
4636
{
4637
    $return = '';
4638
    $origin = api_get_origin();
4639
    if ($origin != 'learnpath') {
4640
        $return = '<a href="forumsearch.php?'.api_get_cidreq().'&action=search"> ';
4641
        $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
4642
4643
        if (!empty($_GET['search'])) {
4644
            $return .= ': '.Security::remove_XSS($_GET['search']).' ';
4645
            $url = api_get_self().'?';
4646
            $url_parameter = array();
4647
            foreach ($_GET as $key => $value) {
4648
                if ($key != 'search') {
4649
                    $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
4650
                }
4651
            }
4652
            $url = $url.implode('&', $url_parameter);
4653
            $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
4654
        }
4655
    }
4656
4657
    return $return;
4658
}
4659
4660
/**
4661
 * This function adds an attachment file into a forum
4662
 * @param string $file_comment  a comment about file
4663
 * @param int $last_id from forum_post table
4664
 * @return false|null
4665
 */
4666
function add_forum_attachment_file($file_comment, $last_id)
4667
{
4668
    $_course = api_get_course_info();
4669
    $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4670
4671
    if (!isset($_FILES['user_upload'])) {
4672
        return false;
4673
    }
4674
4675
    $fileCount = count($_FILES['user_upload']['name']);
4676
    $filesData = [];
4677
4678 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4679
        $filesData[] = $_FILES['user_upload'];
4680
    } else {
4681
        $fileKeys = array_keys($_FILES['user_upload']);
4682
        for ($i = 0; $i < $fileCount; $i++) {
4683
            foreach ($fileKeys as $key) {
4684
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4685
            }
4686
        }
4687
    }
4688
4689
    foreach ($filesData as $attachment) {
4690
        if (empty($attachment['name'])) {
4691
            continue;
4692
        }
4693
4694
        $upload_ok = process_uploaded_file($attachment);
4695
4696
        if (!$upload_ok) {
4697
            continue;
4698
        }
4699
4700
        $course_dir = $_course['path'] . '/upload/forum';
4701
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4702
        $updir = $sys_course_path . $course_dir;
4703
4704
        // Try to add an extension to the file if it hasn't one.
4705
        $new_file_name = add_ext_on_mime(
4706
            stripslashes($attachment['name']),
4707
            $attachment['type']
4708
        );
4709
        // User's file name
4710
        $file_name = $attachment['name'];
4711
4712
        if (!filter_extension($new_file_name)) {
4713
            Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error'));
4714
4715
            return;
4716
        }
4717
4718
        $new_file_name = uniqid('');
4719
        $new_path = $updir . '/' . $new_file_name;
4720
        $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4721
        $safe_file_comment = Database::escape_string($file_comment);
4722
        $safe_file_name = Database::escape_string($file_name);
4723
        $safe_new_file_name = Database::escape_string($new_file_name);
4724
        $last_id = intval($last_id);
4725
        // Storing the attachments if any.
4726
        if (!$result) {
4727
            return;
4728
        }
4729
4730
        $last_id_file = Database::insert(
4731
            $agenda_forum_attachment,
4732
            [
4733
                'c_id' => api_get_course_int_id(),
4734
                'filename' => $safe_file_name,
4735
                'comment' => $safe_file_comment,
4736
                'path' => $safe_new_file_name,
4737
                'post_id' => $last_id,
4738
                'size' => intval($attachment['size']),
4739
            ]
4740
        );
4741
4742
        api_item_property_update(
4743
            $_course,
4744
            TOOL_FORUM_ATTACH,
4745
            $last_id_file,
4746
            'ForumAttachmentAdded',
4747
            api_get_user_id()
4748
        );
4749
    }
4750
}
4751
4752
/**
4753
 * This function edits an attachment file into a forum
4754
 * @param string $file_comment  a comment about file
4755
 * @param int $post_id
4756
 * @param int $id_attach attachment file Id
4757
 * @return void
4758
 */
4759
function edit_forum_attachment_file($file_comment, $post_id, $id_attach)
4760
{
4761
    $_course = api_get_course_info();
4762
    $table_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4763
    $course_id = api_get_course_int_id();
4764
4765
    $fileCount = count($_FILES['user_upload']['name']);
4766
    $filesData = [];
4767
4768 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4769
        $filesData[] = $_FILES['user_upload'];
4770
    } else {
4771
        $fileKeys = array_keys($_FILES['user_upload']);
4772
4773
        for ($i = 0; $i < $fileCount; $i++) {
4774
            foreach ($fileKeys as $key) {
4775
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4776
            }
4777
        }
4778
    }
4779
4780
    foreach ($filesData as $attachment) {
4781
        if (empty($attachment['name'])) {
4782
            continue;
4783
        }
4784
4785
        $upload_ok = process_uploaded_file($attachment);
4786
4787
        if (!$upload_ok) {
4788
            continue;
4789
        }
4790
4791
        $course_dir = $_course['path'].'/upload/forum';
4792
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4793
        $updir = $sys_course_path.$course_dir;
4794
4795
        // Try to add an extension to the file if it hasn't one.
4796
        $new_file_name = add_ext_on_mime(stripslashes($attachment['name']), $attachment['type']);
4797
        // User's file name
4798
        $file_name = $attachment['name'];
4799
4800
        if (!filter_extension($new_file_name)) {
4801
            Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error'));
4802
        } else {
4803
            $new_file_name = uniqid('');
4804
            $new_path = $updir.'/'.$new_file_name;
4805
            $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4806
            $safe_file_comment = Database::escape_string($file_comment);
4807
            $safe_file_name = Database::escape_string($file_name);
4808
            $safe_new_file_name = Database::escape_string($new_file_name);
4809
            $safe_post_id = (int) $post_id;
4810
            $safe_id_attach = (int) $id_attach;
4811
            // Storing the attachments if any.
4812 View Code Duplication
            if ($result) {
4813
                $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']."'
4814
                       WHERE c_id = $course_id AND id = '$safe_id_attach'";
4815
                Database::query($sql);
4816
                api_item_property_update($_course, TOOL_FORUM_ATTACH, $safe_id_attach, 'ForumAttachmentUpdated', api_get_user_id());
4817
            }
4818
        }
4819
    }
4820
}
4821
4822
/**
4823
 * Show a list with all the attachments according to the post's id
4824
 * @param int $post_id
4825
 * @return array with the post info
4826
 * @author Julio Montoya
4827
 * @version avril 2008, dokeos 1.8.5
4828
 */
4829
function get_attachment($post_id)
4830
{
4831
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4832
    $course_id = api_get_course_int_id();
4833
    $row = array();
4834
    $post_id = intval($post_id);
4835
    $sql = "SELECT iid, path, filename, comment 
4836
            FROM $forum_table_attachment
4837
            WHERE c_id = $course_id AND post_id = $post_id";
4838
    $result = Database::query($sql);
4839
    if (Database::num_rows($result) != 0) {
4840
        $row = Database::fetch_array($result);
4841
    }
4842
4843
    return $row;
4844
}
4845
4846
/**
4847
 * @param int $postId
4848
 *
4849
 * @return array
4850
 */
4851
function getAllAttachment($postId)
4852
{
4853
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4854
    $courseId = api_get_course_int_id();
4855
    $postId = intval($postId);
4856
    $columns = array('iid', 'path', 'filename', 'comment');
4857
    $conditions = array(
4858
        'where' => array(
4859
            'c_id = ? AND post_id = ?' => array($courseId, $postId),
4860
        ),
4861
    );
4862
    $array = Database::select(
4863
        $columns,
4864
        $forumAttachmentTable,
4865
        $conditions,
4866
        'all',
4867
        'ASSOC'
4868
    );
4869
4870
    return $array;
4871
}
4872
4873
/**
4874
 * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
4875
 * @param int $post_id
4876
 * @param int $id_attach
4877
 * @param bool $display to show or not result message
4878
 * @return integer
4879
 * @author Julio Montoya
4880
 * @version october 2014, chamilo 1.9.8
4881
 */
4882
function delete_attachment($post_id, $id_attach = 0, $display = true)
4883
{
4884
    $_course = api_get_course_info();
4885
4886
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4887
    $course_id = api_get_course_int_id();
4888
4889
    $cond = (!empty($id_attach)) ? " iid = " . (int) $id_attach . "" : " post_id = " . (int) $post_id . "";
4890
    $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
4891
    $res = Database::query($sql);
4892
    $row = Database::fetch_array($res);
4893
4894
    $course_dir = $_course['path'] . '/upload/forum';
4895
    $sys_course_path = api_get_path(SYS_COURSE_PATH);
4896
    $updir = $sys_course_path . $course_dir;
4897
    $my_path = isset($row['path']) ? $row['path'] : null;
4898
    $file = $updir . '/' . $my_path;
4899
    if (Security::check_abs_path($file, $updir)) {
4900
        @unlink($file);
4901
    }
4902
4903
    // Delete from forum_attachment table.
4904
    $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
4905
    $result = Database::query($sql);
4906
    if ($result !== false) {
4907
        $affectedRows = Database::affected_rows($result);
4908
    } else {
4909
        $affectedRows = 0;
4910
    }
4911
4912
    // Update item_property.
4913
    api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
4914
4915
    if (!empty($result) && !empty($id_attach) && $display) {
4916
        $message = get_lang('AttachmentFileDeleteSuccess');
4917
        echo Display::return_message($message, 'confirmation');
4918
    }
4919
4920
    return $affectedRows;
4921
}
4922
4923
/**
4924
 * This function gets all the forum information of the all the forum of the group
4925
 *
4926
 * @param integer $groupId the id of the group we need the fora of (see forum.forum_of_group)
0 ignored issues
show
Bug introduced by
There is no parameter named $groupId. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
4927
 * @return array
4928
 *
4929
 * @todo this is basically the same code as the get_forums function. Consider merging the two.
4930
 */
4931
function get_forums_of_group($groupInfo)
4932
{
4933
    $table_forums = Database::get_course_table(TABLE_FORUM);
4934
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
4935
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
4936
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
4937
    $course_id = api_get_course_int_id();
4938
    $groupId = (int) $groupInfo['id'];
4939
4940
    // Student
4941
    // Select all the forum information of all forums (that are visible to students).
4942
4943
    $sql = "SELECT * FROM $table_forums forum 
4944
            INNER JOIN $table_item_property item_properties
4945
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
4946
            WHERE
4947
                forum.forum_of_group = $groupId AND
4948
                forum.c_id = $course_id AND
4949
                item_properties.c_id = $course_id AND                
4950
                item_properties.visibility = 1 AND
4951
                item_properties.tool = '".TOOL_FORUM."'
4952
            ORDER BY forum.forum_order ASC";
4953
4954
    // Select the number of threads of the forums (only the threads that are visible).
4955
    $sql2 = "SELECT 
4956
                count(thread_id) AS number_of_threads, 
4957
                threads.forum_id
4958
            FROM $table_threads threads 
4959
            INNER JOIN $table_item_property item_properties
4960
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
4961
            WHERE                
4962
                threads.c_id = $course_id AND
4963
                item_properties.c_id = $course_id AND
4964
                item_properties.visibility = 1 AND
4965
                item_properties.tool='".TOOL_FORUM_THREAD."'
4966
            GROUP BY threads.forum_id";
4967
4968
    // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
4969
    $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id
4970
            FROM $table_posts posts 
4971
            INNER JOIN $table_threads threads 
4972
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
4973
            INNER JOIN $table_item_property item_properties
4974
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
4975
            WHERE 
4976
                posts.visible=1 AND
4977
                posts.c_id = $course_id AND
4978
                item_properties.c_id = $course_id AND
4979
                threads.c_id = $course_id AND 
4980
                item_properties.visibility = 1 AND 
4981
                item_properties.tool='".TOOL_FORUM_THREAD."'
4982
            GROUP BY threads.forum_id";
4983
4984
    // Course Admin
4985 View Code Duplication
    if (api_is_allowed_to_edit()) {
4986
        // Select all the forum information of all forums (that are not deleted).
4987
        $sql = "SELECT *
4988
                FROM $table_forums forum INNER JOIN $table_item_property item_properties
4989
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
4990
                WHERE
4991
                    forum.forum_of_group = $groupId AND
4992
                    forum.c_id = $course_id AND
4993
                    item_properties.c_id = $course_id AND                    
4994
                    item_properties.visibility <> 2 AND
4995
                    item_properties.tool = '".TOOL_FORUM."'
4996
                ORDER BY forum_order ASC";
4997
4998
        // Select the number of threads of the forums (only the threads that are not deleted).
4999
        $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
5000
                 FROM $table_threads threads INNER JOIN $table_item_property item_properties
5001
                 ON (threads.thread_id=item_properties.ref AND item_properties.c_id = threads.c_id)
5002
                 WHERE
5003
                    threads.c_id = $course_id AND
5004
                    item_properties.c_id = $course_id AND
5005
                    item_properties.visibility <> 2 AND
5006
                    item_properties.tool='".TOOL_FORUM_THREAD."'
5007
                GROUP BY threads.forum_id";
5008
        // Select the number of posts of the forum.
5009
        $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id
5010
                FROM $table_posts
5011
                WHERE c_id = $course_id 
5012
                GROUP BY forum_id";
5013
    }
5014
5015
    // Handling all the forum information.
5016
    $result = Database::query($sql);
5017
    $forum_list = array();
5018
    while ($row = Database::fetch_array($result, 'ASSOC')) {
5019
        $forum_list[$row['forum_id']] = $row;
5020
    }
5021
5022
    // Handling the thread count information.
5023
    $result2 = Database::query($sql2);
5024 View Code Duplication
    while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
5025
        if (is_array($forum_list)) {
5026
            if (array_key_exists($row2['forum_id'], $forum_list)) {
5027
                $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
5028
            }
5029
        }
5030
    }
5031
5032
    // Handling the post count information.
5033
    $result3 = Database::query($sql3);
5034 View Code Duplication
    while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
5035
        if (is_array($forum_list)) {
5036
            if (array_key_exists($row3['forum_id'], $forum_list)) {
5037
                // This is needed because sql3 takes also the deleted forums into account.
5038
                $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
5039
            }
5040
        }
5041
    }
5042
5043
    // Finding the last post information
5044
    // (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
5045
    if (!empty($forum_list)) {
5046 View Code Duplication
        foreach ($forum_list as $key => $value) {
5047
            $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit());
5048
            if ($last_post_info_of_forum) {
5049
                $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
5050
                $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
5051
                $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
5052
                $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
5053
                $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
5054
                $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
5055
            }
5056
        }
5057
    }
5058
5059
    return $forum_list;
5060
}
5061
5062
/**
5063
 * This function stores which users have to be notified of which forums or threads
5064
 *
5065
 * @param string $content does the user want to be notified about a forum or about a thread
5066
 * @param integer $id the id of the forum or thread
5067
 * @return string language variable
5068
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5069
 * @version May 2008, dokeos 1.8.5
5070
 * @since May 2008, dokeos 1.8.5
5071
 */
5072
function set_notification($content, $id, $add_only = false)
5073
{
5074
    $_user = api_get_user_info();
5075
5076
    // Database table definition
5077
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5078
5079
    $course_id = api_get_course_int_id();
5080
5081
    // Which database field do we have to store the id in?
5082
    if ($content == 'forum') {
5083
        $database_field = 'forum_id';
5084
    } else {
5085
        $database_field = 'thread_id';
5086
    }
5087
5088
    // First we check if the notification is already set for this.
5089
    $sql = "SELECT * FROM $table_notification
5090
            WHERE
5091
                c_id = $course_id AND
5092
                $database_field = '".Database::escape_string($id)."' AND
5093
                user_id = '".intval($_user['user_id'])."'";
5094
    $result = Database::query($sql);
5095
    $total = Database::num_rows($result);
5096
5097
    // If the user did not indicate that (s)he wanted to be notified already
5098
    // then we store the notification request (to prevent double notification requests).
5099
    if ($total <= 0) {
5100
        $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id)
5101
                VALUES (".$course_id.", '".Database::escape_string($id)."','".intval($_user['user_id'])."')";
5102
        Database::query($sql);
5103
        Session::erase('forum_notification');
5104
        get_notifications_of_user(0, true);
5105
5106
        return get_lang('YouWillBeNotifiedOfNewPosts');
5107
    } else {
5108
        if (!$add_only) {
5109
            $sql = "DELETE FROM $table_notification
5110
                    WHERE
5111
                        c_id = $course_id AND
5112
                        $database_field = '".Database::escape_string($id)."' AND
5113
                        user_id = '".intval($_user['user_id'])."'";
5114
            Database::query($sql);
5115
            Session::erase('forum_notification');
5116
            get_notifications_of_user(0, true);
5117
5118
            return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
5119
        }
5120
    }
5121
}
5122
5123
/**
5124
 * This function retrieves all the email adresses of the users who wanted to be notified
5125
 * about a new post in a certain forum or thread
5126
 *
5127
 * @param string $content does the user want to be notified about a forum or about a thread
5128
 * @param integer $id the id of the forum or thread
5129
 * @return array returns
5130
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5131
 * @version May 2008, dokeos 1.8.5
5132
 * @since May 2008, dokeos 1.8.5
5133
 */
5134
function get_notifications($content, $id)
5135
{
5136
    // Database table definition
5137
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5138
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5139
5140
    $course_id = api_get_course_int_id();
5141
5142
    // Which database field contains the notification?
5143
    if ($content == 'forum') {
5144
        $database_field = 'forum_id';
5145
    } else {
5146
        $database_field = 'thread_id';
5147
    }
5148
5149
    $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
5150
            FROM $table_users user, $table_notification notification
5151
            WHERE notification.c_id = $course_id AND user.active = 1 AND
5152
            user.user_id = notification.user_id AND
5153
            notification.$database_field= '".Database::escape_string($id)."'";
5154
5155
    $result = Database::query($sql);
5156
    $return = array();
5157
5158
    while ($row = Database::fetch_array($result)) {
5159
        $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
5160
    }
5161
5162
    return $return;
5163
}
5164
5165
/**
5166
 * Get all the users who need to receive a notification of a new post (those subscribed to
5167
 * the forum or the thread)
5168
 *
5169
 * @param integer $forum_id the id of the forum
5170
 * @param integer $thread_id the id of the thread
5171
 * @param integer $post_id the id of the post
5172
 * @return false|null
5173
 *
5174
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5175
 * @version May 2008, dokeos 1.8.5
5176
 * @since May 2008, dokeos 1.8.5
5177
 */
5178
function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
5179
{
5180
    $_course = api_get_course_info();
5181
    $forum_id = (int) $forum_id;
5182
5183
    // The content of the mail
5184
    $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forum_id.'&thread='.$thread_id;
5185
5186
    // Users who subscribed to the forum
5187
    if ($forum_id != 0) {
5188
        $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
5189
    } else {
5190
        return false;
5191
    }
5192
5193
    $current_thread = get_thread_information($forum_id, $thread_id);
5194
    $current_forum = get_forum_information($current_thread['forum_id']);
5195
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
5196
5197
    // User who subscribed to the thread
5198
    if ($thread_id != 0) {
5199
        $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
5200
    }
5201
5202
    // Merging the two
5203
    $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
5204
    $sender_id = api_get_user_id();
5205
5206
    if (is_array($users_to_be_notified)) {
5207
        foreach ($users_to_be_notified as $value) {
5208
5209
            $user_info = api_get_user_info($value['user_id']);
5210
            $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
5211
            $email_body .= get_lang('NewForumPost').": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
5212
            $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."]  <br />\n";
5213
            $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
5214
            $email_body .= get_lang('ThreadCanBeFoundHere').': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
5215
5216
            MessageManager::send_message_simple(
5217
                $value['user_id'], $subject, $email_body, $sender_id
5218
            );
5219
        }
5220
    }
5221
}
5222
5223
/**
5224
 * Get all the notification subscriptions of the user
5225
 * = which forums and which threads does the user wants to be informed of when a new
5226
 * post is added to this thread
5227
 *
5228
 * @param integer $user_id the user_id of a user (default = 0 => the current user)
5229
 * @param boolean $force force get the notification subscriptions (even if the information is already in the session
5230
 * @return array returns
5231
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5232
 * @version May 2008, dokeos 1.8.5
5233
 * @since May 2008, dokeos 1.8.5
5234
 */
5235
function get_notifications_of_user($user_id = 0, $force = false)
5236
{
5237
    // Database table definition
5238
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5239
    $course_id = api_get_course_int_id();
5240
    if (empty($course_id) || $course_id == -1) {
5241
        return null;
5242
    }
5243
    if ($user_id == 0) {
5244
        $user_id = api_get_user_id();
5245
    }
5246
5247
    if (!isset($_SESSION['forum_notification']) ||
5248
        $_SESSION['forum_notification']['course'] != $course_id ||
5249
        $force = true
5250
    ) {
5251
        $_SESSION['forum_notification']['course'] = $course_id;
5252
5253
        $sql = "SELECT * FROM $table_notification
5254
                WHERE c_id = $course_id AND user_id='".intval($user_id)."'";
5255
        $result = Database::query($sql);
5256
        while ($row = Database::fetch_array($result)) {
5257
            if (!is_null($row['forum_id'])) {
5258
                $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
5259
            }
5260
            if (!is_null($row['thread_id'])) {
5261
                $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
5262
            }
5263
        }
5264
    }
5265
}
5266
5267
/**
5268
 * This function counts the number of post inside a thread
5269
 * @param   int $thread_id
5270
 * @return  int the number of post inside a thread
5271
 * @author Jhon Hinojosa <[email protected]>,
5272
 * @version octubre 2008, dokeos 1.8
5273
 */
5274 View Code Duplication
function count_number_of_post_in_thread($thread_id)
5275
{
5276
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5277
    $course_id = api_get_course_int_id();
5278
    if (empty($course_id)) {
5279
        return 0;
5280
    }
5281
    $sql = "SELECT count(*) count FROM $table_posts
5282
            WHERE 
5283
                c_id = $course_id AND 
5284
                thread_id='".intval($thread_id)."' ";
5285
    $result = Database::query($sql);
5286
5287
    $count = 0;
5288
    if (Database::num_rows($result) > 0) {
5289
        $row = Database::fetch_array($result);
5290
        $count = $row['count'];
5291
    }
5292
5293
    return $count;
5294
}
5295
5296
/**
5297
 * This function counts the number of post inside a thread user
5298
 * @param   int $thread_id
5299
 * @param   int $user_id
5300
 *
5301
 * @return  int the number of post inside a thread user
5302
 */
5303 View Code Duplication
function count_number_of_post_for_user_thread($thread_id, $user_id)
5304
{
5305
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5306
    $course_id = api_get_course_int_id();
5307
    $sql = "SELECT count(iid) as count 
5308
            FROM $table_posts
5309
            WHERE c_id = $course_id AND
5310
                  thread_id=".intval($thread_id)." AND
5311
                  poster_id = ".intval($user_id)." AND visible = 1 ";
5312
    $result = Database::query($sql);
5313
    $count = 0;
5314
    if (Database::num_rows($result) > 0) {
5315
        $count = Database::fetch_array($result);
5316
        $count = $count['count'];
5317
    }
5318
5319
    return $count;
5320
}
5321
5322
/**
5323
 * This function counts the number of user register in course
5324
 * @param   int $course_id Course ID
5325
 * @deprecated use CourseManager::get_users_count_in_course
5326
 * @return  int the number of user register in course
5327
 * @author Jhon Hinojosa <[email protected]>,
5328
 * @version octubre 2008, dokeos 1.8
5329
 */
5330
function count_number_of_user_in_course($course_id)
5331
{
5332
    $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5333
5334
    $sql = "SELECT * FROM $table
5335
            WHERE c_id ='".intval($course_id)."' ";
5336
    $result = Database::query($sql);
5337
5338
    return count(Database::store_result($result));
5339
}
5340
5341
/**
5342
 * This function retrieves information of statistical
5343
 * @param   int $thread_id
5344
 * @param   int $user_id
5345
 * @param   int $course_id
5346
 *
5347
 * @return  array the information of statistical
5348
 * @author Jhon Hinojosa <[email protected]>,
5349
 * @version oct 2008, dokeos 1.8
5350
 */
5351
function get_statistical_information($thread_id, $user_id, $course_id)
5352
{
5353
    $result = array();
5354
    $courseInfo = api_get_course_info_by_id($course_id);
5355
    $result['user_course'] = CourseManager::get_users_count_in_course($courseInfo['code']);
5356
    $result['post'] = count_number_of_post_in_thread($thread_id);
5357
    $result['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
5358
5359
    return $result;
5360
}
5361
5362
/**
5363
 * This function return the posts inside a thread from a given user
5364
 * @param   string $course_code
5365
 * @param   int $thread_id
5366
 * @param   int $user_id
5367
 *
5368
 * @return  array posts inside a thread
5369
 * @author Jhon Hinojosa <[email protected]>,
5370
 * @version oct 2008, dokeos 1.8
5371
 */
5372
function get_thread_user_post($course_code, $thread_id, $user_id)
5373
{
5374
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5375
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5376
    $thread_id = intval($thread_id);
5377
    $user_id = intval($user_id);
5378
    $course_info = api_get_user_info($course_code);
5379
    $course_id = $course_info['real_id'];
5380
5381
    if (empty($course_id)) {
5382
        $course_id = api_get_course_int_id();
5383
    }
5384
    $sql = "SELECT * FROM $table_posts posts
5385
            LEFT JOIN  $table_users users
5386
                ON posts.poster_id=users.user_id
5387
            WHERE
5388
                posts.c_id = $course_id AND
5389
                posts.thread_id='$thread_id'
5390
                AND posts.poster_id='$user_id'
5391
            ORDER BY posts.post_id ASC";
5392
5393
    $result = Database::query($sql);
5394
    $post_list = array();
5395 View Code Duplication
    while ($row = Database::fetch_array($result)) {
5396
        $row['status'] = '1';
5397
        $post_list[] = $row;
5398
        $sql = "SELECT * FROM $table_posts posts
5399
                LEFT JOIN $table_users users
5400
                ON (posts.poster_id=users.user_id)
5401
                WHERE
5402
                    posts.c_id = $course_id AND
5403
                    posts.thread_id='$thread_id'
5404
                    AND posts.post_parent_id='".$row['post_id']."'
5405
                ORDER BY posts.post_id ASC";
5406
        $result2 = Database::query($sql);
5407
        while ($row2 = Database::fetch_array($result2)) {
5408
            $row2['status'] = '0';
5409
            $post_list[] = $row2;
5410
        }
5411
    }
5412
5413
    return $post_list;
5414
}
5415
5416
/**
5417
 * This function get the name of an thread by id
5418
 * @param int thread_id
5419
 * @return String
5420
 * @author Christian Fasanando
5421
 * @author Julio Montoya <[email protected]> Adding security
5422
 */
5423
function get_name_thread_by_id($thread_id)
5424
{
5425
    $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
5426
    $course_id = api_get_course_int_id();
5427
    $sql = "SELECT thread_title 
5428
            FROM $t_forum_thread
5429
            WHERE c_id = $course_id AND thread_id = '".intval($thread_id)."' ";
5430
    $result = Database::query($sql);
5431
    $row = Database::fetch_array($result);
5432
5433
    return $row[0];
5434
}
5435
5436
/**
5437
 * This function gets all the post written by an user
5438
 * @param int $user_id
5439
 * @param string $course_code
5440
 *
5441
 * @return string
5442
 */
5443
function get_all_post_from_user($user_id, $course_code)
5444
{
5445
    $j = 0;
5446
    $forums = get_forums('', $course_code);
5447
    krsort($forums);
5448
    $forum_results = '';
5449
5450
    foreach ($forums as $forum) {
5451
        if ($forum['visibility'] == 0) {
5452
            continue;
5453
        }
5454
        if ($j <= 4) {
5455
            $threads = get_threads($forum['forum_id']);
5456
5457
            if (is_array($threads)) {
5458
                $i = 0;
5459
                $hand_forums = '';
5460
                $post_counter = 0;
5461
5462
                foreach ($threads as $thread) {
5463
                    if ($thread['visibility'] == 0) {
5464
                        continue;
5465
                    }
5466
                    if ($i <= 4) {
5467
                        $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
5468
                        $post_counter = count($post_list);
5469
                        if (is_array($post_list) && count($post_list) > 0) {
5470
                            $hand_forums.= '<div id="social-thread">';
5471
                            $hand_forums.= Display::return_icon('thread.png', get_lang('Thread'), '', ICON_SIZE_MEDIUM);
5472
                            $hand_forums.= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
5473
                            $hand_forums.= '</div>';
5474
5475
                            foreach ($post_list as $posts) {
5476
                                $hand_forums.= '<div id="social-post">';
5477
                                $hand_forums.= '<strong>'.Security::remove_XSS($posts['post_title'], STUDENT).'</strong>';
5478
                                $hand_forums.= '<br / >';
5479
                                $hand_forums.= Security::remove_XSS($posts['post_text'], STUDENT);
5480
                                $hand_forums.= '</div>';
5481
                                $hand_forums.= '<br / >';
5482
                            }
5483
                        }
5484
                    }
5485
                    $i++;
5486
                }
5487
                $forum_results .='<div id="social-forum">';
5488
                $forum_results .='<div class="clear"></div><br />';
5489
                $forum_results .='<div id="social-forum-title">'.
5490
                    Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS($forum['forum_title'], STUDENT).
5491
                    '<div style="float:right;margin-top:-35px">
5492
                        <a href="../forum/viewforum.php?'.api_get_cidreq_params($course_code).'&forum='.$forum['forum_id'].' " >'.
5493
                            get_lang('SeeForum').'    
5494
                        </a>
5495
                     </div></div>';
5496
                $forum_results .='<br / >';
5497
                if ($post_counter > 0) {
5498
                    $forum_results .=$hand_forums;
5499
                }
5500
                $forum_results .='</div>';
5501
            }$j++;
5502
        }
5503
    }
5504
5505
    return $forum_results;
5506
}
5507
5508
/**
5509
 * @param string $course_code
5510
 * @param int $thread_id
5511
 * @param int $user_id
5512
 * @param int $limit
5513
 *
5514
 * @return array
5515
 */
5516
function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
5517
{
5518
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5519
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5520
5521
    $course_info = api_get_course_info($course_code);
5522
    $course_id = $course_info['real_id'];
5523
5524
    $sql = "SELECT * FROM $table_posts posts
5525
            LEFT JOIN  $table_users users
5526
                ON posts.poster_id=users.user_id
5527
            WHERE
5528
                posts.c_id = $course_id AND
5529
                posts.thread_id='".Database::escape_string($thread_id)."'
5530
                AND posts.poster_id='".Database::escape_string($user_id)."'
5531
            ORDER BY posts.post_id DESC LIMIT $limit ";
5532
    $result = Database::query($sql);
5533
    $post_list = array();
5534
    while ($row = Database::fetch_array($result)) {
5535
        $row['status'] = '1';
5536
        $post_list[] = $row;
5537
    }
5538
5539
    return $post_list;
5540
}
5541
5542
/**
5543
 * @param string $user_id
5544
 * @param int $courseId
5545
 * @param int $sessionId
5546
 *
5547
 * @return array
5548
 */
5549
function getForumCreatedByUser($user_id, $courseId, $sessionId)
5550
{
5551
    $items = api_get_item_property_list_by_tool_by_user(
5552
        $user_id,
5553
        'forum',
5554
        $courseId,
5555
        $sessionId
5556
    );
5557
5558
    $courseInfo = api_get_course_info_by_id($courseId);
5559
5560
    $forumList = array();
5561 View Code Duplication
    if (!empty($items)) {
5562
        foreach ($items as $forum) {
5563
            $forumInfo = get_forums(
5564
                $forum['ref'],
5565
                $courseInfo['code'],
5566
                true,
5567
                $sessionId
5568
            );
5569
5570
            $forumList[] = array(
5571
                $forumInfo['forum_title'],
5572
                api_get_local_time($forum['insert_date']),
5573
                api_get_local_time($forum['lastedit_date']),
5574
            );
5575
        }
5576
    }
5577
5578
    return $forumList;
5579
}
5580
5581
/**
5582
 * This function builds an array of all the posts in a given thread
5583
 * where the key of the array is the post_id
5584
 * It also adds an element children to the array which itself is an array
5585
 * that contains all the id's of the first-level children
5586
 * @return array $rows containing all the information on the posts of a thread
5587
 * @author Patrick Cool <[email protected]>, Ghent University
5588
 */
5589
function calculate_children($rows)
5590
{
5591
    $sorted_rows = array(0 => array());
5592
    if (!empty($rows)) {
5593
        foreach ($rows as $row) {
5594
            $rows_with_children[$row['post_id']] = $row;
5595
            $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
5596
        }
5597
5598
        $rows = $rows_with_children;
5599
        forumRecursiveSort($rows, $sorted_rows);
5600
        unset($sorted_rows[0]);
5601
    }
5602
5603
    return $sorted_rows;
5604
}
5605
5606
/**
5607
 * @param $rows
5608
 * @param $threads
5609
 * @param int $seed
5610
 * @param int $indent
5611
 */
5612
function forumRecursiveSort($rows, &$threads, $seed = 0, $indent = 0)
5613
{
5614
    if ($seed > 0) {
5615
        $threads[$rows[$seed]['post_id']] = $rows[$seed];
5616
        $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
5617
        $indent++;
5618
    }
5619
5620
    if (isset($rows[$seed]['children'])) {
5621
        foreach ($rows[$seed]['children'] as $child) {
5622
            forumRecursiveSort($rows, $threads, $child, $indent);
5623
        }
5624
    }
5625
}
5626
5627
/**
5628
 * Update forum attachment data, used to update comment and post ID.
5629
 * @param $array Array (field => value) to update forum attachment row.
5630
 * @param $id Attach ID to find row to update.
5631
 * @param null $courseId Course ID to find row to update.
5632
 * @return int Number of affected rows.
5633
 */
5634
function editAttachedFile($array, $id, $courseId = null) {
5635
    // Init variables
5636
    $setString = '';
5637
    $id = intval($id);
5638
    $courseId = intval($courseId);
5639
    if (empty($courseId)) {
5640
        // $courseId can be null, use api method
5641
        $courseId= api_get_course_int_id();
5642
    }
5643
    /*
5644
     * Check if Attachment ID and Course ID are greater than zero
5645
     * and array of field values is not empty
5646
     */
5647
    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
5648
        foreach($array as $key => &$item) {
5649
            $item = Database::escape_string($item);
5650
            $setString .= $key . ' = "' .$item . '", ';
5651
        }
5652
        // Delete last comma
5653
        $setString = substr($setString, 0, strlen($setString) - 2);
5654
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5655
        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
5656
        $result = Database::query($sql);
5657
        if ($result !== false) {
5658
            $affectedRows = Database::affected_rows($result);
5659 View Code Duplication
            if ($affectedRows > 0) {
5660
                /*
5661
                 * If exist in $_SESSION variable, then delete them from it
5662
                 * because they would be deprecated
5663
                 */
5664
                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
5665
                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
5666
                }
5667
            }
5668
5669
            return $affectedRows;
5670
        }
5671
    }
5672
5673
    return 0;
5674
}
5675
5676
/**
5677
 * Return a table where the attachments will be set
5678
 * @param int $postId Forum Post ID
5679
 *
5680
 * @return string The Forum Attachments Ajax Table
5681
 */
5682
function getAttachmentsAjaxTable($postId = 0)
5683
{
5684
    // Init variables
5685
    $postId = intval($postId);
5686
    $courseId = api_get_course_int_id();
5687
    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5688
    $fileDataContent = '';
5689
    // Update comment to show if form did not pass validation
5690
    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
5691
        // 'file_ids is the name from forum attachment ajax form
5692
        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
5693
            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) &&
5694
                is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])
5695
            ) {
5696
                // If exist forum attachment then update into $_SESSION data
5697
                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
5698
            }
5699
        }
5700
    }
5701
5702
    // Get data to fill into attachment files table
5703
    if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5704
        is_array($_SESSION['forum']['upload_file'][$courseId])
5705
    ) {
5706
        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
5707
        foreach ($uploadedFiles as $k => $uploadedFile) {
5708
            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
5709
                // Buil html table including an input with attachmentID
5710
                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
5711
                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
5712
                    $uploadedFile['delete'] . '</td>' .
5713
                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
5714
            } else {
5715
                /*
5716
                 * If attachment data is empty, then delete it from $_SESSION
5717
                 * because could generate and empty row into html table
5718
                 */
5719
                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
5720
            }
5721
        }
5722
    }
5723
    $style = empty($fileDataContent) ? 'display: none;' : '';
5724
    // Forum attachment Ajax table
5725
    $fileData = '
5726
    <div class="control-group " style="'. $style . '">
5727
        <label class="control-label">'.get_lang('AttachmentList').'</label>
5728
        <div class="controls">
5729
            <table id="attachmentFileList" class="files data_table span10">
5730
                <tr>
5731
                    <th>'.get_lang('FileName').'</th>
5732
                    <th>'.get_lang('Size').'</th>
5733
                    <th>'.get_lang('Status').'</th>
5734
                    <th>'.get_lang('Comment').'</th>
5735
                    <th>'.get_lang('Delete').'</th>
5736
                </tr>
5737
                '.$fileDataContent.'
5738
            </table>
5739
        </div>
5740
    </div>';
5741
5742
    return $fileData;
5743
}
5744
5745
/**
5746
 * Return an array of prepared attachment data to build forum attachment table
5747
 * Also, save this array into $_SESSION to do available the attachment data
5748
 * @param int $forumId
5749
 * @param int $threadId
5750
 * @param int $postId
5751
 * @param int $attachId
5752
 * @param int $courseId
5753
 *
5754
 * @return array
5755
 */
5756
function getAttachedFiles($forumId, $threadId, $postId = 0, $attachId = 0, $courseId = 0)
5757
{
5758
    $forumId = intval($forumId);
5759
    $courseId = intval($courseId);
5760
    $attachId = intval($attachId);
5761
    $postId = intval($postId);
5762
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5763
    if (empty($courseId)) {
5764
        // $courseId can be null, use api method
5765
        $courseId = api_get_course_int_id();
5766
    }
5767
    if (empty($forumId)) {
5768
        if (!empty($_REQUEST['forum'])) {
5769
            $forumId = intval($_REQUEST['forum']);
5770
        } else {
5771
            // if forum ID is empty, cannot generate delete url
5772
5773
            return array();
5774
        }
5775
    }
5776
    // Check if exist at least one of them to filter forum attachment select query
5777
    if (empty($postId) && empty($attachId)) {
5778
5779
        return array();
5780
    } elseif (empty($postId)) {
5781
        $filter = "AND iid = $attachId";
5782
    } elseif (empty($attachId)) {
5783
        $filter = "AND post_id = $postId";
5784
    } else {
5785
        $filter = "AND post_id = $postId AND iid = $attachId";
5786
    }
5787
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5788
    $sql = "SELECT iid, comment, filename, path, size
5789
            FROM $forumAttachmentTable
5790
            WHERE c_id = $courseId $filter";
5791
    $result = Database::query($sql);
5792
    $json = array();
5793
    if ($result !== false && Database::num_rows($result) > 0) {
5794
        while ($row = Database::fetch_array($result, 'ASSOC')) {
5795
            // name contains an URL to download attachment file and its filename
5796
            $json['name'] = Display::url(
5797
                api_htmlentities($row['filename']),
5798
                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'].'&'.api_get_cidreq(),
5799
                array('target'=>'_blank', 'class' => 'attachFilename')
5800
            );
5801
            $json['id'] = $row['iid'];
5802
            $json['comment'] = $row['comment'];
5803
            // Format file size
5804
            $json['size'] = format_file_size($row['size']);
5805
            // Check if $row is consistent
5806
            if (!empty($row) && is_array($row)) {
5807
                // Set result as success and bring delete URL
5808
                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
5809
                $url = api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php?' . api_get_cidreq() . '&action=delete_attach&forum=' . $forumId . '&thread=' . $threadId.'&id_attach=' . $row['iid'];
5810
                $json['delete'] = Display::url(
5811
                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL),
5812
                    $url,
5813
                    array('class' => 'deleteLink')
5814
                );
5815
            } else {
5816
                // If not, set an exclamation result
5817
                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
5818
            }
5819
            // Store array data into $_SESSION
5820
            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
5821
        }
5822
    }
5823
5824
    return $json;
5825
}
5826
5827
/**
5828
 * Clear forum attachment data stored in $_SESSION,
5829
 * If is not defined post, it will clear all forum attachment data from course
5830
 * @param int $postId -1 : Clear all attachments from course stored in $_SESSION
5831
 *                      0 : Clear attachments from course, except from temporal post "0"
5832
 *                          but without delete them from file system and database
5833
 *                     Other values : Clear attachments from course except specified post
5834
 *                          and delete them from file system and database
5835
 * @param int $courseId : Course ID, if it is null, will use api_get_course_int_id()
5836
 *
5837
 * @return array
5838
 */
5839
function clearAttachedFiles($postId = null, $courseId = null) {
5840
    // Init variables
5841
    $courseId = intval($courseId);
5842
    $postId = intval($postId);
5843
    $array = array();
5844
    if (empty($courseId)) {
5845
        // $courseId can be null, use api method
5846
        $courseId = api_get_course_int_id();
5847
    }
5848
    if ($postId === -1) {
5849
        // If post ID is -1 then delete course's attachment data from $_SESSION
5850 View Code Duplication
        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
5851
            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
5852
            unset($_SESSION['forum']['upload_file'][$courseId]);
5853
        }
5854
    } else {
5855
        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5856
        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5857
            is_array($_SESSION['forum']['upload_file'][$courseId])) {
5858
            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
5859
                if (!in_array($attachId, $attachIds)) {
5860
                    // If attach ID is not into specified post, delete attachment
5861
                    // Save deleted attachment ID
5862
                    $array[] = $attachId;
5863
                    if ($postId !== 0) {
5864
                        // Post 0 is temporal, delete them from file system and DB
5865
                        delete_attachment(0, $attachId, false);
5866
                    }
5867
                    // Delete attachment data from $_SESSION
5868
                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
5869
                }
5870
            }
5871
        }
5872
    }
5873
5874
    return $array;
5875
}
5876
5877
/**
5878
 * Returns an array of forum attachment ids into a course and forum post
5879
 * @param int $postId
5880
 * @param int $courseId
5881
 *
5882
 * @return array
5883
 */
5884
function getAttachmentIdsByPostId($postId, $courseId = null)
5885
{
5886
5887
    $array = array();
5888
    $courseId = intval($courseId);
5889
    $postId = intval($postId);
5890
    if (empty($courseId)) {
5891
        // $courseId can be null, use api method
5892
        $courseId = api_get_course_int_id();
5893
    }
5894
    if ($courseId > 0) {
5895
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5896
        $sql = "SELECT id FROM $forumAttachmentTable
5897
                WHERE c_id = $courseId AND post_id = $postId";
5898
        $result = Database::query($sql);
5899
        if ($result !== false && Database::num_rows($result) > 0) {
5900
            while ($row = Database::fetch_array($result,'ASSOC')) {
5901
                $array[] = $row['id'];
5902
            }
5903
        }
5904
    }
5905
    return $array;
5906
}
5907
5908
/**
5909
 * Check if the forum category exists looking for its title
5910
 * @param string $title The forum category title
5911
 * @param int $courseId The course ID
5912
 * @param int $sessionId Optional. The session ID
5913
 * @return boolean
5914
 */
5915
function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
5916
{
5917
    $sessionId = intval($sessionId);
5918
5919
    $forumCategoryTable = Database::get_course_table(TABLE_FORUM_CATEGORY);
5920
    $itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
5921
5922
    $fakeFrom = "$forumCategoryTable fc
5923
        INNER JOIN $itemProperty ip ";
5924
5925
    if ($sessionId === 0) {
5926
        $fakeFrom .= "
5927
            ON (
5928
                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)
5929
            )
5930
        ";
5931
    } else {
5932
        $fakeFrom .= "
5933
            ON (
5934
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND fc.session_id = ip.session_id
5935
            )
5936
        ";
5937
    }
5938
5939
    $resultData = Database::select(
5940
        'fc.*',
5941
        $fakeFrom,
5942
        [
5943
            'where' => [
5944
                'ip.visibility != ? AND ' => 2,
5945
                'ip.tool = ? AND ' => TOOL_FORUM_CATEGORY,
5946
                'fc.session_id = ? AND ' => $sessionId,
5947
                'fc.cat_title = ? AND ' => $title,
5948
                'fc.c_id = ?' => intval($courseId)
5949
            ]
5950
        ],
5951
        'first'
5952
    );
5953
5954
    if (empty($resultData)) {
5955
        return false;
5956
    }
5957
5958
    return $resultData;
5959
}
5960
5961
/**
5962
 * @param array $current_forum
5963
 * @param array $row
5964
 *
5965
 * @return string
5966
 */
5967
function getPostStatus($current_forum, $row, $addWrapper = true)
5968
{
5969
    $statusIcon = '';
5970
    if ($current_forum['moderated']) {
5971
        if ($addWrapper) {
5972
            $statusIcon = '<br /><br /><span id="status_post_'.$row['iid'].'">';
5973
        }
5974
        $row['status'] = empty($row['status']) ? 2 : $row['status'];
5975
5976
        $addUrl = false;
5977
        $showStatus = false;
5978
        if (api_is_allowed_to_edit(false, true)) {
5979
            $addUrl = true;
5980
        } else {
5981
            if ($row['user_id'] == api_get_user_id()) {
5982
                $showStatus = true;
5983
            }
5984
        }
5985
5986
        $label = '';
5987
        $icon = '';
5988
        $buttonType = '';
5989
        switch ($row['status']) {
5990
            case CForumPost::STATUS_VALIDATED:
5991
                $label = get_lang('Validated');
5992
                $icon = 'check-circle';
5993
                $buttonType = 'success';
5994
                break;
5995
            case CForumPost::STATUS_WAITING_MODERATION:
5996
                $label = get_lang('WaitingModeration');
5997
                $icon = 'warning';
5998
                $buttonType = 'warning';
5999
                break;
6000
            case CForumPost::STATUS_REJECTED:
6001
                $label = get_lang('Rejected');
6002
                $icon = 'minus-circle';
6003
                $buttonType = 'danger';
6004
                break;
6005
        }
6006
6007
        if ($addUrl) {
6008
            $statusIcon .= Display::toolbarButton(
6009
                $label.'&nbsp;',
6010
                'javascript:void(0)',
6011
                $icon,
6012
                $buttonType,
6013
                ['class' => 'change_post_status']
6014
            );
6015
        } else {
6016
            if ($showStatus) {
6017
                $statusIcon .= Display::label(
6018
                    Display::returnFontAwesomeIcon($icon).$label,
6019
                    $buttonType
6020
                );
6021
            }
6022
        }
6023
6024
        if ($addWrapper) {
6025
            $statusIcon .= '</span>';
6026
        }
6027
    }
6028
6029
    return $statusIcon;
6030
}
6031
6032
/**
6033
 * @param array $forumInfo
6034
 * @param int $threadId
6035
 * @param int $status
6036
 * @return mixed
6037
 */
6038
function getCountPostsWithStatus($status, $forumInfo, $threadId = null)
6039
{
6040
    $em = Database::getManager();
6041
    $criteria = Criteria::create();
6042
    $criteria
6043
        ->where(Criteria::expr()->eq('status', $status))
6044
        ->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
6045
        ->andWhere(Criteria::expr()->eq('visible', 1))
6046
    ;
6047
6048
    if (!empty($threadId)) {
6049
        $criteria->andWhere(Criteria::expr()->eq('threadId', $threadId));
6050
    }
6051
6052
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
6053
    $qb->select('count(p.iid)')
6054
        ->addCriteria($criteria);
6055
6056
    return $qb->getQuery()->getSingleScalarResult();
6057
}
6058
6059
/**
6060
 * @param array $forum
6061
 * @param array $post
6062
 *
6063
 * @return bool
6064
 */
6065
function postIsEditableByStudent($forum, $post)
6066
{
6067
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
6068
        return true;
6069
    }
6070
6071
    if ($forum['moderated'] == 1) {
6072
        if (is_null($post['status'])) {
6073
            return true;
6074
        } else {
6075
            return in_array($post['status'],
6076
                [
6077
                    CForumPost::STATUS_WAITING_MODERATION,
6078
                    CForumPost::STATUS_REJECTED,
6079
                ]
6080
            );
6081
        }
6082
    } else {
6083
        return true;
6084
    }
6085
}
6086
6087