Completed
Push — master ( 98c16a...17e47f )
by Julito
36:20
created

forumfunction.inc.php ➔ move_up_down()   D

Complexity

Conditions 14
Paths 163

Size

Total Lines 89
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 61
nc 163
nop 3
dl 0
loc 89
rs 4.6283
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
 */
29
30
define('FORUM_NEW_POST', 0);
31
32
get_notifications_of_user();
33
34
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
35
$htmlHeadXtra[] = '<script>
36
37
function check_unzip() {
38
    if (document.upload.unzip.checked){
39
        document.upload.if_exists[0].disabled=true;
40
        document.upload.if_exists[1].checked=true;
41
        document.upload.if_exists[2].disabled=true;
42
    } else {
43
        document.upload.if_exists[0].checked=true;
44
        document.upload.if_exists[0].disabled=false;
45
        document.upload.if_exists[2].disabled=false;
46
    }
47
}
48
function setFocus() {
49
    $("#title_file").focus();
50
}
51
</script>';
52
// The next javascript script is to manage ajax upload file
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_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);
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);
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);
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);
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
    // Initialize the object.
183
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
184
    // hidden field if from learning path
185
186
    $form->addElement('hidden', 'lp_id', $lp_id);
187
    // Setting the form elements.
188
    $form->addElement('header', get_lang('AddForumCategory'));
189
    $form->addElement('text', 'forum_category_title', get_lang('Title'), array('autofocus'));
190
    $form->addElement(
191
        'html_editor',
192
        'forum_category_comment',
193
        get_lang('Description'),
194
        null,
195
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
196
    );
197
    $form->addButtonCreate(get_lang('CreateCategory'), 'SubmitForumCategory');
198
199
    // Setting the rules.
200
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
201
202
    // The validation or display
203 View Code Duplication
    if ($form->validate()) {
204
        $check = Security::check_token('post');
205
        if ($check) {
206
            $values = $form->exportValues();
207
            store_forumcategory($values);
208
        }
209
        Security::clear_token();
210
    } else {
211
        $token = Security::get_token();
212
        $form->addElement('hidden', 'sec_token');
213
        $form->setConstants(array('sec_token' => $token));
214
        $form->display();
215
    }
216
}
217
218
/**
219
 * This function displays the form that is used to add a forum category.
220
 *
221
 * @param array $inputvalues
222
 * @param int $lp_id
223
 * @return void HTML
224
 *
225
 * @author Patrick Cool <[email protected]>, Ghent University
226
 * @author Juan Carlos Raña Trabado (return to lp_id)
227
 *
228
 * @version may 2011, Chamilo 1.8.8
229
 */
230
function show_add_forum_form($inputvalues = array(), $lp_id)
231
{
232
    $_course = api_get_course_info();
233
    $form = new FormValidator('forumcategory', 'post', 'index.php?' . api_get_cidreq());
234
235
    // The header for the form
236
    if (!empty($inputvalues)) {
237
        $form_title = get_lang('EditForum');
238
    } else {
239
        $form_title = get_lang('AddForum');
240
    }
241
    $session_header = api_get_session_name();
242
    $form->addElement('header', $form_title.$session_header);
243
244
    // We have a hidden field if we are editing.
245
    if (!empty($inputvalues) && is_array($inputvalues)) {
246
        $my_forum_id = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
247
        $form->addElement('hidden', 'forum_id', $my_forum_id);
248
    }
249
    $lp_id = intval($lp_id);
250
    // hidden field if from learning path
251
    $form->addElement('hidden', 'lp_id', $lp_id);
252
253
    // The title of the forum
254
    $form->addElement('text', 'forum_title', get_lang('Title'), array('autofocus'));
255
256
    // The comment of the forum.
257
    $form->addElement(
258
        'html_editor',
259
        'forum_comment',
260
        get_lang('Description'),
261
        null,
262
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
263
    );
264
265
    // Dropdown list: Forum categories
266
    $forum_categories = get_forum_categories();
267
    foreach ($forum_categories as $key => $value) {
268
        $forum_categories_titles[$value['cat_id']] = $value['cat_title'];
269
    }
270
    $form->addElement('select', 'forum_category', get_lang('InForumCategory'), $forum_categories_titles);
271
    $form->applyFilter('forum_category', 'html_filter');
272
273
    if ($_course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD) {
274
        // This is for horizontal
275
        $group = array();
276
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('Yes'), 1);
277
        $group[] = $form->createElement('radio', 'allow_anonymous', null, get_lang('No'), 0);
278
        $form->addGroup($group, 'allow_anonymous_group', get_lang('AllowAnonymousPosts'));
279
    }
280
281
    $form->addButtonAdvancedSettings('advanced_params');
282
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
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('forum.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
        $defaults['forum_id'] = isset($inputvalues['forum_id']) ? $inputvalues['forum_id'] : null;
391
        $defaults['forum_title'] = prepare4display(isset($inputvalues['forum_title']) ? $inputvalues['forum_title'] : null);
392
        $defaults['forum_comment'] = prepare4display(isset($inputvalues['forum_comment']) ? $inputvalues['forum_comment'] : null);
393
        $defaults['start_time'] = isset($inputvalues['start_time']) ? api_get_local_time($inputvalues['start_time']) : null;
394
        $defaults['end_time'] = isset($inputvalues['end_time']) ? api_get_local_time($inputvalues['end_time']) : null;
395
        $defaults['moderated']['moderated'] = isset($inputvalues['moderated']) ? $inputvalues['moderated'] : 0;
396
        $defaults['forum_category'] = isset($inputvalues['forum_category']) ? $inputvalues['forum_category'] : null;
397
        $defaults['allow_anonymous_group']['allow_anonymous'] = isset($inputvalues['allow_anonymous']) ? $inputvalues['allow_anonymous'] : null;
398
        $defaults['students_can_edit_group']['students_can_edit'] = isset($inputvalues['allow_edit']) ? $inputvalues['allow_edit'] : null;
399
        $defaults['approval_direct_group']['approval_direct'] = isset($inputvalues['approval_direct_post']) ? $inputvalues['approval_direct_post'] : null;
400
        $defaults['allow_attachments_group']['allow_attachments'] = isset($inputvalues['allow_attachments']) ? $inputvalues['allow_attachments'] : null;
401
        $defaults['allow_new_threads_group']['allow_new_threads'] = isset($inputvalues['allow_new_threads']) ? $inputvalues['allow_new_threads'] : $defaultSettingAllowNewThreads;
402
        $defaults['default_view_type_group']['default_view_type'] = isset($inputvalues['default_view']) ? $inputvalues['default_view'] : null;
403
        $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
404
        $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
405
    }
406
    $form->setDefaults($defaults);
407
    // Validation or display
408 View Code Duplication
    if ($form->validate()) {
409
        $check = Security::check_token('post');
410
        if ($check) {
411
            $values = $form->getSubmitValues();
412
            $return_message = store_forum($values);
413
            Display :: display_confirmation_message($return_message);
414
        }
415
        Security::clear_token();
416
    } else {
417
        $token = Security::get_token();
418
        $form->addElement('hidden', 'sec_token');
419
        $form->setConstants(array('sec_token' => $token));
420
        $form->display();
421
    }
422
}
423
424
/**
425
 * This function deletes the forum image if exists
426
 *
427
 * @param int forum id
428
 * @return boolean true if success
429
 * @author Julio Montoya <[email protected]>
430
 * @version february 2006, dokeos 1.8
431
 */
432
function delete_forum_image($forum_id)
433
{
434
    $table_forums = Database::get_course_table(TABLE_FORUM);
435
    $course_id = api_get_course_int_id();
436
    $forum_id = intval($forum_id);
437
438
    $sql = "SELECT forum_image FROM $table_forums
439
            WHERE forum_id = $forum_id AND c_id = $course_id";
440
    $result = Database::query($sql);
441
    $row = Database::fetch_array($result);
442
    if ($row['forum_image'] != '') {
443
        $file = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/upload/forum/images/'.$row['forum_image'];
444
        if (file_exists($file)) {
445
            unlink($file);
446
        }
447
448
        return true;
449
    } else {
450
        return false;
451
    }
452
}
453
454
/**
455
 * This function displays the form that is used to edit a forum category.
456
 * This is more or less a copy from the show_add_forumcategory_form function with the only difference that is uses
457
 * some default values. I tried to have both in one function but this gave problems with the handle_forum_and_forumcategories function
458
 * (storing was done twice)
459
 *
460
 * @param array
461
 * @return void HTML
462
 *
463
 * @author Patrick Cool <[email protected]>, Ghent University
464
 * @version february 2006, dokeos 1.8
465
 */
466
function show_edit_forumcategory_form($inputvalues = array())
467
{
468
    $categoryId = $inputvalues['cat_id'];
469
    $form = new FormValidator('forumcategory', 'post', 'index.php?'.api_get_cidreq().'&id='.$categoryId);
470
471
    // Setting the form elements.
472
    $form->addElement('header', '', get_lang('EditForumCategory'));
473
    $form->addElement('hidden', 'forum_category_id');
474
    $form->addElement('text', 'forum_category_title', get_lang('Title'));
475
476
    $form->addHtmlEditor(
477
        'forum_category_comment',
478
        get_lang('Comment'),
479
        null,
480
        null,
481
        array('ToolbarSet' => 'Forum', 'Width' => '98%', 'Height' => '200')
482
    );
483
484
    $form->addButtonUpdate(get_lang('ModifyCategory'), 'SubmitEditForumCategory');
485
486
    // Setting the default values.
487
    $defaultvalues['forum_category_id'] = $inputvalues['cat_id'];
488
    $defaultvalues['forum_category_title'] = $inputvalues['cat_title'];
489
    $defaultvalues['forum_category_comment'] = $inputvalues['cat_comment'];
490
    $form->setDefaults($defaultvalues);
491
492
    // Setting the rules.
493
    $form->addRule('forum_category_title', get_lang('ThisFieldIsRequired'), 'required');
494
495
    // Validation or display
496 View Code Duplication
    if ($form->validate()) {
497
        $check = Security::check_token('post');
498
        if ($check) {
499
            $values = $form->exportValues();
500
            store_forumcategory($values);
501
        }
502
        Security::clear_token();
503
    } else {
504
        $token = Security::get_token();
505
        $form->addElement('hidden', 'sec_token');
506
        $form->setConstants(array('sec_token' => $token));
507
        $form->display();
508
    }
509
}
510
511
/**
512
 * This function stores the forum category in the database.
513
 * The new category is added to the end.
514
 *
515
 * @param array $values
516
 * @param array $courseInfo
517
 * @param bool $showMessage
518
 * @return void HMTL language variable
519
 *
520
 * @author Patrick Cool <[email protected]>, Ghent University
521
 * @version february 2006, dokeos 1.8
522
 */
523
function store_forumcategory($values, $courseInfo = array(), $showMessage = true)
524
{
525
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
526
    $course_id = $courseInfo['real_id'];
527
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
        Database::update(
548
            $table_categories,
549
            $params,
550
            [
551
                'c_id = ? AND cat_id = ?' => [
552
                    $course_id,
553
                    $values['forum_category_id'],
554
                ],
555
            ]
556
        );
557
558
        api_item_property_update(
559
            $courseInfo,
560
            TOOL_FORUM_CATEGORY,
561
            $values['forum_category_id'],
562
            'ForumCategoryUpdated',
563
            api_get_user_id()
564
        );
565
        $return_message = get_lang('ForumCategoryEdited');
566
    } else {
567
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
581
            $sql = "UPDATE $table_categories SET cat_id = $last_id WHERE iid = $last_id";
582
            Database::query($sql);
583
584
            api_item_property_update(
585
                $courseInfo,
586
                TOOL_FORUM_CATEGORY,
587
                $last_id,
588
                'ForumCategoryAdded',
589
                api_get_user_id()
590
            );
591
            api_set_default_visibility(
592
                $last_id,
593
                TOOL_FORUM_CATEGORY,
594
                0,
595
                $courseInfo
596
            );
597
        }
598
        $return_message = get_lang('ForumCategoryAdded');
599
    }
600
601
    if ($showMessage) {
602
        Display::display_confirmation_message($return_message, 'success');
603
    }
604
605
    return $last_id;
606
}
607
608
/**
609
 * This function stores the forum in the database. The new forum is added to the end.
610
 *
611
 * @param array $values
612
 * @param array $courseInfo
613
 * @param bool  $returnId
614
 * @return string language variable
615
 *
616
 * @author Patrick Cool <[email protected]>, Ghent University
617
 * @version february 2006, dokeos 1.8
618
 */
619
function store_forum($values, $courseInfo = array(), $returnId = false)
620
{
621
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
622
    $course_id = $courseInfo['real_id'];
623
    $session_id = api_get_session_id();
624
625
    if (isset($values['group_id']) && !empty($values['group_id'])) {
626
        $group_id = $values['group_id'];
627
    } else {
628
        $group_id = api_get_group_id();
629
    }
630
631
    $table_forums = Database::get_course_table(TABLE_FORUM);
632
633
    // Find the max forum_order for the given category. The new forum is added at the end => max cat_order + &
634
    if (is_null($values['forum_category'])) {
635
        $new_max = null;
636
    } else {
637
        $sql = "SELECT MAX(forum_order) as sort_max
638
                FROM $table_forums
639
                WHERE
640
                    c_id = $course_id AND
641
                    forum_category='".Database::escape_string($values['forum_category'])."'";
642
        $result = Database::query($sql);
643
        $row = Database::fetch_array($result);
644
        $new_max = $row['sort_max'] + 1;
645
    }
646
647
    // Forum images
648
    $image_moved = false;
649
    $has_attachment = false;
650
    if (!empty($_FILES['picture']['name'])) {
651
        $upload_ok = process_uploaded_file($_FILES['picture']);
652
        $has_attachment = true;
653
    } else {
654
        $image_moved = true;
655
    }
656
657
    // Remove existing picture if it was requested.
658
    if (!empty($_POST['remove_picture'])) {
659
        delete_forum_image($values['forum_id']);
660
    }
661
662
    $new_file_name = '';
663
    if (isset($upload_ok)) {
664
        if ($has_attachment) {
665
            $course_dir = $courseInfo['path'].'/upload/forum/images';
666
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
667
            $updir = $sys_course_path.$course_dir;
668
            // Try to add an extension to the file if it hasn't one.
669
            $new_file_name = add_ext_on_mime(
670
                Database::escape_string($_FILES['picture']['name']),
671
                $_FILES['picture']['type']
672
            );
673
            if (!filter_extension($new_file_name)) {
674
                //Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
675
                $image_moved = false;
676
            } else {
677
                $file_extension = explode('.', $_FILES['picture']['name']);
678
                $file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
679
                $new_file_name = uniqid('').'.'.$file_extension;
680
                $new_path = $updir.'/'.$new_file_name;
681
                $result = @move_uploaded_file($_FILES['picture']['tmp_name'], $new_path);
682
                // Storing the attachments if any
683
                if ($result) {
684
                    $image_moved = true;
685
                }
686
            }
687
        }
688
    }
689
690
    if (isset($values['forum_id'])) {
691
692
        // Storing after edition.
693
        $params = [
694
            'forum_title'=> $values['forum_title'],
695
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
696
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
697
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
698
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
699
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
700
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
701
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
702
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
703
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
704
            '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,
705
            'moderated'=> $values['moderated']['moderated'],
706
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
707
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
708
            'session_id'=> $session_id,
709
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0
710
        ];
711
        if (isset($upload_ok)) {
712
            if ($has_attachment) {
713
                $params['forum_image'] = $new_file_name;
714
            }
715
        }
716
717
        if (isset($values['remove_picture']) && $values['remove_picture'] == 1) {
718
            $params['forum_image'] = '';
719
            delete_forum_image($values['forum_id']);
720
        }
721
722
        Database::update(
723
            $table_forums,
724
            $params,
725
            ['c_id = ? AND forum_id = ?' => [$course_id, $values['forum_id']]]
726
        );
727
728
        api_item_property_update(
729
            $courseInfo,
730
            TOOL_FORUM,
731
            Database::escape_string($values['forum_id']),
732
            'ForumUpdated',
733
            api_get_user_id(),
734
            $group_id
735
        );
736
737
        $return_message = get_lang('ForumEdited');
738
    } else {
739
        if ($image_moved) {
740
            $new_file_name = isset($new_file_name) ? $new_file_name : '';
741
        }
742
743
        $params = [
744
            'c_id' => $course_id,
745
            'forum_title'=> $values['forum_title'],
746
            'forum_image'=> $new_file_name,
747
            'forum_comment'=> isset($values['forum_comment']) ? $values['forum_comment'] : null,
748
            'forum_category'=> isset($values['forum_category']) ? $values['forum_category'] : null,
749
            'allow_anonymous'=> isset($values['allow_anonymous_group']['allow_anonymous']) ? $values['allow_anonymous_group']['allow_anonymous'] : null,
750
            'allow_edit'=> isset($values['students_can_edit_group']['students_can_edit']) ? $values['students_can_edit_group']['students_can_edit'] : null,
751
            'approval_direct_post'=> isset($values['approval_direct_group']['approval_direct']) ? $values['approval_direct_group']['approval_direct'] : null,
752
            'allow_attachments'=> isset($values['allow_attachments_group']['allow_attachments']) ? $values['allow_attachments_group']['allow_attachments'] : null,
753
            'allow_new_threads'=> isset($values['allow_new_threads_group']['allow_new_threads']) ? $values['allow_new_threads_group']['allow_new_threads'] : null,
754
            'default_view'=> isset($values['default_view_type_group']['default_view_type']) ? $values['default_view_type_group']['default_view_type'] : null,
755
            'forum_of_group'=> isset($values['group_forum']) ? $values['group_forum'] : null,
756
            '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,
757
            'moderated'=> isset($values['moderated']['moderated']) ? (int) $values['moderated']['moderated'] : 0,
758
            'start_time' => !empty($values['start_time']) ? api_get_utc_datetime($values['start_time']) : null,
759
            'end_time' => !empty($values['end_time']) ? api_get_utc_datetime($values['end_time']) : null,
760
            'forum_order'=> isset($new_max) ? $new_max : null,
761
            'session_id'=> $session_id,
762
            'lp_id' => isset($values['lp_id']) ? intval($values['lp_id']) : 0,
763
            'locked' => 0,
764
            'forum_id' => 0
765
        ];
766
767
        $last_id = Database::insert($table_forums, $params);
768 View Code Duplication
        if ($last_id > 0) {
769
770
            $sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $last_id";
771
            Database::query($sql);
772
773
            api_item_property_update(
774
                $courseInfo,
775
                TOOL_FORUM,
776
                $last_id,
777
                'ForumAdded',
778
                api_get_user_id(),
779
                $group_id
780
            );
781
782
            api_set_default_visibility(
783
                $last_id,
784
                TOOL_FORUM,
785
                $group_id,
786
                $courseInfo
787
            );
788
        }
789
        $return_message = get_lang('ForumAdded');
790
        if ($returnId) {
791
792
            return $last_id;
793
        }
794
    }
795
796
    return $return_message;
797
}
798
799
/**
800
 * This function deletes a forum or a forum category
801
 * This function currently does not delete the forums inside the category,
802
 * nor the threads and replies inside these forums.
803
 * For the moment this is the easiest method and it has the advantage that it
804
 * allows to recover fora that were acidently deleted
805
 * when the forum category got deleted.
806
 *
807
 * @param $content = what we are deleting (a forum or a forum category)
808
 * @param $id The id of the forum category that has to be deleted.
809
 *
810
 * @todo write the code for the cascading deletion of the forums inside a
811
 * forum category and also the threads and replies inside these forums
812
 * @todo config setting for recovery or not
813
 * (see also the documents tool: real delete or not).
814
 * @return string
815
 * @author Patrick Cool <[email protected]>, Ghent University
816
 * @version february 2006, dokeos 1.8
817
 */
818
function deleteForumCategoryThread($content, $id)
819
{
820
    $_course = api_get_course_info();
821
    $table_forums = Database::get_course_table(TABLE_FORUM);
822
    $table_forums_post = Database::get_course_table(TABLE_FORUM_POST);
823
    $table_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
824
    $course_id = api_get_course_int_id();
825
    $groupId = api_get_group_id();
826
    $userId = api_get_user_id();
827
    $id = intval($id);
828
829
    // Delete all attachment file about this tread id.
830
    $sql = "SELECT post_id FROM $table_forums_post
831
            WHERE c_id = $course_id AND thread_id = '".$id."' ";
832
    $res = Database::query($sql);
833
    while ($poster_id = Database::fetch_row($res)) {
834
        delete_attachment($poster_id[0]);
835
    }
836
837
    $tool_constant = null;
838
    $return_message = '';
839
840 View Code Duplication
    if ($content == 'forumcategory') {
841
        $tool_constant = TOOL_FORUM_CATEGORY;
842
        $return_message = get_lang('ForumCategoryDeleted');
843
844
        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...
845
            $sql = "SELECT forum_id FROM $table_forums
846
                    WHERE c_id = $course_id AND forum_category='".$id."'";
847
            $result = Database::query($sql);
848
            $row = Database::fetch_array($result);
849
            foreach ($row as $arr_forum) {
850
                $forum_id = $arr_forum['forum_id'];
851
                api_item_property_update(
852
                    $_course,
853
                    'forum',
854
                    $forum_id,
855
                    'delete',
856
                    api_get_user_id()
857
                );
858
            }
859
        }
860
    }
861
862 View Code Duplication
    if ($content == 'forum') {
863
        $tool_constant = TOOL_FORUM;
864
        $return_message = get_lang('ForumDeleted');
865
866
        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...
867
            $sql = "SELECT thread_id FROM $table_forum_thread
868
                    WHERE c_id = $course_id AND forum_id = $id ";
869
            $result = Database::query($sql);
870
            $row = Database::fetch_array($result);
871
            foreach ($row as $arr_forum) {
872
                $forum_id = $arr_forum['thread_id'];
873
                api_item_property_update(
874
                    $_course,
875
                    'forum_thread',
876
                    $forum_id,
877
                    'delete',
878
                    api_get_user_id()
879
                );
880
            }
881
        }
882
    }
883
884
    if ($content == 'thread') {
885
        $tool_constant = TOOL_FORUM_THREAD;
886
        $return_message = get_lang('ThreadDeleted');
887
    }
888
889
    api_item_property_update(
890
        $_course,
891
        $tool_constant,
892
        $id,
893
        'delete',
894
        $userId,
895
        $groupId
896
    );
897
898
    // Check if this returns a true and if so => return $return_message, if not => return false;
899
    return $return_message;
900
}
901
902
/**
903
 * This function deletes a forum post. This separate function is needed because forum posts do not appear in the item_property table (yet)
904
 * and because deleting a post also has consequence on the posts that have this post as parent_id (they are also deleted).
905
 * an alternative would be to store the posts also in item_property and mark this post as deleted (visibility = 2).
906
 * We also have to decrease the number of replies in the thread table
907
 *
908
 * @param $post_id the id of the post that will be deleted
909
 * @todo write recursive function that deletes all the posts that have this message as parent
910
 * @return string language variable
911
 * @author Patrick Cool <[email protected]>, Ghent University
912
 * @author Hubert Borderiou Function cleanead and fixed
913
 * @version february 2006
914
 */
