Completed
Push — master ( 395485...bbad3a )
by Julito
43:12
created

forumfunction.inc.php ➔ getPostStatus()   C

Complexity

Conditions 10
Paths 129

Size

Total Lines 57
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 42
nc 129
nop 3
dl 0
loc 57
rs 6.2295
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
use Doctrine\Common\Collections\Criteria;
6
use Chamilo\CourseBundle\Entity\CForumPost;
7
use Chamilo\CourseBundle\Entity\CForumThread;
8
9
/**
10
 * These files are a complete rework of the forum. The database structure is
11
 * based on phpBB but all the code is rewritten. A lot of new functionalities
12
 * are added:
13
 * - forum categories and forums can be sorted up or down, locked or made invisible
14
 * - consistent and integrated forum administration
15
 * - forum options:     are students allowed to edit their post?
16
 *                         moderation of posts (approval)
17
 *                         reply only forums (students cannot create new threads)
18
 *                         multiple forums per group
19
 * - sticky messages
20
 * - new view option: nested view
21
 * - quoting a message
22
 *
23
 * @package chamilo.forum
24
 *
25
 * @todo several functions have to be moved to the itemmanager library
26
 * @todo displaying icons => display library
27
 * @todo complete the missing phpdoc the correct order should be
28
 * @todo convert into a class
29
 */
30
31
get_notifications_of_user();
32
33
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
34
$htmlHeadXtra[] = '<script>
35
36
function check_unzip() {
37
    if (document.upload.unzip.checked){
38
        document.upload.if_exists[0].disabled=true;
39
        document.upload.if_exists[1].checked=true;
40
        document.upload.if_exists[2].disabled=true;
41
    } else {
42
        document.upload.if_exists[0].checked=true;
43
        document.upload.if_exists[0].disabled=false;
44
        document.upload.if_exists[2].disabled=false;
45
    }
46
}
47
function setFocus() {
48
    $("#title_file").focus();
49
}
50
</script>';
51
// The next javascript script is to manage ajax upload file
52
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
53
54
// Recover Thread ID, will be used to generate delete attachment URL to do ajax
55
$threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : 0;
56
$forumId = isset($_REQUEST['forum']) ? intval($_REQUEST['forum']) : 0;
57
58
// The next javascript script is to delete file by ajax
59
$htmlHeadXtra[] = '<script>
60
$(function () {
61
    $(document).on("click", ".deleteLink", function(e) {
62
        e.preventDefault();
63
        e.stopPropagation();
64
        var l = $(this);
65
        var id = l.closest("tr").attr("id");
66
        var filename = l.closest("tr").find(".attachFilename").html();
67
        if (confirm("' . get_lang('AreYouSureToDeleteJS') . '", filename)) {
68
            $.ajax({
69
                type: "POST",
70
                url: "'.api_get_path(WEB_AJAX_PATH) . 'forum.ajax.php?'.api_get_cidreq().'&a=delete_file&attachId=" + id +"&thread='.$threadId .'&forum='.$forumId .'",
71
                dataType: "json",
72
                success: function(data) {
73
                    if (data.error == false) {
74
                        l.closest("tr").remove();
75
                        if ($(".files td").length < 1) {
76
                            $(".files").closest(".control-group").hide();
77
                        }
78
                    }
79
                }
80
            })
81
        }
82
    });
83
});
84
</script>';
85
86
/**
87
 * This function handles all the forum and forum categories actions. This is a wrapper for the
88
 * forum and forum categories. All this code code could go into the section where this function is
89
 * called but this make the code there cleaner.
90
 * @param int $lp_id Learning path Id
91
 *
92
 * @return void
93
 * @author Patrick Cool <[email protected]>, Ghent University
94
 * @author Juan Carlos Raña Trabado (return to lp_id)
95
 * @version may 2011, Chamilo 1.8.8
96
 */
97
function handle_forum_and_forumcategories($lp_id = null)
98
{
99
    $action_forum_cat = isset($_GET['action']) ? $_GET['action'] : '';
100
    $get_content = isset($_GET['content']) ? $_GET['content'] : '';
101
    $post_submit_cat = isset($_POST['SubmitForumCategory']) ? true : false;
102
    $post_submit_forum = isset($_POST['SubmitForum']) ? true : false;
103
    $get_id = isset($_GET['id']) ? intval($_GET['id']) : '';
104
    $forum_categories_list = get_forum_categories();
105
106
    //Verify if forum category exists
107
    if (empty($forum_categories_list)) {
108
        $get_content = 'forumcategory';
109
    }
110
111
    // Adding a forum category
112
    if (($action_forum_cat == 'add' && $get_content == 'forumcategory') || $post_submit_cat) {
113
        show_add_forumcategory_form(array(), $lp_id); //$lp_id when is called from learning path
114
    }
115
116
    // Adding a forum
117
    if ((($action_forum_cat == 'add' || $action_forum_cat == 'edit') && $get_content == 'forum') || $post_submit_forum) {
118
        if ($action_forum_cat == 'edit' && $get_id || $post_submit_forum) {
119
            $inputvalues = get_forums($get_id);
120
        } else {
121
            $inputvalues = array();
122
        }
123
        show_add_forum_form($inputvalues, $lp_id);
124
    }
125
126
    // Edit a forum category
127
    if (($action_forum_cat == 'edit' && $get_content == 'forumcategory') || (isset($_POST['SubmitEditForumCategory'])) ? true : false) {
128
        $forum_category = get_forum_categories($get_id);
129
        show_edit_forumcategory_form($forum_category);
130
    }
131
132
    // Delete a forum category
133
    if ($action_forum_cat == 'delete') {
134
        $id_forum = intval($get_id);
135
        $list_threads = get_threads($id_forum);
136
137
        for ($i = 0; $i < count($list_threads); $i++) {
138
            deleteForumCategoryThread('thread', $list_threads[$i]['thread_id']);
139
            $link_info = GradebookUtils::isResourceInCourseGradebook(
140
                api_get_course_int_id(),
141
                5,
142
                $list_threads[$i]['thread_id'],
143
                api_get_session_id()
144
            );
145
            if ($link_info !== false) {
146
                GradebookUtils::remove_resource_from_course_gradebook($link_info['id']);
147
            }
148
        }
149
        $return_message = deleteForumCategoryThread($get_content, $get_id);
150
        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...
151
    }
152
153
    // Change visibility of a forum or a forum category.
154
    if ($action_forum_cat == 'invisible' || $action_forum_cat == 'visible') {
155
        $return_message = change_visibility($get_content, $get_id, $action_forum_cat);
156
        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...
157
    }
158
    // Change lock status of a forum or a forum category.
159
    if ($action_forum_cat == 'lock' || $action_forum_cat == 'unlock') {
160
        $return_message = change_lock_status($get_content, $get_id, $action_forum_cat);
161
        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...
162
    }
163
    // Move a forum or a forum category.
164
    if ($action_forum_cat == 'move' && isset($_GET['direction'])) {
165
        $return_message = move_up_down($get_content, $_GET['direction'], $get_id);
166
        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...
167
    }
168
}
169
170
/**
171
 * This function displays the form that is used to add a forum category.
172
 *
173
 * @param  array $inputvalues (deprecated, set to null when calling)
174
 * @param  int $lp_id Learning path ID
175
 *
176
 * @author Patrick Cool <[email protected]>, Ghent University
177
 * @author Juan Carlos Raña Trabado (return to lp_id)
178
 * @version may 2011, Chamilo 1.8.8
179
 */
180
function show_add_forumcategory_form($inputvalues = array(), $lp_id)
181
{
182
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
183
    // hidden field if from learning path
184
    $form->addElement('hidden', 'lp_id', $lp_id);
185
    // Setting the form elements.
186
    $form->addElement('header', get_lang('AddForumCategory'));
187
    $form->addElement('text', 'forum_category_title', get_lang('Title'), array('autofocus'));
188
    $form->addElement(
189
        'html_editor',
190
        'forum_category_comment',
191
        get_lang('Description'),
192
        null,
193
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
194
    );
195
    $form->addButtonCreate(get_lang('CreateCategory'), 'SubmitForumCategory');
196
197
    // Setting the rules.
198
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
199
200
    // The validation or display
201 View Code Duplication
    if ($form->validate()) {
202
        $check = Security::check_token('post');
203
        if ($check) {
204
            $values = $form->exportValues();
205
            store_forumcategory($values);
206
        }
207
        Security::clear_token();
208
    } else {
209
        $token = Security::get_token();
210
        $form->addElement('hidden', 'sec_token');
211
        $form->setConstants(array('sec_token' => $token));
212
        $form->display();
213
    }
214
}
215
216
/**
217
 * This function displays the form that is used to add a forum category.
218
 *
219
 * @param array $inputvalues
220
 * @param int $lp_id
221
 * @return void HTML
222
 *
223
 * @author Patrick Cool <[email protected]>, Ghent University
224
 * @author Juan Carlos Raña Trabado (return to lp_id)
225
 *
226
 * @version may 2011, Chamilo 1.8.8
227
 */
228
function show_add_forum_form($inputvalues = array(), $lp_id)
229
{
230
    $_course = api_get_course_info();
231
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
232
233
    // The header for the form
234
    if (!empty($inputvalues)) {
235
        $form_title = get_lang('EditForum');
236
    } else {
237
        $form_title = get_lang('AddForum');
238
    }
239
    $session_header = api_get_session_name();
240
    $form->addElement('header', $form_title.$session_header);
241
242
    // We have a hidden field if we are editing.
243
    if (!empty($inputvalues) && is_array($inputvalues)) {
244
        $my_forum_id = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
245
        $form->addElement('hidden', 'forum_id', $my_forum_id);
246
    }
247
    $lp_id = intval($lp_id);
248
249
    // hidden field if from learning path
250
    $form->addElement('hidden', 'lp_id', $lp_id);
251
252
    // The title of the forum
253
    $form->addElement('text', 'forum_title', get_lang('Title'), array('autofocus'));
254
255
    // The comment of the forum.
256
    $form->addElement(
257
        'html_editor',
258
        'forum_comment',
259
        get_lang('Description'),
260
        null,
261
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
262
    );
263
264
    // Dropdown list: Forum categories
265
    $forum_categories = get_forum_categories();
266
    foreach ($forum_categories as $key => $value) {
267
        $forum_categories_titles[$value['cat_id']] = $value['cat_title'];
268
    }
269
    $form->addElement('select', 'forum_category', get_lang('InForumCategory'), $forum_categories_titles);
270
    $form->applyFilter('forum_category', 'html_filter');
271
272
    if ($_course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD) {
273
        // This is for horizontal
274
        $group = array();
275
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('Yes'), 1);
276
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('No'), 0);
277
        $form->addGroup($group, 'allow_anonymous_group', get_lang('AllowAnonymousPosts'));
278
    }
279
280
    $form->addButtonAdvancedSettings('advanced_params');
281
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
282
283
    $form->addDateTimePicker(
284
        'start_time',
285
        array(get_lang('ForumStartDate'), get_lang('ForumStartDateComment')),
286
        array('id' => 'start_time')
287
    );
288
289
    $form->addDateTimePicker(
290
        'end_time',
291
        array(get_lang('ForumEndDate'), get_lang('ForumEndDateComment')),
292
        array('id' => 'end_time')
293
    );
294
295
    $form->addRule(
296
        array('start_time', 'end_time'),
297
        get_lang('StartDateMustBeBeforeTheEndDate'),
298
        'compare_datetime_text',
299
        '< allow_empty'
300
    );
301
302
    $group = array();
303
    $group[] = $form->createElement('radio', 'moderated', null, get_lang('Yes'), 1);
304
    $group[] = $form->createElement('radio', 'moderated', null, get_lang('No'), 0);
305
    $form->addGroup($group, 'moderated', get_lang('ModeratedForum'));
306
307
    $group = array();
308
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('Yes'), 1);
309
    $group[] = $form->createElement('radio', 'students_can_edit', null, get_lang('No'), 0);
310
    $form->addGroup($group, 'students_can_edit_group', get_lang('StudentsCanEdit'));
311
312
    $group = array();
313
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Approval'), 1);
314
    $group[] = $form->createElement('radio', 'approval_direct', null, get_lang('Direct'), 0);
315
316
    $group = array();
317
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('Yes'), 1);
318
    $group[] = $form->createElement('radio', 'allow_attachments', null, get_lang('No'), 0);
319
320
    $group = array();
321
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('Yes'), 1);
322
    $group[] = $form->createElement('radio', 'allow_new_threads', null, get_lang('No'), 0);
323
    $form->addGroup($group, 'allow_new_threads_group', get_lang('AllowNewThreads'));
324
325
    $group = array();
326
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Flat'), 'flat');
327
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Threaded'), 'threaded');
328
    $group[] = $form->createElement('radio', 'default_view_type', null, get_lang('Nested'), 'nested');
329
    $form->addGroup($group, 'default_view_type_group', get_lang('DefaultViewType'));
330
331
    // Drop down list: Groups
332
    $groups = GroupManager::get_group_list();
333
    $groups_titles[0] = get_lang('NotAGroupForum');
334
    foreach ($groups as $key => $value) {
335
        $groups_titles[$value['id']] = $value['name'];
336
    }
337
    $form->addElement('select', 'group_forum', get_lang('ForGroup'), $groups_titles);
338
339
    // Public or private group forum
340
    $group = array();
341
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Public'), 'public');
342
    $group[] = $form->createElement('radio', 'public_private_group_forum', null, get_lang('Private'), 'private');
343
    $form->addGroup($group, 'public_private_group_forum_group', get_lang('PublicPrivateGroupForum'));
344
345
    // Forum image
346
    $form->addProgress();
347
    if (!empty($inputvalues['forum_image'])) {
348
        $baseImagePath = api_get_course_path() . '/upload/forum/images/' . $inputvalues['forum_image'];
349
        $image_path = api_get_path(WEB_COURSE_PATH) . $baseImagePath;
350
        $sysImagePath = api_get_path(SYS_COURSE_PATH) . $baseImagePath;
351
352
        if (file_exists($sysImagePath)) {
353
            $show_preview_image = Display::img($image_path, null, ['class' => 'img-responsive']);
354
            $form->addElement('label', get_lang('PreviewImage'), $show_preview_image);
355
            $form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
356
        }
357
    }
358
    $forum_image = isset($inputvalues['forum_image']) ? $inputvalues['forum_image'] : '';
359
    $form->addElement('file', 'picture', ($forum_image != '' ? get_lang('UpdateImage') : get_lang('AddImage')));
360
    $form->addRule('picture', get_lang('OnlyImagesAllowed'), 'filetype', array('jpg', 'jpeg', 'png', 'gif'));
361
    $form->addElement('html', '</div>');
362
363
    // The OK button
364
    if (isset($_GET['id']) && $_GET['action'] == 'edit') {
365
        $form->addButtonUpdate(get_lang('ModifyForum'), 'SubmitForum');
366
    } else {
367
        $form->addButtonCreate(get_lang('CreateForum'), 'SubmitForum');
368
    }
369
370
    // setting the rules
371
    $form->addRule('forum_title', get_lang('ThisFieldIsRequired'), 'required');
372
    $form->addRule('forum_category', get_lang('ThisFieldIsRequired'), 'required');
373
374
    $defaultSettingAllowNewThreads = api_get_default_tool_setting('forum', 'allow_new_threads', 0);
375
376
    // Settings the defaults
377
    if (empty($inputvalues) || !is_array($inputvalues)) {
378
        $defaults['moderated']['moderated'] = 0;
379
        $defaults['allow_anonymous_group']['allow_anonymous'] = 0;
380
        $defaults['students_can_edit_group']['students_can_edit'] = 0;
381
        $defaults['approval_direct_group']['approval_direct'] = 0;
382
        $defaults['allow_attachments_group']['allow_attachments'] = 1;
383
        $defaults['allow_new_threads_group']['allow_new_threads'] = $defaultSettingAllowNewThreads;
384
        $defaults['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
385
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = 'public';
386
        if (isset($_GET['forumcategory'])) {
387
            $defaults['forum_category'] = Security::remove_XSS($_GET['forumcategory']);
388
        }
389
    } else {
390
        // the default values when editing = the data in the table
391
        $defaults['forum_id'] = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
392
        $defaults['forum_title'] = prepare4display(isset($inputvalues['forum_title']) ? $inputvalues['forum_title'] : null);
393
        $defaults['forum_comment'] = prepare4display(isset($inputvalues['forum_comment']) ? $inputvalues['forum_comment'] : null);
394
        $defaults['start_time'] = isset($inputvalues['start_time']) ? api_get_local_time($inputvalues['start_time']) : null;
395
        $defaults['end_time'] = isset($inputvalues['end_time']) ? api_get_local_time($inputvalues['end_time']) : null;
396
        $defaults['moderated']['moderated'] = isset($inputvalues['moderated']) ? $inputvalues['moderated'] : 0;
397
        $defaults['forum_category'] = isset($inputvalues['forum_category']) ? $inputvalues['forum_category'] : null;
398
        $defaults['allow_anonymous_group']['allow_anonymous'] = isset($inputvalues['allow_anonymous']) ? $inputvalues['allow_anonymous'] : null;
399
        $defaults['students_can_edit_group']['students_can_edit'] = isset($inputvalues['allow_edit']) ? $inputvalues['allow_edit'] : null;
400
        $defaults['approval_direct_group']['approval_direct'] = isset($inputvalues['approval_direct_post']) ? $inputvalues['approval_direct_post'] : null;
401
        $defaults['allow_attachments_group']['allow_attachments'] = isset($inputvalues['allow_attachments']) ? $inputvalues['allow_attachments'] : null;
402
        $defaults['allow_new_threads_group']['allow_new_threads'] = isset($inputvalues['allow_new_threads']) ? $inputvalues['allow_new_threads'] : $defaultSettingAllowNewThreads;
403
        $defaults['default_view_type_group']['default_view_type'] = isset($inputvalues['default_view']) ? $inputvalues['default_view'] : null;
404
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
405
        $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
406
    }
407
    $form->setDefaults($defaults);
408
    // Validation or display
409 View Code Duplication
    if ($form->validate()) {
410
        $check = Security::check_token('post');
411
        if ($check) {
412
            $values = $form->getSubmitValues();
413
            $return_message = store_forum($values);
414
            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...
415
        }
416
        Security::clear_token();
417
    } else {
418
        $token = Security::get_token();
419
        $form->addElement('hidden', 'sec_token');
420
        $form->setConstants(array('sec_token' => $token));
421
        $form->display();
422
    }
423
}
424
425
/**
426
 * This function deletes the forum image if exists
427
 *
428
 * @param int forum id
429
 * @return boolean true if success
430
 * @author Julio Montoya <[email protected]>
431
 * @version february 2006, dokeos 1.8
432
 */
433
function delete_forum_image($forum_id)
434
{
435
    $table_forums = Database::get_course_table(TABLE_FORUM);
436
    $course_id = api_get_course_int_id();
437
    $forum_id = intval($forum_id);
438
439
    $sql = "SELECT forum_image FROM $table_forums
440
            WHERE forum_id = $forum_id AND c_id = $course_id";
441
    $result = Database::query($sql);
442
    $row = Database::fetch_array($result);
443
    if ($row['forum_image'] != '') {
444
        $file = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$row['forum_image'];
445
        if (file_exists($file)) {
446
            unlink($file);
447
        }
448
449
        return true;
450
    } else {
451
        return false;
452
    }
453
}
454
455
/**
456
 * This function displays the form that is used to edit a forum category.
457
 * This is more or less a copy from the show_add_forumcategory_form function with the only difference that is uses
458
 * some default values. I tried to have both in one function but this gave problems with the handle_forum_and_forumcategories function
459
 * (storing was done twice)
460
 *
461
 * @param array
462
 * @return void HTML
463
 *
464
 * @author Patrick Cool <[email protected]>, Ghent University
465
 * @version february 2006, dokeos 1.8
466
 */
467
function show_edit_forumcategory_form($inputvalues = array())
468
{
469
    $categoryId = $inputvalues['cat_id'];
470
    $form = new FormValidator('forumcategory', 'post', 'index.php?'.api_get_cidreq().'&id='.$categoryId);
471
472
    // Setting the form elements.
473
    $form->addElement('header', '', get_lang('EditForumCategory'));
474
    $form->addElement('hidden', 'forum_category_id');
475
    $form->addElement('text', 'forum_category_title', get_lang('Title'));
476
477
    $form->addElement(
478
        'html_editor',
479
        'forum_category_comment',
480
        get_lang('Comment'),
481
        null,
482
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
483
    );
484
485
    $form->addButtonUpdate(get_lang('ModifyCategory'), 'SubmitEditForumCategory');
486
487
    // Setting the default values.
488
    $defaultvalues['forum_category_id'] = $inputvalues['cat_id'];
489
    $defaultvalues['forum_category_title'] = $inputvalues['cat_title'];
490
    $defaultvalues['forum_category_comment'] = $inputvalues['cat_comment'];
491
    $form->setDefaults($defaultvalues);
492
493
    // Setting the rules.
494
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
495
496
    // Validation or display
497 View Code Duplication
    if ($form->validate()) {
498
        $check = Security::check_token('post');
499
        if ($check) {
500
            $values = $form->exportValues();
501
            store_forumcategory($values);
502
        }
503
        Security::clear_token();
504
    } else {
505
        $token = Security::get_token();
506
        $form->addElement('hidden', 'sec_token');
507
        $form->setConstants(array('sec_token' => $token));
508
        $form->display();
509
    }
510
}
511
512
/**
513
 * This function stores the forum category in the database.
514
 * The new category is added to the end.
515
 *
516
 * @param array $values
517
 * @param array $courseInfo
518
 * @param bool $showMessage
519
 * @return void HMTL language variable
520
 *
521
 * @author Patrick Cool <[email protected]>, Ghent University
522
 * @version february 2006, dokeos 1.8
523
 */
524
function store_forumcategory($values, $courseInfo = array(), $showMessage = true)
525
{
526
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
527
    $course_id = $courseInfo['real_id'];
528
    $table_categories = Database::get_course_table(TABLE_FORUM_CATEGORY);
529
530
    // Find the max cat_order. The new forum category is added at the end => max cat_order + &
531
    $sql = "SELECT MAX(cat_order) as sort_max
532
            FROM $table_categories
533
            WHERE c_id = $course_id";
534
    $result = Database::query($sql);
535
    $row = Database::fetch_array($result);
536
    $new_max = $row['sort_max'] + 1;
537
    $session_id = api_get_session_id();
538
    $clean_cat_title = $values['forum_category_title'];
539
    $last_id = null;
540
541
    if (isset($values['forum_category_id'])) {
542
        // Storing after edition.
543
        $params = [
544
            'cat_title' => $clean_cat_title,
545
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
546
        ];
547
548
        Database::update(
549
            $table_categories,
550
            $params,
551
            [
552
                'c_id = ? AND cat_id = ?' => [
553
                    $course_id,
554
                    $values['forum_category_id'],
555
                ],
556
            ]
557
        );
558
559
        api_item_property_update(
560
            $courseInfo,
561
            TOOL_FORUM_CATEGORY,
562
            $values['forum_category_id'],
563
            'ForumCategoryUpdated',
564
            api_get_user_id()
565
        );
566
        $return_message = get_lang('ForumCategoryEdited');
567
    } else {
568
        $params = [
569
            'c_id' => $course_id,
570
            'cat_title' => $clean_cat_title,
571
            'cat_comment' => isset($values['forum_category_comment']) ? $values['forum_category_comment'] : '',
572
            'cat_order' => $new_max,
573
            'session_id' => $session_id,
574
            'locked' => 0,
575
            'cat_id' => 0
576
        ];
577
        $last_id = Database::insert($table_categories, $params);
578
579
        if ($last_id > 0) {
580
            $sql = "UPDATE $table_categories SET cat_id = $last_id WHERE iid = $last_id";
581
            Database::query($sql);
582
583
            api_item_property_update(
584
                $courseInfo,
585
                TOOL_FORUM_CATEGORY,
586
                $last_id,
587
                'ForumCategoryAdded',
588
                api_get_user_id()
589
            );
590
            api_set_default_visibility(
591
                $last_id,
592
                TOOL_FORUM_CATEGORY,
593
                0,
594
                $courseInfo
595
            );
596
        }
597
        $return_message = get_lang('ForumCategoryAdded');
598
    }
599
600
    if ($showMessage) {
601
        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...
602
    }
603
604
    return $last_id;
605
}
606
607
/**
608
 * This function stores the forum in the database. The new forum is added to the end.
609
 *
610
 * @param array $values
611
 * @param array $courseInfo
612
 * @param bool  $returnId
613
 * @return string language variable
614
 *
615
 * @author Patrick Cool <[email protected]>, Ghent University
616
 * @version february 2006, dokeos 1.8
617
 */
