Completed
Push — master ( 2ab56b...9d3aa0 )
by Julito
38:18
created

forumfunction.inc.php ➔ get_whats_new()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 45
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

    return array();
}

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

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

Loading history...
3474
3475
            // Update the forum.
3476
            api_item_property_update(
3477
                $_course,
3478
                TOOL_FORUM,
3479
                $values['forum_id'],
3480
                'NewMessageInForum',
3481
                $userId
3482
            );
3483
3484
            // Insert post
3485
            api_item_property_update(
3486
                $_course,
3487
                TOOL_FORUM_POST,
3488
                $new_post_id,
3489
                'NewPost',
3490
                $userId
3491
            );
3492
3493
            if ($current_forum['approval_direct_post'] == '1' &&
3494
                !api_is_allowed_to_edit(null, true)
3495
            ) {
3496
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3497
            }
3498
3499
            if ($current_forum['moderated'] &&
3500
                !api_is_allowed_to_edit(null, true)
3501
            ) {
3502
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3503
            }
3504
3505
            // Setting the notification correctly.
3506
            $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
3507
            if ($my_post_notification == 1) {
3508
                set_notification('thread', $values['thread_id'], true);
3509
            }
3510
3511
            send_notification_mails(
3512
                $values['forum_id'],
3513
                $values['thread_id'],
3514
                $values
3515
            );
3516
            add_forum_attachment_file('', $new_post_id);
3517
        }
3518
3519
        Session::erase('formelements');
3520
        Session::erase('origin');
3521
        Session::erase('breadcrumbs');
3522
        Session::erase('addedresource');
3523
        Session::erase('addedresourceid');
3524
3525
        Display::addFlash(Display::return_message($message, 'confirmation', false));
3526
    } else {
3527
        Display::addFlash(
3528
            Display::return_message(get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'), 'error')
3529
        );
3530
    }
3531
3532
    return $return;
3533
}
3534
3535
/**
3536
 * This function displays the form that is used to edit a post. This can be a new thread or a reply.
3537
 * @param array contains all the information about the current post
3538
 * @param array contains all the information about the current thread
3539
 * @param array contains all info about the current forum (to check if attachments are allowed)
3540
 * @param array contains the default values to fill the form
3541
 * @return void
3542
 *
3543
 * @author Patrick Cool <[email protected]>, Ghent University
3544
 * @version february 2006, dokeos 1.8
3545
 */
3546
function show_edit_post_form(
3547
    $forum_setting,
3548
    $current_post,
3549
    $current_thread,
3550
    $current_forum,
3551
    $form_values = '',
3552
    $id_attach = 0
3553
) {
3554
    // Initialize the object.
3555
    $form = new FormValidator(
3556
        'edit_post',
3557
        'post',
3558
        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
3559
    );
3560
    $form->addElement('header', get_lang('EditPost'));
3561
    // Setting the form elements.
3562
    $form->addElement('hidden', 'post_id', $current_post['post_id']);
3563
    $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
3564
    $form->addElement('hidden', 'id_attach', $id_attach);
3565
3566
    if (empty($current_post['post_parent_id'])) {
3567
        $form->addElement('hidden', 'is_first_post_of_thread', '1');
3568
    }
3569
3570
    $form->addElement('text', 'post_title', get_lang('Title'));
3571
    $form->applyFilter('post_title', 'html_filter');
3572
    $form->addElement(
3573
        'html_editor',
3574
        'post_text',
3575
        get_lang('Text'),
3576
        null,
3577
        api_is_allowed_to_edit(null, true) ? array(
3578
            'ToolbarSet' => 'Forum',
3579
            'Width' => '100%',
3580
            'Height' => '400',
3581
        ) : array(
3582
            'ToolbarSet' => 'ForumStudent',
3583
            'Width' => '100%',
3584
            'Height' => '400',
3585
            'UserStatus' => 'student',
3586
        )
3587
    );
3588
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
3589
3590
    $form->addButtonAdvancedSettings('advanced_params');
3591
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
3592
3593
    if (!isset($_GET['edit'])) {
3594
        if (Gradebook::is_active()) {
3595
            $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
3596
            $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\';}"');
3597
3598
            $link_info = GradebookUtils::isResourceInCourseGradebook(
3599
                api_get_course_int_id(),
3600
                5,
3601
                $_GET['thread'],
3602
                api_get_session_id()
3603
            );
3604
            if (!empty($link_info)) {
3605
                $defaults['thread_qualify_gradebook'] = true;
3606
                $defaults['category_id'] = $link_info['category_id'];
3607
            } else {
3608
                $defaults['thread_qualify_gradebook'] = false;
3609
                $defaults['category_id'] = '';
3610
            }
3611
        } else {
3612
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
3613
            $defaults['thread_qualify_gradebook'] = false;
3614
        }
3615
3616
        if (!empty($defaults['thread_qualify_gradebook'])) {
3617
            $form->addElement('html', '<div id="options_field" style="display:block">');
3618
        } else {
3619
            $form->addElement('html', '<div id="options_field" style="display:none">');
3620
        }
3621
3622
        // Loading gradebook select
3623
        GradebookUtils::load_gradebook_select_in_tool($form);
3624
3625
        $form->addElement(
3626
            'text',
3627
            'numeric_calification',
3628
            get_lang('QualificationNumeric'),
3629
            array(
3630
                'value' => $current_thread['thread_qualify_max'],
3631
                'style' => 'width:40px',
3632
            )
3633
        );
3634
        $form->applyFilter('numeric_calification', 'html_filter');
3635
3636
        $form->addElement(
3637
            'text',
3638
            'calification_notebook_title',
3639
            get_lang('TitleColumnGradebook'),
3640
            array('value' => $current_thread['thread_title_qualify'])
3641
        );
3642
        $form->applyFilter('calification_notebook_title', 'html_filter');
3643
3644
        $form->addElement(
3645
            'text',
3646
            'weight_calification',
3647
            array(get_lang('QualifyWeight'), null, ''),
3648
            array(
3649
                'value' => $current_thread['thread_weight'],
3650
                'style' => 'width:40px',
3651
            )
3652
        );
3653
        $form->applyFilter('weight_calification', 'html_filter');
3654
3655
        $group = array();
3656
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
3657
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
3658
        $form->addGroup(
3659
            $group,
3660
            '',
3661
            [
3662
                get_lang('ForumThreadPeerScoring'),
3663
                get_lang('ForumThreadPeerScoringComment'),
3664
            ]
3665
        );
3666
3667
        $form->addElement('html', '</div>');
3668
    }
3669
3670
    if ($current_forum['moderated']) {
3671
        $group = array();
3672
        $group[] = $form->createElement('radio', 'status', null, get_lang('Validated'), 1);
3673
        $group[] = $form->createElement('radio', 'status', null, get_lang('WaitingModeration'), 2);
3674
        $group[] = $form->createElement('radio', 'status', null, get_lang('Rejected'), 3);
3675
        $form->addGroup($group, 'status', get_lang('Status'));
3676
    }
3677
3678
    $defaults['status']['status'] = isset($current_post['status']) && !empty($current_post['status']) ? $current_post['status'] : 2;
3679
3680
    if ($forum_setting['allow_post_notification']) {
3681
        $form->addElement('checkbox', 'post_notification', '', get_lang('NotifyByEmail').' ('.$current_post['email'].')');
3682
    }
3683
3684
    if ($forum_setting['allow_sticky'] &&
3685
        api_is_allowed_to_edit(null, true) &&
3686
        empty($current_post['post_parent_id'])
3687
    ) {
3688
        // The sticky checkbox only appears when it is the first post of a thread.
3689
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3690
        if ($current_thread['thread_sticky'] == 1) {
3691
            $defaults['thread_sticky'] = true;
3692
        }
3693
    }
3694
3695
    $form->addElement('html', '</div>');
3696
3697
    $form->addFile('user_upload[]', get_lang('Attachment'));
3698
    $form->addButton(
3699
        'add_attachment',
3700
        get_lang('AddAttachment'),
3701
        'paperclip',
3702
        'default',
3703
        'default',
3704
        null,
3705
        ['id' => 'reply-add-attachment']
3706
    );
3707
3708
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
3709
3710
    // Setting the default values for the form elements.
3711
    $defaults['post_title'] = $current_post['post_title'];
3712
    $defaults['post_text'] = $current_post['post_text'];
3713
3714
    if ($current_post['post_notification'] == 1) {
3715
        $defaults['post_notification'] = true;
3716
    }
3717
3718
    if (!empty($form_values)) {
3719
        $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
3720
        $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
3721
    }
3722
3723
    $defaults['thread_peer_qualify'] = intval($current_thread['thread_peer_qualify']);
3724
3725
    $form->setDefaults($defaults);
3726
3727
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3728
3729
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3730
3731
    // Validation or display
3732
    if ($form->validate()) {
3733
        $values = $form->exportValues();
3734
3735
        if (isset($values['thread_qualify_gradebook']) && $values['thread_qualify_gradebook'] == '1' &&
3736
            empty($values['weight_calification'])
3737
        ) {
3738
            Display::display_error_message(get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>', false);
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_error_message() has been deprecated with message: use Display::addFlash with Display::return_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...
3739
            return false;
3740
        }
3741
        return $values;
3742
    } else {
3743
        // Delete from $_SESSION forum attachment from other posts
3744
        clearAttachedFiles($current_post['post_id']);
3745
        // Get forum attachment ajax table to add it to form
3746
        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
3747
        $form->addElement('html', $fileData);
3748
        $form->display();
3749
    }
3750
}
3751
3752
/**
3753
 * This function stores the edit of a post in the forum_post table.
3754
 *
3755
 * @param array
3756
 * @return void HTML
3757
 *
3758
 * @author Patrick Cool <[email protected]>, Ghent University
3759
 * @version february 2006, dokeos 1.8
3760
 */
3761
function store_edit_post($forumInfo, $values)
3762
{
3763
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
3764
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3765
    $gradebook = Security::remove_XSS($_GET['gradebook']);
3766
    $course_id = api_get_course_int_id();
3767
3768
    //check if this post is the first of the thread
3769
    // First we check if the change affects the thread and if so we commit
3770
    // the changes (sticky and post_title=thread_title are relevant).
3771
3772
    $posts = getPosts($forumInfo, $values['thread_id']);
3773
    $first_post = null;
3774
    if (!empty($posts) && count($posts) > 0 && isset($posts[0])) {
3775
        $first_post = $posts[0];
3776
    }
3777
3778
    if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
3779
        $params = [
3780
            'thread_title' => $values['post_title'],
3781
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
3782
            'thread_title_qualify' => $values['calification_notebook_title'],
3783
            'thread_qualify_max' => $values['numeric_calification'],
3784
            'thread_weight' => $values['weight_calification'],
3785
            'thread_peer_qualify' => $values['thread_peer_qualify'],
3786
        ];
3787
        $where = ['c_id = ? AND thread_id = ?' => [$course_id, $values['thread_id']]];
3788
3789
        Database::update($threadTable, $params, $where);
3790
    }
3791
3792
    $status = '';
3793
    if ($forumInfo['moderated']) {
3794
        $status = $values['status']['status'];
3795
    }
3796
3797
    // Update the post_title and the post_text.
3798
    $params = [
3799
        'status' => $status,
3800
        'post_title' => $values['post_title'],
3801
        'post_text' => $values['post_text'],
3802
        'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
3803
    ];