915
function delete_post($post_id)
916
{
917
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
918
    $post_id = intval($post_id);
919
    $course_id = api_get_course_int_id();
920
    $em = Database::getManager();
921
922
    $post = $em
923
        ->getRepository('ChamiloCourseBundle:CForumPost')
924
        ->findOneBy(['cId' => $course_id, 'postId' => $post_id]);
925
926
    if ($post) {
927
        $em
928
            ->createQuery('
929
                UPDATE ChamiloCourseBundle:CForumPost p
930
                SET p.postParentId = :parent_of_deleted_post
931
                WHERE
932
                    p.cId = :course AND
933
                    p.postParentId = :post AND
934
                    p.threadId = :thread_of_deleted_post AND
935
                    p.forumId = :forum_of_deleted_post
936
            ')
937
            ->execute([
938
                'parent_of_deleted_post' => $post->getPostParentId(),
939
                'course' => $course_id,
940
                'post' => $post->getPostId(),
941
                'thread_of_deleted_post' => $post->getThreadId(),
942
                'forum_of_deleted_post' => $post->getForumId()
943
            ]);
944
945
        $em->remove($post);
946
        $em->flush();
947
948
        // Delete attachment file about this post id.
949
        delete_attachment($post_id);
950
    }
951
952
    $last_post_of_thread = check_if_last_post_of_thread($_GET['thread']);
953
954
    if (is_array($last_post_of_thread)) {
955
        // Decreasing the number of replies for this thread and also changing the last post information.
956
        $sql = "UPDATE $table_threads
957
                SET
958
                    thread_replies = thread_replies - 1,
959
                    thread_last_post = ".intval($last_post_of_thread['post_id']).",
960
                    thread_date='".Database::escape_string($last_post_of_thread['post_date'])."'
961
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
962
        Database::query($sql);
963
964
        return 'PostDeleted';
965
    }
966
    if (!$last_post_of_thread) {
967
        // We deleted the very single post of the thread so we need to delete the entry in the thread table also.
968
        $sql = "DELETE FROM $table_threads
969
                WHERE c_id = $course_id AND thread_id = ".intval($_GET['thread']);
970
        Database::query($sql);
971
972
        return 'PostDeletedSpecial';
973
    }
974
}
975
976
/**
977
 * This function gets the all information of the last (=most recent) post of the thread
978
 * This can be done by sorting the posts that have the field thread_id=$thread_id and sort them by post_date
979
 *
980
 * @param $thread_id the id of the thread we want to know the last post of.
981
 * @return an array or bool if there is a last post found, false if there is
982
 * no post entry linked to that thread => thread will be deleted
983
 *
984
 * @author Patrick Cool <[email protected]>, Ghent University
985
 * @version february 2006, dokeos 1.8
986
 */
987
function check_if_last_post_of_thread($thread_id)
988
{
989
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
990
    $course_id = api_get_course_int_id();
991
    $sql = "SELECT * FROM $table_posts
992
            WHERE c_id = $course_id AND thread_id = ".intval($thread_id)."
993
            ORDER BY post_date DESC";
994
    $result = Database::query($sql);
995
    if (Database::num_rows($result) > 0) {
996
        $row = Database::fetch_array($result);
997
998
        return $row;
999
    } else {
1000
        return false;
1001
    }
1002
}
1003
1004
/**
1005
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1006
 * @param $id the id of the content we want to make invisible
1007
 * @param $current_visibility_status what is the current status of the visibility (0 = invisible, 1 = visible)
1008
 * @param array $additional_url_parameters
1009
 *
1010
 * @return string HTML
1011
 */
1012
function return_visible_invisible_icon($content, $id, $current_visibility_status, $additional_url_parameters = '')
1013
{
1014
    $html = '';
1015
    $id = Security::remove_XSS($id);
1016 View Code Duplication
    if ($current_visibility_status == '1') {
1017
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1018
        if (is_array($additional_url_parameters)) {
1019
            foreach ($additional_url_parameters as $key => $value) {
1020
                $html .= $key . '=' . $value . '&';
1021
            }
1022
        }
1023
       $html.='action=invisible&content='.$content.'&id='.$id.'">'.
1024
           Display::return_icon('visible.png', get_lang('MakeInvisible'), array(), ICON_SIZE_SMALL).'</a>';
1025
    }
1026 View Code Duplication
    if ($current_visibility_status == '0') {
1027
        $html .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&';
1028
        if (is_array($additional_url_parameters)) {
1029
            foreach ($additional_url_parameters as $key => $value) {
1030
                $html .= $key . '=' . $value . '&';
1031
            }
1032
        }
1033
       $html .= 'action=visible&content=' . $content . '&id=' . $id . '">' .
1034
           Display::return_icon('invisible.png', get_lang('MakeVisible'), array(), ICON_SIZE_SMALL) . '</a>';
1035
    }
1036
    return $html;
1037
}
1038
1039
/**
1040
 * @param $content
1041
 * @param $id
1042
 * @param $current_lock_status
1043
 * @param string $additional_url_parameters
1044
 * @return string
1045
 */
1046
function return_lock_unlock_icon($content, $id, $current_lock_status, $additional_url_parameters = '')
1047
{
1048
    $html = '';
1049
    $id = intval($id);
1050
    //check if the forum is blocked due
1051
    if ($content == 'thread') {
1052
        if (api_resource_is_locked_by_gradebook($id, LINK_FORUM_THREAD)) {
1053
            $html .= Display::return_icon('lock_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
1054
1055
            return $html;
1056
        }
1057
    }
1058 View Code Duplication
    if ($current_lock_status == '1') {
1059
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1060
        if (is_array($additional_url_parameters)) {
1061
            foreach ($additional_url_parameters as $key => $value) {
1062
                $html .= $key . '=' . $value . '&';
1063
            }
1064
        }
1065
        $html.= 'action=unlock&content='.$content.'&id='.$id.'">'.
1066
            Display::return_icon('lock.png', get_lang('Unlock'), array(), ICON_SIZE_SMALL).'</a>';
1067
    }
1068 View Code Duplication
    if ($current_lock_status == '0') {
1069
        $html .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&';
1070
        if (is_array($additional_url_parameters)) {
1071
            foreach ($additional_url_parameters as $key => $value) {
1072
                $html .= $key . '=' . $value . '&';
1073
            }
1074
        }
1075
        $html .= 'action=lock&content=' . $content . '&id=' . $id . '">' .
1076
            Display::return_icon('unlock.png', get_lang('Lock'), array(), ICON_SIZE_SMALL) . '</a>';
1077
    }
1078
    return $html;
1079
}
1080
1081
/**
1082
 * This function takes care of the display of the up and down icon
1083
 *
1084
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1085
 * @param $id is the id of the item we want to display the icons for
1086
 * @param $list is an array of all the items. All items in this list should have
1087
 * an up and down icon except for the first (no up icon) and the last (no down icon)
1088
 *          The key of this $list array is the id of the item.
1089
 *
1090
 * @return string HTML
1091
 **/
1092
function return_up_down_icon($content, $id, $list)
1093
{
1094
    $id = strval(intval($id));
1095
    $total_items = count($list);
1096
    $position = 0;
1097
    $internal_counter = 0;
1098
    $forumCategory = isset($_GET['forumcategory']) ? Security::remove_XSS($_GET['forumcategory']) : null;
1099
1100
    if (is_array($list)) {
1101
        foreach ($list as $key => $listitem) {
1102
            $internal_counter++;
1103
            if ($id == $key) {
1104
                $position = $internal_counter;
1105
            }
1106
        }
1107
    }
1108
1109
    if ($position > 1) {
1110
        $return_value = '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=up&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveUp').'">'.
1111
            Display::return_icon('up.png', get_lang('MoveUp'), array(), ICON_SIZE_SMALL).'</a>';
1112
    } else {
1113
        $return_value = Display::return_icon('up_na.png', '-', array(), ICON_SIZE_SMALL);
1114
    }
1115
1116
    if ($position < $total_items) {
1117
        $return_value .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=move&direction=down&content='.$content.'&forumcategory='.$forumCategory.'&id='.$id.'" title="'.get_lang('MoveDown').'" >'.
1118
            Display::return_icon('down.png', get_lang('MoveDown'), array(), ICON_SIZE_SMALL).'</a>';
1119
    } else {
1120
        $return_value .= Display::return_icon('down_na.png', '-', array(), ICON_SIZE_SMALL);
1121
    }
1122
    return $return_value;
1123
}
1124
1125
/**
1126
 * This function changes the visibility in the database (item_property)
1127
 *
1128
 * @param string $content what is it that we want to make (in)visible: forum category, forum, thread, post
1129
 * @param int $id the id of the content we want to make invisible
1130
 * @param string $target_visibility what is the current status of the visibility (0 = invisible, 1 = visible)
1131
 *
1132
 * @todo change the get parameter so that it matches the tool constants.
1133
 * @todo check if api_item_property_update returns true or false => returnmessage depends on it.
1134
 * @todo move to itemmanager
1135
 *
1136
 * @return string language variable
1137
 *
1138
 * @author Patrick Cool <[email protected]>, Ghent University
1139
 * @version february 2006, dokeos 1.8
1140
 */
1141
function change_visibility($content, $id, $target_visibility)
1142
{
1143
    $_course = api_get_course_info();
1144
    $constants = array(
1145
        'forumcategory' => TOOL_FORUM_CATEGORY,
1146
        'forum' => TOOL_FORUM,
1147
        'thread' => TOOL_FORUM_THREAD,
1148
    );
1149
    api_item_property_update(
1150
        $_course,
1151
        $constants[$content],
1152
        $id,
1153
        $target_visibility,
1154
        api_get_user_id()
1155
    );
1156
1157
    if ($target_visibility == 'visible') {
1158
        handle_mail_cue($content, $id);
1159
    }
1160
    return get_lang('VisibilityChanged');
1161
}
1162
1163
/**
1164
 * This function changes the lock status in the database
1165
 *
1166
 * @param string $content what is it that we want to (un)lock: forum category, forum, thread, post
1167
 * @param int $id the id of the content we want to (un)lock
1168
 * @param string $action do we lock (=>locked value in db = 1) or unlock (=> locked value in db = 0)
1169
 * @return string language variable
1170
 *
1171
 * @todo move to item manager
1172
 *
1173
 * @author Patrick Cool <[email protected]>, Ghent University
1174
 * @version february 2006, dokeos 1.8
1175
 */
1176
function change_lock_status($content, $id, $action)
1177
{
1178
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1179
    $table_forums = Database :: get_course_table(TABLE_FORUM);
1180
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1181
1182
    // Determine the relevant table.
1183
    if ($content == 'forumcategory') {
1184
        $table = $table_categories;
1185
        $id_field = 'cat_id';
1186
    } elseif ($content == 'forum') {
1187
        $table = $table_forums;
1188
        $id_field = 'forum_id';
1189
    } elseif ($content == 'thread') {
1190
        $table = $table_threads;
1191
        $id_field = 'thread_id';
1192
    } else {
1193
        return get_lang('Error');
1194
    }
1195
1196
    // Determine what we are doing => defines the value for the database and the return message.
1197
    if ($action == 'lock') {
1198
        $db_locked = 1;
1199
        $return_message = get_lang('Locked');
1200
    } elseif ($action == 'unlock') {
1201
        $db_locked = 0;
1202
        $return_message = get_lang('Unlocked');
1203
    } else {
1204
        return get_lang('Error');
1205
    }
1206
1207
    $course_id = api_get_course_int_id();
1208
1209
    // Doing the change in the database
1210
    $sql = "UPDATE $table SET locked='".Database::escape_string($db_locked)."'
1211
            WHERE c_id = $course_id AND $id_field='".Database::escape_string($id)."'";
1212
    if (Database::query($sql)) {
1213
        return $return_message;
1214
    } else {
1215
        return get_lang('Error');
1216
    }
1217
}
1218
1219
/**
1220
 * This function moves a forum or a forum category up or down
1221
 *
1222
 * @param $content what is it that we want to make (in)visible: forum category, forum, thread, post
1223
 * @param $direction do we want to move it up or down.
1224
 * @param $id the id of the content we want to make invisible
1225
 * @todo consider removing the table_item_property calls here but this can
1226
 * prevent unwanted side effects when a forum does not have an entry in
1227
 * the item_property table but does have one in the forum table.
1228
 * @return string language variable
1229
 *
1230
 * @author Patrick Cool <[email protected]>, Ghent University
1231
 * @version february 2006, dokeos 1.8
1232
 */
1233
function move_up_down($content, $direction, $id)
1234
{
1235
    $table_categories = Database:: get_course_table(TABLE_FORUM_CATEGORY);
1236
    $table_forums = Database:: get_course_table(TABLE_FORUM);
1237
    $table_item_property = Database:: get_course_table(TABLE_ITEM_PROPERTY);
1238
    $course_id = api_get_course_int_id();
1239
    $id = intval($id);
1240
1241
    // Determine which field holds the sort order.
1242
    if ($content == 'forumcategory') {
1243
        $table = $table_categories;
1244
        $sort_column = 'cat_order';
1245
        $id_column = 'cat_id';
1246
        $sort_column = 'cat_order';
1247
    } elseif ($content == 'forum') {
1248
        $table = $table_forums;
1249
        $sort_column = 'forum_order';
1250
        $id_column = 'forum_id';
1251
        $sort_column = 'forum_order';
1252
        // We also need the forum_category of this forum.
1253
        $sql = "SELECT forum_category FROM $table_forums
1254
                WHERE c_id = $course_id AND forum_id = " . intval($id);
1255
        $result = Database::query($sql);
1256
        $row = Database::fetch_array($result);
1257
        $forum_category = $row['forum_category'];
1258
    } else {
1259
        return get_lang('Error');
1260
    }
1261
1262
    // Determine the need for sorting ascending or descending order.
1263
    if ($direction == 'down') {
1264
        $sort_direction = 'ASC';
1265
    } elseif ($direction == 'up') {
1266
        $sort_direction = 'DESC';
1267
    } else {
1268
        return get_lang('Error');
1269
    }
1270
1271
    // The SQL statement
1272
    if ($content == 'forumcategory') {
1273
        $sql = "SELECT *
1274
                FROM $table_categories forum_categories, $table_item_property item_properties
1275
                WHERE
1276
                    forum_categories.c_id = $course_id AND
1277
                    item_properties.c_id = $course_id AND
1278
                    forum_categories.cat_id=item_properties.ref AND
1279
                    item_properties.tool='" . TOOL_FORUM_CATEGORY . "'
1280
                ORDER BY forum_categories.cat_order $sort_direction";
1281
    }
1282
    if ($content == 'forum') {
1283
        $sql = "SELECT *
1284
            FROM $table
1285
            WHERE
1286
                c_id = $course_id AND
1287
                forum_category='" . Database::escape_string($forum_category) . "'
1288
            ORDER BY forum_order $sort_direction";
1289
    }
1290
    // Finding the items that need to be switched.
1291
    $result = Database::query($sql);
1292
    $found = false;
1293
    while ($row = Database::fetch_array($result)) {
1294
        //echo $row[$id_column].'-';
1295
        if ($found) {
1296
            $next_id = $row[$id_column];
1297
            $next_sort = $row[$sort_column];
1298
            $found = false;
1299
        }
1300
        if ($id == $row[$id_column]) {
1301
            $this_id = $id;
1302
            $this_sort = $row[$sort_column];
1303
            $found = true;
1304
        }
1305
    }
1306
1307
    // Committing the switch.
1308
    // We do an extra check if we do not have illegal values. If your remove this if statment you will
1309
    // be able to mess with the sorting by refreshing the page over and over again.
1310
    if ($this_sort != '' && $next_sort != '' && $next_id != '' && $this_id != '') {
1311
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($this_sort) . "'
1312
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($next_id) . "'";
1313
        Database::query($sql);
1314
1315
        $sql = "UPDATE $table SET $sort_column='" . Database::escape_string($next_sort) . "'
1316
                WHERE c_id = $course_id AND $id_column='" . Database::escape_string($this_id) . "'";
1317
        Database::query($sql);
1318
    }
1319
1320
    return get_lang(ucfirst($content) . 'Moved');
1321
}
1322
1323
/**
1324
 * Retrieve all the information off the forum categories (or one specific) for the current course.
1325
 * The categories are sorted according to their sorting order (cat_order
1326
 *
1327
 * @param int|string $id default ''. When an id is passed we only find the information
1328
 * about that specific forum category. If no id is passed we get all the forum categories.
1329
 * @param int $courseId Optional. The course ID
1330
 * @param int $sessionId Optional. The session ID
1331
 * @return array containing all the information about all the forum categories
1332
 *
1333
 * @author Patrick Cool <[email protected]>, Ghent University
1334
 * @version february 2006, dokeos 1.8
1335
 */
1336
function get_forum_categories($id = '', $courseId = 0, $sessionId = 0)
1337
{
1338
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1339
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1340
1341
    // Condition for the session
1342
    $session_id = $sessionId ?: api_get_session_id();
1343
    $course_id = $courseId ?: api_get_course_int_id();
1344
1345
    $condition_session = api_get_session_condition($session_id, true, true, 'forum_categories.session_id');
1346
    $condition_session .= " AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id";
1347
1348
    if (empty($id)) {
1349
        $sql = "SELECT *
1350
                FROM $table_item_property item_properties 
1351
                INNER JOIN $table_categories forum_categories
1352
                ON (
1353
                    forum_categories.cat_id = item_properties.ref AND 
1354
                    item_properties.c_id = forum_categories.c_id
1355
                )
1356
                WHERE
1357
                    item_properties.visibility = 1 AND
1358
                    item_properties.tool = '".TOOL_FORUM_CATEGORY."'
1359
                    $condition_session
1360
                ORDER BY forum_categories.cat_order ASC";
1361
        if (api_is_allowed_to_edit()) {
1362
            $sql = "SELECT *
1363
                    FROM $table_item_property item_properties  
1364
                    INNER JOIN $table_categories forum_categories
1365
                    ON (
1366
                        forum_categories.cat_id = item_properties.ref AND 
1367
                        item_properties.c_id = forum_categories.c_id
1368
                    )
1369
                    WHERE
1370
                        item_properties.visibility<>2 AND
1371
                        item_properties.tool='".TOOL_FORUM_CATEGORY."'
1372
                        $condition_session
1373
                    ORDER BY forum_categories.cat_order ASC";
1374
        }
1375
    } else {
1376
        $sql = "SELECT *
1377
                FROM $table_item_property item_properties 
1378
                INNER JOIN $table_categories forum_categories
1379
                ON (
1380
                    forum_categories.cat_id = item_properties.ref AND 
1381
                    item_properties.c_id = forum_categories.c_id
1382
                )
1383
                WHERE
1384
                    item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
1385
                    forum_categories.cat_id = ".intval($id)."
1386
                    $condition_session
1387
                ORDER BY forum_categories.cat_order ASC";
1388
    }
1389
    $result = Database::query($sql);
1390
    $forum_categories_list = array();
1391
1392
    while ($row = Database::fetch_assoc($result)) {
1393
        if (empty($id)) {
1394
            $forum_categories_list[$row['cat_id']] = $row;
1395
        } else {
1396
            $forum_categories_list = $row;
1397
        }
1398
    }
1399
1400
    return $forum_categories_list;
1401
}
1402
1403
/**
1404
 * This function retrieves all the fora in a given forum category
1405
 *
1406
 * @param int $cat_id the id of the forum category
1407
 * @param int $courseId Optional. The course ID
1408
 * @return array containing all the information about the forums (regardless of their category)
1409
 *
1410
 * @author Patrick Cool <[email protected]>, Ghent University
1411
 * @version february 2006, dokeos 1.8
1412
 */
1413
function get_forums_in_category($cat_id, $courseId = 0)
1414
{
1415
    $table_forums = Database::get_course_table(TABLE_FORUM);
1416
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1417
1418
    $forum_list = array();
1419
    $course_id = $courseId ?: api_get_course_int_id();
1420
    $cat_id = (int) $cat_id;
1421
1422
    $sql = "SELECT * FROM $table_forums forum 
1423
            INNER JOIN $table_item_property item_properties
1424
            ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1425
            WHERE
1426
                forum.forum_category = '".$cat_id."' AND                
1427
                item_properties.visibility = 1 AND
1428
                forum.c_id = $course_id AND
1429
                item_properties.c_id = $course_id AND
1430
                item_properties.tool = '".TOOL_FORUM."'                 
1431
            ORDER BY forum.forum_order ASC";
1432
    if (api_is_allowed_to_edit()) {
1433
        $sql = "SELECT * FROM $table_forums forum  
1434
                INNER JOIN $table_item_property item_properties
1435
                ON (forum.forum_id = item_properties.ref AND item_properties.c_id = forum.c_id)
1436
                WHERE
1437
                    forum.forum_category = '".$cat_id."' AND                    
1438
                    item_properties.visibility <> 2 AND
1439
                    item_properties.tool = '".TOOL_FORUM."' AND
1440
                    item_properties.c_id = $course_id AND
1441
                    forum.c_id = $course_id
1442
                ORDER BY forum_order ASC";
1443
    }
1444
    $result = Database::query($sql);
1445
    while ($row = Database::fetch_array($result)) {
1446
        $forum_list[$row['forum_id']] = $row;
1447
    }
1448
1449
    return $forum_list;
1450
}
1451
1452
/**
1453
 * Retrieve all the forums (regardless of their category) or of only one.
1454
 * The forums are sorted according to the forum_order.
1455
 * Since it does not take the forum category into account there probably
1456
 * will be two or more forums that have forum_order=1, ...
1457
 * @param int $id forum id
1458
 * @param string $course_code
1459
 * @param bool $includeGroupsForum
1460
 * @param int $sessionId
1461
 * @return array an array containing all the information about the forums (regardless of their category)
1462
 * @todo check $sql4 because this one really looks fishy.
1463
 *
1464
 * @author Patrick Cool <[email protected]>, Ghent University
1465
 * @version february 2006, dokeos 1.8
1466
 */
1467
function get_forums(
1468
    $id = '',
1469
    $course_code = '',
1470
    $includeGroupsForum = true,
1471
    $sessionId = 0
1472
) {
1473
    $course_info = api_get_course_info($course_code);
1474
1475
    $table_forums = Database::get_course_table(TABLE_FORUM);
1476
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
1477
    $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1478
1479
    // Condition for the session
1480
    $session_id = intval($sessionId) ?: api_get_session_id();
1481
    $sessionIdLink = $session_id === 0 ? '' : ' AND threads.session_id = item_properties.session_id';
1482
1483
    $condition_session = api_get_session_condition(
1484
        $session_id,
1485
        true,
1486
        false,
1487
        'item_properties.session_id'
1488
    );
1489
    $course_id = $course_info['real_id'];
1490
1491
    $forum_list = array();
1492
    $includeGroupsForumSelect = '';
1493
    if (!$includeGroupsForum) {
1494
        $includeGroupsForumSelect = " AND forum_of_group = 0 ";
1495
    }
1496
1497
    if ($id == '') {
1498
        // Student
1499
        // Select all the forum information of all forums (that are visible to students).
1500
        $sql = "SELECT item_properties.*, forum.* 
1501
                FROM $table_forums forum
1502
                INNER JOIN $table_item_property item_properties
1503
                ON (
1504
                    forum.forum_id = item_properties.ref AND
1505
                    forum.c_id = item_properties.c_id
1506
                )
1507
                WHERE
1508
                    item_properties.visibility = 1 AND
1509
                    item_properties.tool = '".TOOL_FORUM."'
1510
                    $condition_session AND
1511
                    forum.c_id = $course_id AND
1512
                    item_properties.c_id = $course_id
1513
                    $includeGroupsForumSelect
1514
                ORDER BY forum.forum_order ASC";
1515
1516
        // Select the number of threads of the forums (only the threads that are visible).
1517
        $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1518
                FROM $table_threads threads
1519
                INNER JOIN $table_item_property item_properties
1520
                ON (
1521
                    threads.thread_id = item_properties.ref AND
1522
                    threads.c_id = item_properties.c_id
1523
                    $sessionIdLink
1524
                )
1525
                WHERE
1526
                    item_properties.visibility=1 AND
1527
                    item_properties.tool='".TOOL_FORUM_THREAD."' AND
1528
                    threads.c_id = $course_id AND
1529
                    item_properties.c_id = $course_id
1530
                GROUP BY threads.forum_id";
1531
1532
1533
        // Course Admin
1534 View Code Duplication
        if (api_is_allowed_to_edit()) {
1535
            // Select all the forum information of all forums (that are not deleted).
1536
            $sql = "SELECT item_properties.*, forum.* 
1537
                    FROM $table_forums forum
1538
                    INNER JOIN $table_item_property item_properties
1539
                    ON (
1540
                        forum.forum_id = item_properties.ref AND
1541
                        forum.c_id = item_properties.c_id
1542
                    )
1543
                    WHERE
1544
                        item_properties.visibility <> 2 AND
1545
                        item_properties.tool = '".TOOL_FORUM."'
1546
                        $condition_session AND
1547
                        forum.c_id = $course_id AND
1548
                        item_properties.c_id = $course_id
1549
                        $includeGroupsForumSelect
1550
                    ORDER BY forum_order ASC";
1551
1552
            // Select the number of threads of the forums (only the threads that are not deleted).
1553
            $sql2 = "SELECT count(*) AS number_of_threads, threads.forum_id
1554
                    FROM $table_threads threads
1555
                    INNER JOIN $table_item_property item_properties
1556
                    ON (
1557
                        threads.thread_id = item_properties.ref AND
1558
                        threads.c_id = item_properties.c_id
1559
                        $sessionIdLink
1560
                    )
1561
                    WHERE
1562
                        item_properties.visibility<>2 AND
1563
                        item_properties.tool='".TOOL_FORUM_THREAD."' AND
1564
                        threads.c_id = $course_id AND
1565
                        item_properties.c_id = $course_id
1566
                    GROUP BY threads.forum_id";
1567
        }
1568
    } else {
1569
        // GETTING ONE SPECIFIC FORUM
1570
        /* We could do the splitup into student and course admin also but we want
1571
        to have as much as information about a certain forum as possible
1572
        so we do not take too much information into account. This function
1573
         (or this section of the function) is namely used to fill the forms
1574
        when editing a forum (and for the moment it is the only place where
1575
        we use this part of the function) */
1576
1577
        // Select all the forum information of the given forum (that is not deleted).
1578
        $sql = "SELECT * FROM $table_item_property item_properties 
1579
                INNER JOIN $table_forums forum
1580
                ON (forum.forum_id = item_properties.ref AND forum.c_id = item_properties.c_id)
1581
                WHERE
1582
                    forum.forum_id = " . intval($id) . " AND
1583
                    forum.c_id = $course_id AND
1584
                    item_properties.visibility != 2 AND
1585
                    item_properties.tool = '".TOOL_FORUM."'
1586
                ORDER BY forum_order ASC";
1587
1588
        // Select the number of threads of the forum.
1589
        $sql2 = "SELECT count(*) AS number_of_threads, forum_id
1590
                FROM $table_threads
1591
                WHERE
1592
                    forum_id = ".intval($id)." AND
1593
                    c_id = $course_id
1594
                GROUP BY forum_id";
1595
    }
1596
1597
    // Handling all the forum information.
1598
1599
    $result = Database::query($sql);
1600
    while ($row = Database::fetch_assoc($result)) {
1601
        if ($id == '') {
1602
            $forum_list[$row['forum_id']] = $row;
1603
        } else {
1604
            $forum_list = $row;
1605
        }
1606
    }
1607
1608
    // Handling the thread count information.
1609
    $result2 = Database::query($sql2);
1610
    while ($row2 = Database::fetch_array($result2)) {
1611
        if ($id == '') {
1612
            $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
1613
        } else {
1614
            $forum_list['number_of_threads'] = $row2['number_of_threads'];
1615
        }
1616
    }
1617
1618
    /* Finding the last post information
1619
    (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)*/
1620
    if ($id == '') {
1621
        if (is_array($forum_list)) {
1622 View Code Duplication
            foreach ($forum_list as $key => $value) {
1623
                $last_post_info_of_forum = get_last_post_information(
1624
                    $key,
1625
                    api_is_allowed_to_edit(),
1626
                    $course_id
1627
                );
1628
                if ($last_post_info_of_forum) {
1629
                    $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1630
                    $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1631
                    $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1632
                    $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1633
                    $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1634
                    $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1635
                }
1636
            }
1637
        } else {
1638
            $forum_list = array();
1639
        }
1640
    } else {
1641
        $last_post_info_of_forum = get_last_post_information(
1642
            $id,
1643
            api_is_allowed_to_edit(),
1644
            $course_id
1645
        );
1646
        if ($last_post_info_of_forum) {
1647
            $forum_list['last_post_id'] = $last_post_info_of_forum['last_post_id'];
1648
            $forum_list['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
1649
            $forum_list['last_post_date'] = $last_post_info_of_forum['last_post_date'];
1650
            $forum_list['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
1651
            $forum_list['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
1652
            $forum_list['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
1653
        }
1654
    }
1655
1656
    return $forum_list;
1657
}
1658
1659
/**
1660
 * @param int $course_id
1661
 * @param int $thread_id
1662
 * @param int $forum_id
1663
 * @param bool $show_visible
1664
 * @return array|bool
1665
 */
1666
function get_last_post_by_thread($course_id, $thread_id, $forum_id, $show_visible = true)
1667
{
1668
    if (empty($thread_id) || empty($forum_id) || empty($course_id)) {
1669
        return false;
1670
    }
1671
1672
    $thread_id = intval($thread_id);
1673
    $forum_id = intval($forum_id);
1674
    $course_id = intval($course_id);
1675
1676
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1677
    $sql = "SELECT * FROM $table_posts
1678
            WHERE c_id = $course_id AND thread_id = $thread_id AND forum_id = $forum_id";
1679
1680
    if ($show_visible == false) {
1681
        $sql .= " AND visible = 1 ";
1682
    }
1683
1684
    $sql .= " ORDER BY post_id DESC LIMIT 1";
1685
    $result = Database::query($sql);
1686
    if (Database::num_rows($result)) {
1687
        return Database::fetch_array($result, 'ASSOC');
1688
    } else {
1689
        return false;
1690
    }
1691
}
1692
1693
/**
1694
 * This function gets all the last post information of a certain forum
1695
 *
1696
 * @param int   $forum_id the id of the forum we want to know the last post information of.
1697
 * @param bool  $show_invisibles
1698
 * @param string course db name
1699
 * @return array containing all the information about the last post
1700
 * (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname)
1701
 *
1702
 * @author Patrick Cool <[email protected]>, Ghent University
1703
 * @version february 2006, dokeos 1.8
1704
 */
1705
function get_last_post_information($forum_id, $show_invisibles = false, $course_id = null)
1706
{
1707
    if (!isset($course_id)) {
1708
        $course_id = api_get_course_int_id();
1709
    } else {
1710
        $course_id = intval($course_id);
1711
    }
1712
    $sessionId = api_get_session_id();
1713
1714
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
1715
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1716
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1717
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1718
1719
    $forum_id = intval($forum_id);
1720
    $return_array = array();
1721
1722
    // First get the threads to make sure there is no inconsistency in the
1723
    // database between forum and thread
1724
    $sql = "SELECT thread_id FROM $table_threads 
1725
            WHERE 
1726
                forum_id = $forum_id AND 
1727
                c_id = $course_id AND 
1728
                session_id = $sessionId";
1729
    $result = Database::query($sql);
1730
    if (Database::num_rows($result) == 0) {
1731
        // If there are no threads in this forum, then there are no posts
1732
        return [];
1733
    }
1734
    $threads = array();
1735
    while ($row = Database::fetch_row($result)) {
1736
        $threads[] = $row[0];
1737
    }
1738
    $threadsList = implode(',', $threads);
1739
1740
    $sql = "SELECT
1741
                post.post_id,
1742
                post.forum_id,
1743
                post.poster_id,
1744
                post.poster_name,
1745
                post.post_date,
1746
                users.lastname,
1747
                users.firstname,
1748
                post.visible,
1749
                thread_properties.visibility AS thread_visibility,
1750
                forum_properties.visibility AS forum_visibility
1751
            FROM
1752
                $table_posts post,
1753
                $table_users users,
1754
                $table_item_property thread_properties,
1755
                $table_item_property forum_properties
1756
            WHERE
1757
                post.forum_id = $forum_id
1758
                AND post.thread_id IN ($threadsList)
1759
                AND post.poster_id = users.user_id
1760
                AND post.thread_id = thread_properties.ref
1761
                AND thread_properties.tool='".TOOL_FORUM_THREAD."'
1762
                AND post.forum_id=forum_properties.ref
1763
                AND forum_properties.tool='".TOOL_FORUM."'
1764
                AND post.c_id = $course_id AND
1765
                thread_properties.c_id = $course_id AND
1766
                forum_properties.c_id = $course_id
1767
            ORDER BY post.post_id DESC";
1768
    $result = Database::query($sql);
1769
1770
    if ($show_invisibles) {
1771
        $row = Database::fetch_array($result);
1772
        $return_array['last_post_id'] = $row['post_id'];
1773
        $return_array['last_poster_id'] = $row['poster_id'];
1774
        $return_array['last_post_date'] = $row['post_date'];
1775
        $return_array['last_poster_name'] = $row['poster_name'];
1776
        $return_array['last_poster_lastname'] = $row['lastname'];
1777
        $return_array['last_poster_firstname'] = $row['firstname'];
1778
1779
        return $return_array;
1780
    } else {
1781
        // We have to loop through the results to find the first one that is
1782
        // actually visible to students (forum_category, forum, thread AND post are visible).
1783
        while ($row = Database::fetch_array($result)) {
1784
            if ($row['visible'] == '1' && $row['thread_visibility'] == '1' && $row['forum_visibility'] == '1') {
1785
                $return_array['last_post_id'] = $row['post_id'];
1786
                $return_array['last_poster_id'] = $row['poster_id'];
1787
                $return_array['last_post_date'] = $row['post_date'];
1788
                $return_array['last_poster_name'] = $row['poster_name'];
1789
                $return_array['last_poster_lastname'] = $row['lastname'];
1790
                $return_array['last_poster_firstname'] = $row['firstname'];
1791
1792
                return $return_array;
1793
            }
1794
        }
1795
    }
1796
}
1797
1798
/**
1799
 * Retrieve all the threads of a given forum
1800
 *
1801
 * @param int $forum_id
1802
 * @param int|null $courseId Optional If is null then it is considered the current course
1803
 * @param int|null $sessionId Optional. If is null then it is considered the current session
1804
 * @return array containing all the information about the threads
1805
 *
1806
 * @author Patrick Cool <[email protected]>, Ghent University
1807
 * @version february 2006, dokeos 1.8
1808
 */
1809
function get_threads($forum_id, $courseId = null, $sessionId = null)
1810
{
1811
    $groupId = api_get_group_id();
1812
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
1813
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
1814
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
1815
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
1816
1817
    $courseId = $courseId !== null ? intval($courseId) : api_get_course_int_id();
1818
    $groupInfo = GroupManager::get_group_properties($groupId);
1819
    $groupCondition = '';
1820
    if (!empty($groupInfo)) {
1821
        $groupIid = $groupInfo['iid'];
1822
        $groupCondition =  " AND item_properties.to_group_id = '$groupIid' ";
1823
    }
1824
    // important note:  it might seem a little bit awkward that we have 'thread.locked as locked' in the sql statement
1825
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'item_properties.session_id');
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
1830
    $sql = "SELECT DISTINCT
1831
                item_properties.*,
1832
                users.firstname,
1833
                users.lastname,
1834
                users.user_id,
1835
                thread.locked as locked,
1836
                thread.*
1837
            FROM $table_threads thread
1838
            INNER JOIN $table_item_property item_properties
1839
            ON
1840
                thread.thread_id = item_properties.ref AND
1841
                item_properties.c_id = thread.c_id AND
1842
                item_properties.tool = '".TABLE_FORUM_THREAD."' 
1843
                $groupCondition
1844
                $sessionCondition
1845
            LEFT JOIN $table_users users
1846
                ON thread.thread_poster_id = users.user_id
1847
            WHERE
1848
                item_properties.visibility='1' AND
1849
                thread.forum_id = ".intval($forum_id)." AND
1850
                thread.c_id = $courseId 
1851
            ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1852
1853
    if (api_is_allowed_to_edit()) {
1854
1855
        $sql = "SELECT DISTINCT
1856
                    item_properties.*,
1857
                    users.firstname,
1858
                    users.lastname,
1859
                    users.user_id,
1860
                    thread.locked as locked,
1861
                    thread.*
1862
                FROM $table_threads thread
1863
                INNER JOIN $table_item_property item_properties
1864
                ON
1865
                    thread.thread_id = item_properties.ref AND
1866
                    item_properties.c_id = thread.c_id AND
1867
                    item_properties.tool = '".TABLE_FORUM_THREAD."'
1868
                    $groupCondition
1869
                    $sessionCondition
1870
                LEFT JOIN $table_users users
1871
                    ON thread.thread_poster_id=users.user_id
1872
                WHERE
1873
                    item_properties.visibility<>2 AND
1874
                    thread.forum_id = ".intval($forum_id)." AND
1875
                    thread.c_id = $courseId 
1876
                ORDER BY thread.thread_sticky DESC, thread.thread_date DESC";
1877
    }
1878
1879
    $result = Database::query($sql);
1880
    $list = array();
1881
    $alreadyAdded = array();
1882 View Code Duplication
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1883
        if (in_array($row['thread_id'], $alreadyAdded)) {
1884
            continue;
1885
        }
1886
        $list[] = $row;
1887
        $alreadyAdded[] = $row['thread_id'];
1888
    }
1889
1890
    return $list;
1891
}
1892
1893
/**
1894
 * Get a thread by Id and course id
1895
 *
1896
 * @param int $threadId the thread Id
1897
 * @param int $cId the course id
1898
 * @return array containing all the information about the thread
1899
 */
1900
function getThreadInfo($threadId, $cId)
1901
{
1902
    $em = Database::getManager();
1903
    $forumThread = $em->getRepository('ChamiloCourseBundle:CForumThread')->findOneBy(['threadId' => $threadId, 'cId' => $cId]);
1904
    
1905
    $thread = [];
1906
    
1907
    if ($forumThread) {
1908
        $thread['threadId'] = $forumThread->getThreadId();
1909
        $thread['threadTitle'] = $forumThread->getThreadTitle();
1910
        $thread['forumId'] = $forumThread->getForumId();
1911
        $thread['sessionId'] = $forumThread->getSessionId();
1912
        $thread['threadSticky'] = $forumThread->getThreadSticky();
1913
        $thread['locked'] = $forumThread->getLocked();
1914
        $thread['threadTitleQualify'] = $forumThread->getThreadTitleQualify();
1915
        $thread['threadQualifyMax'] = $forumThread->getThreadQualifyMax();
1916
        $thread['threadCloseDate'] = $forumThread->getThreadCloseDate();
1917
        $thread['threadWeight'] = $forumThread->getThreadWeight();
1918
        $thread['threadPeerQualify'] = $forumThread->isThreadPeerQualify();
1919
    }
1920
1921
    return $thread;
1922
}
1923
1924
/**
1925
 * Retrieve all posts of a given thread
1926
 * @param array $forumInfo
1927
 * @param int $threadId The thread ID
1928
 * @param string $orderDirection Optional. The direction for sort the posts
1929
 * @param boolean $recursive Optional. If the list is recursive
1930
 * @param int $postId Optional. The post ID for recursive list
1931
 * @param int $depth Optional. The depth to indicate the indent
1932
 * @todo move to a repository
1933
 *
1934
 * @return array containing all the information about the posts of a given thread
1935
 */
1936
function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = false, $postId = null, $depth = -1)
1937
{
1938
1939
    $em = Database::getManager();
1940
1941
    if (api_is_allowed_to_edit(false, true)) {
1942
        $visibleCriteria = Criteria::expr()->neq('visible', 2);
1943
    } else {
1944
        $visibleCriteria = Criteria::expr()->eq('visible', 1);
1945
    }
1946
1947
    $criteria = Criteria::create();
1948
    $criteria
1949
        ->where(Criteria::expr()->eq('threadId', $threadId))
1950
        ->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
1951
        ->andWhere($visibleCriteria)
1952
    ;
1953
1954
    $groupId = api_get_group_id();
1955
    $groupInfo = GroupManager::get_group_properties($groupId);
1956
    $filterModerated = true;
1957
1958
    if (empty($groupId)) {
1959
        if (api_is_allowed_to_edit()) {
1960
            $filterModerated = false;
1961
        }
1962
    } else {
1963
        if (GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid']) || api_is_allowed_to_edit()) {
1964
            $filterModerated = false;
1965
        }
1966
    }
1967
1968
    if ($filterModerated && $forumInfo['moderated'] == 1) {
1969
        $criteria->andWhere(Criteria::expr()->eq('status', 1));
1970
    }
1971
1972
    if ($recursive) {
1973
        $criteria->andWhere(Criteria::expr()->eq('postParentId', $postId));
1974
    }
1975
1976
    $qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
1977
    $qb->select('p')
1978
        ->addCriteria($criteria)
1979
        ->addOrderBy('p.postId', $orderDirection);
1980
1981
    $posts = $qb->getQuery()->getResult();
1982
1983
    $depth++;
1984
    $list = [];
1985
    /** @var CForumPost $post */
1986
    foreach ($posts as $post) {
1987
        $postInfo = [
1988
            'iid' => $post->getIid(),
1989
            'c_id' => $post->getCId(),
1990
            'post_id' => $post->getPostId(),
1991
            'post_title' => $post->getPostTitle(),
1992
            'post_text' => $post->getPostText(),
1993
            'thread_id' => $post->getThreadId(),
1994
            'forum_id' => $post->getForumId(),
1995
            'poster_id' => $post->getPosterId(),
1996
            'poster_name' => $post->getPosterName(),
1997
            'post_date' => $post->getPostDate(),
1998
            'post_notification' => $post->getPostNotification(),
1999
            'post_parent_id' => $post->getPostParentId(),
2000
            'visible' => $post->getVisible(),
2001
            'status' => $post->getStatus(),
2002
            'indent_cnt' => $depth
2003
        ];
2004
        $posterId = $post->getPosterId();
2005
        if (!empty($posterId)) {
2006
            $user = $em->find('ChamiloUserBundle:User', $posterId);
2007
2008
            if ($user) {
2009
                $postInfo['user_id'] = $user->getUserId();
2010
                $postInfo['username'] = $user->getUsername();
2011
                $postInfo['username_canonical'] = $user->getUsernameCanonical();
2012
                $postInfo['lastname'] = $user->getLastname();
2013
                $postInfo['firstname'] = $user->getFirstname();
2014
            }
2015
        }
2016
2017
        $list[] = $postInfo;
2018
2019
        if (!$recursive) {
2020
            continue;
2021
        }
2022
2023
        $list = array_merge(
2024
            $list,
2025
            getPosts(
2026
                $forumInfo,
2027
                $threadId,
2028
                $orderDirection,
2029
                $recursive,
2030
                $post->getPostId(),
2031
                $depth
2032
            )
2033
        );
2034
    }
2035
2036
    return $list;
2037
}
2038
2039
/**
2040
 * This function retrieves all the information of a post
2041
 *
2042
 * @param int $post_id integer that indicates the forum
2043
 *
2044
 * @return array returns
2045
 *
2046
 * @author Patrick Cool <[email protected]>, Ghent University
2047
 * @version february 2006, dokeos 1.8
2048
 */
2049 View Code Duplication
function get_post_information($post_id)
2050
{
2051
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
2052
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
2053
    $course_id = api_get_course_int_id();
2054
2055
    $sql = "SELECT posts.*, email FROM ".$table_posts." posts, ".$table_users." users
2056
            WHERE
2057
                c_id = $course_id AND
2058
                posts.poster_id=users.user_id AND
2059
                posts.post_id = ".intval($post_id);
2060
    $result = Database::query($sql);
2061
    $row = Database::fetch_array($result, 'ASSOC');
2062
2063
    return $row;
2064
}
2065
2066
/**
2067
 * This function retrieves all the information of a thread
2068
 *
2069
 * @param int $forumId
2070
 * @param $thread_id integer that indicates the forum
2071
 * @param int|null $sessionId Optional. If is null then it is considered the current session
2072
 * @return array returns
2073
 *
2074
 * @author Patrick Cool <[email protected]>, Ghent University
2075
 * @version february 2006, dokeos 1.8
2076
 */
2077
function get_thread_information($forumId, $thread_id, $sessionId = null)
2078
{
2079
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2080
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
2081
    $thread_id = intval($thread_id);
2082
2083
    $sessionId = $sessionId !== null ? intval($sessionId) : api_get_session_id();
2084
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'threads.session_id');
2085
    $forumCondition = '';
2086
    if (!empty($forumId)) {
2087
        $forumId = (int) $forumId;
2088
        $forumCondition = " threads.forum_id = $forumId AND ";
2089
    }
2090
    $sql = "SELECT * FROM $table_item_property item_properties
2091
            INNER JOIN
2092
            $table_threads threads
2093
            ON (item_properties.ref = threads.thread_id AND threads.c_id = item_properties.c_id)
2094
            WHERE
2095
                $forumCondition
2096
                item_properties.tool= '".TOOL_FORUM_THREAD."' AND
2097
                threads.thread_id = $thread_id 
2098
                $sessionCondition
2099
            ";
2100
    $result = Database::query($sql);
2101
    $row = Database::fetch_assoc($result);
2102
2103
    return $row;
2104
}
2105
2106
/**
2107
 * This function retrieves forum thread users details
2108
 * @param   int Thread ID
2109
 * @param   string  Course DB name (optional)
2110
 * @return  Doctrine\DBAL\Driver\Statement|null array Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2111
 * @author Christian Fasanando <[email protected]>,
2112
 * @todo     this function need to be improved
2113
 * @version octubre 2008, dokeos 1.8
2114
 */
2115
function get_thread_users_details($thread_id)
2116
{
2117
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2118
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2119
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2120
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2121
2122
    $course_id = api_get_course_int_id();
2123
2124
    $is_western_name_order = api_is_western_name_order();
2125
    if ($is_western_name_order) {
2126
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2127
    } else {
2128
        $orderby = 'ORDER BY user.lastname, user.firstname';
2129
    }
2130
2131 View Code Duplication
    if (api_get_session_id()) {
2132
        $session_info = api_get_session_info(api_get_session_id());
2133
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2134
        //not showing coaches
2135
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2136
                  FROM $t_posts p, $t_users user, $t_session_rel_user session_rel_user_rel_course
2137
                  WHERE p.poster_id = user.id AND
2138
                  user.id = session_rel_user_rel_course.user_id AND
2139
                  session_rel_user_rel_course.status<>'2' AND
2140
                  session_rel_user_rel_course.user_id NOT IN ($user_to_avoid) AND
2141
                  p.thread_id = ".intval($thread_id)." AND
2142
                  session_id = ".api_get_session_id()." AND
2143
                  p.c_id = $course_id AND
2144
                  session_rel_user_rel_course.c_id = ".$course_id." $orderby ";
2145
    } else {
2146
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, thread_id
2147
                  FROM $t_posts p, $t_users user, $t_course_user course_user
2148
                  WHERE p.poster_id = user.id
2149
                  AND user.id = course_user.user_id
2150
                  AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2151
                  AND p.thread_id = ".intval($thread_id)."
2152
                  AND course_user.status NOT IN('1') AND
2153
                  p.c_id = $course_id AND
2154
                  course_user.c_id = ".$course_id." $orderby";
2155
    }
2156
    $result = Database::query($sql);
2157
2158
    return $result;
2159
}
2160
2161
/**
2162
 * This function retrieves forum thread users qualify
2163
 * @param   int Thread ID
2164
 * @param   string  Course DB name (optional)
2165
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2166
 * @author Jhon Hinojosa
2167
 * @todo     this function need to be improved
2168
 */
2169
function get_thread_users_qualify($thread_id)
2170
{
2171
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2172
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2173
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2174
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2175
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2176
2177
    $course_id = api_get_course_int_id();
2178
2179
    $is_western_name_order = api_is_western_name_order();
2180
    if ($is_western_name_order) {
2181
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2182
    } else {
2183
        $orderby = 'ORDER BY user.lastname, user.firstname';
2184
    }
2185
2186
    if (api_get_session_id()) {
2187
        $session_info = api_get_session_info(api_get_session_id());
2188
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2189
        //not showing coaches
2190
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2191
                FROM $t_posts post , $t_users user, $t_session_rel_user scu, $t_qualify qualify
2192
                WHERE poster_id = user.id
2193
                    AND post.poster_id = qualify.user_id
2194
                    AND user.id = session_rel_user_rel_course.user_id
2195
                    AND scu.status<>'2'
2196
                    AND scu.user_id NOT IN ($user_to_avoid)
2197
                    AND qualify.thread_id = ".intval($thread_id)."
2198
                    AND post.thread_id = ".intval($thread_id)."
2199
                    AND session_id = ".api_get_session_id()."
2200
                    AND scu.c_id = ".$course_id." AND
2201
                    qualify.c_id = $course_id AND
2202
                    post.c_id = $course_id
2203
                $orderby ";
2204
    } else {
2205
        $sql = "SELECT DISTINCT post.poster_id, user.lastname, user.firstname, post.thread_id,user.id,qualify.qualify
2206
                FROM $t_posts post,
2207
                     $t_qualify qualify,
2208
                     $t_users user,
2209
                     $t_course_user course_user
2210
                WHERE
2211
                     post.poster_id = user.id
2212
                     AND post.poster_id = qualify.user_id
2213
                     AND user.id = course_user.user_id
2214
                     AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2215
                     AND qualify.thread_id = ".intval($thread_id)."
2216
                     AND post.thread_id = ".intval($thread_id)."
2217
                     AND course_user.status not in('1')
2218
                     AND course_user.c_id = $course_id
2219
                     AND qualify.c_id = $course_id
2220
                     AND post.c_id = $course_id
2221
                 $orderby ";
2222
    }
2223
    $result = Database::query($sql);
2224
2225
    return $result;
2226
}
2227
2228
/**
2229
 * This function retrieves forum thread users not qualify
2230
 * @param   int Thread ID
2231
 * @param   string  Course DB name (optional)
2232
 * @return  Doctrine\DBAL\Driver\Statement|null Array of type ([user_id=>w,lastname=>x,firstname=>y,thread_id=>z],[])
2233
 * @author   Jhon Hinojosa<[email protected]>,
2234
 * @version oct 2008, dokeos 1.8
2235
 */
2236
function get_thread_users_not_qualify($thread_id)
2237
{
2238
    $t_posts = Database :: get_course_table(TABLE_FORUM_POST);
2239
    $t_qualify = Database :: get_course_table(TABLE_FORUM_THREAD_QUALIFY);
2240
    $t_users = Database :: get_main_table(TABLE_MAIN_USER);
2241
    $t_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
2242
    $t_session_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2243
2244
    $is_western_name_order = api_is_western_name_order();
2245
    if ($is_western_name_order) {
2246
        $orderby = 'ORDER BY user.firstname, user.lastname ';
2247
    } else {
2248
        $orderby = 'ORDER BY user.lastname, user.firstname';
2249
    }
2250
2251
    $course_id = api_get_course_int_id();
2252
2253
    $sql1 = "SELECT user_id FROM  $t_qualify
2254
             WHERE c_id = $course_id AND thread_id = '".$thread_id."'";
2255
    $result1 = Database::query($sql1);
2256
    $cad = '';
2257
    while ($row = Database::fetch_array($result1)) {
2258
        $cad .= $row['user_id'].',';
2259
    }
2260
    if ($cad == '') {
2261
        $cad = '0';
2262
    } else {
2263
        $cad = substr($cad, 0, strlen($cad) - 1);
2264
    }
2265
2266 View Code Duplication
    if (api_get_session_id()) {
2267
        $session_info = api_get_session_info(api_get_session_id());
2268
        $user_to_avoid = "'".$session_info['id_coach']."', '".$session_info['session_admin_id']."'";
2269
        //not showing coaches
2270
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2271
                FROM $t_posts post , $t_users user, $t_session_rel_user session_rel_user_rel_course
2272
                WHERE poster_id = user.id
2273
                    AND user.id NOT IN (".$cad.")
2274
                    AND user.id = session_rel_user_rel_course.user_id
2275
                    AND session_rel_user_rel_course.status<>'2'
2276
                    AND session_rel_user_rel_course.user_id NOT IN ($user_to_avoid)
2277
                    AND post.thread_id = ".intval($thread_id)."
2278
                    AND session_id = ".api_get_session_id()."
2279
                    AND session_rel_user_rel_course.c_id = $course_id AND post.c_id = $course_id $orderby ";
2280
    } else {
2281
        $sql = "SELECT DISTINCT user.id, user.lastname, user.firstname, post.thread_id
2282
                FROM $t_posts post, $t_users user,$t_course_user course_user
2283
                WHERE post.poster_id = user.id
2284
                AND user.id NOT IN (".$cad.")
2285
                AND user.id = course_user.user_id
2286
                AND course_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
2287
                AND post.thread_id = ".intval($thread_id)."
2288
                AND course_user.status not in('1')
2289
                AND course_user.c_id = $course_id AND post.c_id = $course_id  $orderby";
2290
    }
2291
    $result = Database::query($sql);
2292
2293
    return $result;
2294
}
2295
2296
/**
2297
 * This function retrieves all the information of a given forum_id
2298
 *
2299
 * @param $forum_id integer that indicates the forum
2300
 * @return array returns
2301
 *
2302
 * @author Patrick Cool <[email protected]>, Ghent University
2303
 * @version february 2006, dokeos 1.8
2304
 *
2305
 * @deprecated this functionality is now moved to get_forums($forum_id)
2306
 */
2307
function get_forum_information($forum_id, $courseId = 0)
2308
{
2309
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2310
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2311
    $courseId = empty($courseId) ? api_get_course_int_id(): intval($courseId);
2312
    $forum_id = intval($forum_id);
2313
2314
    $sql = "SELECT *
2315
            FROM $table_forums forums
2316
            INNER JOIN $table_item_property item_properties
2317
            ON (forums.c_id = item_properties.c_id)
2318
            WHERE
2319
                item_properties.tool = '".TOOL_FORUM."' AND
2320
                item_properties.ref = '".$forum_id."' AND
2321
                forums.forum_id = '".$forum_id."' AND
2322
                forums.c_id = ".$courseId."
2323
            ";
2324
2325
    $result = Database::query($sql);
2326
    $row = Database::fetch_array($result, 'ASSOC');
2327
    $row['approval_direct_post'] = 0;
2328
    // We can't anymore change this option, so it should always be activated.
2329
2330
    return $row;
2331
}
2332
2333
/**
2334
 * This function retrieves all the information of a given forumcategory id
2335
 *
2336
 * @param $cat_id integer that indicates the forum
2337
 *
2338
 * @return array returns if there are category or bool returns if there aren't category
2339
 * @author Patrick Cool <[email protected]>, Ghent University
2340
 * @version february 2006, dokeos 1.8
2341
 */
2342
function get_forumcategory_information($cat_id)
2343
{
2344
    $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY);
2345
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
2346
2347
    $course_id = api_get_course_int_id();
2348
    $sql = "SELECT *
2349
            FROM ".$table_categories." forumcategories, ".$table_item_property." item_properties
2350
            WHERE
2351
                forumcategories.c_id = $course_id AND
2352
                item_properties.c_id = $course_id AND
2353
                item_properties.tool='".TOOL_FORUM_CATEGORY."' AND
2354
                item_properties.ref='".Database::escape_string($cat_id)."' AND
2355
                forumcategories.cat_id='".Database::escape_string($cat_id)."'";
2356
    $result = Database::query($sql);
2357
    $row = Database::fetch_array($result);
2358
2359
    return $row;
2360
}
2361
2362
/**
2363
 * This function counts the number of forums inside a given category
2364
 *
2365
 * @param int $cat_id the id of the forum category
2366
 * @todo an additional parameter that takes the visibility into account. For instance $countinvisible=0 would return the number
2367
 *      of visible forums, $countinvisible=1 would return the number of visible and invisible forums
2368
 * @return int the number of forums inside the given category
2369
 *
2370
 * @author Patrick Cool <[email protected]>, Ghent University
2371
 * @version february 2006, dokeos 1.8
2372
 */