618
function store_forum($values, $courseInfo = array(), $returnId = false)
619
{
620
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
621
    $course_id = $courseInfo['real_id'];
622
    $session_id = api_get_session_id();
623
624
    if (isset($values['group_id']) && !empty($values['group_id'])) {
625
        $group_id = $values['group_id'];
626
    } else {
627
        $group_id = api_get_group_id();
628
    }
629
630
    $table_forums = Database::get_course_table(TABLE_FORUM);
631
632
    // Find the max forum_order for the given category. The new forum is added at the end => max cat_order + &
633
    if (is_null($values['forum_category'])) {
634
        $new_max = null;
635
    } else {
636
        $sql = "SELECT MAX(forum_order) as sort_max
637
                FROM $table_forums
638
                WHERE
639
                    c_id = $course_id AND
640
                    forum_category='".Database::escape_string($values['forum_category'])."'";
641
        $result = Database::query($sql);
642
        $row = Database::fetch_array($result);
643
        $new_max = $row['sort_max'] + 1;
644
    }
645
646
    // Forum images
647
    $image_moved = false;
648
    $has_attachment = false;
649
    if (!empty($_FILES['picture']['name'])) {
650
        $upload_ok = process_uploaded_file($_FILES['picture']);
651
        $has_attachment = true;
652
    } else {
653
        $image_moved = true;
654
    }
655
656
    // Remove existing picture if it was requested.
657
    if (!empty($_POST['remove_picture'])) {
658
        delete_forum_image($values['forum_id']);
659
    }
660
661
    $new_file_name = '';
662
    if (isset($upload_ok)) {
663
        if ($has_attachment) {
664
            $course_dir = $courseInfo['path'].'/upload/forum/images';
665
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
666
            $updir = $sys_course_path.$course_dir;
667
            // Try to add an extension to the file if it hasn't one.
668
            $new_file_name = add_ext_on_mime(
669
                Database::escape_string($_FILES['picture']['name']),
670
                $_FILES['picture']['type']
671
            );
672
            if (!filter_extension($new_file_name)) {
673
                //Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
674
                $image_moved = false;
675
            } else {
676
                $file_extension = explode('.', $_FILES['picture']['name']);
677
                $file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
678
                $new_file_name = uniqid('').'.'.$file_extension;
679
                $new_path = $updir.'/'.$new_file_name;
680
                $result = @move_uploaded_file($_FILES['picture']['tmp_name'], $new_path);
681
                // Storing the attachments if any
682
                if ($result) {
683
                    $image_moved = true;
684
                }
685
            }
686
        }
687
    }
688
689
    if (isset($values['forum_id'])) {
690
        // Storing after edition.
691
        $params = [
692
            'forum_title'=> $values['forum_title'],
693
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
694
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
695
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
696
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
697
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
698
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
699
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
700
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
701
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
702
            'forum_group_public_private'=> isset($values['public_private_group_forum_group']['public_private_group_forum']) ? $values['public_private_group_forum_group']['public_private_group_forum'] : null,
703
            'moderated'=> $values['moderated']['moderated'],
704
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
705
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
706
            'session_id'=> $session_id,
707
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0
708
        ];
709
710
        if (isset($upload_ok)) {
711
            if ($has_attachment) {
712
                $params['forum_image'] = $new_file_name;
713
            }
714
        }
715
716
        if (isset($values['remove_picture']) && $values['remove_picture'] == 1) {
717
            $params['forum_image'] = '';
718
            delete_forum_image($values['forum_id']);
719
        }
720
721
        Database::update(
722
            $table_forums,
723
            $params,
724
            ['c_id = ? AND forum_id = ?' => [$course_id, $values['forum_id']]]
725
        );
726
727
        api_item_property_update(
728
            $courseInfo,
729
            TOOL_FORUM,
730
            Database::escape_string($values['forum_id']),
731
            'ForumUpdated',
732
            api_get_user_id(),
733
            $group_id
734
        );
735
736
        $return_message = get_lang('ForumEdited');
737
    } else {
738
        if ($image_moved) {
739
            $new_file_name = isset($new_file_name) ? $new_file_name : '';
740
        }
741
        $params = [
742
            'c_id' => $course_id,
743
            'forum_title'=> $values['forum_title'],
744
            'forum_image'=> $new_file_name,
745
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
746
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
747
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
748
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
749
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
750
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
751
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
752
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
753
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
754
            'forum_group_public_private'=> isset($values['public_private_group_forum_group']['public_private_group_forum']) ? $values['public_private_group_forum_group']['public_private_group_forum'] : null,
755
            'moderated'=> isset($values['moderated']['moderated']) ? (int) $values['moderated']['moderated'] : 0,
756
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
757
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
758
            'forum_order'=> isset($new_max) ? $new_max : null,
759
            'session_id'=> $session_id,
760
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0,
761
            'locked' => 0,
762
            'forum_id' => 0
763
        ];
764
765
        $last_id = Database::insert($table_forums, $params);
766 View Code Duplication
        if ($last_id > 0) {
767
            $sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $last_id";
768
            Database::query($sql);
769
770
            api_item_property_update(
771
                $courseInfo,
772
                TOOL_FORUM,
773
                $last_id,
774
                'ForumAdded',
775
                api_get_user_id(),
776
                $group_id
777
            );
778
779
            api_set_default_visibility(
780
                $last_id,
781
                TOOL_FORUM,
782
                $group_id,
783
                $courseInfo
784
            );
785
        }
786
        $return_message = get_lang('ForumAdded');
787
        if ($returnId) {
788
            return $last_id;
789
        }
790
    }
791
792
    return $return_message;
793
}
794
795
/**
796
 * This function deletes a forum or a forum category
797
 * This function currently does not delete the forums inside the category,
798
 * nor the threads and replies inside these forums.
799
 * For the moment this is the easiest method and it has the advantage that it
800
 * allows to recover fora that were acidently deleted
801
 * when the forum category got deleted.
802
 *
803
 * @param $content = what we are deleting (a forum or a forum category)
804
 * @param $id The id of the forum category that has to be deleted.
805
 *
806
 * @todo write the code for the cascading deletion of the forums inside a
807
 * forum category and also the threads and replies inside these forums
808
 * @todo config setting for recovery or not
809
 * (see also the documents tool: real delete or not).
810
 * @return string
811
 * @author Patrick Cool <[email protected]>, Ghent University
812
 * @version february 2006, dokeos 1.8
813
 */
814
function deleteForumCategoryThread($content, $id)
815
{
816
    $_course = api_get_course_info();
817
    $table_forums = Database::get_course_table(TABLE_FORUM);
818
    $table_forums_post = Database::get_course_table(TABLE_FORUM_POST);
819
    $table_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
820
    $course_id = api_get_course_int_id();
821
    $groupId = api_get_group_id();
822
    $userId = api_get_user_id();
823
    $id = intval($id);
824
825
    // Delete all attachment file about this tread id.
826
    $sql = "SELECT post_id FROM $table_forums_post
827
            WHERE c_id = $course_id AND thread_id = '".$id."' ";
828
    $res = Database::query($sql);
829
    while ($poster_id = Database::fetch_row($res)) {
830
        delete_attachment($poster_id[0]);
831
    }
832
833
    $tool_constant = null;
834
    $return_message = '';
835
836 View Code Duplication
    if ($content == 'forumcategory') {
837
        $tool_constant = TOOL_FORUM_CATEGORY;
838
        $return_message = get_lang('ForumCategoryDeleted');
839
840
        if (!empty($forum_list)) {
0 ignored issues
show
Bug introduced by
The variable $forum_list seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

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

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

Loading history...
841
            $sql = "SELECT forum_id FROM $table_forums
842
                    WHERE c_id = $course_id AND forum_category='".$id."'";
843
            $result = Database::query($sql);
844
            $row = Database::fetch_array($result);
845
            foreach ($row as $arr_forum) {
846
                $forum_id = $arr_forum['forum_id'];
847
                api_item_property_update(
848
                    $_course,
849
                    'forum',
850
                    $forum_id,
851
                    'delete',
852
                    api_get_user_id()
853
                );
854
            }
855
        }
856
    }
857
858 View Code Duplication
    if ($content == 'forum') {
859
        $tool_constant = TOOL_FORUM;
860
        $return_message = get_lang('ForumDeleted');
861
862
        if (!empty($number_threads)) {
0 ignored issues
show
Bug introduced by
The variable $number_threads seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

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

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

Loading history...
863
            $sql = "SELECT thread_id FROM $table_forum_thread
864
                    WHERE c_id = $course_id AND forum_id = $id ";
865
            $result = Database::query($sql);
866
            $row = Database::fetch_array($result);
867
            foreach ($row as $arr_forum) {
868
                $forum_id = $arr_forum['thread_id'];
869
                api_item_property_update(
870
                    $_course,
871
                    'forum_thread',
872
                    $forum_id,
873
                    'delete',
874
                    api_get_user_id()
875
                );
876
            }
877
        }
878
    }
879
880
    if ($content == 'thread') {
881
        $tool_constant = TOOL_FORUM_THREAD;
882
        $return_message = get_lang('ThreadDeleted');
883
    }
884
885
    api_item_property_update(
886
        $_course,
887
        $tool_constant,
888
        $id,
889
        'delete',
890
        $userId,
891
        $groupId
892
    );
893
894
    // Check if this returns a true and if so => return $return_message, if not => return false;
895
    return $return_message;
896
}
897
898
/**
899
 * This function deletes a forum post. This separate function is needed because forum posts do not appear in the item_property table (yet)
900
 * and because deleting a post also has consequence on the posts that have this post as parent_id (they are also deleted).
901
 * an alternative would be to store the posts also in item_property and mark this post as deleted (visibility = 2).
902
 * We also have to decrease the number of replies in the thread table
903
 *
904
 * @param $post_id the id of the post that will be deleted
905
 * @todo write recursive function that deletes all the posts that have this message as parent
906
 * @return string language variable
907
 * @author Patrick Cool <[email protected]>, Ghent University
908
 * @author Hubert Borderiou Function cleanead and fixed
909
 * @version february 2006
910
 */