3804
    $where = ['c_id = ? AND post_id = ?' => [$course_id, $values['post_id']]];
3805
3806
    Database::update($table_posts, $params, $where);
3807
3808
    // Update attached files
3809 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3810
        foreach ($_POST['file_ids'] as $key => $id) {
3811
            editAttachedFile(
3812
                array(
3813
                    'comment' => $_POST['file_comments'][$key],
3814
                    'post_id' => $values['post_id'],
3815
                ),
3816
                $id
3817
            );
3818
        }
3819
    }
3820
3821
    if (!empty($values['remove_attach'])) {
3822
        delete_attachment($values['post_id']);
3823
    }
3824
3825
    if (empty($values['id_attach'])) {
3826
        add_forum_attachment_file(
3827
            isset($values['file_comment']) ? $values['file_comment'] : null,
3828
            $values['post_id']
3829
        );
3830
    } else {
3831
        edit_forum_attachment_file(
3832
            isset($values['file_comment']) ? $values['file_comment'] : null,
3833
            $values['post_id'],
3834
            $values['id_attach']
3835
        );
3836
    }
3837
3838
    $message = get_lang('EditPostStored').'<br />';
3839
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&">'.get_lang('Forum').'</a><br />';
3840
    $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>';
3841
3842
    Session::erase('formelements');
3843
    Session::erase('origin');
3844
    Session::erase('breadcrumbs');
3845
    Session::erase('addedresource');
3846
    Session::erase('addedresourceid');
3847
3848
    Display :: display_confirmation_message($message, false);
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_confirmation_message() has been deprecated with message: use Display::addFlash with Display::return_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...
3849
}
3850
3851
/**
3852
 * This function displays the firstname and lastname of the user as a link to the user tool.
3853
 *
3854
 * @param string names
3855
 * @ in_title : title tootip
3856
 * @return string HTML
3857
 *
3858
 * @author Patrick Cool <[email protected]>, Ghent University
3859
 * @version february 2006, dokeos 1.8
3860
 */
3861
function display_user_link($user_id, $name, $origin = '', $in_title = '')
3862
{
3863
    if ($user_id != 0) {
3864
        $userInfo = api_get_user_info($user_id);
3865
3866
        return '<a href="'.$userInfo['profile_url'].'">'.Security::remove_XSS($userInfo['complete_name']).'</a>';
3867
    } else {
3868
        return $name.' ('.get_lang('Anonymous').')';
3869
    }
3870
}
3871
3872
/**
3873
 * This function displays the user image from the profile, with a link to the user's details.
3874
 * @param   int     User's database ID
3875
 * @param   string  User's name
3876
 * @param   string  the origin where the forum is called (example : learnpath)
3877
 * @return  string  An HTML with the anchor and the image of the user
3878
 * @author Julio Montoya <[email protected]>
3879
 */
3880
function display_user_image($user_id, $name, $origin = '')
3881
{
3882
    $userInfo = api_get_user_info($user_id);
3883
3884
    $link = '<a href="'.(!empty($origin) ? '#' : $userInfo['profile_url']).'" '.(!empty($origin) ? 'target="_self"' : '').'>';
3885
3886
    if ($user_id != 0) {
3887
        return $link.'<img src="'.$userInfo['avatar'].'"  alt="'.$name.'"  title="'.$name.'" /></a>';
3888
    } else {
3889
        return $link.Display::return_icon('unknown.jpg', $name).'</a>';
3890
    }
3891
}
3892
3893
/**
3894
 * The thread view counter gets increased every time someone looks at the thread
3895
 *
3896
 * @param int
3897
 * @return void
3898
 *
3899
 * @author Patrick Cool <[email protected]>, Ghent University
3900
 * @version february 2006, dokeos 1.8
3901
 */
3902 View Code Duplication
function increase_thread_view($thread_id)
3903
{
3904
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3905
    $course_id = api_get_course_int_id();
3906
3907
    $sql = "UPDATE $table_threads SET thread_views=thread_views+1
3908
            WHERE 
3909
                c_id = $course_id AND  
3910
                thread_id = '".intval($thread_id)."'";
3911
    Database::query($sql);
3912
}
3913
3914
/**
3915
 * The relies counter gets increased every time somebody replies to the thread
3916
 *
3917
 * @author Patrick Cool <[email protected]>, Ghent University
3918
 * @version february 2006, dokeos 1.8
3919
 * @param string $last_post_id
3920
 * @param string $post_date
3921
 */
3922
function updateThreadInfo($thread_id, $last_post_id, $post_date)
3923
{
3924
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3925
    $course_id = api_get_course_int_id();
3926
    $sql = "UPDATE $table_threads SET 
3927
            thread_replies = thread_replies+1,
3928
            thread_last_post = '".Database::escape_string($last_post_id)."',
3929
            thread_date = '".Database::escape_string($post_date)."'
3930
            WHERE 
3931
                c_id = $course_id AND  
3932
                thread_id='".Database::escape_string($thread_id)."'"; // this needs to be cleaned first
3933
    Database::query($sql);
3934
}
3935
3936
/**
3937
 * This function is called when the user is not allowed in this forum/thread/...
3938
 * @return bool display message of "not allowed"
3939
 *
3940
 * @author Patrick Cool <[email protected]>, Ghent University
3941
 * @version february 2006, dokeos 1.8
3942
 */
3943
function forum_not_allowed_here()
3944
{
3945
    Display :: display_error_message(get_lang('NotAllowedHere'));
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_error_message() has been deprecated with message: use Display::addFlash with Display::return_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...
3946
    Display :: display_footer();
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_footer() has been deprecated with message: See template.lib.php class documentation

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

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

Loading history...
3947
3948
    return false;
3949
}
3950
3951
/**
3952
 * This function is used to find all the information about what's new in the forum tool
3953
 * @return void
3954
 *
3955
 * @author Patrick Cool <[email protected]>, Ghent University
3956
 * @version february 2006, dokeos 1.8
3957
 */
