Completed
Push — 1.10.x ( 7bd44d...00ff6f )
by Angel Fernando Quiroz
204:53 queued 154:38
created

forumfunction.inc.php ➔ delete_post()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 60
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 33
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 60
rs 8.9618

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Consider the follow example

<?php

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

    return false;
}

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

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

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

Consider the follow example

<?php

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

    return false;
}

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

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

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

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

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

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

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

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

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

could be turned into

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

This is much more concise to read.

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