911
function delete_post($post_id)
912
{
913
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
914
    $post_id = intval($post_id);
915
    $course_id = api_get_course_int_id();
916
    $em = Database::getManager();
917
918
    $post = $em
919
        ->getRepository('ChamiloCourseBundle:CForumPost')
920
        ->findOneBy(['cId' => $course_id, 'postId' => $post_id]);
921
922
    if ($post) {
923
        $em
924
            ->createQuery('
925
                UPDATE ChamiloCourseBundle:CForumPost p
926
                SET p.postParentId = :parent_of_deleted_post
927
                WHERE
928
                    p.cId = :course AND
929
                    p.postParentId = :post AND
930
                    p.threadId = :thread_of_deleted_post AND
931
                    p.forumId = :forum_of_deleted_post
932
            ')
933
            ->execute([
934
                'parent_of_deleted_post' => $post->getPostParentId(),
935
                'course' => $course_id,
936
                'post' => $post->getPostId(),
937
                'thread_of_deleted_post' => $post->getThreadId(),
938
                'forum_of_deleted_post' => $post->getForumId()
939
            ]);
940
941
        $em->remove($post);
942
        $em->flush();
943
944
        // Delete attachment file about this post id.
945
        delete_attachment($post_id);
946
    }
947
948
    $last_post_of_thread = check_if_last_post_of_thread($_GET['thread']);
949
950
    if (is_array($last_post_of_thread)) {
951
        // Decreasing the number of replies for this thread and also changing the last post information.
952
        $sql = "UPDATE $table_threads
953
                SET
954
                    thread_replies = thread_replies - 1,
955
                    thread_last_post = ".intval($last_post_of_thread['post_id']).",
956
                    thread_date='".Database::escape_string($last_post_of_thread['post_date'])."'
957
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
958
        Database::query($sql);
959
960
        return 'PostDeleted';
961
    }
962
    if (!$last_post_of_thread) {
963
        // We deleted the very single post of the thread so we need to delete the entry in the thread table also.
964
        $sql = "DELETE FROM $table_threads
965
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
966
        Database::query($sql);
967
968
        return 'PostDeletedSpecial';
969
    }
970
}
971
972
/**
973
 * This function gets the all information of the last (=most recent) post of the thread
974
 * This can be done by sorting the posts that have the field thread_id=$thread_id and sort them by post_date
975
 *
976
 * @param $thread_id the id of the thread we want to know the last post of.
977
 * @return an array or bool if there is a last post found, false if there is
978
 * no post entry linked to that thread => thread will be deleted
979
 *
980
 * @author Patrick Cool <[email protected]>, Ghent University
981
 * @version february 2006, dokeos 1.8
982
 */
983 View Code Duplication
function check_if_last_post_of_thread($thread_id)
984
{
985
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
986
    $course_id = api_get_course_int_id();
987
    $sql = "SELECT * FROM $table_posts
988
            WHERE c_id = $course_id AND thread_id = ".intval($thread_id)."
989
            ORDER BY post_date DESC";
990
    $result = Database::query($sql);
991
    if (Database::num_rows($result) > 0) {
992
        $row = Database::fetch_array($result);
993
994
        return $row;
995
    } else {
996
        return false;
997
    }
998
}
999
1000
/**
1001
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1002
 * @param $id the id of the content we want to make invisible
1003
 * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
1004
 * @param array $additional_url_parameters
1005
 *
1006
 * @return string HTML
1007
 */
1008
function return_visible_invisible_icon($content, $id, $current_visibility_status, $additional_url_parameters = '')
1009
{
1010
    $html = '';
1011
    $id = Security::remove_XSS($id);
1012 View Code Duplication
    if ($current_visibility_status == '1') {
1013
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1014
        if (is_array($additional_url_parameters)) {
1015
            foreach ($additional_url_parameters as $key => $value) {
1016
                $html .= $key . '=' . $value . '&';
1017
            }
1018
        }
1019
        $html.='action=invisible&content='.$content.'&id='.$id.'">'.
1020
            Display::return_icon('visible.png', get_lang('MakeInvisible'), array(), ICON_SIZE_SMALL).'</a>';
1021
    }
1022 View Code Duplication
    if ($current_visibility_status == '0') {
1023
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1024
        if (is_array($additional_url_parameters)) {
1025
            foreach ($additional_url_parameters as $key => $value) {
1026
                $html .= $key . '=' . $value . '&';
1027
            }
1028
        }
1029
        $html .= 'action=visible&content=' . $content . '&id=' . $id . '">' .
1030
            Display::return_icon('invisible.png', get_lang('MakeVisible'), array(), ICON_SIZE_SMALL) . '</a>';
1031
    }
1032
    return $html;
1033
}
1034
1035
/**
1036
 * @param $content
1037
 * @param $id
1038
 * @param $current_lock_status
1039
 * @param string $additional_url_parameters
1040
 * @return string
1041
 */
1042
function return_lock_unlock_icon($content, $id, $current_lock_status, $additional_url_parameters = '')
1043
{
1044
    $html = '';
1045
    $id = intval($id);
1046
    //check if the forum is blocked due
1047
    if ($content == 'thread') {
1048
        if (api_resource_is_locked_by_gradebook($id, LINK_FORUM_THREAD)) {
1049
            $html .= Display::return_icon('lock_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
1050
1051
            return $html;
1052
        }
1053
    }
1054 View Code Duplication
    if ($current_lock_status == '1') {
1055
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1056
        if (is_array($additional_url_parameters)) {
1057
            foreach ($additional_url_parameters as $key => $value) {
1058
                $html .= $key . '=' . $value . '&';
1059
            }
1060
        }
1061
        $html.= 'action=unlock&content='.$content.'&id='.$id.'">'.
1062
            Display::return_icon('lock.png', get_lang('Unlock'), array(), ICON_SIZE_SMALL).'</a>';
1063
    }
1064 View Code Duplication
    if ($current_lock_status == '0') {
1065
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1066
        if (is_array($additional_url_parameters)) {
1067
            foreach ($additional_url_parameters as $key => $value) {
1068
                $html .= $key . '=' . $value . '&';
1069
            }
1070
        }
1071
        $html .= 'action=lock&content=' . $content . '&id=' . $id . '">' .
1072
            Display::return_icon('unlock.png', get_lang('Lock'), array(), ICON_SIZE_SMALL) . '</a>';
1073
    }
1074
1075
    return $html;
1076
}
1077
1078
/**
1079
 * This function takes care of the display of the up and down icon
1080
 *
1081
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1082
 * @param $id is the id of the item we want to display the icons for
1083
 * @param $list is an array of all the items. All items in this list should have
1084
 * an up and down icon except for the first (no up icon) and the last (no down icon)
1085
 *          The key of this $list array is the id of the item.
1086
 *
1087
 * @return string HTML
1088
 **/
1089
function return_up_down_icon($content, $id, $list)
1090
{
1091
    $id = strval(intval($id));
1092
    $total_items = count($list);
1093
    $position = 0;
1094
    $internal_counter = 0;
1095
    $forumCategory = isset($_GET['forumcategory']) ? Security::remove_XSS($_GET['forumcategory']) : null;
1096
1097
    if (is_array($list)) {
1098
        foreach ($list as $key => $listitem) {
1099
            $internal_counter++;
1100
            if ($id == $key) {
1101
                $position = $internal_counter;
1102
            }
1103
        }
1104
    }
1105
1106
    if ($position > 1) {
1107
        $return_value = '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=up&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveUp').'">'.
1108
            Display::return_icon('up.png', get_lang('MoveUp'), array(), ICON_SIZE_SMALL).'</a>';
1109
    } else {
1110
        $return_value = Display::return_icon('up_na.png', '-', array(), ICON_SIZE_SMALL);
1111
    }
1112
1113
    if ($position < $total_items) {
1114
        $return_value .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=down&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveDown').'" >'.
1115
            Display::return_icon('down.png', get_lang('MoveDown'), array(), ICON_SIZE_SMALL).'</a>';
1116
    } else {
1117
        $return_value .= Display::return_icon('down_na.png', '-', array(), ICON_SIZE_SMALL);
1118
    }
1119
    return $return_value;
1120
}
1121
1122
/**
1123
 * This function changes the visibility in the database (item_property)
1124
 *
1125
 * @param string $content what is it that we want to make (in)visible: forum category, forum, thread, post
1126
 * @param int $id the id of the content we want to make invisible
1127
 * @param string $target_visibility what is the current status of the visibility (0 = invisible, 1 = visible)
1128
 *
1129
 * @todo change the get parameter so that it matches the tool constants.
1130
 * @todo check if api_item_property_update returns true or false => returnmessage depends on it.
1131
 * @todo move to itemmanager
1132
 *
1133
 * @return string language variable
1134
 *
1135
 * @author Patrick Cool <[email protected]>, Ghent University
1136
 * @version february 2006, dokeos 1.8
1137
 */
1138
function change_visibility($content, $id, $target_visibility)
1139
{
1140
    $_course = api_get_course_info();
1141
    $constants = array(
1142
        'forumcategory' => TOOL_FORUM_CATEGORY,
1143
        'forum' => TOOL_FORUM,
1144
        'thread' => TOOL_FORUM_THREAD,
1145
    );
1146
    api_item_property_update(
1147
        $_course,
1148
        $constants[$content],
1149
        $id,
1150
        $target_visibility,
1151
        api_get_user_id()
1152
    );
1153
1154
    if ($target_visibility == 'visible') {
1155
        handle_mail_cue($content, $id);
1156
    }
1157
    return get_lang('VisibilityChanged');
1158
}
1159
1160
/**
1161
 * This function changes the lock status in the database
1162
 *
1163
 * @param string $content what is it that we want to (un)lock: forum category, forum, thread, post
1164
 * @param int $id the id of the content we want to (un)lock
1165
 * @param string $action do we lock (=>locked value in db = 1) or unlock (=> locked value in db = 0)
1166
 * @return string language variable
1167
 *
1168
 * @todo move to item manager
1169
 *
1170
 * @author Patrick Cool <[email protected]>, Ghent University
1171
 * @version february 2006, dokeos 1.8
1172
 */
1173
function change_lock_status($content, $id, $action)
1174
{
1175
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1176
    $table_forums = Database :: get_course_table(TABLE_FORUM);
1177
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1178
1179
    // Determine the relevant table.
1180
    if ($content == 'forumcategory') {
1181
        $table = $table_categories;
1182
        $id_field = 'cat_id';
1183
    } elseif ($content == 'forum') {
1184
        $table = $table_forums;
1185
        $id_field = 'forum_id';
1186
    } elseif ($content == 'thread') {
1187
        $table = $table_threads;
1188
        $id_field = 'thread_id';
1189
    } else {
1190
        return get_lang('Error');
1191
    }
1192
1193
    // Determine what we are doing => defines the value for the database and the return message.
1194
    if ($action == 'lock') {
1195
        $db_locked = 1;
1196
        $return_message = get_lang('Locked');
1197
    } elseif ($action == 'unlock') {
1198
        $db_locked = 0;
1199
        $return_message = get_lang('Unlocked');
1200
    } else {
1201
        return get_lang('Error');
1202
    }
1203
1204
    $course_id = api_get_course_int_id();
1205
1206
    // Doing the change in the database
1207
    $sql = "UPDATE $table SET locked='".Database::escape_string($db_locked)."'
1208
            WHERE c_id = $course_id AND $id_field='".Database::escape_string($id)."'";
1209
    if (Database::query($sql)) {
1210
        return $return_message;
1211
    } else {
1212
        return get_lang('Error');
1213
    }
1214
}
1215
1216
/**
1217
 * This function moves a forum or a forum category up or down
1218
 *
1219
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1220
 * @param $direction do we want to move it up or down.
1221
 * @param $id the id of the content we want to make invisible
1222
 * @todo consider removing the table_item_property calls here but this can
1223
 * prevent unwanted side effects when a forum does not have an entry in
1224
 * the item_property table but does have one in the forum table.
1225
 * @return string language variable
1226
 *
1227
 * @author Patrick Cool <[email protected]>, Ghent University
1228
 * @version february 2006, dokeos 1.8
1229
 */
1230
function move_up_down($content, $direction, $id)
1231
{
1232
    $table_categories = Database:: get_course_table(TABLE_FORUM_CATEGORY);
1233
    $table_forums = Database:: get_course_table(TABLE_FORUM);
1234
    $table_item_property = Database:: get_course_table(TABLE_ITEM_PROPERTY);
1235
    $course_id = api_get_course_int_id();
1236
    $id = intval($id);
1237
1238
    // Determine which field holds the sort order.
1239
    if ($content == 'forumcategory') {
1240
        $table = $table_categories;
1241
        $sort_column = 'cat_order';
1242
        $id_column = 'cat_id';
1243
        $sort_column = 'cat_order';
1244
    } elseif ($content == 'forum') {
1245
        $table = $table_forums;
1246
        $sort_column = 'forum_order';
1247
        $id_column = 'forum_id';
1248
        $sort_column = 'forum_order';
1249
        // We also need the forum_category of this forum.
1250
        $sql = "SELECT forum_category FROM $table_forums
1251
                WHERE c_id = $course_id AND forum_id = " . intval($id);
1252
        $result = Database::query($sql);
1253
        $row = Database::fetch_array($result);
1254
        $forum_category = $row['forum_category'];
1255
    } else {
1256
        return get_lang('Error');
1257
    }
1258
1259
    // Determine the need for sorting ascending or descending order.
1260
    if ($direction == 'down') {
1261
        $sort_direction = 'ASC';
1262
    } elseif ($direction == 'up') {
1263
        $sort_direction = 'DESC';
1264
    } else {
1265
        return get_lang('Error');
1266
    }
1267
1268
    // The SQL statement
1269
    if ($content == 'forumcategory') {
1270
        $sql = "SELECT *
1271
                FROM $table_categories forum_categories, $table_item_property item_properties
1272
                WHERE
1273
                    forum_categories.c_id = $course_id AND
1274
                    item_properties.c_id = $course_id AND
1275
                    forum_categories.cat_id=item_properties.ref AND
1276
                    item_properties.tool='" . TOOL_FORUM_CATEGORY . "'
1277
                ORDER BY forum_categories.cat_order $sort_direction";
1278
    }
1279
    if ($content == 'forum') {
1280
        $sql = "SELECT *
1281
            FROM $table
1282
            WHERE
1283
                c_id = $course_id AND
1284
                forum_category='" . Database::escape_string($forum_category) . "'
1285
            ORDER BY forum_order $sort_direction";
1286
    }
1287
    // Finding the items that need to be switched.
1288
    $result = Database::query($sql);
1289
    $found = false;
1290
    while ($row = Database::fetch_array($result)) {
1291
        //echo $row[$id_column].'-';
1292
        if ($found) {
1293
            $next_id = $row[$id_column];
1294
            $next_sort = $row[$sort_column];
1295
            $found = false;
1296
        }
1297
        if ($id == $row[$id_column]) {
1298
            $this_id = $id;
1299
            $this_sort = $row[$sort_column];
1300
            $found = true;
1301
        }
1302
    }
1303
1304
    // Committing the switch.
1305
    // We do an extra check if we do not have illegal values. If your remove this if statment you will
1306
    // be able to mess with the sorting by refreshing the page over and over again.
1307
    if ($this_sort != '' && $next_sort != '' && $next_id != '' && $this_id != '') {
1308
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($this_sort) . "'
1309
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($next_id) . "'";
1310
        Database::query($sql);
1311
1312
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($next_sort) . "'
1313
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($this_id) . "'";
1314
        Database::query($sql);
1315
    }
1316
1317
    return get_lang(ucfirst($content) . 'Moved');
1318
}
1319
1320
/**
1321
 * Retrieve all the information off the forum categories (or one specific) for the current course.
1322
 * The categories are sorted according to their sorting order (cat_order
1323
 *
1324
 * @param int|string $id default ''. When an id is passed we only find the information
1325
 * about that specific forum category. If no id is passed we get all the forum categories.
1326
 * @param int $courseId Optional. The course ID
1327
 * @param int $sessionId Optional. The session ID
1328
 * @return array containing all the information about all the forum categories
1329
 *
1330
 * @author Patrick Cool <[email protected]>, Ghent University
1331
 * @version february 2006, dokeos 1.8
1332
 */
1333
function get_forum_categories($id = '', $courseId = 0, $sessionId = 0)
1334
{
1335
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1336
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1337
1338
    // Condition for the session
1339
    $session_id = $sessionId ?: api_get_session_id();
1340
    $course_id = $courseId ?: api_get_course_int_id();
1341
1342
    $condition_session = api_get_session_condition($session_id, true, true, 'forum_categories.session_id');
1343
    $condition_session .= " AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id";
1344
1345
    if (empty($id)) {
1346
        $sql = "SELECT *
1347
                FROM $table_item_property item_properties 
1348
                INNER JOIN $table_categories forum_categories
1349
                ON (
1350
                    forum_categories.cat_id = item_properties.ref AND 
1351
                    item_properties.c_id = forum_categories.c_id
1352
                )
1353
                WHERE                    
1354
                    item_properties.visibility = 1 AND
1355
                    item_properties.tool = '".TOOL_FORUM_CATEGORY."'
1356
                    $condition_session
1357
                ORDER BY forum_categories.cat_order ASC";
1358
        if (api_is_allowed_to_edit()) {
1359
            $sql = "SELECT *
1360
                    FROM $table_item_property item_properties  
1361
                    INNER JOIN $table_categories forum_categories
1362
                    ON (
1363
                        forum_categories.cat_id = item_properties.ref AND 
1364
                        item_properties.c_id = forum_categories.c_id
1365
                    )
1366
                    WHERE                        
1367
                        item_properties.visibility<>2 AND
1368
                        item_properties.tool='".TOOL_FORUM_CATEGORY."'
1369
                        $condition_session
1370
                    ORDER BY forum_categories.cat_order ASC";
1371
        }
1372
    } else {
1373
        $sql = "SELECT *
1374
                FROM $table_item_property item_properties 
1375
                INNER JOIN $table_categories forum_categories
1376
                ON (
1377
                    forum_categories.cat_id = item_properties.ref AND 
1378
                    item_properties.c_id = forum_categories.c_id
1379
                )
1380
                WHERE                    
1381
                    item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
1382
                    forum_categories.cat_id = ".intval($id)."
1383
                    $condition_session
1384
                ORDER BY forum_categories.cat_order ASC";
1385
    }
1386
    $result = Database::query($sql);
1387
    $forum_categories_list = array();
1388
    while ($row = Database::fetch_assoc($result)) {
1389
        if (empty($id)) {
1390
            $forum_categories_list[$row['cat_id']] = $row;
1391
        } else {
1392
            $forum_categories_list = $row;
1393
        }
1394
    }
1395
1396
    return $forum_categories_list;
1397
}
1398
1399
/**
1400
 * This function retrieves all the fora in a given forum category
1401
 *
1402
 * @param int $cat_id the id of the forum category
1403
 * @param int $courseId Optional. The course ID
1404
 * @return array containing all the information about the forums (regardless of their category)
1405
 *
1406
 * @author Patrick Cool <[email protected]>, Ghent University
1407
 * @version february 2006, dokeos 1.8
1408
 */
1409
function get_forums_in_category($cat_id, $courseId = 0)
1410
{
1411
    $table_forums = Database::get_course_table(TABLE_FORUM);
1412
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1413
1414
    $forum_list = array();
1415
    $course_id = $courseId ?: api_get_course_int_id();
1416
    $cat_id = (int) $cat_id;
1417
1418
    $sql = "SELECT * FROM $table_forums forum 
1419
            INNER JOIN $table_item_property item_properties
1420
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1421
            WHERE
1422
                forum.forum_category = '".$cat_id."' AND                
1423
                item_properties.visibility = 1 AND
1424
                forum.c_id = $course_id AND
1425
                item_properties.c_id = $course_id AND
1426
                item_properties.tool = '".TOOL_FORUM."'                 
1427
            ORDER BY forum.forum_order ASC";
1428
    if (api_is_allowed_to_edit()) {
1429
        $sql = "SELECT * FROM $table_forums forum  
1430
                INNER JOIN $table_item_property item_properties
1431
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1432
                WHERE
1433
                    forum.forum_category = '".$cat_id."' AND                    
1434
                    item_properties.visibility <> 2 AND
1435
                    item_properties.tool = '".TOOL_FORUM."' AND
1436
                    item_properties.c_id = $course_id AND
1437
                    forum.c_id = $course_id
1438
                ORDER BY forum_order ASC";
1439
    }
1440
    $result = Database::query($sql);
1441
    while ($row = Database::fetch_array($result)) {
1442
        $forum_list[$row['forum_id']] = $row;
1443
    }
1444
1445
    return $forum_list;
1446
}
1447
1448
/**
1449
 * Retrieve all the forums (regardless of their category) or of only one.
1450
 * The forums are sorted according to the forum_order.
1451
 * Since it does not take the forum category into account there probably
1452
 * will be two or more forums that have forum_order=1, ...
1453
 * @param int $id forum id
1454
 * @param string $course_code
1455
 * @param bool $includeGroupsForum
1456
 * @param int $sessionId
1457
 * @return array an array containing all the information about the forums (regardless of their category)
1458
 * @todo check $sql4 because this one really looks fishy.
1459
 *
1460
 * @author Patrick Cool <[email protected]>, Ghent University
1461
 * @version february 2006, dokeos 1.8
1462
 */
1463
function get_forums(
1464
    $id = '',
1465
    $course_code = '',
1466
    $includeGroupsForum = true,
1467
    $sessionId = 0
1468
) {
1469
    $course_info = api_get_course_info($course_code);
1470
1471
    $table_forums = Database::get_course_table(TABLE_FORUM);
1472
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1473
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1474
1475
    // Condition for the session
1476
    $session_id = intval($sessionId) ?: api_get_session_id();
1477
    $sessionIdLink = $session_id === 0 ? '' : ' AND threads.session_id = item_properties.session_id';
1478
1479
    $condition_session = api_get_session_condition(
1480
        $session_id,
1481
        true,
1482
        false,
1483
        'item_properties.session_id'
1484
    );
1485
1486
    $course_id = $course_info['real_id'];
1487
1488
    $forum_list = array();
1489
    $includeGroupsForumSelect = '';
1490
    if (!$includeGroupsForum) {
1491
        $includeGroupsForumSelect = " AND forum_of_group = 0 ";
1492
    }
1493
1494
    if ($id == '') {
1495
        // Student
1496
        // Select all the forum information of all forums (that are visible to students).
1497
        $sql = "SELECT item_properties.*, forum.* 
1498
                FROM $table_forums forum
1499
                INNER JOIN $table_item_property item_properties
1500
                ON (
1501
                    forum.forum_id = item_properties.ref AND
1502
                    forum.c_id = item_properties.c_id
1503
                )
1504
                WHERE
1505
                    item_properties.visibility = 1 AND
1506
                    item_properties.tool = '".TOOL_FORUM."'
1507
                    $condition_session AND
1508
                    forum.c_id = $course_id AND
1509
                    item_properties.c_id = $course_id
1510
                    $includeGroupsForumSelect
1511
                ORDER BY forum.forum_order ASC";
1512
1513
        // Select the number of threads of the forums (only the threads that are visible).
1514
        $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1515
                FROM $table_threads threads
1516
                INNER JOIN $table_item_property item_properties
1517
                ON (
1518
                    threads.thread_id = item_properties.ref AND
1519
                    threads.c_id = item_properties.c_id
1520
                    $sessionIdLink
1521
                )
1522
                WHERE
1523
                    item_properties.visibility=1 AND
1524
                    item_properties.tool='".TOOL_FORUM_THREAD."' AND
1525
                    threads.c_id = $course_id AND
1526
                    item_properties.c_id = $course_id
1527
                GROUP BY threads.forum_id";
1528
1529
        // Course Admin
1530 View Code Duplication
        if (api_is_allowed_to_edit()) {
1531
            // Select all the forum information of all forums (that are not deleted).
1532
            $sql = "SELECT item_properties.*, forum.* 
1533
                    FROM $table_forums forum
1534
                    INNER JOIN $table_item_property item_properties
1535
                    ON (
1536
                        forum.forum_id = item_properties.ref AND
1537
                        forum.c_id = item_properties.c_id
1538
                    )
1539
                    WHERE
1540
                        item_properties.visibility <> 2 AND
1541
                        item_properties.tool = '".TOOL_FORUM."'
1542
                        $condition_session AND
1543
                        forum.c_id = $course_id AND
1544
                        item_properties.c_id = $course_id
1545
                        $includeGroupsForumSelect
1546
                    ORDER BY forum_order ASC";
1547
1548
            // Select the number of threads of the forums (only the threads that are not deleted).
1549
            $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1550
                    FROM $table_threads threads
1551
                    INNER JOIN $table_item_property item_properties
1552
                    ON (
1553
                        threads.thread_id = item_properties.ref AND
1554
                        threads.c_id = item_properties.c_id
1555
                        $sessionIdLink
1556
                    )
1557
                    WHERE
1558
                        item_properties.visibility<>2 AND
1559
                        item_properties.tool='".TOOL_FORUM_THREAD."' AND
1560
                        threads.c_id = $course_id AND
1561
                        item_properties.c_id = $course_id
1562
                    GROUP BY threads.forum_id";
1563
        }
1564
    } else {
1565
        // GETTING ONE SPECIFIC FORUM
1566
        /* We could do the splitup into student and course admin also but we want
1567
        to have as much as information about a certain forum as possible
1568
        so we do not take too much information into account. This function
1569
         (or this section of the function) is namely used to fill the forms
1570
        when editing a forum (and for the moment it is the only place where
1571
        we use this part of the function) */
1572
1573
        // Select all the forum information of the given forum (that is not deleted).
1574
        $sql = "SELECT * FROM $table_item_property item_properties 
1575
                INNER JOIN $table_forums forum
1576
                ON (forum.forum_id = item_properties.ref AND forum.c_id = item_properties.c_id)
1577
                WHERE
1578
                    forum.forum_id = " . intval($id) . " AND
1579
                    forum.c_id = $course_id AND
1580
                    item_properties.visibility != 2 AND
1581
                    item_properties.tool = '".TOOL_FORUM."'
1582
                ORDER BY forum_order ASC";
1583
1584
        // Select the number of threads of the forum.
1585
        $sql2 = "SELECT count(*) AS number_of_threads, forum_id
1586
                FROM $table_threads
1587
                WHERE
1588
                    forum_id = " . intval($id) . "
1589
                GROUP BY forum_id";
1590
    }
1591
1592
    // Handling all the forum information.
1593
    $result = Database::query($sql);
1594
    while ($row = Database::fetch_assoc($result)) {
1595
        if ($id == '') {
1596
            $forum_list[$row['forum_id']] = $row;
1597
        } else {
1598
            $forum_list = $row;
1599
        }
1600
    }
1601
1602
    // Handling the thread count information.
1603
    $result2 = Database::query($sql2);
1604
    while ($row2 = Database::fetch_array($result2)) {
1605
        if ($id == '') {
1606
            $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
1607
        } else {
1608
            $forum_list['number_of_threads'] = $row2['number_of_threads'];
1609
        }
1610
    }
1611
1612
    /* Finding the last post information
1613
    (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)*/
1614
    if ($id == '') {
1615
        if (is_array($forum_list)) {
1616 View Code Duplication
            foreach ($forum_list as $key => $value) {
1617
                $last_post_info_of_forum = get_last_post_information(
1618
                    $key,
1619
                    api_is_allowed_to_edit(),
1620
                    $course_id
1621
                );
1622
1623
                if ($last_post_info_of_forum) {
1624
                    $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1625
                    $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1626
                    $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1627
                    $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1628
                    $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1629
                    $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1630
                }
1631
            }
1632
        } else {
1633
            $forum_list = array();
1634
        }
1635
    } else {
1636
        $last_post_info_of_forum = get_last_post_information(
1637
            $id,
1638
            api_is_allowed_to_edit(),
1639
            $course_id
1640
        );
1641
        if ($last_post_info_of_forum) {
1642
            $forum_list['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1643
            $forum_list['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1644
            $forum_list['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1645
            $forum_list['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1646
            $forum_list['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1647
            $forum_list['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1648
        }
1649
    }
1650
1651
    return $forum_list;
1652
}
1653
1654
/**
1655
 * @param int $course_id
1656
 * @param int $thread_id
1657
 * @param int $forum_id
1658
 * @param bool $show_visible
1659
 * @return array|bool
1660
 */
1661
function get_last_post_by_thread($course_id, $thread_id, $forum_id, $show_visible = true)
1662
{
1663
    if (empty($thread_id) || empty($forum_id) || empty($course_id)) {
1664
        return false;
1665
    }
1666
1667
    $thread_id = intval($thread_id);
1668
    $forum_id = intval($forum_id);
1669
    $course_id = intval($course_id);
1670
1671
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1672
    $sql = "SELECT * FROM $table_posts
1673
            WHERE 
1674
                c_id = $course_id AND 
1675
                thread_id = $thread_id AND 
1676
                forum_id = $forum_id";
1677
1678
    if ($show_visible == false) {
1679
        $sql .= " AND visible = 1 ";
1680
    }
1681
1682
    $sql .= " ORDER BY post_id DESC LIMIT 1";
1683
    $result = Database::query($sql);
1684
    if (Database::num_rows($result)) {
1685
        return Database::fetch_array($result, 'ASSOC');
1686
    } else {
1687
        return false;
1688
    }
1689
}
1690
1691
/**
1692
 * This function gets all the last post information of a certain forum
1693
 *
1694
 * @param int   $forum_id the id of the forum we want to know the last post information of.
1695
 * @param bool  $show_invisibles
1696
 * @param string course db name
1697
 * @return array containing all the information about the last post
1698
 * (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)
1699
 *
1700
 * @author Patrick Cool <[email protected]>, Ghent University
1701
 * @version february 2006, dokeos 1.8
1702
 */
1703
function get_last_post_information($forum_id, $show_invisibles = false, $course_id = null)
1704
{
1705
    if (!isset($course_id)) {
1706
        $course_id = api_get_course_int_id();
1707
    } else {
1708
        $course_id = intval($course_id);
1709
    }
1710
    $sessionId = api_get_session_id();
1711
1712
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1713
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1714
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1715
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1716
1717
    $forum_id = intval($forum_id);
1718
    $return_array = array();
1719
1720
    // First get the threads to make sure there is no inconsistency in the
1721
    // database between forum and thread
1722
    $sql = "SELECT thread_id FROM $table_threads 
1723
            WHERE 
1724
                forum_id = $forum_id AND 
1725
                c_id = $course_id AND 
1726
                session_id = $sessionId";
1727
    $result = Database::query($sql);
1728
    if (Database::num_rows($result) == 0) {
1729
        // If there are no threads in this forum, then there are no posts
1730
        return [];
1731
    }
1732
    $threads = array();
1733
    while ($row = Database::fetch_row($result)) {
1734
        $threads[] = $row[0];
1735
    }
1736
    $threadsList = implode(',', $threads);
1737
    // Now get the posts that are linked to these threads
1738
    $sql = "SELECT
1739
                post.post_id,
1740
                post.forum_id,
1741
                post.poster_id,
1742
                post.poster_name,
1743
                post.post_date,
1744
                users.lastname,
1745
                users.firstname,
1746
                post.visible,
1747
                thread_properties.visibility AS thread_visibility,
1748
                forum_properties.visibility AS forum_visibility
1749
            FROM
1750
                $table_posts post,
1751
                $table_users users,
1752
                $table_item_property thread_properties,
1753
                $table_item_property forum_properties
1754
            WHERE
1755
                post.forum_id = $forum_id
1756
                AND post.thread_id IN ($threadsList)
1757
                AND post.poster_id = users.user_id
1758
                AND post.thread_id = thread_properties.ref
1759
                AND thread_properties.tool='".TOOL_FORUM_THREAD."'
1760
                AND post.forum_id=forum_properties.ref
1761
                AND forum_properties.tool='".TOOL_FORUM."'
1762
                AND post.c_id = $course_id AND
1763
                thread_properties.c_id = $course_id AND
1764
                forum_properties.c_id = $course_id
1765
            ORDER BY post.post_id DESC";
1766
    $result = Database::query($sql);
1767
1768
    if ($show_invisibles) {
1769
        $row = Database::fetch_array($result);
1770
        $return_array['last_post_id'] = $row['post_id'];
1771
        $return_array['last_poster_id'] = $row['poster_id'];
1772
        $return_array['last_post_date'] = $row['post_date'];
1773
        $return_array['last_poster_name'] = $row['poster_name'];
1774
        $return_array['last_poster_lastname'] = $row['lastname'];
1775
        $return_array['last_poster_firstname'] = $row['firstname'];
1776
1777
        return $return_array;
1778
    } else {
1779
        // We have to loop through the results to find the first one that is
1780
        // actually visible to students (forum_category, forum, thread AND post are visible).
1781
        while ($row = Database::fetch_array($result)) {
1782
            if ($row['visible'] == '1' && $row['thread_visibility'] == '1' && $row['forum_visibility'] == '1') {
1783
                $return_array['last_post_id'] = $row['post_id'];
1784
                $return_array['last_poster_id'] = $row['poster_id'];
1785
                $return_array['last_post_date'] = $row['post_date'];
1786
                $return_array['last_poster_name'] = $row['poster_name'];
1787
                $return_array['last_poster_lastname'] = $row['lastname'];
1788
                $return_array['last_poster_firstname'] = $row['firstname'];
1789
1790
                return $return_array;
1791
            }
1792
        }
1793
    }
1794
}
1795
1796
/**
1797
 * Retrieve all the threads of a given forum
1798
 *
1799
 * @param int $forum_id
1800
 * @param int|null $courseId Optional If is null then it is considered the current course
1801
 * @param int|null $sessionId Optional. If is null then it is considered the current session
1802
 * @return array containing all the information about the threads
1803
 *
1804
 * @author Patrick Cool <[email protected]>, Ghent University
1805
 * @version february 2006, dokeos 1.8
1806
 */
1807
function get_threads($forum_id, $courseId = null, $sessionId = null)
1808
{
1809
    $groupId = api_get_group_id();
1810
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
1811
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1812
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1813
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1814
1815
    $courseId = $courseId !== null ? intval($courseId) : api_get_course_int_id();
1816
    $groupInfo = GroupManager::get_group_properties($groupId);
1817
    $groupCondition = '';
1818
    if (!empty($groupInfo)) {
1819
        $groupIid = $groupInfo['iid'];
1820
        $groupCondition =  " AND item_properties.to_group_id = '$groupIid' ";
1821
    }
1822
1823
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'item_properties.session_id');
1824
1825
    // important note:  it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
1826
    // because we also have thread.* in it. This is because thread has a field locked and post also has the same field
1827
    // since we are merging these we would have the post.locked value but in fact we want the thread.locked value
1828
    // This is why it is added to the end of the field selection
1829
    $sql = "SELECT DISTINCT
1830
                item_properties.*,
1831
                users.firstname,
1832
                users.lastname,
1833
                users.user_id,
1834
                thread.locked as locked,
1835
                thread.*
1836
            FROM $table_threads thread
1837
            INNER JOIN $table_item_property item_properties
1838
            ON
1839
                thread.thread_id = item_properties.ref AND
1840
                item_properties.c_id = thread.c_id AND
1841
                item_properties.tool = '".TABLE_FORUM_THREAD."' 
1842
                $groupCondition
1843
                $sessionCondition
1844
            LEFT JOIN $table_users users
1845
                ON thread.thread_poster_id = users.user_id
1846
            WHERE
1847
                item_properties.visibility='1' AND
1848
                thread.forum_id = ".intval($forum_id)." AND
1849
                thread.c_id = $courseId 
1850
            ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1851
1852
    if (api_is_allowed_to_edit()) {
1853
        $sql = "SELECT DISTINCT
1854
                    item_properties.*,
1855
                    users.firstname,
1856
                    users.lastname,
1857
                    users.user_id,
1858
                    thread.locked as locked,
1859
                    thread.*
1860
                FROM $table_threads thread
1861
                INNER JOIN $table_item_property item_properties
1862
                ON
1863
                    thread.thread_id = item_properties.ref AND
1864
                    item_properties.c_id = thread.c_id AND
1865
                    item_properties.tool = '".TABLE_FORUM_THREAD."'
1866
                    $groupCondition
1867
                    $sessionCondition
1868
                LEFT JOIN $table_users users
1869
                    ON thread.thread_poster_id=users.user_id
1870
                WHERE
1871
                    item_properties.visibility<>2 AND
1872
                    thread.forum_id = ".intval($forum_id)." AND
1873
                    thread.c_id = $courseId 
1874
                ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1875
    }
1876
    $result = Database::query($sql);
1877
    $list = array();
1878
    $alreadyAdded = array();
1879 View Code Duplication
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1880
        if (in_array($row['thread_id'], $alreadyAdded)) {
1881
            continue;
1882
        }
1883
        $list[] = $row;
1884
        $alreadyAdded[] = $row['thread_id'];
1885
    }
1886
1887
    return $list;
1888
}
1889
1890
/**
1891
 * Get a thread by Id and course id
1892
 *
1893
 * @param int $threadId the thread Id
1894
 * @param int $cId the course id
1895
 * @return array containing all the information about the thread
1896
 */
1897
function getThreadInfo($threadId, $cId)
1898
{
1899
    $em = Database::getManager();
1900
    $forumThread = $em->getRepository('ChamiloCourseBundle:CForumThread')->findOneBy(['threadId' => $threadId, 'cId' => $cId]);
1901
1902
    $thread = [];
1903
1904
    if ($forumThread) {
1905
        $thread['threadId'] = $forumThread->getThreadId();
1906
        $thread['threadTitle'] = $forumThread->getThreadTitle();
1907
        $thread['forumId'] = $forumThread->getForumId();
1908
        $thread['sessionId'] = $forumThread->getSessionId();
1909
        $thread['threadSticky'] = $forumThread->getThreadSticky();
1910
        $thread['locked'] = $forumThread->getLocked();
1911
        $thread['threadTitleQualify'] = $forumThread->getThreadTitleQualify();
1912
        $thread['threadQualifyMax'] = $forumThread->getThreadQualifyMax();
1913
        $thread['threadCloseDate'] = $forumThread->getThreadCloseDate();
1914
        $thread['threadWeight'] = $forumThread->getThreadWeight();
1915
        $thread['threadPeerQualify'] = $forumThread->isThreadPeerQualify();
1916
    }
1917
1918
    return $thread;
1919
}
1920
1921
/**
1922
 * Retrieve all posts of a given thread
1923
 * @param array $forumInfo
1924
 * @param int $threadId The thread ID
1925
 * @param string $orderDirection Optional. The direction for sort the posts
1926
 * @param boolean $recursive Optional. If the list is recursive
1927
 * @param int $postId Optional. The post ID for recursive list
1928
 * @param int $depth Optional. The depth to indicate the indent
1929
 * @todo move to a repository
1930
 *
1931
 * @return array containing all the information about the posts of a given thread
1932
 */
1933
function getPosts(
1934
    $forumInfo,
1935
    $threadId,
1936
    $orderDirection = 'ASC',
1937
    $recursive = false,
1938
    $postId = null,
1939
    $depth = -1
1940
) {
1941
    $em = Database::getManager();
1942
1943
    if (api_is_allowed_to_edit(false, true)) {
1944
        $visibleCriteria = Criteria::expr()->neq('visible', 2);
1945
    } else {
1946
        $visibleCriteria = Criteria::expr()->eq('visible', 1);
1947
    }
1948
1949
    $criteria = Criteria::create();
1950
    $criteria
1951
        ->where(Criteria::expr()->eq('threadId', $threadId))
1952
        ->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
1953
        ->andWhere($visibleCriteria)
1954
    ;
1955
1956
    $groupId = api_get_group_id();
1957
    $groupInfo = GroupManager::get_group_properties($groupId);
1958
    $filterModerated = true;
1959
1960
    if (empty($groupId)) {
1961
        if (api_is_allowed_to_edit()) {
1962
            $filterModerated = false;
1963
        }
1964
    } else {
1965
        if (GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid']) || api_is_allowed_to_edit(false, true)) {
1966
            $filterModerated = false;
1967
        }
1968
    }
1969
1970
    if ($recursive) {
1971
        $criteria->andWhere(Criteria::expr()->eq('postParentId', $postId));
1972
    }
1973
1974
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
1975
    $qb->select('p')
1976
        ->addCriteria($criteria)
1977
        ->addOrderBy('p.postId', $orderDirection);
1978
1979
1980
    if ($filterModerated && $forumInfo['moderated'] == 1) {
1981
        if (!api_is_allowed_to_edit(false, true)) {
1982
            $userId = api_get_user_id();
1983
            $qb->andWhere(
1984
                "p.status = 1 OR 
1985
                    (p.status = ".CForumPost::STATUS_WAITING_MODERATION." AND p.posterId = $userId) OR
1986
                    (p.status IS NULL AND p.posterId = $userId) 
1987
                    "
1988
            );
1989
        }
1990
    }
1991
1992
    $posts = $qb->getQuery()->getResult();
1993
    $depth++;
1994
1995
    $list = [];
1996
    /** @var CForumPost $post */
1997
    foreach ($posts as $post) {
1998
        $postInfo = [
1999
            'iid' => $post->getIid(),
2000
            'c_id' => $post->getCId(),
2001
            'post_id' => $post->getPostId(),
2002
            'post_title' => $post->getPostTitle(),
2003
            'post_text' => $post->getPostText(),
2004
            'thread_id' => $post->getThreadId(),
2005
            'forum_id' => $post->getForumId(),
2006
            'poster_id' => $post->getPosterId(),
2007
            'poster_name' => $post->getPosterName(),
2008
            'post_date' => $post->getPostDate(),
2009
            'post_notification' => $post->getPostNotification(),
2010
            'post_parent_id' => $post->getPostParentId(),
2011
            'visible' => $post->getVisible(),
2012
            'status' => $post->getStatus(),
2013
            'indent_cnt' => $depth
2014
        ];
2015
2016
        $posterId = $post->getPosterId();
2017
        if (!empty($posterId)) {
2018
            $user = $em->find('ChamiloUserBundle:User', $posterId);
2019
2020
            if ($user) {
2021
                $postInfo['user_id'] = $user->getUserId();
2022
                $postInfo['username'] = $user->getUsername();
2023
                $postInfo['username_canonical'] = $user->getUsernameCanonical();
2024
                $postInfo['lastname'] = $user->getLastname();
2025
                $postInfo['firstname'] = $user->getFirstname();
2026
            }
2027
        }
2028
2029
        $list[] = $postInfo;
2030
2031
        if (!$recursive) {
2032
            continue;
2033
        }
2034
        $list = array_merge(
2035
            $list,
2036
            getPosts(
2037
                $forumInfo,
2038
                $threadId,
2039
                $orderDirection,
2040
                $recursive,
2041
                $post->getPostId(),
2042
                $depth
2043
            )
2044
        );
2045
    }
2046
2047
    return $list;
2048
}
2049
2050
/**
2051
 * This function retrieves all the information of a post
2052
 *
2053
 * @param int $post_id integer that indicates the forum
2054
 *
2055
 * @return array returns
2056
 *
2057
 * @author Patrick Cool <[email protected]>, Ghent University
2058
 * @version february 2006, dokeos 1.8
2059
 */
2060 View Code Duplication
function get_post_information($post_id)
2061
{
2062
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
2063
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
2064
    $course_id = api_get_course_int_id();
2065
2066
    $sql = "SELECT posts.*, email FROM ".$table_posts." posts, ".$table_users." users
2067
            WHERE
2068
                c_id = $course_id AND
2069
                posts.poster_id=users.user_id AND
2070
                posts.post_id = ".intval($post_id);
2071
    $result = Database::query($sql);
2072
    $row = Database::fetch_array($result, 'ASSOC');
2073
2074
    return $row;
2075
}
2076
2077
/**
2078
 * This function retrieves all the information of a thread
2079
 *
2080
 * @param int $forumId
2081
 * @param $thread_id integer that indicates the forum
2082
 * @param int|null $sessionId Optional. If is null then it is considered the current session
2083
 * @return array returns
2084
 *
2085
 * @author Patrick Cool <[email protected]>, Ghent University
2086
 * @version february 2006, dokeos 1.8
2087
 */
2088
function get_thread_information($forumId, $thread_id, $sessionId = null)
2089
{
2090
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2091
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
2092
    $thread_id = intval($thread_id);
2093
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
2094
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'threads.session_id');
2095
    $forumCondition = '';
2096
    if (!empty($forumId)) {
2097
        $forumId = (int) $forumId;
2098
        $forumCondition = " threads.forum_id = $forumId AND ";
2099
    }
2100
    $sql = "SELECT * FROM $table_item_property item_properties
2101
            INNER JOIN
2102
            $table_threads threads
2103
            ON (item_properties.ref = threads.thread_id AND threads.c_id = item_properties.c_id)
2104
            WHERE
2105
                $forumCondition
2106
                item_properties.tool= '".TOOL_FORUM_THREAD."' AND                
2107
                threads.thread_id = $thread_id 
2108
                $sessionCondition
2109
            ";
2110
2111
    $result = Database::query($sql);
2112
    $row = Database::fetch_assoc($result);
2113
2114
    return $row;
2115
}
2116
2117
/**
2118
 * This function retrieves forum thread users details
2119
 * @param   int Thread ID
2120
 * @param   string  Course DB name (optional)
2121
 * @return  Doctrine\DBAL\Driver\Statement|null array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2122
 * @author Christian Fasanando <[email protected]>,
2123
 * @todo     this function need to be improved
2124
 * @version octubre 2008, dokeos 1.8
2125
 */
2126
function get_thread_users_details($thread_id)
2127
{
2128
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2129
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2130
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2131
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2132
2133
    $course_id = api_get_course_int_id();
2134
2135
    $is_western_name_order = api_is_western_name_order();
2136
    if ($is_western_name_order) {
2137
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2138
    } else {
2139
        $orderby = 'ORDER BY user.lastname, user.firstname';
2140
    }
2141
2142 View Code Duplication
    if (api_get_session_id()) {
2143
        $session_info = api_get_session_info(api_get_session_id());
2144
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2145
        //not showing coaches
2146
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2147
                  FROM $t_posts p, $t_users user, $t_session_rel_user session_rel_user_rel_course
2148
                  WHERE p.poster_id = user.id AND
2149
                  user.id = session_rel_user_rel_course.user_id AND
2150
                  session_rel_user_rel_course.status<>'2' AND
2151
                  session_rel_user_rel_course.user_id NOT IN ($user_to_avoid) AND
2152
                  p.thread_id = ".intval($thread_id)." AND
2153
                  session_id = ".api_get_session_id()." AND
2154
                  p.c_id = $course_id AND
2155
                  session_rel_user_rel_course.c_id = ".$course_id." $orderby ";
2156
    } else {
2157
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2158
                  FROM $t_posts p, $t_users user, $t_course_user course_user
2159
                  WHERE p.poster_id = user.id
2160
                  AND user.id = course_user.user_id
2161
                  AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2162
                  AND p.thread_id = ".intval($thread_id)."
2163
                  AND course_user.status NOT IN('1') AND
2164
                  p.c_id = $course_id AND
2165
                  course_user.c_id = ".$course_id." $orderby";
2166
    }
2167
    $result = Database::query($sql);
2168
2169
    return $result;
2170
}
2171
2172
/**
2173
 * This function retrieves forum thread users qualify
2174
 * @param   int Thread ID
2175
 * @param   string  Course DB name (optional)
2176
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2177
 * @author Jhon Hinojosa
2178
 * @todo     this function need to be improved
2179
 */
2180
function get_thread_users_qualify($thread_id)
2181
{
2182
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2183
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2184
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2185
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2186
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2187
2188
    $course_id = api_get_course_int_id();
2189
2190
    $is_western_name_order = api_is_western_name_order();
2191
    if ($is_western_name_order) {
2192
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2193
    } else {
2194
        $orderby = 'ORDER BY user.lastname, user.firstname';
2195
    }
2196
2197
    if (api_get_session_id()) {
2198
        $session_info = api_get_session_info(api_get_session_id());
2199
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2200
        //not showing coaches
2201
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2202
                FROM $t_posts post , $t_users user, $t_session_rel_user scu, $t_qualify qualify
2203
                WHERE poster_id = user.id
2204
                    AND post.poster_id = qualify.user_id
2205
                    AND user.id = session_rel_user_rel_course.user_id
2206
                    AND scu.status<>'2'
2207
                    AND scu.user_id NOT IN ($user_to_avoid)
2208
                    AND qualify.thread_id = ".intval($thread_id)."
2209
                    AND post.thread_id = ".intval($thread_id)."
2210
                    AND session_id = ".api_get_session_id()."
2211
                    AND scu.c_id = ".$course_id." AND
2212
                    qualify.c_id = $course_id AND
2213
                    post.c_id = $course_id
2214
                $orderby ";
2215
    } else {
2216
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2217
                FROM $t_posts post,
2218
                     $t_qualify qualify,
2219
                     $t_users user,
2220
                     $t_course_user course_user
2221
                WHERE
2222
                     post.poster_id = user.id
2223
                     AND post.poster_id = qualify.user_id
2224
                     AND user.id = course_user.user_id
2225
                     AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2226
                     AND qualify.thread_id = ".intval($thread_id)."
2227
                     AND post.thread_id = ".intval($thread_id)."
2228
                     AND course_user.status not in('1')
2229
                     AND course_user.c_id = $course_id
2230
                     AND qualify.c_id = $course_id
2231
                     AND post.c_id = $course_id
2232
                 $orderby ";
2233
    }
2234
    $result = Database::query($sql);
2235
2236
    return $result;
2237
}
2238
2239
/**
2240
 * This function retrieves forum thread users not qualify
2241
 * @param   int Thread ID
2242
 * @param   string  Course DB name (optional)
2243
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2244
 * @author   Jhon Hinojosa<[email protected]>,
2245
 * @version oct 2008, dokeos 1.8
2246
 */
2247
function get_thread_users_not_qualify($thread_id)
2248
{
2249
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2250
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2251
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2252
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2253
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2254
2255
    $is_western_name_order = api_is_western_name_order();
2256
    if ($is_western_name_order) {
2257
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2258
    } else {
2259
        $orderby = 'ORDER BY user.lastname, user.firstname';
2260
    }
2261
2262
    $course_id = api_get_course_int_id();
2263
2264
    $sql1 = "SELECT user_id FROM  $t_qualify
2265
             WHERE c_id = $course_id AND thread_id = '".$thread_id."'";
2266
    $result1 = Database::query($sql1);
2267
    $cad = '';
2268
    while ($row = Database::fetch_array($result1)) {
2269
        $cad .= $row['user_id'].',';
2270
    }
2271
    if ($cad == '') {
2272
        $cad = '0';
2273
    } else {
2274
        $cad = substr($cad, 0, strlen($cad) - 1);
2275
    }
2276
2277 View Code Duplication
    if (api_get_session_id()) {
2278
        $session_info = api_get_session_info(api_get_session_id());
2279
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2280
        //not showing coaches
2281
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2282
                FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course
2283
                WHERE poster_id = user.id
2284
                    AND user.id NOT IN (".$cad.")
2285
                    AND user.id = session_rel_user_rel_course.user_id
2286
                    AND session_rel_user_rel_course.status<>'2'
2287
                    AND session_rel_user_rel_course.user_id NOT IN ($user_to_avoid)
2288
                    AND post.thread_id = ".intval($thread_id)."
2289
                    AND session_id = ".api_get_session_id()."
2290
                    AND session_rel_user_rel_course.c_id = $course_id AND post.c_id = $course_id $orderby ";
2291
    } else {
2292
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2293
                FROM $t_posts post, $t_users user,$t_course_user course_user
2294
                WHERE post.poster_id = user.id
2295
                AND user.id NOT IN (".$cad.")
2296
                AND user.id = course_user.user_id
2297
                AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2298
                AND post.thread_id = ".intval($thread_id)."
2299
                AND course_user.status not in('1')
2300
                AND course_user.c_id = $course_id AND post.c_id = $course_id  $orderby";
2301
    }
2302
    $result = Database::query($sql);
2303
2304
    return $result;
2305
}
2306
2307
/**
2308
 * This function retrieves all the information of a given forum_id
2309
 *
2310
 * @param $forum_id integer that indicates the forum
2311
 * @return array returns
2312
 *
2313
 * @author Patrick Cool <[email protected]>, Ghent University
2314
 * @version february 2006, dokeos 1.8
2315
 *
2316
 * @deprecated this functionality is now moved to get_forums($forum_id)
2317
 */
2318
function get_forum_information($forum_id, $courseId = 0)
2319
{
2320
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2321
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2322
    $courseId = empty($courseId) ? api_get_course_int_id(): intval($courseId);
2323
    $forum_id = intval($forum_id);
2324
2325
    $sql = "SELECT *
2326
            FROM $table_forums forums
2327
            INNER JOIN $table_item_property item_properties
2328
            ON (forums.c_id = item_properties.c_id)
2329
            WHERE
2330
                item_properties.tool = '".TOOL_FORUM."' AND
2331
                item_properties.ref = '".$forum_id."' AND
2332
                forums.forum_id = '".$forum_id."' AND
2333
                forums.c_id = ".$courseId."
2334
            ";
2335
2336
    $result = Database::query($sql);
2337
    $row = Database::fetch_array($result, 'ASSOC');
2338
    $row['approval_direct_post'] = 0;
2339
    // We can't anymore change this option, so it should always be activated.
2340
2341
    return $row;
2342
}
2343
2344
/**
2345
 * This function retrieves all the information of a given forumcategory id
2346
 *
2347
 * @param $cat_id integer that indicates the forum
2348
 *
2349
 * @return array returns if there are category or bool returns if there aren't category
2350
 * @author Patrick Cool <[email protected]>, Ghent University
2351
 * @version february 2006, dokeos 1.8
2352
 */
2353
function get_forumcategory_information($cat_id)
2354
{
2355
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
2356
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2357
2358
    $course_id = api_get_course_int_id();
2359
    $sql = "SELECT *
2360
            FROM ".$table_categories." forumcategories, ".$table_item_property." item_properties
2361
            WHERE
2362
                forumcategories.c_id = $course_id AND
2363
                item_properties.c_id = $course_id AND
2364
                item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
2365
                item_properties.ref='".Database::escape_string($cat_id)."' AND
2366
                forumcategories.cat_id='".Database::escape_string($cat_id)."'";
2367
    $result = Database::query($sql);
2368
    $row = Database::fetch_array($result);
2369
2370
    return $row;
2371
}
2372
2373
/**
2374
 * This function counts the number of forums inside a given category
2375
 *
2376
 * @param int $cat_id the id of the forum category
2377
 * @todo an additional parameter that takes the visibility into account. For instance $countinvisible=0 would return the number
2378
 *      of visible forums, $countinvisible=1 would return the number of visible and invisible forums
2379
 * @return int the number of forums inside the given category
2380
 *
2381
 * @author Patrick Cool <[email protected]>, Ghent University
2382
 * @version february 2006, dokeos 1.8
2383
 */
2384 View Code Duplication
function count_number_of_forums_in_category($cat_id)
2385
{
2386
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2387
    $course_id = api_get_course_int_id();
2388
    $sql = "SELECT count(*) AS number_of_forums
2389
            FROM ".$table_forums."
2390
            WHERE c_id = $course_id AND forum_category='".Database::escape_string($cat_id)."'";
2391
    $result = Database::query($sql);
2392
    $row = Database::fetch_array($result);
2393
2394
    return $row['number_of_forums'];
2395
}
2396
2397
/**
2398
 * This function update a thread
2399
 *
2400
 * @param array $values - The form Values
2401
 * @return void HTML
2402
 *
2403
 */
2404
function updateThread($values)
2405
{
2406
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
2407
    $courseId = api_get_course_int_id();
2408
2409
    $params = [
2410
        'thread_title' => $values['thread_title'],
2411
        'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
2412
        'thread_title_qualify' => $values['calification_notebook_title'],
2413
        'thread_qualify_max' => $values['numeric_calification'],
2414
        'thread_weight' => $values['weight_calification'],
2415
        'thread_peer_qualify' => $values['thread_peer_qualify'],
2416
    ];
2417
    $where = ['c_id = ? AND thread_id = ?' => [$courseId, $values['thread_id']]];
2418
    Database::update($threadTable, $params, $where);
2419
2420
    if (api_is_course_admin() == true) {
2421
        $option_chek = isset($values['thread_qualify_gradebook']) ? $values['thread_qualify_gradebook'] : false; // values 1 or 0
2422
        if ($option_chek) {
2423
            $id = $values['thread_id'];
2424
            $titleGradebook = Security::remove_XSS(stripslashes($values['calification_notebook_title']));
2425
            $valueCalification = isset($values['numeric_calification']) ? intval($values['numeric_calification']) : 0;
2426
            $weightCalification = isset($values['weight_calification']) ? floatval($values['weight_calification']) : 0;
2427
            $description = '';
2428
            $sessionId = api_get_session_id();
2429
            $courseId = api_get_course_id();
2430
2431
            $linkInfo = GradebookUtils::isResourceInCourseGradebook(
2432
                api_get_course_int_id(),
2433
                LINK_FORUM_THREAD,
2434
                $id,
2435
                $sessionId
2436
            );
2437
            $linkId = $linkInfo['id'];
2438
2439
            if (!$linkInfo) {
2440
                GradebookUtils::add_resource_to_course_gradebook(
2441
                    $values['category_id'],
2442
                    $courseId,
2443
                    LINK_FORUM_THREAD,
2444
                    $id,
2445
                    $titleGradebook,
2446
                    $weightCalification,
2447
                    $valueCalification,
2448
                    $description,
2449
                    1,
2450
                    $sessionId
2451
                );
2452
            } else {
2453
                $em = Database::getManager();
2454
                $gradebookLink = $em->getRepository('ChamiloCoreBundle:GradebookLink')->find($linkId);
2455
                $gradebookLink->setWeight($weightCalification);
2456
                $em->persist($gradebookLink);
0 ignored issues
show
Bug introduced by
It seems like $gradebookLink defined by $em->getRepository('Cham...okLink')->find($linkId) on line 2454 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...
2457
                $em->flush();
2458
            }
2459
        }
2460
    }
2461
2462
    $message = get_lang('EditPostStored').'<br />';
2463
    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...
2464
}
2465
2466
/**
2467
 * This function stores a new thread. This is done through an entry in the forum_thread table AND
2468
 * in the forum_post table because. The threads are also stored in the item_property table. (forum posts are not (yet))
2469
 *
2470
 * @param array $current_forum
2471
 * @param array $values
2472
 * @param array $courseInfo
2473
 * @param bool $showMessage
2474
 * @param int $userId Optional. The user ID
2475
 * @param int $sessionId
2476
 * @return int
2477
 * @author Patrick Cool <[email protected]>, Ghent University
2478
 * @version february 2006, dokeos 1.8
2479
 */
2480
function store_thread($current_forum, $values, $courseInfo = array(), $showMessage = true, $userId = 0, $sessionId = 0)
2481
{
2482
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
2483
    $userId = $userId ?: api_get_user_id();
2484
    $course_id = $courseInfo['real_id'];
2485
    $courseCode = $courseInfo['code'];
2486
    $groupId = api_get_group_id();
2487
    $groupInfo = GroupManager::get_group_properties($groupId);
2488
    $groupIid = null;
2489
    if (!empty($groupInfo)) {
2490
        $groupIid = $groupInfo['iid'];
2491
    }
2492
    $sessionId = $sessionId ?: api_get_session_id();
2493
2494
    $em = Database::getManager();
2495
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
2496
2497
    $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2498
    $upload_ok = 1;
2499
    $has_attachment = false;
2500
2501 View Code Duplication
    if (!empty($_FILES['user_upload']['name'])) {
2502
        $upload_ok = process_uploaded_file($_FILES['user_upload']);
2503
        $has_attachment = true;
2504
    }
2505
2506
    if (!$upload_ok) {
2507
        if ($showMessage) {
2508
            Display::addFlash(
2509
                Display::return_message(get_lang('UplNoFileUploaded'), 'error', false)
2510
            );
2511
        }
2512
2513
        return null;
2514
    }
2515
2516
    $post_date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
2517
2518 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2519
        $visible = 0; // The post has not been approved yet.
2520
    } else {
2521
        $visible = 1;
2522
    }
2523
2524
    $clean_post_title = $values['post_title'];
2525
2526
    // We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
2527
2528
    $lastThread = new CForumThread();
2529
    $lastThread
2530
        ->setCId($course_id)
2531
        ->setThreadTitle($clean_post_title)
2532
        ->setForumId($values['forum_id'])
2533
        ->setThreadPosterId($userId)
2534
        ->setThreadPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2535
        ->setThreadDate($post_date)
2536
        ->setThreadSticky(isset($values['thread_sticky']) ? $values['thread_sticky'] : 0)
2537
        ->setThreadTitleQualify(
2538
            isset($values['calification_notebook_title']) ? $values['calification_notebook_title'] : null
2539
        )
2540
        ->setThreadQualifyMax(isset($values['numeric_calification']) ? (int) $values['numeric_calification'] : 0)
2541
        ->setThreadWeight(isset($values['weight_calification']) ? (int) $values['weight_calification'] : 0)
2542
        ->setThreadPeerQualify(isset($values['thread_peer_qualify']) ? (int) $values['thread_peer_qualify'] : 0)
2543
        ->setSessionId($sessionId)
2544
        ->setLpItemId(isset($values['lp_item_id']) ? (int) $values['lp_item_id'] : 0)
2545
        ->setThreadId(0)
2546
        ->setLocked(0)
2547
    ;
2548
2549
    $em->persist($lastThread);
2550
    $em->flush();
2551
2552
    // Add option gradebook qualify.
2553
2554
    if (isset($values['thread_qualify_gradebook']) &&
2555
        1 == $values['thread_qualify_gradebook']
2556
    ) {
2557
        // Add function gradebook.
2558
        $resourcetype = 5;
2559
        $resourceid = $lastThread->getIid();
2560
        $resourcename = stripslashes($values['calification_notebook_title']);
2561
        $maxqualify = $values['numeric_calification'];
2562
        $weigthqualify = $values['weight_calification'];
2563
        $resourcedescription = '';
2564
        GradebookUtils::add_resource_to_course_gradebook(
2565
            $values['category_id'],
2566
            $courseCode,
2567
            $resourcetype,
2568
            $resourceid,
2569
            $resourcename,
2570
            $weigthqualify,
2571
            $maxqualify,
2572
            $resourcedescription,
2573
            0,
2574
            $sessionId
2575
        );
2576
    }
2577
2578
    if ($lastThread->getIid()) {
2579
        $lastThread->setThreadId($lastThread->getIid());
2580
2581
        $em->merge($lastThread);
2582
        $em->flush();
2583
2584
        api_item_property_update(
2585
            $courseInfo,
2586
            TOOL_FORUM_THREAD,
2587
            $lastThread->getIid(),
2588
            'ForumThreadAdded',
2589
            $userId,
2590
            $groupIid,
2591
            null,
2592
            null,
2593
            null,
2594
            $sessionId
2595
        );
2596
2597
        // If the forum properties tell that the posts have to be approved
2598
        // we have to put the whole thread invisible,
2599
        // because otherwise the students will see the thread and not the post
2600
        // in the thread.
2601
        // We also have to change $visible because the post itself has to be
2602
        // visible in this case (otherwise the teacher would have
2603
        // to make the thread visible AND the post.
2604
        // Default behaviour
2605
        api_set_default_visibility(
2606
            $lastThread->getIid(),
2607
            TOOL_FORUM_THREAD,
2608
            $groupIid,
2609
            $courseInfo,
2610
            $sessionId,
2611
            $userId
2612
        );
2613
2614
        if ($visible == 0) {
2615
            api_item_property_update(
2616
                $courseInfo,
2617
                TOOL_FORUM_THREAD,
2618
                $lastThread->getIid(),
2619
                'invisible',
2620
                $userId,
2621
                $groupIid
2622
2623
            );
2624
            $visible = 1;
2625
        }
2626
    }
2627
2628
    // We now store the content in the table_post table.
2629
    $lastPost = new CForumPost();
2630
    $lastPost
2631
        ->setCId($course_id)
2632
        ->setPostTitle($clean_post_title)
2633
        ->setPostText($values['post_text'])
2634
        ->setThreadId($lastThread->getIid())
2635
        ->setForumId($values['forum_id'])
2636
        ->setPosterId($userId)
2637
        ->setPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2638
        ->setPostDate($post_date)
2639
        ->setPostNotification(isset($values['post_notification']) ? (int) $values['post_notification'] : null)
2640
        ->setPostParentId(null)
2641
        ->setVisible($visible)
2642
        ->setPostId(0)
2643
        ->setStatus(CForumPost::STATUS_VALIDATED);
2644
2645
    if ($current_forum['moderated']) {
2646
        $lastPost->setStatus(
2647
            api_is_course_admin() ? CForumPost::STATUS_VALIDATED : CForumPost::STATUS_WAITING_MODERATION
2648
        );
2649
    }
2650
2651
    $em->persist($lastPost);
2652
    $em->flush();
2653
2654
    $last_post_id = $lastPost->getIid();
2655
2656
    if ($last_post_id) {
2657
        $lastPost->setPostId($last_post_id);
2658
        $em->merge($lastPost);
2659
        $em->flush();
2660
    }
2661
2662
    // Update attached files
2663 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
2664
        foreach ($_POST['file_ids'] as $key => $id) {
2665
            editAttachedFile(
2666
                array(
2667
                    'comment' => $_POST['file_comments'][$key],
2668
                    'post_id' => $last_post_id
2669
                ),
2670
                $id
2671
            );
2672
        }
2673
    }
2674
2675
    // Now we have to update the thread table to fill the thread_last_post
2676
    // field (so that we know when the thread has been updated for the last time).
2677
    $sql = "UPDATE $table_threads
2678
            SET thread_last_post = '".Database::escape_string($last_post_id)."'
2679
            WHERE
2680
                c_id = $course_id AND
2681
                thread_id='".Database::escape_string($lastThread->getIid())."'";
2682
    $result = Database::query($sql);
2683
    $message = get_lang('NewThreadStored');
2684
    // Storing the attachments if any.
2685
    if ($has_attachment) {
2686
        // Try to add an extension to the file if it hasn't one.
2687
        $new_file_name = add_ext_on_mime(
2688
            stripslashes($_FILES['user_upload']['name']),
2689
            $_FILES['user_upload']['type']
2690
        );
2691
2692
        if (!filter_extension($new_file_name)) {
2693
            if ($showMessage) {
2694
                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...
2695
                    get_lang('UplUnableToSaveFileFilteredExtension')
2696
                );
2697
            }
2698
        } else {
2699
            if ($result) {
2700
                add_forum_attachment_file(
2701
                    isset($values['file_comment']) ? $values['file_comment'] : null,
2702
                    $last_post_id
2703
                );
2704
            }
2705
        }
2706
    } else {
2707
        $message .= '<br />';
2708
    }
2709
2710
    if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2711
        $message .= get_lang('MessageHasToBeApproved').'<br />';
2712
        $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2713
            get_lang('Forum').'</a><br />';
2714
    } else {
2715
        $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2716
            get_lang('Forum').'</a><br />';
2717
        $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'&gradebook='.$gradebook.'&thread='.$lastThread->getIid().'">'.
2718
            get_lang('Message').'</a>';
2719
    }
2720
    $reply_info['new_post_id'] = $last_post_id;
2721
    $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
2722
2723
    if ($my_post_notification == 1) {
2724
        set_notification('thread', $lastThread->getIid(), true);
2725
    }
2726
2727
    send_notification_mails(
2728
        $current_forum['forum_id'],
2729
        $lastThread->getIid(),
2730
        $reply_info,
2731
        $courseInfo['code']
2732
    );
2733
2734
    Session::erase('formelements');
2735
    Session::erase('origin');
2736
    Session::erase('breadcrumbs');
2737
    Session::erase('addedresource');
2738
    Session::erase('addedresourceid');
2739
2740
    if ($showMessage) {
2741
        Display::addFlash(Display::return_message($message, 'success', false));
2742
    }
2743
    return $lastThread->getIid();
2744
}
2745
2746
/**
2747
 * This function displays the form that is used to UPDATE a Thread.
2748
 * @param array $currentForum
2749
 * @param array $forumSetting
2750
 * @param array $formValues
2751
 * @return void HMTL
2752
 * @author José Loguercio <[email protected]>
2753
 * @version february 2016, chamilo 1.10.4
2754
 */