3958
function get_whats_new()
3959
{
3960
    $userId = api_get_user_id();
3961
    $course_id = api_get_course_int_id();
3962
3963
    if (empty($course_id) || empty($userId)) {
3964
        return false;
3965
    }
3966
3967
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3968
    $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
3969
3970
    $tool = TOOL_FORUM;
3971
    $lastForumAccess = Session::read('last_forum_access');
3972
3973
    if (!$lastForumAccess) {
3974
        $sql = "SELECT * FROM $tracking_last_tool_access
3975
                WHERE
3976
                    access_user_id = $userId AND
3977
                    c_id = $course_id AND
3978
                    access_tool = '".Database::escape_string($tool)."'";
3979
        $result = Database::query($sql);
3980
        $row = Database::fetch_array($result);
3981
        Session::write('last_forum_access', $row['access_date']);
3982
        $lastForumAccess = $row['access_date'];
3983
    }
3984
3985
    $whatsNew = Session::read('whatsnew_post_info');
3986
3987
    if (!$whatsNew) {
3988
        if ($lastForumAccess != '') {
3989
            $postInfo = array();
3990
            $sql = "SELECT * FROM $table_posts
3991
                    WHERE
3992
                        c_id = $course_id AND
3993
                        visible = 1 AND                        
3994
                        post_date > '".Database::escape_string($lastForumAccess)."'";
3995
            $result = Database::query($sql);
3996
            while ($row = Database::fetch_array($result)) {
3997
                $postInfo[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
3998
            }
3999
            Session::write('whatsnew_post_info', $postInfo);
4000
        }
4001
    }
4002
}
4003
4004
/**
4005
 * This function approves a post = change
4006
 *
4007
 * @param int $post_id the id of the post that will be deleted
4008
 * @param string $action make the post visible or invisible
4009
 * @return string language variable
4010
 *
4011
 * @author Patrick Cool <[email protected]>, Ghent University
4012
 * @version february 2006, dokeos 1.8
4013
 */
4014
function approve_post($post_id, $action)
4015
{
4016
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4017
    $course_id = api_get_course_int_id();
4018
4019
    if ($action == 'invisible') {
4020
        $visibility_value = 0;
4021
    }
4022
4023
    if ($action == 'visible') {
4024
        $visibility_value = 1;
4025
        handle_mail_cue('post', $post_id);
4026
    }
4027
4028
    $sql = "UPDATE $table_posts SET
4029
            visible='".Database::escape_string($visibility_value)."'
4030
            WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
4031
    $return = Database::query($sql);
4032
4033
    if ($return) {
4034
        return 'PostVisibilityChanged';
4035
    }
4036
}
4037
4038
/**
4039
 * This function retrieves all the unapproved messages for a given forum
4040
 * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
4041
 *
4042
 * @param $forum_id the forum where we want to know the unapproved messages of
4043
 * @return array returns
4044
 *
4045
 * @author Patrick Cool <[email protected]>, Ghent University
4046
 * @version february 2006, dokeos 1.8
4047
 */
4048
function get_unaproved_messages($forum_id)
4049
{
4050
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4051
    $course_id = api_get_course_int_id();
4052
4053
    $return_array = array();
4054
    $sql = "SELECT DISTINCT thread_id FROM $table_posts
4055
            WHERE 
4056
                c_id = $course_id AND 
4057
                forum_id='".Database::escape_string($forum_id)."' AND 
4058
                visible='0' ";
4059
    $result = Database::query($sql);
4060
    while ($row = Database::fetch_array($result)) {
4061
        $return_array[] = $row['thread_id'];
4062
    }
4063
4064
    return $return_array;
4065
}
4066
4067
/**
4068
 * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
4069
 * was added to a given thread.
4070
 *
4071
 * @param array reply information
4072
 * @return void
4073
 *
4074
 * @author Patrick Cool <[email protected]>, Ghent University
4075
 * @version february 2006, dokeos 1.8
4076
 */
4077
function send_notification_mails($forumId, $thread_id, $reply_info)
4078
{
4079
    $table = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
4080
4081
    // First we need to check if
4082
    // 1. the forum category is visible
4083
    // 2. the forum is visible
4084
    // 3. the thread is visible
4085
    // 4. the reply is visible (=when there is)
4086
    $current_thread = get_thread_information($forumId, $thread_id);
4087
    $current_forum = get_forum_information($current_thread['forum_id'], $current_thread['c_id']);
4088
4089
    $current_forum_category = null;
4090
    if (isset($current_forum['forum_category'])) {
4091
        $current_forum_category = get_forumcategory_information(
4092
            $current_forum['forum_category']
4093
        );
4094
    }
4095
4096
    if ($current_thread['visibility'] == '1' &&
4097
        $current_forum['visibility'] == '1' &&
4098
        ($current_forum_category && $current_forum_category['visibility'] == '1') &&
4099
        $current_forum['approval_direct_post'] != '1'
4100
    ) {
4101
        $send_mails = true;
4102
    } else {
4103
        $send_mails = false;
4104
    }
4105
4106
    // The forum category, the forum, the thread and the reply are visible to the user
4107
    if ($send_mails) {
4108
        if (!empty($forumId)) {
4109
            send_notifications($forumId, $thread_id);
4110
        }
4111
    } else {
4112
        $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
4113
        if (isset($current_forum['forum_id'])) {
4114
            $sql = "SELECT * FROM $table_notification
4115
                    WHERE
4116
                        c_id = ".api_get_course_int_id()." AND
4117
                        (
4118
                            forum_id = '".intval($current_forum['forum_id'])."' OR
4119
                            thread_id = '".intval($thread_id)."'
4120
                        ) ";
4121
4122
            $result = Database::query($sql);
4123
            $user_id = api_get_user_id();
4124
            while ($row = Database::fetch_array($result)) {
4125
                $sql = "INSERT INTO $table (c_id, thread_id, post_id, user_id)
4126
                        VALUES (".api_get_course_int_id().", '".intval($thread_id)."', '".intval($reply_info['new_post_id'])."', '$user_id' )";
4127
                Database::query($sql);
4128
            }
4129
        }
4130
    }
4131
}
4132
4133
/**
4134
 * This function is called whenever something is made visible because there might
4135
 * be new posts and the user might have indicated that (s)he wanted to be
4136
 * informed about the new posts by mail.
4137
 *
4138
 * @param string  Content type (post, thread, forum, forum_category)
4139
 * @param int     Item DB ID
4140
 * @param string $content
4141
 * @param integer $id
4142
 * @return string language variable
4143
 * @author Patrick Cool <[email protected]>, Ghent University
4144
 * @version february 2006, dokeos 1.8
4145
 */
4146
function handle_mail_cue($content, $id)
4147
{
4148
    $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
4149
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4150
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4151
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4152
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
4153
4154
    $course_id = api_get_course_int_id();
4155
4156
    /* If the post is made visible we only have to send mails to the people
4157
     who indicated that they wanted to be informed for that thread.*/
4158
    if ($content == 'post') {
4159
        // Getting the information about the post (need the thread_id).
4160
        $post_info = get_post_information($id);
4161
        $thread_id = intval($post_info['thread_id']);
4162
4163
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4164
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4165
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4166
                WHERE
4167
                    posts.c_id = $course_id AND
4168
                    mailcue.c_id = $course_id AND
4169
                    posts.thread_id='$thread_id'
4170
                    AND posts.post_notification='1'
4171
                    AND mailcue.thread_id='$thread_id'
4172
                    AND users.user_id=posts.poster_id
4173
                    AND users.active=1
4174
                GROUP BY users.email";
4175
4176
        $result = Database::query($sql);
4177
        while ($row = Database::fetch_array($result)) {
4178
            send_mail($row, get_thread_information($post_info['forum_id'], $post_info['thread_id']));
4179
        }
4180
    } elseif ($content == 'thread') {
4181
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4182
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email, posts.forum_id
4183
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4184
                WHERE
4185
                    posts.c_id = $course_id AND
4186
                    mailcue.c_id = $course_id AND
4187
                    posts.thread_id = ".intval($id)."
4188
                    AND posts.post_notification='1'
4189
                    AND mailcue.thread_id = ".intval($id)."
4190
                    AND users.user_id=posts.poster_id
4191
                    AND users.active=1
4192
                GROUP BY users.email";
4193
        $result = Database::query($sql);
4194
        while ($row = Database::fetch_array($result)) {
4195
            send_mail($row, get_thread_information($row['forum_id'], $id));
4196
        }
4197
4198
        // Deleting the relevant entries from the mailcue.
4199
        $sql = "DELETE FROM $table_mailcue
4200
                WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
4201
        Database::query($sql);
4202
    } elseif ($content == 'forum') {
4203
        $sql = "SELECT thread_id FROM $table_threads
4204
                WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
4205
        $result = Database::query($sql);
4206
        while ($row = Database::fetch_array($result)) {
4207
            handle_mail_cue('thread', $row['thread_id']);
4208
        }
4209
    } elseif ($content == 'forum_category') {
4210
        $sql = "SELECT forum_id FROM $table_forums
4211
                WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
4212
        $result = Database::query($sql);
4213
        while ($row = Database::fetch_array($result)) {
4214
            handle_mail_cue('forum', $row['forum_id']);
4215
        }
4216
    } else {
4217
        return get_lang('Error');
4218
    }
4219
}
4220
4221
/**
4222
 * This function sends the mails for the mail notification
4223
 *
4224
 * @param array
4225
 * @param array
4226
 * @return void
4227
 *
4228
 * @author Patrick Cool <[email protected]>, Ghent University
4229
 * @version february 2006, dokeos 1.8
4230
 */
4231
function send_mail($user_info = array(), $thread_information = array())
4232
{
4233
    $_course = api_get_course_info();
4234
    $user_id = api_get_user_id();
4235
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
4236 View Code Duplication
    if (isset($thread_information) && is_array($thread_information)) {
4237
        $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$thread_information['forum_id'].'&thread='.$thread_information['thread_id'];
4238
    }
4239
    $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
4240
    $email_body .= get_lang('NewForumPost')."\n";
4241
    $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
4242
    $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
4243
    $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
4244
4245
    if ($user_info['user_id'] <> $user_id) {
4246
        MessageManager::send_message($user_info['user_id'], $subject, $email_body, [], [], null, null, null, null, $user_id);
4247
    }
4248
}
4249
4250
/**
4251
 * This function displays the form for moving a thread to a different (already existing) forum
4252
 * @return void HTML
4253
 *
4254
 * @author Patrick Cool <[email protected]>, Ghent University
4255
 * @version february 2006, dokeos 1.8
4256
 */
4257
function move_thread_form()
4258
{
4259
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4260
    $form = new FormValidator(
4261
        'movepost',
4262
        'post',
4263
        api_get_self().'?forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
4264
    );
4265
    // The header for the form
4266
    $form->addElement('header', get_lang('MoveThread'));
4267
    // Invisible form: the thread_id
4268
    $form->addElement('hidden', 'thread_id', intval($_GET['thread']));
4269
    // the fora
4270
    $forum_categories = get_forum_categories();
4271
    $forums = get_forums();
4272
4273
    $htmlcontent = '<div class="row">
4274
        <div class="label">
4275
            <span class="form_required">*</span>'.get_lang('MoveTo').'
4276
        </div>
4277
        <div class="formw">';
4278
    $htmlcontent .= '<select name="forum">';
4279
    foreach ($forum_categories as $key => $category) {
4280
        $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
4281
        foreach ($forums as $key => $forum) {
4282
            if (isset($forum['forum_category'])) {
4283
                if ($forum['forum_category'] == $category['cat_id']) {
4284
                    $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
4285
                }
4286
            }
4287
        }
4288
        $htmlcontent .= '</optgroup>';
4289
    }
4290
    $htmlcontent .= "</select>";
4291
    $htmlcontent .= '   </div>
4292
                    </div>';
4293
4294
    $form->addElement('html', $htmlcontent);
4295
4296
    // The OK button
4297
    $form->addButtonSave(get_lang('MoveThread'), 'SubmitForum');
4298
4299
    // Validation or display
4300
    if ($form->validate()) {
4301
        $values = $form->exportValues();
4302
        if (isset($_POST['forum'])) {
4303
            store_move_thread($values);
4304
        }
4305
    } else {
4306
        $form->display();
4307
    }
4308
}
4309
4310
/**
4311
 * This function displays the form for moving a post message to a different (already existing) or a new thread.
4312
 * @return void HTML
4313
 *
4314
 * @author Patrick Cool <[email protected]>, Ghent University
4315
 * @version february 2006, dokeos 1.8
4316
 */
4317
function move_post_form()
4318
{
4319
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4320
    // initiate the object
4321
    $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']));
4322
    // The header for the form
4323
    $form->addElement('header', '', get_lang('MovePost'));
4324
4325
    // Invisible form: the post_id
4326
    $form->addElement('hidden', 'post_id', intval($_GET['post']));
4327
4328
    // Dropdown list: Threads of this forum
4329
    $threads = get_threads($_GET['forum']);
4330
    //my_print_r($threads);
4331
    $threads_list[0] = get_lang('ANewThread');
4332
    foreach ($threads as $key => $value) {
4333
        $threads_list[$value['thread_id']] = $value['thread_title'];
4334
    }
4335
    $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
4336
    $form->applyFilter('thread', 'html_filter');
4337
4338
    // The OK button
4339
    $form->addButtonSave(get_lang('MovePost'), 'submit');
4340
4341
    // Setting the rules
4342
    $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
4343
4344
    // Validation or display
4345
    if ($form->validate()) {
4346
        $values = $form->exportValues();
4347
        store_move_post($values);
4348
    } else {
4349
        $form->display();
4350
    }
4351
}
4352
4353
/**
4354
 *
4355
 * @param array
4356
 * @return string HTML language variable
4357
 *
4358
 * @author Patrick Cool <[email protected]>, Ghent University
4359
 * @version february 2006, dokeos 1.8
4360
 */
4361
function store_move_post($values)
4362
{
4363
    $_course = api_get_course_info();
4364
    $course_id = api_get_course_int_id();
4365
4366
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4367
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4368
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4369
4370
    if ($values['thread'] == '0') {
4371
        $current_post = get_post_information($values['post_id']);
4372
4373
        // Storing a new thread.
4374
        $params = [
4375
            'c_id' => $course_id,
4376
            'thread_title' => $current_post['post_title'],
4377
            'forum_id' => $current_post['forum_id'],
4378
            'thread_poster_id' => $current_post['poster_id'],
4379
            'thread_poster_name' => $current_post['poster_name'],
4380
            'thread_last_post' => $values['post_id'],
4381
            'thread_date' => $current_post['post_date'],
4382
        ];
4383
4384
        $new_thread_id = Database::insert($table_threads, $params);
4385
4386
        api_item_property_update(
4387
            $_course,
4388
            TOOL_FORUM_THREAD,
4389
            $new_thread_id,
4390
            'visible',
4391
            $current_post['poster_id']
4392
        );
4393
4394
        // Moving the post to the newly created thread.
4395
        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
4396
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4397
        Database::query($sql);
4398
4399
        // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
4400
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4401
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4402
        Database::query($sql);
4403
4404
        // Updating updating the number of threads in the forum.
4405
        $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
4406
                WHERE c_id = $course_id AND forum_id='".intval($current_post['forum_id'])."'";
4407
        Database::query($sql);
4408
4409
        // Resetting the last post of the old thread and decreasing the number of replies and the thread.
4410
        $sql = "SELECT * FROM $table_posts
4411
                WHERE c_id = $course_id AND thread_id='".intval($current_post['thread_id'])."'
4412
                ORDER BY post_id DESC";
4413
        $result = Database::query($sql);
4414
        $row = Database::fetch_array($result);
4415
        $sql = "UPDATE $table_threads SET
4416
                    thread_last_post='".$row['post_id']."',
4417
                    thread_replies=thread_replies-1
4418
                WHERE
4419
                    c_id = $course_id AND
4420
                    thread_id='".intval($current_post['thread_id'])."'";
4421
        Database::query($sql);
4422
    } else {
4423
        // Moving to the chosen thread.
4424
        $sql = "SELECT thread_id FROM ".$table_posts."
4425
                WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
4426
        $result = Database::query($sql);
4427
        $row = Database::fetch_array($result);
4428
4429
        $original_thread_id = $row['thread_id'];
4430
4431
        $sql = "SELECT thread_last_post FROM ".$table_threads."
4432
                WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4433
4434
        $result = Database::query($sql);
4435
        $row = Database::fetch_array($result);
4436
        $thread_is_last_post = $row['thread_last_post'];
4437
        // If is this thread, update the thread_last_post with the last one.
4438
4439
        if ($thread_is_last_post == $values['post_id']) {
4440
            $sql = "SELECT post_id FROM ".$table_posts."
4441
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."'
4442
                    ORDER BY post_date DESC LIMIT 1";
4443
            $result = Database::query($sql);
4444
4445
            $row = Database::fetch_array($result);
4446
            $thread_new_last_post = $row['post_id'];
4447
4448
            $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."'
4449
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4450
            Database::query($sql);
4451
        }
4452
4453
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
4454
                WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
4455
        Database::query($sql);
4456
4457
        // moving to the chosen thread
4458
        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
4459
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4460
        Database::query($sql);
4461
4462
        // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
4463
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4464
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4465
        Database::query($sql);
4466
4467
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
4468
                WHERE c_id = $course_id AND thread_id='".intval($_POST['thread'])."'";
4469
        Database::query($sql);
4470
    }
4471
4472
    return get_lang('ThreadMoved');
4473
}
4474
4475
/**
4476
 *
4477
 * @param array
4478
 * @return string HTML language variable
4479
 *
4480
 * @author Patrick Cool <[email protected]>, Ghent University
4481
 * @version february 2006, dokeos 1.8
4482
 */
4483
function store_move_thread($values)
4484
{
4485
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4486
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4487
4488
    $courseId = api_get_course_int_id();
4489
    $sessionId = api_get_session_id();
4490
4491
    $forumId = intval($_POST['forum']);
4492
    $threadId = intval($_POST['thread_id']);
4493
    $forumInfo = get_forums($forumId);
4494
4495
    // Change the thread table: Setting the forum_id to the new forum.
4496
    $sql = "UPDATE $table_threads SET forum_id = $forumId
4497
            WHERE c_id = $courseId AND thread_id = $threadId";
4498
    Database::query($sql);
4499
4500
    // Changing all the posts of the thread: setting the forum_id to the new forum.
4501
    $sql = "UPDATE $table_posts SET forum_id = $forumId
4502
            WHERE c_id = $courseId AND thread_id= $threadId";
4503
    Database::query($sql);
4504
    // Fix group id, if forum is moved to a different group
4505
    if (!empty($forumInfo['to_group_id'])) {
4506
        $groupId = $forumInfo['to_group_id'];
4507
        $item = api_get_item_property_info($courseId, TABLE_FORUM_THREAD, $threadId, $sessionId, $groupId);
4508
        $table = Database:: get_course_table(TABLE_ITEM_PROPERTY);
4509
        $sessionCondition = api_get_session_condition($sessionId);
4510
4511
        if (!empty($item)) {
4512
            if ($item['to_group_id'] != $groupId) {
4513
                $sql = "UPDATE $table
4514
                    SET to_group_id = $groupId
4515
                    WHERE
4516
                      tool = '".TABLE_FORUM_THREAD."' AND
4517
                      c_id = $courseId AND
4518
                      ref = ".$item['ref']."
4519
                      $sessionCondition
4520
                ";
4521
                Database::query($sql);
4522
            }
4523
        } else {
4524
            $sql = "UPDATE $table
4525
                    SET to_group_id = $groupId
4526
                    WHERE
4527
                      tool = '".TABLE_FORUM_THREAD."' AND
4528
                      c_id = $courseId AND
4529
                      ref = ".$threadId."
4530
                      $sessionCondition
4531
            ";
4532
            Database::query($sql);
4533
        }
4534
    }
4535
4536
    return get_lang('ThreadMoved');
4537
}
4538
4539
/**
4540
 * Prepares a string for displaying by highlighting the search results inside, if any.
4541
 * @param string $input    The input string.
4542
 * @return string          The same string with highlighted hits inside.
4543
 *
4544
 * @author Patrick Cool <[email protected]>, Ghent University, February 2006 - the initial version.
4545
 * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
4546
 */
4547
function prepare4display($input)
4548
{
4549
    static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
4550
    static $search;
4551
4552
    if (!isset($search)) {
4553
        if (isset($_POST['search_term'])) {
4554
            $search = $_POST['search_term']; // No html at all.
4555
        } elseif (isset($_GET['search'])) {
4556
            $search = $_GET['search'];
4557
        } else {
4558
            $search = '';
4559
        }
4560
    }
4561
4562
    if (!empty($search)) {
4563
        if (strstr($search, '+')) {
4564
            $search_terms = explode('+', $search);
4565
        } else {
4566
            $search_terms[] = trim($search);
4567
        }
4568
        $counter = 0;
4569
        foreach ($search_terms as $key => $search_term) {
4570
            $input = api_preg_replace('/'.preg_quote(trim($search_term), '/').'/i', '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>', $input);
4571
            $counter++;
4572
        }
4573
    }
4574
4575
    // TODO: Security should be implemented outside this function.
4576
    // 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).
4577
4578
    return Security::remove_XSS($input, STUDENT, true);
4579
}
4580
4581
/**
4582
 * Display the search form for the forum and display the search results
4583
 * @return void display an HTML search results
4584
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4585
 * @version march 2008, dokeos 1.8.5
4586
 */
4587
function forum_search()
4588
{
4589
    $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?'.api_get_cidreq());
4590
4591
    // Setting the form elements.
4592
    $form->addElement('header', '', get_lang('ForumSearch'));
4593
    $form->addElement('text', 'search_term', get_lang('SearchTerm'), array('autofocus'));
4594
    $form->applyFilter('search_term', 'html_filter');
4595
    $form->addElement('static', 'search_information', '', get_lang('ForumSearchInformation'));
4596
    $form->addButtonSearch(get_lang('Search'));
4597
4598
    // Setting the rules.
4599
    $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
4600
    $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
4601
4602
    // Validation or display.
4603
    if ($form->validate()) {
4604
        $values = $form->exportValues();
4605
        $form->setDefaults($values);
4606
        $form->display();
4607
        // Display the search results.
4608
        display_forum_search_results(stripslashes($values['search_term']));
4609
    } else {
4610
        $form->display();
4611
    }
4612
}
4613
4614
/**
4615
 * Display the search results
4616
 * @param string
4617
 * @param string $search_term
4618
 * @return void display the results
4619
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4620
 * @version march 2008, dokeos 1.8.5
4621
 */
4622
function display_forum_search_results($search_term)
4623
{
4624
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4625
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4626
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
4627
    $session_id = api_get_session_id();
4628
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4629
    $course_id = api_get_course_int_id();
4630
4631
    // Defining the search strings as an array.
4632
    if (strstr($search_term, '+')) {
4633
        $search_terms = explode('+', $search_term);
4634
    } else {
4635
        $search_terms[] = $search_term;
4636
    }
4637
4638
    // Search restriction.
4639
    foreach ($search_terms as $value) {
4640
        $search_restriction[] = "
4641
        (
4642
            posts.post_title LIKE '%".Database::escape_string(trim($value))."%' OR 
4643
            posts.post_text LIKE '%".Database::escape_string(trim($value))."%' 
4644
        )";
4645
    }
4646
4647
    $sessionCondition = api_get_session_condition($session_id, true, false, 'item_property.session_id');
4648
4649
    $sql = "SELECT posts.*
4650
            FROM $table_posts posts INNER JOIN $table_threads threads
4651
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
4652
            INNER JOIN $table_item_property item_property
4653
            ON (item_property.ref = threads.thread_id AND item_property.c_id = threads.c_id)
4654
            WHERE
4655
                posts.c_id = $course_id AND 
4656
                item_property.c_id = $course_id AND 
4657
                item_property.visibility = 1  
4658
                $sessionCondition AND
4659
                posts.visible = 1 AND 
4660
                item_property.tool = '".TOOL_FORUM_THREAD."' AND 
4661
                ".implode(' AND ', $search_restriction)."
4662
            GROUP BY posts.post_id";
4663
4664
    // Getting all the information of the forum categories.
4665
    $forum_categories_list = get_forum_categories();
4666
4667
    // Getting all the information of the forums.
4668
    $forum_list = get_forums();
4669
4670
    $result = Database::query($sql);
4671
    $search_results = [];
4672
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4673
        $forumId = $row['forum_id'];
4674
        $forumData = get_forums($forumId);
4675
        $category = isset($forum_categories_list[$forumData['forum_category']]) ? $forum_categories_list[$forumData['forum_category']] : null;
4676
        $display_result = false;
4677
        /*
4678
          We only show it when
4679
          1. forum category is visible
4680
          2. forum is visible
4681
          3. thread is visible (to do)
4682
          4. post is visible
4683
         */
4684
        if (!api_is_allowed_to_edit(null, true)) {
4685
            if (!empty($category)) {
4686
                if ($category['visibility'] == '1' && $forumData['visibility'] == '1') {
4687
                    $display_result = true;
4688
                }
4689
            } else {
4690
                if ($forumData['visible'] == '1') {
4691
                    $display_result = true;
4692
                }
4693
            }
4694
        } else {
4695
            $display_result = true;
4696
        }
4697
4698
        if ($display_result) {
4699
            $categoryName = !empty($category) ? $category['cat_title'] : '';
4700
            $search_results_item = '<li><a href="viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.$forumData['forum_category'].'&search='.urlencode($search_term).'">'.
4701
                prepare4display($categoryName).'</a> &gt; ';
4702
            $search_results_item .= '<a href="viewforum.php?'.api_get_cidreq().'&forum='.$forumId.'&search='.urlencode($search_term).'">'.
4703
                prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
4704
            $search_results_item .= '<a href="viewthread.php?'.api_get_cidreq().'&forum='.$forumId.'&gradebook='.$gradebook.'&thread='.$row['thread_id'].'&search='.urlencode($search_term).'">'.
4705
                prepare4display($row['post_title']).'</a>';
4706
            $search_results_item .= '<br />';
4707
            if (api_strlen($row['post_title']) > 200) {
4708
                $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...
4709
            } else {
4710
                $search_results_item .= prepare4display($row['post_title']);
4711
            }
4712
            $search_results_item .= '</li>';
4713
            $search_results[] = $search_results_item;
4714
        }
4715
    }
4716
    echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
4717
    echo '<ol>';
4718
    if ($search_results) {
4719
        echo implode($search_results);
4720
    }
4721
    echo '</ol>';
4722
}
4723
4724
/**
4725
 * Return the link to the forum search page
4726
 *
4727
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4728
 * @version April 2008, dokeos 1.8.5
4729
 */