2373
function count_number_of_forums_in_category($cat_id)
2374
{
2375
    $table_forums = Database :: get_course_table(TABLE_FORUM);
2376
    $course_id = api_get_course_int_id();
2377
    $sql = "SELECT count(*) AS number_of_forums
2378
            FROM ".$table_forums."
2379
            WHERE c_id = $course_id AND forum_category='".Database::escape_string($cat_id)."'";
2380
    $result = Database::query($sql);
2381
    $row = Database::fetch_array($result);
2382
2383
    return $row['number_of_forums'];
2384
}
2385
2386
/**
2387
 * This function update a thread
2388
 *
2389
 * @param array $values - The form Values
2390
 * @return void HTML
2391
 *
2392
 */
2393
function updateThread($values)
2394
{
2395
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
2396
    $courseId = api_get_course_int_id();
2397
        
2398
    $params = [
2399
            'thread_title' => $values['thread_title'],
2400
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
2401
            'thread_title_qualify' => $values['calification_notebook_title'],
2402
            'thread_qualify_max' => $values['numeric_calification'],
2403
            'thread_weight' => $values['weight_calification'],
2404
            'thread_peer_qualify' => $values['thread_peer_qualify'],
2405
        ];
2406
        $where = ['c_id = ? AND thread_id = ?' => [$courseId, $values['thread_id']]];
2407
        Database::update($threadTable, $params, $where);
2408
        
2409
        if (api_is_course_admin() == true) {
2410
            $option_chek = isset($values['thread_qualify_gradebook']) ? $values['thread_qualify_gradebook'] : false; // values 1 or 0
2411
            if ($option_chek) {
2412
                $id = $values['thread_id'];
2413
                $titleGradebook = Security::remove_XSS(stripslashes($values['calification_notebook_title']));
2414
                $valueCalification = isset($values['numeric_calification']) ? intval($values['numeric_calification']) : 0;
2415
                $weightCalification = isset($values['weight_calification']) ? floatval($values['weight_calification']) : 0;
2416
                $description = '';
2417
                $sessionId = api_get_session_id();
2418
                $courseId = api_get_course_id();
2419
2420
                $linkInfo = GradebookUtils::isResourceInCourseGradebook(
2421
                    $courseId,
2422
                    LINK_FORUM_THREAD,
2423
                    $id,
2424
                    $sessionId
2425
                );
2426
                $linkId = $linkInfo['id'];
2427
2428
                if (!$linkInfo) {
2429
                    GradebookUtils::add_resource_to_course_gradebook(
2430
                        $values['category_id'],
2431
                        $courseId,
2432
                        LINK_FORUM_THREAD,
2433
                        $id,
2434
                        $titleGradebook,
2435
                        $weightCalification,
2436
                        $valueCalification,
2437
                        $description,
2438
                        1,
2439
                        $sessionId
2440
                    );
2441
                } else {
2442
                    $em = Database::getManager();
2443
                    $gradebookLink = $em->getRepository('ChamiloCoreBundle:GradebookLink')->find($linkId);
2444
                    $gradebookLink->setWeight($weightCalification);
2445
                    $em->persist($gradebookLink);
0 ignored issues
show
Bug introduced by
It seems like $gradebookLink defined by $em->getRepository('Cham...okLink')->find($linkId) on line 2443 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...
2446
                    $em->flush();
2447
                }
2448
            }
2449
        }
2450
        
2451
        $message = get_lang('EditPostStored').'<br />';
2452
        Display :: display_confirmation_message($message, false);
2453
}
2454
2455
/**
2456
 * This function stores a new thread. This is done through an entry in the forum_thread table AND
2457
 * in the forum_post table because. The threads are also stored in the item_property table. (forum posts are not (yet))
2458
 *
2459
 * @param array $current_forum
2460
 * @param array $values
2461
 * @param array $courseInfo
2462
 * @param bool $showMessage
2463
 * @param int $userId Optional. The user ID
2464
 * @param int $sessionId
2465
 * @return int
2466
 * @author Patrick Cool <[email protected]>, Ghent University
2467
 * @version february 2006, dokeos 1.8
2468
 */