2755
function showUpdateThreadForm($currentForum, $forumSetting, $formValues = '')
2756
{
2757
    $myThread = isset($_GET['thread']) ? intval($_GET['thread']) : '';
2758
    $myForum = isset($_GET['forum']) ? intval($_GET['forum']) : '';
2759
    $myGradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2760
    $form = new FormValidator(
2761
        'thread',
2762
        'post',
2763
        api_get_self() . '?' . http_build_query([
2764
            'forum' => $myForum,
2765
            'gradebook' => $myGradebook,
2766
            'thread' => $myThread,
2767
        ]) . '&' . api_get_cidreq()
2768
    );
2769
2770
    $form->addElement('header', get_lang('EditThread'));
2771
    $form->setConstants(array('forum' => '5'));
2772
    $form->addElement('hidden', 'forum_id', $myForum);
2773
    $form->addElement('hidden', 'thread_id', $myThread);
2774
    $form->addElement('hidden', 'gradebook', $myGradebook);
2775
    $form->addElement('text', 'thread_title', get_lang('Title'));
2776
    $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2777
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2778
2779
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && ($myThread)) {
2780
        // Thread qualify
2781
        if (Gradebook::is_active()) {
2782
            //Loading gradebook select
2783
            GradebookUtils::load_gradebook_select_in_tool($form);
2784
            $form->addElement(
2785
                'checkbox',
2786
                'thread_qualify_gradebook',
2787
                '',
2788
                get_lang('QualifyThreadGradebook'),
2789
                [
2790
                    'id' => 'thread_qualify_gradebook'
2791
                ]
2792
            );
2793
        } else {
2794
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2795
        }
2796
2797
        $form->addElement('html', '<div id="options_field" style="display:none">');
2798
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2799
        $form->applyFilter('numeric_calification', 'html_filter');
2800
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2801
        $form->applyFilter('calification_notebook_title', 'html_filter');
2802
        $form->addElement(
2803
            'text',
2804
            'weight_calification',
2805
            get_lang('QualifyWeight'),
2806
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2807
        );
2808
        $form->applyFilter('weight_calification', 'html_filter');
2809
        $group = array();
2810
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2811
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2812
        $form->addGroup(
2813
            $group,
2814
            '',
2815
            [
2816
                get_lang('ForumThreadPeerScoring'),
2817
                get_lang('ForumThreadPeerScoringComment'),
2818
            ]
2819
        );
2820
        $form->addElement('html', '</div>');
2821
    }
2822
2823 View Code Duplication
    if ($forumSetting['allow_sticky'] && api_is_allowed_to_edit(null, true)) {
2824
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2825
    }
2826
2827
    $form->addElement('html', '</div>');
2828
2829
    if (!empty($formValues)) {
2830
        $defaults['thread_qualify_gradebook'] = ($formValues['threadQualifyMax'] > 0 && empty($_POST)) ? 1 : 0 ;
2831
        $defaults['thread_title'] = prepare4display($formValues['threadTitle']);
2832
        $defaults['thread_sticky'] = strval(intval($formValues['threadSticky']));
2833
        $defaults['thread_peer_qualify'] = intval($formValues['threadPeerQualify']);
2834
        $defaults['numeric_calification'] = $formValues['threadQualifyMax'];
2835
        $defaults['calification_notebook_title'] = $formValues['threadTitleQualify'];
2836
        $defaults['weight_calification'] = $formValues['threadWeight'];
2837
    } else {
2838
        $defaults['thread_qualify_gradebook'] = 0;
2839
        $defaults['numeric_calification'] = 0;
2840
        $defaults['calification_notebook_title'] = '';
2841
        $defaults['weight_calification'] = 0;
2842
        $defaults['thread_peer_qualify'] = 0;
2843
    }
2844
    $form->setDefaults(isset($defaults) ? $defaults : null);
2845
2846
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
2847
2848
    if ($form->validate()) {
2849
        $check = Security::check_token('post');
2850
        if ($check) {
2851
            $values = $form->exportValues();
2852
            if (isset($values['thread_qualify_gradebook']) &&
2853
                $values['thread_qualify_gradebook'] == '1' &&
2854
                empty($values['weight_calification'])
2855
            ) {
2856
                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...
2857
                    get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.
2858
                    get_lang('Back').'</a>',
2859
                    false
2860
                );
2861
                return false;
2862
            }
2863
            Security::clear_token();
2864
            return $values;
2865
        }
2866
    } else {
2867
        $token = Security::get_token();
2868
        $form->addElement('hidden', 'sec_token');
2869
        $form->setConstants(array('sec_token' => $token));
2870
        $form->display();
2871
    }
2872
}
2873
2874
/**
2875
 * This function displays the form that is used to add a post. This can be a new thread or a reply.
2876
 * @param array $current_forum
2877
 * @param array $forum_setting
2878
 * @param string $action is the parameter that determines if we are
2879
 *  1. newthread: adding a new thread (both empty) => No I-frame
2880
 *  2. replythread: Replying to a thread ($action = replythread) => I-frame with the complete thread (if enabled)
2881
 *  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)
2882
 *  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)
2883
 * @return FormValidator
2884
 * @author Patrick Cool <[email protected]>, Ghent University
2885
 * @version february 2006, dokeos 1.8
2886
 */
2887
function show_add_post_form($current_forum, $forum_setting, $action, $id = '', $form_values = '')
2888
{
2889
    $_user = api_get_user_info();
2890
    $action = isset($action) ? Security::remove_XSS($action) : '';
2891
    $myThread = isset($_GET['thread']) ? (int) $_GET['thread'] : '';
2892
    $forumId = isset($_GET['forum']) ? (int) $_GET['forum'] : '';
2893
    $my_post = isset($_GET['post']) ? (int) $_GET['post'] : '';
2894
    $my_gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2895
2896
    $url = api_get_self() . '?' . http_build_query([
2897
        'action' => $action,
2898
        'forum' => $forumId,
2899
        'gradebook' => $my_gradebook,
2900
        'thread' => $myThread,
2901
        'post' => $my_post
2902
    ]) . '&' . api_get_cidreq();
2903
2904
    $form = new FormValidator(
2905
        'thread',
2906
        'post',
2907
        $url
2908
    );
2909
2910
    $form->setConstants(array('forum' => '5'));
2911
2912
    // Setting the form elements.
2913
    $form->addElement('hidden', 'forum_id', $forumId);
2914
    $form->addElement('hidden', 'thread_id', $myThread);
2915
    $form->addElement('hidden', 'gradebook', $my_gradebook);
2916
    $form->addElement('hidden', 'action', $action);
2917
2918
    // If anonymous posts are allowed we also display a form to allow the user to put his name or username in.
2919
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2920
        $form->addElement('text', 'poster_name', get_lang('Name'));
2921
        $form->applyFilter('poster_name', 'html_filter');
2922
    }
2923
2924
    $form->addElement('text', 'post_title', get_lang('Title'));