4730
function search_link()
4731
{
4732
    $return = '';
4733
    $origin = api_get_origin();
4734
    if ($origin != 'learnpath') {
4735
        $return = '<a href="forumsearch.php?'.api_get_cidreq().'&action=search"> ';
4736
        $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
4737
4738
        if (!empty($_GET['search'])) {
4739
            $return .= ': '.Security::remove_XSS($_GET['search']).' ';
4740
            $url = api_get_self().'?';
4741
            $url_parameter = array();
4742
            foreach ($_GET as $key => $value) {
4743
                if ($key != 'search') {
4744
                    $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
4745
                }
4746
            }
4747
            $url = $url.implode('&', $url_parameter);
4748
            $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
4749
        }
4750
    }
4751
4752
    return $return;
4753
}
4754
4755
/**
4756
 * This function adds an attachment file into a forum
4757
 * @param string $file_comment  a comment about file
4758
 * @param int $last_id from forum_post table
4759
 * @return false|null
4760
 */
4761
function add_forum_attachment_file($file_comment, $last_id)
4762
{
4763
    $_course = api_get_course_info();
4764
    $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4765
4766
    if (!isset($_FILES['user_upload'])) {
4767
        return false;
4768
    }
4769
4770
    $fileCount = count($_FILES['user_upload']['name']);
4771
    $filesData = [];
4772
4773 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4774
        $filesData[] = $_FILES['user_upload'];
4775
    } else {
4776
        $fileKeys = array_keys($_FILES['user_upload']);
4777
        for ($i = 0; $i < $fileCount; $i++) {
4778
            foreach ($fileKeys as $key) {
4779
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4780
            }
4781
        }
4782
    }
