Completed
Push — 1.10.x ( ba0bf0...97c0d2 )
by Angel Fernando Quiroz
44:06
created

work.lib.php ➔ updatePublicationAssignment()   F

Complexity

Conditions 21
Paths > 20000

Size

Total Lines 155
Code Lines 107

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 21
eloc 107
nc 48384
nop 4
dl 0
loc 155
rs 2

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
6
/**
7
 *  @package chamilo.work
8
 *  @author Thomas, Hugues, Christophe - original version
9
 *  @author Patrick Cool <[email protected]>, Ghent University -
10
 * ability for course admins to specify wether uploaded documents are visible or invisible by default.
11
 *  @author Roan Embrechts, code refactoring and virtual course support
12
 *  @author Frederic Vauthier, directories management
13
 *  @author Julio Montoya <[email protected]> BeezNest 2011 LOTS of bug fixes
14
 *  @todo   this lib should be convert in a static class and moved to main/inc/lib
15
 */
16
17
/**
18
 * Displays action links (for admins, authorized groups members and authorized students)
19
 * @param   string  Current dir
20
 * @param   integer Whether to show tool options
21
 * @param   integer Whether to show upload form option
22
 * @return  void
23
 */
24
function display_action_links($id, $cur_dir_path, $action)
25
{
26
    global $gradebook;
27
28
    $id = $my_back_id = intval($id);
29
    if ($action == 'list') {
30
        $my_back_id = 0;
31
    }
32
33
    $display_output = '';
34
    $origin = isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '';
35
36
    if (!empty($id)) {
37
        $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&origin='.$origin.'&gradebook='.$gradebook.'&id='.$my_back_id.'">'.
38
            Display::return_icon('back.png', get_lang('BackToWorksList'),'',ICON_SIZE_MEDIUM).'</a>';
39
    }
40
41
    if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath') {
42
        // Create dir
43
        if (empty($id)) {
44
            $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=create_dir&origin='.$origin.'&gradebook='.$gradebook.'">';
45
            $display_output .= Display::return_icon('new_work.png', get_lang('CreateAssignment'),'',ICON_SIZE_MEDIUM).'</a>';
46
        }
47
        if (empty($id)) {
48
            // Options
49
            $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=settings&origin='.$origin.'&gradebook='.$gradebook.'">';
50
            $display_output .= Display::return_icon('settings.png', get_lang('EditToolOptions'),'',ICON_SIZE_MEDIUM).'</a>';
51
        }
52
        $display_output .= '<a id="open-view-list" href="#">' . Display::return_icon('listwork.png', get_lang('ViewStudents'),'',ICON_SIZE_MEDIUM) . '</a>';
53
54
    }
55
56
    if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath' && api_is_allowed_to_session_edit(false, true)) {
57
        // Delete all files
58
        if (api_get_setting('permanently_remove_deleted_files') == 'true'){
59
            $message = get_lang('ConfirmYourChoiceDeleteAllfiles');
60
        } else {
61
            $message = get_lang('ConfirmYourChoice');
62
        }
63
    }
64
65
    if ($display_output != '') {
66
        echo '<div class="actions">';
67
        echo $display_output;
68
        echo '</div>';
69
    }
70
}
71
72
/**
73
 * Returns a form displaying all options for this tool.
74
 * These are
75
 * - make all files visible / invisible
76
 * - set the default visibility of uploaded files
77
 * @param $defaults
78
 * @return string The HTML form
79
 */
80
function settingsForm($defaults)
81
{
82
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
83
84
    if (!$is_allowed_to_edit) {
85
        return;
86
    }
87
88
    $url = api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'&action=settings';
89
    $form = new FormValidator('edit_settings', 'post', $url);
90
    $form->addElement('hidden', 'changeProperties', 1);
91
    $form->addElement('header', get_lang('EditToolOptions'));
92
93
    $group = array(
94
        $form->createElement('radio', 'show_score', null, get_lang('NewVisible'), 0),
95
        $form->createElement('radio', 'show_score', null, get_lang('NewUnvisible'), 1)
96
    );
97
    $form->addGroup($group, '', get_lang('DefaultUpload'));
98
99
    $group = array(
100
        $form->createElement('radio', 'student_delete_own_publication', null, get_lang('Yes'), 1),
101
        $form->createElement('radio', 'student_delete_own_publication', null, get_lang('No'), 0)
102
    );
103
    $form->addGroup($group, '', get_lang('StudentAllowedToDeleteOwnPublication'));
104
    $form->addButtonSave(get_lang('Save'));
105
    $form->setDefaults($defaults);
106
107
    return $form->returnForm();
108
}
109
110
/**
111
 * converts 1-9 to 01-09
112
 */
113
function two_digits($number)
114
{
115
    $number = (int)$number;
116
    return ($number < 10) ? '0'.$number : $number;
117
}
118
119
/**
120
 * Converts 2008-10-06 12:45:00 to -> array('prefix' => array(year'=>2008, 'month'=>10, etc...)
121
 * @param string
122
 * @param string
123
 * @param array
124
 */
125
function convert_date_to_array($date, $group)
126
{
127
    $parts = explode(' ', $date);
128
    $date_parts = explode('-', $parts[0]);
129
    $date_parts_tmp = array();
130
    foreach ($date_parts as $item) {
131
        $date_parts_tmp[] = intval($item);
132
    }
133
134
    $time_parts = explode(':', $parts[1]);
135
    $time_parts_tmp = array();
136
    foreach ($time_parts as $item) {
137
        $time_parts_tmp[] = intval($item);
138
    }
139
    list($data[$group]['year'], $data[$group]['month'], $data[$group]['day']) = $date_parts_tmp;
140
    list($data[$group]['hour'], $data[$group]['minute']) = $time_parts_tmp;
141
    return $data;
0 ignored issues
show
Bug introduced by
The variable $data does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
142
}
143
144
/**
145
 * get date from a group of date
146
 */
147 View Code Duplication
function get_date_from_group($group)
148
{
149
    return
150
        $_POST[$group]['year'].'-'.
151
        two_digits($_POST[$group]['month']).'-'.
152
        two_digits($_POST[$group]['day']).' '.
153
        two_digits($_POST[$group]['hour']).':'.
154
        two_digits($_POST[$group]['minute']).':00';
155
}
156
157
/**
158
 * Create a group of select from a date
159
 * @param FormValidator $form
160
 * @param string $prefix
161
 * @return array
162
 */
163
function create_group_date_select($form, $prefix = '')
164
{
165
    $minute = range(10, 59);
166
    $d_year = date('Y');
167
    array_unshift($minute, '00', '01', '02', '03', '04', '05', '06', '07', '08', '09');
168
169
    $group_name = array(
170
        $form->createElement('select', $prefix.'day', '', array_combine(range(1, 31), range(1, 31))),
171
        $form->createElement('select', $prefix.'month', '', array_combine(range(1, 12), api_get_months_long())),
172
        $form->createElement('select', $prefix.'year', '', array($d_year => $d_year, $d_year + 1 => $d_year + 1)),
173
        $form->createElement('select', $prefix.'hour', '', array_combine(range(0, 23), range(0, 23))),
174
        $form->createElement('select', $prefix.'minute', '', $minute)
175
    );
176
    return $group_name;
177
}
178
179
/**
180
 * @param string $path
181
 * @param int $courseId
182
 *
183
 * @return array
184
 */
185 View Code Duplication
function get_work_data_by_path($path, $courseId = null)
186
{
187
    $path = Database::escape_string($path);
188
    if (empty($courseId)) {
189
        $courseId = api_get_course_int_id();
190
    } else {
191
        $courseId = intval($courseId);
192
    }
193
194
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
195
    $sql = "SELECT *  FROM  ".$work_table."
196
            WHERE url = '$path' AND c_id = $courseId ";
197
    $result = Database::query($sql);
198
    $return = array();
199
    if (Database::num_rows($result)) {
200
        $return = Database::fetch_array($result, 'ASSOC');
201
    }
202
203
    return $return;
204
}
205
206
/**
207
 * @param int $id
208
 * @param int $courseId
209
 * @param int $sessionId
210
 * @return array
211
 */
212
function get_work_data_by_id($id, $courseId = null, $sessionId = null)
213
{
214
    $id = intval($id);
215
216
    if (!empty($courseId)) {
217
        $courseId = intval($courseId);
218
    } else {
219
        $courseId = api_get_course_int_id();
220
    }
221
222
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
223
224
    $sessionCondition = null;
225
    if (!empty($sessionId)) {
226
        $sessionCondition = api_get_session_condition($sessionId, true);
227
    }
228
229
    $sql = "SELECT * FROM $table
230
            WHERE
231
                id = $id AND c_id = $courseId
232
                $sessionCondition";
233
    $result = Database::query($sql);
234
    $work = array();
235
    if (Database::num_rows($result)) {
236
        $work = Database::fetch_array($result, 'ASSOC');
237
        if (empty($work['title'])) {
238
            $work['title'] = basename($work['url']);
239
        }
240
        $work['download_url'] = api_get_path(WEB_CODE_PATH).'work/download.php?id='.$work['id'].'&'.api_get_cidreq();
241
        $work['view_url'] = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&'.api_get_cidreq();
242
        $work['show_url'] = api_get_path(WEB_CODE_PATH).'work/show_file.php?id='.$work['id'].'&'.api_get_cidreq();
243
        $work['show_content'] = '';
244
        if ($work['contains_file']) {
245
            $fileInfo = pathinfo($work['title']);
246
            if (is_array($fileInfo) &&
247
                !empty($fileInfo['extension']) &&
248
                in_array($fileInfo['extension'], array('jpg', 'png', 'gif'))
249
            ) {
250
                $work['show_content'] = '<img src="'.$work['show_url'].'"/>';
251
            }
252
        }
253
    }
254
255
    return $work;
256
}
257
258
/**
259
 * @param int $user_id
260
 * @param int $work_id
261
 *
262
 * @return int
263
 */
264
function get_work_count_by_student($user_id, $work_id)
265
{
266
    $user_id = intval($user_id);
267
    $work_id = intval($work_id);
268
    $course_id = api_get_course_int_id();
269
    $session_id = api_get_session_id();
270
271
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
272
    $sql = "SELECT COUNT(*) as count
273
            FROM  $table
274
            WHERE
275
                c_id = $course_id AND
276
                parent_id = $work_id AND
277
                user_id = $user_id AND
278
                active IN (0, 1) AND
279
                session_id = $session_id ";
280
    $result = Database::query($sql);
281
    $return = 0;
282
    if (Database::num_rows($result)) {
283
        $return = Database::fetch_row($result, 'ASSOC');
284
        $return = intval($return[0]);
285
    }
286
287
    return $return;
288
}
289
290
/**
291
 * @param int $id
292
 * @param int $courseId
293
 *
294
 * @return array
295
 */
296 View Code Duplication
function get_work_assignment_by_id($id, $courseId = null)
297
{
298
    if (empty($courseId)) {
299
        $courseId = api_get_course_int_id();
300
    } else {
301
        $courseId = intval($courseId);
302
    }
303
    $id = intval($id);
304
305
    $table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
306
    $sql = "SELECT * FROM $table
307
            WHERE c_id = $courseId AND publication_id = $id";
308
    $result = Database::query($sql);
309
    $return = array();
310
    if (Database::num_rows($result)) {
311
        $return = Database::fetch_array($result, 'ASSOC');
312
    }
313
314
    return $return;
315
}
316
317
/**
318
 * @param int $id
319
 * @param array $my_folder_data
320
 * @param string $add_in_where_query
321
 *
322
 * @return array
323
 */
324
function getWorkList($id, $my_folder_data, $add_in_where_query = null)
325
{
326
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
327
328
    $course_id = api_get_course_int_id();
329
    $session_id = api_get_session_id();
330
    $condition_session = api_get_session_condition($session_id);
331
    $group_id = api_get_group_id();
332
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
333
334
    $linkInfo = GradebookUtils::is_resource_in_course_gradebook(
335
        api_get_course_id(),
336
        3,
337
        $id,
338
        api_get_session_id()
339
    );
340
341
    if ($linkInfo) {
342
        $workInGradeBookLinkId = $linkInfo['id'];
343
        if ($workInGradeBookLinkId) {
344
            if ($is_allowed_to_edit) {
345
                if (intval($my_folder_data['qualification']) == 0) {
346
                    Display::display_warning_message(
347
                        get_lang('MaxWeightNeedToBeProvided')
348
                    );
349
                }
350
            }
351
        }
352
    }
353
354
    $contains_file_query = '';
355
356
    // Get list from database
357
    if ($is_allowed_to_edit) {
358
        $active_condition = ' active IN (0, 1)';
359
        $sql = "SELECT * FROM $work_table
360
                WHERE
361
                    c_id = $course_id
362
                    $add_in_where_query
363
                    $condition_session AND
364
                    $active_condition AND
365
                    (parent_id = 0)
366
                    $contains_file_query AND
367
                    post_group_id = '".$group_id."'
368
                ORDER BY sent_date DESC";
369
    } else {
370 View Code Duplication
        if (!empty($group_id)) {
371
            // set to select only messages posted by the user's group
372
            $group_query = " WHERE c_id = $course_id AND post_group_id = '".$group_id."' ";
373
            $subdirs_query = "AND parent_id = 0";
374
        } else {
375
            $group_query = " WHERE c_id = $course_id AND  post_group_id = '0' ";
376
            $subdirs_query = "AND parent_id = 0";
377
        }
378
        //@todo how we can active or not an assignment?
379
        $active_condition = ' AND active IN (1, 0)';
380
        $sql = "SELECT * FROM  $work_table
381
                $group_query
382
                $subdirs_query
383
                $add_in_where_query
384
                $active_condition
385
                $condition_session
386
                ORDER BY title";
387
    }
388
389
    $work_parents = array();
390
391
    $sql_result = Database::query($sql);
392
    if (Database::num_rows($sql_result)) {
393
        while ($work = Database::fetch_object($sql_result)) {
394
            if ($work->parent_id == 0) {
395
                $work_parents[] = $work;
396
            }
397
        }
398
    }
399
400
    return $work_parents;
401
}
402
403
/**
404
 * @param int $userId
405
 * @return array
406
 */
407
function getWorkPerUser($userId)
408
{
409
    $works = getWorkList(null, null, null);
410
    $result = array();
411
    if (!empty($works)) {
412
        foreach ($works as $workData) {
413
            $workId = $workData->id;
414
            $result[$workId]['work'] = $workData;
415
            $result[$workId]['work']->user_results = get_work_user_list(
416
                0,
417
                100,
418
                null,
419
                null,
420
                $workId,
421
                null,
422
                $userId
423
            );
424
        }
425
    }
426
    return $result;
427
}
428
429
/**
430
 * @param int $workId
431
 * @param int $groupId
432
 * @param int $course_id
433
 * @param int $sessionId
434
 * @return mixed
435
 */
436
function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
437
{
438
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
439
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
440
    $course_id = intval($course_id);
441
    $workId = intval($workId);
442
    $sessionId = intval($sessionId);
443
    $groupId = intval($groupId);
444
445
    $sql = "SELECT count(DISTINCT u.user_id)
446
            FROM $work_table w
447
            INNER JOIN $user_table u
448
                ON w.user_id = u.user_id
449
            WHERE
450
                w.c_id = $course_id AND
451
                w.session_id = $sessionId AND
452
                w.parent_id = ".$workId." AND
453
                w.post_group_id = ".$groupId." AND
454
                w.active IN (0, 1)
455
            ";
456
457
    $res_document = Database::query($sql);
458
    $rowCount = Database::fetch_row($res_document);
459
460
    return $rowCount[0];
461
}
462
463
/**
464
 * @param mixed $workId
465
 * @param int $groupId
466
 * @param int $course_id
467
 * @param int $sessionId
468
 * @param int $userId user id to filter
469
 * @param array $onlyUserList only parse this user list
470
 * @return mixed
471
 */
472
function getUniqueStudentAttempts(
473
    $workId,
474
    $groupId,
475
    $course_id,
476
    $sessionId,
477
    $userId = null,
478
    $onlyUserList = array()
479
) {
480
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
481
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
482
483
    $course_id = intval($course_id);
484
    $workCondition = null;
485
    if (is_array($workId)) {
486
        $workId = array_map('intval', $workId);
487
        $workId = implode("','", $workId);
488
        $workCondition = " w.parent_id IN ('".$workId."') AND";
489
    } else {
490
        $workId = intval($workId);
491
        $workCondition = " w.parent_id = ".$workId." AND";
492
    }
493
494
    $sessionId = intval($sessionId);
495
    $groupId = intval($groupId);
496
497
    $studentCondition = null;
498
499 View Code Duplication
    if (!empty($onlyUserList)) {
500
        $onlyUserList = array_map('intval', $onlyUserList);
501
        $studentCondition = "AND u.user_id IN ('".implode("', '", $onlyUserList)."') ";
502
    } else {
503
        if (empty($userId)) {
504
            return 0;
505
        }
506
    }
507
508
    $sql = "SELECT count(*) FROM (
509
                SELECT count(*), w.parent_id
510
                FROM $work_table w
511
                INNER JOIN $user_table u
512
                    ON w.user_id = u.user_id
513
                WHERE
514
                    w.filetype = 'file' AND
515
                    w.c_id = $course_id AND
516
                    w.session_id = $sessionId AND
517
                    $workCondition
518
                    w.post_group_id = ".$groupId." AND
519
                    w.active IN (0, 1) $studentCondition
520
                ";
521
    if (!empty($userId)) {
522
        $userId = intval($userId);
523
        $sql .= " AND u.user_id = ".$userId;
524
    }
525
    $sql .= " GROUP BY u.user_id, w.parent_id) as t";
526
    $result = Database::query($sql);
527
    $row = Database::fetch_row($result);
528
529
    return $row[0];
530
}
531
532
/**
533
 * Shows the work list (student view)
534
 * @return string
535
 */
536
function showStudentWorkGrid()
537
{
538
    $courseInfo = api_get_course_info();
539
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student&'.api_get_cidreq();
540
541
    $columns = array(
542
        get_lang('Type'),
543
        get_lang('Title'),
544
        get_lang('HandOutDateLimit'),
545
        get_lang('Feedback'),
546
        get_lang('LastUpload')
547
    );
548
549
    $columnModel = array(
550
        array('name'=>'type', 'index'=>'type', 'width'=>'30',   'align'=>'center', 'sortable' => 'false'),
551
        array('name'=>'title', 'index'=>'title', 'width'=>'250',   'align'=>'left'),
552
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
553
        array('name'=>'feedback', 'index'=>'feedback', 'width'=>'80',  'align'=>'center'),
554
        array('name'=>'last_upload', 'index'=>'feedback', 'width'=>'125',  'align'=>'center'),
555
    );
556
557 View Code Duplication
    if ($courseInfo['show_score'] == 0) {
558
        $columnModel[] = array(
559
            'name' => 'others',
560
            'index' => 'others',
561
            'width' => '80',
562
            'align' => 'left',
563
            'sortable' => 'false'
564
        );
565
        $columns[] = get_lang('Others');
566
    }
567
568
    $params = array(
569
        'autowidth' => 'true',
570
        'height' => 'auto'
571
    );
572
573
    $html = '<script>
574
    $(function() {
575
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
576
    });
577
    </script>';
578
579
    $html .= Display::grid_html('workList');
580
    return $html;
581
}
582
583
/**
584
 * Shows the work list (teacher view)
585
 * @return string
586
 */
587
function showTeacherWorkGrid()
588
{
589
    $columnModel = array(
590
        array('name'=>'type', 'index'=>'type', 'width'=>'35', 'align'=>'center', 'sortable' => 'false'),
591
        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left', 'wrap_cell' => "true"),
592
        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'125',  'align'=>'center'),
593
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'125',  'align'=>'center'),
594
        array('name'=>'amount', 'index'=>'end_on', 'width'=>'110',  'align'=>'center'),
595
        array('name'=>'actions', 'index'=>'actions', 'width'=>'110', 'align'=>'left', 'sortable'=>'false')
596
    );
597
598
    $token = null;
599
600
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
601
    $deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
602
603
    $columns = array(
604
        get_lang('Type'),
605
        get_lang('Title'),
606
        get_lang('SentDate'),
607
        get_lang('HandOutDateLimit'),
608
        get_lang('AmountSubmitted'),
609
        get_lang('Actions')
610
    );
611
612
    $params = array(
613
        'multiselect' => true,
614
        'autowidth' => 'true',
615
        'height' => 'auto'
616
    );
617
618
    $html = '<script>
619
    $(function() {
620
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
621
        $("#workList").jqGrid(
622
            "navGrid",
623
            "#workList_pager",
624
            { edit: false, add: false, del: true },
625
            { height:280, reloadAfterSubmit:false }, // edit options
626
            { height:280, reloadAfterSubmit:false }, // add options
627
            { reloadAfterSubmit:false, url: "'.$deleteUrl.'" }, // del options
628
            { width:500 } // search options
629
        );
630
    });
631
    </script>';
632
    $html .= Display::grid_html('workList');
633
    return $html;
634
}
635
636
/**
637
 * Builds the form thats enables the user to
638
 * select a directory to browse/upload in
639
 * This function has been copied from the document/document.inc.php library
640
 *
641
 * @param array $folders
642
 * @param string $curdirpath
643
 * @param string $group_dir
644
 * @return string html form
645
 */