2469
function store_thread($current_forum, $values, $courseInfo = array(), $showMessage = true, $userId = 0, $sessionId = 0)
2470
{
2471
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
2472
    $userId = $userId ?: api_get_user_id();
2473
    $course_id = $courseInfo['real_id'];
2474
    $courseCode = $courseInfo['code'];
2475
    $groupId = api_get_group_id();
2476
    $groupInfo = GroupManager::get_group_properties($groupId);
2477
    $groupIid = null;
2478
    if (!empty($groupInfo)) {
2479
        $groupIid = $groupInfo['iid'];
2480
    }
2481
    $sessionId = $sessionId ?: api_get_session_id();
2482
2483
    $em = Database::getManager();
2484
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
2485
    $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2486
    $upload_ok = 1;
2487
    $has_attachment = false;
2488
2489 View Code Duplication
    if (!empty($_FILES['user_upload']['name'])) {
2490
        $upload_ok = process_uploaded_file($_FILES['user_upload']);
2491
        $has_attachment = true;
2492
    }
2493
2494 View Code Duplication
    if (!$upload_ok) {
2495
        if ($showMessage) {
2496
            Display::addFlash(
2497
                Display::return_message(get_lang('UplNoFileUploaded'), 'error', false)
2498
            );
2499
        }
2500
2501
        return null;
2502
    }
2503
2504
    $post_date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
2505
2506 View Code Duplication
        if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2507
            $visible = 0; // The post has not been approved yet.
2508
        } else {
2509
            $visible = 1;
2510
        }
2511
2512
        $clean_post_title = $values['post_title'];
2513
2514
        // We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
2515
        $lastThread = new CForumThread();
2516
        $lastThread
0 ignored issues
show
Bug introduced by
The method setSessionId cannot be called on $lastThread->setCId($cou...ead_peer_qualify'] : 0) (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2517
            ->setCId($course_id)
2518
            ->setThreadTitle($clean_post_title)
2519
            ->setForumId($values['forum_id'])
2520
            ->setThreadPosterId($userId)
2521
            ->setThreadPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2522
            ->setThreadDate($post_date)
2523
            ->setThreadSticky(isset($values['thread_sticky']) ? $values['thread_sticky'] : 0)
2524
            ->setThreadTitleQualify(
2525
                isset($values['calification_notebook_title']) ? $values['calification_notebook_title'] : null
2526
            )
2527
            ->setThreadQualifyMax(isset($values['numeric_calification']) ? (int) $values['numeric_calification'] : 0)
2528
            ->setThreadWeight(isset($values['weight_calification']) ? (int) $values['weight_calification'] : 0)
2529
            ->setThreadPeerQualify(isset($values['thread_peer_qualify']) ? (int) $values['thread_peer_qualify'] : 0)
2530
            ->setSessionId($sessionId)
2531
            ->setLpItemId(isset($values['lp_item_id']) ? (int) $values['lp_item_id'] : 0)
2532
            ->setThreadId(0)
2533
            ->setLocked(0)
2534
        ;
2535
2536
        $em->persist($lastThread);
2537
        $em->flush();
2538
2539
        // Add option gradebook qualify.
2540
2541
        if (isset($values['thread_qualify_gradebook']) &&
2542
            1 == $values['thread_qualify_gradebook']
2543
        ) {
2544
            // Add function gradebook.
2545
            $resourcetype = 5;
2546
            $resourceid = $lastThread->getIid();
2547
            $resourcename = stripslashes($values['calification_notebook_title']);
2548
            $maxqualify = $values['numeric_calification'];
2549
            $weigthqualify = $values['weight_calification'];
2550
            $resourcedescription = '';
2551
            GradebookUtils::add_resource_to_course_gradebook(
2552
                $values['category_id'],
2553
                $courseCode,
2554
                $resourcetype,
2555
                $resourceid,
2556
                $resourcename,
2557
                $weigthqualify,
2558
                $maxqualify,
2559
                $resourcedescription,
2560
                0,
2561
                $sessionId
2562
            );
2563
        }
2564
2565
        if ($lastThread->getIid()) {
2566
            $lastThread->setThreadId($lastThread->getIid());
2567
2568
            $em->merge($lastThread);
2569
            $em->flush();
2570
2571
            api_item_property_update(
2572
                $courseInfo,
2573
                TOOL_FORUM_THREAD,
2574
                $lastThread->getIid(),
2575
                'ForumThreadAdded',
2576
                $userId,
2577
                $groupIid,
2578
                null,
2579
                null,
2580
                null,
2581
                $sessionId
2582
            );
2583
2584
            // If the forum properties tell that the posts have to be approved
2585
            // we have to put the whole thread invisible,
2586
            // because otherwise the students will see the thread and not the post
2587
            // in the thread.
2588
            // We also have to change $visible because the post itself has to be
2589
            // visible in this case (otherwise the teacher would have
2590
            // to make the thread visible AND the post.
2591
            // Default behaviour
2592
            api_set_default_visibility(
2593
                $lastThread->getIid(),
2594
                TOOL_FORUM_THREAD,
2595
                $groupIid,
2596
                $courseInfo,
2597
                $sessionId,
2598
                $userId
2599
            );
2600
2601
            if ($visible == 0) {
2602
                api_item_property_update(
2603
                    $courseInfo,
2604
                    TOOL_FORUM_THREAD,
2605
                    $lastThread->getIid(),
2606
                    'invisible',
2607
                    $userId,
2608
                    $groupIid
2609
                );
2610
                $visible = 1;
2611
            }
2612
        }
2613
2614
        // We now store the content in the table_post table.
2615
    $lastPost = new CForumPost();
2616
    $lastPost
2617
        ->setCId($course_id)
2618
        ->setPostTitle($clean_post_title)
2619
        ->setPostText($values['post_text'])
2620
        ->setThreadId($lastThread->getIid())
2621
        ->setForumId($values['forum_id'])
2622
        ->setPosterId($userId)
2623
        ->setPosterName(isset($values['poster_name']) ? $values['poster_name'] : null)
2624
        ->setPostDate($post_date)
2625
        ->setPostNotification(isset($values['post_notification']) ? (int) $values['post_notification'] : null)
2626
        ->setPostParentId(null)
2627
        ->setVisible($visible)
2628
        ->setPostId(0)
2629
        ->setStatus(CForumPost::STATUS_VALIDATED);
2630
2631
    if ($current_forum['moderated']) {
2632
        $lastPost->setStatus(
2633
            api_is_course_admin() ? CForumPost::STATUS_VALIDATED : CForumPost::STATUS_WAITING_MODERATION
2634
        );
2635
    }
2636
2637
    $em->persist($lastPost);
2638
    $em->flush();
2639
2640
    $last_post_id = $lastPost->getIid();
2641
2642
    if ($last_post_id) {
2643
        $lastPost->setPostId($last_post_id);
2644
        $em->merge($lastPost);
2645
        $em->flush();
2646
    }
2647
2648
    // Update attached files
2649 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
2650
        foreach ($_POST['file_ids'] as $key => $id) {
2651
            editAttachedFile(
2652
                array(
2653
                    'comment' => $_POST['file_comments'][$key],
2654
                    'post_id' => $last_post_id
2655
                ),
2656
                $id
2657
            );
2658
        }
2659
    }
2660
2661
    // Now we have to update the thread table to fill the thread_last_post
2662
    // field (so that we know when the thread has been updated for the last time).
2663
    $sql = "UPDATE $table_threads
2664
            SET thread_last_post = '".Database::escape_string($last_post_id)."'
2665
            WHERE
2666
                c_id = $course_id AND
2667
            thread_id='".Database::escape_string($lastThread->getIid())."'";
2668
    $result = Database::query($sql);
2669
    $message = get_lang('NewThreadStored');
2670
    // Storing the attachments if any.
2671
    if ($has_attachment) {
2672
2673
        // Try to add an extension to the file if it hasn't one.
2674
        $new_file_name = add_ext_on_mime(
2675
            stripslashes($_FILES['user_upload']['name']),
2676
            $_FILES['user_upload']['type']
2677
        );
2678
2679
        if (!filter_extension($new_file_name)) {
2680
            if ($showMessage) {
2681
                Display:: display_error_message(
2682
                    get_lang('UplUnableToSaveFileFilteredExtension')
2683
                );
2684
            }
2685
        } else {
2686
            if ($result) {
2687
                add_forum_attachment_file(
2688
                    isset($values['file_comment']) ? $values['file_comment'] : null,
2689
                    $last_post_id
2690
                );
2691
            }
2692
        }
2693
    } else {
2694
        $message .= '<br />';
2695
    }
2696
2697
    if ($current_forum['approval_direct_post'] == '1' && !api_is_allowed_to_edit(null, true)) {
2698
        $message .= get_lang('MessageHasToBeApproved').'<br />';
2699
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2700
        get_lang('Forum').'</a><br />';
2701
    } else {
2702
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'">'.
2703
        get_lang('Forum').'</a><br />';
2704
    $message .= get_lang('ReturnTo').' <a href="viewthread.php?'.api_get_cidreq().'&forum='.$values['forum_id'].'&gradebook='.$gradebook.'&thread='.$lastThread->getIid().'">'.
2705
        get_lang('Message').'</a>';
2706
    }
2707
    $reply_info['new_post_id'] = $last_post_id;
2708
    $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
2709
2710
    if ($my_post_notification == 1) {
2711
        set_notification('thread', $lastThread->getIid(), true);
2712
    }
2713
2714
    send_notification_mails(
2715
        $current_forum['forum_id'],
2716
        $lastThread->getIid(),
2717
        $reply_info,
2718
        $courseInfo['code']
2719
    );
2720
2721
    Session::erase('formelements');
2722
    Session::erase('origin');
2723
    Session::erase('breadcrumbs');
2724
    Session::erase('addedresource');
2725
    Session::erase('addedresourceid');
2726
    if ($showMessage) {
2727
        Display::addFlash(Display::return_message($message, 'success', false));
2728
    }
2729
    return $lastThread->getIid();
2730
}
2731
2732
/**
2733
 * This function displays the form that is used to UPDATE a Thread.
2734
 * @param array $currentForum
2735
 * @param array $forumSetting
2736
 * @param array $formValues
2737
 * @return void HMTL
2738
 * @author José Loguercio <[email protected]>
2739
 * @version february 2016, chamilo 1.10.4
2740
 */
2741
function showUpdateThreadForm($currentForum, $forumSetting, $formValues = '')
2742
{
2743
    
2744
    $myThread = isset($_GET['thread']) ? intval($_GET['thread']) : '';
2745
    $myForum = isset($_GET['forum']) ? intval($_GET['forum']) : '';
2746
    $myGradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2747
    $form = new FormValidator(
2748
        'thread',
2749
        'post',
2750
        api_get_self() . '?' . http_build_query([
2751
            'forum' => $myForum,
2752
            'gradebook' => $myGradebook,
2753
            'thread' => $myThread,
2754
        ]) . '&' . api_get_cidreq()
2755
    );
2756
    
2757
    $form->addElement('header', get_lang('EditThread'));
2758
    $form->setConstants(array('forum' => '5'));
2759
    $form->addElement('hidden', 'forum_id', $myForum);
2760
    $form->addElement('hidden', 'thread_id', $myThread);
2761
    $form->addElement('hidden', 'gradebook', $myGradebook);
2762
    $form->addElement('text', 'thread_title', get_lang('Title'));
2763
    $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2764
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2765
2766
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && ($myThread)) {
2767
        // Thread qualify
2768
        if (Gradebook::is_active()) {
2769
            //Loading gradebook select
2770
            GradebookUtils::load_gradebook_select_in_tool($form);
2771
            $form->addElement(
2772
                'checkbox',
2773
                'thread_qualify_gradebook',
2774
                '',
2775
                get_lang('QualifyThreadGradebook'),
2776
                [
2777
                    'id' => 'thread_qualify_gradebook'
2778
                ]
2779
            );
2780
        } else {
2781
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2782
        }
2783
        
2784
        $form->addElement('html', '<div id="options_field" style="display:none">');
2785
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2786
        $form->applyFilter('numeric_calification', 'html_filter');
2787
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2788
        $form->applyFilter('calification_notebook_title', 'html_filter');
2789
        $form->addElement(
2790
            'text',
2791
            'weight_calification',
2792
            get_lang('QualifyWeight'),
2793
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2794
        );
2795
        $form->applyFilter('weight_calification', 'html_filter');
2796
        $group = array();
2797
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2798
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2799
        $form->addGroup(
2800
            $group,
2801
            '',
2802
            [
2803
                get_lang('ForumThreadPeerScoring'),
2804
                get_lang('ForumThreadPeerScoringComment'),
2805
            ]
2806
        );
2807
        $form->addElement('html', '</div>');
2808
    }
2809
2810 View Code Duplication
    if ($forumSetting['allow_sticky'] && api_is_allowed_to_edit(null, true)) {
2811
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2812
    }
2813
    
2814
    $form->addElement('html', '</div>');
2815
    
2816
    if (!empty($formValues)) {
2817
        $defaults['thread_qualify_gradebook'] = ($formValues['threadQualifyMax'] > 0 && empty($_POST)) ? 1 : 0 ;
2818
        $defaults['thread_title'] = prepare4display($formValues['threadTitle']);
2819
        $defaults['thread_sticky'] = strval(intval($formValues['threadSticky']));
2820
        $defaults['thread_peer_qualify'] = intval($formValues['threadPeerQualify']);
2821
        $defaults['numeric_calification'] = $formValues['threadQualifyMax'];
2822
        $defaults['calification_notebook_title'] = $formValues['threadTitleQualify'];
2823
        $defaults['weight_calification'] = $formValues['threadWeight'];
2824
    } else {
2825
        $defaults['thread_qualify_gradebook'] = 0;
2826
        $defaults['numeric_calification'] = 0;
2827
        $defaults['calification_notebook_title'] = '';
2828
        $defaults['weight_calification'] = 0;
2829
        $defaults['thread_peer_qualify'] = 0;
2830
    }
2831
    $form->setDefaults(isset($defaults) ? $defaults : null);
2832
    
2833
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
2834
    
2835
    if ($form->validate()) {
2836
        $check = Security::check_token('post');
2837
        if ($check) {
2838
            $values = $form->exportValues();
2839
            if (isset($values['thread_qualify_gradebook']) &&
2840
                $values['thread_qualify_gradebook'] == '1' &&
2841
                empty($values['weight_calification'])
2842
            ) {
2843
                Display::display_error_message(
2844
                    get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.
2845
                    get_lang('Back').'</a>',
2846
                    false
2847
                );
2848
                return false;
2849
            }
2850
            Security::clear_token();
2851
            return $values;
2852
        }
2853
    } else {
2854
        $token = Security::get_token();
2855
        $form->addElement('hidden', 'sec_token');
2856
        $form->setConstants(array('sec_token' => $token));
2857
        
2858
        
2859
        $form->display();
2860
    }
2861
}
2862
2863
/**
2864
 * This function displays the form that is used to add a post. This can be a new thread or a reply.
2865
 * @param array $current_forum
2866
 * @param array $forum_setting
2867
 * @param string $action is the parameter that determines if we are
2868
 *  1. newthread: adding a new thread (both empty) => No I-frame
2869
 *  2. replythread: Replying to a thread ($action = replythread) => I-frame with the complete thread (if enabled)
2870
 *  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)
2871
 *  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)
2872
 * @return FormValidator
2873
 * @author Patrick Cool <[email protected]>, Ghent University
2874
 * @version february 2006, dokeos 1.8
2875
 */
2876
function show_add_post_form($current_forum, $forum_setting, $action, $id = '', $form_values = '')
2877
{
2878
    $_user = api_get_user_info();
2879
    $action = isset($action) ? Security::remove_XSS($action) : '';
2880
    $myThread = isset($_GET['thread']) ? (int) $_GET['thread'] : '';
2881
    $forumId = isset($_GET['forum']) ? (int) $_GET['forum'] : '';
2882
    $my_post = isset($_GET['post']) ? (int) $_GET['post'] : '';
2883
    $my_gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : '';
2884
    $url = api_get_self() . '?' . http_build_query([
2885
        'action' => $action,
2886
        'forum' => $forumId,
2887
        'gradebook' => $my_gradebook,
2888
        'thread' => $myThread,
2889
        'post' => $my_post
2890
    ]) . '&' . api_get_cidreq();
2891
    $form = new FormValidator(
2892
        'thread',
2893
        'post',
2894
        $url
2895
    );
2896
    $form->setConstants(array('forum' => '5'));
2897
2898
    // Setting the form elements.
2899
    $form->addElement('hidden', 'forum_id', $forumId);
2900
    $form->addElement('hidden', 'thread_id', $myThread);
2901
    $form->addElement('hidden', 'gradebook', $my_gradebook);
2902
    $form->addElement('hidden', 'action', $action);
2903
2904
    // If anonymous posts are allowed we also display a form to allow the user to put his name or username in.
2905
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
2906
        $form->addElement('text', 'poster_name', get_lang('Name'));
2907
        $form->applyFilter('poster_name', 'html_filter');
2908
    }
2909
2910
    $form->addElement('text', 'post_title', get_lang('Title'));
2911
    $form->addHtmlEditor(
2912
        'post_text',
2913
        get_lang('Text'),
2914
        true,
2915
        false,
2916
        api_is_allowed_to_edit(null, true) ? array(
2917
            'ToolbarSet' => 'Forum',
2918
            'Width' => '100%',
2919
            'Height' => '300',
2920
        ) : array(
2921
            'ToolbarSet' => 'ForumStudent',
2922
            'Width' => '100%',
2923
            'Height' => '300',
2924
            'UserStatus' => 'student'
2925
        )
2926
    );
2927
2928
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
2929
    $iframe = null;
2930
    $myThread = Security::remove_XSS($myThread);
2931
    if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
2932
        $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?".api_get_cidreq()."&forum=".intval($forumId)."&thread=".$myThread."#".Security::remove_XSS($my_post)."\" width=\"100%\"></iframe>";
2933
    }
2934
    if (!empty($iframe)) {
2935
        $form->addElement('label', get_lang('Thread'), $iframe);
2936
    }
2937
2938
    if ((api_is_course_admin() || api_is_course_coach() || api_is_course_tutor()) && !($myThread)) {
2939
        $form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
2940
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
2941
2942
2943
        // Thread qualify
2944
        if (Gradebook::is_active()) {
2945
            //Loading gradebook select
2946
            GradebookUtils::load_gradebook_select_in_tool($form);
2947
            $form->addElement(
2948
                'checkbox',
2949
                'thread_qualify_gradebook',
2950
                '',
2951
                get_lang('QualifyThreadGradebook'),
2952
                'onclick="javascript:if(this.checked==true){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
2953
            );
2954
        } else {
2955
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
2956
        }
2957
2958
        $form->addElement('html', '<div id="options_field" style="display:none">');
2959
2960
        $form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
2961
        $form->applyFilter('numeric_calification', 'html_filter');
2962
2963
        $form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
2964
        $form->applyFilter('calification_notebook_title', 'html_filter');
2965
2966
        $form->addElement(
2967
            'text',
2968
            'weight_calification',
2969
            get_lang('QualifyWeight'),
2970
            array('value' => '0.00', 'onfocus' => "javascript: this.select();")
2971
        );
2972
        $form->applyFilter('weight_calification', 'html_filter');
2973
2974
        $group = array();
2975
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
2976
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
2977
        $form->addGroup(
2978
            $group,
2979
            '',
2980
            [
2981
                get_lang('ForumThreadPeerScoring'),
2982
                get_lang('ForumThreadPeerScoringComment'),
2983
            ]
2984
        );
2985
2986
        $form->addElement('html', '</div>');
2987
        $form->addElement('html', '</div>');
2988
    }
2989
2990 View Code Duplication
    if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
2991
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
2992
    }
2993
2994
    if (in_array($action, ['quote', 'replymessage'])) {
2995
        $form->addFile('user_upload[]', get_lang('Attachment'));
2996
        $form->addButton(
2997
            'add_attachment',
2998
            get_lang('AddAttachment'),
2999
            'paperclip',
3000
            'default',
3001
            'default',
3002
            null,
3003
            ['id' => 'reply-add-attachment']
3004
        );
3005
    } else {
3006
        $form->addFile('user_upload', get_lang('Attachment'));
3007
    }
3008
3009
    // Setting the class and text of the form title and submit button.
3010
    if ($action == 'quote') {
3011
        $form->addButtonCreate(get_lang('QuoteMessage'), 'SubmitPost');
3012
    } elseif ($action == 'replythread') {
3013
        $form->addButtonCreate(get_lang('ReplyToThread'), 'SubmitPost');
3014
    } elseif ($action == 'replymessage') {
3015
        $form->addButtonCreate(get_lang('ReplyToMessage'), 'SubmitPost');
3016
    } else {
3017
        $form->addButtonCreate(get_lang('CreateThread'), 'SubmitPost');
3018
    }
3019
3020
    if (!empty($form_values)) {
3021
        $defaults['post_title'] = prepare4display($form_values['post_title']);
3022
        $defaults['post_text'] = prepare4display($form_values['post_text']);
3023
        $defaults['post_notification'] = strval(intval($form_values['post_notification']));
3024
        $defaults['thread_sticky'] = strval(intval($form_values['thread_sticky']));
3025
        $defaults['thread_peer_qualify'] = intval($form_values['thread_peer_qualify']);
3026
    } else {
3027
        $defaults['thread_peer_qualify'] = 0;
3028
    }
3029
3030
    // If we are quoting a message we have to retrieve the information of the post we are quoting so that
3031
    // we can add this as default to the textarea.
3032
3033
    if (($action == 'quote' || $action == 'replymessage') && isset($my_post)) {
3034
        // We also need to put the parent_id of the post in a hidden form when
3035
        // we are quoting or replying to a message (<> reply to a thread !!!)
3036
        $form->addHidden('post_parent_id', intval($my_post));
3037
3038
        // If we are replying or are quoting then we display a default title.
3039
        $values = get_post_information($my_post);
3040
        $posterInfo = api_get_user_info($values['poster_id']);
3041
        $posterName = '';
3042
        if ($posterInfo) {
3043
            $posterName = $posterInfo['complete_name'];
3044
        }
3045
        $defaults['post_title'] = get_lang('ReplyShort').api_html_entity_decode($values['post_title'], ENT_QUOTES);
3046
        // When we are quoting a message then we have to put that message into the wysiwyg editor.
3047
        // Note: The style has to be hardcoded here because using class="quote" didn't work.
3048
        if ($action == 'quote') {
3049
            $defaults['post_text'] = '<div>&nbsp;</div>
3050
                <div style="margin: 5px;">
3051
                    <div style="font-size: 90%; font-style: italic;">'.
3052
                        get_lang('Quoting').' '.$posterName.':</div>
3053
                        <div style="color: #006600; font-size: 90%;  font-style: italic; background-color: #FAFAFA; border: #D1D7DC 1px solid; padding: 3px;">'.
3054
                            prepare4display($values['post_text']).'
3055
                        </div>
3056
                    </div>
3057
                <div>&nbsp;</div>
3058
                <div>&nbsp;</div>
3059
            ';
3060
        }
3061
    }
3062
3063
    $form->setDefaults(isset($defaults) ? $defaults : []);
3064
3065
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3066
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3067
    if ($current_forum['allow_anonymous'] == 1 && !isset($_user['user_id'])) {
3068
        $form->addRule('poster_name', get_lang('ThisFieldIsRequired'), 'required');
3069
    }
3070
3071
    // Validation or display
3072
    if ($form->validate()) {
3073
        $check = Security::check_token('post');
3074
        if ($check) {
3075
            $values = $form->exportValues();
3076
            if (isset($values['thread_qualify_gradebook']) &&
3077
                $values['thread_qualify_gradebook'] == '1' &&
3078
                empty($values['weight_calification'])
3079
            ) {
3080
                Display::addFlash(
3081
                    Display::return_message(
3082
                    get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>',
3083
                    'error',
3084
                    false
3085
                    )
3086
                );
3087
3088
                return false;
3089
            }
3090
3091
            switch ($action) {
3092
                case 'newthread':
3093
                    $myThread = store_thread($current_forum, $values);
3094
                    break;
3095
                case 'quote':
3096
                case 'replythread':
3097
                case 'replymessage':
3098
                    store_reply($current_forum, $values);
3099
3100
                    break;
3101
            }
3102
3103
            $url = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&'.http_build_query(
3104
                [
3105
                    'forum' => $forumId,
3106
                    'thread' => $myThread
3107
                ]
3108
            );
3109
3110
            Security::clear_token();
3111
            header('Location: '.$url);
3112
            exit;
3113
        }