4783
4784
    foreach ($filesData as $attachment) {
4785
        if (empty($attachment['name'])) {
4786
            continue;
4787
        }
4788
4789
        $upload_ok = process_uploaded_file($attachment);
4790
4791
        if (!$upload_ok) {
4792
            continue;
4793
        }
4794
4795
        $course_dir = $_course['path'] . '/upload/forum';
4796
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4797
        $updir = $sys_course_path . $course_dir;
4798
4799
        // Try to add an extension to the file if it hasn't one.
4800
        $new_file_name = add_ext_on_mime(
4801
            stripslashes($attachment['name']),
4802
            $attachment['type']
4803
        );
4804
        // User's file name
4805
        $file_name = $attachment['name'];
4806
4807
        if (!filter_extension($new_file_name)) {
4808
            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_error_message() has been deprecated with message: use Display::addFlash with Display::return_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...
4809
4810
            return;
4811
        }
4812
4813
        $new_file_name = uniqid('');
4814
        $new_path = $updir . '/' . $new_file_name;
4815
        $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4816
        $safe_file_comment = Database::escape_string($file_comment);
4817
        $safe_file_name = Database::escape_string($file_name);
4818
        $safe_new_file_name = Database::escape_string($new_file_name);
4819
        $last_id = intval($last_id);
4820
        // Storing the attachments if any.
4821
        if (!$result) {
4822
            return;
4823
        }
4824
4825
        $last_id_file = Database::insert(
4826
            $agenda_forum_attachment,
4827
            [
4828
                'c_id' => api_get_course_int_id(),
4829
                'filename' => $safe_file_name,
4830
                'comment' => $safe_file_comment,
4831
                'path' => $safe_new_file_name,
4832
                'post_id' => $last_id,
4833
                'size' => intval($attachment['size']),
4834
            ]
4835
        );
4836
4837
        api_item_property_update(
4838
            $_course,
4839
            TOOL_FORUM_ATTACH,
4840
            $last_id_file,
4841
            'ForumAttachmentAdded',
4842
            api_get_user_id()
4843
        );
4844
    }
4845
}
4846
4847
/**
4848
 * This function edits an attachment file into a forum
4849
 * @param string $file_comment  a comment about file
4850
 * @param int $post_id
4851
 * @param int $id_attach attachment file Id
4852
 * @return void
4853
 */
4854
function edit_forum_attachment_file($file_comment, $post_id, $id_attach)
4855
{
4856
    $_course = api_get_course_info();
4857
    $table_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4858
    $course_id = api_get_course_int_id();
4859
4860
    $fileCount = count($_FILES['user_upload']['name']);
4861
    $filesData = [];
4862
4863 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4864
        $filesData[] = $_FILES['user_upload'];
4865
    } else {
4866
        $fileKeys = array_keys($_FILES['user_upload']);
4867
4868
        for ($i = 0; $i < $fileCount; $i++) {
4869
            foreach ($fileKeys as $key) {
4870
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4871
            }
4872
        }
4873
    }
4874
4875
    foreach ($filesData as $attachment) {
4876
        if (empty($attachment['name'])) {
4877
            continue;
4878
        }
4879
4880
        $upload_ok = process_uploaded_file($attachment);
4881
4882
        if (!$upload_ok) {
4883
            continue;
4884
        }
4885
4886
        $course_dir = $_course['path'].'/upload/forum';
4887
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4888
        $updir = $sys_course_path.$course_dir;
4889
4890
        // Try to add an extension to the file if it hasn't one.
4891
        $new_file_name = add_ext_on_mime(stripslashes($attachment['name']), $attachment['type']);
4892
        // User's file name
4893
        $file_name = $attachment['name'];
4894
4895
        if (!filter_extension($new_file_name)) {
4896
            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_error_message() has been deprecated with message: use Display::addFlash with Display::return_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...
4897
        } else {
4898
            $new_file_name = uniqid('');
4899
            $new_path = $updir.'/'.$new_file_name;
4900
            $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4901
            $safe_file_comment = Database::escape_string($file_comment);
4902
            $safe_file_name = Database::escape_string($file_name);
4903
            $safe_new_file_name = Database::escape_string($new_file_name);
4904
            $safe_post_id = (int) $post_id;
4905
            $safe_id_attach = (int) $id_attach;
4906
            // Storing the attachments if any.
4907 View Code Duplication
            if ($result) {
4908
                $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']."'
4909
                       WHERE c_id = $course_id AND id = '$safe_id_attach'";
4910
                Database::query($sql);
4911
                api_item_property_update($_course, TOOL_FORUM_ATTACH, $safe_id_attach, 'ForumAttachmentUpdated', api_get_user_id());
4912
            }
4913
        }
4914
    }
4915
}
4916
4917
/**
4918
 * Show a list with all the attachments according to the post's id
4919
 * @param int $post_id
4920
 * @return array with the post info
4921
 * @author Julio Montoya
4922
 * @version avril 2008, dokeos 1.8.5
4923
 */
4924
function get_attachment($post_id)
4925
{
4926
    $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4927
    $course_id = api_get_course_int_id();
4928
    $row = array();
4929
    $post_id = intval($post_id);
4930
    $sql = "SELECT iid, path, filename, comment 
4931
            FROM $forum_table_attachment
4932
            WHERE c_id = $course_id AND post_id = $post_id";
4933
    $result = Database::query($sql);
4934
    if (Database::num_rows($result) != 0) {
4935
        $row = Database::fetch_array($result);
4936
    }
4937
4938
    return $row;
4939
}
4940
4941
/**
4942
 * @param int $postId
4943
 *
4944
 * @return array
4945
 */
4946
function getAllAttachment($postId)
4947
{
4948
    $forumAttachmentTable = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4949
    $courseId = api_get_course_int_id();
4950
    $postId = intval($postId);
4951
    $columns = array('iid', 'path', 'filename', 'comment');
4952
    $conditions = array(
4953
        'where' => array(
4954
            'c_id = ? AND post_id = ?' => array($courseId, $postId),
4955
        ),
4956
    );
4957
    $array = Database::select(
4958
        $columns,
4959
        $forumAttachmentTable,
4960
        $conditions,
4961
        'all',
4962
        'ASSOC'
4963
    );
4964
4965
    return $array;
4966
}
4967
4968
/**
4969
 * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
4970
 * @param int $post_id
4971
 * @param int $id_attach
4972
 * @param bool $display to show or not result message
4973
 * @return integer
4974
 * @author Julio Montoya
4975
 * @version october 2014, chamilo 1.9.8
4976
 */
4977
function delete_attachment($post_id, $id_attach = 0, $display = true)
4978
{
4979
    $_course = api_get_course_info();
4980
4981
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4982
    $course_id = api_get_course_int_id();
4983
4984
    $cond = (!empty($id_attach)) ? " iid = " . (int) $id_attach . "" : " post_id = " . (int) $post_id . "";
4985
    $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
4986
    $res = Database::query($sql);
4987
    $row = Database::fetch_array($res);
4988
4989
    $course_dir = $_course['path'] . '/upload/forum';
4990
    $sys_course_path = api_get_path(SYS_COURSE_PATH);
4991
    $updir = $sys_course_path . $course_dir;
4992
    $my_path = isset($row['path']) ? $row['path'] : null;
4993
    $file = $updir . '/' . $my_path;
4994
    if (Security::check_abs_path($file, $updir)) {
4995
        @unlink($file);
4996
    }
4997
4998
    // Delete from forum_attachment table.
4999
    $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
5000
    $result = Database::query($sql);
5001
    if ($result !== false) {
5002
        $affectedRows = Database::affected_rows($result);
5003
    } else {
5004
        $affectedRows = 0;
5005
    }
5006
5007
    // Update item_property.
5008
    api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
5009
5010
    if (!empty($result) && !empty($id_attach) && $display) {
5011
        $message = get_lang('AttachmentFileDeleteSuccess');
5012
        Display::display_confirmation_message($message);
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_confirmation_message() has been deprecated with message: use Display::addFlash with Display::return_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...
5013
    }
5014
5015
    return $affectedRows;
5016
}
5017
5018
/**
5019
 * This function gets all the forum information of the all the forum of the group
5020
 *
5021
 * @param integer $groupId the id of the group we need the fora of (see forum.forum_of_group)
5022
 * @return array
5023
 *
5024
 * @todo this is basically the same code as the get_forums function. Consider merging the two.
5025
 */
5026
function get_forums_of_group($groupId)
5027
{
5028
    $table_forums = Database :: get_course_table(TABLE_FORUM);
5029
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
5030
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5031
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
5032
    $course_id = api_get_course_int_id();
5033
    $groupId = (int) $groupId;
5034
5035
    // Student
5036
    // Select all the forum information of all forums (that are visible to students).
5037
5038
    $sql = "SELECT * FROM $table_forums forum 
5039
            INNER JOIN $table_item_property item_properties
5040
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
5041
            WHERE
5042
                forum.forum_of_group = $groupId AND
5043
                forum.c_id = $course_id AND
5044
                item_properties.c_id = $course_id AND                
5045
                item_properties.visibility = 1 AND
5046
                item_properties.tool = '".TOOL_FORUM."'
5047
            ORDER BY forum.forum_order ASC";
5048
5049
    // Select the number of threads of the forums (only the threads that are visible).
5050
    $sql2 = "SELECT 
5051
                count(thread_id) AS number_of_threads, 
5052
                threads.forum_id
5053
            FROM $table_threads threads 
5054
            INNER JOIN $table_item_property item_properties
5055
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
5056
            WHERE                
5057
                threads.c_id = $course_id AND
5058
                item_properties.c_id = $course_id AND
5059
                item_properties.visibility = 1 AND
5060
                item_properties.tool='".TOOL_FORUM_THREAD."'
5061
            GROUP BY threads.forum_id";
5062
5063
    // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
5064
    $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id
5065
            FROM $table_posts posts 
5066
            INNER JOIN $table_threads threads 
5067
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
5068
            INNER JOIN $table_item_property item_properties
5069
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
5070
            WHERE 
5071
                posts.visible=1 AND
5072
                posts.c_id = $course_id AND
5073
                item_properties.c_id = $course_id AND
5074
                threads.c_id = $course_id AND 
5075
                item_properties.visibility = 1 AND 
5076
                item_properties.tool='".TOOL_FORUM_THREAD."'
5077
            GROUP BY threads.forum_id";
5078
5079
    // Course Admin
5080 View Code Duplication
    if (api_is_allowed_to_edit()) {
5081
        // Select all the forum information of all forums (that are not deleted).
5082
        $sql = "SELECT *
5083
                FROM $table_forums forum INNER JOIN $table_item_property item_properties
5084
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
5085
                WHERE
5086
                    forum.forum_of_group = $groupId AND
5087
                    forum.c_id = $course_id AND
5088
                    item_properties.c_id = $course_id AND                    
5089
                    item_properties.visibility <> 2 AND
5090
                    item_properties.tool = '".TOOL_FORUM."'
5091
                ORDER BY forum_order ASC";
5092
5093
        // Select the number of threads of the forums (only the threads that are not deleted).
5094
        $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
5095
                 FROM $table_threads threads INNER JOIN $table_item_property item_properties
5096
                 ON (threads.thread_id=item_properties.ref AND item_properties.c_id = threads.c_id)
5097
                 WHERE
5098
                    threads.c_id = $course_id AND
5099
                    item_properties.c_id = $course_id AND
5100
                    item_properties.visibility <> 2 AND
5101
                    item_properties.tool='".TOOL_FORUM_THREAD."'
5102
                GROUP BY threads.forum_id";
5103
        // Select the number of posts of the forum.
5104
        $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id
5105
                FROM $table_posts
5106
                WHERE c_id = $course_id 
5107
                GROUP BY forum_id";
5108
    }
5109
5110
    // Handling all the forum information.
5111
    $result = Database::query($sql);
5112
    $forum_list = array();
5113
    while ($row = Database::fetch_array($result, 'ASSOC')) {
5114
        $forum_list[$row['forum_id']] = $row;
5115
    }
5116
5117
    // Handling the thread count information.
5118
    $result2 = Database::query($sql2);
5119 View Code Duplication
    while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
5120
        if (is_array($forum_list)) {
5121
            if (array_key_exists($row2['forum_id'], $forum_list)) {
5122
                $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
5123
            }
5124
        }
5125
    }