646
// TODO: This function is a candidate for removal, it is not used anywhere.
647
function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
648
{
649
    $form = '<form name="selector" action="'.api_get_self().'?'.api_get_cidreq().'" method="POST">';
650
    $form .= get_lang('CurrentDirectory').' <select name="curdirpath" onchange="javascript: document.selector.submit();">';
651
    //group documents cannot be uploaded in the root
652
    if ($group_dir == '') {
653
        $form .= '<option value="/">/ ('.get_lang('Root').')</option>';
654
        if (is_array($folders)) {
655
            foreach ($folders as $folder) {
656
                $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
657
                $form .= '<option'.$selected.' value="'.$folder.'">'.$folder.'</option>'."\n";
658
            }
659
        }
660
    } else {
661
        foreach ($folders as $folder) {
662
            $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
663
            $display_folder = substr($folder, strlen($group_dir));
664
            $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
665
            $form .= '<option'.$selected.' value="'.$folder.'">'.$display_folder.'</option>'."\n";
666
        }
667
    }
668
669
    $form .= '</select>';
670
    $form .= '<noscript><input type="submit" name="change_path" value="'.get_lang('Ok').'" /></noscript>';
671
    $form .= '</form>';
672
673
    return $form;
674
}
675
676
/**
677
 * Builds the form thats enables the user to
678
 * move a document from one directory to another
679
 * This function has been copied from the document/document.inc.php library
680
 *
681
 * @param array $folders
682
 * @param string $curdirpath
683
 * @param string $move_file
684
 * @param string $group_dir
685
 * @return string html form
686
 */
687
function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_dir = '')
688
{
689
    $course_id = api_get_course_int_id();
690
    $move_file = intval($move_file);
691
    $tbl_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
692
    $sql = "SELECT title, url FROM $tbl_work
693
            WHERE c_id = $course_id AND id ='".$move_file."'";
694
    $result = Database::query($sql);
695
    $row = Database::fetch_array($result, 'ASSOC');
696
    $title = empty($row['title']) ? basename($row['url']) : $row['title'];
697
698
    $form = new FormValidator(
699
        'move_to_form',
700
        'post',
701
        api_get_self().'?'.api_get_cidreq().'&curdirpath='.Security::remove_XSS($curdirpath)
702
    );
703
704
    $form->addHeader(get_lang('MoveFile').' - '.Security::remove_XSS($title));
705
    $form->addHidden('item_id', $move_file);
706
    $form->addHidden('action', 'move_to');
707
708
    //group documents cannot be uploaded in the root
709
    if ($group_dir == '') {
710
        if ($curdirpath != '/') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
711
            //$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
712
        }
713
        if (is_array($folders)) {
714
            foreach ($folders as $fid => $folder) {
715
                //you cannot move a file to:
716
                //1. current directory
717
                //2. inside the folder you want to move
718
                //3. inside a subfolder of the folder you want to move
719
                if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
720
                    //$form .= '<option value="'.$fid.'">'.$folder.'</option>';
721
                    $options[$fid] = $folder;
722
                }
723
            }
724
        }
725
    } else {
726
        if ($curdirpath != '/') {
727
            $form .= '<option value="0">/ ('.get_lang('Root').')</option>';
728
        }
729
        foreach ($folders as $fid => $folder) {
730
            if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
731
                //cannot copy dir into his own subdir
732
                $display_folder = substr($folder, strlen($group_dir));
733
                $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
734
                //$form .= '<option value="'.$fid.'">'.$display_folder.'</option>'."\n";
735
                $options[$fid] = $display_folder;
736
            }
737
        }
738
    }
739
740
    $form->addSelect('move_to_id', get_lang('Select'), $options);
741
    $form->addButtonSend(get_lang('MoveFile'), 'move_file_submit');
742
743
    return $form->returnForm();
744
}
745
746
/**
747
 * creates a new directory trying to find a directory name
748
 * that doesn't already exist
749
 * (we could use unique_name() here...)
750
 *
751
 * @author Hugues Peeters <[email protected]>
752
 * @author Bert Vanderkimpen
753
 * @author Yannick Warnier <[email protected]> Adaptation for work tool
754
 * @param   string $base_work_dir Base work dir (.../work)
755
 * @param   string $desiredDirName complete path of the desired name
0 ignored issues
show
Bug introduced by
There is no parameter named $desiredDirName. Was it maybe removed?

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

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

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

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

Loading history...
756
 *
757
 * @return  string actual directory name if it succeeds, boolean false otherwise
758
 */
759
function create_unexisting_work_directory($base_work_dir, $desired_dir_name)
760
{
761
    $nb = '';
762
    $base_work_dir = (substr($base_work_dir, -1, 1) == '/' ? $base_work_dir : $base_work_dir.'/');
763
    while (file_exists($base_work_dir.$desired_dir_name.$nb)) {
764
        $nb += 1;
765
    }
766
767
    if (@mkdir($base_work_dir.$desired_dir_name.$nb, api_get_permissions_for_new_directories())) {
768
        return $desired_dir_name.$nb;
769
    } else {
770
        return false;
771
    }
772
}
773
774
/**
775
 * Delete a work-tool directory
776
 * @param   int  $id work directory id to delete
777
 * @return  integer -1 on error
778
 */
779
function deleteDirWork($id)
780
{
781
    $locked = api_resource_is_locked_by_gradebook($id, LINK_STUDENTPUBLICATION);
782
783
    if ($locked == true) {
784
        Display::display_warning_message(get_lang('ResourceLockedByGradebook'));
785
        return false;
786
    }
787
788
    $_course = api_get_course_info();
789
    $id = intval($id);
790
    $work_data = get_work_data_by_id($id);
791
792
    if (empty($work_data)) {
793
        return false;
794
    }
795
796
    $base_work_dir = api_get_path(SYS_COURSE_PATH) .$_course['path'].'/work';
797
    $work_data_url = $base_work_dir.$work_data['url'];
798
    $check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
799
800
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
801
    $TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
802
    $t_agenda = Database::get_course_table(TABLE_AGENDA);
803
804
    $course_id = api_get_course_int_id();
805
806
    if (!empty($work_data['url'])) {
807
        if ($check) {
808
            // Deleting all contents inside the folder
809
            $sql = "UPDATE $table SET active = 2
810
                    WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
811
            Database::query($sql);
812
813
            $sql = "UPDATE $table SET active = 2
814
                    WHERE c_id = $course_id AND parent_id = $id";
815
            Database::query($sql);
816
817
            $new_dir = $work_data_url.'_DELETED_'.$id;
818
819 View Code Duplication
            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
820
                my_delete($work_data_url);
821
            } else {
822
                if (file_exists($work_data_url)) {
823
                    rename($work_data_url, $new_dir);
824
                }
825
            }
826
827
            // Gets calendar_id from student_publication_assigment
828
            $sql = "SELECT add_to_calendar FROM $TSTDPUBASG
829
                    WHERE c_id = $course_id AND publication_id = $id";
830
            $res = Database::query($sql);
831
            $calendar_id = Database::fetch_row($res);
832
833
            // delete from agenda if it exists
834
            if (!empty($calendar_id[0])) {
835
                $sql = "DELETE FROM $t_agenda
836
                        WHERE c_id = $course_id AND id = '".$calendar_id[0]."'";
837
                Database::query($sql);
838
            }
839
            $sql = "DELETE FROM $TSTDPUBASG
840
                    WHERE c_id = $course_id AND publication_id = $id";
841
            Database::query($sql);
842
843
            $link_info = GradebookUtils::is_resource_in_course_gradebook(
844
                api_get_course_id(),
845
                3,
846
                $id,
847
                api_get_session_id()
848
            );
849
            $link_id = $link_info['id'];
850
            if ($link_info !== false) {
851
                GradebookUtils::remove_resource_from_course_gradebook($link_id);
852
            }
853
            return true;
854
        }
855
    }
856
}
857
858
/**
859
 * Get the path of a document in the student_publication table (path relative to the course directory)
860
 * @param   integer $id
861
 * @return  string  Path (or -1 on error)
862
 */
863
function get_work_path($id)
864
{
865
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
866
    $course_id  = api_get_course_int_id();
867
    $sql = 'SELECT url FROM '.$table.'
868
            WHERE c_id = '.$course_id.' AND id='.intval($id);
869
    $res = Database::query($sql);
870
    if (Database::num_rows($res)) {
871
        $row = Database::fetch_array($res);
872
        return $row['url'];
873
    }
874
    return -1;
875
}
876
877
/**
878
 * Update the url of a work in the student_publication table
879
 * @param integer $id of the work to update
880
 * @param string  $new_path Destination directory where the work has been moved (must end with a '/')
881
 * @param int $parent_id
882
 *
883
 * @return  -1 on error, sql query result on success
0 ignored issues
show
Documentation introduced by
The doc-type -1 could not be parsed: Unknown type name "-1" at position 0. (view supported doc-types)

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

Loading history...
884
 */
885
function updateWorkUrl($id, $new_path, $parent_id)
886
{
887
    if (empty($id)) {
888
        return -1;
889
    }
890
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
891
    $course_id = api_get_course_int_id();
892
    $id = intval($id);
893
    $parent_id = intval($parent_id);
894
895
    $sql = "SELECT * FROM $table
896
            WHERE c_id = $course_id AND id = $id";
897
    $res = Database::query($sql);
898
    if (Database::num_rows($res) != 1) {
899
        return -1;
900
    } else {
901
        $row = Database::fetch_array($res);
902
        $filename = basename($row['url']);
903
        $new_url = $new_path.$filename;
904
        $new_url = Database::escape_string($new_url);
905
906
        $sql = "UPDATE $table SET
907
                   url = '$new_url',
908
                   parent_id = '$parent_id'
909
                WHERE c_id = $course_id AND id = $id";
910
        $res = Database::query($sql);
911
912
        return $res;
913
    }
914
}
915
916
/**
917
 * Update the url of a dir in the student_publication table
918
 * @param  array $work_data work original data
919
 * @param  string $newPath Example: "folder1"
920
 * @return bool
921
 */
922
function updateDirName($work_data, $newPath)
923
{
924
    $course_id = $work_data['c_id'];
925
    $sessionId = intval($work_data['session_id']);
926
    $work_id = intval($work_data['id']);
927
    $oldPath = $work_data['url'];
928
    $originalNewPath = Database::escape_string($newPath);
929
    $newPath = Database::escape_string($newPath);
930
    $newPath = api_replace_dangerous_char($newPath);
931
    $newPath = disable_dangerous_file($newPath);
932
933
    if ($oldPath == '/'.$newPath) {
934
        return true;
935
    }
936
937
    if (!empty($newPath)) {
938
        $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
939
        $sql = "UPDATE $table SET
940
                    title = '".$originalNewPath."'
941
                WHERE
942
                    c_id = $course_id AND
943
                    id = $work_id AND
944
                    session_id = $sessionId
945
                ";
946
        Database::query($sql);
947
    }
948
}
949
950
/**
951
 * Return an array with all the folder's ids that are in the given path
952
 * @param   string Path of the directory
953
 * @return  array The list of ids of all the directories in the path
954
 * @author  Julio Montoya Dokeos
955
 * @version April 2008
956
 */
957
958
function get_parent_directories($id)
959
{
960
    $course_id = api_get_course_int_id();
961
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
962
    $id = intval($id);
963
    $sql = "SELECT id FROM $work_table WHERE c_id = $course_id AND parent_id = $id";
964
    $result = Database::query($sql);
965
    $list_id = array();
966
    if (Database::num_rows($result)) {
967
        while ($row = Database::fetch_array($result)) {
968
            $list_id[] = $row['id'];
969
        }
970
    }
971
    return $list_id;
972
}
973
974
/**
975
 * Transform an all directory structure (only directories) in an array
976
 * @param   string path of the directory
977
 * @return  array the directory structure into an array
978
 * @author  Julio Montoya Dokeos
979
 * @version April 2008
980
 */
981 View Code Duplication
function directory_to_array($directory)
982
{
983
    $array_items = array();
984
    if ($handle = @opendir($directory)) {
985
        while (false !== ($file = readdir($handle))) {
986
            if ($file != '.' && $file != '..') {
987
                if (is_dir($directory. '/' . $file)) {
988
                    $array_items = array_merge($array_items, directory_to_array($directory. '/' . $file));
989
                    $file = $directory . '/' . $file;
990
                    $array_items[] = preg_replace("/\/\//si", '/', $file);
991
                }
992
            }
993
        }
994
        closedir($handle);
995
    }
996
    return $array_items;
997
}
998
999
/**
1000
 * Insert into the DB of the course all the directories
1001
 * @param   string path of the /work directory of the course
1002
 * @return  -1 on error, sql query result on success
1003
 * @author  Julio Montoya
0 ignored issues
show
Documentation introduced by
The doc-type -1 could not be parsed: Unknown type name "-1" at position 0. (view supported doc-types)

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

Loading history...
1004
 * @version April 2008
1005
 * @param string $base_work_dir
1006
 */
1007
1008
function insert_all_directory_in_course_table($base_work_dir)
1009
{
1010
    $dir_to_array = directory_to_array($base_work_dir, true);
1011
    $only_dir = array();
1012
1013
    for ($i = 0; $i < count($dir_to_array); $i++) {
1014
        $only_dir[] = substr($dir_to_array[$i], strlen($base_work_dir), strlen($dir_to_array[$i]));
1015
    }
1016
    $course_id = api_get_course_int_id();
1017
    $group_id  = api_get_group_id();
1018
1019
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
1020
1021
    for($i = 0; $i < count($only_dir); $i++) {
1022
        $url = $only_dir[$i];
1023
1024
        $params = [
1025
            'c_id' => $course_id,
1026
            'url' => $url,
1027
            'title' => '',
1028
            'description' => '',
1029
            'author' => '',
1030
            'active' => '1',
1031
            'accepted' => '1',
1032
            'filetype' => 'folder',
1033
            'post_group_id' => $group_id,
1034
        ];
1035
1036
        Database::insert($work_table, $params);
1037
    }
1038
}
1039
1040
/**
1041
 * This function displays the number of files contained in a directory
1042
 *
1043
 * @param   string the path of the directory
1044
 * @param   boolean true if we want the total quantity of files
1045
 * include in others child directories, false only  files in the directory
1046
 * @return  array the first element is an integer with the number of files
1047
 * in the folder, the second element is the number of directories
1048
 * @author  Julio Montoya
1049
 * @version April 2008
1050
 */
1051
function count_dir($path_dir, $recurse)
1052
{
1053
    $count = 0;
1054
    $count_dir = 0;
1055
    $d = dir($path_dir);
1056
    while ($entry = $d->Read()) {
1057
        if (!(($entry == '..') || ($entry == '.'))) {
1058
            if (is_dir($path_dir.'/'.$entry)) {
1059
                $count_dir++;
1060
                if ($recurse) {
1061
                    $count += count_dir($path_dir . '/' . $entry, $recurse);
1062
                }
1063
            } else {
1064
                $count++;
1065
            }
1066
        }
1067
    }
1068
    $return_array = array();
1069
    $return_array[] = $count;
1070
    $return_array[] = $count_dir;
1071
    return $return_array;
1072
}
1073
1074
/**
1075
 * returns all the javascript that is required for easily
1076
 * validation when you create a work
1077
 * this goes into the $htmlHeadXtra[] array
1078
 */
1079
function to_javascript_work()
1080
{
1081
    $js = '<script>
1082
        function updateDocumentTitle(value) {
1083
            var temp = value.indexOf("/");
1084
            //linux path
1085
            if(temp!=-1){
1086
                var temp=value.split("/");
1087
            } else {
1088
                var temp=value.split("\\\");
1089
            }
1090
            document.getElementById("file_upload").value=temp[temp.length-1];
1091
            $("#contains_file_id").attr("value", 1);
1092
        }
1093
1094
        function checkDate(month, day, year) {
1095
          var monthLength =
1096
            new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1097
1098
          if (!day || !month || !year)
1099
            return false;
1100
1101
          // check for bisestile year
1102
          if (year/4 == parseInt(year/4))
1103
            monthLength[1] = 29;
1104
1105
          if (month < 1 || month > 12)
1106
            return false;
1107
1108
          if (day > monthLength[month-1])
1109
            return false;
1110
1111
          return true;
1112
        }
1113
1114
        function mktime() {
1115
1116
            var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
1117
            d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
1118
1119
            var dateManip = {
1120
                0: function(tt){ return d.setHours(tt); },
1121
                1: function(tt){ return d.setMinutes(tt); },
1122
                2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
1123
                3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
1124
                4: function(tt){ return d.setDate(tt+mb); },
1125
                5: function(tt){ return d.setYear(tt+ma); }
1126
            };
1127
1128
            for( i = 0; i < argc; i++ ){
1129
                no = parseInt(argv[i]*1);
1130
                if (isNaN(no)) {
1131
                    return false;
1132
                } else {
1133
                    // arg is number, lets manipulate date object
1134
                    if(!dateManip[i](no)){
1135
                        // failed
1136
                        return false;
1137
                    }
1138
                }
1139
            }
1140
            return Math.floor(d.getTime()/1000);
1141
        }
1142
1143
        function setFocus() {
1144
            $("#work_title").focus();
1145
        }
1146
1147
        $(document).ready(function() {
1148
            setFocus();
1149
1150
            var checked = $("#expiry_date").attr("checked");
1151
            if (checked) {
1152
                $("#option2").show();
1153
                $("#option3").show();
1154
                $("#end_date").attr("checked", true);
1155
            } else {
1156
                $("#option2").hide();
1157
                $("#option3").hide();
1158
                $("#end_date").attr("checked", false);
1159
            }
1160
1161
            $("#expiry_date").click(function() {
1162
                $("#option2").toggle();
1163
            });
1164
1165
            $("#end_date").click(function() {
1166
                $("#option3").toggle();
1167
            });
1168
        });
1169
    </script>';
1170
1171
    return $js;
1172
}
1173
1174
/**
1175
 * Gets the id of a student publication with a given path
1176
 * @param string $path
1177
 * @return true if is found / false if not found
1178
 */
1179
// TODO: The name of this function does not fit with the kind of information it returns. Maybe check_work_id() or is_work_id()?
1180
function get_work_id($path)
1181
{
1182
    $TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1183
    $TBL_PROP_TABLE = Database::get_course_table(TABLE_ITEM_PROPERTY);
1184
    $course_id = api_get_course_int_id();
1185
    $path = Database::escape_string($path);
1186
1187
    if (api_is_allowed_to_edit()) {
1188
        $sql = "SELECT work.id
1189
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1190
                WHERE
1191
                    props.c_id = $course_id AND
1192
                    work.c_id = $course_id AND
1193
                    props.tool='work' AND
1194
                    work.id=props.ref AND
1195
                    work.url LIKE 'work/".$path."%' AND
1196
                    work.filetype='file' AND
1197
                    props.visibility<>'2'";
1198
    } else {
1199
        $sql = "SELECT work.id
1200
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1201
                WHERE
1202
                    props.c_id = $course_id AND
1203
                    work.c_id = $course_id AND
1204
                    props.tool='work' AND
1205
                    work.id=props.ref AND
1206
                    work.url LIKE 'work/".$path."%' AND
1207
                    work.filetype='file' AND
1208
                    props.visibility<>'2' AND
1209
                    props.lastedit_user_id = '".api_get_user_id()."'";
1210
    }
1211
    $result = Database::query($sql);
1212
    $num_rows = Database::num_rows($result);
1213
1214
    if ($result && $num_rows > 0) {
1215
        return true;
1216
    } else {
1217
        return false;
1218
    }
1219
}
1220
1221
/**
1222
 * @param int $work_id
1223
 * @param int $onlyMeUserId show only my works
1224
 * @param int $notMeUserId show works from everyone except me
1225
 * @return int
1226
 */
1227
function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
1228
{
1229
    $work_table      = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1230
    $iprop_table     = Database::get_course_table(TABLE_ITEM_PROPERTY);
1231
    $user_table      = Database::get_main_table(TABLE_MAIN_USER);
1232
1233
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
1234
    $session_id = api_get_session_id();
1235
    $condition_session = api_get_session_condition($session_id, true, false, 'work.session_id');
1236
1237
    $group_id = api_get_group_id();
1238
    $course_info = api_get_course_info();
1239
    $course_id = $course_info['real_id'];
1240
    $work_id = intval($work_id);
1241
1242 View Code Duplication
    if (!empty($group_id)) {
1243
        // set to select only messages posted by the user's group
1244
        $extra_conditions = " work.post_group_id = '".intval($group_id)."' ";
1245
    } else {
1246
        $extra_conditions = " work.post_group_id = '0' ";
1247
    }
1248
1249 View Code Duplication
    if ($is_allowed_to_edit) {
1250
        $extra_conditions .= ' AND work.active IN (0, 1) ';
1251
    } else {
1252
        $extra_conditions .= ' AND work.active IN (0, 1) AND accepted = 1';
1253
        if (isset($course_info['show_score']) && $course_info['show_score'] == 1) {
1254
            $extra_conditions .= " AND work.user_id = ".api_get_user_id()." ";
1255
        } else {
1256
            $extra_conditions .= '';
1257
        }
1258
    }
1259
1260
    $extra_conditions .= " AND parent_id  = ".$work_id."  ";
1261
1262
    $where_condition = null;
1263
1264
    if (!empty($notMeUserId)) {
1265
        $where_condition .= " AND u.user_id <> ".intval($notMeUserId);
1266
    }
1267
1268
    if (!empty($onlyMeUserId)) {
1269
        $where_condition .= " AND u.user_id =  ".intval($onlyMeUserId);
1270
    }
1271
1272
    $sql = "SELECT count(*) as count
1273
            FROM $iprop_table prop
1274
            INNER JOIN $work_table work
1275
            ON (
1276
                prop.ref = work.id AND
1277
                prop.c_id = $course_id AND
1278
                prop.tool='work' AND
1279
                prop.visibility <> 2 AND
1280
                work.c_id = $course_id
1281
            )
1282
            INNER JOIN $user_table u ON (work.user_id = u.user_id)
1283
            WHERE $extra_conditions $where_condition $condition_session";
1284
1285
    $result = Database::query($sql);
1286
1287
    $users_with_work = 0;
1288
    if (Database::num_rows($result)) {
1289
        $result = Database::fetch_array($result);
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1290
        $users_with_work = $result['count'];
1291
    }
1292
    return $users_with_work;
1293
}
1294
1295
/**
1296
 * @param int $start
1297
 * @param int $limit
1298
 * @param string $column
1299
 * @param string $direction
1300
 * @param string $where_condition
1301
 * @param bool $getCount
1302
 * @return array
1303
 */
1304
function getWorkListStudent(
1305
    $start,
1306
    $limit,
1307
    $column,
1308
    $direction,
1309
    $where_condition,
1310
    $getCount = false
1311
) {
1312
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1313
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1314
    $courseInfo = api_get_course_info();
1315
    $course_id = $courseInfo['real_id'];
1316
    $session_id = api_get_session_id();
1317
    $condition_session = api_get_session_condition($session_id);
1318
    $group_id = api_get_group_id();
1319
    $userId = api_get_user_id();
1320
1321
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1322
        api_get_user_id(),
1323
        $courseInfo
1324
    );
1325
1326
    if (!in_array($direction, array('asc','desc'))) {
1327
        $direction = 'desc';
1328
    }
1329
    if (!empty($where_condition)) {
1330
        $where_condition = ' AND ' . $where_condition;
1331
    }
1332
1333
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1334
    $start = intval($start);
1335
    $limit = intval($limit);
1336
1337
    // Get list from database
1338
1339 View Code Duplication
    if (!empty($group_id)) {
1340
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = '".$group_id."' ";
1341
        $subdirs_query = "AND parent_id = 0";
1342
    } else {
1343
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = '0' ";
1344
        $subdirs_query = "AND parent_id = 0";
1345
    }
1346
1347
    $active_condition = ' AND active IN (1, 0)';
1348
1349
    if ($getCount) {
1350
        $select = "SELECT count(w.id) as count ";
1351
    } else {
1352
        $select = "SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1353
    }
1354
1355
    $sql = "$select
1356
            FROM $workTable w
1357
            LEFT JOIN $workTableAssignment a
1358
            ON (a.publication_id = w.id AND a.c_id = w.c_id)
1359
                $group_query
1360
                $subdirs_query
1361
                $active_condition
1362
                $condition_session
1363
                $where_condition
1364
            ";
1365
1366
    $sql .= " ORDER BY $column $direction ";
1367
1368
    if (!empty($start) && !empty($limit)) {
1369
        $sql .= " LIMIT $start, $limit";
1370
    }
1371
1372
    $result = Database::query($sql);
1373
1374
    if ($getCount) {
1375
        $row = Database::fetch_array($result);
1376
        return $row['count'];
1377
    }
1378
1379
    $works = array();
1380
1381
    $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
1382
    if ($isDrhOfCourse) {
1383
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1384
    }
1385
1386
    $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
1387
    while ($work = Database::fetch_array($result, 'ASSOC')) {
1388
        $isSubscribed = userIsSubscribedToWork($userId, $work['id'], $course_id);
1389
        if ($isSubscribed == false) {
1390
            continue;
1391
        }
1392
1393
        $visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $session_id);
1394
1395
        if ($visibility != 1) {
1396
            continue;
1397
        }
1398
1399
        $work['type'] = Display::return_icon('work.png');
1400
        $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1401
1402
        if (empty($work['title'])) {
1403
            $work['title'] = basename($work['url']);
1404
        }
1405
1406
        $whereCondition = " AND u.user_id = ".intval($userId);
1407
1408
        $workList = get_work_user_list(
1409
            0,
1410
            1000,
1411
            null,
1412
            null,
1413
            $work['id'],
1414
            $whereCondition
1415
        );
1416
1417
        $count = getTotalWorkComment($workList, $courseInfo);
1418
1419 View Code Duplication
        if (!is_null($count) && !empty($count)) {
1420
            $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info');
1421
        }
1422
1423
        $lastWork = getLastWorkStudentFromParentByUser($userId, $work['id'], $courseInfo);
1424
1425
        if (!empty($lastWork)) {
1426
            $work['last_upload'] = Display::label($lastWork['qualification'], 'warning').' - ';
1427
            $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1428
        }
1429
1430
1431
        $work['title'] = Display::url($work['title'], $url.'&id='.$work['id']);
1432
        $work['others'] = Display::url(
1433
            Display::return_icon('group.png', get_lang('Others')),
1434
            $urlOthers.$work['id']
1435
        );
1436
        $works[] = $work;
1437
    }