3114
    } else {
3115
        $token = Security::get_token();
3116
        $form->addElement('hidden', 'sec_token');
3117
        $form->setConstants(array('sec_token' => $token));
3118
3119
        // Delete from $_SESSION forum attachment from other posts
3120
        // and keep only attachments for new post
3121
        clearAttachedFiles(FORUM_NEW_POST);
3122
        // Get forum attachment ajax table to add it to form
3123
        $attachmentAjaxTable = getAttachmentsAjaxTable(0, $current_forum['forum_id']);
3124
        $ajaxHtml = $attachmentAjaxTable;
3125
        $form->addElement('html', $ajaxHtml);
3126
3127
        return $form;
3128
    }
3129
}
3130
3131
/**
3132
 * @param array $threadInfo
3133
 * @param integer $user_id
3134
 * @param integer $thread_id
3135
 * @param integer $thread_qualify
3136
 * @param integer $qualify_time
3137
 * @param integer $session_id
3138
 * @return array optional
3139
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3140
 * @version October 2008, dokeos  1.8.6
3141
 */
3142
function saveThreadScore(
3143
    $threadInfo,
3144
    $user_id,
3145
    $thread_id,
3146
    $thread_qualify = 0,
3147
    $qualify_time,
3148
    $session_id = 0
3149
) {
3150
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3151
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3152
3153
    $course_id = api_get_course_int_id();
3154
    $session_id = intval($session_id);
3155
    $currentUserId = api_get_user_id();
3156
3157
    if ($user_id == strval(intval($user_id)) &&
3158
        $thread_id == strval(intval($thread_id)) &&
3159
        $thread_qualify == strval(floatval($thread_qualify))
3160
    ) {
3161
        // Testing
3162
        $sql = "SELECT thread_qualify_max FROM $table_threads
3163
                WHERE c_id = $course_id AND thread_id=".$thread_id;
3164
        $res_string = Database::query($sql);
3165
        $row_string = Database::fetch_array($res_string);
3166
        if ($thread_qualify <= $row_string[0]) {
3167
3168
            if ($threadInfo['thread_peer_qualify'] == 0) {
3169
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3170
                        WHERE
3171
                            c_id = $course_id AND
3172
                            user_id = $user_id AND
3173
                            thread_id = ".$thread_id;
3174
            } else {
3175
                $sql = "SELECT COUNT(*) FROM $table_threads_qualify
3176
                        WHERE
3177
                            c_id = $course_id AND
3178
                            user_id = $user_id AND
3179
                            qualify_user_id = $currentUserId AND
3180
                            thread_id = ".$thread_id;
3181
            }
3182
3183
            $result = Database::query($sql);
3184
            $row = Database::fetch_array($result);
3185
3186
            if ($row[0] == 0) {
3187
                $sql = "INSERT INTO $table_threads_qualify (c_id, user_id, thread_id,qualify,qualify_user_id,qualify_time,session_id)
3188
                        VALUES (".$course_id.", '".$user_id."','".$thread_id."',".(float)$thread_qualify.", '".$currentUserId."','".$qualify_time."','".$session_id."')";
3189
                Database::query($sql);
3190
3191
                $insertId = Database::insert_id();
3192
                if ($insertId) {
3193
                    $sql = "UPDATE $table_threads_qualify SET id = iid
3194
                            WHERE iid = $insertId";
3195
                    Database::query($sql);
3196
                }
3197
3198
                return 'insert';
3199
            } else {
3200
3201
                saveThreadScoreHistory(
3202
                    '1',
3203
                    $course_id,
3204
                    $user_id,
3205
                    $thread_id
3206
                );
3207
3208
3209
                // Update
3210
                $sql = "UPDATE $table_threads_qualify
3211
                        SET
3212
                            qualify = '".$thread_qualify."',
3213
                            qualify_time = '".$qualify_time."'
3214
                        WHERE
3215
                            c_id = $course_id AND
3216
                            user_id=".$user_id." AND
3217
                            thread_id=".$thread_id." AND
3218
                            qualify_user_id = $currentUserId
3219
                        ";
3220
                Database::query($sql);
3221
3222
                return 'update';
3223
            }
3224
3225
        } else {
3226
            return null;
3227
        }
3228
    }
3229
}
3230
3231
/**
3232
 * This function shows qualify.
3233
 * @param string $option contains the information of option to run
3234
 * @param integer $user_id contains the information the current user id
3235
 * @param integer $thread_id contains the information the current thread id
3236
 * @return integer qualify
3237
 * <code> $option=1 obtained the qualification of the current thread</code>
3238
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3239
 * @version October 2008, dokeos  1.8.6
3240
 */
3241
function showQualify($option, $user_id, $thread_id)
3242
{
3243
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3244
    $table_threads = Database::get_course_table(TABLE_FORUM_THREAD);
3245
3246
    $course_id = api_get_course_int_id();
3247
    $user_id = intval($user_id);
3248
    $thread_id = intval($thread_id);
3249
3250
    if (empty($user_id) || empty($thread_id)) {
3251
        return false;
3252
    }
3253
3254
    $sql = '';
3255
    switch ($option) {
3256
        case 1:
3257
            $sql = "SELECT qualify FROM $table_threads_qualify
3258
                    WHERE
3259
                        c_id = $course_id AND
3260
                        user_id=".$user_id." AND
3261
                        thread_id=".$thread_id;
3262
            break;
3263
        case 2:
3264
            $sql = "SELECT thread_qualify_max FROM $table_threads
3265
                    WHERE c_id = $course_id AND thread_id=".$thread_id;
3266
            break;
3267
    }
3268
3269
    if (!empty($sql)) {
3270
        $rs = Database::query($sql);
3271
        $row = Database::fetch_array($rs);
3272
3273
        return $row[0];
3274
    }
3275
3276
    return array();
3277
}
3278
3279
/**
3280
 * This function gets qualify historical.
3281
 * @param integer $user_id contains the information the current user id
3282
 * @param integer $thread_id contains the information the current thread id
3283
 * @param boolean $opt contains the information of option to run
3284
 * @return array
3285
 * @author Christian Fasanando <[email protected]>,
3286
 * @author Isaac Flores <[email protected]>,
3287
 * @version October 2008, dokeos  1.8.6
3288
 */
3289
function getThreadScoreHistory($user_id, $thread_id, $opt)
3290
{
3291
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3292
    $course_id = api_get_course_int_id();
3293
3294
    if ($opt == 'false') {
3295
        $sql = "SELECT * FROM ".$table_threads_qualify_log."
3296
                WHERE
3297
                    c_id = $course_id AND
3298
                    thread_id='".Database::escape_string($thread_id)."' AND
3299
                    user_id='".Database::escape_string($user_id)."'
3300
                ORDER BY qualify_time";
3301
    } else {
3302
        $sql = "SELECT * FROM ".$table_threads_qualify_log."
3303
                WHERE
3304
                    c_id = $course_id AND
3305
                    thread_id='".Database::escape_string($thread_id)."' AND
3306
                    user_id='".Database::escape_string($user_id)."'
3307
                ORDER BY qualify_time DESC";
3308
    }
3309
    $rs = Database::query($sql);
3310
    $log = array();
3311
    while ($row = Database::fetch_array($rs, 'ASSOC')) {
3312
        $log[] = $row;
3313
    }
3314
3315
    return $log;
3316
}
3317
3318
/**
3319
 * This function stores qualify historical.
3320
 * @param boolean contains the information of option to run
3321
 * @param string contains the information the current course id
3322
 * @param integer contains the information the current forum id
3323
 * @param integer contains the information the current user id
3324
 * @param integer contains the information the current thread id
3325
 * @param integer contains the information the current qualify
3326
 * @param string $option
3327
 * @param integer $course_id
3328
 * @param integer $user_id
3329
 * @param integer $thread_id
3330
 * @return void
3331
 * <code>$option=1 obtained the qualification of the current thread</code>
3332
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3333
 * @version October 2008, dokeos  1.8.6
3334
 */
3335
function saveThreadScoreHistory(
3336
    $option,
3337
    $course_id,
3338
    $user_id,
3339
    $thread_id
3340
) {
3341
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3342
    $table_threads_qualify_log = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY_LOG);
3343
3344
    $course_id = intval($course_id);
3345
    $qualify_user_id = api_get_user_id();
3346
3347
    if ($user_id == strval(intval($user_id)) &&
3348
        $thread_id == strval(intval($thread_id)) && $option == 1
3349
    ) {
3350
3351
        // Extract information of thread_qualify.
3352
        $sql = "SELECT qualify, qualify_time
3353
                FROM $table_threads_qualify
3354
                WHERE
3355
                    c_id = $course_id AND
3356
                    user_id = ".$user_id." AND
3357
                    thread_id = ".$thread_id." AND
3358
                    qualify_user_id = $qualify_user_id
3359
                ";
3360
        $rs = Database::query($sql);
3361
        $row = Database::fetch_array($rs);
3362
3363
        // Insert thread_historical.
3364
        $sql = "INSERT INTO $table_threads_qualify_log (c_id, user_id, thread_id, qualify, qualify_user_id,qualify_time,session_id)
3365
                VALUES(".$course_id.", '".$user_id."','".$thread_id."',".(float) $row[0].", '".$qualify_user_id."','".$row[1]."','')";
3366
        Database::query($sql);
3367
3368
        $insertId = Database::insert_id();
3369
        if ($insertId) {
3370
            $sql = "UPDATE $table_threads_qualify_log SET id = iid
3371
                    WHERE iid = $insertId";
3372
            Database::query($sql);
3373
        }
3374
    }
3375
}
3376
3377
/**
3378
 * This function shows current thread qualify .
3379
 * @param integer $threadId
3380
 * @param integer $sessionId
3381
 * @param integer $userId
3382
 *
3383
 * @return array or null if is empty
3384
 * @author Isaac Flores <[email protected]>, U.N.A.S University
3385
 * @version December 2008, dokeos  1.8.6
3386
 */
3387 View Code Duplication
function current_qualify_of_thread($threadId, $sessionId, $userId)
3388
{
3389
    $table_threads_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
3390
3391
    $course_id = api_get_course_int_id();
3392
    $currentUserId = api_get_user_id();
3393
    $sessionId = intval($sessionId);
3394
    $threadId = intval($threadId);
3395
3396
    $sql = "SELECT qualify FROM $table_threads_qualify
3397
            WHERE
3398
                c_id = $course_id AND
3399
                thread_id = $threadId AND
3400
                session_id = $sessionId AND
3401
                qualify_user_id = $currentUserId AND
3402
                user_id = $userId
3403
            ";
3404
    $res = Database::query($sql);
3405
    $row = Database::fetch_array($res, 'ASSOC');
3406
3407
    return $row['qualify'];
3408
}
3409
3410
/**
3411
 * This function stores a reply in the forum_post table.
3412
 * It also updates the forum_threads table (thread_replies +1 , thread_last_post, thread_date)
3413
 * @param array $current_forum
3414
 * @param array $values
3415
 * @param int $courseId Optional
3416
 * @param int $userId Optional
3417
 * @return array
3418
 * @author Patrick Cool <[email protected]>, Ghent University
3419
 * @version february 2006, dokeos 1.8
3420
 */
3421
function store_reply($current_forum, $values, $courseId = 0, $userId = 0)
3422
{
3423
    $courseId = !empty($courseId) ? $courseId : api_get_course_int_id();
3424
    $_course = api_get_course_info_by_id($courseId);
3425
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3426
    $post_date = api_get_utc_datetime();
3427
    $userId = $userId ?: api_get_user_id();
3428
3429 View Code Duplication
    if ($current_forum['approval_direct_post'] == '1' &&
3430
        !api_is_allowed_to_edit(null, true)
3431
    ) {
3432
        $visible = 0;
3433
    } else {
3434
        $visible = 1;
3435
    }
3436
3437
    $upload_ok = 1;
3438
    $return = array();
3439
3440
    if ($upload_ok) {
3441
        // We first store an entry in the forum_post table.
3442
        $new_post_id = Database::insert(
3443
            $table_posts,
3444
            [
3445
                'c_id' => $courseId,
3446
                'post_title' => $values['post_title'],
3447
                'post_text' => isset($values['post_text']) ? ($values['post_text']) : null,
3448
                'thread_id' => $values['thread_id'],
3449
                'forum_id' => $values['forum_id'],
3450
                'poster_id' => $userId,
3451
                'post_id' => 0,
3452
                'post_date' => $post_date,
3453
                'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : null,
3454
                'post_parent_id' => isset($values['post_parent_id']) ? $values['post_parent_id'] : null,
3455
                'visible' => $visible,
3456
            ]
3457
        );
3458
3459
        if ($new_post_id) {
3460
            $sql = "UPDATE $table_posts SET post_id = iid WHERE iid = $new_post_id";
3461
            Database::query($sql);
3462
3463
            $values['new_post_id'] = $new_post_id;
3464
            $message = get_lang('ReplyAdded');
3465
3466 View Code Duplication
            if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3467
                foreach ($_POST['file_ids'] as $key => $id) {
3468
                    editAttachedFile(
3469
                        array(
3470
                            'comment' => $_POST['file_comments'][$key],
3471
                            'post_id' => $new_post_id,
3472
                        ),
3473
                        $id
3474
                    );
3475
                }
3476
            }
3477
3478
            // Update the thread.
3479
            updateThreadInfo($values['thread_id'], $new_post_id, $post_date);
3480
3481
            // Update the forum.
3482
            api_item_property_update(
3483
                $_course,
3484
                TOOL_FORUM,
3485
                $values['forum_id'],
3486
                'NewMessageInForum',
3487
                $userId
3488
            );
3489
3490
            // Insert post
3491
            api_item_property_update(
3492
                $_course,
3493
                TOOL_FORUM_POST,
3494
                $new_post_id,
3495
                'NewPost',
3496
                $userId
3497
            );
3498
3499
            if ($current_forum['approval_direct_post'] == '1' &&
3500
                !api_is_allowed_to_edit(null, true)
3501
            ) {
3502
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3503
            }
3504
3505
            if ($current_forum['moderated'] &&
3506
                !api_is_allowed_to_edit(null, true)
3507
            ) {
3508
                $message .= '<br />'.get_lang('MessageHasToBeApproved').'<br />';
3509
            }
3510
3511
            // Setting the notification correctly.
3512
            $my_post_notification = isset($values['post_notification']) ? $values['post_notification'] : null;
3513
            if ($my_post_notification == 1) {
3514
                set_notification('thread', $values['thread_id'], true);
3515
            }
3516
3517
            send_notification_mails(
3518
                $values['forum_id'],
3519
                $values['thread_id'],
3520
                $values
3521
            );
3522
            add_forum_attachment_file('', $new_post_id);
3523
        }
3524
3525
        Session::erase('formelements');
3526
        Session::erase('origin');
3527
        Session::erase('breadcrumbs');
3528
        Session::erase('addedresource');
3529
        Session::erase('addedresourceid');
3530
3531
        Display::addFlash(Display::return_message($message, 'confirmation', false));
3532
    } else {
3533
        Display::addFlash(
3534
            Display::return_message(get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'), 'error')
3535
        );
3536
    }
3537
3538
    return $return;
3539
}
3540
3541
/**
3542
 * This function displays the form that is used to edit a post. This can be a new thread or a reply.
3543
 * @param array contains all the information about the current post
3544
 * @param array contains all the information about the current thread
3545
 * @param array contains all info about the current forum (to check if attachments are allowed)
3546
 * @param array contains the default values to fill the form
3547
 * @return void
3548
 *
3549
 * @author Patrick Cool <[email protected]>, Ghent University
3550
 * @version february 2006, dokeos 1.8
3551
 */
3552
function show_edit_post_form(
3553
    $forum_setting,
3554
    $current_post,
3555
    $current_thread,
3556
    $current_forum,
3557
    $form_values = '',
3558
    $id_attach = 0
3559
) {
3560
    // Initialize the object.
3561
    $form = new FormValidator(
3562
        'edit_post',
3563
        'post',
3564
        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
3565
    );
3566
    $form->addElement('header', get_lang('EditPost'));
3567
    // Setting the form elements.
3568
    $form->addElement('hidden', 'post_id', $current_post['post_id']);
3569
    $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
3570
    $form->addElement('hidden', 'id_attach', $id_attach);
3571
3572
    if (empty($current_post['post_parent_id'])) {
3573
        $form->addElement('hidden', 'is_first_post_of_thread', '1');
3574
    }
3575
3576
    $form->addElement('text', 'post_title', get_lang('Title'));
3577
    $form->applyFilter('post_title', 'html_filter');
3578
    $form->addHtmlEditor(
3579
        'post_text',
3580
        get_lang('Text'),
3581
        null,
3582
        null,
3583
        api_is_allowed_to_edit(null, true) ? array(
3584
            'ToolbarSet' => 'Forum',
3585
            'Width' => '100%',
3586
            'Height' => '400',
3587
        ) : array(
3588
            'ToolbarSet' => 'ForumStudent',
3589
            'Width' => '100%',
3590
            'Height' => '400',
3591
            'UserStatus' => 'student',
3592
        )
3593
    );
3594
    $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
3595
3596
    $form->addButtonAdvancedSettings('advanced_params');
3597
    $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
3598
3599
    if (!isset($_GET['edit'])) {
3600
        if (Gradebook::is_active()) {
3601
            $form->addElement('label', '<strong>'.get_lang('AlterQualifyThread').'</strong>');
3602
            $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\';}"');
3603
3604
            $link_info = GradebookUtils::isResourceInCourseGradebook(
3605
                api_get_course_id(),
3606
                5,
3607
                $_GET['thread'],
3608
                api_get_session_id()
3609
            );
3610
            if (!empty($link_info)) {
3611
                $defaults['thread_qualify_gradebook'] = true;
3612
                $defaults['category_id'] = $link_info['category_id'];
3613
            } else {
3614
                $defaults['thread_qualify_gradebook'] = false;
3615
                $defaults['category_id'] = '';
3616
            }
3617
        } else {
3618
            $form->addElement('hidden', 'thread_qualify_gradebook', false);
3619
            $defaults['thread_qualify_gradebook'] = false;
3620
        }
3621
3622
        if (!empty($defaults['thread_qualify_gradebook'])) {
3623
            $form->addElement('html', '<div id="options_field" style="display:block">');
3624
        } else {
3625
            $form->addElement('html', '<div id="options_field" style="display:none">');
3626
        }
3627
3628
        // Loading gradebook select
3629
        GradebookUtils::load_gradebook_select_in_tool($form);
3630
3631
        $form->addElement(
3632
            'text',
3633
            'numeric_calification',
3634
            get_lang('QualificationNumeric'),
3635
            array(
3636
                'value' => $current_thread['thread_qualify_max'],
3637
                'style' => 'width:40px',
3638
            )
3639
        );
3640
        $form->applyFilter('numeric_calification', 'html_filter');
3641
3642
        $form->addElement(
3643
            'text',
3644
            'calification_notebook_title',
3645
            get_lang('TitleColumnGradebook'),
3646
            array('value' => $current_thread['thread_title_qualify'])
3647
        );
3648
        $form->applyFilter('calification_notebook_title', 'html_filter');
3649
3650
        $form->addElement(
3651
            'text',
3652
            'weight_calification',
3653
            array(get_lang('QualifyWeight'), null, ''),
3654
            array(
3655
                'value' => $current_thread['thread_weight'],
3656
                'style' => 'width:40px',
3657
            )
3658
        );
3659
        $form->applyFilter('weight_calification', 'html_filter');
3660
3661
        $group = array();
3662
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('Yes'), 1);
3663
        $group[] = $form->createElement('radio', 'thread_peer_qualify', null, get_lang('No'), 0);
3664
        $form->addGroup(
3665
            $group,
3666
            '',
3667
            [
3668
                get_lang('ForumThreadPeerScoring'),
3669
                get_lang('ForumThreadPeerScoringComment'),
3670
            ]
3671
        );
3672
3673
        $form->addElement('html', '</div>');
3674
    }
3675
3676
    if ($current_forum['moderated']) {
3677
        $group = array();
3678
        $group[] = $form->createElement('radio', 'status', null, get_lang('Validated'), 1);
3679
        $group[] = $form->createElement('radio', 'status', null, get_lang('WaitingModeration'), 2);
3680
        $group[] = $form->createElement('radio', 'status', null, get_lang('Rejected'), 3);
3681
        $form->addGroup($group, 'status', get_lang('Status'));
3682
    }
3683
3684
    $defaults['status']['status'] = isset($current_post['status']) && !empty($current_post['status']) ? $current_post['status'] : 2;
3685
3686
    if ($forum_setting['allow_post_notification']) {
3687
        $form->addElement('checkbox', 'post_notification', '', get_lang('NotifyByEmail').' ('.$current_post['email'].')');
3688
    }
3689
3690
    if ($forum_setting['allow_sticky'] &&
3691
        api_is_allowed_to_edit(null, true) &&
3692
        empty($current_post['post_parent_id'])
3693
    ) {
3694
        // The sticky checkbox only appears when it is the first post of a thread.
3695
        $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
3696
        if ($current_thread['thread_sticky'] == 1) {
3697
            $defaults['thread_sticky'] = true;
3698
            //edit_added_resources('forum_post', $current_post['post_id']);
3699
        }
3700
    }
3701
3702
    $form->addElement('html', '</div>');
3703
3704
    $form->addFile('user_upload[]', get_lang('Attachment'));
3705
    $form->addButton(
3706
        'add_attachment',
3707
        get_lang('AddAttachment'),
3708
        'paperclip',
3709
        'default',
3710
        'default',
3711
        null,
3712
        ['id' => 'reply-add-attachment']
3713
    );
3714
3715
    $form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
3716
3717
    // Setting the default values for the form elements.
3718
    $defaults['post_title'] = $current_post['post_title'];
3719
    $defaults['post_text'] = $current_post['post_text'];
3720
3721
    if ($current_post['post_notification'] == 1) {
3722
        $defaults['post_notification'] = true;
3723
    }
3724
3725
    if (!empty($form_values)) {
3726
        $defaults['post_notification'] = Security::remove_XSS($form_values['post_notification']);
3727
        $defaults['thread_sticky'] = Security::remove_XSS($form_values['thread_sticky']);
3728
    }
3729
3730
    $defaults['thread_peer_qualify'] = intval($current_thread['thread_peer_qualify']);
3731
3732
    $form->setDefaults($defaults);
3733
3734
    // The course admin can make a thread sticky (=appears with special icon and always on top).
3735
3736
    $form->addRule('post_title', get_lang('ThisFieldIsRequired'), 'required');
3737
3738
    // Validation or display
3739
    if ($form->validate()) {
3740
        $values = $form->exportValues();
3741
3742
        if (isset($values['thread_qualify_gradebook']) && $values['thread_qualify_gradebook'] == '1' &&
3743
            empty($values['weight_calification'])
3744
        ) {
3745
            Display::display_error_message(get_lang('YouMustAssignWeightOfQualification').'&nbsp;<a href="javascript:window.history.go(-1);">'.get_lang('Back').'</a>', false);
3746
            return false;
3747
        }
3748
        return $values;
3749
    } else {
3750
        // Delete from $_SESSION forum attachment from other posts
3751
        clearAttachedFiles($current_post['post_id']);
3752
        // Get forum attachment ajax table to add it to form
3753
        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
3754
        $form->addElement('html', $fileData);
3755
        $form->display();
3756
    }
3757
}
3758
3759
/**
3760
 * This function stores the edit of a post in the forum_post table.
3761
 *
3762
 * @param array
3763
 * @return void HTML
3764
 *
3765
 * @author Patrick Cool <[email protected]>, Ghent University
3766
 * @version february 2006, dokeos 1.8
3767
 */
3768
function store_edit_post($forumInfo, $values)
3769
{
3770
    $threadTable = Database :: get_course_table(TABLE_FORUM_THREAD);
3771
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3772
    $gradebook = Security::remove_XSS($_GET['gradebook']);
3773
    $course_id = api_get_course_int_id();
3774
3775
    //check if this post is the first of the thread
3776
    // First we check if the change affects the thread and if so we commit
3777
    // the changes (sticky and post_title=thread_title are relevant).
3778
3779
    $posts = getPosts($forumInfo, $values['thread_id']);
3780
    $first_post = null;
3781
    if (!empty($posts) && count($posts) > 0 && isset($posts[0])) {
3782
        $first_post = $posts[0];
3783
    }
3784
3785
    if (!empty($first_post) && $first_post['post_id'] == $values['post_id']) {
3786
        $params = [
3787
            'thread_title' => $values['post_title'],
3788
            'thread_sticky' => isset($values['thread_sticky']) ? $values['thread_sticky'] : null,
3789
            'thread_title_qualify' => $values['calification_notebook_title'],
3790
            'thread_qualify_max' => $values['numeric_calification'],
3791
            'thread_weight' => $values['weight_calification'],
3792
            'thread_peer_qualify' => $values['thread_peer_qualify'],
3793
        ];
3794
        $where = ['c_id = ? AND thread_id = ?' => [$course_id, $values['thread_id']]];
3795
3796
        Database::update($threadTable, $params, $where);
3797
    }
3798
3799
    $status = '';
3800
    if ($forumInfo['moderated']) {
3801
        $status = $values['status']['status'];
3802
    }
3803
3804
    // Update the post_title and the post_text.
3805
    $params = [
3806
        'status' => $status,
3807
        'post_title' => $values['post_title'],
3808
        'post_text' => $values['post_text'],
3809
        'post_notification' => isset($values['post_notification']) ? $values['post_notification'] : '',
3810
    ];
3811
    $where = ['c_id = ? AND post_id = ?' => [$course_id, $values['post_id']]];
3812
3813
    Database::update($table_posts, $params, $where);
3814
3815
    // Update attached files
3816 View Code Duplication
    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
3817
        foreach ($_POST['file_ids'] as $key => $id) {
3818
            editAttachedFile(
3819
                array(
3820
                    'comment' => $_POST['file_comments'][$key],
3821
                    'post_id' => $values['post_id'],
3822
                ),
3823
                $id
3824
            );
3825
        }
3826
    }
3827
3828
    if (!empty($values['remove_attach'])) {
3829
        delete_attachment($values['post_id']);
3830
    }
3831
3832
    if (empty($values['id_attach'])) {
3833
        add_forum_attachment_file(
3834
            isset($values['file_comment']) ? $values['file_comment'] : null,
3835
            $values['post_id']
3836
        );
3837
    } else {
3838
        edit_forum_attachment_file(
3839
            isset($values['file_comment']) ? $values['file_comment'] : null,
3840
            $values['post_id'],
3841
            $values['id_attach']
3842
        );
3843
    }
3844
3845
    // Storing the attachments if any.
3846
    //update_added_resources('forum_post', $values['post_id']);
3847
3848
    $message = get_lang('EditPostStored').'<br />';
3849
    $message .= get_lang('ReturnTo').' <a href="viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&">'.get_lang('Forum').'</a><br />';
3850
    $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>';
3851
3852
    Session::erase('formelements');
3853
    Session::erase('origin');