2925
    $form->addHtmlEditor(
2926
        'post_text',
2927
        get_lang('Text'),
2928
        true,
2929
        false,
2930
        api_is_allowed_to_edit(null, true) ? array(
2931
            'ToolbarSet' => 'Forum',
2932
            'Width' => '100%',
2933
            'Height' => '300',
2934
        ) : array(
2935
            'ToolbarSet' => 'ForumStudent',
2936
            'Width' => '100%',
2937
            'Height' => '300',
2938
            'UserStatus' => 'student'
2939
        )
2940
    );
2941
2942
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
2943
    $iframe = null;
2944
    $myThread = Security::remove_XSS($myThread);
2945
    if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
2946
        $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>";
2947
    }
2948
    if (!empty($iframe)) {
2949
        $form->addElement('label', get_lang('Thread'), $iframe);
2950
    }
2951
2952
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && !($myThread)) {
2953
        $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2954
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2955
2956
        // Thread qualify
2957
        if (Gradebook::is_active()) {
2958
            //Loading gradebook select
2959
            GradebookUtils::load_gradebook_select_in_tool($form);
2960
            $form->addElement(
2961
                'checkbox',
2962
                'thread_qualify_gradebook',
2963
                '',
2964
                get_lang('QualifyThreadGradebook'),
2965
                'onclick="javascript:if(this.checked==true){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
2966
            );
2967
        } else {
2968
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2969
        }
2970
2971
        $form->addElement('html', '<div id="options_field" style="display:none">');
2972
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2973
        $form->applyFilter('numeric_calification', 'html_filter');
2974
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2975
        $form->applyFilter('calification_notebook_title', 'html_filter');
2976
2977
        $form->addElement(
2978
            'text',
2979
            'weight_calification',
2980
            get_lang('QualifyWeight'),
2981
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2982
        );
2983
        $form->applyFilter('weight_calification', 'html_filter');
2984
2985
        $group = array();
2986
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2987
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2988
        $form->addGroup(
2989
            $group,
2990
            '',
2991
            [
2992
                get_lang('ForumThreadPeerScoring'),
2993
                get_lang('ForumThreadPeerScoringComment'),
2994
            ]
2995
        );
2996
        $form->addElement('html', '</div>');
2997
        $form->addElement('html', '</div>');
2998
    }
2999
3000 View Code Duplication
    if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
3001
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3002
    }
3003
3004
    if (in_array($action, ['quote', 'replymessage'])) {
3005
        $form->addFile('user_upload[]', get_lang('Attachment'));
3006
        $form->addButton(
3007
            'add_attachment',
3008
            get_lang('AddAttachment'),
3009
            'paperclip',
3010
            'default',
3011
            'default',
3012
            null,
3013
            ['id' => 'reply-add-attachment']
3014
        );
3015
    } else {
3016
        $form->addFile('user_upload', get_lang('Attachment'));
3017
    }
3018
3019
    // Setting the class and text of the form title and submit button.
3020
    if ($action == 'quote') {
3021
        $form->addButtonCreate(get_lang('QuoteMessage'), 'SubmitPost');
3022
    } elseif ($action == 'replythread') {
3023
        $form->addButtonCreate(get_lang('ReplyToThread'), 'SubmitPost');
3024
    } elseif ($action == 'replymessage') {
3025
        $form->addButtonCreate(get_lang('ReplyToMessage'), 'SubmitPost');
3026
    } else {
3027
        $form->addButtonCreate(get_lang('CreateThread'), 'SubmitPost');
3028
    }
3029
3030
    if (!empty($form_values)) {
3031
        $defaults['post_title'] = prepare4display($form_values['post_title']);
3032
        $defaults['post_text'] = prepare4display($form_values['post_text']);
3033
        $defaults['post_notification'] = strval(intval($form_values['post_notification']));
3034
        $defaults['thread_sticky'] = strval(intval($form_values['thread_sticky']));
3035
        $defaults['thread_peer_qualify'] = intval($form_values['thread_peer_qualify']);
3036
    } else {
3037
        $defaults['thread_peer_qualify'] = 0;
3038
    }
3039
3040
    // If we are quoting a message we have to retrieve the information of the post we are quoting so that
3041
    // we can add this as default to the textarea.
3042
    if (($action == 'quote' || $action == 'replymessage') && isset($my_post)) {
3043
        // We also need to put the parent_id of the post in a hidden form when
3044
        // we are quoting or replying to a message (<> reply to a thread !!!)
3045
        $form->addHidden('post_parent_id', intval($my_post));
3046
3047
        // If we are replying or are quoting then we display a default title.
3048
        $values = get_post_information($my_post);
3049
        $posterInfo = api_get_user_info($values['poster_id']);
3050
        $posterName = '';
3051
        if ($posterInfo) {
3052
            $posterName = $posterInfo['complete_name'];
3053
        }
3054
        $defaults['post_title'] = get_lang('ReplyShort').api_html_entity_decode($values['post_title'], ENT_QUOTES);
3055
        // When we are quoting a message then we have to put that message into the wysiwyg editor.
3056
        // Note: The style has to be hardcoded here because using class="quote" didn't work.
3057
        if ($action == 'quote') {
3058
            $defaults['post_text'] = '<div>&nbsp;</div>
3059
                <div style="margin: 5px;">
3060
                    <div style="font-size: 90%; font-style: italic;">'.
3061
                        get_lang('Quoting').' '.$posterName.':</div>
3062
                        <div style="color: #006600; font-size: 90%;  font-style: italic; background-color: #FAFAFA; border: #D1D7DC 1px solid; padding: 3px;">'.
3063
                            prepare4display($values['post_text']).'
3064
                        </div>
3065
                    </div>
3066
                <div>&nbsp;</div>
3067
                <div>&nbsp;</div>
3068
            ';
3069
        }
3070
    }
3071
3072
    $form->setDefaults(isset($defaults) ? $defaults : []);
3073
3074
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3075
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3076
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
3077
        $form->addRule('poster_name', get_lang('ThisFieldIsRequired'), 'required');
3078
    }
3079
3080
    // Validation or display
3081
    if ($form->validate()) {
3082
        $check = Security::check_token('post');
3083
        if ($check) {
3084
            $values = $form->exportValues();
3085
            if (isset($values['thread_qualify_gradebook']) &&
3086
                $values['thread_qualify_gradebook'] == '1' &&
3087
                empty($values['weight_calification'])
3088
            ) {
3089
                Display::addFlash(
3090
                    Display::return_message(
3091
                        get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>',
3092
                        'error',
3093
                        false
3094
                    )
3095
                );
3096
3097
                return false;
3098
            }
3099
3100
            switch ($action) {
3101
                case 'newthread':
3102
                    $myThread = store_thread($current_forum, $values);
3103
                    break;
3104
                case 'quote':
3105
                case 'replythread':
3106
                case 'replymessage':
3107
                    store_reply($current_forum, $values);
3108
3109
                    break;
3110
            }
3111
3112
            $url = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&'.http_build_query(
3113
                [
3114
                    'forum' => $forumId,
3115
                    'thread' => $myThread
3116
                ]
3117
            );
3118
3119
            Security::clear_token();
3120
            header('Location: '.$url);
3121
            exit;
3122
        }
3123
    } else {
3124
        $token = Security::get_token();
3125
        $form->addElement('hidden', 'sec_token');
3126
        $form->setConstants(array('sec_token' => $token));
3127
3128
        // Delete from $_SESSION forum attachment from other posts
3129
        // and keep only attachments for new post
3130
        clearAttachedFiles(FORUM_NEW_POST);
3131
        // Get forum attachment ajax table to add it to form
3132
        $attachmentAjaxTable = getAttachmentsAjaxTable(0, $current_forum['forum_id']);
3133
        $ajaxHtml = $attachmentAjaxTable;
3134
        $form->addElement('html', $ajaxHtml);
3135
3136
        return $form;
3137
    }
3138
}
3139
3140
/**
3141
 * @param array $threadInfo
3142
 * @param integer $user_id
3143
 * @param integer $thread_id
3144
 * @param integer $thread_qualify
3145
 * @param integer $qualify_time
3146
 * @param integer $session_id
3147
 * @return array optional
3148
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3149
 * @version October 2008, dokeos  1.8.6
3150
 */
3151
function saveThreadScore(
3152
    $threadInfo,
3153
    $user_id,
3154
    $thread_id,
3155
    $thread_qualify = 0,
3156
    $qualify_time,
3157
    $session_id = 0
3158
) {
3159
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3160
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3161
3162
    $course_id = api_get_course_int_id();
3163
    $session_id = intval($session_id);
3164
    $currentUserId = api_get_user_id();
3165
3166
    if ($user_id == strval(intval($user_id)) &&
3167
        $thread_id == strval(intval($thread_id)) &&
3168
        $thread_qualify == strval(floatval($thread_qualify))
3169
    ) {
3170
        // Testing
3171
        $sql = "SELECT thread_qualify_max FROM $table_threads
3172
                WHERE c_id = $course_id AND thread_id=".$thread_id;
3173
        $res_string = Database::query($sql);
3174
        $row_string = Database::fetch_array($res_string);
3175
        if ($thread_qualify <= $row_string[0]) {
3176
            if ($threadInfo['thread_peer_qualify'] == 0) {
3177
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3178
                        WHERE
3179
                            c_id = $course_id AND
3180
                            user_id = $user_id AND
3181
                            thread_id = ".$thread_id;
3182
            } else {
3183
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3184
                        WHERE
3185
                            c_id = $course_id AND
3186
                            user_id = $user_id AND
3187
                            qualify_user_id = $currentUserId AND
3188
                            thread_id = ".$thread_id;
3189
            }
3190
3191
            $result = Database::query($sql);
3192
            $row = Database::fetch_array($result);
3193
3194
            if ($row[0] == 0) {
3195
                $sql = "INSERT INTO $table_threads_qualify (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
3196
                        VALUES (".$course_id.", '".$user_id."','".$thread_id."',".(float)$thread_qualify.", '".$currentUserId."','".$qualify_time."','".$session_id."')";
3197
                Database::query($sql);
3198
3199
                $insertId = Database::insert_id();
3200
                if ($insertId) {
3201
                    $sql = "UPDATE $table_threads_qualify SET id = iid
3202
                            WHERE iid = $insertId";
3203
                    Database::query($sql);
3204
                }
3205
3206
                return 'insert';
3207
            } else {
3208
3209
                saveThreadScoreHistory(
3210
                    '1',
3211
                    $course_id,
3212
                    $user_id,
3213
                    $thread_id
3214
                );
3215
3216
3217
                // Update
3218
                $sql = "UPDATE $table_threads_qualify
3219
                        SET
3220
                            qualify = '".$thread_qualify."',
3221
                            qualify_time = '".$qualify_time."'
3222
                        WHERE
3223
                            c_id = $course_id AND
3224
                            user_id=".$user_id." AND
3225
                            thread_id=".$thread_id." AND
3226
                            qualify_user_id = $currentUserId
3227
                        ";
3228
                Database::query($sql);
3229
3230
                return 'update';
3231
            }
3232
3233
        } else {
3234
            return null;
3235
        }
3236
    }
3237
}
3238
3239
/**
3240
 * This function shows qualify.
3241
 * @param string $option contains the information of option to run
3242
 * @param integer $user_id contains the information the current user id
3243
 * @param integer $thread_id contains the information the current thread id
3244
 * @return integer qualify
3245
 * <code> $option=1 obtained the qualification of the current thread</code>
3246
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3247
 * @version October 2008, dokeos  1.8.6
3248
 */
3249
function showQualify($option, $user_id, $thread_id)
3250
{
3251
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3252
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3253
3254
    $course_id = api_get_course_int_id();
3255
    $user_id = intval($user_id);
3256
    $thread_id = intval($thread_id);
3257
3258
    if (empty($user_id) || empty($thread_id)) {
3259
        return false;
3260
    }
3261
3262
    $sql = '';
3263
    switch ($option) {
3264
        case 1:
3265
            $sql = "SELECT qualify FROM $table_threads_qualify
3266
                    WHERE
3267
                        c_id = $course_id AND
3268
                        user_id=".$user_id." AND
3269
                        thread_id=".$thread_id;
3270
            break;
3271
        case 2:
3272
            $sql = "SELECT thread_qualify_max FROM $table_threads
3273
                    WHERE c_id = $course_id AND thread_id=".$thread_id;
3274
            break;
3275
    }
3276
3277
    if (!empty($sql)) {
3278
        $rs = Database::query($sql);
3279
        $row = Database::fetch_array($rs);
3280
3281
        return $row[0];
3282
    }
3283
3284
    return array();
3285
}
3286
3287
/**
3288
 * This function gets qualify historical.
3289
 * @param integer $user_id contains the information the current user id
3290
 * @param integer $thread_id contains the information the current thread id
3291
 * @param boolean $opt contains the information of option to run
3292
 * @return array
3293
 * @author Christian Fasanando <[email protected]>,
3294
 * @author Isaac Flores <[email protected]>,
3295
 * @version October 2008, dokeos  1.8.6
3296
 */
3297
function getThreadScoreHistory($user_id, $thread_id, $opt)
3298
{
3299
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3300
    $course_id = api_get_course_int_id();
3301
3302
    if ($opt == 'false') {
3303
        $sql = "SELECT * FROM $table_threads_qualify_log
3304
                WHERE
3305
                    c_id = $course_id AND
3306
                    thread_id='".Database::escape_string($thread_id)."' AND
3307
                    user_id='".Database::escape_string($user_id)."'
3308
                ORDER BY qualify_time";
3309
    } else {
3310
        $sql = "SELECT * FROM $table_threads_qualify_log
3311
                WHERE
3312
                    c_id = $course_id AND
3313
                    thread_id='".Database::escape_string($thread_id)."' AND
3314
                    user_id='".Database::escape_string($user_id)."'
3315
                ORDER BY qualify_time DESC";
3316
    }
3317
    $rs = Database::query($sql);
3318
    $log = array();
3319
    while ($row = Database::fetch_array($rs, 'ASSOC')) {
3320
        $log[] = $row;
3321
    }
3322
3323
    return $log;
3324
}
3325
3326
/**
3327
 * This function stores qualify historical.
3328
 * @param boolean contains the information of option to run
3329
 * @param string contains the information the current course id
3330
 * @param integer contains the information the current forum id
3331
 * @param integer contains the information the current user id
3332
 * @param integer contains the information the current thread id
3333
 * @param integer contains the information the current qualify
3334
 * @param string $option
3335
 * @param integer $course_id
3336
 * @param integer $user_id
3337
 * @param integer $thread_id
3338
 * @return void
3339
 * <code>$option=1 obtained the qualification of the current thread</code>
3340
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3341
 * @version October 2008, dokeos  1.8.6
3342
 */
3343
function saveThreadScoreHistory(
3344
    $option,
3345
    $course_id,
3346
    $user_id,
3347
    $thread_id
3348
) {
3349
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3350
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3351
3352
    $course_id = intval($course_id);
3353
    $qualify_user_id = api_get_user_id();
3354
3355
    if ($user_id == strval(intval($user_id)) &&
3356
        $thread_id == strval(intval($thread_id)) && $option == 1
3357
    ) {
3358
3359
        // Extract information of thread_qualify.
3360
        $sql = "SELECT qualify, qualify_time
3361
                FROM $table_threads_qualify
3362
                WHERE
3363
                    c_id = $course_id AND
3364
                    user_id = ".$user_id." AND
3365
                    thread_id = ".$thread_id." AND
3366
                    qualify_user_id = $qualify_user_id
3367
                ";
3368
        $rs = Database::query($sql);
3369
        $row = Database::fetch_array($rs);
3370
3371
        // Insert thread_historical.
3372
        $sql = "INSERT INTO $table_threads_qualify_log (c_id, user_id, thread_id, qualify, qualify_user_id,qualify_time,session_id)
3373
                VALUES(".$course_id.", '".$user_id."','".$thread_id."',".(float) $row[0].", '".$qualify_user_id."','".$row[1]."','')";
3374
        Database::query($sql);
3375
3376
        $insertId = Database::insert_id();
3377
        if ($insertId) {
3378
            $sql = "UPDATE $table_threads_qualify_log SET id = iid
3379
                    WHERE iid = $insertId";
3380
            Database::query($sql);
3381
        }
3382
    }
3383
}
3384
3385
/**
3386
 * This function shows current thread qualify .
3387
 * @param integer $threadId
3388
 * @param integer $sessionId
3389
 * @param integer $userId
3390
 *
3391
 * @return array or null if is empty
3392
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3393
 * @version December 2008, dokeos  1.8.6
3394
 */
3395 View Code Duplication
function current_qualify_of_thread($threadId, $sessionId, $userId)
3396
{
3397
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3398
3399
    $course_id = api_get_course_int_id();
3400
    $currentUserId = api_get_user_id();
3401
    $sessionId = intval($sessionId);
3402
    $threadId = intval($threadId);
3403
3404
    $sql = "SELECT qualify FROM $table_threads_qualify
3405
            WHERE
3406
                c_id = $course_id AND
3407
                thread_id = $threadId AND
3408
                session_id = $sessionId AND
3409
                qualify_user_id = $currentUserId AND
3410
                user_id = $userId
3411
            ";
3412
    $res = Database::query($sql);
3413
    $row = Database::fetch_array($res, 'ASSOC');
3414
3415
    return $row['qualify'];
3416
}
3417
3418
/**
3419
 * This function stores a reply in the forum_post table.
3420
 * It also updates the forum_threads table (thread_replies +1 , thread_last_post, thread_date)
3421
 * @param array $current_forum
3422
 * @param array $values
3423
 * @param int $courseId Optional
3424
 * @param int $userId Optional
3425
 * @return array
3426
 * @author Patrick Cool <[email protected]>, Ghent University
3427
 * @version february 2006, dokeos 1.8
3428
 */
3429
function store_reply($current_forum, $values, $courseId = 0, $userId = 0)
3430
{
3431
    $courseId = !empty($courseId) ? $courseId : api_get_course_int_id();
3432
    $_course = api_get_course_info_by_id($courseId);
3433
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3434
    $post_date = api_get_utc_datetime();
3435
    $userId = $userId ?: api_get_user_id();
3436
3437 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' &&
3438
        !api_is_allowed_to_edit(null, true)
3439
    ) {
3440
        $visible = 0;
3441
    } else {
3442
        $visible = 1;
3443
    }
3444
3445
    $upload_ok = 1;
3446
    $return = array();
3447
3448
    if ($upload_ok) {
3449
        // We first store an entry in the forum_post table.
3450
        $new_post_id = Database::insert(
3451
            $table_posts,
3452
            [
3453
                'c_id' => $courseId,
3454
                'post_title' => $values['post_title'],
3455
                'post_text' => isset($values['post_text']) ? ($values['post_text']) : null,
3456
                'thread_id' => $values['thread_id'],
3457
                'forum_id' => $values['forum_id'],
3458
                'poster_id' => $userId,
3459
                'post_id' => 0,
3460
                'post_date' => $post_date,
3461
                'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : null,
3462
                'post_parent_id' => isset($values['post_parent_id']) ? $values['post_parent_id'] : null,
3463
                'visible' => $visible,
3464
            ]
3465
        );
3466
3467
        if ($new_post_id) {
3468
            $sql = "UPDATE $table_posts SET post_id = iid WHERE iid = $new_post_id";
3469
            Database::query($sql);
3470
3471
            $values['new_post_id'] = $new_post_id;
3472
            $message = get_lang('ReplyAdded');
3473
3474 View Code Duplication
            if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3475
                foreach ($_POST['file_ids'] as $key => $id) {
3476
                    editAttachedFile(
3477
                        array(
3478
                            'comment' => $_POST['file_comments'][$key],
3479
                            'post_id' => $new_post_id,
3480
                        ),
3481
                        $id
3482
                    );
3483
                }
3484
            }
3485
3486
            // Update the thread.
3487
            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 3434 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...
3488
3489
            // Update the forum.
3490
            api_item_property_update(
3491
                $_course,
3492
                TOOL_FORUM,
3493
                $values['forum_id'],
3494
                'NewMessageInForum',
3495
                $userId
3496
            );
3497
3498
            // Insert post
3499
            api_item_property_update(
3500
                $_course,
3501
                TOOL_FORUM_POST,
3502
                $new_post_id,
3503
                'NewPost',
3504
                $userId
3505
            );
3506
3507
            if ($current_forum['approval_direct_post'] == '1' &&
3508
                !api_is_allowed_to_edit(null, true)
3509
            ) {
3510
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3511
            }
3512
3513
            if ($current_forum['moderated'] &&
3514
                !api_is_allowed_to_edit(null, true)
3515
            ) {
3516
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3517
            }
3518
3519
            // Setting the notification correctly.
3520
            $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
3521
            if ($my_post_notification == 1) {
3522
                set_notification('thread', $values['thread_id'], true);
3523
            }
3524
3525
            send_notification_mails(
3526
                $values['forum_id'],
3527
                $values['thread_id'],
3528
                $values
3529
            );
3530
            add_forum_attachment_file('', $new_post_id);
3531
        }
3532
3533
        Session::erase('formelements');
3534
        Session::erase('origin');
3535
        Session::erase('breadcrumbs');
3536
        Session::erase('addedresource');
3537
        Session::erase('addedresourceid');
3538
3539
        Display::addFlash(Display::return_message($message, 'confirmation', false));
3540
    } else {
3541
        Display::addFlash(
3542
            Display::return_message(get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'), 'error')
3543
        );
3544
    }
3545
3546
    return $return;
3547
}
3548
3549
/**
3550
 * This function displays the form that is used to edit a post. This can be a new thread or a reply.
3551
 * @param array contains all the information about the current post
3552
 * @param array contains all the information about the current thread
3553
 * @param array contains all info about the current forum (to check if attachments are allowed)
3554
 * @param array contains the default values to fill the form
3555
 * @return void
3556
 *
3557
 * @author Patrick Cool <[email protected]>, Ghent University
3558
 * @version february 2006, dokeos 1.8
3559
 */
3560
function show_edit_post_form(
3561
    $forum_setting,
3562
    $current_post,
3563
    $current_thread,
3564
    $current_forum,
3565
    $form_values = '',
3566
    $id_attach = 0
3567
) {
3568
    // Initialize the object.
3569
    $form = new FormValidator(
3570
        'edit_post',
3571
        'post',
3572
        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
3573
    );
3574
    $form->addElement('header', get_lang('EditPost'));
3575
    // Setting the form elements.
3576
    $form->addElement('hidden', 'post_id', $current_post['post_id']);
3577
    $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
3578
    $form->addElement('hidden', 'id_attach', $id_attach);
3579
3580
    if (empty($current_post['post_parent_id'])) {
3581
        $form->addElement('hidden', 'is_first_post_of_thread', '1');
3582
    }
3583
3584
    $form->addElement('text', 'post_title', get_lang('Title'));
3585
    $form->applyFilter('post_title', 'html_filter');
3586
    $form->addElement(
3587
        'html_editor',
3588
        'post_text',
3589
        get_lang('Text'),
3590
        null,
3591
        api_is_allowed_to_edit(null, true) ? array(
3592
            'ToolbarSet' => 'Forum',
3593
            'Width' => '100%',
3594
            'Height' => '400',
3595
        ) : array(
3596
            'ToolbarSet' => 'ForumStudent',
3597
            'Width' => '100%',
3598
            'Height' => '400',
3599
            'UserStatus' => 'student',
3600
        )
3601
    );
3602
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
3603
3604
    $form->addButtonAdvancedSettings('advanced_params');
3605
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
3606
3607
    if (!isset($_GET['edit'])) {
3608
        if (Gradebook::is_active()) {
3609
            $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
3610
            $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\';}"');
3611
3612
            $link_info = GradebookUtils::isResourceInCourseGradebook(
3613
                api_get_course_int_id(),
3614
                5,
3615
                $_GET['thread'],
3616
                api_get_session_id()
3617
            );
3618
            if (!empty($link_info)) {
3619
                $defaults['thread_qualify_gradebook'] = true;
3620
                $defaults['category_id'] = $link_info['category_id'];
3621
            } else {
3622
                $defaults['thread_qualify_gradebook'] = false;
3623
                $defaults['category_id'] = '';
3624
            }
3625
        } else {
3626
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
3627
            $defaults['thread_qualify_gradebook'] = false;
3628
        }
3629
3630
        if (!empty($defaults['thread_qualify_gradebook'])) {
3631
            $form->addElement('html', '<div id="options_field" style="display:block">');
3632
        } else {
3633
            $form->addElement('html', '<div id="options_field" style="display:none">');
3634
        }
3635
3636
        // Loading gradebook select
3637
        GradebookUtils::load_gradebook_select_in_tool($form);
3638
3639
        $form->addElement(
3640
            'text',
3641
            'numeric_calification',
3642
            get_lang('QualificationNumeric'),
3643
            array(
3644
                'value' => $current_thread['thread_qualify_max'],
3645
                'style' => 'width:40px',
3646
            )
3647
        );
3648
        $form->applyFilter('numeric_calification', 'html_filter');
3649
3650
        $form->addElement(
3651
            'text',
3652
            'calification_notebook_title',
3653
            get_lang('TitleColumnGradebook'),
3654
            array('value' => $current_thread['thread_title_qualify'])
3655
        );
3656
        $form->applyFilter('calification_notebook_title', 'html_filter');
3657
3658
        $form->addElement(
3659
            'text',
3660
            'weight_calification',
3661
            array(get_lang('QualifyWeight'), null, ''),
3662
            array(
3663
                'value' => $current_thread['thread_weight'],
3664
                'style' => 'width:40px',
3665
            )
3666
        );
3667
        $form->applyFilter('weight_calification', 'html_filter');
3668
3669
        $group = array();
3670
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
3671
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
3672
        $form->addGroup(
3673
            $group,
3674
            '',
3675
            [
3676
                get_lang('ForumThreadPeerScoring'),
3677
                get_lang('ForumThreadPeerScoringComment'),
3678
            ]
3679
        );
3680
3681
        $form->addElement('html', '</div>');
3682
    }
3683
3684
    if ($current_forum['moderated']) {
3685
        $group = array();
3686
        $group[] = $form->createElement('radio', 'status', null, get_lang('Validated'), 1);
3687
        $group[] = $form->createElement('radio', 'status', null, get_lang('WaitingModeration'), 2);
3688
        $group[] = $form->createElement('radio', 'status', null, get_lang('Rejected'), 3);
3689
        $form->addGroup($group, 'status', get_lang('Status'));
3690
    }
3691
3692
    $defaults['status']['status'] = isset($current_post['status']) && !empty($current_post['status']) ? $current_post['status'] : 2;
3693
3694
    if ($forum_setting['allow_post_notification']) {
3695
        $form->addElement('checkbox', 'post_notification', '', get_lang('NotifyByEmail').' ('.$current_post['email'].')');
3696
    }
3697
3698
    if ($forum_setting['allow_sticky'] &&
3699
        api_is_allowed_to_edit(null, true) &&
3700
        empty($current_post['post_parent_id'])
3701
    ) {
3702
        // The sticky checkbox only appears when it is the first post of a thread.
3703
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3704
        if ($current_thread['thread_sticky'] == 1) {
3705
            $defaults['thread_sticky'] = true;
3706
        }
3707
    }
3708
3709
    $form->addElement('html', '</div>');
3710
3711
    $form->addFile('user_upload[]', get_lang('Attachment'));
3712
    $form->addButton(
3713
        'add_attachment',
3714
        get_lang('AddAttachment'),
3715
        'paperclip',
3716
        'default',
3717
        'default',
3718
        null,
3719
        ['id' => 'reply-add-attachment']
3720
    );
3721
3722
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
3723
3724
    // Setting the default values for the form elements.