1438
1439
    return $works;
1440
}
1441
1442
/**
1443
 * @param int $start
1444
 * @param int $limit
1445
 * @param string $column
1446
 * @param string $direction
1447
 * @param string $where_condition
1448
 * @param bool $getCount
1449
 * @return array
1450
 */
1451
function getWorkListTeacher(
1452
    $start,
1453
    $limit,
1454
    $column,
1455
    $direction,
1456
    $where_condition,
1457
    $getCount = false
1458
) {
1459
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1460
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1461
1462
    $courseInfo = api_get_course_info();
1463
    $course_id = api_get_course_int_id();
1464
    $session_id = api_get_session_id();
1465
    $condition_session = api_get_session_condition($session_id);
1466
    $group_id = api_get_group_id();
1467
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1468
1469
    if (!in_array($direction, array('asc', 'desc'))) {
1470
        $direction = 'desc';
1471
    }
1472
    if (!empty($where_condition)) {
1473
        $where_condition = ' AND ' . $where_condition;
1474
    }
1475
1476
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1477
    $start = intval($start);
1478
    $limit = intval($limit);
1479
    $works = array();
1480
1481
    // Get list from database
1482
    if ($is_allowed_to_edit) {
1483
        $active_condition = ' active IN (0, 1)';
1484
        if ($getCount) {
1485
            $select = " SELECT count(w.id) as count";
1486
        } else {
1487
            $select = " SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1488
        }
1489
        $sql = " $select
1490
                FROM $workTable w
1491
                LEFT JOIN $workTableAssignment a
1492
                ON (a.publication_id = w.id AND a.c_id = w.c_id)
1493
                WHERE
1494
                    w.c_id = $course_id
1495
                    $condition_session AND
1496
                    $active_condition AND
1497
                    (parent_id = 0) AND
1498
                    post_group_id = '".$group_id."'
1499
                    $where_condition
1500
                ORDER BY $column $direction
1501
                LIMIT $start, $limit";
1502
        $result = Database::query($sql);
1503
1504
        if ($getCount) {
1505
            $row = Database::fetch_array($result);
1506
1507
            return $row['count'];
1508
        }
1509
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1510
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1511
            $workId = $work['id'];
1512
            $work['type'] = Display::return_icon('work.png');
1513
            $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1514
1515
            $totalUsers = getStudentSubscribedToWork(
1516
                $workId,
1517
                $course_id,
1518
                $group_id,
1519
                $session_id,
1520
                true
1521
            );
1522
1523
            $countUniqueAttempts = getUniqueStudentAttemptsTotal(
1524
                $workId,
1525
                $group_id,
1526
                $course_id,
1527
                $session_id
1528
            );
1529
1530
            $work['amount'] = Display::label(
1531
                $countUniqueAttempts . '/' .
1532
                $totalUsers,
1533
                'success'
1534
            );
1535
1536
            $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1537
1538
            if ($visibility == 1) {
1539
                $icon = 'visible.png';
1540
                $text = get_lang('Visible');
1541
                $action = 'invisible';
1542
                $class = '';
1543
            } else {
1544
                $icon = 'invisible.png';
1545
                $text = get_lang('Invisible');
1546
                $action = 'visible';
1547
                $class = 'muted';
1548
            }
1549
1550
            $visibilityLink = Display::url(
1551
                Display::return_icon($icon, $text, array(), ICON_SIZE_SMALL),
1552
                api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action='.$action.'&'.api_get_cidreq()
1553
            );
1554
1555
            if (empty($work['title'])) {
1556
                $work['title'] = basename($work['url']);
1557
            }
1558
            $work['title'] = Display::url($work['title'], $url.'&id='.$workId, ['class' => $class]);
1559
            $work['title'] .= ' '.Display::label(get_count_work($work['id']), 'success');
1560
            $work['sent_date'] = api_get_local_time($work['sent_date']);
1561
1562
            $editLink = Display::url(
1563
                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL),
1564
                api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq()
1565
            );
1566
1567
            $correctionLink = Display::url(
1568
                Display::return_icon('upload_file.png', get_lang('UploadCorrections'), '', ICON_SIZE_SMALL),
1569
                api_get_path(WEB_CODE_PATH).'work/upload_corrections.php?'.api_get_cidreq().'&id='.$workId
1570
            );
1571
1572
            if ($countUniqueAttempts > 0) {
1573
                $downloadLink = Display::url(
1574
                    Display::return_icon(
1575
                        'save_pack.png',
1576
                        get_lang('Save'),
1577
                        array(),
1578
                        ICON_SIZE_SMALL
1579
                    ),
1580
                    api_get_path(WEB_CODE_PATH) . 'work/downloadfolder.inc.php?id=' . $workId . '&' . api_get_cidreq()
1581
                );
1582
            } else {
1583
                $downloadLink = Display::url(
1584
                    Display::return_icon(
1585
                        'save_pack_na.png',
1586
                        get_lang('Save'),
1587
                        array(),
1588
                        ICON_SIZE_SMALL
1589
                    ),
1590
                    '#'
1591
                );
1592
            }
1593
            // Remove Delete Work Button from action List
1594
            // Because removeXSS "removes" the onClick JS Event to do the action (See model.ajax.php - Line 1639)
1595
            // But still can use the another jqgrid button to remove works (trash icon)
1596
            //
1597
            // $deleteUrl = api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action=delete_dir&'.api_get_cidreq();
1598
            // $deleteLink = '<a href="#" onclick="showConfirmationPopup(this, \'' . $deleteUrl . '\' ) " >' .
1599
            //     Display::return_icon(
1600
            //         'delete.png',
1601
            //         get_lang('Delete'),
1602
            //         array(),
1603
            //         ICON_SIZE_SMALL
1604
            //     ) . '</a>';
1605
1606
            if (!api_is_allowed_to_edit()) {
1607
                // $deleteLink = null;
1608
                $editLink = null;
1609
            }
1610
            $work['actions'] = $visibilityLink.$correctionLink.$downloadLink.$editLink;
1611
            $works[] = $work;
1612
        }
1613
    }
1614
1615
    return $works;
1616
}
1617
1618
/**
1619
 * @param int $start
1620
 * @param int $limit
1621
 * @param string $column
1622
 * @param string $direction
1623
 * @param int $workId
1624
 * @param int $studentId
1625
 * @param string $whereCondition
1626
 * @param bool $getCount
1627
 * @return array
1628
 */
1629
function get_work_user_list_from_documents(
1630
    $start,
1631
    $limit,
1632
    $column,
1633
    $direction,
1634
    $workId,
1635
    $studentId = null,
1636
    $whereCondition,
1637
    $getCount = false
1638
) {
1639
    if ($getCount) {
1640
        $select1 = " SELECT count(u.user_id) as count ";
1641
        $select2 = " SELECT count(u.user_id) as count ";
1642
    } else {
1643
        $select1 = " SELECT DISTINCT u.firstname, u.lastname, u.user_id, w.title, w.parent_id, w.document_id document_id, w.id, qualification, qualificator_id";
1644
        $select2 = " SELECT DISTINCT u.firstname, u.lastname, u.user_id, d.title, w.parent_id, d.id document_id, 0, 0, 0";
1645
    }
1646
1647
    $documentTable = Database::get_course_table(TABLE_DOCUMENT);
1648
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1649
    $workRelDocument = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
1650
    $userTable = Database::get_main_table(TABLE_MAIN_USER);
1651
1652
    $courseId = api_get_course_int_id();
1653
    $sessionId = api_get_session_id();
1654
1655
    if (empty($studentId)) {
1656
        $studentId = api_get_user_id();
1657
    }
1658
    $studentId = intval($studentId);
1659
    $workId = intval($workId);
1660
1661
    $userCondition = " AND u.user_id = $studentId ";
1662
    $sessionCondition = " AND w.session_id = $sessionId ";
1663
    $workCondition = " AND w_rel.work_id = $workId";
1664
    $workParentCondition  = " AND w.parent_id = $workId";
1665
1666
    $sql = "(
1667
                $select1 FROM $userTable u
1668
                INNER JOIN $workTable w
1669
                ON (u.user_id = w.user_id AND w.active IN (0, 1) AND w.filetype = 'file')
1670
                WHERE
1671
                    w.c_id = $courseId
1672
                    $userCondition
1673
                    $sessionCondition
1674
                    $whereCondition
1675
                    $workParentCondition
1676
            ) UNION (
1677
                $select2 FROM $workTable w
1678
                INNER JOIN $workRelDocument w_rel
1679
                ON (w_rel.work_id = w.id AND w.active IN (0, 1) AND w_rel.c_id = w.c_id)
1680
                INNER JOIN $documentTable d
1681
                ON (w_rel.document_id = d.id AND d.c_id = w.c_id)
1682
                INNER JOIN $userTable u ON (u.user_id = $studentId)
1683
                WHERE
1684
                    w.c_id = $courseId
1685
                    $workCondition
1686
                    $sessionCondition AND
1687
                    d.id NOT IN (
1688
                        SELECT w.document_id id
1689
                        FROM $workTable w
1690
                        WHERE
1691
                            user_id = $studentId AND
1692
                            c_id = $courseId AND
1693
                            filetype = 'file' AND
1694
                            active IN (0, 1)
1695
                            $sessionCondition
1696
                            $workParentCondition
1697
                    )
1698
            )";
1699
1700
    $start = intval($start);
1701
    $limit = intval($limit);
1702
1703
    $direction = in_array(strtolower($direction), array('desc', 'asc')) ? $direction : 'desc';
1704
    $column = Database::escape_string($column);
1705
1706
    if ($getCount) {
1707
        $result = Database::query($sql);
1708
        $result = Database::fetch_array($result);
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1709
        return $result['count'];
1710
    }
1711
1712
    $sql .= " ORDER BY $column $direction";
1713
    $sql .= " LIMIT $start, $limit";
1714
1715
    $result = Database::query($sql);
1716
1717
    $currentUserId = api_get_user_id();
1718
    $work_data = get_work_data_by_id($workId);
1719
1720
    $qualificationExists = false;
1721
1722 View Code Duplication
    if (!empty($work_data['qualification']) && intval($work_data['qualification']) > 0) {
1723
        $qualificationExists = true;
1724
    }
1725
1726
    $urlAdd = api_get_path(WEB_CODE_PATH).'work/upload_from_template.php?'.api_get_cidreq();
1727
    $urlEdit = api_get_path(WEB_CODE_PATH).'work/edit.php?'.api_get_cidreq();
1728
    $urlDelete = api_get_path(WEB_CODE_PATH).'work/work_list.php?action=delete&'.api_get_cidreq();
1729
    $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq();
1730
1731
    $editIcon = Display::return_icon('edit.png', get_lang('Edit'));
1732
    $addIcon = Display::return_icon('add.png', get_lang('Add'));
1733
    $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'));
1734
    $viewIcon = Display::return_icon('default.png', get_lang('View'));
1735
    $allowEdition = api_get_course_setting('student_delete_own_publication');
1736
1737
    $workList = array();
1738
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1739
        $userId = $row['user_id'];
1740
        $documentId = $row['document_id'];
1741
        $itemId = $row['id'];
1742
        $addLinkShowed = false;
1743
1744
        if (empty($documentId)) {
1745
            $url = $urlEdit.'&item_id='.$row['id'].'&id='.$workId;
1746
            $editLink = Display::url($editIcon, $url);
1747
            if ($allowEdition == false) {
1748
                $editLink = null;
1749
            }
1750
        } else {
1751
            $documentToWork = getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId);
1752
1753
            if (empty($documentToWork)) {
1754
                $url = $urlAdd.'&document_id='.$documentId.'&id='.$workId;
1755
                $editLink = Display::url($addIcon, $url);
1756
                $addLinkShowed = true;
1757
            } else {
1758
1759
                $row['title'] = $documentToWork['title'];
1760
                $row['sent_date'] = $documentToWork['sent_date'];
1761
                $newWorkId = $documentToWork['id'];
1762
                $url = $urlEdit.'&item_id='.$newWorkId.'&id='.$workId;
1763
                $editLink = Display::url($editIcon, $url);
1764
1765
                if ($allowEdition == false) {
1766
                    $editLink = null;
1767
                }
1768
            }
1769
        }
1770
1771
        if ($allowEdition && !empty($itemId)) {
1772
            $deleteLink  = Display::url($deleteIcon, $urlDelete.'&item_id='.$itemId.'&id='.$workId);
1773
        } else {
1774
            $deleteLink = null;
1775
        }
1776
1777
        $viewLink = null;
1778
1779
        if (!empty($itemId)) {
1780
            $viewLink = Display::url($viewIcon, $urlView.'&id='.$itemId);
1781
        }
1782
1783
        //$row['type'] = build_document_icon_tag('file', $row['url']);
1784
        $row['type'] = null;
1785
1786
        if ($qualificationExists) {
1787 View Code Duplication
            if (empty($row['qualificator_id'])) {
1788
                $status = Display::label(get_lang('NotRevised'), 'warning');
1789
            } else {
1790
                $status = Display::label(get_lang('Revised'), 'success');
1791
            }
1792
            $row['qualificator_id'] = $status;
1793
        }
1794
1795
        if (!empty($row['qualification'])) {
1796
            $row['qualification'] = Display::label($row['qualification'], 'info');
1797
        }
1798
1799
        if (!empty($row['sent_date'])) {
1800
            $row['sent_date'] = api_get_local_time($row['sent_date']);
1801
        }
1802
1803
        if ($userId == $currentUserId) {
1804
            $row['actions'] = $viewLink.$editLink.$deleteLink;
1805
        }
1806
1807
        if ($addLinkShowed) {
1808
            $row['qualification'] = '';
1809
            $row['qualificator_id'] = '';
1810
        }
1811
1812
        $workList[] = $row;
1813
    }
1814
1815
    return $workList;
1816
}
1817
1818
/**
1819
 * @param int $start
1820
 * @param int $limit
1821
 * @param int $column
1822
 * @param string $direction
1823
 * @param int $work_id
1824
 * @param array $where_condition
1825
 * @param int $studentId
1826
 * @param bool $getCount
1827
 * @return array
1828
 */
1829
function get_work_user_list(
1830
    $start,
1831
    $limit,
1832
    $column,
1833
    $direction,
1834
    $work_id,
1835
    $where_condition = null,
1836
    $studentId = null,
1837
    $getCount = false
1838
) {
1839
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1840
    $iprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1841
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1842
1843
    $session_id = api_get_session_id();
1844
    $group_id = api_get_group_id();
1845
    $course_info = api_get_course_info();
1846
    $course_id = $course_info['real_id'];
1847
1848
    $work_id = intval($work_id);
1849
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1850
    $start = intval($start);
1851
    $limit = intval($limit);
1852
1853
    if (!in_array($direction, array('asc','desc'))) {
1854
        $direction = 'desc';
1855
    }
1856
1857
    $work_data = get_work_data_by_id($work_id);
1858
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1859
    $condition_session  = api_get_session_condition($session_id, true, false, 'work.session_id');
1860
    $locked = api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION);
1861
1862
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1863
        api_get_user_id(),
1864
        $course_info
1865
    );
1866
1867
    if (!empty($work_data)) {
1868 View Code Duplication
        if (!empty($group_id)) {
1869
            $extra_conditions = " work.post_group_id = '".intval($group_id)."' ";
1870
            // set to select only messages posted by the user's group
1871
        } else {
1872
            $extra_conditions = " work.post_group_id = '0' ";
1873
        }
1874
1875 View Code Duplication
        if ($is_allowed_to_edit || $isDrhOfCourse) {
1876
            $extra_conditions .= ' AND work.active IN (0, 1) ';
1877
        } else {
1878
            if (isset($course_info['show_score']) &&
1879
                $course_info['show_score'] == 1
1880
            ) {
1881
                $extra_conditions .= " AND (u.user_id = ".api_get_user_id()." AND work.active IN (0, 1)) ";
1882
            } else {
1883
                $extra_conditions .= ' AND work.active IN (0, 1) ';
1884
            }
1885
        }
1886
1887
        $extra_conditions .= " AND parent_id  = ".$work_id." ";
1888
1889
        $select = 'SELECT DISTINCT
1890
                        u.user_id,
1891
                        work.id as id,
1892
                        title as title,
1893
                        description,
1894
                        url,
1895
                        sent_date,
1896
                        contains_file,
1897
                        has_properties,
1898
                        view_properties,
1899
                        qualification,
1900
                        weight,
1901
                        allow_text_assignment,
1902
                        u.firstname,
1903
                        u.lastname,
1904
                        u.username,
1905
                        parent_id,
1906
                        accepted,
1907
                        qualificator_id,
1908
                        url_correction
1909
                        ';
1910
        if ($getCount) {
1911
            $select = "SELECT DISTINCT count(u.user_id) as count ";
1912
        }
1913
1914
        $user_condition = "INNER JOIN $user_table u  ON (work.user_id = u.user_id) ";
1915
        $work_condition = "$iprop_table prop INNER JOIN $work_table work
1916
                           ON (prop.ref = work.id AND prop.c_id = $course_id AND work.c_id = $course_id ) ";
1917
1918
        $work_assignment = get_work_assignment_by_id($work_id);
1919
1920
        if (!empty($studentId)) {
1921
            $where_condition.= " AND u.user_id = ".intval($studentId);
1922
        }
1923
1924
        $sql = " $select
1925
                FROM $work_condition  $user_condition
1926
                WHERE $extra_conditions $where_condition $condition_session
1927
                    AND u.status != " . INVITEE . "
1928
                ORDER BY $column $direction";
1929
1930
        if (!empty($start) && !empty($limit)) {
1931
            $sql .= " LIMIT $start, $limit";
1932
        }
1933
        $result = Database::query($sql);
1934
        $works = array();
1935
1936
        if ($getCount) {
1937
            $work = Database::fetch_array($result, 'ASSOC');
1938
            return $work['count'];
1939
        }
1940
1941
        $url = api_get_path(WEB_CODE_PATH).'work/';
1942
1943
        $unoconv = api_get_configuration_value('unoconv.binaries');
1944
1945
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1946
            $item_id = $work['id'];
1947
1948
            // Get the author ID for that document from the item_property table
1949
            $is_author  = false;
1950
            $can_read   = false;
1951
1952
            $owner_id = $work['user_id'];
1953
1954
            /* Because a bug found when saving items using the api_item_property_update()
1955
               the field $item_property_data['insert_user_id'] is not reliable. */
1956
1957
            if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
1958
                $is_author = true;
1959
            }