3854
    Session::erase('breadcrumbs');
3855
    Session::erase('addedresource');
3856
    Session::erase('addedresourceid');
3857
3858
    Display :: display_confirmation_message($message, false);
3859
}
3860
3861
/**
3862
 * This function displays the firstname and lastname of the user as a link to the user tool.
3863
 *
3864
 * @param string names
3865
 * @ in_title : title tootip
3866
 * @return string HTML
3867
 *
3868
 * @author Patrick Cool <[email protected]>, Ghent University
3869
 * @version february 2006, dokeos 1.8
3870
 */
3871
function display_user_link($user_id, $name, $origin = '', $in_title = '')
3872
{
3873
    if ($user_id != 0) {
3874
        $userInfo = api_get_user_info($user_id);
3875
3876
        return '<a href="'.$userInfo['profile_url'].'">'.Security::remove_XSS($userInfo['complete_name']).'</a>';
3877
    } else {
3878
        return $name.' ('.get_lang('Anonymous').')';
3879
    }
3880
}
3881
3882
/**
3883
 * This function displays the user image from the profile, with a link to the user's details.
3884
 * @param   int     User's database ID
3885
 * @param   string  User's name
3886
 * @param   string  the origin where the forum is called (example : learnpath)
3887
 * @return  string  An HTML with the anchor and the image of the user
3888
 * @author Julio Montoya <[email protected]>
3889
 */
3890
function display_user_image($user_id, $name, $origin = '')
3891
{
3892
    $userInfo = api_get_user_info($user_id);
3893
    
3894
    $link = '<a href="'.(!empty($origin) ? '#' : $userInfo['profile_url']).'" '.(!empty($origin) ? 'target="_self"' : '').'>';
3895
    
3896
    if ($user_id != 0) {
3897
        return $link.'<img src="'.$userInfo['avatar'].'"  alt="'.$name.'"  title="'.$name.'" /></a>';
3898
    } else {
3899
        return $link.Display::return_icon('unknown.jpg', $name).'</a>';
3900
    }
3901
}
3902
3903
/**
3904
 * The thread view counter gets increased every time someone looks at the thread
3905
 *
3906
 * @param int
3907
 * @return void
3908
 *
3909
 * @author Patrick Cool <[email protected]>, Ghent University
3910
 * @version february 2006, dokeos 1.8
3911
 */
3912 View Code Duplication
function increase_thread_view($thread_id)
3913
{
3914
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3915
    $course_id = api_get_course_int_id();
3916
3917
    $sql = "UPDATE $table_threads SET thread_views=thread_views+1
3918
            WHERE 
3919
                c_id = $course_id AND  
3920
                thread_id = '".intval($thread_id)."'";
3921
    Database::query($sql);
3922
}
3923
3924
/**
3925
 * The relies counter gets increased every time somebody replies to the thread
3926
 *
3927
 * @author Patrick Cool <[email protected]>, Ghent University
3928
 * @version february 2006, dokeos 1.8
3929
 * @param string $last_post_id
3930
 * @param string $post_date
3931
 */
3932
function updateThreadInfo($thread_id, $last_post_id, $post_date)
3933
{
3934
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
3935
    $course_id = api_get_course_int_id();
3936
    $sql = "UPDATE $table_threads SET 
3937
            thread_replies = thread_replies+1,
3938
            thread_last_post = '".Database::escape_string($last_post_id)."',
3939
            thread_date = '".Database::escape_string($post_date)."'
3940
            WHERE 
3941
                c_id = $course_id AND  
3942
                thread_id='".Database::escape_string($thread_id)."'"; // this needs to be cleaned first
3943
    Database::query($sql);
3944
}
3945
3946
/**
3947
 * This function is called when the user is not allowed in this forum/thread/...
3948
 * @return bool display message of "not allowed"
3949
 *
3950
 * @author Patrick Cool <[email protected]>, Ghent University
3951
 * @version february 2006, dokeos 1.8
3952
 */
3953
function forum_not_allowed_here()
3954
{
3955
    Display :: display_error_message(get_lang('NotAllowedHere'));
3956
    Display :: display_footer();
3957
3958
    return false;
3959
}
3960
3961
/**
3962
 * This function is used to find all the information about what's new in the forum tool
3963
 * @return void
3964
 *
3965
 * @author Patrick Cool <[email protected]>, Ghent University
3966
 * @version february 2006, dokeos 1.8
3967
 */
3968
function get_whats_new()
3969
{
3970
    $_user = api_get_user_info();
3971
    $_course = api_get_course_info();
3972
3973
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
3974
    $tracking_last_tool_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
3975
3976
    // Note: This has to be replaced by the tool constant later. But temporarily bb_forum is used since this is the only thing that is in the tracking currently.
3977
    //$tool = TOOL_FORUM;
3978
    $tool = TOOL_FORUM; //
3979
    // to do: Remove this. For testing purposes only.
3980
    //Session::erase('last_forum_access');
3981
    //Session::erase('whatsnew_post_info');
3982
3983
    $course_id = api_get_course_int_id();
3984
    $lastForumAccess = Session::read('last_forum_access');
3985
3986
    if (!$lastForumAccess) {
3987
        $sql = "SELECT * FROM ".$tracking_last_tool_access."
3988
                WHERE
3989
                    access_user_id='".Database::escape_string($_user['user_id'])."' AND
3990
                    c_id ='".$course_id."' AND
3991
                    access_tool='".Database::escape_string($tool)."'";
3992
        $result = Database::query($sql);
3993
        $row = Database::fetch_array($result);
3994
        Session::write('last_forum_access', $row['access_date']);
3995
    }
3996
3997
    $whatsNew = Session::read('whatsnew_post_info');
3998
3999
    if (!$whatsNew) {
4000
        if ($lastForumAccess != '') {
4001
            $whatsnew_post_info = array();
4002
            $access = Session::read('last_forum_access');
4003
            $sql = "SELECT * FROM $table_posts
4004
                    WHERE
4005
                        c_id = $course_id AND
4006
                        post_date >'".Database::escape_string($access)."'"; // note: check the performance of this query.
4007
            $result = Database::query($sql);
4008
            while ($row = Database::fetch_array($result)) {
4009
                $whatsnew_post_info[$row['forum_id']][$row['thread_id']][$row['post_id']] = $row['post_date'];
4010
            }
4011
            $_SESSION['whatsnew_post_info'] = $whatsnew_post_info;
4012
        }
4013
    }
4014
}
4015
4016
/**
4017
 * This function approves a post = change
4018
 *
4019
 * @param int $post_id the id of the post that will be deleted
4020
 * @param string $action make the post visible or invisible
4021
 * @return string language variable
4022
 *
4023
 * @author Patrick Cool <[email protected]>, Ghent University
4024
 * @version february 2006, dokeos 1.8
4025
 */
4026
function approve_post($post_id, $action)
4027
{
4028
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4029
    $course_id = api_get_course_int_id();
4030
4031
    if ($action == 'invisible') {
4032
        $visibility_value = 0;
4033
    }
4034
4035
    if ($action == 'visible') {
4036
        $visibility_value = 1;
4037
        handle_mail_cue('post', $post_id);
4038
    }
4039
4040
    $sql = "UPDATE $table_posts SET
4041
            visible='".Database::escape_string($visibility_value)."'
4042
            WHERE c_id = $course_id AND post_id='".Database::escape_string($post_id)."'";
4043
    $return = Database::query($sql);
4044
4045
    if ($return) {
4046
        return 'PostVisibilityChanged';
4047
    }
4048
}
4049
4050
/**
4051
 * This function retrieves all the unapproved messages for a given forum
4052
 * This is needed to display the icon that there are unapproved messages in that thread (only the courseadmin can see this)
4053
 *
4054
 * @param $forum_id the forum where we want to know the unapproved messages of
4055
 * @return array returns
4056
 *
4057
 * @author Patrick Cool <[email protected]>, Ghent University
4058
 * @version february 2006, dokeos 1.8
4059
 */
4060
function get_unaproved_messages($forum_id)
4061
{
4062
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4063
    $course_id = api_get_course_int_id();
4064
4065
    $return_array = array();
4066
    $sql = "SELECT DISTINCT thread_id FROM $table_posts
4067
            WHERE 
4068
                c_id = $course_id AND 
4069
                forum_id='".Database::escape_string($forum_id)."' AND 
4070
                visible='0' ";
4071
    $result = Database::query($sql);
4072
    while ($row = Database::fetch_array($result)) {
4073
        $return_array[] = $row['thread_id'];
4074
    }
4075
4076
    return $return_array;
4077
}
4078
4079
/**
4080
 * This function sends the notification mails to everybody who stated that they wanted to be informed when a new post
4081
 * was added to a given thread.
4082
 *
4083
 * @param array reply information
4084
 * @return void
4085
 *
4086
 * @author Patrick Cool <[email protected]>, Ghent University
4087
 * @version february 2006, dokeos 1.8
4088
 */
4089
function send_notification_mails($forumId, $thread_id, $reply_info)
4090
{
4091
    $table = Database::get_course_table(TABLE_FORUM_MAIL_QUEUE);
4092
4093
    // First we need to check if
4094
    // 1. the forum category is visible
4095
    // 2. the forum is visible
4096
    // 3. the thread is visible
4097
    // 4. the reply is visible (=when there is)
4098
    $current_thread = get_thread_information($forumId, $thread_id);
4099
    $current_forum = get_forum_information($current_thread['forum_id'], $current_thread['c_id']);
4100
4101
    $current_forum_category = null;
4102
    if (isset($current_forum['forum_category'])) {
4103
        $current_forum_category = get_forumcategory_information(
4104
            $current_forum['forum_category']
4105
        );
4106
    }
4107
4108
    if ($current_thread['visibility'] == '1' &&
4109
        $current_forum['visibility'] == '1' &&
4110
        ($current_forum_category && $current_forum_category['visibility'] == '1') &&
4111
        $current_forum['approval_direct_post'] != '1'
4112
    ) {
4113
        $send_mails = true;
4114
    } else {
4115
        $send_mails = false;
4116
    }
4117
4118
    // The forum category, the forum, the thread and the reply are visible to the user
4119
    if ($send_mails) {
4120
        if (!empty($forumId)) {
4121
            send_notifications($forumId, $thread_id);
4122
        }
4123
    } else {
4124
        $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
4125
        if (isset($current_forum['forum_id'])) {
4126
            $sql = "SELECT * FROM $table_notification
4127
                    WHERE
4128
                        c_id = ".api_get_course_int_id()." AND
4129
                        (
4130
                            forum_id = '".intval($current_forum['forum_id'])."' OR
4131
                            thread_id = '".intval($thread_id)."'
4132
                        ) ";
4133
4134
            $result = Database::query($sql);
4135
            $user_id = api_get_user_id();
4136
            while ($row = Database::fetch_array($result)) {
4137
                $sql = "INSERT INTO $table (c_id, thread_id, post_id, user_id)
4138
                        VALUES (".api_get_course_int_id().", '".intval($thread_id)."', '".intval($reply_info['new_post_id'])."', '$user_id' )";
4139
                Database::query($sql);
4140
            }
4141
        }
4142
    }
4143
}
4144
4145
/**
4146
 * This function is called whenever something is made visible because there might
4147
 * be new posts and the user might have indicated that (s)he wanted to be
4148
 * informed about the new posts by mail.
4149
 *
4150
 * @param string  Content type (post, thread, forum, forum_category)
4151
 * @param int     Item DB ID
4152
 * @param string $content
4153
 * @param integer $id
4154
 * @return string language variable
4155
 * @author Patrick Cool <[email protected]>, Ghent University
4156
 * @version february 2006, dokeos 1.8
4157
 */
4158
function handle_mail_cue($content, $id)
4159
{
4160
    $table_mailcue = Database :: get_course_table(TABLE_FORUM_MAIL_QUEUE);
4161
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4162
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4163
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4164
    $table_users = Database :: get_main_table(TABLE_MAIN_USER);
4165
4166
    $course_id = api_get_course_int_id();
4167
4168
    /* If the post is made visible we only have to send mails to the people
4169
     who indicated that they wanted to be informed for that thread.*/
4170
    if ($content == 'post') {
4171
        // Getting the information about the post (need the thread_id).
4172
        $post_info = get_post_information($id);
4173
        $thread_id = intval($post_info['thread_id']);
4174
4175
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4176
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
4177
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4178
                WHERE
4179
                    posts.c_id = $course_id AND
4180
                    mailcue.c_id = $course_id AND
4181
                    posts.thread_id='$thread_id'
4182
                    AND posts.post_notification='1'
4183
                    AND mailcue.thread_id='$thread_id'
4184
                    AND users.user_id=posts.poster_id
4185
                    AND users.active=1
4186
                GROUP BY users.email";
4187
4188
        $result = Database::query($sql);
4189
        while ($row = Database::fetch_array($result)) {
4190
            send_mail($row, get_thread_information($post_info['forum_id'], $post_info['thread_id']));
4191
        }
4192
    } elseif ($content == 'thread') {
4193
        // Sending the mail to all the users that wanted to be informed for replies on this thread.
4194
        $sql = "SELECT users.firstname, users.lastname, users.user_id, users.email, posts.forum_id
4195
                FROM $table_mailcue mailcue, $table_posts posts, $table_users users
4196
                WHERE
4197
                    posts.c_id = $course_id AND
4198
                    mailcue.c_id = $course_id AND
4199
                    posts.thread_id = ".intval($id)."
4200
                    AND posts.post_notification='1'
4201
                    AND mailcue.thread_id = ".intval($id)."
4202
                    AND users.user_id=posts.poster_id
4203
                    AND users.active=1
4204
                GROUP BY users.email";
4205
        $result = Database::query($sql);
4206
        while ($row = Database::fetch_array($result)) {
4207
            send_mail($row, get_thread_information($row['forum_id'], $id));
4208
        }
4209
4210
        // Deleting the relevant entries from the mailcue.
4211
        $sql = "DELETE FROM $table_mailcue
4212
                WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
4213
        Database::query($sql);
4214
    } elseif ($content == 'forum') {
4215
        $sql = "SELECT thread_id FROM $table_threads
4216
                WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
4217
        $result = Database::query($sql);
4218
        while ($row = Database::fetch_array($result)) {
4219
            handle_mail_cue('thread', $row['thread_id']);
4220
        }
4221
    } elseif ($content == 'forum_category') {
4222
        $sql = "SELECT forum_id FROM $table_forums
4223
                WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
4224
        $result = Database::query($sql);
4225
        while ($row = Database::fetch_array($result)) {
4226
            handle_mail_cue('forum', $row['forum_id']);
4227
        }
4228
    } else {
4229
        return get_lang('Error');
4230
    }
4231
}
4232
4233
/**
4234
 * This function sends the mails for the mail notification
4235
 *
4236
 * @param array
4237
 * @param array
4238
 * @return void
4239
 *
4240
 * @author Patrick Cool <[email protected]>, Ghent University
4241
 * @version february 2006, dokeos 1.8
4242
 */
4243
function send_mail($user_info = array(), $thread_information = array())
4244
{
4245
    $_course = api_get_course_info();
4246
    $user_id = api_get_user_id();
4247
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'];
4248 View Code Duplication
    if (isset($thread_information) && is_array($thread_information)) {
4249
        $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$thread_information['forum_id'].'&thread='.$thread_information['thread_id'];
4250
    }
4251
    $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
4252
    $email_body .= get_lang('NewForumPost')."\n";
4253
    $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."] - <br />\n";
4254
    $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
4255
    $email_body .= get_lang('ThreadCanBeFoundHere')." : <br /><a href=\"".$thread_link."\">".$thread_link."</a>\n";
4256
4257
    if ($user_info['user_id'] <> $user_id) {
4258
        MessageManager::send_message($user_info['user_id'], $subject, $email_body, [], [], null, null, null, null, $user_id);
4259
    }
4260
}
4261
4262
/**
4263
 * This function displays the form for moving a thread to a different (already existing) forum
4264
 * @return void HTML
4265
 *
4266
 * @author Patrick Cool <[email protected]>, Ghent University
4267
 * @version february 2006, dokeos 1.8
4268
 */
4269
function move_thread_form()
4270
{
4271
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4272
    $form = new FormValidator(
4273
        'movepost',
4274
        'post',
4275
        api_get_self().'?forum='.intval($_GET['forum']).'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
4276
    );
4277
    // The header for the form
4278
    $form->addElement('header', get_lang('MoveThread'));
4279
    // Invisible form: the thread_id
4280
    $form->addElement('hidden', 'thread_id', intval($_GET['thread']));
4281
    // the fora
4282
    $forum_categories = get_forum_categories();
4283
    $forums = get_forums();
4284
4285
    $htmlcontent = '<div class="row">
4286
        <div class="label">
4287
            <span class="form_required">*</span>'.get_lang('MoveTo').'
4288
        </div>
4289
        <div class="formw">';
4290
    $htmlcontent .= '<select name="forum">';
4291
    foreach ($forum_categories as $key => $category) {
4292
        $htmlcontent .= '<optgroup label="'.$category['cat_title'].'">';
4293
        foreach ($forums as $key => $forum) {
4294
            if (isset($forum['forum_category'])) {
4295
                if ($forum['forum_category'] == $category['cat_id']) {
4296
                    $htmlcontent .= '<option value="'.$forum['forum_id'].'">'.$forum['forum_title'].'</option>';
4297
                }
4298
            }
4299
        }
4300
        $htmlcontent .= '</optgroup>';
4301
    }
4302
    $htmlcontent .= "</select>";
4303
    $htmlcontent .= '   </div>
4304
                    </div>';
4305
4306
    $form->addElement('html', $htmlcontent);
4307
4308
    // The OK button
4309
    $form->addButtonSave(get_lang('MoveThread'), 'SubmitForum');
4310
4311
    // Validation or display
4312
    if ($form->validate()) {
4313
        $values = $form->exportValues();
4314
        if (isset($_POST['forum'])) {
4315
            store_move_thread($values);
4316
        }
4317
    } else {
4318
        $form->display();
4319
    }
4320
}
4321
4322
/**
4323
 * This function displays the form for moving a post message to a different (already existing) or a new thread.
4324
 * @return void HTML
4325
 *
4326
 * @author Patrick Cool <[email protected]>, Ghent University
4327
 * @version february 2006, dokeos 1.8
4328
 */
4329
function move_post_form()
4330
{
4331
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4332
    // initiate the object
4333
    $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']));
4334
    // The header for the form
4335
    $form->addElement('header', '', get_lang('MovePost'));
4336
4337
    // Invisible form: the post_id
4338
    $form->addElement('hidden', 'post_id', intval($_GET['post']));
4339
4340
    // Dropdown list: Threads of this forum
4341
    $threads = get_threads($_GET['forum']);
4342
    //my_print_r($threads);
4343
    $threads_list[0] = get_lang('ANewThread');
4344
    foreach ($threads as $key => $value) {
4345
        $threads_list[$value['thread_id']] = $value['thread_title'];
4346
    }
4347
    $form->addElement('select', 'thread', get_lang('MoveToThread'), $threads_list);
4348
    $form->applyFilter('thread', 'html_filter');
4349
4350
    // The OK button
4351
    $form->addButtonSave(get_lang('MovePost'), 'submit');
4352
4353
    // Setting the rules
4354
    $form->addRule('thread', get_lang('ThisFieldIsRequired'), 'required');
4355
4356
    // Validation or display
4357
    if ($form->validate()) {
4358
        $values = $form->exportValues();
4359
        store_move_post($values);
4360
    } else {
4361
        $form->display();
4362
    }
4363
}
4364
4365
/**
4366
 *
4367
 * @param array
4368
 * @return string HTML language variable
4369
 *
4370
 * @author Patrick Cool <[email protected]>, Ghent University
4371
 * @version february 2006, dokeos 1.8
4372
 */
4373
function store_move_post($values)
4374
{
4375
    $_course = api_get_course_info();
4376
    $course_id = api_get_course_int_id();
4377
4378
    $table_forums = Database :: get_course_table(TABLE_FORUM);
4379
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4380
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4381
4382
    if ($values['thread'] == '0') {
4383
        $current_post = get_post_information($values['post_id']);
4384
4385
        // Storing a new thread.
4386
        $params = [
4387
            'c_id' => $course_id,
4388
            'thread_title' => $current_post['post_title'],
4389
            'forum_id' => $current_post['forum_id'],
4390
            'thread_poster_id' => $current_post['poster_id'],
4391
            'thread_poster_name' => $current_post['poster_name'],
4392
            'thread_last_post' => $values['post_id'],
4393
            'thread_date' => $current_post['post_date'],
4394
        ];
4395
4396
        $new_thread_id = Database::insert($table_threads, $params);
4397
4398
        api_item_property_update(
4399
            $_course,
4400
            TOOL_FORUM_THREAD,
4401
            $new_thread_id,
4402
            'visible',
4403
            $current_post['poster_id']
4404
        );
4405
4406
        // Moving the post to the newly created thread.
4407
        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
4408
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4409
        Database::query($sql);
4410
4411
        // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
4412
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4413
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4414
        Database::query($sql);
4415
4416
        // Updating updating the number of threads in the forum.
4417
        $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
4418
                WHERE c_id = $course_id AND forum_id='".intval($current_post['forum_id'])."'";
4419
        Database::query($sql);
4420
4421
        // Resetting the last post of the old thread and decreasing the number of replies and the thread.
4422
        $sql = "SELECT * FROM $table_posts
4423
                WHERE c_id = $course_id AND thread_id='".intval($current_post['thread_id'])."'
4424
                ORDER BY post_id DESC";
4425
        $result = Database::query($sql);
4426
        $row = Database::fetch_array($result);
4427
        $sql = "UPDATE $table_threads SET
4428
                    thread_last_post='".$row['post_id']."',
4429
                    thread_replies=thread_replies-1
4430
                WHERE
4431
                    c_id = $course_id AND
4432
                    thread_id='".intval($current_post['thread_id'])."'";
4433
        Database::query($sql);
4434
    } else {
4435
        // Moving to the chosen thread.
4436
4437
        $sql = "SELECT thread_id FROM ".$table_posts."
4438
                WHERE c_id = $course_id AND post_id = '".$values['post_id']."' ";
4439
        $result = Database::query($sql);
4440
        $row = Database::fetch_array($result);
4441
4442
        $original_thread_id = $row['thread_id'];
4443
4444
        $sql = "SELECT thread_last_post FROM ".$table_threads."
4445
                WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4446
4447
        $result = Database::query($sql);
4448
        $row = Database::fetch_array($result);
4449
        $thread_is_last_post = $row['thread_last_post'];
4450
        // If is this thread, update the thread_last_post with the last one.
4451
4452
        if ($thread_is_last_post == $values['post_id']) {
4453
            $sql = "SELECT post_id FROM ".$table_posts."
4454
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' AND post_id <> '".$values['post_id']."'
4455
                    ORDER BY post_date DESC LIMIT 1";
4456
            $result = Database::query($sql);
4457
4458
            $row = Database::fetch_array($result);
4459
            $thread_new_last_post = $row['post_id'];
4460
4461
            $sql = "UPDATE ".$table_threads." SET thread_last_post = '".$thread_new_last_post."'
4462
                    WHERE c_id = $course_id AND thread_id = '".$original_thread_id."' ";
4463
            Database::query($sql);
4464
        }
4465
4466
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
4467
                WHERE c_id = $course_id AND thread_id='".$original_thread_id."'";
4468
        Database::query($sql);
4469
4470
        // moving to the chosen thread
4471
        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
4472
                WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
4473
        Database::query($sql);
4474
4475
        // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
4476
        $sql = "UPDATE $table_posts SET post_parent_id = NULL
4477
                WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
4478
        Database::query($sql);
4479
4480
        $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
4481
                WHERE c_id = $course_id AND thread_id='".intval($_POST['thread'])."'";
4482
        Database::query($sql);
4483
    }
4484
4485
    return get_lang('ThreadMoved');
4486
}
4487
4488
/**
4489
 *
4490
 * @param array
4491
 * @return string HTML language variable
4492
 *
4493
 * @author Patrick Cool <[email protected]>, Ghent University
4494
 * @version february 2006, dokeos 1.8
4495
 */
4496
function store_move_thread($values)
4497
{
4498
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4499
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4500
4501
    $courseId = api_get_course_int_id();
4502
    $sessionId = api_get_session_id();
4503
4504
    $forumId = intval($_POST['forum']);
4505
    $threadId = intval($_POST['thread_id']);
4506
    $forumInfo = get_forums($forumId);
4507
4508
    // Change the thread table: Setting the forum_id to the new forum.
4509
    $sql = "UPDATE $table_threads SET forum_id = $forumId
4510
            WHERE c_id = $courseId AND thread_id = $threadId";
4511
    Database::query($sql);
4512
4513
    // Changing all the posts of the thread: setting the forum_id to the new forum.
4514
    $sql = "UPDATE $table_posts SET forum_id = $forumId
4515
            WHERE c_id = $courseId AND thread_id= $threadId";
4516
    Database::query($sql);
4517
    // Fix group id, if forum is moved to a different group
4518
    if (!empty($forumInfo['to_group_id'])) {
4519
        $groupId = $forumInfo['to_group_id'];
4520
        $item = api_get_item_property_info($courseId, TABLE_FORUM_THREAD, $threadId, $sessionId, $groupId);
4521
        $table = Database:: get_course_table(TABLE_ITEM_PROPERTY);
4522
        $sessionCondition = api_get_session_condition($sessionId);
4523
4524
        if (!empty($item)) {
4525
            if ($item['to_group_id'] != $groupId) {
4526
                $sql = "UPDATE $table
4527
                    SET to_group_id = $groupId
4528
                    WHERE
4529
                      tool = '".TABLE_FORUM_THREAD."' AND
4530
                      c_id = $courseId AND
4531
                      ref = ".$item['ref']."
4532
                      $sessionCondition
4533
                ";
4534
                Database::query($sql);
4535
            }
4536
        } else {
4537
            $sql = "UPDATE $table
4538
                    SET to_group_id = $groupId
4539
                    WHERE
4540
                      tool = '".TABLE_FORUM_THREAD."' AND
4541
                      c_id = $courseId AND
4542
                      ref = ".$threadId."
4543
                      $sessionCondition
4544
            ";
4545
            Database::query($sql);
4546
        }
4547
    }
4548
4549
    return get_lang('ThreadMoved');
4550
}
4551
4552
/**
4553
 * Prepares a string for displaying by highlighting the search results inside, if any.
4554
 * @param string $input    The input string.
4555
 * @return string          The same string with highlighted hits inside.
4556
 *
4557
 * @author Patrick Cool <[email protected]>, Ghent University, February 2006 - the initial version.
4558
 * @author Ivan Tcholakov, March 2011 - adaptation for Chamilo LMS.
4559
 */