5126
5127
    // Handling the post count information.
5128
    $result3 = Database::query($sql3);
5129 View Code Duplication
    while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
5130
        if (is_array($forum_list)) {
5131
            if (array_key_exists($row3['forum_id'], $forum_list)) {
5132
                // This is needed because sql3 takes also the deleted forums into account.
5133
                $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
5134
            }
5135
        }
5136
    }
5137
5138
    // Finding the last post information
5139
    // (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
5140
    if (!empty($forum_list)) {
5141 View Code Duplication
        foreach ($forum_list as $key => $value) {
5142
            $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit());
5143
            if ($last_post_info_of_forum) {
5144
                $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
5145
                $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
5146
                $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
5147
                $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
5148
                $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
5149
                $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
5150
            }
5151
        }
5152
    }
5153
5154
    return $forum_list;
5155
}
5156
5157
/**
5158
 * This function stores which users have to be notified of which forums or threads
5159
 *
5160
 * @param string $content does the user want to be notified about a forum or about a thread
5161
 * @param integer $id the id of the forum or thread
5162
 * @return string language variable
5163
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5164
 * @version May 2008, dokeos 1.8.5
5165
 * @since May 2008, dokeos 1.8.5
5166
 */
5167
function set_notification($content, $id, $add_only = false)
5168
{
5169
    $_user = api_get_user_info();
5170
5171
    // Database table definition
5172
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5173
5174
    $course_id = api_get_course_int_id();
5175
5176
    // Which database field do we have to store the id in?
5177
    if ($content == 'forum') {
5178
        $database_field = 'forum_id';
5179
    } else {
5180
        $database_field = 'thread_id';
5181
    }
5182
5183
    // First we check if the notification is already set for this.
5184
    $sql = "SELECT * FROM $table_notification
5185
            WHERE
5186
                c_id = $course_id AND
5187
                $database_field = '".Database::escape_string($id)."' AND
5188
                user_id = '".intval($_user['user_id'])."'";
5189
    $result = Database::query($sql);
5190
    $total = Database::num_rows($result);
5191
5192
    // If the user did not indicate that (s)he wanted to be notified already
5193
    // then we store the notification request (to prevent double notification requests).
5194
    if ($total <= 0) {
5195
        $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id)
5196
                VALUES (".$course_id.", '".Database::escape_string($id)."','".intval($_user['user_id'])."')";
5197
        Database::query($sql);
5198
        Session::erase('forum_notification');
5199
        get_notifications_of_user(0, true);
5200
5201
        return get_lang('YouWillBeNotifiedOfNewPosts');
5202
    } else {
5203
        if (!$add_only) {
5204
            $sql = "DELETE FROM $table_notification
5205
                    WHERE
5206
                        c_id = $course_id AND
5207
                        $database_field = '".Database::escape_string($id)."' AND
5208
                        user_id = '".intval($_user['user_id'])."'";
5209
            Database::query($sql);
5210
            Session::erase('forum_notification');
5211
            get_notifications_of_user(0, true);
5212
5213
            return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
5214
        }
5215
    }
5216
}
5217
5218
/**
5219
 * This function retrieves all the email adresses of the users who wanted to be notified
5220
 * about a new post in a certain forum or thread
5221
 *
5222
 * @param string $content does the user want to be notified about a forum or about a thread
5223
 * @param integer $id the id of the forum or thread
5224
 * @return array returns
5225
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5226
 * @version May 2008, dokeos 1.8.5
5227
 * @since May 2008, dokeos 1.8.5
5228
 */
5229
function get_notifications($content, $id)
5230
{
5231
    // Database table definition
5232
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5233
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5234
5235
    $course_id = api_get_course_int_id();
5236
5237
    // Which database field contains the notification?
5238
    if ($content == 'forum') {
5239
        $database_field = 'forum_id';
5240
    } else {
5241
        $database_field = 'thread_id';
5242
    }
5243
5244
    $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
5245
            FROM $table_users user, $table_notification notification
5246
            WHERE notification.c_id = $course_id AND user.active = 1 AND
5247
            user.user_id = notification.user_id AND
5248
            notification.$database_field= '".Database::escape_string($id)."'";
5249
5250
    $result = Database::query($sql);
5251
    $return = array();
5252
5253
    while ($row = Database::fetch_array($result)) {
5254
        $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
5255
    }
5256
5257
    return $return;
5258
}
5259
5260
/**
5261
 * Get all the users who need to receive a notification of a new post (those subscribed to
5262
 * the forum or the thread)
5263
 *
5264
 * @param integer $forum_id the id of the forum
5265
 * @param integer $thread_id the id of the thread
5266
 * @param integer $post_id the id of the post
5267
 * @return false|null
5268
 *
5269
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5270
 * @version May 2008, dokeos 1.8.5
5271
 * @since May 2008, dokeos 1.8.5
5272
 */
5273
function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
5274
{
5275
    $_course = api_get_course_info();
5276
    $forum_id = (int) $forum_id;
5277
5278
    // The content of the mail
5279
    $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forum_id.'&thread='.$thread_id;
5280
5281
    // Users who subscribed to the forum
5282
    if ($forum_id != 0) {
5283
        $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
5284
    } else {
5285
        return false;
5286
    }
5287
5288
    $current_thread = get_thread_information($forum_id, $thread_id);
5289
    $current_forum = get_forum_information($current_thread['forum_id']);
5290
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
5291
5292
    // User who subscribed to the thread
5293
    if ($thread_id != 0) {
5294
        $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
5295
    }
5296
5297
    // Merging the two
5298
    $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
5299
    $sender_id = api_get_user_id();
5300
5301
    if (is_array($users_to_be_notified)) {
5302
        foreach ($users_to_be_notified as $value) {
5303
5304
            $user_info = api_get_user_info($value['user_id']);
5305
            $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
5306
            $email_body .= get_lang('NewForumPost').": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
5307
            $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."]  <br />\n";
5308
            $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
5309
            $email_body .= get_lang('ThreadCanBeFoundHere').': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
5310
5311
            MessageManager::send_message_simple(
5312
                $value['user_id'], $subject, $email_body, $sender_id
5313
            );
5314
        }
5315
    }
5316
}
5317
5318
/**
5319
 * Get all the notification subscriptions of the user
5320
 * = which forums and which threads does the user wants to be informed of when a new
5321
 * post is added to this thread
5322
 *
5323
 * @param integer $user_id the user_id of a user (default = 0 => the current user)
5324
 * @param boolean $force force get the notification subscriptions (even if the information is already in the session
5325
 * @return array returns
5326
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5327
 * @version May 2008, dokeos 1.8.5
5328
 * @since May 2008, dokeos 1.8.5
5329
 */
5330
function get_notifications_of_user($user_id = 0, $force = false)
5331
{
5332
    // Database table definition
5333
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5334
    $course_id = api_get_course_int_id();
5335
    if (empty($course_id) || $course_id == -1) {
5336
        return null;
5337
    }
5338
    if ($user_id == 0) {
5339
        $user_id = api_get_user_id();
5340
    }
5341
5342
    if (!isset($_SESSION['forum_notification']) ||
5343
        $_SESSION['forum_notification']['course'] != $course_id ||
5344
        $force = true
5345
    ) {
5346
        $_SESSION['forum_notification']['course'] = $course_id;
5347
5348
        $sql = "SELECT * FROM $table_notification
5349
                WHERE c_id = $course_id AND user_id='".intval($user_id)."'";
5350
        $result = Database::query($sql);
5351
        while ($row = Database::fetch_array($result)) {
5352
            if (!is_null($row['forum_id'])) {
5353
                $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
5354
            }
5355
            if (!is_null($row['thread_id'])) {
5356
                $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
5357
            }
5358
        }
5359
    }
5360
}
5361
5362
/**
5363
 * This function counts the number of post inside a thread
5364
 * @param   int $thread_id
5365
 * @return  int the number of post inside a thread
5366
 * @author Jhon Hinojosa <[email protected]>,
5367
 * @version octubre 2008, dokeos 1.8
5368
 */
5369 View Code Duplication
function count_number_of_post_in_thread($thread_id)
5370
{
5371
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5372
    $course_id = api_get_course_int_id();
5373
    if (empty($course_id)) {
5374
        return 0;
5375
    }
5376
    $sql = "SELECT count(*) count FROM $table_posts
5377
            WHERE 
5378
                c_id = $course_id AND 
5379
                thread_id='".intval($thread_id)."' ";
5380
    $result = Database::query($sql);
5381
5382
    $count = 0;
5383
    if (Database::num_rows($result) > 0) {
5384
        $row = Database::fetch_array($result);
5385
        $count = $row['count'];
5386
    }
5387
5388
    return $count;
5389
}
5390
5391
/**
5392
 * This function counts the number of post inside a thread user
5393
 * @param   int $thread_id
5394
 * @param   int $user_id
5395
 *
5396
 * @return  int the number of post inside a thread user
5397
 */
5398 View Code Duplication
function count_number_of_post_for_user_thread($thread_id, $user_id)
5399
{
5400
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5401
    $course_id = api_get_course_int_id();
5402
    $sql = "SELECT count(iid) as count 
5403
            FROM $table_posts
5404
            WHERE c_id = $course_id AND
5405
                  thread_id=".intval($thread_id)." AND
5406
                  poster_id = ".intval($user_id)." AND visible = 1 ";
5407
    $result = Database::query($sql);
5408
    $count = 0;
5409
    if (Database::num_rows($result) > 0) {
5410
        $count = Database::fetch_array($result);
5411
        $count = $count['count'];
5412
    }
5413
5414
    return $count;
5415
}
5416
5417
/**
5418
 * This function counts the number of user register in course
5419
 * @param   int $course_id Course ID
5420
 * @deprecated use CourseManager::get_users_count_in_course
5421
 * @return  int the number of user register in course
5422
 * @author Jhon Hinojosa <[email protected]>,
5423
 * @version octubre 2008, dokeos 1.8
5424
 */