1960
1961
            if ($course_info['show_score'] == 0) {
1962
                $can_read = true;
1963
            }
1964
1965
            if ($work['accepted'] == '0') {
1966
                $class = 'invisible';
1967
            } else {
1968
                $class = '';
1969
            }
1970
1971
            $qualification_exists = false;
1972 View Code Duplication
            if (!empty($work_data['qualification']) &&
1973
                intval($work_data['qualification']) > 0
1974
            ) {
1975
                $qualification_exists = true;
1976
            }
1977
1978
            $qualification_string = '';
1979
            if ($qualification_exists) {
1980
                if ($work['qualification'] == '') {
1981
                    $qualification_string = Display::label('-');
1982
                } else {
1983
                    $label = 'info';
1984
                    $relativeScore = $work['qualification']/$work_data['qualification'];
1985
                    if ($relativeScore < 0.5) {
1986
                        $label = 'important';
1987
                    } elseif ($relativeScore < 0.75) {
1988
                        $label = 'warning';
1989
                    }
1990
                    $qualification_string = Display::label(
1991
                        $work['qualification'].' / '.$work_data['qualification'],
1992
                        $label
1993
                    );
1994
                }
1995
            }
1996
1997
            $work['qualification_score'] = $work['qualification'];
1998
1999
            $add_string = '';
2000
2001
            $time_expires = '';
2002
            if (!empty($work_assignment['expires_on'])) {
2003
                $time_expires = api_strtotime(
2004
                    $work_assignment['expires_on'],
2005
                    'UTC'
2006
                );
2007
            }
2008
2009
            if (!empty($work_assignment['expires_on']) &&
2010
                !empty($time_expires) && ($time_expires < api_strtotime($work['sent_date'], 'UTC'))) {
2011
                $add_string = Display::label(get_lang('Expired'), 'important');
2012
            }
2013
2014
            if (($can_read && $work['accepted'] == '1') ||
2015
                ($is_author && in_array($work['accepted'], array('1', '0'))) ||
2016
                ($is_allowed_to_edit || api_is_drh())
2017
            ) {
2018
                // Firstname, lastname, username
2019
                $work['firstname'] = Display::div($work['firstname'], array('class' => $class));
2020
                $work['lastname'] = Display::div($work['lastname'], array('class' => $class));
2021
2022
                $work['title_clean'] = $work['title'];
2023
2024
                if (strlen($work['title']) > 30) {
2025
                    $short_title = substr($work['title'], 0, 27).'...';
2026
                    $work['title'] = Display::span($short_title, array('class' => $class, 'title' => $work['title']));
2027
                } else {
2028
                    $work['title'] = Display::div($work['title'], array('class' => $class));
2029
                }
2030
2031
                // Type.
2032
                $work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
2033
2034
                // File name.
2035
                $link_to_download = null;
2036
2037
                // If URL is present then there's a file to download keep BC.
2038
                if ($work['contains_file'] || !empty($work['url'])) {
2039
                    $link_to_download = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.
2040
                        Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
2041
                }
2042
2043
                $send_to = Portfolio::share('work', $work['id'],  array('style' => 'white-space:nowrap;'));
2044
2045
                $feedback = null;
2046
                $count = getWorkCommentCount($item_id, $course_info);
2047
                if (!is_null($count) && !empty($count)) {
2048
                    if ($qualification_exists) {
2049
                        $feedback .= "<br />";
2050
                    }
2051
                    $feedback .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2052
                        Display::label($count.' '.get_lang('Feedback'), 'info').'</a> ';
2053
                }
2054
2055
                $work['qualification'] = $qualification_string.$feedback;
2056
                $work['qualification_only'] = $qualification_string;
2057
2058
                // Date.
2059
                $work_date = api_convert_and_format_date($work['sent_date']);
2060
2061
                $work['sent_date_from_db'] = $work['sent_date'];
2062
                $work['sent_date'] = '<div class="date-time">' . date_to_str_ago(api_get_local_time($work['sent_date'])) . ' ' . $add_string . ' ' . $work_date . '</div>';
2063
2064
                // Actions.
2065
                $correction = '';
2066
2067
                $action = '';
2068
                if (api_is_allowed_to_edit()) {
2069
                    if (!empty($work['url_correction'])) {
2070
                        $action .= Display::url(
2071
                            Display::return_icon('check-circle.png', get_lang('Correction'), null, ICON_SIZE_SMALL),
2072
                            api_get_path(WEB_CODE_PATH).'work/download.php?id='.$item_id.'&'.api_get_cidreq().'&correction=1'
2073
                        );
2074
                    }
2075
2076
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2077
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a> ';
2078
2079
                    if ($unoconv && empty($work['contains_file'])) {
2080
                        $action .=  '<a href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=export_to_doc&item_id='.$item_id.'" title="'.get_lang('ExportToDoc').'" >'.
2081
                            Display::return_icon('export_doc.png', get_lang('ExportToDoc'),array(), ICON_SIZE_SMALL).'</a> ';
2082
                    }
2083
2084
                    $correction = '
2085
                        <form
2086
                        id="file_upload_'.$item_id.'"
2087
                        class="work_correction_file_upload file_upload_small"
2088
                        action="'.api_get_path(WEB_AJAX_PATH).'work.ajax.php?'.api_get_cidreq().'&a=upload_correction_file&item_id='.$item_id.'" method="POST" enctype="multipart/form-data"
2089
                        >
2090
                        <div class="button-load">
2091
                            '.get_lang('ClickOrDropOneFileHere').'
2092
                        </div>
2093
                        <input type="file" name="file" multiple>
2094
                        <button type="submit"></button>
2095
                        </form>
2096
                    ';
2097
2098
                    $correction .= "
2099
                        <script>
2100
                        $(document).ready(function() {
2101
                            $('#file_upload_".$item_id."').fileupload({
2102
                                uploadTable: $('.files'),
2103
                                downloadTable: $('.files'),
2104
                                buildUploadRow: function (files, index) {
2105
                                    $('.files').show();
2106
                                    return
2107
                                        $('<tr><td>' + files[index].name + '<\/td>' +
2108
                                        '<td class=\"file_upload_progress\"><div><\/div><\/td>' +
2109
                                        '<td class=\"file_upload_cancel\">' +
2110
                                        '<button class=\"ui-state-default ui-corner-all\" title=\"".get_lang('Cancel')."\">' +
2111
                                        '<span class=\"ui-icon ui-icon-cancel\">".get_lang('Cancel')."<\/span>' +'<\/button>'+
2112
                                        '<\/td><\/tr>');
2113
                                },
2114
                                buildDownloadRow: function (file) {
2115
                                    return $('<tr><td>' + file.name + '<\/td> <td> ' + file.size + ' <\/td>  <td>&nbsp;' + file.result + ' <\/td> <\/tr>');
2116
                                }
2117
                            });
2118
                        });
2119
                        </script>
2120
                    ";
2121
2122
                    if ($locked) {
2123
                        if ($qualification_exists) {
2124
                            $action .= Display::return_icon('rate_work_na.png', get_lang('CorrectAndRate'),array(), ICON_SIZE_SMALL);
2125
                        } else {
2126
                            $action .= Display::return_icon('edit_na.png', get_lang('Comment'),array(), ICON_SIZE_SMALL);
2127
                        }
2128 View Code Duplication
                    } else {
2129
                        if ($qualification_exists) {
2130
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Edit').'"  >'.
2131
                                Display::return_icon('rate_work.png', get_lang('CorrectAndRate'), array(), ICON_SIZE_SMALL).'</a>';
2132
                        } else {
2133
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2134
                                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
2135
                        }
2136
                    }
2137
2138 View Code Duplication
                    if ($work['contains_file']) {
2139
                        if ($locked) {
2140
                            $action .= Display::return_icon('move_na.png', get_lang('Move'),array(), ICON_SIZE_SMALL);
2141
                        } else {
2142
                            $action .= '<a href="'.$url.'work.php?'.api_get_cidreq().'&action=move&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Move').'">'.
2143
                                Display::return_icon('move.png', get_lang('Move'),array(), ICON_SIZE_SMALL).'</a>';
2144
                        }
2145
                    }
2146
2147 View Code Duplication
                    if ($work['accepted'] == '1') {
2148
                        $action .= '<a href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=make_invisible&item_id='.$item_id.'" title="'.get_lang('Invisible').'" >'.
2149
                            Display::return_icon('visible.png', get_lang('Invisible'),array(), ICON_SIZE_SMALL).'</a>';
2150
                    } else {
2151
                        $action .= '<a href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=make_visible&item_id='.$item_id.'" title="'.get_lang('Visible').'" >'.
2152
                            Display::return_icon('invisible.png', get_lang('Visible'),array(), ICON_SIZE_SMALL).'</a> ';
2153
                    }
2154
2155
                    if ($locked) {
2156
                        $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2157
                    } else {
2158
                        $action .= '<a href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=delete&item_id='.$item_id.'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'" >'.
2159
                            Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2160
                    }
2161
                } elseif ($is_author && (empty($work['qualificator_id']) || $work['qualificator_id'] == 0)) {
2162
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2163
                        Display::return_icon('default.png', get_lang('View'),array(), ICON_SIZE_SMALL).'</a>';
2164
2165
                    if (api_get_course_setting('student_delete_own_publication') == 1) {
2166 View Code Duplication
                        if (api_is_allowed_to_session_edit(false, true)) {
2167
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2168
                                Display::return_icon('edit.png', get_lang('Comment'),array(), ICON_SIZE_SMALL).'</a>';
2169
                        }
2170
                        $action .= ' <a href="'.$url.'work_list.php?'.api_get_cidreq().'&action=delete&item_id='.$item_id.'&id='.$work['parent_id'].'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'"  >'.
2171
                            Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2172
                    } else {
2173
                        $action .= Display::return_icon('edit_na.png', get_lang('Modify'),array(), ICON_SIZE_SMALL);
2174
                    }
2175
                } else {
2176
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2177
                        Display::return_icon('default.png', get_lang('View'),array(), ICON_SIZE_SMALL).'</a>';
2178
                    $action .= Display::return_icon('edit_na.png', get_lang('Modify'),array(), ICON_SIZE_SMALL);
2179
                }
2180
2181
                // Status.
2182 View Code Duplication
                if (empty($work['qualificator_id'])) {
2183
                    $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
2184
                } else {
2185
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2186
                }
2187
                $work['qualificator_id'] = $qualificator_id;
2188
                $work['actions'] = $send_to.$link_to_download.$action;
2189
                $work['correction'] = $correction;
2190
2191
                $works[] = $work;
2192
            }
2193
        }
2194
2195
        return $works;
2196
    }
2197
}
2198
2199
/**
2200
 * Send reminder to users who have not given the task
2201
 *
2202
 * @param int
2203
 * @return array
2204
 * @author cvargas [email protected] cfasanando, [email protected]
2205
 */
2206
function send_reminder_users_without_publication($task_data)
2207
{
2208
    $_course = api_get_course_info();
2209
    $task_id = $task_data['id'];
2210
    $task_title = !empty($task_data['title']) ? $task_data['title'] : basename($task_data['url']);
2211
    $subject = '[' . api_get_setting('siteName') . '] ';
2212
2213
    // The body can be as long as you wish, and any combination of text and variables
2214
    $content = get_lang('ReminderToSubmitPendingTask')."\n".get_lang('CourseName').' : '.$_course['name']."\n";
2215
    $content .= get_lang('WorkName').' : '.$task_title."\n";
2216
2217
    $list_users = get_list_users_without_publication($task_id);
2218
2219
    $mails_sent_to = array();
2220
    foreach ($list_users as $user) {
2221
        $name_user = api_get_person_name($user[1], $user[0], null, PERSON_NAME_EMAIL_ADDRESS);
2222
        $dear_line = get_lang('Dear')." ".api_get_person_name($user[1], $user[0]) .", \n\n";
2223
        $body      = $dear_line.$content;
2224
        MessageManager::send_message($user[3], $subject, $body);
2225
        $mails_sent_to[] = $name_user;
2226
    }
2227
    return $mails_sent_to;
2228
}
2229
2230
/**
2231
 * Sends an email to the students of a course when a homework is created
2232
 *
2233
 * @param int $courseId course_id
2234
 * @param int $sessionId session_id
2235
 * @param int $workId work_id
2236
 *
2237
 *
2238
 * @author Guillaume Viguier <[email protected]>
2239
 * @author Julio Montoya <[email protected]> Adding session support - 2011
2240
 */
2241
function send_email_on_homework_creation($courseId, $sessionId = 0, $workId)
2242
{
2243
    $courseInfo = api_get_course_info_by_id($courseId);
2244
    $courseCode = $courseInfo['code'];
2245
    // Get the students of the course
2246 View Code Duplication
    if (empty($session_id)) {
0 ignored issues
show
Bug introduced by
The variable $session_id 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...
2247
        $students = CourseManager::get_student_list_from_course_code($courseCode);
2248
    } else {
2249
        $students = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionId);
2250
    }
2251
    $emailsubject = '[' . api_get_setting('siteName') . '] '.get_lang('HomeworkCreated');
2252
    $currentUser = api_get_user_info(api_get_user_id());
2253
    if (!empty($students)) {
2254
        foreach($students as $student) {
2255
            $user_info = api_get_user_info($student["user_id"]);
2256
            if(!empty($user_info["mail"])) {
2257
                $name_user = api_get_person_name(
2258
                    $user_info["firstname"],
2259
                    $user_info["lastname"],
2260
                    null,
2261
                    PERSON_NAME_EMAIL_ADDRESS
2262
                );
2263
                $link = api_get_path(WEB_CODE_PATH) . 'work/work_list_all.php?' . api_get_cidreq() . '&id=' . $workId;
2264
                $emailbody = get_lang('Dear')." ".$name_user.",\n\n";
2265
                $emailbody .= get_lang('HomeworkHasBeenCreatedForTheCourse')." ".$courseCode.". "."\n\n".
2266
                    '<a href="'. $link . '">' . get_lang('PleaseCheckHomeworkPage') . '</a>';
2267
                $emailbody .= "\n\n".api_get_person_name($currentUser["firstname"], $currentUser["lastname"]);
2268
2269
                $additionalParameters = array(
2270
                    'smsType' => SmsPlugin::ASSIGNMENT_BEEN_CREATED_COURSE,
2271
                    'userId' => $student["user_id"],
2272
                    'courseTitle' => $courseCode,
2273
                    'link' => $link
2274
                );
2275
2276
                api_mail_html(
2277
                    $name_user,
2278
                    $user_info["mail"],
2279
                    $emailsubject,
2280
                    $emailbody,
2281
                    api_get_person_name(
2282
                        $currentUser["firstname"],
2283
                        $currentUser["lastname"],
2284
                        null,
2285
                        PERSON_NAME_EMAIL_ADDRESS
2286
                    ),
2287
                    $currentUser["mail"],
2288
                    null,
2289
                    null,
2290
                    null,
2291
                    $additionalParameters
2292
                );
2293
            }
2294
        }
2295
    }
2296
}
2297
2298
/**
2299
 * @param string $url
2300
 * @return bool
2301
 */
2302
function is_work_exist_by_url($url)
2303
{
2304
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2305
    $url = Database::escape_string($url);
2306
    $sql = "SELECT id FROM $work_table WHERE url='$url'";
2307
    $result = Database::query($sql);
2308
    if (Database::num_rows($result)> 0) {
2309
        $row = Database::fetch_row($result);
2310
        if (empty($row)) {
2311
            return false;
2312
        } else {
2313
            return true;
2314
        }
2315
    } else {
2316
        return false;
2317
    }
2318
}
2319
2320
/**
2321
 * @param $name
2322
 * @param $values
2323
 * @param string $checked
2324
 * @return string
2325
 */
2326 View Code Duplication
function make_select($name, $values, $checked = '')
2327
{
2328
    $output = '<select name="'.$name.'" id="'.$name.'">';
2329
    foreach ($values as $key => $value) {
2330
        $output .= '<option value="'.$key.'" '.(($checked==$key) ? 'selected="selected"' : '').'>'.$value.'</option>';
2331
    }
2332
    $output .= '</select>';
2333
    return $output;
2334
}
2335
2336
/**
2337
 * @param $name
2338
 * @param string $checked
2339
 * @param null $label
2340
 * @return string
2341
 */
2342
function make_checkbox($name, $checked = '', $label = null)
2343
{
2344
    $check = '<input id ="'.$name.'" type="checkbox" value="1" name="'.$name.'" '.((!empty($checked))?'checked="checked"':'').'/>';
2345
    if (!empty($label)) {
2346
        $check .="<label for ='$name'>$label</label>";
2347
    }
2348
    return $check;
2349
}
2350
2351
/**
2352
 * @param $prefix
2353
 * @param string $default
2354
 * @return string
2355
 */
2356
function draw_date_picker($prefix, $default = '')
2357
{
2358
    if (empty($default)) {
2359
        $default = api_get_local_time();
2360
    }
2361
    $parts = explode(' ', $default);
2362
    list($d_year, $d_month, $d_day) = explode('-', $parts[0]);
2363
    list($d_hour, $d_minute) = explode(':', $parts[1]);
2364
2365
    $minute = range(10, 59);
2366
    array_unshift($minute, '00', '01', '02', '03', '04', '05', '06', '07', '08', '09');
2367
    $date_form = make_select($prefix.'_day', array_combine(range(1, 31), range(1, 31)), $d_day);
2368
    $date_form .= make_select($prefix.'_month', array_combine(range(1, 12), api_get_months_long()), $d_month);
2369
    $date_form .= make_select($prefix.'_year', array($d_year => $d_year, $d_year + 1 => $d_year + 1), $d_year).'&nbsp;&nbsp;&nbsp;&nbsp;';
2370
    $date_form .= make_select($prefix.'_hour', array_combine(range(0, 23), range(0, 23)), $d_hour).' : ';
2371
    $date_form .= make_select($prefix.'_minute', $minute, $d_minute);
2372
    return $date_form;
2373
}
2374
2375
/**
2376
 * @param string $prefix
2377
 * @param array of values
2378
 * @return string
2379
 *
2380
 */
2381 View Code Duplication
function get_date_from_select($prefix, $array = array())
2382
{
2383
    return
2384
        $array[$prefix]['year'].'-'.
2385
        two_digits($array[$prefix]['month']).'-'.
2386
        two_digits($array[$prefix]['day']).' '.
2387
        two_digits($array[$prefix]['hour']).':'.
2388
        two_digits($array[$prefix]['minute']).':00';
2389
}
2390
2391
/**
2392
 * Check if a user is the author of a work document.
2393
 * @param int $itemId
2394
 * @param int $userId
2395
 * @param int $courseId
2396
 * @param int $sessionId
2397
 * @return bool
2398
 */
2399
function user_is_author($itemId, $userId = null, $courseId = null, $sessionId = null)
2400
{
2401
    if (empty($itemId)) {
2402
        return false;
2403
    }
2404
2405
    if (empty($userId)) {
2406
        $userId = api_get_user_id();
2407
    }
2408
2409
    $isAuthor = false;
2410
    $is_allowed_to_edit = api_is_allowed_to_edit();
2411
2412
    if ($is_allowed_to_edit) {
2413
        $isAuthor = true;
2414
    } else {
2415
2416
        if (empty($courseId)) {
2417
            $courseId = api_get_course_int_id();
2418
        }
2419
        if (empty($sessionId)) {
2420
            $sessionId = api_get_session_id();
2421
        }
2422
2423
        $data = api_get_item_property_info($courseId, 'work', $itemId, $sessionId);
2424
        if ($data['insert_user_id'] == $userId) {
2425
            $isAuthor = true;
2426
        }
2427
2428
        $workData = get_work_data_by_id($itemId);
2429
        if ($workData['user_id'] == $userId) {
2430
            $isAuthor = true;
2431
        }
2432
    }
2433
2434
    if (!$isAuthor) {
2435
        return false;
2436
    }
2437
2438
    return $isAuthor;
2439
}
2440
2441
/**
2442
 * Get list of users who have not given the task
2443
 * @param int
2444
 * @param int
2445
 * @return array
2446
 * @author cvargas
2447
 * @author Julio Montoya <[email protected]> Fixing query
2448
 */