3725
    $defaults['post_title'] = $current_post['post_title'];
3726
    $defaults['post_text'] = $current_post['post_text'];
3727
3728
    if ($current_post['post_notification'] == 1) {
3729
        $defaults['post_notification'] = true;
3730
    }
3731
3732
    if (!empty($form_values)) {
3733
        $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
3734
        $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
3735
    }
3736
3737
    $defaults['thread_peer_qualify'] = intval($current_thread['thread_peer_qualify']);
3738
3739
    $form->setDefaults($defaults);
3740
3741
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3742
3743
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3744
3745
    // Validation or display
3746
    if ($form->validate()) {
3747
        $values = $form->exportValues();
3748
3749
        if (isset($values['thread_qualify_gradebook']) && $values['thread_qualify_gradebook'] == '1' &&
3750
            empty($values['weight_calification'])
3751
        ) {
3752
            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...
3753
            return false;
3754
        }
3755
        return $values;
3756
    } else {
3757
        // Delete from $_SESSION forum attachment from other posts
3758
        clearAttachedFiles($current_post['post_id']);
3759
        // Get forum attachment ajax table to add it to form
3760
        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
3761
        $form->addElement('html', $fileData);
3762
        $form->display();
3763
    }
3764
}
3765
3766
/**
3767
 * This function stores the edit of a post in the forum_post table.
3768
 *
3769
 * @param array
3770
 * @return void HTML
3771
 *
3772
 * @author Patrick Cool <[email protected]>, Ghent University
3773
 * @version february 2006, dokeos 1.8
3774
 */
3775
function store_edit_post($forumInfo, $values)
3776
{
3777
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
3778
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3779
    $gradebook = Security::remove_XSS($_GET['gradebook']);
3780
    $course_id = api_get_course_int_id();
3781
3782
    //check if this post is the first of the thread
3783
    // First we check if the change affects the thread and if so we commit
3784
    // the changes (sticky and post_title=thread_title are relevant).
3785
3786
    $posts = getPosts($forumInfo, $values['thread_id']);
3787
    $first_post = null;
3788
    if (!empty($posts) && count($posts) > 0 && isset($posts[0])) {
3789
        $first_post = $posts[0];
3790
    }
3791
3792
    if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
3793
        $params = [
3794
            'thread_title' => $values['post_title'],
3795
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
3796
            'thread_title_qualify' => $values['calification_notebook_title'],
3797
            'thread_qualify_max' => $values['numeric_calification'],
3798
            'thread_weight' => $values['weight_calification'],
3799
            'thread_peer_qualify' => $values['thread_peer_qualify'],
3800
        ];
3801
        $where = ['c_id = ? AND thread_id = ?' => [$course_id, $values['thread_id']]];
3802
3803
        Database::update($threadTable, $params, $where);
3804
    }
3805
3806
    $status = '';
3807
    if ($forumInfo['moderated']) {
3808
        $status = $values['status']['status'];
3809
    }
3810
3811
    // Update the post_title and the post_text.
3812
    $params = [
3813
        'status' => $status,
3814
        'post_title' => $values['post_title'],
3815
        'post_text' => $values['post_text'],
3816
        'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
3817
    ];
3818
    $where = ['c_id = ? AND post_id = ?' => [$course_id, $values['post_id']]];
3819
3820
    Database::update($table_posts, $params, $where);
3821
3822
    // Update attached files
3823 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3824
        foreach ($_POST['file_ids'] as $key => $id) {
3825
            editAttachedFile(
3826
                array(
3827
                    'comment' => $_POST['file_comments'][$key],
3828
                    'post_id' => $values['post_id'],
3829
                ),
3830
                $id
3831
            );
3832
        }
3833
    }
3834
3835
    if (!empty($values['remove_attach'])) {
3836
        delete_attachment($values['post_id']);
3837
    }
3838
3839
    if (empty($values['id_attach'])) {
3840
        add_forum_attachment_file(
3841
            isset($values['file_comment']) ? $values['file_comment'] : null,
3842
            $values['post_id']
3843
        );
3844
    } else {
3845
        edit_forum_attachment_file(
3846
            isset($values['file_comment']) ? $values['file_comment'] : null,
3847
            $values['post_id'],
3848
            $values['id_attach']
3849
        );
3850
    }
3851
3852
    $message = get_lang('EditPostStored').'<br />';
3853
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&">'.get_lang('Forum').'</a><br />';
3854
    $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>';
3855
3856
    Session::erase('formelements');
3857
    Session::erase('origin');
3858
    Session::erase('breadcrumbs');
3859
    Session::erase('addedresource');
3860
    Session::erase('addedresourceid');
3861
3862
    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...
3863
}
3864
3865
/**
3866
 * This function displays the firstname and lastname of the user as a link to the user tool.
3867
 *
3868
 * @param string names
3869
 * @ in_title : title tootip
3870
 * @return string HTML
3871
 *
3872
 * @author Patrick Cool <[email protected]>, Ghent University
3873
 * @version february 2006, dokeos 1.8
3874
 */
3875
function display_user_link($user_id, $name, $origin = '', $in_title = '')
3876
{
3877
    if ($user_id != 0) {
3878
        $userInfo = api_get_user_info($user_id);
3879
3880
        return '<a href="'.$userInfo['profile_url'].'">'.Security::remove_XSS($userInfo['complete_name']).'</a>';
3881
    } else {
3882
        return $name.' ('.get_lang('Anonymous').')';
3883
    }
3884
}
3885
3886
/**
3887
 * This function displays the user image from the profile, with a link to the user's details.
3888
 * @param   int     User's database ID
3889
 * @param   string  User's name
3890
 * @param   string  the origin where the forum is called (example : learnpath)
3891
 * @return  string  An HTML with the anchor and the image of the user
3892
 * @author Julio Montoya <[email protected]>
3893
 */
3894
function display_user_image($user_id, $name, $origin = '')
3895
{
3896
    $userInfo = api_get_user_info($user_id);
3897
3898
    $link = '<a href="'.(!empty($origin) ? '#' : $userInfo['profile_url']).'" '.(!empty($origin) ? 'target="_self"' : '').'>';
3899
3900
    if ($user_id != 0) {
3901
        return $link.'<img src="'.$userInfo['avatar'].'"  alt="'.$name.'"  title="'.$name.'" /></a>';
3902
    } else {
3903
        return $link.Display::return_icon('unknown.jpg', $name).'</a>';
3904
    }
3905
}
3906
3907
/**
3908
 * The thread view counter gets increased every time someone looks at the thread
3909
 *
3910
 * @param int
3911
 * @return void
3912
 *
3913
 * @author Patrick Cool <[email protected]>, Ghent University
3914
 * @version february 2006, dokeos 1.8
3915
 */
3916 View Code Duplication
function increase_thread_view($thread_id)
3917
{
3918
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3919
    $course_id = api_get_course_int_id();
3920
3921
    $sql = "UPDATE $table_threads SET thread_views=thread_views+1
3922
            WHERE 
3923
                c_id = $course_id AND  
3924
                thread_id = '".intval($thread_id)."'";
3925
    Database::query($sql);
3926
}
3927
3928
/**
3929
 * The relies counter gets increased every time somebody replies to the thread
3930
 *
3931
 * @author Patrick Cool <[email protected]>, Ghent University
3932
 * @version february 2006, dokeos 1.8
3933
 * @param string $last_post_id
3934
 * @param string $post_date
3935
 */
3936
function updateThreadInfo($thread_id, $last_post_id, $post_date)
3937
{
3938
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3939
    $course_id = api_get_course_int_id();
3940
    $sql = "UPDATE $table_threads SET 
3941
            thread_replies = thread_replies+1,
3942
            thread_last_post = '".Database::escape_string($last_post_id)."',
3943
            thread_date = '".Database::escape_string($post_date)."'
3944
            WHERE 
3945
                c_id = $course_id AND  
3946
                thread_id='".Database::escape_string($thread_id)."'"; // this needs to be cleaned first
3947
    Database::query($sql);
3948
}
3949
3950
/**
3951
 * This function is called when the user is not allowed in this forum/thread/...
3952
 * @return bool display message of "not allowed"
3953
 *
3954
 * @deprecated use api_not_allowed()
3955
 *
3956
 * @author Patrick Cool <[email protected]>, Ghent University
3957
 * @version february 2006, dokeos 1.8
3958
 */
3959
function forum_not_allowed_here()
3960
{
3961
    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...
3962
    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...
3963
3964
    return false;
3965
}
3966
3967
/**
3968
 * This function is used to find all the information about what's new in the forum tool
3969
 * @return void
3970
 *
3971
 * @author Patrick Cool <[email protected]>, Ghent University
3972
 * @version february 2006, dokeos 1.8
3973
 */
3974
function get_whats_new()
3975
{
3976
    $userId = api_get_user_id();
3977
    $course_id = api_get_course_int_id();
3978
3979
    if (empty($course_id) || empty($userId)) {
3980
        return false;
3981
    }
3982
3983
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3984
    $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
3985
3986
    $tool = TOOL_FORUM;
3987
    $lastForumAccess = Session::read('last_forum_access');
3988
3989
    if (!$lastForumAccess) {
3990
        $sql = "SELECT * FROM $tracking_last_tool_access
3991
                WHERE
3992
                    access_user_id = $userId AND
3993
                    c_id = $course_id AND
3994
                    access_tool = '".Database::escape_string($tool)."'";
3995
        $result = Database::query($sql);
3996
        $row = Database::fetch_array($result);
3997
        Session::write('last_forum_access', $row['access_date']);
3998
        $lastForumAccess = $row['access_date'];
3999
    }
4000
4001
    $whatsNew = Session::read('whatsnew_post_info');
4002
4003
    if (!$whatsNew) {
4004
        if ($lastForumAccess != '') {
4005
            $postInfo = array();
4006
            $sql = "SELECT * FROM $table_posts
4007
                    WHERE
4008
                        c_id = $course_id AND
4009
                        visible = 1 AND                        
4010
                        post_date > '".Database::escape_string($lastForumAccess)."'";
4011
            $result = Database::query($sql);
4012
            while ($row = Database::fetch_array($result)) {
4013
                $postInfo[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
4014
            }
4015
            Session::write('whatsnew_post_info', $postInfo);
4016
        }
4017
    }
4018
}
4019
4020
/**
4021
 * This function approves a post = change
4022
 *
4023
 * @param int $post_id the id of the post that will be deleted
4024
 * @param string $action make the post visible or invisible
4025
 * @return string language variable
4026
 *
4027
 * @author Patrick Cool <[email protected]>, Ghent University
4028
 * @version february 2006, dokeos 1.8
4029
 */
4030
function approve_post($post_id, $action)
4031
{
4032
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4033
    $course_id = api_get_course_int_id();
4034
4035
    if ($action == 'invisible') {
4036
        $visibility_value = 0;
4037
    }
4038
4039
    if ($action == 'visible') {
4040
        $visibility_value = 1;
4041
        handle_mail_cue('post', $post_id);
4042
    }
4043
4044
    $sql = "UPDATE $table_posts SET
4045
            visible='".Database::escape_string($visibility_value)."'
4046
            WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
4047
    $return = Database::query($sql);
4048
4049
    if ($return) {
4050
        return 'PostVisibilityChanged';
4051
    }
4052
}
4053
4054
/**
4055
 * This function retrieves all the unapproved messages for a given forum
4056
 * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
4057
 *
4058
 * @param $forum_id the forum where we want to know the unapproved messages of
4059
 * @return array returns
4060
 *
4061
 * @author Patrick Cool <[email protected]>, Ghent University
4062
 * @version february 2006, dokeos 1.8
4063
 */
4064
function get_unaproved_messages($forum_id)
4065
{
4066
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4067
    $course_id = api_get_course_int_id();
4068
4069
    $return_array = array();
4070
    $sql = "SELECT DISTINCT thread_id FROM $table_posts
4071
            WHERE 
4072
                c_id = $course_id AND 
4073
                forum_id='".Database::escape_string($forum_id)."' AND 
4074
                visible='0' ";
4075
    $result = Database::query($sql);
4076
    while ($row = Database::fetch_array($result)) {
4077
        $return_array[] = $row['thread_id'];
4078
    }
4079
4080
    return $return_array;
4081
}
4082
4083
/**
4084
 * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
4085
 * was added to a given thread.
4086
 *
4087
 * @param array reply information
4088
 * @return void
4089
 *
4090
 * @author Patrick Cool <[email protected]>, Ghent University
4091
 * @version february 2006, dokeos 1.8
4092
 */
4093
function send_notification_mails($forumId, $thread_id, $reply_info)
4094
{
4095
    $table = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
4096
4097
    // First we need to check if
4098
    // 1. the forum category is visible
4099
    // 2. the forum is visible
4100
    // 3. the thread is visible
4101
    // 4. the reply is visible (=when there is)
4102
    $current_thread = get_thread_information($forumId, $thread_id);
4103
    $current_forum = get_forum_information($current_thread['forum_id'], $current_thread['c_id']);
4104
4105
    $current_forum_category = null;
4106
    if (isset($current_forum['forum_category'])) {
4107
        $current_forum_category = get_forumcategory_information(
4108
            $current_forum['forum_category']
4109
        );
4110
    }
4111
4112
    if ($current_thread['visibility'] == '1' &&
4113
        $current_forum['visibility'] == '1' &&
4114
        ($current_forum_category && $current_forum_category['visibility'] == '1') &&
4115
        $current_forum['approval_direct_post'] != '1'
4116
    ) {
4117
        $send_mails = true;
4118
    } else {
4119
        $send_mails = false;
4120
    }
4121
4122
    // The forum category, the forum, the thread and the reply are visible to the user
4123
    if ($send_mails) {
4124
        if (!empty($forumId)) {
4125
            send_notifications($forumId, $thread_id);
4126
        }
4127
    } else {
4128
        $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
4129
        if (isset($current_forum['forum_id'])) {
4130
            $sql = "SELECT * FROM $table_notification
4131
                    WHERE
4132
                        c_id = ".api_get_course_int_id()." AND
4133
                        (
4134
                            forum_id = '".intval($current_forum['forum_id'])."' OR
4135
                            thread_id = '".intval($thread_id)."'
4136
                        ) ";
4137
4138
            $result = Database::query($sql);
4139
            $user_id = api_get_user_id();
4140
            while ($row = Database::fetch_array($result)) {
4141
                $sql = "INSERT INTO $table (c_id, thread_id, post_id, user_id)
4142
                        VALUES (".api_get_course_int_id().", '".intval($thread_id)."', '".intval($reply_info['new_post_id'])."', '$user_id' )";
4143
                Database::query($sql);
4144
            }
4145
        }
4146
    }
4147
}
4148
4149
/**
4150
 * This function is called whenever something is made visible because there might
4151
 * be new posts and the user might have indicated that (s)he wanted to be
4152
 * informed about the new posts by mail.
4153
 *
4154
 * @param string  Content type (post, thread, forum, forum_category)
4155
 * @param int     Item DB ID
4156
 * @param string $content
4157
 * @param integer $id
4158
 * @return string language variable
4159
 * @author Patrick Cool <[email protected]>, Ghent University
4160
 * @version february 2006, dokeos 1.8
4161
 */
4162
function handle_mail_cue($content, $id)
4163
{
4164
    $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
4165
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4166
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4167
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4168
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
4169
4170
    $course_id = api_get_course_int_id();
4171
4172
    /* If the post is made visible we only have to send mails to the people
4173
     who indicated that they wanted to be informed for that thread.*/
4174
    if ($content == 'post') {
4175
        // Getting the information about the post (need the thread_id).
4176
        $post_info = get_post_information($id);
4177
        $thread_id = intval($post_info['thread_id']);
4178
4179
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4180
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4181
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4182
                WHERE
4183
                    posts.c_id = $course_id AND
4184
                    mailcue.c_id = $course_id AND
4185
                    posts.thread_id='$thread_id'
4186
                    AND posts.post_notification='1'
4187
                    AND mailcue.thread_id='$thread_id'
4188
                    AND users.user_id=posts.poster_id
4189
                    AND users.active=1
4190
                GROUP BY users.email";
4191
4192
        $result = Database::query($sql);
4193
        while ($row = Database::fetch_array($result)) {
4194
            send_mail($row, get_thread_information($post_info['forum_id'], $post_info['thread_id']));
4195
        }
4196
    } elseif ($content == 'thread') {
4197
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4198
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email, posts.forum_id
4199
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4200
                WHERE
4201
                    posts.c_id = $course_id AND
4202
                    mailcue.c_id = $course_id AND
4203
                    posts.thread_id = ".intval($id)."
4204
                    AND posts.post_notification='1'
4205
                    AND mailcue.thread_id = ".intval($id)."
4206
                    AND users.user_id=posts.poster_id
4207
                    AND users.active=1
4208
                GROUP BY users.email";
4209
        $result = Database::query($sql);
4210
        while ($row = Database::fetch_array($result)) {
4211
            send_mail($row, get_thread_information($row['forum_id'], $id));
4212
        }
4213
4214
        // Deleting the relevant entries from the mailcue.
4215
        $sql = "DELETE FROM $table_mailcue
4216
                WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
4217
        Database::query($sql);
4218
    } elseif ($content == 'forum') {
4219
        $sql = "SELECT thread_id FROM $table_threads
4220
                WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
4221
        $result = Database::query($sql);
4222
        while ($row = Database::fetch_array($result)) {
4223
            handle_mail_cue('thread', $row['thread_id']);
4224
        }
4225
    } elseif ($content == 'forum_category') {
4226
        $sql = "SELECT forum_id FROM $table_forums
4227
                WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
4228
        $result = Database::query($sql);
4229
        while ($row = Database::fetch_array($result)) {
4230
            handle_mail_cue('forum', $row['forum_id']);
4231
        }
4232
    } else {
4233
        return get_lang('Error');
4234
    }
4235
}
4236
4237
/**
4238
 * This function sends the mails for the mail notification
4239
 *
4240
 * @param array
4241
 * @param array
4242
 * @return void
4243
 *
4244
 * @author Patrick Cool <[email protected]>, Ghent University
4245
 * @version february 2006, dokeos 1.8
4246
 */
4247
function send_mail($user_info = array(), $thread_information = array())
4248
{
4249
    $_course = api_get_course_info();
4250
    $user_id = api_get_user_id();
4251
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
4252 View Code Duplication
    if (isset($thread_information) && is_array($thread_information)) {
4253
        $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$thread_information['forum_id'].'&thread='.$thread_information['thread_id'];
4254
    }
4255
    $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
4256
    $email_body .= get_lang('NewForumPost')."\n";
4257
    $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
4258
    $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
4259
    $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
4260
4261
    if ($user_info['user_id'] <> $user_id) {
4262
        MessageManager::send_message($user_info['user_id'], $subject, $email_body, [], [], null, null, null, null, $user_id);
4263
    }
4264
}
4265
4266
/**
4267
 * This function displays the form for moving a thread to a different (already existing) forum
4268
 * @return void HTML
4269
 *
4270
 * @author Patrick Cool <[email protected]>, Ghent University
4271
 * @version february 2006, dokeos 1.8
4272
 */
4273
function move_thread_form()
4274
{
4275
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4276
    $form = new FormValidator(
4277
        'movepost',
4278
        'post',
4279
        api_get_self().'?forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
4280
    );
4281
    // The header for the form
4282
    $form->addElement('header', get_lang('MoveThread'));
4283
    // Invisible form: the thread_id
4284
    $form->addElement('hidden', 'thread_id', intval($_GET['thread']));
4285
    // the fora
4286
    $forum_categories = get_forum_categories();
4287
    $forums = get_forums();
4288
4289
    $htmlcontent = '<div class="row">
4290
        <div class="label">
4291
            <span class="form_required">*</span>'.get_lang('MoveTo').'
4292
        </div>
4293
        <div class="formw">';
4294
    $htmlcontent .= '<select name="forum">';
4295
    foreach ($forum_categories as $key => $category) {
4296
        $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
4297
        foreach ($forums as $key => $forum) {
4298
            if (isset($forum['forum_category'])) {
4299
                if ($forum['forum_category'] == $category['cat_id']) {
4300
                    $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
4301
                }
4302
            }
4303
        }
4304
        $htmlcontent .= '</optgroup>';
4305
    }
4306
    $htmlcontent .= "</select>";
4307
    $htmlcontent .= '   </div>
4308
                    </div>';
4309
4310
    $form->addElement('html', $htmlcontent);
4311
4312
    // The OK button
4313
    $form->addButtonSave(get_lang('MoveThread'), 'SubmitForum');
4314
4315
    // Validation or display
4316
    if ($form->validate()) {
4317
        $values = $form->exportValues();
4318
        if (isset($_POST['forum'])) {
4319
            store_move_thread($values);
4320
        }
4321
    } else {
4322
        $form->display();
4323
    }
4324
}
4325
4326
/**
4327
 * This function displays the form for moving a post message to a different (already existing) or a new thread.
4328
 * @return void HTML
4329
 *
4330
 * @author Patrick Cool <[email protected]>, Ghent University
4331
 * @version february 2006, dokeos 1.8
4332
 */
4333
function move_post_form()
4334
{
4335
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4336
    // initiate the object
4337
    $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']));
4338
    // The header for the form
4339
    $form->addElement('header', '', get_lang('MovePost'));
4340
4341
    // Invisible form: the post_id
4342
    $form->addElement('hidden', 'post_id', intval($_GET['post']));
4343
4344
    // Dropdown list: Threads of this forum
4345
    $threads = get_threads($_GET['forum']);
4346
    //my_print_r($threads);
4347
    $threads_list[0] = get_lang('ANewThread');
4348
    foreach ($threads as $key => $value) {
4349
        $threads_list[$value['thread_id']] = $value['thread_title'];
4350
    }
4351
    $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
4352
    $form->applyFilter('thread', 'html_filter');
4353
4354
    // The OK button
4355
    $form->addButtonSave(get_lang('MovePost'), 'submit');
4356
4357
    // Setting the rules
4358
    $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
4359
4360
    // Validation or display
4361
    if ($form->validate()) {
4362
        $values = $form->exportValues();
4363
        store_move_post($values);
4364
    } else {
4365
        $form->display();
4366
    }
4367
}
4368
4369
/**
4370
 *
4371
 * @param array
4372
 * @return string HTML language variable
4373
 *
4374
 * @author Patrick Cool <[email protected]>, Ghent University
4375
 * @version february 2006, dokeos 1.8
4376
 */
4377
function store_move_post($values)
4378
{
4379
    $_course = api_get_course_info();
4380
    $course_id = api_get_course_int_id();
4381
4382
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4383
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4384
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4385
4386
    if ($values['thread'] == '0') {
4387
        $current_post = get_post_information($values['post_id']);
4388
4389
        // Storing a new thread.
4390
        $params = [
4391
            'c_id' => $course_id,
4392
            'thread_title' => $current_post['post_title'],
4393
            'forum_id' => $current_post['forum_id'],
4394
            'thread_poster_id' => $current_post['poster_id'],
4395
            'thread_poster_name' => $current_post['poster_name'],
4396
            'thread_last_post' => $values['post_id'],
4397
            'thread_date' => $current_post['post_date'],
4398
        ];
4399
4400
        $new_thread_id = Database::insert($table_threads, $params);
4401
4402
        api_item_property_update(
4403
            $_course,
4404
            TOOL_FORUM_THREAD,
4405
            $new_thread_id,
4406
            'visible',
4407
            $current_post['poster_id']
4408
        );
4409
4410
        // Moving the post to the newly created thread.
4411
        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
4412
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4413
        Database::query($sql);
4414
4415
        // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
4416
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4417
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4418
        Database::query($sql);
4419
4420
        // Updating updating the number of threads in the forum.
4421
        $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
4422
                WHERE c_id = $course_id AND forum_id='".intval($current_post['forum_id'])."'";
4423
        Database::query($sql);
4424
4425
        // Resetting the last post of the old thread and decreasing the number of replies and the thread.
4426
        $sql = "SELECT * FROM $table_posts
4427
                WHERE c_id = $course_id AND thread_id='".intval($current_post['thread_id'])."'
4428
                ORDER BY post_id DESC";
4429
        $result = Database::query($sql);
4430
        $row = Database::fetch_array($result);
4431
        $sql = "UPDATE $table_threads SET
4432
                    thread_last_post='".$row['post_id']."',
4433
                    thread_replies=thread_replies-1
4434
                WHERE
4435
                    c_id = $course_id AND
4436
                    thread_id='".intval($current_post['thread_id'])."'";
4437
        Database::query($sql);
4438
    } else {
4439
        // Moving to the chosen thread.
4440
        $sql = "SELECT thread_id FROM ".$table_posts."
4441
                WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
4442
        $result = Database::query($sql);
4443
        $row = Database::fetch_array($result);
4444
4445
        $original_thread_id = $row['thread_id'];
4446
4447
        $sql = "SELECT thread_last_post FROM ".$table_threads."
4448
                WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4449
4450
        $result = Database::query($sql);
4451
        $row = Database::fetch_array($result);
4452
        $thread_is_last_post = $row['thread_last_post'];
4453
        // If is this thread, update the thread_last_post with the last one.
4454
4455
        if ($thread_is_last_post == $values['post_id']) {
4456
            $sql = "SELECT post_id FROM ".$table_posts."
4457
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."'
4458
                    ORDER BY post_date DESC LIMIT 1";
4459
            $result = Database::query($sql);
4460
4461
            $row = Database::fetch_array($result);
4462
            $thread_new_last_post = $row['post_id'];
4463
4464
            $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."'
4465
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4466
            Database::query($sql);
4467
        }
4468
4469
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
4470
                WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
4471
        Database::query($sql);
4472
4473
        // moving to the chosen thread
4474
        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
4475
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4476
        Database::query($sql);
4477
4478
        // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
4479
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4480
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4481
        Database::query($sql);
4482
4483
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
4484
                WHERE c_id = $course_id AND thread_id='".intval($_POST['thread'])."'";
4485
        Database::query($sql);
4486
    }
4487
4488
    return get_lang('ThreadMoved');
4489
}
4490
4491
/**
4492
 *
4493
 * @param array
4494
 * @return string HTML language variable
4495
 *
4496
 * @author Patrick Cool <[email protected]>, Ghent University
4497
 * @version february 2006, dokeos 1.8
4498
 */
4499
function store_move_thread($values)
4500
{
4501
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4502
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4503
4504
    $courseId = api_get_course_int_id();
4505
    $sessionId = api_get_session_id();
4506
4507
    $forumId = intval($_POST['forum']);
4508
    $threadId = intval($_POST['thread_id']);
4509
    $forumInfo = get_forums($forumId);
4510
4511
    // Change the thread table: Setting the forum_id to the new forum.
4512
    $sql = "UPDATE $table_threads SET forum_id = $forumId
4513
            WHERE c_id = $courseId AND thread_id = $threadId";
4514
    Database::query($sql);
4515
4516
    // Changing all the posts of the thread: setting the forum_id to the new forum.
4517
    $sql = "UPDATE $table_posts SET forum_id = $forumId
4518
            WHERE c_id = $courseId AND thread_id= $threadId";
4519
    Database::query($sql);
4520
    // Fix group id, if forum is moved to a different group
4521
    if (!empty($forumInfo['to_group_id'])) {
4522
        $groupId = $forumInfo['to_group_id'];
4523
        $item = api_get_item_property_info($courseId, TABLE_FORUM_THREAD, $threadId, $sessionId, $groupId);
4524
        $table = Database:: get_course_table(TABLE_ITEM_PROPERTY);
4525
        $sessionCondition = api_get_session_condition($sessionId);
4526
4527
        if (!empty($item)) {
4528
            if ($item['to_group_id'] != $groupId) {
4529
                $sql = "UPDATE $table
4530
                    SET to_group_id = $groupId
4531
                    WHERE
4532
                      tool = '".TABLE_FORUM_THREAD."' AND
4533
                      c_id = $courseId AND
4534
                      ref = ".$item['ref']."
4535
                      $sessionCondition
4536
                ";
4537
                Database::query($sql);
4538
            }
4539
        } else {
4540
            $sql = "UPDATE $table
4541
                    SET to_group_id = $groupId
4542
                    WHERE
4543
                      tool = '".TABLE_FORUM_THREAD."' AND
4544
                      c_id = $courseId AND
4545
                      ref = ".$threadId."
4546
                      $sessionCondition
4547
            ";
4548
            Database::query($sql);
4549
        }
4550
    }
4551
4552
    return get_lang('ThreadMoved');
4553
}
4554
4555
/**
4556
 * Prepares a string for displaying by highlighting the search results inside, if any.
4557
 * @param string $input    The input string.
4558
 * @return string          The same string with highlighted hits inside.
4559
 *
4560
 * @author Patrick Cool <[email protected]>, Ghent University, February 2006 - the initial version.
4561
 * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
4562
 */
4563
function prepare4display($input)
4564
{
4565
    static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
4566
    static $search;
4567
4568
    if (!isset($search)) {
4569
        if (isset($_POST['search_term'])) {
4570
            $search = $_POST['search_term']; // No html at all.
4571
        } elseif (isset($_GET['search'])) {
4572
            $search = $_GET['search'];
4573
        } else {
4574
            $search = '';
4575
        }
4576
    }
4577
4578
    if (!empty($search)) {
4579
        if (strstr($search, '+')) {
4580
            $search_terms = explode('+', $search);
4581
        } else {
4582
            $search_terms[] = trim($search);
4583
        }
4584
        $counter = 0;
4585
        foreach ($search_terms as $key => $search_term) {
4586
            $input = api_preg_replace('/'.preg_quote(trim($search_term), '/').'/i', '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>', $input);
4587
            $counter++;
4588
        }
4589
    }
4590
4591
    // TODO: Security should be implemented outside this function.
4592
    // 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).
4593
4594
    return Security::remove_XSS($input, STUDENT, true);
4595
}
4596
4597
/**
4598
 * Display the search form for the forum and display the search results
4599
 * @return void display an HTML search results
4600
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4601
 * @version march 2008, dokeos 1.8.5
4602
 */
4603
function forum_search()
4604
{
4605
    $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?'.api_get_cidreq());
4606
4607
    // Setting the form elements.
4608
    $form->addElement('header', '', get_lang('ForumSearch'));
4609
    $form->addElement('text', 'search_term', get_lang('SearchTerm'), array('autofocus'));
4610
    $form->applyFilter('search_term', 'html_filter');
4611
    $form->addElement('static', 'search_information', '', get_lang('ForumSearchInformation'));
4612
    $form->addButtonSearch(get_lang('Search'));
4613
4614
    // Setting the rules.
4615
    $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
4616
    $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
4617
4618
    // Validation or display.
4619
    if ($form->validate()) {
4620
        $values = $form->exportValues();
4621
        $form->setDefaults($values);
4622
        $form->display();
4623
        // Display the search results.
4624
        display_forum_search_results(stripslashes($values['search_term']));
4625
    } else {
4626
        $form->display();
4627
    }
4628
}
4629
4630
/**
4631
 * Display the search results
4632
 * @param string
4633
 * @param string $search_term
4634
 * @return void display the results
4635
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4636
 * @version march 2008, dokeos 1.8.5
4637
 */
4638
function display_forum_search_results($search_term)
4639
{
4640
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4641
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4642
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
4643
    $session_id = api_get_session_id();
4644
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4645
    $course_id = api_get_course_int_id();
4646
4647
    // Defining the search strings as an array.
4648
    if (strstr($search_term, '+')) {
4649
        $search_terms = explode('+', $search_term);
4650
    } else {
4651
        $search_terms[] = $search_term;
4652
    }
4653
4654
    // Search restriction.
4655
    foreach ($search_terms as $value) {
4656
        $search_restriction[] = "
4657
        (
4658
            posts.post_title LIKE '%".Database::escape_string(trim($value))."%' OR 
4659
            posts.post_text LIKE '%".Database::escape_string(trim($value))."%' 
4660
        )";
4661
    }
4662
4663
    $sessionCondition = api_get_session_condition($session_id, true, false, 'item_property.session_id');
4664
4665
    $sql = "SELECT posts.*
4666
            FROM $table_posts posts INNER JOIN $table_threads threads
4667
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
4668
            INNER JOIN $table_item_property item_property
4669
            ON (item_property.ref = threads.thread_id AND item_property.c_id = threads.c_id)
4670
            WHERE
4671
                posts.c_id = $course_id AND 
4672
                item_property.c_id = $course_id AND 
4673
                item_property.visibility = 1  
4674
                $sessionCondition AND
4675
                posts.visible = 1 AND 
4676
                item_property.tool = '".TOOL_FORUM_THREAD."' AND 
4677
                ".implode(' AND ', $search_restriction)."
4678
            GROUP BY posts.post_id";
4679
4680
    // Getting all the information of the forum categories.
4681
    $forum_categories_list = get_forum_categories();
4682
4683
    // Getting all the information of the forums.
4684
    $forum_list = get_forums();
4685
4686
    $result = Database::query($sql);
4687
    $search_results = [];
4688
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4689
        $forumId = $row['forum_id'];
4690
        $forumData = get_forums($forumId);
4691
        $category = isset($forum_categories_list[$forumData['forum_category']]) ? $forum_categories_list[$forumData['forum_category']] : null;
4692
        $display_result = false;
4693
        /*
4694
          We only show it when
4695
          1. forum category is visible
4696
          2. forum is visible
4697
          3. thread is visible (to do)
4698
          4. post is visible
4699
         */
4700
        if (!api_is_allowed_to_edit(null, true)) {
4701
            if (!empty($category)) {
4702
                if ($category['visibility'] == '1' && $forumData['visibility'] == '1') {
4703
                    $display_result = true;
4704
                }
4705
            } else {
4706
                if ($forumData['visible'] == '1') {
4707
                    $display_result = true;
4708
                }
4709
            }
4710
        } else {
4711
            $display_result = true;
4712
        }
4713
4714
        if ($display_result) {
4715
            $categoryName = !empty($category) ? $category['cat_title'] : '';
4716
            $search_results_item = '<li><a href="viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.$forumData['forum_category'].'&search='.urlencode($search_term).'">'.
4717
                prepare4display($categoryName).'</a> &gt; ';
4718
            $search_results_item .= '<a href="viewforum.php?'.api_get_cidreq().'&forum='.$forumId.'&search='.urlencode($search_term).'">'.
4719
                prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
4720
            $search_results_item .= '<a href="viewthread.php?'.api_get_cidreq().'&forum='.$forumId.'&gradebook='.$gradebook.'&thread='.$row['thread_id'].'&search='.urlencode($search_term).'">'.
4721
                prepare4display($row['post_title']).'</a>';
4722
            $search_results_item .= '<br />';
4723
            if (api_strlen($row['post_title']) > 200) {
4724
                $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...
4725
            } else {
4726
                $search_results_item .= prepare4display($row['post_title']);
4727
            }
4728
            $search_results_item .= '</li>';
4729
            $search_results[] = $search_results_item;
4730
        }
4731
    }
4732
    echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
4733
    echo '<ol>';
4734
    if ($search_results) {
4735
        echo implode($search_results);
4736
    }
4737
    echo '</ol>';
4738
}
4739
4740
/**
4741
 * Return the link to the forum search page
4742
 *
4743
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4744
 * @version April 2008, dokeos 1.8.5
4745
 */