5425
function count_number_of_user_in_course($course_id)
5426
{
5427
    $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5428
5429
    $sql = "SELECT * FROM $table
5430
            WHERE c_id ='".intval($course_id)."' ";
5431
    $result = Database::query($sql);
5432
5433
    return count(Database::store_result($result));
5434
}
5435
5436
/**
5437
 * This function retrieves information of statistical
5438
 * @param   int $thread_id
5439
 * @param   int $user_id
5440
 * @param   int $course_id
5441
 *
5442
 * @return  array the information of statistical
5443
 * @author Jhon Hinojosa <[email protected]>,
5444
 * @version oct 2008, dokeos 1.8
5445
 */
5446
function get_statistical_information($thread_id, $user_id, $course_id)
5447
{
5448
    $result = array();
5449
    $courseInfo = api_get_course_info_by_id($course_id);
5450
    $result['user_course'] = CourseManager::get_users_count_in_course($courseInfo['code']);
5451
    $result['post'] = count_number_of_post_in_thread($thread_id);
5452
    $result['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
5453
5454
    return $result;
5455
}
5456
5457
/**
5458
 * This function return the posts inside a thread from a given user
5459
 * @param   string $course_code
5460
 * @param   int $thread_id
5461
 * @param   int $user_id
5462
 *
5463
 * @return  array posts inside a thread
5464
 * @author Jhon Hinojosa <[email protected]>,
5465
 * @version oct 2008, dokeos 1.8
5466
 */
5467
function get_thread_user_post($course_code, $thread_id, $user_id)
5468
{
5469
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5470
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5471
    $thread_id = intval($thread_id);
5472
    $user_id = intval($user_id);
5473
    $course_info = api_get_user_info($course_code);
5474
    $course_id = $course_info['real_id'];
5475
5476
    if (empty($course_id)) {
5477
        $course_id = api_get_course_int_id();
5478
    }
5479
    $sql = "SELECT * FROM $table_posts posts
5480
            LEFT JOIN  $table_users users
5481
                ON posts.poster_id=users.user_id
5482
            WHERE
5483
                posts.c_id = $course_id AND
5484
                posts.thread_id='$thread_id'
5485
                AND posts.poster_id='$user_id'
5486
            ORDER BY posts.post_id ASC";
5487
5488
    $result = Database::query($sql);
5489
    $post_list = array();
5490 View Code Duplication
    while ($row = Database::fetch_array($result)) {
5491
        $row['status'] = '1';
5492
        $post_list[] = $row;
5493
        $sql = "SELECT * FROM $table_posts posts
5494
                LEFT JOIN $table_users users
5495
                ON (posts.poster_id=users.user_id)
5496
                WHERE
5497
                    posts.c_id = $course_id AND
5498
                    posts.thread_id='$thread_id'
5499
                    AND posts.post_parent_id='".$row['post_id']."'
5500
                ORDER BY posts.post_id ASC";
5501
        $result2 = Database::query($sql);
5502
        while ($row2 = Database::fetch_array($result2)) {
5503
            $row2['status'] = '0';
5504
            $post_list[] = $row2;
5505
        }
5506
    }
5507
5508
    return $post_list;
5509
}
5510
5511
/**
5512
 * This function get the name of an thread by id
5513
 * @param int thread_id
5514
 * @return String
5515
 * @author Christian Fasanando
5516
 * @author Julio Montoya <[email protected]> Adding security
5517
 */
5518
function get_name_thread_by_id($thread_id)
5519
{
5520
    $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
5521
    $course_id = api_get_course_int_id();
5522
    $sql = "SELECT thread_title 
5523
            FROM $t_forum_thread
5524
            WHERE c_id = $course_id AND thread_id = '".intval($thread_id)."' ";
5525
    $result = Database::query($sql);
5526
    $row = Database::fetch_array($result);
5527
5528
    return $row[0];
5529
}
5530
5531
/**
5532
 * This function gets all the post written by an user
5533
 * @param int $user_id
5534
 * @param string $course_code
5535
 *
5536
 * @return string
5537
 */
5538
function get_all_post_from_user($user_id, $course_code)
5539
{
5540
    $j = 0;
5541
    $forums = get_forums('', $course_code);
5542
    krsort($forums);
5543
    $forum_results = '';
5544
5545
    foreach ($forums as $forum) {
5546
        if ($forum['visibility'] == 0) {
5547
            continue;
5548
        }
5549
        if ($j <= 4) {
5550
            $threads = get_threads($forum['forum_id']);
5551
5552
            if (is_array($threads)) {
5553
                $i = 0;
5554
                $hand_forums = '';
5555
                $post_counter = 0;
5556
5557
                foreach ($threads as $thread) {
5558
                    if ($thread['visibility'] == 0) {
5559
                        continue;
5560
                    }
5561
                    if ($i <= 4) {
5562
                        $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
5563
                        $post_counter = count($post_list);
5564
                        if (is_array($post_list) && count($post_list) > 0) {
5565
                            $hand_forums.= '<div id="social-thread">';
5566
                            $hand_forums.= Display::return_icon('thread.png', get_lang('Thread'), '', ICON_SIZE_MEDIUM);
5567
                            $hand_forums.= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
5568
                            $hand_forums.= '</div>';
5569
5570
                            foreach ($post_list as $posts) {
5571
                                $hand_forums.= '<div id="social-post">';
5572
                                $hand_forums.= '<strong>'.Security::remove_XSS($posts['post_title'], STUDENT).'</strong>';
5573
                                $hand_forums.= '<br / >';
5574
                                $hand_forums.= Security::remove_XSS($posts['post_text'], STUDENT);
5575
                                $hand_forums.= '</div>';
5576
                                $hand_forums.= '<br / >';
5577
                            }
5578
                        }
5579
                    }
5580
                    $i++;
5581
                }
5582
                $forum_results .='<div id="social-forum">';
5583
                $forum_results .='<div class="clear"></div><br />';
5584
                $forum_results .='<div id="social-forum-title">'.
5585
                    Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS($forum['forum_title'], STUDENT).
5586
                    '<div style="float:right;margin-top:-35px">
5587
                        <a href="../forum/viewforum.php?'.api_get_cidreq_params($course_code).'&forum='.$forum['forum_id'].' " >'.
5588
                            get_lang('SeeForum').'    
5589
                        </a>
5590
                     </div></div>';
5591
                $forum_results .='<br / >';
5592
                if ($post_counter > 0) {
5593
                    $forum_results .=$hand_forums;
5594
                }
5595
                $forum_results .='</div>';
5596
            }$j++;
5597
        }
5598
    }
5599
5600
    return $forum_results;
5601
}
5602
5603
/**
5604
 * @param string $course_code
5605
 * @param int $thread_id
5606
 * @param int $user_id
5607
 * @param int $limit
5608
 *
5609
 * @return array
5610
 */
5611
function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
5612
{
5613
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5614
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5615
5616
    $course_info = api_get_course_info($course_code);
5617
    $course_id = $course_info['real_id'];
5618
5619
    $sql = "SELECT * FROM $table_posts posts
5620
            LEFT JOIN  $table_users users
5621
                ON posts.poster_id=users.user_id
5622
            WHERE
5623
                posts.c_id = $course_id AND
5624
                posts.thread_id='".Database::escape_string($thread_id)."'
5625
                AND posts.poster_id='".Database::escape_string($user_id)."'
5626
            ORDER BY posts.post_id DESC LIMIT $limit ";
5627
    $result = Database::query($sql);
5628
    $post_list = array();
5629
    while ($row = Database::fetch_array($result)) {
5630
        $row['status'] = '1';
5631
        $post_list[] = $row;
5632
    }
5633
5634
    return $post_list;
5635
}
5636
5637
/**
5638
 * @param string $user_id
5639
 * @param int $courseId
5640
 * @param int $sessionId
5641
 *
5642
 * @return array
5643
 */
5644
function getForumCreatedByUser($user_id, $courseId, $sessionId)
5645
{
5646
    $items = api_get_item_property_list_by_tool_by_user(
5647
        $user_id,
5648
        'forum',
5649
        $courseId,
5650
        $sessionId
5651
    );
5652
5653
    $courseInfo = api_get_course_info_by_id($courseId);
5654
5655
    $forumList = array();
5656 View Code Duplication
    if (!empty($items)) {
5657
        foreach ($items as $forum) {
5658
            $forumInfo = get_forums(
5659
                $forum['ref'],
5660
                $courseInfo['code'],
5661
                true,
5662
                $sessionId
5663
            );
5664
5665
            $forumList[] = array(
5666
                $forumInfo['forum_title'],
5667
                api_get_local_time($forum['insert_date']),
5668
                api_get_local_time($forum['lastedit_date']),
5669
            );
5670
        }
5671
    }
5672
5673
    return $forumList;
5674
}
5675
5676
/**
5677
 * This function builds an array of all the posts in a given thread
5678
 * where the key of the array is the post_id
5679
 * It also adds an element children to the array which itself is an array
5680
 * that contains all the id's of the first-level children
5681
 * @return array $rows containing all the information on the posts of a thread
5682
 * @author Patrick Cool <[email protected]>, Ghent University
5683
 */
5684
function calculate_children($rows)
5685
{
5686
    $sorted_rows = array(0 => array());
5687
    if (!empty($rows)) {
5688
        foreach ($rows as $row) {
5689
            $rows_with_children[$row['post_id']] = $row;
5690
            $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
5691
        }
5692
5693
        $rows = $rows_with_children;
5694
        forumRecursiveSort($rows, $sorted_rows);
5695
        unset($sorted_rows[0]);
5696
    }
5697
5698
    return $sorted_rows;
5699
}
5700
5701
/**
5702
 * @param $rows
5703
 * @param $threads
5704
 * @param int $seed
5705
 * @param int $indent
5706
 */
5707
function forumRecursiveSort($rows, &$threads, $seed = 0, $indent = 0)
5708
{
5709
    if ($seed > 0) {
5710
        $threads[$rows[$seed]['post_id']] = $rows[$seed];
5711
        $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
5712
        $indent++;
5713
    }
5714
5715
    if (isset($rows[$seed]['children'])) {
5716
        foreach ($rows[$seed]['children'] as $child) {
5717
            forumRecursiveSort($rows, $threads, $child, $indent);
5718
        }
5719
    }
5720
}
5721
5722
/**
5723
 * Update forum attachment data, used to update comment and post ID.
5724
 * @param $array Array (field => value) to update forum attachment row.
5725
 * @param $id Attach ID to find row to update.
5726
 * @param null $courseId Course ID to find row to update.
5727
 * @return int Number of affected rows.
5728
 */
5729
function editAttachedFile($array, $id, $courseId = null) {
5730
    // Init variables
5731
    $setString = '';
5732
    $id = intval($id);
5733
    $courseId = intval($courseId);
5734
    if (empty($courseId)) {
5735
        // $courseId can be null, use api method
5736
        $courseId= api_get_course_int_id();
5737
    }
5738
    /*
5739
     * Check if Attachment ID and Course ID are greater than zero
5740
     * and array of field values is not empty
5741
     */
5742
    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
5743
        foreach($array as $key => &$item) {
5744
            $item = Database::escape_string($item);
5745
            $setString .= $key . ' = "' .$item . '", ';
5746
        }
5747
        // Delete last comma
5748
        $setString = substr($setString, 0, strlen($setString) - 2);
5749
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5750
        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
5751
        $result = Database::query($sql);
5752
        if ($result !== false) {
5753
            $affectedRows = Database::affected_rows($result);
5754 View Code Duplication
            if ($affectedRows > 0) {
5755
                /*
5756
                 * If exist in $_SESSION variable, then delete them from it
5757
                 * because they would be deprecated
5758
                 */
5759
                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
5760
                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
5761
                }
5762
            }
5763
5764
            return $affectedRows;
5765
        }
5766
    }