2449
function get_list_users_without_publication($task_id, $studentId = null)
2450
{
2451
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2452
    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2453
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
2454
    $session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2455
2456
    $users = getAllUserToWork($task_id, api_get_course_int_id());
2457
    $users = array_column($users, 'user_id');
2458
2459
    // Condition for the session
2460
    $session_id = api_get_session_id();
2461
    $course_id = api_get_course_int_id();
2462
    $task_id = intval($task_id);
2463
2464
    if ($session_id == 0) {
2465
        $sql = "SELECT user_id as id FROM $work_table
2466
                WHERE
2467
                    c_id = $course_id AND
2468
                    parent_id = '$task_id' AND
2469
                    active IN (0, 1)";
2470
    } else {
2471
        $sql = "SELECT user_id as id FROM $work_table
2472
                WHERE
2473
                    c_id = $course_id AND
2474
                    parent_id = '$task_id' AND
2475
                    session_id = '".$session_id."' AND
2476
                    active IN (0, 1)";
2477
    }
2478
2479
    $result = Database::query($sql);
2480
    $users_with_tasks = array();
2481
    while ($row = Database::fetch_array($result)) {
2482
        $users_with_tasks[] = $row['id'];
2483
    }
2484
2485
    if ($session_id == 0) {
2486
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2487
                      FROM $table_course_user AS cu, $table_user AS u
2488
                      WHERE u.status != 1 and cu.c_id='".$course_id."' AND u.user_id = cu.user_id";
2489
    } else {
2490
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2491
                      FROM $session_course_rel_user AS cu, $table_user AS u
2492
                      WHERE
2493
                        u.status != 1 AND
2494
                        cu.c_id='".$course_id."' AND
2495
                        u.user_id = cu.user_id AND
2496
                        cu.session_id = '".$session_id."'";
2497
    }
2498
2499
    if (!empty($studentId)) {
2500
        $sql_users.= " AND u.user_id = ".intval($studentId);
2501
    }
2502
2503
    $group_id = api_get_group_id();
2504
2505
    $new_group_user_list = array();
2506
2507
    if ($group_id) {
2508
        $group_user_list = GroupManager::get_subscribed_users($group_id);
2509
        if (!empty($group_user_list)) {
2510
            foreach($group_user_list as $group_user) {
2511
                $new_group_user_list[] = $group_user['user_id'];
2512
            }
2513
        }
2514
    }
2515
2516
    $result_users = Database::query($sql_users);
2517
    $users_without_tasks = array();
2518
    while ($rowUsers = Database::fetch_array($result_users)) {
2519
        $userId = $rowUsers['user_id'];
2520
        if (in_array($userId, $users_with_tasks)) {
2521
            continue;
2522
        }
2523
2524
        if ($group_id && !in_array($userId, $new_group_user_list)) {
2525
            continue;
2526
        }
2527
2528
        if (!empty($users)) {
2529
            if (!in_array($userId, $users)) {
2530
                continue;
2531
            }
2532
        }
2533
2534
        $row_users = [];
2535
        $row_users[0] = $rowUsers['lastname'];
2536
        $row_users[1] = $rowUsers['firstname'];
2537
        $row_users[2] = Display::encrypted_mailto_link($rowUsers['email']);
2538
        $row_users[3] = $userId;
2539
        $users_without_tasks[] = $row_users;
2540
    }
2541
2542
    return $users_without_tasks;
2543
}
2544
2545
/**
2546
 * Display list of users who have not given the task
2547
 *
2548
 * @param int task id
2549
 * @param int $studentId
2550
 * @return array
2551
 * @author cvargas [email protected] cfasanando, [email protected]
2552
 * @author Julio Montoya <[email protected]> Fixes
2553
 */
2554
function display_list_users_without_publication($task_id, $studentId = null)
2555
{
2556
    global $origin;
2557
    $table_header[] = array(get_lang('LastName'), true);
2558
    $table_header[] = array(get_lang('FirstName'), true);
2559
    $table_header[] = array(get_lang('Email'), true);
2560
2561
    $data = get_list_users_without_publication($task_id);
2562
2563
    $sorting_options = array();
2564
    $sorting_options['column'] = 1;
2565
    $paging_options = array();
2566
    $my_params = array();
2567
2568
    if (isset($_GET['edit_dir'])) {
2569
        $my_params['edit_dir'] = Security::remove_XSS($_GET['edit_dir']);
2570
    }
2571
    if (isset($_GET['list'])) {
2572
        $my_params['list'] = Security::remove_XSS($_GET['list']);
2573
    }
2574
    $my_params['origin'] = $origin;
2575
    $my_params['id'] = intval($_GET['id']);
2576
2577
    //$column_show
2578
    $column_show[] = 1;
2579
    $column_show[] = 1;
2580
    $column_show[] = 1;
2581
    Display::display_sortable_config_table(
2582
        'work',
2583
        $table_header,
2584
        $data,
2585
        $sorting_options,
2586
        $paging_options,
2587
        $my_params,
2588
        $column_show
2589
    );
2590
}
2591
2592
/**
2593
 * @param int $documentId
2594
 * @param int $workId
2595
 * @param int $courseId
2596
 */
2597 View Code Duplication
function addDocumentToWork($documentId, $workId, $courseId)
2598
{
2599
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2600
    $params = array(
2601
        'document_id' => $documentId,
2602
        'work_id' => $workId,
2603
        'c_id' => $courseId
2604
    );
2605
    Database::insert($table, $params);
2606
}
2607
2608
/**
2609
 * @param int $documentId
2610
 * @param int $workId
2611
 * @param int $courseId
2612
 * @return array
2613
 */
2614 View Code Duplication
function getDocumentToWork($documentId, $workId, $courseId)
2615
{
2616
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2617
    $params = array(
2618
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2619
    );
2620
    return Database::select('*', $table, array('where' => $params));
2621
}
2622
2623
/**
2624
 * @param int $documentId
2625
 * @param int $workId
2626
 * @param int $courseId
2627
 * @param int $sessionId
2628
 * @param int $userId
2629
 * @param int $active
2630
 * @return array
2631
 */
2632
function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId, $active = 1)
2633
{
2634
    $workRel = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2635
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2636
2637
    $documentId = intval($documentId);
2638
    $workId = intval($workId);
2639
    $courseId = intval($courseId);
2640
    $userId = intval($userId);
2641
    $sessionId = intval($sessionId);
2642
    $active = intval($active);
2643
2644
    $sql = "SELECT w.* FROM $work w INNER JOIN $workRel rel ON (w.parent_id = rel.work_id)
2645
            WHERE
2646
                w.document_id = $documentId AND
2647
                w.parent_id = $workId AND
2648
                w.c_id = $courseId AND
2649
                w.session_id = $sessionId AND
2650
                user_id = $userId AND
2651
                active = $active
2652
            ";
2653
2654
    $result = Database::query($sql);
2655
    $workInfo = array();
2656
    if (Database::num_rows($result)) {
2657
        $workInfo = Database::fetch_array($result, 'ASSOC');
2658
    }
2659
    return $workInfo;
2660
}
2661
2662
/**
2663
 *
2664
 * @param int $workId
2665
 * @param int $courseId
2666
 * @return array
2667
 */
2668 View Code Duplication
function getAllDocumentToWork($workId, $courseId)
2669
{
2670
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2671
    $params = array(
2672
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2673
    );
2674
    return Database::select('*', $table, array('where' => $params));
2675
}
2676
2677
/**
2678
 * @param int $documentId
2679
 * @param int $workId
2680
 * @param int $courseId
2681
 */
2682 View Code Duplication
function deleteDocumentToWork($documentId, $workId, $courseId)
2683
{
2684
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2685
    $params = array(
2686
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2687
    );
2688
    Database::delete($table, $params);
2689
}
2690
2691
/**
2692
 * @param int $userId
2693
 * @param int $workId
2694
 * @param int $courseId
2695
 */
2696 View Code Duplication
function addUserToWork($userId, $workId, $courseId)
2697
{
2698
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2699
    $params = array(
2700
        'user_id' => $userId,
2701
        'work_id' => $workId,
2702
        'c_id' => $courseId
2703
    );
2704
    Database::insert($table, $params);
2705
}
2706
2707
/**
2708
 * @param int $userId
2709
 * @param int $workId
2710
 * @param int $courseId
2711
 * @return array
2712
 */
2713 View Code Duplication
function getUserToWork($userId, $workId, $courseId)
2714
{
2715
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2716
    $params = array(
2717
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2718
    );
2719
    return Database::select('*', $table, array('where' => $params));
2720
}
2721
2722
/**
2723
 * @param int $workId
2724
 * @param int $courseId
2725
 * @param bool $getCount
2726
 * @return array
2727
 */
2728
function getAllUserToWork($workId, $courseId, $getCount = false)
2729
{
2730
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2731
    $params = array(
2732
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2733
    );
2734
    if ($getCount) {
2735
        $count = 0;
2736
        $result = Database::select(
2737
            'count(user_id) as count',
2738
            $table,
2739
            array('where' => $params),
2740
            'simple'
2741
        );
2742
        if (!empty($result)) {
2743
            $count = intval($result['count']);
2744
        }
2745
        return $count;
2746
    } else {
2747
        return Database::select('*', $table, array('where' => $params));
2748
    }
2749
}
2750
2751
/**
2752
 * @param int $userId
2753
 * @param int $workId
2754
 * @param int $courseId
2755
 */
2756 View Code Duplication
function deleteUserToWork($userId, $workId, $courseId)
2757
{
2758
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2759
    $params = array(
2760
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2761
    );
2762
    Database::delete($table, $params);
2763
}
2764
2765
/**
2766
 * @param int $userId
2767
 * @param int $workId
2768
 * @param int $courseId
2769
 * @return bool
2770
 */
2771
function userIsSubscribedToWork($userId, $workId, $courseId)
2772
{
2773
    $subscribedUsers = getAllUserToWork($workId, $courseId);
2774
2775
    if (empty($subscribedUsers)) {
2776
        return true;
2777
    } else {
2778
        $subscribedUsersList = array();
2779
        foreach ($subscribedUsers as $item) {
2780
            $subscribedUsersList[] = $item['user_id'];
2781
        }
2782
        if (in_array($userId, $subscribedUsersList)) {
2783
            return true;
2784
        }
2785
    }
2786
    return false;
2787
}
2788
2789
/**
2790
 * Get the list of students that have to submit their work
2791
 * @param integer $workId The internal ID of the assignment
2792
 * @param integer $courseId The course ID
2793
 * @param integer $groupId The group ID, if any
2794
 * @param integer $sessionId The session ID, if any
2795
 * @param bool $getCount Whether we want just the amount or the full result
2796
 * @return array|int An integer (if we just asked for the count) or an array of users
2797
 */
2798
function getStudentSubscribedToWork(
2799
    $workId,
2800
    $courseId,
2801
    $groupId = null,
2802
    $sessionId = null,
2803
    $getCount = false
2804
) {
2805
    $usersInWork = null;
2806
    $usersInCourse = null;
2807
2808
    if (empty($groupId)) {
2809
        $courseInfo = api_get_course_info_by_id($courseId);
2810
        $status = STUDENT;
2811
        if (!empty($sessionId)) {
2812
            $status = 0;
2813
        }
2814
        $usersInCourse = CourseManager::get_user_list_from_course_code(
2815
            $courseInfo['code'],
2816
            $sessionId,
2817
            null,
2818
            null,
2819
            $status,
2820
            $getCount
2821
        );
2822
    } else {
2823
        $usersInCourse = GroupManager::get_users(
2824
            $groupId,
2825
            false,
2826
            null,
2827
            null,
2828
            $getCount,
2829
            $courseId
2830
        );
2831
    }
2832
2833
    $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
2834
2835
    if (empty($usersInWork)) {
2836
        return $usersInCourse;
2837
    } else {
2838
        return $usersInWork;
2839
    }
2840
2841
}
2842
2843
/**
2844
 * @param int $userId
2845
 * @param int $workId
2846
 * @param int $courseId
2847
 * @return bool
2848
 */
2849
function allowOnlySubscribedUser($userId, $workId, $courseId)
2850
{
2851
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2852
        return true;
2853
    }
2854
2855
    if (userIsSubscribedToWork($userId, $workId, $courseId) == false) {
2856
        api_not_allowed(true);
2857
    }
2858
}
2859
2860
/**
2861
 * @param int $workId
2862
 * @param array $courseInfo
2863
 * @param int $documentId
2864
 * @return array
2865
 */
2866
function getDocumentTemplateFromWork($workId, $courseInfo, $documentId)
2867
{
2868
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2869
    if (!empty($documents)) {
2870
        foreach ($documents as $doc) {
2871
            if ($documentId != $doc['document_id']) {
2872
                continue;
2873
            }
2874
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2875
            $fileInfo = pathinfo($docData['path']);
2876
            if ($fileInfo['extension'] == 'html') {
2877
                if (file_exists($docData['absolute_path']) && is_file($docData['absolute_path'])) {
2878
                    $docData['file_content'] = file_get_contents($docData['absolute_path']);
2879
                    return $docData;
2880
                }
2881
            }
2882
        }
2883
    }
2884
    return array();
2885
}
2886
2887
/**
2888
 * @param int $workId
2889
 * @param array $courseInfo
2890
 * @return string
2891
 */
2892
function getAllDocumentsFromWorkToString($workId, $courseInfo)
2893
{
2894
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2895
    $content = null;
2896
    if (!empty($documents)) {
2897
        $content .= '<ul class="nav nav-list well">';
2898
        $content .= '<li class="nav-header">'.get_lang('Documents').'</li>';
2899
        foreach ($documents as $doc) {
2900
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2901
            if ($docData) {
2902
                $content .= '<li><a target="_blank" href="'.$docData['url'].'">'.$docData['title'].'</a></li>';
2903
            }
2904
        }
2905
        $content .= '</ul><br />';
2906
    }
2907
    return $content;
2908
}
2909
2910
/**
2911
 * Returns fck editor toolbar
2912
 * @return array
2913
 */
2914
function getWorkDescriptionToolbar()
2915
{
2916
    return array(
2917
        'ToolbarStartExpanded' => 'true',
2918
        'ToolbarSet' => 'Work',
2919
        'Width' => '100%',
2920
        'Height' => '400'
2921
    );
2922
}
2923
2924
/**
2925
 * @param array $work
2926
 * @return array
2927
 */
2928
function getWorkComments($work)
2929
{
2930
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2931
    $userTable= Database::get_main_table(TABLE_MAIN_USER);
2932
2933
    $courseId = intval($work['c_id']);
2934
    $workId = intval($work['id']);
2935
2936
    if (empty($courseId) || empty($workId)) {
2937
        return array();
2938
    }
2939
2940
    $sql = "SELECT
2941
            c.id, c.user_id, u.firstname, u.lastname, u.username, u.picture_uri
2942
            FROM $commentTable c
2943
            INNER JOIN $userTable u ON (u.user_id = c.user_id)
2944
            WHERE c_id = $courseId AND work_id = $workId
2945
            ORDER BY sent_at
2946
            ";
2947
    $result = Database::query($sql);
2948
    $comments = Database::store_result($result, 'ASSOC');
2949
    if (!empty($comments)) {
2950
        foreach ($comments as &$comment) {
2951
            $comment['picture'] = UserManager::getUserPicture($comment['user_id']);
2952
            $commentInfo = getWorkComment($comment['id']);
2953
2954
            if (!empty($commentInfo)) {
2955
                $comment = array_merge($comment, $commentInfo);
2956
            }
2957
        }
2958
    }
2959
    return $comments;
2960
}
2961
2962
/**
2963
 * Get total score from a work list
2964
 * @param $workList
2965
 * @return int|null
2966
 */
2967
function getTotalWorkScore($workList)
2968
{
2969
    $count = 0;
2970
    foreach ($workList as $data) {
2971
        $count += $data['qualification_score'];
2972
    }
2973
    return $count;
2974
}
2975
2976
2977
/**
2978
 * Get comment count from a work list (docs sent by students)
2979
 * @param array $workList
2980
 * @param array $courseInfo
2981
 * @return int|null
2982
 */
2983
function getTotalWorkComment($workList, $courseInfo = array())
2984
{
2985
    if (empty($courseInfo)) {
2986
        $courseInfo = api_get_course_info();
2987
    }
2988
2989
    $count = 0;
2990
    foreach ($workList as $data) {
2991
        $count += getWorkCommentCount($data['id'], $courseInfo);
2992
    }
2993
    return $count;
2994
}
2995
2996
/**
2997
 * Get comment count for a specific work sent by a student.
2998
 * @param int $id
2999
 * @param array $courseInfo
3000
 * @return int
3001
 */
3002 View Code Duplication
function getWorkCommentCount($id, $courseInfo = array())
3003
{
3004
    if (empty($courseInfo)) {
3005
        $courseInfo = api_get_course_info();
3006
    }
3007
3008
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3009
    $id = intval($id);
3010
3011
    $sql = "SELECT count(*) as count
3012
            FROM $commentTable
3013
            WHERE work_id = $id AND c_id = ".$courseInfo['real_id'];
3014
3015
    $result = Database::query($sql);
3016
    if (Database::num_rows($result)) {
3017
        $comment = Database::fetch_array($result);
3018
        return $comment['count'];
3019
    }
3020
3021
    return 0;
3022
}
3023
3024
/**
3025
 * Get comment count for a specific parent
3026
 * @param int $parentId
3027
 * @param array $courseInfo
3028
 * @param int $sessionId
3029
 * @return int
3030
 */
3031 View Code Duplication
function getWorkCommentCountFromParent(
3032
    $parentId,
3033
    $courseInfo = array(),
3034
    $sessionId = 0
3035
) {
3036
    if (empty($courseInfo)) {
3037
        $courseInfo = api_get_course_info();
3038
    }
3039
3040
    if (empty($sessionId)) {
3041
        $sessionId = api_get_session_id();
3042
    } else {
3043
        $sessionId = intval($sessionId);
3044
    }
3045
3046
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3047
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3048
    $parentId = intval($parentId);
3049
3050
    $sql = "SELECT count(*) as count
3051
            FROM $commentTable c INNER JOIN $work w
3052
            ON c.c_id = w.c_id AND w.id = c.work_id
3053
            WHERE
3054
                session_id = $sessionId AND
3055
                parent_id = $parentId AND
3056
                w.c_id = ".$courseInfo['real_id'];
3057
3058
    $result = Database::query($sql);
3059
    if (Database::num_rows($result)) {
3060
        $comment = Database::fetch_array($result);
3061
        return $comment['count'];
3062
    }
3063
3064
    return 0;
3065
}
3066
3067
/**
3068
 * Get last work information from parent
3069
 * @param int $parentId
3070
 * @param array $courseInfo
3071
 * @param int $sessionId
3072
 * @return int
3073
 */
3074 View Code Duplication
function getLastWorkStudentFromParent(
3075
    $parentId,
3076
    $courseInfo = array(),
3077
    $sessionId = 0
3078
) {
3079
    if (empty($courseInfo)) {
3080
        $courseInfo = api_get_course_info();
3081
    }
3082
3083
    if (empty($sessionId)) {
3084
        $sessionId = api_get_session_id();
3085
    } else {
3086
        $sessionId = intval($sessionId);
3087
    }
3088
3089
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3090
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3091
    $parentId = intval($parentId);
3092
3093
    $sql = "SELECT w.*
3094
            FROM $commentTable c INNER JOIN $work w
3095
            ON c.c_id = w.c_id AND w.id = c.work_id
3096
            WHERE
3097
                session_id = $sessionId AND
3098
                parent_id = $parentId AND
3099
                w.c_id = ".$courseInfo['real_id']."
3100
            ORDER BY w.sent_date
3101
            LIMIT 1
3102
            ";
3103
3104
    $result = Database::query($sql);
3105
    if (Database::num_rows($result)) {
3106
        $comment = Database::fetch_array($result, 'ASSOC');
3107
        /*if (!empty($comment)) {
3108
            $comment['assignment'] = get_work_assignment_by_id(
3109
                $comment['id'],
3110
                $courseInfo['real_id']
3111
            );
3112
        }*/
3113
        return $comment;
3114
    }
3115
3116
    return array();
3117
}
3118
3119
/**
3120
 * Get last work information from parent
3121
 * @param int $parentId
3122
 * @param array $courseInfo
3123
 * @param int $sessionId
3124
 * @return int
3125
 */
3126 View Code Duplication
function getLastWorkStudentFromParentByUser(
3127
    $userId,
3128
    $parentId,
3129
    $courseInfo = array(),
3130
    $sessionId = 0
3131
) {
3132
    if (empty($courseInfo)) {
3133
        $courseInfo = api_get_course_info();
3134
    }
3135
3136
    if (empty($sessionId)) {
3137
        $sessionId = api_get_session_id();
3138
    } else {
3139
        $sessionId = intval($sessionId);
3140
    }
3141
3142
    $userId = intval($userId);
3143
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3144
    $parentId = intval($parentId);
3145
3146
    $sql = "SELECT *
3147
            FROM  $work
3148
            WHERE
3149
                user_id = $userId AND
3150
                session_id = $sessionId AND
3151
                parent_id = $parentId AND
3152
                c_id = ".$courseInfo['real_id']."
3153
            ORDER BY sent_date DESC
3154
            LIMIT 1
3155
            ";
3156
    $result = Database::query($sql);
3157
    if (Database::num_rows($result)) {
3158
        $work = Database::fetch_array($result, 'ASSOC');
3159
        /*if (!empty($comment)) {
3160
            $comment['assignment'] = get_work_assignment_by_id(
3161
                $comment['id'],
3162
                $courseInfo['real_id']
3163
            );
3164
        }*/
3165
        return $work;
3166
    }
3167
3168
    return array();
3169
}
3170
3171
/**
3172
 * @param int $id comment id
3173
 * @param array $courseInfo
3174
 * @return string
3175
 */
3176
function getWorkComment($id, $courseInfo = array())
3177
{
3178
    if (empty($courseInfo)) {
3179
        $courseInfo = api_get_course_info();
3180
    }
3181
3182
    if (empty($courseInfo['real_id'])) {
3183
        return array();
3184
    }
3185
3186
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3187
    $id = intval($id);
3188
3189
    $sql = "SELECT * FROM $commentTable
3190
            WHERE id = $id AND c_id = ".$courseInfo['real_id'];
3191
    $result = Database::query($sql);
3192
    $comment = array();
3193
    if (Database::num_rows($result)) {
3194
        $comment = Database::fetch_array($result, 'ASSOC');
3195
        $filePath = null;
3196
        $fileUrl = null;
3197
        $deleteUrl = null;
3198
        $fileName = null;
3199
        if (!empty($comment['file'])) {
3200
            $work = get_work_data_by_id($comment['work_id']);
3201
            $workParent = get_work_data_by_id($work['parent_id']);
3202
            $filePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/'.$workParent['url'].'/'.$comment['file'];
3203
            $fileUrl = api_get_path(WEB_CODE_PATH).'work/download_comment_file.php?comment_id='.$id.'&'.api_get_cidreq();
3204
            $deleteUrl = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$comment['work_id'].'&action=delete_attachment&comment_id='.$id;
3205
            $fileParts = explode('_', $comment['file']);
3206
            $fileName = str_replace($fileParts[0].'_'.$fileParts[1].'_', '', $comment['file']);
3207
        }
3208
        $comment['delete_file_url'] = $deleteUrl;
3209
        $comment['file_path'] = $filePath;
3210
        $comment['file_url'] = $fileUrl;
3211
        $comment['file_name_to_show'] = $fileName;
3212
    }
3213
3214
    return $comment;
3215
}
3216
3217
/**
3218
 * @param int $id
3219
 * @param array $courseInfo
3220
 */