4746
function search_link()
4747
{
4748
    $return = '';
4749
    $origin = api_get_origin();
4750
    if ($origin != 'learnpath') {
4751
        $return = '<a href="forumsearch.php?'.api_get_cidreq().'&action=search"> ';
4752
        $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
4753
4754
        if (!empty($_GET['search'])) {
4755
            $return .= ': '.Security::remove_XSS($_GET['search']).' ';
4756
            $url = api_get_self().'?';
4757
            $url_parameter = array();
4758
            foreach ($_GET as $key => $value) {
4759
                if ($key != 'search') {
4760
                    $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
4761
                }
4762
            }
4763
            $url = $url.implode('&', $url_parameter);
4764
            $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
4765
        }
4766
    }
4767
4768
    return $return;
4769
}
4770
4771
/**
4772
 * This function adds an attachment file into a forum
4773
 * @param string $file_comment  a comment about file
4774
 * @param int $last_id from forum_post table
4775
 * @return false|null
4776
 */
4777
function add_forum_attachment_file($file_comment, $last_id)
4778
{
4779
    $_course = api_get_course_info();
4780
    $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4781
4782
    if (!isset($_FILES['user_upload'])) {
4783
        return false;
4784
    }
4785
4786
    $fileCount = count($_FILES['user_upload']['name']);
4787
    $filesData = [];
4788
4789 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4790
        $filesData[] = $_FILES['user_upload'];
4791
    } else {
4792
        $fileKeys = array_keys($_FILES['user_upload']);
4793
        for ($i = 0; $i < $fileCount; $i++) {
4794
            foreach ($fileKeys as $key) {
4795
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4796
            }
4797
        }
4798
    }
4799
4800
    foreach ($filesData as $attachment) {
4801
        if (empty($attachment['name'])) {
4802
            continue;
4803
        }
4804
4805
        $upload_ok = process_uploaded_file($attachment);
4806
4807
        if (!$upload_ok) {
4808
            continue;
4809
        }
4810
4811
        $course_dir = $_course['path'] . '/upload/forum';
4812
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4813
        $updir = $sys_course_path . $course_dir;
4814
4815
        // Try to add an extension to the file if it hasn't one.
4816
        $new_file_name = add_ext_on_mime(
4817
            stripslashes($attachment['name']),
4818
            $attachment['type']
4819
        );
4820
        // User's file name
4821
        $file_name = $attachment['name'];
4822
4823
        if (!filter_extension($new_file_name)) {
4824
            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...
4825
4826
            return;
4827
        }
4828
4829
        $new_file_name = uniqid('');
4830
        $new_path = $updir . '/' . $new_file_name;
4831
        $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4832
        $safe_file_comment = Database::escape_string($file_comment);
4833
        $safe_file_name = Database::escape_string($file_name);
4834
        $safe_new_file_name = Database::escape_string($new_file_name);
4835
        $last_id = intval($last_id);
4836
        // Storing the attachments if any.
4837
        if (!$result) {
4838
            return;
4839
        }
4840
4841
        $last_id_file = Database::insert(
4842
            $agenda_forum_attachment,
4843
            [
4844
                'c_id' => api_get_course_int_id(),
4845
                'filename' => $safe_file_name,
4846
                'comment' => $safe_file_comment,
4847
                'path' => $safe_new_file_name,
4848
                'post_id' => $last_id,
4849
                'size' => intval($attachment['size']),
4850
            ]
4851
        );
4852
4853
        api_item_property_update(
4854
            $_course,
4855
            TOOL_FORUM_ATTACH,
4856
            $last_id_file,
4857
            'ForumAttachmentAdded',
4858
            api_get_user_id()
4859
        );
4860
    }
4861
}
4862
4863
/**
4864
 * This function edits an attachment file into a forum
4865
 * @param string $file_comment  a comment about file
4866
 * @param int $post_id
4867
 * @param int $id_attach attachment file Id
4868
 * @return void
4869
 */
4870
function edit_forum_attachment_file($file_comment, $post_id, $id_attach)
4871
{
4872
    $_course = api_get_course_info();
4873
    $table_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4874
    $course_id = api_get_course_int_id();
4875
4876
    $fileCount = count($_FILES['user_upload']['name']);
4877
    $filesData = [];
4878
4879 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4880
        $filesData[] = $_FILES['user_upload'];
4881
    } else {
4882
        $fileKeys = array_keys($_FILES['user_upload']);
4883
4884
        for ($i = 0; $i < $fileCount; $i++) {
4885
            foreach ($fileKeys as $key) {
4886
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4887
            }
4888
        }
4889
    }
4890
4891
    foreach ($filesData as $attachment) {
4892
        if (empty($attachment['name'])) {
4893
            continue;
4894
        }
4895
4896
        $upload_ok = process_uploaded_file($attachment);
4897
4898
        if (!$upload_ok) {
4899
            continue;
4900
        }
4901
4902
        $course_dir = $_course['path'].'/upload/forum';
4903
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4904
        $updir = $sys_course_path.$course_dir;
4905
4906
        // Try to add an extension to the file if it hasn't one.
4907
        $new_file_name = add_ext_on_mime(stripslashes($attachment['name']), $attachment['type']);
4908
        // User's file name
4909
        $file_name = $attachment['name'];
4910
4911
        if (!filter_extension($new_file_name)) {
4912
            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...
4913
        } else {
4914
            $new_file_name = uniqid('');
4915
            $new_path = $updir.'/'.$new_file_name;
4916
            $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4917
            $safe_file_comment = Database::escape_string($file_comment);
4918
            $safe_file_name = Database::escape_string($file_name);
4919
            $safe_new_file_name = Database::escape_string($new_file_name);
4920
            $safe_post_id = (int) $post_id;
4921
            $safe_id_attach = (int) $id_attach;
4922
            // Storing the attachments if any.
4923 View Code Duplication
            if ($result) {
4924
                $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']."'
4925
                       WHERE c_id = $course_id AND id = '$safe_id_attach'";
4926
                Database::query($sql);
4927
                api_item_property_update($_course, TOOL_FORUM_ATTACH, $safe_id_attach, 'ForumAttachmentUpdated', api_get_user_id());
4928
            }
4929
        }
4930
    }
4931
}
4932
4933
/**
4934
 * Show a list with all the attachments according to the post's id
4935
 * @param int $post_id
4936
 * @return array with the post info
4937
 * @author Julio Montoya
4938
 * @version avril 2008, dokeos 1.8.5
4939
 */
4940
function get_attachment($post_id)
4941
{
4942
    $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4943
    $course_id = api_get_course_int_id();
4944
    $row = array();
4945
    $post_id = intval($post_id);
4946
    $sql = "SELECT iid, path, filename, comment 
4947
            FROM $forum_table_attachment
4948
            WHERE c_id = $course_id AND post_id = $post_id";
4949
    $result = Database::query($sql);
4950
    if (Database::num_rows($result) != 0) {
4951
        $row = Database::fetch_array($result);
4952
    }
4953
4954
    return $row;
4955
}
4956
4957
/**
4958
 * @param int $postId
4959
 *
4960
 * @return array
4961
 */
4962
function getAllAttachment($postId)
4963
{
4964
    $forumAttachmentTable = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4965
    $courseId = api_get_course_int_id();
4966
    $postId = intval($postId);
4967
    $columns = array('iid', 'path', 'filename', 'comment');
4968
    $conditions = array(
4969
        'where' => array(
4970
            'c_id = ? AND post_id = ?' => array($courseId, $postId),
4971
        ),
4972
    );
4973
    $array = Database::select(
4974
        $columns,
4975
        $forumAttachmentTable,
4976
        $conditions,
4977
        'all',
4978
        'ASSOC'
4979
    );
4980
4981
    return $array;
4982
}
4983
4984
/**
4985
 * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
4986
 * @param int $post_id
4987
 * @param int $id_attach
4988
 * @param bool $display to show or not result message
4989
 * @return integer
4990
 * @author Julio Montoya
4991
 * @version october 2014, chamilo 1.9.8
4992
 */
4993
function delete_attachment($post_id, $id_attach = 0, $display = true)
4994
{
4995
    $_course = api_get_course_info();
4996
4997
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4998
    $course_id = api_get_course_int_id();
4999
5000
    $cond = (!empty($id_attach)) ? " iid = " . (int) $id_attach . "" : " post_id = " . (int) $post_id . "";
5001
    $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
5002
    $res = Database::query($sql);
5003
    $row = Database::fetch_array($res);
5004
5005
    $course_dir = $_course['path'] . '/upload/forum';
5006
    $sys_course_path = api_get_path(SYS_COURSE_PATH);
5007
    $updir = $sys_course_path . $course_dir;
5008
    $my_path = isset($row['path']) ? $row['path'] : null;
5009
    $file = $updir . '/' . $my_path;
5010
    if (Security::check_abs_path($file, $updir)) {
5011
        @unlink($file);
5012
    }
5013
5014
    // Delete from forum_attachment table.
5015
    $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
5016
    $result = Database::query($sql);
5017
    if ($result !== false) {
5018
        $affectedRows = Database::affected_rows($result);
5019
    } else {
5020
        $affectedRows = 0;
5021
    }
5022
5023
    // Update item_property.
5024
    api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
5025
5026
    if (!empty($result) && !empty($id_attach) && $display) {
5027
        $message = get_lang('AttachmentFileDeleteSuccess');
5028
        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...
5029
    }
5030
5031
    return $affectedRows;
5032
}
5033
5034
/**
5035
 * This function gets all the forum information of the all the forum of the group
5036
 *
5037
 * @param integer $groupId the id of the group we need the fora of (see forum.forum_of_group)
5038
 * @return array
5039
 *
5040
 * @todo this is basically the same code as the get_forums function. Consider merging the two.
5041
 */
5042
function get_forums_of_group($groupId)
5043
{
5044
    $table_forums = Database :: get_course_table(TABLE_FORUM);
5045
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
5046
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5047
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
5048
    $course_id = api_get_course_int_id();
5049
    $groupId = (int) $groupId;
5050
5051
    // Student
5052
    // Select all the forum information of all forums (that are visible to students).
5053
5054
    $sql = "SELECT * FROM $table_forums forum 
5055
            INNER JOIN $table_item_property item_properties
5056
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
5057
            WHERE
5058
                forum.forum_of_group = $groupId AND
5059
                forum.c_id = $course_id AND
5060
                item_properties.c_id = $course_id AND                
5061
                item_properties.visibility = 1 AND
5062
                item_properties.tool = '".TOOL_FORUM."'
5063
            ORDER BY forum.forum_order ASC";
5064
5065
    // Select the number of threads of the forums (only the threads that are visible).
5066
    $sql2 = "SELECT 
5067
                count(thread_id) AS number_of_threads, 
5068
                threads.forum_id
5069
            FROM $table_threads threads 
5070
            INNER JOIN $table_item_property item_properties
5071
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
5072
            WHERE                
5073
                threads.c_id = $course_id AND
5074
                item_properties.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
    // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
5080
    $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id
5081
            FROM $table_posts posts 
5082
            INNER JOIN $table_threads threads 
5083
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
5084
            INNER JOIN $table_item_property item_properties
5085
            ON (threads.thread_id = item_properties.ref AND item_properties.c_id = threads.c_id)
5086
            WHERE 
5087
                posts.visible=1 AND
5088
                posts.c_id = $course_id AND
5089
                item_properties.c_id = $course_id AND
5090
                threads.c_id = $course_id AND 
5091
                item_properties.visibility = 1 AND 
5092
                item_properties.tool='".TOOL_FORUM_THREAD."'
5093
            GROUP BY threads.forum_id";
5094
5095
    // Course Admin
5096 View Code Duplication
    if (api_is_allowed_to_edit()) {
5097
        // Select all the forum information of all forums (that are not deleted).
5098
        $sql = "SELECT *
5099
                FROM $table_forums forum INNER JOIN $table_item_property item_properties
5100
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
5101
                WHERE
5102
                    forum.forum_of_group = $groupId AND
5103
                    forum.c_id = $course_id AND
5104
                    item_properties.c_id = $course_id AND                    
5105
                    item_properties.visibility <> 2 AND
5106
                    item_properties.tool = '".TOOL_FORUM."'
5107
                ORDER BY forum_order ASC";
5108
5109
        // Select the number of threads of the forums (only the threads that are not deleted).
5110
        $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
5111
                 FROM $table_threads threads INNER JOIN $table_item_property item_properties
5112
                 ON (threads.thread_id=item_properties.ref AND item_properties.c_id = threads.c_id)
5113
                 WHERE
5114
                    threads.c_id = $course_id AND
5115
                    item_properties.c_id = $course_id AND
5116
                    item_properties.visibility <> 2 AND
5117
                    item_properties.tool='".TOOL_FORUM_THREAD."'
5118
                GROUP BY threads.forum_id";
5119
        // Select the number of posts of the forum.
5120
        $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id
5121
                FROM $table_posts
5122
                WHERE c_id = $course_id 
5123
                GROUP BY forum_id";
5124
    }
5125
5126
    // Handling all the forum information.
5127
    $result = Database::query($sql);
5128
    $forum_list = array();
5129
    while ($row = Database::fetch_array($result, 'ASSOC')) {
5130
        $forum_list[$row['forum_id']] = $row;
5131
    }
5132
5133
    // Handling the thread count information.
5134
    $result2 = Database::query($sql2);
5135 View Code Duplication
    while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
5136
        if (is_array($forum_list)) {
5137
            if (array_key_exists($row2['forum_id'], $forum_list)) {
5138
                $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
5139
            }
5140
        }
5141
    }
5142
5143
    // Handling the post count information.
5144
    $result3 = Database::query($sql3);
5145 View Code Duplication
    while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
5146
        if (is_array($forum_list)) {
5147
            if (array_key_exists($row3['forum_id'], $forum_list)) {
5148
                // This is needed because sql3 takes also the deleted forums into account.
5149
                $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
5150
            }
5151
        }
5152
    }
5153
5154
    // Finding the last post information
5155
    // (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
5156
    if (!empty($forum_list)) {
5157 View Code Duplication
        foreach ($forum_list as $key => $value) {
5158
            $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit());
5159
            if ($last_post_info_of_forum) {
5160
                $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
5161
                $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
5162
                $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
5163
                $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
5164
                $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
5165
                $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
5166
            }
5167
        }
5168
    }
5169
5170
    return $forum_list;
5171
}
5172
5173
/**
5174
 * This function stores which users have to be notified of which forums or threads
5175
 *
5176
 * @param string $content does the user want to be notified about a forum or about a thread
5177
 * @param integer $id the id of the forum or thread
5178
 * @return string language variable
5179
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5180
 * @version May 2008, dokeos 1.8.5
5181
 * @since May 2008, dokeos 1.8.5
5182
 */
5183
function set_notification($content, $id, $add_only = false)
5184
{
5185
    $_user = api_get_user_info();
5186
5187
    // Database table definition
5188
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5189
5190
    $course_id = api_get_course_int_id();
5191
5192
    // Which database field do we have to store the id in?
5193
    if ($content == 'forum') {
5194
        $database_field = 'forum_id';
5195
    } else {
5196
        $database_field = 'thread_id';
5197
    }
5198
5199
    // First we check if the notification is already set for this.
5200
    $sql = "SELECT * FROM $table_notification
5201
            WHERE
5202
                c_id = $course_id AND
5203
                $database_field = '".Database::escape_string($id)."' AND
5204
                user_id = '".intval($_user['user_id'])."'";
5205
    $result = Database::query($sql);
5206
    $total = Database::num_rows($result);
5207
5208
    // If the user did not indicate that (s)he wanted to be notified already
5209
    // then we store the notification request (to prevent double notification requests).
5210
    if ($total <= 0) {
5211
        $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id)
5212
                VALUES (".$course_id.", '".Database::escape_string($id)."','".intval($_user['user_id'])."')";
5213
        Database::query($sql);
5214
        Session::erase('forum_notification');
5215
        get_notifications_of_user(0, true);
5216
5217
        return get_lang('YouWillBeNotifiedOfNewPosts');
5218
    } else {
5219
        if (!$add_only) {
5220
            $sql = "DELETE FROM $table_notification
5221
                    WHERE
5222
                        c_id = $course_id AND
5223
                        $database_field = '".Database::escape_string($id)."' AND
5224
                        user_id = '".intval($_user['user_id'])."'";
5225
            Database::query($sql);
5226
            Session::erase('forum_notification');
5227
            get_notifications_of_user(0, true);
5228
5229
            return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
5230
        }
5231
    }
5232
}
5233
5234
/**
5235
 * This function retrieves all the email adresses of the users who wanted to be notified
5236
 * about a new post in a certain forum or thread
5237
 *
5238
 * @param string $content does the user want to be notified about a forum or about a thread
5239
 * @param integer $id the id of the forum or thread
5240
 * @return array returns
5241
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5242
 * @version May 2008, dokeos 1.8.5
5243
 * @since May 2008, dokeos 1.8.5
5244
 */
5245
function get_notifications($content, $id)
5246
{
5247
    // Database table definition
5248
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5249
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5250
5251
    $course_id = api_get_course_int_id();
5252
5253
    // Which database field contains the notification?
5254
    if ($content == 'forum') {
5255
        $database_field = 'forum_id';
5256
    } else {
5257
        $database_field = 'thread_id';
5258
    }
5259
5260
    $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
5261
            FROM $table_users user, $table_notification notification
5262
            WHERE notification.c_id = $course_id AND user.active = 1 AND
5263
            user.user_id = notification.user_id AND
5264
            notification.$database_field= '".Database::escape_string($id)."'";
5265
5266
    $result = Database::query($sql);
5267
    $return = array();
5268
5269
    while ($row = Database::fetch_array($result)) {
5270
        $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
5271
    }
5272
5273
    return $return;
5274
}
5275
5276
/**
5277
 * Get all the users who need to receive a notification of a new post (those subscribed to
5278
 * the forum or the thread)
5279
 *
5280
 * @param integer $forum_id the id of the forum
5281
 * @param integer $thread_id the id of the thread
5282
 * @param integer $post_id the id of the post
5283
 * @return false|null
5284
 *
5285
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5286
 * @version May 2008, dokeos 1.8.5
5287
 * @since May 2008, dokeos 1.8.5
5288
 */
5289
function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
5290
{
5291
    $_course = api_get_course_info();
5292
    $forum_id = (int) $forum_id;
5293
5294
    // The content of the mail
5295
    $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forum_id.'&thread='.$thread_id;
5296
5297
    // Users who subscribed to the forum
5298
    if ($forum_id != 0) {
5299
        $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
5300
    } else {
5301
        return false;
5302
    }
5303
5304
    $current_thread = get_thread_information($forum_id, $thread_id);
5305
    $current_forum = get_forum_information($current_thread['forum_id']);
5306
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
5307
5308
    // User who subscribed to the thread
5309
    if ($thread_id != 0) {
5310
        $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
5311
    }
5312
5313
    // Merging the two
5314
    $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
5315
    $sender_id = api_get_user_id();
5316
5317
    if (is_array($users_to_be_notified)) {
5318
        foreach ($users_to_be_notified as $value) {
5319
5320
            $user_info = api_get_user_info($value['user_id']);
5321
            $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
5322
            $email_body .= get_lang('NewForumPost').": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
5323
            $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."]  <br />\n";
5324
            $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
5325
            $email_body .= get_lang('ThreadCanBeFoundHere').': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
5326
5327
            MessageManager::send_message_simple(
5328
                $value['user_id'], $subject, $email_body, $sender_id
5329
            );
5330
        }
5331
    }
5332
}
5333
5334
/**
5335
 * Get all the notification subscriptions of the user
5336
 * = which forums and which threads does the user wants to be informed of when a new
5337
 * post is added to this thread
5338
 *
5339
 * @param integer $user_id the user_id of a user (default = 0 => the current user)
5340
 * @param boolean $force force get the notification subscriptions (even if the information is already in the session
5341
 * @return array returns
5342
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5343
 * @version May 2008, dokeos 1.8.5
5344
 * @since May 2008, dokeos 1.8.5
5345
 */