4560
function prepare4display($input)
4561
{
4562
    static $highlightcolors = array('yellow', '#33CC33', '#3399CC', '#9999FF', '#33CC33');
4563
    static $search;
4564
4565
    if (!isset($search)) {
4566
        if (isset($_POST['search_term'])) {
4567
            $search = $_POST['search_term']; // No html at all.
4568
        } elseif (isset($_GET['search'])) {
4569
            $search = $_GET['search'];
4570
        } else {
4571
            $search = '';
4572
        }
4573
    }
4574
4575
    if (!empty($search)) {
4576
        if (strstr($search, '+')) {
4577
            $search_terms = explode('+', $search);
4578
        } else {
4579
            $search_terms[] = trim($search);
4580
        }
4581
        $counter = 0;
4582
        foreach ($search_terms as $key => $search_term) {
4583
            $input = api_preg_replace('/'.preg_quote(trim($search_term), '/').'/i', '<span style="background-color: '.$highlightcolors[$counter].'">$0</span>', $input);
4584
            $counter++;
4585
        }
4586
    }
4587
4588
    // TODO: Security should be implemented outside this function.
4589
    // 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).
4590
4591
    return Security::remove_XSS($input, STUDENT, true);
4592
}
4593
4594
/**
4595
 * Display the search form for the forum and display the search results
4596
 * @return void display an HTML search results
4597
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4598
 * @version march 2008, dokeos 1.8.5
4599
 */
4600
function forum_search()
4601
{
4602
    // Initialize the object.
4603
    $form = new FormValidator('forumsearch', 'post', 'forumsearch.php?'.api_get_cidreq());
4604
4605
    // Setting the form elements.
4606
    $form->addElement('header', '', get_lang('ForumSearch'));
4607
    $form->addElement('text', 'search_term', get_lang('SearchTerm'), array('autofocus'));
4608
    $form->applyFilter('search_term', 'html_filter');
4609
    $form->addElement('static', 'search_information', '', get_lang('ForumSearchInformation'));
4610
    $form->addButtonSearch(get_lang('Search'));
4611
4612
    // Setting the rules.
4613
    $form->addRule('search_term', get_lang('ThisFieldIsRequired'), 'required');
4614
    $form->addRule('search_term', get_lang('TooShort'), 'minlength', 3);
4615
4616
    // Validation or display.
4617
    if ($form->validate()) {
4618
        $values = $form->exportValues();
4619
        $form->setDefaults($values);
4620
        $form->display();
4621
        // Display the search results.
4622
        display_forum_search_results(stripslashes($values['search_term']));
4623
    } else {
4624
        $form->display();
4625
    }
4626
}
4627
4628
/**
4629
 * Display the search results
4630
 * @param string
4631
 * @param string $search_term
4632
 * @return void display the results
4633
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4634
 * @version march 2008, dokeos 1.8.5
4635
 */
4636
function display_forum_search_results($search_term)
4637
{
4638
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
4639
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
4640
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
4641
    $session_id = api_get_session_id();
4642
    $gradebook = Security::remove_XSS($_GET['gradebook']);
4643
    $course_id = api_get_course_int_id();
4644
4645
    // Defining the search strings as an array.
4646
    if (strstr($search_term, '+')) {
4647
        $search_terms = explode('+', $search_term);
4648
    } else {
4649
        $search_terms[] = $search_term;
4650
    }
4651
4652
    // Search restriction.
4653
    foreach ($search_terms as $value) {
4654
        $search_restriction[] = "
4655
        (
4656
            posts.post_title LIKE '%".Database::escape_string(trim($value))."%' OR 
4657
            posts.post_text LIKE '%".Database::escape_string(trim($value))."%' 
4658
        )";
4659
    }
4660
    $sessionCondition = api_get_session_condition($session_id, true, false, 'item_property.session_id');
4661
4662
    $sql = "SELECT posts.*
4663
            FROM $table_posts posts INNER JOIN $table_threads threads
4664
            ON (posts.thread_id = threads.thread_id AND posts.c_id = threads.c_id)
4665
            INNER JOIN $table_item_property item_property
4666
            ON (item_property.ref = threads.thread_id AND item_property.c_id = threads.c_id)
4667
            WHERE
4668
                posts.c_id = $course_id AND 
4669
                item_property.c_id = $course_id AND 
4670
                item_property.visibility = 1  
4671
                $sessionCondition AND
4672
                posts.visible = 1 AND 
4673
                item_property.tool = '".TOOL_FORUM_THREAD."' AND 
4674
                ".implode(' AND ', $search_restriction)."
4675
                GROUP BY posts.post_id";
4676
4677
    // Getting all the information of the forum categories.
4678
    $forum_categories_list = get_forum_categories();
4679
4680
    // Getting all the information of the forums.
4681
    $forum_list = get_forums();
4682
4683
    $result = Database::query($sql);
4684
    $search_results = [];
4685
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4686
        $forumId = $row['forum_id'];
4687
        $forumData = get_forums($forumId);
4688
        $category = isset($forum_categories_list[$forumData['forum_category']]) ? $forum_categories_list[$forumData['forum_category']] : null;
4689
        $display_result = false;
4690
        /*
4691
          We only show it when
4692
          1. forum category is visible
4693
          2. forum is visible
4694
          3. thread is visible (to do)
4695
          4. post is visible
4696
         */
4697
        if (!api_is_allowed_to_edit(null, true)) {
4698
            if (!empty($category)) {
4699
                if ($category['visibility'] == '1' && $forumData['visibility'] == '1') {
4700
                $display_result = true;
4701
                }
4702
            } else {
4703
                if ($forumData['visible'] == '1') {
4704
                    $display_result = true;
4705
                }
4706
            }
4707
        } else {
4708
            $display_result = true;
4709
        }
4710
4711
        if ($display_result) {
4712
            $categoryName = !empty($category) ? $category['cat_title'] : '';
4713
            $search_results_item = '<li><a href="viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.$forumData['forum_category'].'&search='.urlencode($search_term).'">'.
4714
                prepare4display($categoryName).'</a> &gt; ';
4715
            $search_results_item .= '<a href="viewforum.php?'.api_get_cidreq().'&forum='.$forumId.'&search='.urlencode($search_term).'">'.
4716
                prepare4display($forum_list[$row['forum_id']]['forum_title']).'</a> &gt; ';
4717
            //$search_results_item .= '<a href="">THREAD</a> &gt; ';
4718
            $search_results_item .= '<a href="viewthread.php?'.api_get_cidreq().'&forum='.$forumId.'&gradebook='.$gradebook.'&thread='.$row['thread_id'].'&search='.urlencode($search_term).'">'.
4719
                prepare4display($row['post_title']).'</a>';
4720
            $search_results_item .= '<br />';
4721
            if (api_strlen($row['post_title']) > 200) {
4722
                $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...
4723
            } else {
4724
                $search_results_item .= prepare4display($row['post_title']);
4725
            }
4726
            $search_results_item .= '</li>';
4727
            $search_results[] = $search_results_item;
4728
        }
4729
    }
4730
    echo '<legend>'.count($search_results).' '.get_lang('ForumSearchResults').'</legend>';
4731
    echo '<ol>';
4732
    if ($search_results) {
4733
        echo implode($search_results);
4734
    }
4735
    echo '</ol>';
4736
}
4737
4738
/**
4739
 * Return the link to the forum search page
4740
 *
4741
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
4742
 * @version April 2008, dokeos 1.8.5
4743
 */
4744
function search_link()
4745
{
4746
    $return = '';
4747
    $origin = api_get_origin();
4748
    if ($origin != 'learnpath') {
4749
        $return = '<a href="forumsearch.php?'.api_get_cidreq().'&action=search"> ';
4750
        $return .= Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';
4751
4752
        if (!empty($_GET['search'])) {
4753
            $return .= ': '.Security::remove_XSS($_GET['search']).' ';
4754
            $url = api_get_self().'?';
4755
            $url_parameter = array();
4756
            foreach ($_GET as $key => $value) {
4757
                if ($key != 'search') {
4758
                    $url_parameter[] = Security::remove_XSS($key).'='.Security::remove_XSS($value);
4759
                }
4760
            }
4761
            $url = $url.implode('&', $url_parameter);
4762
            $return .= '<a href="'.$url.'">'.Display::return_icon('delete.gif', get_lang('RemoveSearchResults')).'</a>';
4763
        }
4764
    }
4765
4766
    return $return;
4767
}
4768
4769
/**
4770
 * This function adds an attachment file into a forum
4771
 * @param string $file_comment  a comment about file
4772
 * @param int $last_id from forum_post table
4773
 * @return false|null
4774
 */
4775
function add_forum_attachment_file($file_comment, $last_id)
4776
{
4777
    $_course = api_get_course_info();
4778
    $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4779
4780
    if (!isset($_FILES['user_upload'])) {
4781
        return false;
4782
    }
4783
4784
    $fileCount = count($_FILES['user_upload']['name']);
4785
4786
    $filesData = [];
4787
4788 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4789
        $filesData[] = $_FILES['user_upload'];
4790
    } else {
4791
        $fileKeys = array_keys($_FILES['user_upload']);
4792
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'));
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
4878
    $filesData = [];
4879
4880 View Code Duplication
    if (!is_array($_FILES['user_upload']['name'])) {
4881
        $filesData[] = $_FILES['user_upload'];
4882
    } else {
4883
        $fileKeys = array_keys($_FILES['user_upload']);
4884
4885
        for ($i = 0; $i < $fileCount; $i++) {
4886
            foreach ($fileKeys as $key) {
4887
                $filesData[$i][$key] = $_FILES['user_upload'][$key][$i];
4888
            }
4889
        }
4890
    }
4891
4892
    foreach ($filesData as $attachment) {
4893
        if (empty($attachment['name'])) {
4894
            continue;
4895
        }
4896
4897
        $upload_ok = process_uploaded_file($attachment);
4898
4899
        if (!$upload_ok) {
4900
            continue;
4901
        }
4902
4903
        $course_dir = $_course['path'].'/upload/forum';
4904
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
4905
        $updir = $sys_course_path.$course_dir;
4906
4907
        // Try to add an extension to the file if it hasn't one.
4908
        $new_file_name = add_ext_on_mime(stripslashes($attachment['name']), $attachment['type']);
4909
        // User's file name
4910
        $file_name = $attachment['name'];
4911
4912
        if (!filter_extension($new_file_name)) {
4913
            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
4914
        } else {
4915
            $new_file_name = uniqid('');
4916
            $new_path = $updir.'/'.$new_file_name;
4917
            $result = @move_uploaded_file($attachment['tmp_name'], $new_path);
4918
            $safe_file_comment = Database::escape_string($file_comment);
4919
            $safe_file_name = Database::escape_string($file_name);
4920
            $safe_new_file_name = Database::escape_string($new_file_name);
4921
            $safe_post_id = (int) $post_id;
4922
            $safe_id_attach = (int) $id_attach;
4923
            // Storing the attachments if any.
4924 View Code Duplication
            if ($result) {
4925
                $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']."'
4926
                       WHERE c_id = $course_id AND id = '$safe_id_attach'";
4927
                Database::query($sql);
4928
                api_item_property_update($_course, TOOL_FORUM_ATTACH, $safe_id_attach, 'ForumAttachmentUpdated', api_get_user_id());
4929
            }
4930
        }
4931
    }
4932
}
4933
4934
/**
4935
 * Show a list with all the attachments according to the post's id
4936
 * @param int $post_id
4937
 * @return array with the post info
4938
 * @author Julio Montoya
4939
 * @version avril 2008, dokeos 1.8.5
4940
 */
4941
function get_attachment($post_id)
4942
{
4943
    $forum_table_attachment = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4944
    $course_id = api_get_course_int_id();
4945
    $row = array();
4946
    $post_id = intval($post_id);
4947
    $sql = "SELECT iid, path, filename, comment 
4948
            FROM $forum_table_attachment
4949
            WHERE c_id = $course_id AND post_id = $post_id";
4950
    $result = Database::query($sql);
4951
    if (Database::num_rows($result) != 0) {
4952
        $row = Database::fetch_array($result);
4953
    }
4954
4955
    return $row;
4956
}
4957
4958
/**
4959
 * @param int $postId
4960
 *
4961
 * @return array
4962
 */
4963
function getAllAttachment($postId)
4964
{
4965
    $forumAttachmentTable = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
4966
    $courseId = api_get_course_int_id();
4967
    $postId = intval($postId);
4968
    $columns = array('iid', 'path', 'filename', 'comment');
4969
    $conditions = array(
4970
        'where' => array(
4971
            'c_id = ? AND post_id = ?' => array($courseId, $postId),
4972
        ),
4973
    );
4974
    $array = Database::select(
4975
        $columns,
4976
        $forumAttachmentTable,
4977
        $conditions,
4978
        'all',
4979
        'ASSOC'
4980
    );
4981
4982
    return $array;
4983
}
4984
4985
/**
4986
 * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
4987
 * @param int $post_id
4988
 * @param int $id_attach
4989
 * @param bool $display to show or not result message
4990
 * @return integer
4991
 * @author Julio Montoya
4992
 * @version october 2014, chamilo 1.9.8
4993
 */
4994
function delete_attachment($post_id, $id_attach = 0, $display = true)
4995
{
4996
    $_course = api_get_course_info();
4997
4998
    $forum_table_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
4999
    $course_id = api_get_course_int_id();
5000
5001
    $cond = (!empty($id_attach)) ? " iid = " . (int) $id_attach . "" : " post_id = " . (int) $post_id . "";
5002
    $sql = "SELECT path FROM $forum_table_attachment WHERE c_id = $course_id AND $cond";
5003
    $res = Database::query($sql);
5004
    $row = Database::fetch_array($res);
5005
5006
    $course_dir = $_course['path'] . '/upload/forum';
5007
    $sys_course_path = api_get_path(SYS_COURSE_PATH);
5008
    $updir = $sys_course_path . $course_dir;
5009
    $my_path = isset($row['path']) ? $row['path'] : null;
5010
    $file = $updir . '/' . $my_path;
5011
    if (Security::check_abs_path($file, $updir)) {
5012
        @unlink($file);
5013
    }
5014
5015
    // Delete from forum_attachment table.
5016
    $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
5017
    $result = Database::query($sql);
5018
    if ($result !== false) {
5019
        $affectedRows = Database::affected_rows($result);
5020
    } else {
5021
        $affectedRows = 0;
5022
    }
5023
5024
    // Update item_property.
5025
    api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
5026
5027
    if (!empty($result) && !empty($id_attach) && $display) {
5028
        $message = get_lang('AttachmentFileDeleteSuccess');
5029
        Display::display_confirmation_message($message);
5030
    }
5031
5032
    return $affectedRows;
5033
}
5034
5035
/**
5036
 * This function gets all the forum information of the all the forum of the group
5037
 *
5038
 * @param integer $groupId the id of the group we need the fora of (see forum.forum_of_group)
5039
 * @return array
5040
 *
5041
 * @todo this is basically the same code as the get_forums function. Consider merging the two.
5042
 */
5043
function get_forums_of_group($groupId)
5044
{
5045
    $table_forums = Database :: get_course_table(TABLE_FORUM);
5046
    $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
5047
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5048
    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
5049
    $course_id = api_get_course_int_id();
5050
    $groupId = (int) $groupId;
5051
5052
    // Student
5053
    // Select all the forum information of all forums (that are visible to students).
5054
5055
    $sql = "SELECT * FROM $table_forums forum, $table_item_property item_properties
5056
            WHERE
5057
                forum.forum_of_group = $groupId AND
5058
                forum.c_id = $course_id AND
5059
                item_properties.c_id = $course_id AND
5060
                forum.forum_id = item_properties.ref AND
5061
                item_properties.visibility = 1 AND
5062
                item_properties.tool = '".TOOL_FORUM."'
5063
            ORDER BY forum.forum_order ASC";
5064
    // Select the number of threads of the forums (only the threads that are visible).
5065
    $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
5066
            FROM $table_threads threads, $table_item_property item_properties
5067
            WHERE
5068
                threads.thread_id = item_properties.ref AND
5069
                threads.c_id = $course_id AND
5070
                item_properties.c_id = $course_id AND
5071
                item_properties.visibility = 1 AND
5072
                item_properties.tool='".TOOL_FORUM_THREAD."'
5073
            GROUP BY threads.forum_id";
5074
    // Select the number of posts of the forum (post that are visible and that are in a thread that is visible).
5075
    $sql3 = "SELECT count(post_id) AS number_of_posts, posts.forum_id
5076
            FROM $table_posts posts, $table_threads threads, $table_item_property item_properties
5077
            WHERE posts.visible=1 AND
5078
                posts.c_id = $course_id AND
5079
                item_properties.c_id = $course_id AND
5080
                threads.c_id = $course_id
5081
                AND posts.thread_id=threads.thread_id
5082
                AND threads.thread_id=item_properties.ref
5083
                AND item_properties.visibility = 1
5084
                AND item_properties.tool='".TOOL_FORUM_THREAD."'
5085
            GROUP BY threads.forum_id";
5086
5087
    // Course Admin
5088 View Code Duplication
    if (api_is_allowed_to_edit()) {
5089
        // Select all the forum information of all forums (that are not deleted).
5090
        $sql = "SELECT *
5091
                FROM $table_forums forum, $table_item_property item_properties
5092
                WHERE
5093
                    forum.forum_of_group = $groupId AND
5094
                    forum.c_id = $course_id AND
5095
                    item_properties.c_id = $course_id AND
5096
                    forum.forum_id = item_properties.ref AND
5097
                    item_properties.visibility <> 2 AND
5098
                    item_properties.tool = '".TOOL_FORUM."'
5099
                ORDER BY forum_order ASC";
5100
5101
        // Select the number of threads of the forums (only the threads that are not deleted).
5102
        $sql2 = "SELECT count(thread_id) AS number_of_threads, threads.forum_id
5103
                 FROM $table_threads threads, $table_item_property item_properties
5104
                 WHERE
5105
                    threads.thread_id=item_properties.ref AND
5106
                    threads.c_id = $course_id AND
5107
                    item_properties.c_id = $course_id AND
5108
                    item_properties.visibility <> 2 AND
5109
                    item_properties.tool='".TOOL_FORUM_THREAD."'
5110
                GROUP BY threads.forum_id";
5111
        // Select the number of posts of the forum.
5112
        $sql3 = "SELECT count(post_id) AS number_of_posts, forum_id
5113
                FROM $table_posts
5114
                WHERE c_id = $course_id 
5115
                GROUP BY forum_id";
5116
5117
    }
5118
5119
    // Handling all the forum information.
5120
5121
    $result = Database::query($sql);
5122
    $forum_list = array();
5123
    while ($row = Database::fetch_array($result, 'ASSOC')) {
5124
        $forum_list[$row['forum_id']] = $row;
5125
    }
5126
5127
    // Handling the thread count information.
5128
    $result2 = Database::query($sql2);
5129 View Code Duplication
    while ($row2 = Database::fetch_array($result2, 'ASSOC')) {
5130
        if (is_array($forum_list)) {
5131
            if (array_key_exists($row2['forum_id'], $forum_list)) {
5132
                $forum_list[$row2['forum_id']]['number_of_threads'] = $row2['number_of_threads'];
5133
            }
5134
        }
5135
    }
5136
5137
    // Handling the post count information.
5138
    $result3 = Database::query($sql3);
5139 View Code Duplication
    while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
5140
        if (is_array($forum_list)) {
5141
            if (array_key_exists($row3['forum_id'], $forum_list)) {
5142
                // This is needed because sql3 takes also the deleted forums into account.
5143
                $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
5144
            }
5145
        }
5146
    }
5147
5148
    // Finding the last post information (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
5149
    if (!empty($forum_list)) {
5150 View Code Duplication
        foreach ($forum_list as $key => $value) {
5151
            $last_post_info_of_forum = get_last_post_information($key, api_is_allowed_to_edit());
5152
            if ($last_post_info_of_forum) {
5153
                $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];
5154
                $forum_list[$key]['last_poster_id'] = $last_post_info_of_forum['last_poster_id'];
5155
                $forum_list[$key]['last_post_date'] = $last_post_info_of_forum['last_post_date'];
5156
                $forum_list[$key]['last_poster_name'] = $last_post_info_of_forum['last_poster_name'];
5157
                $forum_list[$key]['last_poster_lastname'] = $last_post_info_of_forum['last_poster_lastname'];
5158
                $forum_list[$key]['last_poster_firstname'] = $last_post_info_of_forum['last_poster_firstname'];
5159
            }
5160
        }
5161
    }
5162
5163
    return $forum_list;
5164
}
5165
5166
/**
5167
 * This function stores which users have to be notified of which forums or threads
5168
 *
5169
 * @param string $content does the user want to be notified about a forum or about a thread
5170
 * @param integer $id the id of the forum or thread
5171
 * @return string language variable
5172
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5173
 * @version May 2008, dokeos 1.8.5
5174
 * @since May 2008, dokeos 1.8.5
5175
 */
5176
function set_notification($content, $id, $add_only = false)
5177
{
5178
    $_user = api_get_user_info();
5179
5180
    // Database table definition
5181
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5182
5183
    $course_id = api_get_course_int_id();
5184
5185
    // Which database field do we have to store the id in?
5186
    if ($content == 'forum') {
5187
        $database_field = 'forum_id';
5188
    } else {
5189
        $database_field = 'thread_id';
5190
    }
5191
5192
    // First we check if the notification is already set for this.
5193
    $sql = "SELECT * FROM $table_notification
5194
            WHERE
5195
                c_id = $course_id AND
5196
                $database_field = '".Database::escape_string($id)."' AND
5197
                user_id = '".intval($_user['user_id'])."'";
5198
    $result = Database::query($sql);
5199
    $total = Database::num_rows($result);
5200
5201
    // If the user did not indicate that (s)he wanted to be notified already
5202
    // then we store the notification request (to prevent double notification requests).
5203
    if ($total <= 0) {
5204
        $sql = "INSERT INTO $table_notification (c_id, $database_field, user_id)
5205
                VALUES (".$course_id.", '".Database::escape_string($id)."','".intval($_user['user_id'])."')";
5206
        Database::query($sql);
5207
        Session::erase('forum_notification');
5208
        get_notifications_of_user(0, true);
5209
5210
        return get_lang('YouWillBeNotifiedOfNewPosts');
5211
    } else {
5212
        if (!$add_only) {
5213
            $sql = "DELETE FROM $table_notification
5214
                    WHERE
5215
                        c_id = $course_id AND
5216
                        $database_field = '".Database::escape_string($id)."' AND
5217
                        user_id = '".intval($_user['user_id'])."'";
5218
            Database::query($sql);
5219
            Session::erase('forum_notification');
5220
            get_notifications_of_user(0, true);
5221
5222
            return get_lang('YouWillNoLongerBeNotifiedOfNewPosts');
5223
        }
5224
    }
5225
}
5226
5227
/**
5228
 * This function retrieves all the email adresses of the users who wanted to be notified
5229
 * about a new post in a certain forum or thread
5230
 *
5231
 * @param string $content does the user want to be notified about a forum or about a thread
5232
 * @param integer $id the id of the forum or thread
5233
 * @return array returns
5234
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5235
 * @version May 2008, dokeos 1.8.5
5236
 * @since May 2008, dokeos 1.8.5
5237
 */
5238
function get_notifications($content, $id)
5239
{
5240
    // Database table definition
5241
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5242
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5243
5244
    $course_id = api_get_course_int_id();
5245
5246
    // Which database field contains the notification?
5247
    if ($content == 'forum') {
5248
        $database_field = 'forum_id';
5249
    } else {
5250
        $database_field = 'thread_id';
5251
    }
5252
5253
    $sql = "SELECT user.user_id, user.firstname, user.lastname, user.email, user.user_id user
5254
            FROM $table_users user, $table_notification notification
5255
            WHERE notification.c_id = $course_id AND user.active = 1 AND
5256
            user.user_id = notification.user_id AND
5257
            notification.$database_field= '".Database::escape_string($id)."'";
5258
5259
    $result = Database::query($sql);
5260
    $return = array();
5261
5262
    while ($row = Database::fetch_array($result)) {
5263
        $return['user'.$row['user_id']] = array('email' => $row['email'], 'user_id' => $row['user_id']);
5264
    }
5265
5266
    return $return;
5267
}
5268
5269
/**
5270
 * Get all the users who need to receive a notification of a new post (those subscribed to
5271
 * the forum or the thread)
5272
 *
5273
 * @param integer $forum_id the id of the forum
5274
 * @param integer $thread_id the id of the thread
5275
 * @param integer $post_id the id of the post
5276
 * @return false|null
5277
 *
5278
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5279
 * @version May 2008, dokeos 1.8.5
5280
 * @since May 2008, dokeos 1.8.5
5281
 */
5282
function send_notifications($forum_id = 0, $thread_id = 0, $post_id = 0)
5283
{
5284
    $_course = api_get_course_info();
5285
    $forum_id = (int) $forum_id;
5286
5287
    // The content of the mail
5288
    $thread_link = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forum_id.'&thread='.$thread_id;
5289
5290
    // Users who subscribed to the forum
5291
    if ($forum_id != 0) {
5292
        $users_to_be_notified_by_forum = get_notifications('forum', $forum_id);
5293
    } else {
5294
        return false;
5295
    }
5296
5297
    $current_thread = get_thread_information($forum_id, $thread_id);
5298
    $current_forum = get_forum_information($current_thread['forum_id']);
5299
    $subject = get_lang('NewForumPost').' - '.$_course['official_code'].' - '.$current_forum['forum_title'].' - '.$current_thread['thread_title'];
5300
5301
    // User who subscribed to the thread
5302
    if ($thread_id != 0) {
5303
        $users_to_be_notified_by_thread = get_notifications('thread', $thread_id);
5304
    }
5305
5306
    // Merging the two
5307
    $users_to_be_notified = array_merge($users_to_be_notified_by_forum, $users_to_be_notified_by_thread);
5308
    $sender_id = api_get_user_id();
5309
5310
    if (is_array($users_to_be_notified)) {
5311
        foreach ($users_to_be_notified as $value) {
5312
5313
            $user_info = api_get_user_info($value['user_id']);
5314
            $email_body = get_lang('Dear').' '.api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS).", <br />\n\r";
5315
            $email_body .= get_lang('NewForumPost').": ".$current_forum['forum_title'].' - '.$current_thread['thread_title']." <br />\n";
5316
            $email_body .= get_lang('Course').': '.$_course['name'].' - ['.$_course['official_code']."]  <br />\n";
5317
            $email_body .= get_lang('YouWantedToStayInformed')."<br />\n";
5318
            $email_body .= get_lang('ThreadCanBeFoundHere').': <br /> <a href="'.$thread_link.'">'.$thread_link."</a>\n";
5319
5320
            MessageManager::send_message_simple(
5321
                $value['user_id'], $subject, $email_body, $sender_id
5322
            );
5323
        }
5324
    }
5325
}
5326
5327
/**
5328
 * Get all the notification subscriptions of the user
5329
 * = which forums and which threads does the user wants to be informed of when a new
5330
 * post is added to this thread
5331
 *
5332
 * @param integer $user_id the user_id of a user (default = 0 => the current user)
5333
 * @param boolean $force force get the notification subscriptions (even if the information is already in the session
5334
 * @return array returns
5335
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
5336
 * @version May 2008, dokeos 1.8.5
5337
 * @since May 2008, dokeos 1.8.5
5338
 */