3221
function deleteCommentFile($id, $courseInfo = array())
3222
{
3223
    $workComment = getWorkComment($id, $courseInfo);
3224
    if (isset($workComment['file']) && !empty($workComment['file'])) {
3225
        if (file_exists($workComment['file_path'])) {
3226
            $result = my_delete($workComment['file_path']);
3227
            if ($result) {
3228
                $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3229
                $params = array('file' => '');
3230
                Database::update(
3231
                    $commentTable,
3232
                    $params,
3233
                    array('id = ? AND c_id = ? ' => array($workComment['id'], $workComment['c_id']))
3234
                );
3235
            }
3236
        }
3237
    }
3238
}
3239
3240
/**
3241
 * Adds a comments to the work document
3242
 * @param array $courseInfo
3243
 * @param int $userId
3244
 * @param array $work
3245
 * @param array $data
3246
 * @return int
3247
 */
3248
function addWorkComment($courseInfo, $userId, $parentWork, $work, $data)
3249
{
3250
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3251
3252
    $params = array(
3253
        'work_id' => $work['id'],
3254
        'c_id' => $work['c_id'],
3255
        'user_id' => $userId,
3256
        'comment' => $data['comment'],
3257
        'sent_at' => api_get_utc_datetime()
3258
    );
3259
3260
    $commentId = Database::insert($commentTable, $params);
3261
3262
    if ($commentId) {
3263
        $sql = "UPDATE $commentTable SET id = iid WHERE iid = $commentId";
3264
        Database::query($sql);
3265
    }
3266
3267
    $userIdListToSend = array();
3268
3269
    if (api_is_allowed_to_edit()) {
3270
        if (isset($data['send_mail']) && $data['send_mail']) {
3271
            // Teacher sends a feedback
3272
            $userIdListToSend = array($work['user_id']);
3273
        }
3274
    } else {
3275
        $sessionId = api_get_session_id();
3276
        if (empty($sessionId)) {
3277
            $teachers = CourseManager::get_teacher_list_from_course_code(
3278
                $courseInfo['code']
3279
            );
3280
            if (!empty($teachers)) {
3281
                $userIdListToSend = array_keys($teachers);
3282
            }
3283
        } else {
3284
            $teachers = SessionManager::getCoachesByCourseSession(
3285
                $sessionId,
3286
                $courseInfo['code']
3287
            );
3288
3289
            if (!empty($teachers)) {
3290
                $userIdListToSend = array_values($teachers);
3291
            }
3292
        }
3293
    }
3294
3295
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$work['id'];
3296
    $subject = sprintf(get_lang('ThereIsANewWorkFeedback'), $parentWork['title']);
3297
    $content = sprintf(get_lang('ThereIsANewWorkFeedbackInWorkXHere'), $work['title'], $url);
3298
3299
    if (!empty($userIdListToSend)) {
3300
        foreach ($userIdListToSend as $userId) {
3301
            MessageManager::send_message_simple(
3302
                $userId,
3303
                $subject,
3304
                $content
3305
            );
3306
        }
3307
    }
3308
3309
    $fileData = isset($data['file']) ? $data['file'] : null;
3310
    if (!empty($commentId) && !empty($fileData)) {
3311
        $workParent = get_work_data_by_id($work['parent_id']);
3312
        if (!empty($workParent)) {
3313
            $uploadDir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work'.$workParent['url'];
3314
            $newFileName = 'comment_'.$commentId.'_'.php2phps(
3315
                    api_replace_dangerous_char($fileData['name'])
3316
                );
3317
            $newFilePath = $uploadDir.'/'.$newFileName;
3318
            $result = move_uploaded_file($fileData['tmp_name'], $newFilePath);
3319
            if ($result) {
3320
                $params = array('file' => $newFileName);
3321
                Database::update(
3322
                    $commentTable,
3323
                    $params,
3324
                    array('id = ? AND c_id = ? ' => array($commentId, $work['c_id']))
3325
                );
3326
            }
3327
        }
3328
    }
3329
}
3330
3331
/**
3332
 * @param array $work
3333
 * @param string $page
3334
 * @return string
3335
 */
3336
function getWorkCommentForm($work, $page = 'view')
3337
{
3338
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&action=send_comment&'.api_get_cidreq().'&page='.$page;
3339
    $form = new FormValidator(
3340
        'work_comment',
3341
        'post',
3342
        $url
3343
    );
3344
3345
    $form->addElement('file', 'file', get_lang('Attachment'));
3346
    $form->addHtmlEditor('comment', get_lang('Comment'));
3347
    $form->addElement('hidden', 'id', $work['id']);
3348
    $form->addElement('hidden', 'page', $page);
3349
    if (api_is_allowed_to_edit()) {
3350
        $form->addElement('checkbox', 'send_mail', null, get_lang('SendMail'));
3351
    }
3352
    $form->addButtonSend(get_lang('Send'), 'button');
3353
3354
    return $form->returnForm();
3355
}
3356
3357
/**
3358
 * @param array $homework result of get_work_assignment_by_id()
3359
 * @return string
3360
 */
3361
function getWorkDateValidationStatus($homework)
3362
{
3363
    $message = null;
3364
    $has_expired = false;
3365
    $has_ended = false;
3366
3367
    if (!empty($homework)) {
3368
3369 View Code Duplication
        if (!empty($homework['expires_on']) || !empty($homework['ends_on'])) {
3370
            $time_now = time();
3371
3372
            if (!empty($homework['expires_on'])) {
3373
                $time_expires   = api_strtotime($homework['expires_on'], 'UTC');
3374
                $difference     = $time_expires - $time_now;
3375
                if ($difference < 0) {
3376
                    $has_expired = true;
3377
                }
3378
            }
3379
3380
            if (empty($homework['expires_on'])) {
3381
                $has_expired = false;
3382
            }
3383
3384
            if (!empty($homework['ends_on'])) {
3385
                $time_ends = api_strtotime($homework['ends_on'], 'UTC');
3386
                $difference2 = $time_ends - $time_now;
3387
                if ($difference2 < 0) {
3388
                    $has_ended = true;
3389
                }
3390
            }
3391
3392
            $ends_on = api_convert_and_format_date($homework['ends_on']);
3393
            $expires_on = api_convert_and_format_date($homework['expires_on']);
3394
        }
3395
3396
        if ($has_ended) {
3397
            $message = Display::return_message(get_lang('EndDateAlreadyPassed').' '.$ends_on, 'error');
3398
        } elseif ($has_expired) {
3399
            $message = Display::return_message(get_lang('ExpiryDateAlreadyPassed').' '.$expires_on, 'warning');
3400
        } else {
3401
            if ($has_expired) {
3402
                $message = Display::return_message(get_lang('ExpiryDateToSendWorkIs').' '.$expires_on);
3403
            }
3404
        }
3405
    }
3406
3407
    return array(
3408
        'message' => $message,
3409
        'has_ended' => $has_ended,
3410
        'has_expired' => $has_expired
3411
    );
3412
}
3413
3414
/**
3415
 * @param FormValidator $form
3416
 * @param int $uploadFormType
3417
 */
3418
function setWorkUploadForm($form, $uploadFormType = 0)
3419
{
3420
    $form->addElement('header', get_lang('UploadADocument'));
3421
    $form->addElement('hidden', 'contains_file', 0, array('id'=>'contains_file_id'));
3422
    $form->addElement('hidden', 'active', 1);
3423
    $form->addElement('hidden', 'accepted', 1);
3424
    $form->addElement('text', 'title', get_lang('Title'), array('id' => 'file_upload'));
3425
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
3426
3427
    switch ($uploadFormType) {
3428
        case 0:
3429
            // File and text.
3430
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3431
            $form->add_real_progress_bar('uploadWork', 'file');
3432
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3433
            break;
3434
        case 1:
3435
            // Only text.
3436
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3437
            $form->addRule('description', get_lang('ThisFieldIsRequired'), 'required');
3438
            break;
3439
        case 2:
3440
            // Only file.
3441
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3442
            $form->add_real_progress_bar('uploadWork', 'file');
3443
            $form->addRule('file', get_lang('ThisFieldIsRequired'), 'required');
3444
            break;
3445
    }
3446
3447
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
3448
}
3449
3450
/**
3451
 * @param array $my_folder_data
3452
 * @param array $_course
3453
 * @param bool $isCorrection
3454
 * @param array $workInfo
3455
 * @param array $file
3456
 *
3457
 * @return array
3458
 */
3459
function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo = [], $file = [])
3460
{
3461
    if (isset($_FILES['file']) && !empty($_FILES['file'])) {
3462
        $file = $_FILES['file'];
3463
    }
3464
3465
    if (empty($file['size'])) {
3466
        return array('error' => Display :: return_message(get_lang('UplUploadFailedSizeIsZero'), 'error'));
3467
    }
3468
    $updir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work/'; //directory path to upload
3469
3470
    // Try to add an extension to the file if it has'nt one
3471
    $filename = add_ext_on_mime(stripslashes($file['name']), $file['type']);
3472
3473
    // Replace dangerous characters
3474
    $filename = api_replace_dangerous_char($filename);
3475
3476
    // Transform any .php file in .phps fo security
3477
    $filename = php2phps($filename);
3478
    $filesize = filesize($file['tmp_name']);
3479
3480
    if (empty($filesize)) {
3481
        return array(
3482
            'error' => Display:: return_message(
3483
                get_lang('UplUploadFailedSizeIsZero'),
3484
                'error'
3485
            ),
3486
        );
3487
    } elseif (!filter_extension($new_file_name)) {
3488
        return array(
3489
            'error' => Display:: return_message(
3490
                get_lang('UplUnableToSaveFileFilteredExtension'),
3491
                'error'
3492
            ),
3493
        );
3494
    }
3495
3496
    $totalSpace = DocumentManager::documents_total_space($_course['real_id']);
3497
    $course_max_space = DocumentManager::get_course_quota($_course['code']);
3498
    $total_size = $filesize + $totalSpace;
3499
3500
    if ($total_size > $course_max_space) {
3501
        return array(
3502
            'error' => Display :: return_message(get_lang('NoSpace'), 'error')
3503
        );
3504
    }
3505
3506
    // Compose a unique file name to avoid any conflict
3507
    $new_file_name = api_get_unique_id();
3508
3509
    if ($isCorrection) {
3510
        if (!empty($workInfo['url'])) {
3511
            $new_file_name = basename($workInfo['url']).'_correction';
3512
        } else {
3513
            $new_file_name = $new_file_name.'_correction';
3514
        }
3515
    }
3516
3517
    $curdirpath = basename($my_folder_data['url']);
3518
3519
    // If we come from the group tools the groupid will be saved in $work_table
3520
    if (is_dir($updir.$curdirpath) || empty($curdirpath)) {
3521
        $result = move_uploaded_file(
3522
            $file['tmp_name'],
3523
            $updir.$curdirpath.'/'.$new_file_name
3524
        );
3525
    } else {
3526
        return array(
3527
            'error' => Display :: return_message(
3528
                get_lang('FolderDoesntExistsInFileSystem'),
3529
                'error'
3530
            )
3531
        );
3532
    }
3533
3534
    $url = null;
3535
    if ($result) {
3536
        $url = 'work/'.$curdirpath.'/'.$new_file_name;
3537
    }
3538
3539
    return array(
3540
        'url' => $url,
3541
        'filename' => $filename,
3542
        'filesize' => $filesize,
3543
        'error' => null
3544
    );
3545
}
3546
3547
/**
3548
 * Send an e-mail to users related to this work (course teachers, usually, but
3549
 * might include other group members)
3550
 * @param int $workId
3551
 * @param array $courseInfo
3552
 * @param int $session_id
3553
 */
3554
function sendAlertToUsers($workId, $courseInfo, $session_id)
3555
{
3556
    $user_list = array();
3557
    //$workData = get_work_assignment_by_id($workId, $courseInfo['real_id']);
3558
    $workData = get_work_data_by_id($workId, $courseInfo['real_id'], $session_id);
3559
    //last value is to check this is not "just" an edit
3560
    //YW Tis part serve to send a e-mail to the tutors when a new file is sent
3561
    $send = api_get_course_setting('email_alert_manager_on_new_doc');
3562
3563
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_TEACHERS) {
3564
        // Lets predefine some variables. Be sure to change the from address!
3565
        if (empty($session_id)) {
3566
            //Teachers
3567
            $user_list = CourseManager::get_user_list_from_course_code(
3568
                api_get_course_id(),
3569
                null,
3570
                null,
3571
                null,
3572
                COURSEMANAGER
3573
            );
3574
        } else {
3575
            // Coaches
3576
            $user_list = CourseManager::get_user_list_from_course_code(
3577
                api_get_course_id(),
3578
                $session_id,
3579
                null,
3580
                null,
3581
                2
3582
            );
3583
        }
3584
    }
3585
3586
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_STUDENTS) {
3587
        if (!$session_id) {
3588
            $session_id = null;
3589
        }
3590
        $student = CourseManager::get_user_list_from_course_code(
3591
            api_get_course_id(),
3592
            $session_id,
3593
            null,
3594
            null,
3595
            STUDENT,
3596
            null,
3597
            null,
3598
            null,
3599
            null,
3600
            null,
3601
            array(api_get_user_id())
3602
        );
3603
        $user_list = array_merge($user_list, $student);
3604
    }
3605
3606
    if ($send) {
3607
        $senderEmail = api_get_setting('emailAdministrator');
3608
        $senderName = api_get_person_name(
3609
            api_get_setting('administratorName'),
3610
            api_get_setting('administratorSurname'),
3611
            null,
3612
            PERSON_NAME_EMAIL_ADDRESS
3613
        );
3614
        $subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n ".get_lang('CourseName').": ".$courseInfo['name']."  ";
3615
        foreach ($user_list as $user_data) {
0 ignored issues
show
Bug introduced by
The expression $user_list of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
3616
            $to_user_id = $user_data['user_id'];
3617
            $user_info = api_get_user_info($to_user_id);
3618
            $message = get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']."\n";
3619
            $message .= get_lang('UserName')." : ".api_get_person_name($user_info['firstname'], $user_info['lastname'])."\n";
3620
            $message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."\n";
3621
            $url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
3622
            $message .= get_lang('WorkName')." : ".$workData['title']."\n\n".'<a href="'.$url.'">'.get_lang('DownloadLink')."</a>\n";
3623
            //$message .= $url;
3624
            MessageManager::send_message_simple($to_user_id, $subject, $message);
3625
            api_mail_html(
3626
                api_get_person_name(
3627
                    $user_info['firstname'].' '.$user_info['lastname'],
3628
                    null,
3629
                    PERSON_NAME_EMAIL_ADDRESS
3630
                ),
3631
                $user_info['email'],
3632
                $subject,
3633
                $message,
3634
                $senderName,
3635
                $senderEmail
3636
            );
3637
        }
3638
    }
3639
}
3640
3641
/**
3642
 * @param array $workInfo
3643
 * @param array $values
3644
 * @param array $courseInfo
3645
 * @param int $sessionId
3646
 * @param int $groupId
3647
 * @param int $userId
3648
 * @param array $file
3649
 *
3650
 * @return null|string
3651
 */
3652
function processWorkForm($workInfo, $values, $courseInfo, $sessionId, $groupId, $userId, $file = [])
3653
{
3654
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3655
3656
    $courseId = $courseInfo['real_id'];
3657
    $groupId = intval($groupId);
3658
    $sessionId = intval($sessionId);
3659
    $userId = intval($userId);
3660
3661
    $title = $values['title'];
3662
    $description = $values['description'];
3663
    $contains_file = isset($values['contains_file']) && !empty($values['contains_file']) ? intval($values['contains_file']): 0;
3664
3665
    $saveWork = true;
3666
    $message = null;
3667
    $filename = null;
3668
    $url = null;
3669
    $filesize = null;
3670
3671
    if ($values['contains_file']) {
3672
        $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3673
        if (isset($result['error'])) {
3674
            $message = $result['error'];
3675
            $saveWork = false;
3676
        }
3677
        $filename = isset($result['filename']) ? $result['filename'] : null;
3678
        if (empty($title)) {
3679
            $title = isset($result['title']) && !empty($result['title']) ? $result['title'] : get_lang('Untitled');
3680
        }
3681
3682
        $filesize = isset($result['filesize']) ? $result['filesize'] : null;
3683
        $url = $result['url'];
3684
    }
3685
3686
    if (empty($title)) {
3687
        $title = get_lang('Untitled');
3688
    }
3689
3690
    $workData = [];
3691
3692
    if ($saveWork) {
3693
        $active = '1';
3694
        $params = [
3695
            'c_id' => $courseId,
3696
            'url' => $url,
3697
            'filetype' => 'file',
3698
            'title' => $title,
3699
            'description' => $description,
3700
            'contains_file' => $contains_file,
3701
            'active' => $active,
3702
            'accepted' => '1',
3703
            'qualificator_id' => 0,
3704
            'document_id' => 0,
3705
            'weight' => 0,
3706
            'allow_text_assignment' => 0,
3707
            'post_group_id' => $groupId,
3708
            'sent_date' => api_get_utc_datetime(),
3709
            'parent_id' => $workInfo['id'],
3710
            'session_id' => $sessionId,
3711
            'user_id' => $userId,
3712
            'has_properties' => 0,
3713
            'qualification' => 0
3714
3715
            //'filesize' => $filesize
3716
        ];
3717
        $workId = Database::insert($work_table, $params);
3718
3719
        if ($workId) {
3720
            $sql = "UPDATE $work_table SET id = iid WHERE iid = $workId ";
3721
            Database::query($sql);
3722
3723
            if (array_key_exists('filename', $workInfo) && !empty($filename)) {
3724
                $filename = Database::escape_string($filename);
3725
                $sql = "UPDATE $work_table SET
3726
                            filename = '$filename'
3727
                        WHERE iid = $workId";
3728
                Database::query($sql);
3729
            }
3730
3731
            if (array_key_exists('document_id', $workInfo)) {
3732
                $documentId = isset($values['document_id']) ? intval($values['document_id']) : 0;
3733
                $sql = "UPDATE $work_table SET
3734
                            document_id = '$documentId'
3735
                        WHERE iid = $workId";
3736
                Database::query($sql);
3737
            }
3738
            api_item_property_update(
3739
                $courseInfo,
3740
                'work',
3741
                $workId,
3742
                'DocumentAdded',
3743
                $userId,
3744
                $groupId
3745
            );
3746
            sendAlertToUsers($workId, $courseInfo, $sessionId);
3747
            Event::event_upload($workId);
3748
            $workData = get_work_data_by_id($workId);
3749
            Display::addFlash(Display::return_message(get_lang('DocAdd')));
3750
        }
3751
    } else {
3752
        Display::addFlash(Display::return_message(get_lang('IsNotPosibleSaveTheDocument'), 'error'));
3753
    }
3754
3755
    return $workData;
3756
}
3757
3758
/**
3759
 * Creates a new task (directory) in the assignment tool
3760
 * @param array $params
0 ignored issues
show
Bug introduced by
There is no parameter named $params. Was it maybe removed?

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

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

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

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

Loading history...
3761
 * @param int $user_id
3762
 * @param array $courseInfo
3763
 * @param int $group_id
3764
 * @param int $session_id
3765
 * @return bool|int
3766
 * @note $params can have the following elements, but should at least have the 2 first ones: (
3767
 *       'new_dir' => 'some-name',
3768
 *       'description' => 'some-desc',
3769
 *       'qualification' => 20 (e.g. 20),
3770
 *       'weight' => 50 (percentage) to add to gradebook (e.g. 50),
3771
 *       'allow_text_assignment' => 0/1/2,
3772
 * @todo Rename createAssignment or createWork, or something like that
3773
 */
3774
function addDir($formValues, $user_id, $courseInfo, $group_id, $session_id)
3775
{
3776
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3777
3778
    $user_id = intval($user_id);
3779
    $group_id = intval($group_id);
3780
    $session_id = intval($session_id);
3781
3782
    $base_work_dir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work';
3783
    $course_id = $courseInfo['real_id'];
3784
3785
    $directory = api_replace_dangerous_char($formValues['new_dir']);
3786
    $directory = disable_dangerous_file($directory);
3787
    $created_dir = create_unexisting_work_directory($base_work_dir, $directory);
3788
3789
    if (!empty($created_dir)) {
3790
        $dirName = '/'.$created_dir;
3791
        $today = api_get_utc_datetime();
3792
3793
        $params = [
3794
            'c_id' => $course_id,
3795
            'url' => $dirName,
3796
            'title' => $formValues['new_dir'],
3797
            'description' => $formValues['description'],
3798
            'author' => '',
3799
            'active' => '1',
3800
            'accepted' => '1',
3801
            'filetype' => 'folder',
3802
            'post_group_id' => $group_id,
3803
            'sent_date' => $today,
3804
            'qualification' => $formValues['qualification'] != '' ? $formValues['qualification'] : 0,
3805
            'parent_id' => 0,
3806
            'qualificator_id' => 0,
3807
            'weight' => !empty($formValues['weight']) ? $formValues['weight'] : 0,
3808
            'session_id' => $session_id,
3809
            'allow_text_assignment' => $formValues['allow_text_assignment'],
3810
            'contains_file' => 0,
3811
            'user_id' => $user_id,
3812
            'has_properties' => 0,
3813
            'document_id' => 0
3814
        ];
3815
        $id = Database::insert($work_table, $params);
3816
3817
        if ($id) {
3818
3819
            $sql = "UPDATE $work_table SET id = iid WHERE iid = $id";
3820
            Database::query($sql);
3821
3822
            // Folder created
3823
            api_item_property_update(
3824
                $courseInfo,
3825
                'work',
3826
                $id,
3827
                'DirectoryCreated',
3828
                $user_id,
3829
                $group_id
3830
            );
3831
3832
            updatePublicationAssignment($id, $formValues, $courseInfo, $group_id);
3833
3834
            if (api_get_course_setting('email_alert_students_on_new_homework') == 1) {
3835
                send_email_on_homework_creation($course_id, $session_id, $id);
3836
            }
3837
3838
            return $id;
3839
        }
3840
    }
3841
    return false;
3842
}
3843
3844
/**
3845
 * @param int $workId
3846
 * @param array $courseInfo
3847
 * @return int
3848
 */