5767
5768
    return 0;
5769
}
5770
5771
/**
5772
 * Return a table where the attachments will be set
5773
 * @param int $postId Forum Post ID
5774
 *
5775
 * @return string The Forum Attachments Ajax Table
5776
 */
5777
function getAttachmentsAjaxTable($postId = 0)
5778
{
5779
    // Init variables
5780
    $postId = intval($postId);
5781
    $courseId = api_get_course_int_id();
5782
    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5783
    $fileDataContent = '';
5784
    // Update comment to show if form did not pass validation
5785
    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
5786
        // 'file_ids is the name from forum attachment ajax form
5787
        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
5788
            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) &&
5789
                is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])
5790
            ) {
5791
                // If exist forum attachment then update into $_SESSION data
5792
                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
5793
            }
5794
        }
5795
    }
5796
5797
    // Get data to fill into attachment files table
5798
    if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5799
        is_array($_SESSION['forum']['upload_file'][$courseId])
5800
    ) {
5801
        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
5802
        foreach ($uploadedFiles as $k => $uploadedFile) {
5803
            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
5804
                // Buil html table including an input with attachmentID
5805
                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
5806
                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
5807
                    $uploadedFile['delete'] . '</td>' .
5808
                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
5809
            } else {
5810
                /*
5811
                 * If attachment data is empty, then delete it from $_SESSION
5812
                 * because could generate and empty row into html table
5813
                 */
5814
                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
5815
            }
5816
        }
5817
    }
5818
    $style = empty($fileDataContent) ? 'display: none;' : '';
5819
    // Forum attachment Ajax table
5820
    $fileData = '
5821
    <div class="control-group " style="'. $style . '">
5822
        <label class="control-label">'.get_lang('AttachmentList').'</label>
5823
        <div class="controls">
5824
            <table id="attachmentFileList" class="files data_table span10">
5825
                <tr>
5826
                    <th>'.get_lang('FileName').'</th>
5827
                    <th>'.get_lang('Size').'</th>
5828
                    <th>'.get_lang('Status').'</th>
5829
                    <th>'.get_lang('Comment').'</th>
5830
                    <th>'.get_lang('Delete').'</th>
5831
                </tr>
5832
                '.$fileDataContent.'
5833
            </table>
5834
        </div>
5835
    </div>';
5836
5837
    return $fileData;
5838
}
5839
5840
/**
5841
 * Return an array of prepared attachment data to build forum attachment table
5842
 * Also, save this array into $_SESSION to do available the attachment data
5843
 * @param int $forumId
5844
 * @param int $threadId
5845
 * @param int $postId
5846
 * @param int $attachId
5847
 * @param int $courseId
5848
 *
5849
 * @return array
5850
 */
5851
function getAttachedFiles($forumId, $threadId, $postId = 0, $attachId = 0, $courseId = 0)
5852
{
5853
    $forumId = intval($forumId);
5854
    $courseId = intval($courseId);
5855
    $attachId = intval($attachId);
5856
    $postId = intval($postId);
5857
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5858
    if (empty($courseId)) {
5859
        // $courseId can be null, use api method
5860
        $courseId = api_get_course_int_id();
5861
    }
5862
    if (empty($forumId)) {
5863
        if (!empty($_REQUEST['forum'])) {
5864
            $forumId = intval($_REQUEST['forum']);
5865
        } else {
5866
            // if forum ID is empty, cannot generate delete url
5867
5868
            return array();
5869
        }
5870
    }
5871
    // Check if exist at least one of them to filter forum attachment select query
5872
    if (empty($postId) && empty($attachId)) {
5873
5874
        return array();
5875
    } elseif (empty($postId)) {
5876
        $filter = "AND iid = $attachId";
5877
    } elseif (empty($attachId)) {
5878
        $filter = "AND post_id = $postId";
5879
    } else {
5880
        $filter = "AND post_id = $postId AND iid = $attachId";
5881
    }
5882
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5883
    $sql = "SELECT iid, comment, filename, path, size
5884
            FROM $forumAttachmentTable
5885
            WHERE c_id = $courseId $filter";
5886
    $result = Database::query($sql);
5887
    $json = array();
5888
    if ($result !== false && Database::num_rows($result) > 0) {
5889
        while ($row = Database::fetch_array($result, 'ASSOC')) {
5890
            // name contains an URL to download attachment file and its filename
5891
            $json['name'] = Display::url(
5892
                api_htmlentities($row['filename']),
5893
                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'].'&'.api_get_cidreq(),
5894
                array('target'=>'_blank', 'class' => 'attachFilename')
5895
            );
5896
            $json['id'] = $row['iid'];
5897
            $json['comment'] = $row['comment'];
5898
            // Format file size
5899
            $json['size'] = format_file_size($row['size']);
5900
            // Check if $row is consistent
5901
            if (!empty($row) && is_array($row)) {
5902
                // Set result as success and bring delete URL
5903
                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
5904
                $url = api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php?' . api_get_cidreq() . '&action=delete_attach&forum=' . $forumId . '&thread=' . $threadId.'&id_attach=' . $row['iid'];
5905
                $json['delete'] = Display::url(
5906
                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL),
5907
                    $url,
5908
                    array('class' => 'deleteLink')
5909
                );
5910
            } else {
5911
                // If not, set an exclamation result
5912
                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
5913
            }
5914
            // Store array data into $_SESSION
5915
            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
5916
        }
5917
    }
5918
5919
    return $json;
5920
}
5921
5922
/**
5923
 * Clear forum attachment data stored in $_SESSION,
5924
 * If is not defined post, it will clear all forum attachment data from course
5925
 * @param int $postId -1 : Clear all attachments from course stored in $_SESSION
5926
 *                      0 : Clear attachments from course, except from temporal post "0"
5927
 *                          but without delete them from file system and database
5928
 *                     Other values : Clear attachments from course except specified post
5929
 *                          and delete them from file system and database
5930
 * @param int $courseId : Course ID, if it is null, will use api_get_course_int_id()
5931
 *
5932
 * @return array
5933
 */
5934
function clearAttachedFiles($postId = null, $courseId = null) {
5935
    // Init variables
5936
    $courseId = intval($courseId);
5937
    $postId = intval($postId);
5938
    $array = array();
5939
    if (empty($courseId)) {
5940
        // $courseId can be null, use api method
5941
        $courseId = api_get_course_int_id();
5942
    }
5943
    if ($postId === -1) {
5944
        // If post ID is -1 then delete course's attachment data from $_SESSION
5945 View Code Duplication
        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
5946
            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
5947
            unset($_SESSION['forum']['upload_file'][$courseId]);
5948
        }
5949
    } else {
5950
        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5951
        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5952
            is_array($_SESSION['forum']['upload_file'][$courseId])) {
5953
            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
5954
                if (!in_array($attachId, $attachIds)) {
5955
                    // If attach ID is not into specified post, delete attachment
5956
                    // Save deleted attachment ID
5957
                    $array[] = $attachId;
5958
                    if ($postId !== 0) {
5959
                        // Post 0 is temporal, delete them from file system and DB
5960
                        delete_attachment(0, $attachId, false);
5961
                    }
5962
                    // Delete attachment data from $_SESSION
5963
                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
5964
                }
5965
            }
5966
        }
5967
    }
5968
5969
    return $array;
5970
}
5971
5972
/**
5973
 * Returns an array of forum attachment ids into a course and forum post
5974
 * @param int $postId
5975
 * @param int $courseId
5976
 *
5977
 * @return array
5978
 */
5979
function getAttachmentIdsByPostId($postId, $courseId = null)
5980
{
5981
5982
    $array = array();
5983
    $courseId = intval($courseId);
5984
    $postId = intval($postId);
5985
    if (empty($courseId)) {
5986
        // $courseId can be null, use api method
5987
        $courseId = api_get_course_int_id();
5988
    }
5989
    if ($courseId > 0) {
5990
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5991
        $sql = "SELECT id FROM $forumAttachmentTable
5992
                WHERE c_id = $courseId AND post_id = $postId";
5993
        $result = Database::query($sql);
5994
        if ($result !== false && Database::num_rows($result) > 0) {
5995
            while ($row = Database::fetch_array($result,'ASSOC')) {
5996
                $array[] = $row['id'];
5997
            }
5998
        }
5999
    }
6000
    return $array;
6001
}
6002
6003
/**
6004
 * Check if the forum category exists looking for its title
6005
 * @param string $title The forum category title
6006
 * @param int $courseId The course ID
6007
 * @param int $sessionId Optional. The session ID
6008
 * @return boolean
6009
 */
6010
function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
6011
{
6012
    $sessionId = intval($sessionId);
6013
6014
    $forumCategoryTable = Database::get_course_table(TABLE_FORUM_CATEGORY);
6015
    $itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
6016
6017
    $fakeFrom = "$forumCategoryTable fc
6018
        INNER JOIN $itemProperty ip ";
6019
6020
    if ($sessionId === 0) {
6021
        $fakeFrom .= "
6022
            ON (
6023
                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)
6024
            )
6025
        ";
6026
    } else {
6027
        $fakeFrom .= "
6028
            ON (
6029
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND fc.session_id = ip.session_id
6030
            )
6031
        ";
6032
    }
6033
6034
    $resultData = Database::select(
6035
        'fc.*',
6036
        $fakeFrom,
6037
        [
6038
            'where' => [
6039
                'ip.visibility != ? AND ' => 2,
6040
                'ip.tool = ? AND ' => TOOL_FORUM_CATEGORY,
6041
                'fc.session_id = ? AND ' => $sessionId,
6042
                'fc.cat_title = ? AND ' => $title,
6043
                'fc.c_id = ?' => intval($courseId)
6044
            ]
6045
        ],
6046
        'first'
6047
    );
6048
6049
    if (empty($resultData)) {
6050
        return false;
6051
    }
6052
6053
    return $resultData;
6054
}
6055
6056
function getPostStatus($current_forum, $row)
6057
{
6058
    $statusIcon = '';
6059
    if ($current_forum['moderated']) {
6060
        $statusIcon = '<br /><br />';
6061
        $row['status'] = empty($row['status']) ? 2 : $row['status'];
6062
        switch ($row['status']) {
6063
            case CForumPost::STATUS_VALIDATED:
6064
                $statusIcon .= Display::label(get_lang('Validated'), 'success');
6065
                break;
6066
            case CForumPost::STATUS_WAITING_MODERATION:
6067
                $statusIcon .= Display::label(get_lang('WaitingModeration'), 'warning');
6068
                break;
6069
            case CForumPost::STATUS_REJECTED:
6070
                $statusIcon .= Display::label(get_lang('Rejected'), 'danger');
6071
                break;
6072
        }
6073
    }
6074
6075
    return $statusIcon;
6076
}
6077