5339
function get_notifications_of_user($user_id = 0, $force = false)
5340
{
5341
    // Database table definition
5342
    $table_notification = Database::get_course_table(TABLE_FORUM_NOTIFICATION);
5343
    $course_id = api_get_course_int_id();
5344
    if (empty($course_id) || $course_id == -1) {
5345
        return null;
5346
    }
5347
    if ($user_id == 0) {
5348
        $user_id = api_get_user_id();
5349
    }
5350
5351
    if (!isset($_SESSION['forum_notification']) ||
5352
        $_SESSION['forum_notification']['course'] != $course_id ||
5353
        $force = true
5354
    ) {
5355
        $_SESSION['forum_notification']['course'] = $course_id;
5356
5357
        $sql = "SELECT * FROM $table_notification
5358
                WHERE c_id = $course_id AND user_id='".intval($user_id)."'";
5359
        $result = Database::query($sql);
5360
        while ($row = Database::fetch_array($result)) {
5361
            if (!is_null($row['forum_id'])) {
5362
                $_SESSION['forum_notification']['forum'][] = $row['forum_id'];
5363
            }
5364
            if (!is_null($row['thread_id'])) {
5365
                $_SESSION['forum_notification']['thread'][] = $row['thread_id'];
5366
            }
5367
        }
5368
    }
5369
}
5370
5371
/**
5372
 * This function counts the number of post inside a thread
5373
 * @param   int $thread_id
5374
 * @return  int the number of post inside a thread
5375
 * @author Jhon Hinojosa <[email protected]>,
5376
 * @version octubre 2008, dokeos 1.8
5377
 */
5378
function count_number_of_post_in_thread($thread_id)
5379
{
5380
    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
5381
    $course_id = api_get_course_int_id();
5382
    if (empty($course_id)) {
5383
        return 0;
5384
    }
5385
    $sql = "SELECT * FROM $table_posts
5386
            WHERE c_id = $course_id AND thread_id='".intval($thread_id)."' ";
5387
    $result = Database::query($sql);
5388
5389
    return count(Database::store_result($result));
5390
}
5391
5392
/**
5393
 * This function counts the number of post inside a thread user
5394
 * @param   int $thread_id
5395
 * @param   int $user_id
5396
 *
5397
 * @return  int the number of post inside a thread user
5398
 */
5399
function count_number_of_post_for_user_thread($thread_id, $user_id)
5400
{
5401
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5402
    $course_id = api_get_course_int_id();
5403
    $sql = "SELECT count(*) as count FROM $table_posts
5404
            WHERE c_id = $course_id AND
5405
                  thread_id=".intval($thread_id)." AND
5406
                  poster_id = ".intval($user_id)." AND visible = 1 ";
5407
    $result = Database::query($sql);
5408
    $count = 0;
5409
    if (Database::num_rows($result) > 0) {
5410
        $count = Database::fetch_array($result);
5411
        $count = $count['count'];
5412
    }
5413
5414
    return $count;
5415
}
5416
5417
/**
5418
 * This function counts the number of user register in course
5419
 * @param   int $course_id Course ID
5420
 *
5421
 * @return  int the number of user register in course
5422
 * @author Jhon Hinojosa <[email protected]>,
5423
 * @version octubre 2008, dokeos 1.8
5424
 */
5425
function count_number_of_user_in_course($course_id)
5426
{
5427
    $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5428
5429
    $sql = "SELECT * FROM $table
5430
            WHERE c_id ='".intval($course_id)."' ";
5431
    $result = Database::query($sql);
5432
5433
    return count(Database::store_result($result));
5434
}
5435
5436
/**
5437
 * This function retrieves information of statistical
5438
 * @param   int $thread_id
5439
 * @param   int $user_id
5440
 * @param   int $course_id
5441
 *
5442
 * @return  array the information of statistical
5443
 * @author Jhon Hinojosa <[email protected]>,
5444
 * @version oct 2008, dokeos 1.8
5445
 */
5446
function get_statistical_information($thread_id, $user_id, $course_id)
5447
{
5448
    $result = array();
5449
    $result['user_course'] = count_number_of_user_in_course($course_id);
5450
    $result['post'] = count_number_of_post_in_thread($thread_id);
5451
    $result['user_post'] = count_number_of_post_for_user_thread($thread_id, $user_id);
5452
5453
    return $result;
5454
}
5455
5456
/**
5457
 * This function return the posts inside a thread from a given user
5458
 * @param   string $course_code
5459
 * @param   int $thread_id
5460
 * @param   int $user_id
5461
 *
5462
 * @return  int the number of post inside a thread
5463
 * @author Jhon Hinojosa <[email protected]>,
5464
 * @version octubre 2008, dokeos 1.8
5465
 */
5466
function get_thread_user_post($course_code, $thread_id, $user_id)
5467
{
5468
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5469
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5470
    $thread_id = intval($thread_id);
5471
    $user_id = intval($user_id);
5472
    $course_info = api_get_user_info($course_code);
5473
    $course_id = $course_info['real_id'];
5474
5475
    if (empty($course_id)) {
5476
        $course_id = api_get_course_int_id();
5477
    }
5478
    $sql = "SELECT * FROM $table_posts posts
5479
            LEFT JOIN  $table_users users
5480
                ON posts.poster_id=users.user_id
5481
            WHERE
5482
                posts.c_id = $course_id AND
5483
                posts.thread_id='$thread_id'
5484
                AND posts.poster_id='$user_id'
5485
            ORDER BY posts.post_id ASC";
5486
5487
    $result = Database::query($sql);
5488
    $post_list = array();
5489 View Code Duplication
    while ($row = Database::fetch_array($result)) {
5490
        $row['status'] = '1';
5491
        $post_list[] = $row;
5492
        $sql = "SELECT * FROM $table_posts posts
5493
                LEFT JOIN  $table_users users
5494
                    ON posts.poster_id=users.user_id
5495
                WHERE
5496
                    posts.c_id = $course_id AND
5497
                    posts.thread_id='$thread_id'
5498
                    AND posts.post_parent_id='".$row['post_id']."'
5499
                ORDER BY posts.post_id ASC";
5500
        $result2 = Database::query($sql);
5501
        while ($row2 = Database::fetch_array($result2)) {
5502
            $row2['status'] = '0';
5503
            $post_list[] = $row2;
5504
        }
5505
    }
5506
5507
    return $post_list;
5508
}
5509
5510
/**
5511
 * This function get the name of an thread by id
5512
 * @param int thread_id
5513
 * @return String
5514
 * @author Christian Fasanando
5515
 * @author Julio Montoya <[email protected]> Adding security
5516
 */
5517 View Code Duplication
function get_name_thread_by_id($thread_id)
5518
{
5519
    $t_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
5520
    $course_id = api_get_course_int_id();
5521
    $sql = "SELECT thread_title FROM ".$t_forum_thread."
5522
            WHERE c_id = $course_id AND thread_id = '".intval($thread_id)."' ";
5523
    $result = Database::query($sql);
5524
    $row = Database::fetch_array($result);
5525
5526
    return $row[0];
5527
}
5528
5529
/**
5530
 * This function gets all the post written by an user
5531
 * @param int $user_id
5532
 * @param string $course_code
5533
 *
5534
 * @return string
5535
 */
5536
function get_all_post_from_user($user_id, $course_code)
5537
{
5538
    $j = 0;
5539
    $forums = get_forums('', $course_code);
5540
    krsort($forums);
5541
    $forum_results = '';
5542
5543
    foreach ($forums as $forum) {
5544
        if ($forum['visibility'] == 0) {
5545
            continue;
5546
        }
5547
        if ($j <= 4) {
5548
            $threads = get_threads($forum['forum_id'], $course_code);
5549
5550
            if (is_array($threads)) {
5551
                $i = 0;
5552
                $hand_forums = '';
5553
                $post_counter = 0;
5554
5555
                foreach ($threads as $thread) {
5556
                    if ($thread['visibility'] == 0) {
5557
                        continue;
5558
                    }
5559
                    if ($i <= 4) {
5560
                        $post_list = get_thread_user_post_limit($course_code, $thread['thread_id'], $user_id, 1);
5561
                        $post_counter = count($post_list);
5562
                        if (is_array($post_list) && count($post_list) > 0) {
5563
                            $hand_forums.= '<div id="social-thread">';
5564
                            $hand_forums.= Display::return_icon('thread.png', get_lang('Thread'), '', ICON_SIZE_MEDIUM);
5565
                            $hand_forums.= '&nbsp;'.Security::remove_XSS($thread['thread_title'], STUDENT);
5566
                            $hand_forums.= '</div>';
5567
5568
                            foreach ($post_list as $posts) {
5569
                                $hand_forums.= '<div id="social-post">';
5570
                                $hand_forums.= '<strong>'.Security::remove_XSS($posts['post_title'], STUDENT).'</strong>';
5571
                                $hand_forums.= '<br / >';
5572
                                $hand_forums.= Security::remove_XSS($posts['post_text'], STUDENT);
5573
                                $hand_forums.= '</div>';
5574
                                $hand_forums.= '<br / >';
5575
                            }
5576
                        }
5577
                    }
5578
                    $i++;
5579
                }
5580
                $forum_results .='<div id="social-forum">';
5581
                $forum_results .='<div class="clear"></div><br />';
5582
                $forum_results .='<div id="social-forum-title">'.
5583
                    Display::return_icon('forum.gif', get_lang('Forum')).'&nbsp;'.Security::remove_XSS($forum['forum_title'], STUDENT).
5584
                    '<div style="float:right;margin-top:-35px">
5585
                        <a href="../forum/viewforum.php?'.api_get_cidreq_params($course_code).'&forum='.$forum['forum_id'].' " >'.
5586
                            get_lang('SeeForum').'    
5587
                        </a>
5588
                                    </div></div>';
5589
                $forum_results .='<br / >';
5590
                if ($post_counter > 0) {
5591
                    $forum_results .=$hand_forums;
5592
                }
5593
                $forum_results .='</div>';
5594
            }$j++;
5595
        }
5596
    }
5597
5598
    return $forum_results;
5599
}
5600
5601
/**
5602
 * @param string $course_code
5603
 * @param int $thread_id
5604
 * @param int $user_id
5605
 * @param int $limit
5606
 *
5607
 * @return array
5608
 */
5609
function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10)
5610
{
5611
    $table_posts = Database::get_course_table(TABLE_FORUM_POST);
5612
    $table_users = Database::get_main_table(TABLE_MAIN_USER);
5613
5614
    $course_info = api_get_course_info($course_code);
5615
    $course_id = $course_info['real_id'];
5616
5617
    $sql = "SELECT * FROM $table_posts posts
5618
            LEFT JOIN  $table_users users
5619
                ON posts.poster_id=users.user_id
5620
            WHERE
5621
                posts.c_id = $course_id AND
5622
                posts.thread_id='".Database::escape_string($thread_id)."'
5623
                AND posts.poster_id='".Database::escape_string($user_id)."'
5624
            ORDER BY posts.post_id DESC LIMIT $limit ";
5625
    $result = Database::query($sql);
5626
    $post_list = array();
5627
    while ($row = Database::fetch_array($result)) {
5628
        $row['status'] = '1';
5629
        $post_list[] = $row;
5630
    }
5631
5632
    return $post_list;
5633
}
5634
5635
/**
5636
 * @param string $user_id
5637
 * @param int $courseId
5638
 * @param int $sessionId
5639
 *
5640
 * @return array
5641
 */
5642
function getForumCreatedByUser($user_id, $courseId, $sessionId)
5643
{
5644
    $items = api_get_item_property_list_by_tool_by_user(
5645
        $user_id,
5646
        'forum',
5647
        $courseId,
5648
        $sessionId
5649
    );
5650
5651
    $courseInfo = api_get_course_info_by_id($courseId);
5652
5653
    $forumList = array();
5654 View Code Duplication
    if (!empty($items)) {
5655
        foreach ($items as $forum) {
5656
            $forumInfo = get_forums(
5657
                $forum['ref'],
5658
                $courseInfo['code'],
5659
                true,
5660
                $sessionId
5661
            );
5662
5663
            $forumList[] = array(
5664
                $forumInfo['forum_title'],
5665
                api_get_local_time($forum['insert_date']),
5666
                api_get_local_time($forum['lastedit_date']),
5667
            );
5668
        }
5669
    }
5670
5671
    return $forumList;
5672
}
5673
5674
/**
5675
 * This function builds an array of all the posts in a given thread
5676
 * where the key of the array is the post_id
5677
 * It also adds an element children to the array which itself is an array
5678
 * that contains all the id's of the first-level children
5679
 * @return array $rows containing all the information on the posts of a thread
5680
 * @author Patrick Cool <[email protected]>, Ghent University
5681
 */
5682
function calculate_children($rows)
5683
{
5684
    $sorted_rows = array(0 => array());
5685
    if (!empty($rows)) {
5686
        foreach ($rows as $row) {
5687
            $rows_with_children[$row['post_id']] = $row;
5688
            $rows_with_children[$row['post_parent_id']]['children'][] = $row['post_id'];
5689
        }
5690
5691
        $rows = $rows_with_children;
5692
        forumRecursiveSort($rows, $sorted_rows);
5693
        unset($sorted_rows[0]);
5694
    }
5695
5696
    return $sorted_rows;
5697
}
5698
5699
/**
5700
 * @param $rows
5701
 * @param $threads
5702
 * @param int $seed
5703
 * @param int $indent
5704
 */
5705
function forumRecursiveSort($rows, &$threads, $seed = 0, $indent = 0)
5706
{
5707
    if ($seed > 0) {
5708
        $threads[$rows[$seed]['post_id']] = $rows[$seed];
5709
        $threads[$rows[$seed]['post_id']]['indent_cnt'] = $indent;
5710
        $indent++;
5711
    }
5712
5713
    if (isset($rows[$seed]['children'])) {
5714
        foreach ($rows[$seed]['children'] as $child) {
5715
            forumRecursiveSort($rows, $threads, $child, $indent);
5716
        }
5717
    }
5718
}
5719
5720
/**
5721
 * Update forum attachment data, used to update comment and post ID.
5722
 * @param $array Array (field => value) to update forum attachment row.
5723
 * @param $id Attach ID to find row to update.
5724
 * @param null $courseId Course ID to find row to update.
5725
 * @return int Number of affected rows.
5726
 */
5727
function editAttachedFile($array, $id, $courseId = null) {
5728
    // Init variables
5729
    $setString = '';
5730
    $id = intval($id);
5731
    $courseId = intval($courseId);
5732
    if (empty($courseId)) {
5733
        // $courseId can be null, use api method
5734
        $courseId= api_get_course_int_id();
5735
    }
5736
    /*
5737
     * Check if Attachment ID and Course ID are greater than zero
5738
     * and array of field values is not empty
5739
     */
5740
    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
5741
        foreach($array as $key => &$item) {
5742
            $item = Database::escape_string($item);
5743
            $setString .= $key . ' = "' .$item . '", ';
5744
        }
5745
        // Delete last comma
5746
        $setString = substr($setString, 0, strlen($setString) - 2);
5747
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5748
        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
5749
        $result = Database::query($sql);
5750
        if ($result !== false) {
5751
            $affectedRows = Database::affected_rows($result);
5752 View Code Duplication
            if ($affectedRows > 0) {
5753
                /*
5754
                 * If exist in $_SESSION variable, then delete them from it
5755
                 * because they would be deprecated
5756
                 */
5757
                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
5758
                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
5759
                }
5760
            }
5761
5762
            return $affectedRows;
5763
        }
5764
    }
5765
5766
    return 0;
5767
}
5768
5769
/**
5770
 * Return a form to upload asynchronously attachments to forum post.
5771
 * @param int $forumId Forum ID from where the post are
5772
 * @param int $threadId Thread ID where forum post are
5773
 * @param int $postId Post ID to identify Post
5774
 * @deprecated this function seems to never been used
5775
 * @return string The Forum Attachment Ajax Form
5776
 *
5777
 */
5778
function getAttachmentAjaxForm($forumId, $threadId, $postId)
5779
{
5780
    $forumId = intval($forumId);
5781
    $postId = intval($postId);
5782
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5783
    if ($forumId === 0) {
5784
        // Forum Id must be defined
5785
5786
        return '';
5787
    }
5788
5789
    $url = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq().'&forum=' . $forumId . '&thread=' . $threadId . '&postId=' . $postId . '&a=upload_file';
5790
5791
    $multipleForm = new FormValidator('post');
5792
    $multipleForm->addMultipleUpload($url);
5793
5794
    return $multipleForm->returnForm();
5795
}
5796
5797
/**
5798
 * Return a table where the attachments will be set
5799
 * @param int $postId Forum Post ID
5800
 *
5801
 * @return string The Forum Attachments Ajax Table
5802
 */
5803
function getAttachmentsAjaxTable($postId = 0)
5804
{
5805
    // Init variables
5806
    $postId = intval($postId);
5807
    $courseId = api_get_course_int_id();
5808
    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5809
    $fileDataContent = '';
5810
    // Update comment to show if form did not pass validation
5811
    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
5812
        // 'file_ids is the name from forum attachment ajax form
5813
        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
5814
            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) &&
5815
                is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])
5816
            ) {
5817
                // If exist forum attachment then update into $_SESSION data
5818
                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
5819
            }
5820
        }
5821
    }
5822
    // Get data to fill into attachment files table
5823
    if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5824
        is_array($_SESSION['forum']['upload_file'][$courseId])
5825
    ) {
5826
        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
5827
        foreach ($uploadedFiles as $k => $uploadedFile) {
5828
            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
5829
                // Buil html table including an input with attachmentID
5830
                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
5831
                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
5832
                    $uploadedFile['delete'] . '</td>' .
5833
                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
5834
            } else {
5835
                /*
5836
                 * If attachment data is empty, then delete it from $_SESSION
5837
                 * because could generate and empty row into html table
5838
                 */
5839
                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
5840
            }
5841
        }
5842
    }
5843
    $style = empty($fileDataContent) ? 'display: none;' : '';
5844
    // Forum attachment Ajax table
5845
    $fileData = '
5846
    <div class="control-group " style="'. $style . '">
5847
        <label class="control-label">'.get_lang('AttachmentList').'</label>
5848
        <div class="controls">
5849
            <table id="attachmentFileList" class="files data_table span10">
5850
                <tr>
5851
                    <th>'.get_lang('FileName').'</th>
5852
                    <th>'.get_lang('Size').'</th>
5853
                    <th>'.get_lang('Status').'</th>
5854
                    <th>'.get_lang('Comment').'</th>
5855
                    <th>'.get_lang('Delete').'</th>
5856
                </tr>
5857
                '.$fileDataContent.'
5858
            </table>
5859
        </div>
5860
    </div>';
5861
5862
    return $fileData;
5863
}
5864
5865
/**
5866
 * Return an array of prepared attachment data to build forum attachment table
5867
 * Also, save this array into $_SESSION to do available the attachment data
5868
 * @param int $forumId
5869
 * @param int $threadId
5870
 * @param int $postId
5871
 * @param int $attachId
5872
 * @param int $courseId
5873
 *
5874
 * @return array
5875
 */
5876
function getAttachedFiles($forumId, $threadId, $postId = 0, $attachId = 0, $courseId = 0)
5877
{
5878
    $forumId = intval($forumId);
5879
    $courseId = intval($courseId);
5880
    $attachId = intval($attachId);
5881
    $postId = intval($postId);
5882
    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
5883
    if (empty($courseId)) {
5884
        // $courseId can be null, use api method
5885
        $courseId = api_get_course_int_id();
5886
    }
5887
    if (empty($forumId)) {
5888
        if (!empty($_REQUEST['forum'])) {
5889
            $forumId = intval($_REQUEST['forum']);
5890
        } else {
5891
            // if forum ID is empty, cannot generate delete url
5892
5893
            return array();
5894
        }
5895
    }
5896
    // Check if exist at least one of them to filter forum attachment select query
5897
    if (empty($postId) && empty($attachId)) {
5898
5899
        return array();
5900
    } elseif (empty($postId)) {
5901
        $filter = "AND iid = $attachId";
5902
    } elseif (empty($attachId)) {
5903
        $filter = "AND post_id = $postId";
5904
    } else {
5905
        $filter = "AND post_id = $postId AND iid = $attachId";
5906
    }
5907
    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
5908
    $sql = "SELECT iid, comment, filename, path, size
5909
            FROM $forumAttachmentTable
5910
            WHERE c_id = $courseId $filter";
5911
    $result = Database::query($sql);
5912
    $json = array();
5913
    if ($result !== false && Database::num_rows($result) > 0) {
5914
        while ($row = Database::fetch_array($result, 'ASSOC')) {
5915
            // name contains an URL to download attachment file and its filename
5916
            $json['name'] = Display::url(
5917
                api_htmlentities($row['filename']),
5918
                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'].'&'.api_get_cidreq(),
5919
                array('target'=>'_blank', 'class' => 'attachFilename')
5920
            );
5921
            $json['id'] = $row['iid'];
5922
            $json['comment'] = $row['comment'];
5923
            // Format file size
5924
            $json['size'] = format_file_size($row['size']);
5925
            // Check if $row is consistent
5926
            if (!empty($row) && is_array($row)) {
5927
                // Set result as success and bring delete URL
5928
                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
5929
                $url = api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php?' . api_get_cidreq() . '&action=delete_attach&forum=' . $forumId . '&thread=' . $threadId.'&id_attach=' . $row['iid'];
5930
                $json['delete'] = Display::url(
5931
                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL),
5932
                    $url,
5933
                    array('class' => 'deleteLink')
5934
                );
5935
            } else {
5936
                // If not, set an exclamation result
5937
                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
5938
            }
5939
            // Store array data into $_SESSION
5940
            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
5941
        }
5942
    }
5943
5944
    return $json;
5945
}
5946
5947
/**
5948
 * Clear forum attachment data stored in $_SESSION,
5949
 * If is not defined post, it will clear all forum attachment data from course
5950
 * @param int $postId -1 : Clear all attachments from course stored in $_SESSION
5951
 *                      0 : Clear attachments from course, except from temporal post "0"
5952
 *                          but without delete them from file system and database
5953
 *                     Other values : Clear attachments from course except specified post
5954
 *                          and delete them from file system and database
5955
 * @param int $courseId : Course ID, if it is null, will use api_get_course_int_id()
5956
 *
5957
 * @return array
5958
 */
5959
function clearAttachedFiles($postId = null, $courseId = null) {
5960
    // Init variables
5961
    $courseId = intval($courseId);
5962
    $postId = intval($postId);
5963
    $array = array();
5964
    if (empty($courseId)) {
5965
        // $courseId can be null, use api method
5966
        $courseId = api_get_course_int_id();
5967
    }
5968
    if ($postId === -1) {
5969
        // If post ID is -1 then delete course's attachment data from $_SESSION
5970 View Code Duplication
        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
5971
            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
5972
            unset($_SESSION['forum']['upload_file'][$courseId]);
5973
        }
5974
    } else {
5975
        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
5976
        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
5977
            is_array($_SESSION['forum']['upload_file'][$courseId])) {
5978
            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
5979
                if (!in_array($attachId, $attachIds)) {
5980
                    // If attach ID is not into specified post, delete attachment
5981
                    // Save deleted attachment ID
5982
                    $array[] = $attachId;
5983
                    if ($postId !== 0) {
5984
                        // Post 0 is temporal, delete them from file system and DB
5985
                        delete_attachment(0, $attachId, false);
5986
                    }
5987
                    // Delete attachment data from $_SESSION
5988
                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
5989
                }
5990
            }
5991
        }
5992
    }
5993
5994
    return $array;
5995
}
5996
5997
/**
5998
 * Returns an array of forum attachment ids into a course and forum post
5999
 * @param int $postId
6000
 * @param int $courseId
6001
 *
6002
 * @return array
6003
 */
6004
function getAttachmentIdsByPostId($postId, $courseId = null)
6005
{
6006
6007
    $array = array();
6008
    $courseId = intval($courseId);
6009
    $postId = intval($postId);
6010
    if (empty($courseId)) {
6011
        // $courseId can be null, use api method
6012
        $courseId = api_get_course_int_id();
6013
    }
6014
    if ($courseId > 0) {
6015
        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
6016
        $sql = "SELECT id FROM $forumAttachmentTable
6017
                WHERE c_id = $courseId AND post_id = $postId";
6018
        $result = Database::query($sql);
6019
        if ($result !== false && Database::num_rows($result) > 0) {
6020
            while ($row = Database::fetch_array($result,'ASSOC')) {
6021
                $array[] = $row['id'];
6022
            }
6023
        }
6024
    }
6025
    return $array;
6026
}
6027
6028
/**
6029
 * Check if the forum category exists looking for its title
6030
 * @param string $title The forum category title
6031
 * @param int $courseId The course ID
6032
 * @param int $sessionId Optional. The session ID
6033
 * @return boolean
6034
 */
6035
function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
6036
{
6037
    $sessionId = intval($sessionId);
6038
6039
    $forumCategoryTable = Database::get_course_table(TABLE_FORUM_CATEGORY);
6040
    $itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
6041
6042
    $fakeFrom = "$forumCategoryTable fc
6043
        INNER JOIN $itemProperty ip ";
6044
6045
    if ($sessionId === 0) {
6046
        $fakeFrom .= "
6047
            ON (
6048
                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)
6049
            )
6050
        ";
6051
    } else {
6052
        $fakeFrom .= "
6053
            ON (
6054
                fc.cat_id = ip.ref AND fc.c_id = ip.c_id AND fc.session_id = ip.session_id
6055
            )
6056
        ";
6057
    }
6058
6059
    $resultData = Database::select(
6060
        'fc.*',
6061
        $fakeFrom,
6062
        [
6063
            'where' => [
6064
                'ip.visibility != ? AND ' => 2,
6065
                'ip.tool = ? AND ' => TOOL_FORUM_CATEGORY,
6066
                'fc.session_id = ? AND ' => $sessionId,
6067
                'fc.cat_title = ? AND ' => $title,
6068
                'fc.c_id = ?' => intval($courseId)
6069
            ]
6070
        ],
6071
        'first'
6072
    );
6073
6074
    if (empty($resultData)) {
6075
        return false;
6076
    }
6077
6078
    return $resultData;
6079
}
6080
6081
function getPostStatus($current_forum, $row)
6082
{
6083
    $statusIcon = '';
6084
    if ($current_forum['moderated']) {
6085
        $statusIcon = '<br /><br />';
6086
        $row['status'] = empty($row['status']) ? 2 : $row['status'];
6087
        switch ($row['status']) {
6088
            case CForumPost::STATUS_VALIDATED:
6089
                $statusIcon .= Display::label(get_lang('Validated'), 'success');
6090
                break;
6091
            case CForumPost::STATUS_WAITING_MODERATION:
6092
                $statusIcon .= Display::label(get_lang('WaitingModeration'), 'warning');
6093
                break;
6094
            case CForumPost::STATUS_REJECTED:
6095
                $statusIcon .= Display::label(get_lang('Rejected'), 'danger');
6096
                break;
6097
        }
6098
    }
6099
6100
    return $statusIcon;
6101
}
6102