3849
function agendaExistsForWork($workId, $courseInfo)
3850
{
3851
    $workTable = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3852
    $courseId = $courseInfo['real_id'];
3853
    $workId = intval($workId);
3854
3855
    $sql = "SELECT add_to_calendar FROM $workTable
3856
            WHERE c_id = $courseId AND publication_id = ".$workId;
3857
    $res = Database::query($sql);
3858 View Code Duplication
    if (Database::num_rows($res)) {
3859
        $row = Database::fetch_array($res, 'ASSOC');
3860
        if (!empty($row['add_to_calendar'])) {
3861
            return $row['add_to_calendar'];
3862
        }
3863
    }
3864
    return 0;
3865
}
3866
3867
/**
3868
 * Update work description, qualification, weight, allow_text_assignment
3869
 * @param int $workId
3870
 * @param array $params
3871
 * @param array $courseInfo
3872
 * @param int $sessionId
3873
 */
3874
function updateWork($workId, $params, $courseInfo, $sessionId = 0)
3875
{
3876
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3877
    $filteredParams = array(
3878
        'description' => $params['description'],
3879
        'qualification' => $params['qualification'],
3880
        'weight' => $params['weight'],
3881
        'allow_text_assignment' => $params['allow_text_assignment']
3882
    );
3883
3884
    Database::update(
3885
        $workTable,
3886
        $filteredParams,
3887
        array(
3888
            'id = ? AND c_id = ? AND session_id = ? ' => array(
3889
                $workId, $courseInfo['real_id'], $sessionId
3890
            )
3891
        )
3892
    );
3893
}
3894
3895
/**
3896
 * @param int $workId
3897
 * @param array $params
3898
 * @param array $courseInfo
3899
 * @param int $groupId
3900
 */
3901
function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
3902
{
3903
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3904
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3905
    $workId = intval($workId);
3906
    $time = api_get_utc_datetime();
3907
    $course_id = $courseInfo['real_id'];
3908
3909
    // Insert into agenda
3910
    $agendaId = 0;
3911
3912
    if (isset($params['add_to_calendar']) && $params['add_to_calendar'] == 1) {
3913
        require_once api_get_path(SYS_CODE_PATH).'resourcelinker/resourcelinker.inc.php';
3914
3915
        // Setting today date
3916
        $date = $end_date = $time;
3917
3918
        if (isset($params['enableExpiryDate'])) {
3919
            $end_date = $params['expires_on'];
3920
            $date = $end_date;
3921
        }
3922
3923
        $title = sprintf(get_lang('HandingOverOfTaskX'), $params['new_dir']);
3924
        $description = isset($params['description']) ? $params['description'] : '';
3925
        $content = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq().'&id='.$workId.'">'
3926
            .$params['new_dir'].'</a>'.$description;
3927
3928
        $agendaId = agendaExistsForWork($workId, $courseInfo);
3929
3930
        // Add/edit agenda
3931
        $agenda = new Agenda();
3932
        $agenda->set_course($courseInfo);
3933
        $agenda->type = 'course';
3934
3935
        if (empty($agendaId)) {
3936
            $agendaId = $agenda->addEvent(
3937
                $date,
3938
                $end_date,
3939
                'false',
3940
                $title,
3941
                $content,
3942
                array('GROUP:'.$groupId)
3943
            );
3944
        } else {
3945
            $agenda->editEvent(
3946
                $agendaId,
3947
                $end_date,
3948
                $end_date,
3949
                'false',
3950
                $title,
3951
                $content
3952
            );
3953
        }
3954
    }
3955
3956
    $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
3957
    $expiryDate = isset($params['enableExpiryDate']) && $params['enableExpiryDate'] == 1 ? api_get_utc_datetime($params['expires_on']) : '';
3958
    $endDate = isset($params['enableEndDate']) && $params['enableEndDate'] == 1 ? api_get_utc_datetime($params['ends_on']) : '';
3959
3960
    $data = get_work_assignment_by_id($workId, $course_id);
3961
3962
    if (!empty($expiryDate)) {
3963
        $expiryDateCondition = "expires_on = '".Database::escape_string($expiryDate)."', ";
3964
    } else {
3965
        $expiryDateCondition = "expires_on = null, ";
3966
    }
3967
3968
    if (!empty($endDate)) {
3969
        $endOnCondition = "ends_on = '".Database::escape_string($endDate)."', ";
3970
    } else {
3971
        $endOnCondition = "ends_on = null, ";
3972
    }
3973
3974
    if (empty($data)) {
3975
3976
        $sql = "INSERT INTO $table SET
3977
                c_id = $course_id ,
3978
                $expiryDateCondition
3979
                $endOnCondition
3980
                add_to_calendar = $agendaId,
3981
                enable_qualification = '$qualification',
3982
                publication_id = '$workId'";
3983
3984
        Database::query($sql);
3985
3986
        $my_last_id = Database::insert_id();
3987
        if ($my_last_id) {
3988
3989
            $sql = "UPDATE $table SET
3990
                        id = iid
3991
                    WHERE iid = $my_last_id";
3992
            Database::query($sql);
3993
3994
            $sql = "UPDATE $workTable SET
3995
                        has_properties  = $my_last_id,
3996
                        view_properties = 1
3997
                    WHERE c_id = $course_id AND id = $workId";
3998
            Database::query($sql);
3999
        }
4000
    } else {
4001
        $sql = "UPDATE $table SET
4002
                    $expiryDateCondition
4003
                    $endOnCondition
4004
                    add_to_calendar  = $agendaId,
4005
                    enable_qualification = '".$qualification."'
4006
                WHERE
4007
                    publication_id = $workId AND
4008
                    c_id = $course_id AND
4009
                    id = ".$data['id'];
4010
        Database::query($sql);
4011
    }
4012
4013
    if (!empty($params['category_id'])) {
4014
4015
        $link_info = GradebookUtils::is_resource_in_course_gradebook(
4016
            $courseInfo['code'],
4017
            LINK_STUDENTPUBLICATION,
4018
            $workId,
4019
            api_get_session_id()
4020
        );
4021
4022
        $linkId = null;
4023
        if (!empty($link_info)) {
4024
            $linkId = $link_info['id'];
4025
        }
4026
4027
        if (isset($params['make_calification']) &&
4028
            $params['make_calification'] == 1
4029
        ) {
4030
            if (empty($linkId)) {
4031
                GradebookUtils::add_resource_to_course_gradebook(
4032
                    $params['category_id'],
4033
                    $courseInfo['code'],
4034
                    LINK_STUDENTPUBLICATION,
4035
                    $workId,
4036
                    $params['new_dir'],
4037
                    (float)$params['weight'],
4038
                    (float)$params['qualification'],
4039
                    $params['description'],
4040
                    1,
4041
                    api_get_session_id()
4042
                );
4043
            } else {
4044
                GradebookUtils::update_resource_from_course_gradebook(
4045
                    $linkId,
4046
                    $courseInfo['code'],
4047
                    $params['weight']
4048
                );
4049
            }
4050
        } else {
4051
            // Delete everything of the gradebook for this $linkId
4052
            GradebookUtils::remove_resource_from_course_gradebook($linkId);
4053
        }
4054
    }
4055
}
4056
4057
/**
4058
 * Delete all work by student
4059
 * @param int $userId
4060
 * @param array $courseInfo
4061
 * @return array return deleted items
4062
 */
4063
function deleteAllWorkPerUser($userId, $courseInfo)
4064
{
4065
    $deletedItems = array();
4066
    $workPerUser = getWorkPerUser($userId);
4067
    if (!empty($workPerUser)) {
4068
        foreach ($workPerUser as $work) {
4069
            $work = $work['work'];
4070
            foreach ($work->user_results as $userResult) {
4071
                $result = deleteWorkItem($userResult['id'], $courseInfo);
4072
                if ($result) {
4073
                    $deletedItems[] = $userResult;
4074
                }
4075
            }
4076
        }
4077
    }
4078
    return $deletedItems;
4079
}
4080
4081
/**
4082
 * @param int $item_id
4083
 * @param array course info
4084
 * @return bool
4085
 */
4086
function deleteWorkItem($item_id, $courseInfo)
4087
{
4088
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4089
    $TSTDPUBASG = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
4090
4091
    $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
4092
4093
    $is_allowed_to_edit = api_is_allowed_to_edit();
4094
    $file_deleted = false;
4095
    $item_id = intval($item_id);
4096
4097
    $is_author = user_is_author($item_id);
4098
    $work_data = get_work_data_by_id($item_id);
4099
    $locked = api_resource_is_locked_by_gradebook($work_data['parent_id'], LINK_STUDENTPUBLICATION);
4100
    $course_id = $courseInfo['real_id'];
4101
4102
    if (($is_allowed_to_edit && $locked == false) ||
4103
        (
4104
            $locked == false &&
4105
            $is_author &&
4106
            api_get_course_setting('student_delete_own_publication') == 1 &&
4107
            $work_data['qualificator_id'] == 0
4108
        )
4109
    ) {
4110
        // We found the current user is the author
4111
        $sql = "SELECT url, contains_file FROM $work_table
4112
                WHERE c_id = $course_id AND id = $item_id";
4113
        $result = Database::query($sql);
4114
        $row = Database::fetch_array($result);
4115
4116
        if (Database::num_rows($result) > 0) {
4117
            $sql = "UPDATE $work_table SET active = 2
4118
                    WHERE c_id = $course_id AND id = $item_id";
4119
            Database::query($sql);
4120
            $sql = "DELETE FROM $TSTDPUBASG
4121
                    WHERE c_id = $course_id AND publication_id = $item_id";
4122
            Database::query($sql);
4123
4124
            api_item_property_update(
4125
                $courseInfo,
4126
                'work',
4127
                $item_id,
4128
                'DocumentDeleted',
4129
                api_get_user_id()
4130
            );
4131
            $work = $row['url'];
4132
4133
            if ($row['contains_file'] == 1) {
4134
                if (!empty($work)) {
4135
                    if (api_get_setting('permanently_remove_deleted_files') == 'true') {
4136
                        my_delete($currentCourseRepositorySys.'/'.$work);
4137
                        $file_deleted = true;
4138
                    } else {
4139
                        $extension = pathinfo($work, PATHINFO_EXTENSION);
4140
                        $new_dir = $work.'_DELETED_'.$item_id.'.'.$extension;
4141
4142
                        if (file_exists($currentCourseRepositorySys.'/'.$work)) {
4143
                            rename($currentCourseRepositorySys.'/'.$work, $currentCourseRepositorySys.'/'.$new_dir);
4144
                            $file_deleted = true;
4145
                        }
4146
                    }
4147
                }
4148
            } else {
4149
                $file_deleted = true;
4150
            }
4151
        }
4152
    }
4153
    return $file_deleted;
4154
}
4155
4156
/**
4157
 * @param FormValidator $form
4158
 * @param array $defaults
4159
 * @return FormValidator
4160
 */
4161
function getFormWork($form, $defaults = array())
4162
{
4163
    if (!empty($defaults)) {
4164
        if (isset($defaults['submit'])) {
4165
            unset($defaults['submit']);
4166
        }
4167
    }
4168
4169
    // Create the form that asks for the directory name
4170
    $form->addElement('text', 'new_dir', get_lang('AssignmentName'));
4171
    $form->addRule('new_dir', get_lang('ThisFieldIsRequired'), 'required');
4172
    $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
4173
    $form->addButtonAdvancedSettings('advanced_params', get_lang('AdvancedParameters'));
4174
4175
    if (!empty($defaults) && (isset($defaults['enableEndDate']) || isset($defaults['enableExpiryDate']))) {
4176
        $form->addElement('html', '<div id="advanced_params_options" style="display:block">');
4177
    } else {
4178
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
4179
    }
4180
4181
    // QualificationOfAssignment
4182
    $form->addElement('text', 'qualification', get_lang('QualificationNumeric'));
4183
4184
    if ((api_get_session_id() != 0 && Gradebook::is_active()) || api_get_session_id() == 0) {
4185
        $form->addElement(
4186
            'checkbox',
4187
            'make_calification',
4188
            null,
4189
            get_lang('MakeQualifiable'),
4190
            array(
4191
                'id' =>'make_calification_id',
4192
                'onclick' => "javascript: if(this.checked) { document.getElementById('option1').style.display='block';}else{document.getElementById('option1').style.display='none';}"
4193
            )
4194
        );
4195
    } else {
4196
        // QualificationOfAssignment
4197
        $form->addElement('hidden', 'make_calification', false);
4198
    }
4199
4200
    if (!empty($defaults) && isset($defaults['category_id'])) {
4201
        $form->addElement('html', '<div id=\'option1\' style="display:block">');
4202
    } else {
4203
        $form->addElement('html', '<div id=\'option1\' style="display:none">');
4204
    }
4205
4206
    // Loading Gradebook select
4207
    GradebookUtils::load_gradebook_select_in_tool($form);
4208
4209
    $form->addElement('text', 'weight', get_lang('WeightInTheGradebook'));
4210
    $form->addElement('html', '</div>');
4211
4212
    $form->addElement('checkbox', 'enableExpiryDate', null, get_lang('EnableExpiryDate'), 'id="expiry_date"');
4213
    if (isset($defaults['enableExpiryDate']) && $defaults['enableExpiryDate']) {
4214
        $form->addElement('html', '<div id="option2" style="display: block;">');
4215
    } else {
4216
        $form->addElement('html', '<div id="option2" style="display: none;">');
4217
    }
4218
4219
    $currentDate = substr(api_get_local_time(), 0, 10);
4220
4221 View Code Duplication
    if (!isset($defaults['expires_on'])) {
4222
        $date = substr($currentDate, 0, 10);
4223
        $defaults['expires_on'] = $date.' 23:59';
4224
    }
4225
4226 View Code Duplication
    if (!isset($defaults['ends_on'])) {
4227
        $date = substr($currentDate, 0, 10);
4228
        $defaults['ends_on'] = $date.' 23:59';
4229
    }
4230
4231
    $form->addElement('date_time_picker', 'expires_on', get_lang('ExpiresAt'));
4232
    $form->addElement('html', '</div>');
4233
4234
    $form->addElement('checkbox', 'enableEndDate', null, get_lang('EnableEndDate'), 'id="end_date"');
4235
4236
    if (isset($defaults['enableEndDate']) && $defaults['enableEndDate']) {
4237
        $form->addElement('html', '<div id="option3" style="display: block;">');
4238
    } else {
4239
        $form->addElement('html', '<div id="option3" style="display: none;">');
4240
    }
4241
4242
    $form->addElement('date_time_picker', 'ends_on', get_lang('EndsAt'));
4243
    $form->addElement('html', '</div>');
4244
4245
    $form->addElement('checkbox', 'add_to_calendar', null, get_lang('AddToCalendar'));
4246
    $form->addElement('select', 'allow_text_assignment', get_lang('DocumentType'), getUploadDocumentType());
4247
4248
    $form->addElement('html', '</div>');
4249
4250
    if (isset($defaults['enableExpiryDate']) && isset($defaults['enableEndDate'])) {
4251
        $form->addRule(array('expires_on', 'ends_on'), get_lang('DateExpiredNotBeLessDeadLine'), 'comparedate');
4252
    }
4253
    if (!empty($defaults)) {
4254
        $form->setDefaults($defaults);
4255
    }
4256
4257
    return $form;
4258
}
4259
4260
/**
4261
 * @return array
4262
 */
4263
function getUploadDocumentType()
4264
{
4265
    return array(
4266
        0 => get_lang('AllowFileOrText'),
4267
        1 => get_lang('AllowOnlyText'),
4268
        2 => get_lang('AllowOnlyFiles')
4269
    );
4270
}
4271
4272
/**
4273
 * @param array $courseInfo
4274
 * @param bool $showScore
4275
 * @param bool $studentDeleteOwnPublication
4276
 */
4277
function updateSettings($courseInfo, $showScore, $studentDeleteOwnPublication)
4278
{
4279
    $showScore = intval($showScore);
4280
    $courseId = api_get_course_int_id();
4281
    $main_course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
4282
    $table_course_setting = Database :: get_course_table(TOOL_COURSE_SETTING);
4283
4284
    $query = "UPDATE ".$main_course_table." SET show_score = '".$showScore."'
4285
              WHERE id = $courseId";
4286
    Database::query($query);
4287
4288
    /**
4289
     * Course data are cached in session so we need to update both the database
4290
     * and the session data
4291
     */
4292
    $_course['show_score'] = $showScore;
4293
    Session::write('_course', $courseInfo);
4294
4295
    // changing the tool setting: is a student allowed to delete his/her own document
4296
4297
    // counting the number of occurrences of this setting (if 0 => add, if 1 => update)
4298
    $query = "SELECT * FROM " . $table_course_setting . "
4299
              WHERE c_id = $courseId AND variable = 'student_delete_own_publication'";
4300
4301
    $result = Database::query($query);
4302
    $number_of_setting = Database::num_rows($result);
4303
4304
    if ($number_of_setting == 1) {
4305
        $query = "UPDATE " . $table_course_setting . " SET
4306
                  value='" . Database::escape_string($studentDeleteOwnPublication) . "'
4307
                  WHERE variable = 'student_delete_own_publication' AND c_id = $courseId";
4308
        Database::query($query);
4309
    } else {
4310
        $params = [
4311
            'c_id' => $courseId,
4312
            'variable' => 'student_delete_own_publication',
4313
            'value' => $studentDeleteOwnPublication,
4314
            'category' => 'work'
4315
        ];
4316
        Database::insert($table_course_setting, $params);
4317
    }
4318
}
4319
4320
/**
4321
 * @param int $item_id
4322
 * @param array $course_info
4323
 */
4324
function makeVisible($item_id, $course_info)
4325
{
4326
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4327
    $course_id = $course_info['real_id'];
4328
    $item_id = intval($item_id);
4329
4330
    $sql = "UPDATE $work_table SET accepted = 1
4331
            WHERE c_id = $course_id AND id = $item_id";
4332
    Database::query($sql);
4333
    api_item_property_update($course_info, 'work', $item_id, 'visible', api_get_user_id());
4334
}
4335
4336
/**
4337
 * @param int $item_id
4338
 * @param array $course_info
4339
 */
4340 View Code Duplication
function makeInvisible($item_id, $course_info)
4341
{
4342
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4343
    $item_id = intval($item_id);
4344
    $course_id = $course_info['real_id'];
4345
    $sql = "UPDATE  " . $work_table . "
4346
            SET accepted = 0
4347
            WHERE c_id = $course_id AND id = '" . $item_id . "'";
4348
    Database::query($sql);
4349
    api_item_property_update(
4350
        $course_info,
4351
        'work',
4352
        $item_id,
4353
        'invisible',
4354
        api_get_user_id()
4355
    );
4356
}
4357
4358
/**
4359
 * @param int $item_id
4360
 * @param string $path
4361
 * @param array $courseInfo
4362
 * @param int $groupId
4363
 * @param int $sessionId
4364
 * @return string
4365
 */
4366
function generateMoveForm($item_id, $path, $courseInfo, $groupId, $sessionId)
4367
{
4368
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4369
    $courseId = $courseInfo['real_id'];
4370
    $folders = array();
4371
    $session_id = intval($sessionId);
4372
    $groupId = intval($groupId);
4373
    $sessionCondition = empty($sessionId) ? " AND (session_id = 0 OR session_id IS NULL) " : " AND session_id='".$session_id."'";
4374
    $sql = "SELECT id, url, title
4375
            FROM $work_table
4376
            WHERE
4377
                c_id = $courseId AND
4378
                active IN (0, 1) AND
4379
                url LIKE '/%' AND
4380
                post_group_id = $groupId
4381
                $sessionCondition";
4382
    $res = Database::query($sql);
4383
    while ($folder = Database::fetch_array($res)) {
4384
        $title = empty($folder['title']) ? basename($folder['url']) : $folder['title'];
4385
        $folders[$folder['id']] = $title;
4386
    }
4387
    return build_work_move_to_selector($folders, $path, $item_id);
4388
}
4389
4390
/**
4391
 * @param int $workId
4392
 * @return string
4393
 */