5346
function get_notifications_of_user($user_id = 0, $force = false)
5347
{
5348
    // Database table definition
5349
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5350
    $course_id = api_get_course_int_id();
5351
    if (empty($course_id) || $course_id == -1) {
5352
        return null;
5353
    }
5354
    if ($user_id == 0) {
5355
        $user_id = api_get_user_id();
5356
    }
5357
5358
    if (!isset($_SESSION['forum_notification']) ||
5359
        $_SESSION['forum_notification']['course'] != $course_id ||
5360
        $force = true
5361
    ) {
5362
        $_SESSION['forum_notification']['course'] = $course_id;
5363
5364
        $sql = "SELECT * FROM $table_notification
5365
                WHERE c_id = $course_id AND user_id='".intval($user_id)."'";
5366
        $result = Database::query($sql);
5367
        while ($row = Database::fetch_array($result)) {
5368
            if (!is_null($row['forum_id'])) {
5369
                $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
5370
            }
5371
            if (!is_null($row['thread_id'])) {
5372
                $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
5373
            }
5374
        }
5375
    }
5376
}
5377
5378
/**
5379
 * This function counts the number of post inside a thread
5380
 * @param   int $thread_id
5381
 * @return  int the number of post inside a thread
5382
 * @author Jhon Hinojosa <[email protected]>,
5383
 * @version octubre 2008, dokeos 1.8
5384
 */
5385 View Code Duplication
function count_number_of_post_in_thread($thread_id)
5386
{
5387
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5388
    $course_id = api_get_course_int_id();
5389
    if (empty($course_id)) {
5390
        return 0;
5391
    }
5392
    $sql = "SELECT count(*) count FROM $table_posts
5393
            WHERE 
5394
                c_id = $course_id AND 
5395
                thread_id='".intval($thread_id)."' ";
5396
    $result = Database::query($sql);
5397
5398
    $count = 0;
5399
    if (Database::num_rows($result) > 0) {
5400
        $row = Database::fetch_array($result);
5401
        $count = $row['count'];
5402
    }
5403
5404
    return $count;
5405
}
5406
5407
/**
5408
 * This function counts the number of post inside a thread user
5409
 * @param   int $thread_id
5410
 * @param   int $user_id
5411
 *
5412
 * @return  int the number of post inside a thread user
5413
 */
5414 View Code Duplication
function count_number_of_post_for_user_thread($thread_id, $user_id)
5415
{
5416
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5417
    $course_id = api_get_course_int_id();
5418
    $sql = "SELECT count(iid) as count 
5419
            FROM $table_posts
5420
            WHERE c_id = $course_id AND
5421
                  thread_id=".intval($thread_id)." AND
5422
                  poster_id = ".intval($user_id)." AND visible = 1 ";
5423
    $result = Database::query($sql);
5424
    $count = 0;
5425
    if (Database::num_rows($result) > 0) {
5426
        $count = Database::fetch_array($result);
5427
        $count = $count['count'];
5428
    }
5429
5430
    return $count;
5431
}
5432
5433
/**
5434
 * This function counts the number of user register in course
5435
 * @param   int $course_id Course ID
5436
 * @deprecated use CourseManager::get_users_count_in_course
5437
 * @return  int the number of user register in course
5438
 * @author Jhon Hinojosa <[email protected]>,
5439
 * @version octubre 2008, dokeos 1.8
5440
 */
5441
function count_number_of_user_in_course($course_id)
5442
{
5443
    $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5444
5445
    $sql = "SELECT * FROM $table
5446
            WHERE c_id ='".intval($course_id)."' ";
5447
    $result = Database::query($sql);
5448
5449
    return count(Database::store_result($result));
5450
}
5451
5452
/**
5453
 * This function retrieves information of statistical
5454
 * @param   int $thread_id
5455
 * @param   int $user_id
5456
 * @param   int $course_id
5457
 *
5458
 * @return  array the information of statistical
5459
 * @author Jhon Hinojosa <[email protected]>,
5460
 * @version oct 2008, dokeos 1.8
5461
 */
5462
function get_statistical_information($thread_id, $user_id, $course_id)
5463
{
5464
    $result = array();
5465
    $courseInfo = api_get_course_info_by_id($course_id);
5466
    $result['user_course'] = CourseManager::get_users_count_in_course($courseInfo['code']);
5467
    $result['post'] = count_number_of_post_in_thread($thread_id);
5468
    $result['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
5469
5470
    return $result;
5471
}
5472
5473
/**
5474
 * This function return the posts inside a thread from a given user
5475
 * @param   string $course_code
5476
 * @param   int $thread_id
5477
 * @param   int $user_id
5478
 *
5479
 * @return  array posts inside a thread
5480
 * @author Jhon Hinojosa <[email protected]>,
5481
 * @version oct 2008, dokeos 1.8
5482
 */
5483
function get_thread_user_post($course_code, $thread_id, $user_id)
5484
{
5485
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5486
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5487
    $thread_id = intval($thread_id);
5488
    $user_id = intval($user_id);
5489
    $course_info = api_get_user_info($course_code);
5490
    $course_id = $course_info['real_id'];
5491
5492
    if (empty($course_id)) {
5493
        $course_id = api_get_course_int_id();
5494
    }
5495
    $sql = "SELECT * FROM $table_posts posts
5496
            LEFT JOIN  $table_users users
5497
                ON posts.poster_id=users.user_id
5498
            WHERE
5499
                posts.c_id = $course_id AND
5500
                posts.thread_id='$thread_id'
5501
                AND posts.poster_id='$user_id'
5502
            ORDER BY posts.post_id ASC";
5503
5504
    $result = Database::query($sql);
5505
    $post_list = array();
5506 View Code Duplication
    while ($row = Database::fetch_array($result)) {
5507
        $row['status'] = '1';
5508
        $post_list[] = $row;
5509
        $sql = "SELECT * FROM $table_posts posts
5510
                LEFT JOIN $table_users users
5511
                ON (posts.poster_id=users.user_id)
5512
                WHERE
5513
                    posts.c_id = $course_id AND
5514
                    posts.thread_id='$thread_id'
5515
                    AND posts.post_parent_id='".$row['post_id']."'
5516
                ORDER BY posts.post_id ASC";
5517
        $result2 = Database::query($sql);
5518
        while ($row2 = Database::fetch_array($result2)) {
5519
            $row2['status'] = '0';
5520
            $post_list[] = $row2;
5521
        }
5522
    }
5523
5524
    return $post_list;
5525
}
5526
5527
/**
5528
 * This function get the name of an thread by id
5529
 * @param int thread_id
5530
 * @return String
5531
 * @author Christian Fasanando
5532
 * @author Julio Montoya <[email protected]> Adding security
5533
 */
5534
function get_name_thread_by_id($thread_id)
5535
{
5536
    $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
5537
    $course_id = api_get_course_int_id();
5538
    $sql = "SELECT thread_title 
5539
            FROM $t_forum_thread
5540
            WHERE c_id = $course_id AND thread_id = '".intval($thread_id)."' ";
5541
    $result = Database::query($sql);
5542
    $row = Database::fetch_array($result);
5543
5544
    return $row[0];
5545
}
5546
5547
/**
5548
 * This function gets all the post written by an user
5549
 * @param int $user_id
5550
 * @param string $course_code
5551
 *
5552
 * @return string
5553
 */
5554
function get_all_post_from_user($user_id, $course_code)
5555
{
5556
    $j = 0;
5557
    $forums = get_forums('', $course_code);
5558
    krsort($forums);
5559
    $forum_results = '';
5560
5561
    foreach ($forums as $forum) {
5562
        if ($forum['visibility'] == 0) {
5563
            continue;
5564
        }
5565
        if ($j <= 4) {
5566
            $threads = get_threads($forum['forum_id']);
5567
5568
            if (is_array($threads)) {
5569
                $i = 0;
5570
                $hand_forums = '';
5571
                $post_counter = 0;
5572
5573
                foreach ($threads as $thread) {
5574
                    if ($thread['visibility'] == 0) {
5575
                        continue;
5576
                    }
5577
                    if ($i <= 4) {
5578
                        $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
5579
                        $post_counter = count($post_list);
5580
                        if (is_array($post_list) && count($post_list) > 0) {
5581
                            $hand_forums.= '<div id="social-thread">';
5582
                            $hand_forums.= Display::return_icon('thread.png', get_lang('Thread'), '', ICON_SIZE_MEDIUM);
5583
                            $hand_forums.= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
5584
                            $hand_forums.= '</div>';
5585
5586
                            foreach ($post_list as $posts) {
5587
                                $hand_forums.= '<div id="social-post">';
5588
                                $hand_forums.= '<strong>'.Security::remove_XSS($posts['post_title'], STUDENT).'</strong>';
5589
                                $hand_forums.= '<br / >';
5590
                                $hand_forums.= Security::remove_XSS($posts['post_text'], STUDENT);
5591
                                $hand_forums.= '</div>';
5592
                                $hand_forums.= '<br / >';
5593
                            }
5594
                        }
5595
                    }
5596
                    $i++;
5597
                }
5598
                $forum_results .='<div id="social-forum">';
5599
                $forum_results .='<div class="clear"></div><br />';
5600
                $forum_results .='<div id="social-forum-title">'.
5601
                    Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS($forum['forum_title'], STUDENT).
5602
                    '<div style="float:right;margin-top:-35px">
5603
                        <a href="../forum/viewforum.php?'.api_get_cidreq_params($course_code).'&forum='.$forum['forum_id'].' " >'.
5604
                            get_lang('SeeForum').'    
5605
                        </a>
5606
                     </div></div>';
5607
                $forum_results .='<br / >';
5608
                if ($post_counter > 0) {
5609
                    $forum_results .=$hand_forums;
5610
                }
5611
                $forum_results .='</div>';
5612
            }$j++;
5613
        }
5614
    }
5615
5616
    return $forum_results;
5617
}
5618
5619
/**
5620
 * @param string $course_code
5621
 * @param int $thread_id
5622
 * @param int $user_id
5623
 * @param int $limit
5624
 *
5625
 * @return array
5626
 */
5627
function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
5628
{
5629
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5630
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5631
5632
    $course_info = api_get_course_info($course_code);
5633
    $course_id = $course_info['real_id'];
5634
5635
    $sql = "SELECT * FROM $table_posts posts
5636
            LEFT JOIN  $table_users users
5637
                ON posts.poster_id=users.user_id
5638
            WHERE
5639
                posts.c_id = $course_id AND
5640
                posts.thread_id='".Database::escape_string($thread_id)."'
5641
                AND posts.poster_id='".Database::escape_string($user_id)."'
5642
            ORDER BY posts.post_id DESC LIMIT $limit ";
5643
    $result = Database::query($sql);
5644
    $post_list = array();
5645
    while ($row = Database::fetch_array($result)) {
5646
        $row['status'] = '1';
5647
        $post_list[] = $row;
5648
    }
5649
5650
    return $post_list;
5651
}
5652
5653
/**
5654
 * @param string $user_id
5655
 * @param int $courseId
5656
 * @param int $sessionId
5657
 *
5658
 * @return array
5659
 */
5660
function getForumCreatedByUser($user_id, $courseId, $sessionId)
5661
{
5662
    $items = api_get_item_property_list_by_tool_by_user(
5663
        $user_id,
5664
        'forum',
5665
        $courseId,
5666
        $sessionId
5667
    );
5668
5669
    $courseInfo = api_get_course_info_by_id($courseId);
5670
5671
    $forumList = array();
5672 View Code Duplication
    if (!empty($items)) {
5673
        foreach ($items as $forum) {
5674
            $forumInfo = get_forums(
5675
                $forum['ref'],
5676
                $courseInfo['code'],
5677
                true,
5678
                $sessionId
5679
            );
5680
5681
            $forumList[] = array(
5682
                $forumInfo['forum_title'],
5683
                api_get_local_time($forum['insert_date']),
5684
                api_get_local_time($forum['lastedit_date']),
5685
            );
5686
        }
5687
    }
5688
5689
    return $forumList;
5690
}
5691
5692
/**
5693
 * This function builds an array of all the posts in a given thread
5694
 * where the key of the array is the post_id
5695
 * It also adds an element children to the array which itself is an array
5696
 * that contains all the id's of the first-level children
5697
 * @return array $rows containing all the information on the posts of a thread
5698
 * @author Patrick Cool <[email protected]>, Ghent University
5699
 */
5700
function calculate_children($rows)
5701
{
5702
    $sorted_rows = array(0 => array());
5703
    if (!empty($rows)) {
5704
        foreach ($rows as $row) {
5705
            $rows_with_children[$row['post_id']] = $row;
5706
            $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
5707
        }
5708
5709
        $rows = $rows_with_children;
5710
        forumRecursiveSort($rows, $sorted_rows);
5711
        unset($sorted_rows[0]);
5712
    }
5713
5714
    return $sorted_rows;
5715
}
5716
5717
/**
5718
 * @param $rows
5719
 * @param $threads
5720
 * @param int $seed
5721
 * @param int $indent
5722
 */
5723
function forumRecursiveSort($rows, &$threads, $seed = 0, $indent = 0)
5724
{
5725
    if ($seed > 0) {
5726
        $threads[$rows[$seed]['post_id']] = $rows[$seed];
5727
        $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
5728
        $indent++;
5729
    }
5730
5731
    if (isset($rows[$seed]['children'])) {
5732
        foreach ($rows[$seed]['children'] as $child) {
5733
            forumRecursiveSort($rows, $threads, $child, $indent);
5734
        }
5735
    }
5736
}
5737
5738
/**
5739
 * Update forum attachment data, used to update comment and post ID.
5740
 * @param $array Array (field => value) to update forum attachment row.
5741
 * @param $id Attach ID to find row to update.
5742
 * @param null $courseId Course ID to find row to update.
5743
 * @return int Number of affected rows.
5744
 */
5745
function editAttachedFile($array, $id, $courseId = null) {
5746
    // Init variables
5747
    $setString = '';
5748
    $id = intval($id);
5749
    $courseId = intval($courseId);
5750
    if (empty($courseId)) {
5751
        // $courseId can be null, use api method
5752
        $courseId= api_get_course_int_id();
5753
    }
5754
    /*
5755
     * Check if Attachment ID and Course ID are greater than zero
5756
     * and array of field values is not empty
5757
     */
5758
    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
5759
        foreach($array as $key => &$item) {
5760
            $item = Database::escape_string($item);
5761
            $setString .= $key . ' = "' .$item . '", ';
5762
        }
5763
        // Delete last comma
5764
        $setString = substr($setString, 0, strlen($setString) - 2);
5765
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5766
        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
5767
        $result = Database::query($sql);
5768
        if ($result !== false) {
5769
            $affectedRows = Database::affected_rows($result);
5770 View Code Duplication
            if ($affectedRows > 0) {
5771
                /*
5772
                 * If exist in $_SESSION variable, then delete them from it
5773
                 * because they would be deprecated
5774
                 */
5775
                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
5776
                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
5777
                }
5778
            }
5779
5780
            return $affectedRows;
5781
        }
5782
    }
5783
5784
    return 0;
5785
}
5786
5787
/**
5788
 * Return a table where the attachments will be set
5789
 * @param int $postId Forum Post ID
5790
 *
5791
 * @return string The Forum Attachments Ajax Table
5792
 */
5793
function getAttachmentsAjaxTable($postId = 0)
5794
{
5795
    // Init variables
5796
    $postId = intval($postId);
5797
    $courseId = api_get_course_int_id();
5798
    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5799
    $fileDataContent = '';
5800
    // Update comment to show if form did not pass validation
5801
    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
5802
        // 'file_ids is the name from forum attachment ajax form
5803
        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
5804
            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) &&
5805
                is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])
5806
            ) {
5807
                // If exist forum attachment then update into $_SESSION data
5808
                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
5809
            }
5810
        }
5811
    }
5812
5813
    // Get data to fill into attachment files table
5814
    if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5815
        is_array($_SESSION['forum']['upload_file'][$courseId])
5816
    ) {
5817
        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
5818
        foreach ($uploadedFiles as $k => $uploadedFile) {
5819
            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
5820
                // Buil html table including an input with attachmentID
5821
                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
5822
                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
5823
                    $uploadedFile['delete'] . '</td>' .
5824
                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
5825
            } else {
5826
                /*
5827
                 * If attachment data is empty, then delete it from $_SESSION
5828
                 * because could generate and empty row into html table
5829
                 */
5830
                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
5831
            }
5832
        }
5833
    }
5834
    $style = empty($fileDataContent) ? 'display: none;' : '';
5835
    // Forum attachment Ajax table
5836
    $fileData = '
5837
    <div class="control-group " style="'. $style . '">
5838
        <label class="control-label">'.get_lang('AttachmentList').'</label>
5839
        <div class="controls">
5840
            <table id="attachmentFileList" class="files data_table span10">
5841
                <tr>
5842
                    <th>'.get_lang('FileName').'</th>
5843
                    <th>'.get_lang('Size').'</th>
5844
                    <th>'.get_lang('Status').'</th>
5845
                    <th>'.get_lang('Comment').'</th>
5846
                    <th>'.get_lang('Delete').'</th>
5847
                </tr>
5848
                '.$fileDataContent.'
5849
            </table>
5850
        </div>
5851
    </div>';
5852
5853
    return $fileData;
5854
}
5855
5856
/**
5857
 * Return an array of prepared attachment data to build forum attachment table
5858
 * Also, save this array into $_SESSION to do available the attachment data
5859
 * @param int $forumId
5860
 * @param int $threadId
5861
 * @param int $postId
5862
 * @param int $attachId
5863
 * @param int $courseId
5864
 *
5865
 * @return array
5866
 */
5867
function getAttachedFiles($forumId, $threadId, $postId = 0, $attachId = 0, $courseId = 0)
5868
{
5869
    $forumId = intval($forumId);
5870
    $courseId = intval($courseId);
5871
    $attachId = intval($attachId);
5872
    $postId = intval($postId);
5873
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5874
    if (empty($courseId)) {
5875
        // $courseId can be null, use api method
5876
        $courseId = api_get_course_int_id();
5877
    }
5878
    if (empty($forumId)) {
5879
        if (!empty($_REQUEST['forum'])) {
5880
            $forumId = intval($_REQUEST['forum']);
5881
        } else {
5882
            // if forum ID is empty, cannot generate delete url
5883
5884
            return array();
5885
        }
5886
    }
5887
    // Check if exist at least one of them to filter forum attachment select query
5888
    if (empty($postId) && empty($attachId)) {
5889
5890
        return array();
5891
    } elseif (empty($postId)) {
5892
        $filter = "AND iid = $attachId";
5893
    } elseif (empty($attachId)) {
5894
        $filter = "AND post_id = $postId";
5895
    } else {
5896
        $filter = "AND post_id = $postId AND iid = $attachId";
5897
    }
5898
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5899
    $sql = "SELECT iid, comment, filename, path, size
5900
            FROM $forumAttachmentTable
5901
            WHERE c_id = $courseId $filter";
5902
    $result = Database::query($sql);
5903
    $json = array();
5904
    if ($result !== false && Database::num_rows($result) > 0) {
5905
        while ($row = Database::fetch_array($result, 'ASSOC')) {
5906
            // name contains an URL to download attachment file and its filename
5907
            $json['name'] = Display::url(
5908
                api_htmlentities($row['filename']),
5909
                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'].'&'.api_get_cidreq(),
5910
                array('target'=>'_blank', 'class' => 'attachFilename')
5911
            );
5912
            $json['id'] = $row['iid'];
5913
            $json['comment'] = $row['comment'];
5914
            // Format file size
5915
            $json['size'] = format_file_size($row['size']);
5916
            // Check if $row is consistent
5917
            if (!empty($row) && is_array($row)) {
5918
                // Set result as success and bring delete URL
5919
                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
5920
                $url = api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php?' . api_get_cidreq() . '&action=delete_attach&forum=' . $forumId . '&thread=' . $threadId.'&id_attach=' . $row['iid'];
5921
                $json['delete'] = Display::url(
5922
                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL),
5923
                    $url,
5924
                    array('class' => 'deleteLink')
5925
                );
5926
            } else {
5927
                // If not, set an exclamation result
5928
                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
5929
            }
5930
            // Store array data into $_SESSION
5931
            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
5932
        }
5933
    }
5934
5935
    return $json;
5936
}
5937
5938
/**
5939
 * Clear forum attachment data stored in $_SESSION,
5940
 * If is not defined post, it will clear all forum attachment data from course
5941
 * @param int $postId -1 : Clear all attachments from course stored in $_SESSION
5942
 *                      0 : Clear attachments from course, except from temporal post "0"
5943
 *                          but without delete them from file system and database
5944
 *                     Other values : Clear attachments from course except specified post
5945
 *                          and delete them from file system and database
5946
 * @param int $courseId : Course ID, if it is null, will use api_get_course_int_id()
5947
 *
5948
 * @return array
5949
 */
5950
function clearAttachedFiles($postId = null, $courseId = null) {
5951
    // Init variables
5952
    $courseId = intval($courseId);
5953
    $postId = intval($postId);
5954
    $array = array();
5955
    if (empty($courseId)) {
5956
        // $courseId can be null, use api method
5957
        $courseId = api_get_course_int_id();
5958
    }
5959
    if ($postId === -1) {
5960
        // If post ID is -1 then delete course's attachment data from $_SESSION
5961 View Code Duplication
        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
5962
            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
5963
            unset($_SESSION['forum']['upload_file'][$courseId]);
5964
        }
5965
    } else {
5966
        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5967
        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5968
            is_array($_SESSION['forum']['upload_file'][$courseId])) {
5969
            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
5970
                if (!in_array($attachId, $attachIds)) {
5971
                    // If attach ID is not into specified post, delete attachment
5972
                    // Save deleted attachment ID
5973
                    $array[] = $attachId;
5974
                    if ($postId !== 0) {
5975
                        // Post 0 is temporal, delete them from file system and DB
5976
                        delete_attachment(0, $attachId, false);
5977
                    }
5978
                    // Delete attachment data from $_SESSION
5979
                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
5980
                }
5981
            }
5982
        }
5983
    }
5984
5985
    return $array;
5986
}
5987
5988
/**
5989
 * Returns an array of forum attachment ids into a course and forum post
5990
 * @param int $postId
5991
 * @param int $courseId
5992
 *
5993
 * @return array
5994
 */
5995
function getAttachmentIdsByPostId($postId, $courseId = null)
5996
{
5997
5998
    $array = array();
5999
    $courseId = intval($courseId);
6000
    $postId = intval($postId);
6001
    if (empty($courseId)) {
6002
        // $courseId can be null, use api method
6003
        $courseId = api_get_course_int_id();
6004
    }
6005
    if ($courseId > 0) {
6006
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
6007
        $sql = "SELECT id FROM $forumAttachmentTable
6008
                WHERE c_id = $courseId AND post_id = $postId";
6009
        $result = Database::query($sql);
6010
        if ($result !== false && Database::num_rows($result) > 0) {
6011
            while ($row = Database::fetch_array($result,'ASSOC')) {
6012
                $array[] = $row['id'];
6013
            }
6014
        }
6015
    }
6016
    return $array;
6017
}
6018
6019
/**
6020
 * Check if the forum category exists looking for its title
6021
 * @param string $title The forum category title
6022
 * @param int $courseId The course ID
6023
 * @param int $sessionId Optional. The session ID
6024
 * @return boolean
6025
 */
6026
function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
6027
{
6028
    $sessionId = intval($sessionId);
6029
6030
    $forumCategoryTable = Database::get_course_table(TABLE_FORUM_CATEGORY);
6031
    $itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
6032
6033
    $fakeFrom = "$forumCategoryTable fc
6034
        INNER JOIN $itemProperty ip ";
6035
6036
    if ($sessionId === 0) {
6037
        $fakeFrom .= "
6038
            ON (
6039
                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)
6040
            )
6041
        ";
6042
    } else {
6043
        $fakeFrom .= "
6044
            ON (
6045
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND fc.session_id = ip.session_id
6046
            )
6047
        ";
6048
    }
6049
6050
    $resultData = Database::select(
6051
        'fc.*',
6052
        $fakeFrom,
6053
        [
6054
            'where' => [
6055
                'ip.visibility != ? AND ' => 2,
6056
                'ip.tool = ? AND ' => TOOL_FORUM_CATEGORY,
6057
                'fc.session_id = ? AND ' => $sessionId,
6058
                'fc.cat_title = ? AND ' => $title,
6059
                'fc.c_id = ?' => intval($courseId)
6060
            ]
6061
        ],
6062
        'first'
6063
    );
6064
6065
    if (empty($resultData)) {
6066
        return false;
6067
    }
6068
6069
    return $resultData;
6070
}
6071
6072
/**
6073
 * @param array $current_forum
6074
 * @param array $row
6075
 *
6076
 * @return string
6077
 */
6078
function getPostStatus($current_forum, $row, $addWrapper = true)
6079
{
6080
    $statusIcon = '';
6081
    if ($current_forum['moderated']) {
6082
        if ($addWrapper) {
6083
            $statusIcon = '<br /><br /><span id="status_post_'.$row['iid'].'">';
6084
        }
6085
        $row['status'] = empty($row['status']) ? 2 : $row['status'];
6086
6087
        $addUrl = false;
6088
        if (api_is_allowed_to_edit(false, true)) {
6089
            $addUrl = true;
6090
        }
6091
6092
        $label = '';
6093
        $icon = '';
6094
        $buttonType = '';
6095
        switch ($row['status']) {
6096
            case CForumPost::STATUS_VALIDATED:
6097
                $label = get_lang('Validated');
6098
                $icon = 'check-circle';
6099
                $buttonType = 'success';
6100
                break;
6101
            case CForumPost::STATUS_WAITING_MODERATION:
6102
                $label = get_lang('WaitingModeration');
6103
                $icon = 'warning';
6104
                $buttonType = 'warning';
6105
                break;
6106
            case CForumPost::STATUS_REJECTED:
6107
                $label = get_lang('Rejected');
6108
                $icon = 'minus-circle';
6109
                $buttonType = 'danger';
6110
                break;
6111
        }
6112
6113
        if ($addUrl) {
6114
            $statusIcon .= Display::toolbarButton(
6115
                $label.'&nbsp;',
6116
                'javascript:void(0)',
6117
                $icon,
6118
                $buttonType,
6119
                ['class' => 'change_post_status']
6120
            );
6121
        } else {
6122
            $statusIcon .= Display::label(
6123
                Display::returnFontAwesomeIcon($icon).$label,
6124
                $buttonType
6125
            );
6126
        }
6127
6128
        if ($addWrapper) {
6129
            $statusIcon .= '</span>';
6130
        }
6131
    }
6132
6133
    return $statusIcon;
6134
}
6135
6136
/**
6137
 * @param array $forumInfo
6138
 * @param int $threadId
6139
 * @param int $status
6140
 * @return mixed
6141
 */
6142
function getCountPostsWithStatus($status, $forumInfo, $threadId = null)
6143
{
6144
    $em = Database::getManager();
6145
    $criteria = Criteria::create();
6146
    $criteria
6147
        ->where(Criteria::expr()->eq('status', $status))
6148
        ->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
6149
        ->andWhere(Criteria::expr()->eq('visible', 1))
6150
    ;
6151
6152
    if (!empty($threadId)) {
6153
        $criteria->andWhere(Criteria::expr()->eq('threadId', $threadId));
6154
    }
6155
6156
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
6157
    $qb->select('count(p.iid)')
6158
        ->addCriteria($criteria);
6159
6160
    return $qb->getQuery()->getSingleScalarResult();
6161
}
6162