4394
function showStudentList($workId)
4395
{
4396
    $columnModel = array(
4397
        array(
4398
            'name' => 'student',
4399
            'index' => 'student',
4400
            'width' => '350px',
4401
            'align' => 'left',
4402
            'sortable' => 'false',
4403
        ),
4404
        array(
4405
            'name' => 'works',
4406
            'index' => 'works',
4407
            'align' => 'center',
4408
            'sortable' => 'false',
4409
        ),
4410
    );
4411
    $token = null;
4412
4413
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student_list_overview&work_id='.$workId.'&'.api_get_cidreq();
4414
4415
    $columns = array(
4416
        get_lang('Students'),
4417
        get_lang('Works')
4418
    );
4419
4420
    $order = api_is_western_name_order() ? 'firstname' : 'lastname';
4421
    $params = array(
4422
        'autowidth' => 'true',
4423
        'height' => 'auto',
4424
        'rowNum' => 5,
4425
        'sortname' => $order,
4426
        'sortorder' => 'asc'
4427
    );
4428
4429
    $html = '<script>
4430
    $(function() {
4431
        '.Display::grid_js('studentList', $url, $columns, $columnModel, $params, array(), null, true).'
4432
        $("#workList").jqGrid(
4433
            "navGrid",
4434
            "#studentList_pager",
4435
            { edit: false, add: false, del: false },
4436
            { height:280, reloadAfterSubmit:false }, // edit options
4437
            { height:280, reloadAfterSubmit:false }, // add options
4438
            { width:500 } // search options
4439
        );
4440
    });
4441
    </script>';
4442
    $html .= Display::grid_html('studentList');
4443
    return $html;
4444
}
4445
4446
/**
4447
 * @param string $courseCode
4448
 * @param int $sessionId
4449
 * @param int $groupId
4450
 * @param int $start
4451
 * @param int $limit
4452
 * @param string $sidx
4453
 * @param string $sord
4454
 * @param $getCount
4455
 * @return array|int
4456
 */
4457
function getWorkUserList($courseCode, $sessionId, $groupId, $start, $limit, $sidx, $sord, $getCount = false)
4458
{
4459
    if (!empty($groupId)) {
4460
        $userList = GroupManager::get_users(
4461
            $groupId,
4462
            false,
4463
            $start,
4464
            $limit,
4465
            $getCount,
4466
            null,
4467
            $sidx,
4468
            $sord
4469
        );
4470
    } else {
4471
        $limitString = null;
4472 View Code Duplication
        if (!empty($start) && !empty($limit)) {
4473
            $start = intval($start);
4474
            $limit = intval($limit);
4475
            $limitString = " LIMIT $start, $limit";
4476
        }
4477
4478
        $orderBy = null;
4479
4480
        if (!empty($sidx) && !empty($sord)) {
4481
            if (in_array($sidx, array('firstname', 'lastname'))) {
4482
                $orderBy = "ORDER BY $sidx $sord";
4483
            }
4484
        }
4485
4486
        if (empty($sessionId)) {
4487
            $userList = CourseManager::get_user_list_from_course_code(
4488
                $courseCode,
4489
                $sessionId,
4490
                $limitString,
4491
                $orderBy ,
4492
                STUDENT,
4493
                $getCount
4494
            );
4495
        } else {
4496
            $userList = CourseManager::get_user_list_from_course_code(
4497
                $courseCode,
4498
                $sessionId,
4499
                $limitString,
4500
                $orderBy,
4501
                0,
4502
                $getCount
4503
            );
4504
        }
4505
4506
        if ($getCount == false) {
4507
            $userList = array_keys($userList);
4508
        }
4509
    }
4510
    return $userList;
4511
}
4512
4513
/**
4514
 * @param int $workId
4515
 * @param string $courseCode
4516
 * @param int $sessionId
4517
 * @param int $groupId
4518
 * @param int $start
4519
 * @param int $limit
4520
 * @param int $sidx
4521
 * @param string $sord
4522
 * @param bool $getCount
4523
 * @return array|int
4524
 */
4525
function getWorkUserListData(
4526
    $workId,
4527
    $courseCode,
4528
    $sessionId,
4529
    $groupId,
4530
    $start,
4531
    $limit,
4532
    $sidx,
4533
    $sord,
4534
    $getCount = false
4535
) {
4536
    $my_folder_data = get_work_data_by_id($workId);
4537
    $workParents = array();
4538
    if (empty($my_folder_data)) {
4539
        $workParents = getWorkList($workId, $my_folder_data, null);
4540
    }
4541
4542
    $workIdList = array();
4543
    if (!empty($workParents)) {
4544
        foreach ($workParents as $work) {
4545
            $workIdList[] = $work->id;
4546
        }
4547
    }
4548
4549
    $courseInfo = api_get_course_info($courseCode);
4550
4551
    $userList = getWorkUserList(
4552
        $courseCode,
4553
        $sessionId,
4554
        $groupId,
4555
        $start,
4556
        $limit,
4557
        $sidx,
4558
        $sord,
4559
        $getCount
4560
    );
4561
4562
    if ($getCount) {
4563
        return $userList;
4564
    }
4565
    $results = array();
4566
    if (!empty($userList)) {
4567
        foreach ($userList as $userId) {
0 ignored issues
show
Bug introduced by
The expression $userList of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
4568
            $user = api_get_user_info($userId);
4569
            $link = api_get_path(WEB_CODE_PATH).'work/student_work.php?'.api_get_cidreq().'&studentId='.$user['user_id'];
4570
            $url = Display::url(api_get_person_name($user['firstname'], $user['lastname']), $link);
4571
            $userWorks = 0;
4572
            if (!empty($workIdList)) {
4573
                $userWorks = getUniqueStudentAttempts(
4574
                    $workIdList,
4575
                    $groupId,
4576
                    $courseInfo['real_id'],
4577
                    $sessionId,
4578
                    $user['user_id']
4579
                );
4580
            }
4581
            $works = $userWorks." / ".count($workParents);
4582
            $results[] = array(
4583
                'student' => $url,
4584
                'works' => Display::url($works, $link),
4585
            );
4586
        }
4587
    }
4588
    return $results;
4589
}
4590
4591
/**
4592
 * @param int $id
4593
 * @param array $course_info
4594
 * @param bool $isCorrection
4595
 *
4596
 * @return bool
4597
 */
4598
function downloadFile($id, $course_info, $isCorrection)
4599
{
4600
    return getFile($id, $course_info, true, $isCorrection);
4601
}
4602
4603
/**
4604
 * @param int $id
4605
 * @param array $course_info
4606
 * @param bool $download
4607
 * @param bool $isCorrection
4608
 *
4609
 * @return bool
4610
 */
4611
function getFile($id, $course_info, $download = true, $isCorrection = false)
4612
{
4613
    $file = getFileContents($id, $course_info, 0, $isCorrection);
4614
    if (!empty($file) && is_array($file)) {
4615
        return DocumentManager::file_send_for_download(
4616
            $file['path'],
4617
            $download,
4618
            $file['title']
4619
        );
4620
    }
4621
4622
    return false;
4623
}
4624
4625
4626
/**
4627
 * Get the file contents for an assigment
4628
 * @param int $id
4629
 * @param array $course_info
4630
 * @param int Session ID
4631
 * @param $correction
4632
 *
4633
 * @return array|bool
4634
 */
4635
function getFileContents($id, $course_info, $sessionId = 0, $correction = false)
4636
{
4637
    $id = intval($id);
4638
    if (empty($course_info) || empty($id)) {
4639
        return false;
4640
    }
4641
    if (empty($sessionId)) {
4642
        $sessionId = api_get_session_id();
4643
    }
4644
4645
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4646
4647
    if (!empty($course_info['real_id'])) {
4648
        $sql = 'SELECT *
4649
                FROM '.$table.'
4650
                WHERE c_id = '.$course_info['real_id'].' AND id = "'.$id.'"';
4651
        $result = Database::query($sql);
4652
        if ($result && Database::num_rows($result)) {
4653
            $row = Database::fetch_array($result, 'ASSOC');
4654
4655
            if ($correction) {
4656
                $row['url'] = $row['url_correction'];
4657
            }
4658
4659
            if (empty($row['url'])) {
4660
                return false;
4661
            }
4662
4663
            $full_file_name = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.$row['url'];
4664
4665
            $item_info = api_get_item_property_info(
4666
                api_get_course_int_id(),
4667
                'work',
4668
                $row['id'],
4669
                $sessionId
4670
            );
4671
4672
            allowOnlySubscribedUser(
4673
                api_get_user_id(),
4674
                $row['parent_id'],
4675
                $course_info['real_id']
4676
            );
4677
4678
            if (empty($item_info)) {
4679
                api_not_allowed();
4680
            }
4681
4682
            /*
4683
            field show_score in table course :
4684
                0 =>    New documents are visible for all users
4685
                1 =>    New documents are only visible for the teacher(s)
4686
            field visibility in table item_property :
4687
                0 => eye closed, invisible for all students
4688
                1 => eye open
4689
            field accepted in table c_student_publication :
4690
                0 => eye closed, invisible for all students
4691
                1 => eye open
4692
            ( We should have visibility == accepted, otherwise there is an
4693
            inconsistency in the Database)
4694
            field value in table c_course_setting :
4695
                0 => Allow learners to delete their own publications = NO
4696
                1 => Allow learners to delete their own publications = YES
4697
4698
            +------------------+-------------------------+------------------------+
4699
            |Can download work?| doc visible for all = 0 | doc visible for all = 1|
4700
            +------------------+-------------------------+------------------------+
4701
            |  visibility = 0  | editor only             | editor only            |
4702
            |                  |                         |                        |
4703
            +------------------+-------------------------+------------------------+
4704
            |  visibility = 1  | editor                  | editor                 |
4705
            |                  | + owner of the work     | + any student          |
4706
            +------------------+-------------------------+------------------------+
4707
            (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
4708
            */
4709
4710
            $work_is_visible = $item_info['visibility'] == 1 && $row['accepted'] == 1;
4711
            $doc_visible_for_all = ($course_info['show_score'] == 1);
4712
4713
            $is_editor = api_is_allowed_to_edit(true, true, true);
4714
            $student_is_owner_of_work = user_is_author($row['id'], $row['user_id']);
4715
4716
            if ($is_editor ||
4717
                ($student_is_owner_of_work) ||
4718
                ($doc_visible_for_all && $work_is_visible)
4719
            ) {
4720
                $title = $row['title'];
4721
                if ($correction) {
4722
                    $title = $row['title_correction'];
4723
                }
4724
                if (array_key_exists('filename', $row) && !empty($row['filename'])) {
4725
                    $title = $row['filename'];
4726
                }
4727
4728
                $title = str_replace(' ', '_', $title);
4729
                Event::event_download($title);
4730
                if (Security::check_abs_path(
4731
                    $full_file_name,
4732
                    api_get_path(SYS_COURSE_PATH).api_get_course_path().'/')
4733
                ) {
4734
                    return array(
4735
                        'path' => $full_file_name,
4736
                        'title' => $title,
4737
                        'title_correction' => $row['title_correction']
4738
                    );
4739
                }
4740
            }
4741
        }
4742
    }
4743
4744
    return false;
4745
}
4746
4747
/**
4748
 * @param int $userId
4749
 * @param array $courseInfo
4750
 * @param string $format
4751
 * @return bool
4752
 */
4753
function exportAllWork($userId, $courseInfo, $format = 'pdf')
4754
{
4755
    $userInfo = api_get_user_info($userId);
4756
    if (empty($userInfo) || empty($courseInfo)) {
4757
        return false;
4758
    }
4759
4760
    $workPerUser = getWorkPerUser($userId);
4761
4762
    switch ($format) {
4763
        case 'pdf':
4764
            if (!empty($workPerUser)) {
4765
                $pdf = new PDF();
4766
4767
                $content = null;
4768
                foreach ($workPerUser as $work) {
4769
                    $work = $work['work'];
4770
                    foreach ($work->user_results as $userResult) {
4771
                        //var_dump($userResult);exit;
4772
                        $content .= $userResult['title'];
4773
                        // No need to use api_get_local_time()
4774
                        $content .= $userResult['sent_date'];
4775
                        $content .= $userResult['qualification'];
4776
                        $content .= $userResult['description'];
4777
                        //$content .= getWorkComments($userResult);
4778
                    }
4779
                }
4780
4781
                if (!empty($content)) {
4782
                    $pdf->content_to_pdf(
4783
                        $content,
4784
                        null,
4785
                        api_replace_dangerous_char($userInfo['complete_name']),
4786
                        $courseInfo['code']
4787
                    );
4788
                }
4789
            }
4790
            break;
4791
    }
4792
}
4793
4794
/**
4795
 * @param int $workId
4796
 * @param array $courseInfo
4797
 * @param int $sessionId
4798
 * @param string $format
4799
 * @return bool
4800
 */
4801
function exportAllStudentWorkFromPublication(
4802
    $workId,
4803
    $courseInfo,
4804
    $sessionId,
4805
    $format = 'pdf'
4806
) {
4807
    if (empty($courseInfo)) {
4808
        return false;
4809
    }
4810
4811
    $workData = get_work_data_by_id($workId);
4812
4813
    if (empty($workData)) {
4814
        return false;
4815
    }
4816
4817
    $assignment = get_work_assignment_by_id($workId);
4818
4819
    $courseCode = $courseInfo['code'];
4820
    $header = get_lang('Course').': '.$courseInfo['title'];
4821
    $teachers = CourseManager::get_teacher_list_from_course_code_to_string(
4822
        $courseCode
4823
    );
4824
4825
    if (!empty($sessionId)) {
4826
        $sessionInfo = api_get_session_info($sessionId);
4827
        if (!empty($sessionInfo)) {
4828
            $header .= ' - ' . $sessionInfo['name'];
4829
            $header .= '<br />' . $sessionInfo['description'];
4830
            $teachers = SessionManager::getCoachesByCourseSessionToString(
4831
                $sessionId,
4832
                $courseInfo['real_id']
4833
            );
4834
        }
4835
    }
4836
4837
    $header .= '<br />'.get_lang('Teachers').': '.$teachers.'<br />';
4838
    $header .= '<br />'.get_lang('Date').': '.api_get_local_time().'<br />';
4839
    $header .= '<br />'.get_lang('WorkName').': '.$workData['title'].'<br />';
4840
4841
    $content = null;
4842
    $expiresOn = null;
4843
4844
    if (!empty($assignment) && isset($assignment['expires_on'])) {
4845
        $content .= '<br /><strong>' . get_lang('ExpirationDate') . '</strong>: ' . api_get_local_time($assignment['expires_on']);
4846
        $expiresOn = api_get_local_time($assignment['expires_on']);
4847
    }
4848
4849
    if (!empty($workData['description'])) {
4850
        $content .= '<br /><strong>' . get_lang('Description') . '</strong>: ' . $workData['description'];
4851
    }
4852
4853
    $workList = get_work_user_list(null, null, null, null, $workId);
4854
4855
    switch ($format) {
4856
        case 'pdf':
4857
            if (!empty($workList)) {
4858
4859
                $table = new HTML_Table(array('class' => 'data_table'));
4860
                $headers = array(
4861
                    get_lang('Name'),
4862
                    get_lang('User'),
4863
                    get_lang('HandOutDateLimit'),
4864
                    get_lang('SentDate'),
4865
                    get_lang('FileName'),
4866
                    get_lang('Score'),
4867
                    get_lang('Feedback')
4868
                );
4869
4870
                $column = 0;
4871
                foreach($headers as $header) {
4872
                    $table->setHeaderContents(0, $column, $header);
4873
                    $column++;
4874
                }
4875
4876
                $row = 1;
4877
4878
                //$pdf->set_custom_header($header);
4879
                foreach ($workList as $work) {
4880
                    $content .= '<hr />';
4881
                    // getWorkComments need c_id
4882
                    $work['c_id'] = $courseInfo['real_id'];
4883
4884
                    //$content .= get_lang('Date').': '.api_get_local_time($work['sent_date_from_db']).'<br />';
4885
                    $score = null;
4886
                    if (!empty($work['qualification_only'])) {
4887
                        $score = $work['qualification_only'];
4888
                    }
4889
                    //$content .= get_lang('Description').': '.$work['description'].'<br />';
4890
                    $comments = getWorkComments($work);
4891
4892
                    $feedback = null;
4893
                    if (!empty($comments)) {
4894
                        $content .= '<h4>'.get_lang('Feedback').': </h4>';
4895
                        foreach ($comments as $comment) {
4896
                            $feedback .= get_lang('User').': '.api_get_person_name(
4897
                                    $comment['firstname'],
4898
                                    $comment['lastname']
4899
                                ).'<br />';
4900
                            $feedback .= $comment['comment'].'<br />';
4901
                        }
4902
                    }
4903
4904
                    $table->setCellContents($row, 0, strip_tags($workData['title']));
4905
                    $table->setCellContents($row, 1, api_get_person_name(strip_tags($work['firstname']), strip_tags($work['lastname'])));
4906
                    $table->setCellContents($row, 2, $expiresOn);
4907
                    $table->setCellContents($row, 3, api_get_local_time($work['sent_date_from_db']));
4908
                    $table->setCellContents($row, 4, strip_tags($work['title']));
4909
                    $table->setCellContents($row, 5, $score);
4910
                    $table->setCellContents($row, 6, $feedback);
4911
4912
                    $row++;
4913
                }
4914
4915
                $content = $table->toHtml();
4916
4917
                if (!empty($content)) {
4918
                    $params = array(
4919
                        'filename' => $workData['title'] . '_' . api_get_local_time(),
4920
                        'pdf_title' => api_replace_dangerous_char($workData['title']),
4921
                        'course_code' => $courseInfo['code'],
4922
                        'add_signatures' => false
4923
                    );
4924
                    $pdf = new PDF('A4', null, $params);
4925
                    $pdf->html_to_pdf_with_template($content);
4926
                }
4927
                exit;
4928
            }
4929
            break;
4930
    }
4931
}
4932
4933
/**
4934
 * Downloads all user files per user
4935
 * @param int $userId
4936
 * @param array $courseInfo
4937
 * @return bool
4938
 */
4939
function downloadAllFilesPerUser($userId, $courseInfo)
4940
{
4941
    $userInfo = api_get_user_info($userId);
4942
4943
    if (empty($userInfo) || empty($courseInfo)) {
4944
        return false;
4945
    }
4946
4947
    $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
4948
    $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
4949
4950
    $zip  = new PclZip($tempZipFile);
4951
4952
    $workPerUser = getWorkPerUser($userId);
4953
4954
    if (!empty($workPerUser)) {
4955
        $files = array();
4956
        foreach ($workPerUser as $work) {
4957
            $work = $work['work'];
4958
            foreach ($work->user_results as $userResult) {
4959
                if (empty($userResult['url']) || empty($userResult['contains_file'])) {
4960
                    continue;
4961
                }
4962
                $data = getFileContents($userResult['id'], $courseInfo);
4963
                if (!empty($data) && isset($data['path'])) {
4964
                    $files[basename($data['path'])] = array(
4965
                        'title' => $data['title'],
4966
                        'path' => $data['path']
4967
                    );
4968
                }
4969
            }
4970
        }
4971
4972
        if (!empty($files)) {
4973
            Session::write('files', $files);
4974
            foreach ($files as $data) {
4975
                $zip->add(
4976
                    $data['path'],
4977
                    PCLZIP_OPT_REMOVE_PATH,
4978
                    $coursePath,
4979
                    PCLZIP_CB_PRE_ADD,
4980
                    'preAddAllWorkStudentCallback'
4981
                );
4982
            }
4983
        }
4984
4985
        // Start download of created file
4986
        $name = basename(api_replace_dangerous_char($userInfo['complete_name'])).'.zip';
4987
        Event::event_download($name.'.zip (folder)');
4988 View Code Duplication
        if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) {
4989
            DocumentManager::file_send_for_download($tempZipFile, true, $name);
4990
            @unlink($tempZipFile);
4991
            exit;
4992
        }
4993
    }
4994
    exit;
4995
}
4996
4997
/**
4998
 * @param $p_event
4999
 * @param array $p_header
5000
 * @return int
5001
 */
5002 View Code Duplication
function preAddAllWorkStudentCallback($p_event, &$p_header)
5003
{
5004
    $files = Session::read('files');
5005
    if (isset($files[basename($p_header['stored_filename'])])) {
5006
        $p_header['stored_filename'] = $files[basename($p_header['stored_filename'])]['title'];
5007
        return 1;
5008
    }
5009
    return 0;
5010
}
5011
5012
/**
5013
 * Get all work created by a user
5014
 * @param int $user_id
5015
 * @param int $courseId
5016
 * @param int $sessionId
5017
 * @return array
5018
 */
5019
function getWorkCreatedByUser($user_id, $courseId, $sessionId)
5020
{
5021
    $items = api_get_item_property_list_by_tool_by_user(
5022
        $user_id,
5023
        'work',
5024
        $courseId,
5025
        $sessionId
5026
    );
5027
5028
    $forumList = array();
5029 View Code Duplication
    if (!empty($items)) {
5030
        foreach ($items as $forum) {
5031
            $item = get_work_data_by_id(
5032
                $forum['ref'],
5033
                $courseId,
5034
                $sessionId
5035
            );
5036
5037
            $forumList[] = array(
5038
                $item['title'],
5039
                api_get_local_time($forum['insert_date']),
5040
                api_get_local_time($forum['lastedit_date'])
5041
            );
5042
        }
5043
    }
5044
5045
    return $forumList;
5046
}
5047
5048
/**
5049
 * @param array $courseInfo
5050
 * @param int $workId
5051
 * @return bool
5052
 */
5053
function protectWork($courseInfo, $workId)
5054
{
5055
    $userId = api_get_user_id();
5056
    $groupId = api_get_group_id();
5057
    $sessionId = api_get_session_id();
5058
    $workData = get_work_data_by_id($workId);
5059
5060
    if (empty($workData) || empty($courseInfo)) {
5061
        api_not_allowed(true);
5062
    }
5063
5064
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
5065
        return true;
5066
    }
5067
5068
    $workId = $workData['id'];
5069
5070
    if ($workData['active'] != 1) {
5071
        api_not_allowed(true);
5072
    }
5073
5074
    $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $sessionId);
5075
5076
    if ($visibility != 1) {
5077
        api_not_allowed(true);
5078
    }
5079
5080
    allowOnlySubscribedUser($userId, $workId, $courseInfo['real_id']);
5081
5082
    if (!empty($groupId)) {
5083
        $showWork = GroupManager::user_has_access(
5084
            $userId,
5085
            $groupId,
5086
            GroupManager::GROUP_TOOL_WORK
5087
        );
5088
        if (!$showWork) {
5089
            api_not_allowed(true);
5090
        }
5091
    }
5092
}
5093