Completed
Push — 1.11.x ( 651907...6c7c62 )
by José
30:00
created

work.lib.php ➔ updateWork()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nc 1
nop 4
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
use Chamilo\CourseBundle\Entity\CStudentPublication;
6
7
/**
8
 *  @package chamilo.work
9
 *  @author Thomas, Hugues, Christophe - original version
10
 *  @author Patrick Cool <[email protected]>, Ghent University -
11
 * ability for course admins to specify wether uploaded documents are visible or invisible by default.
12
 *  @author Roan Embrechts, code refactoring and virtual course support
13
 *  @author Frederic Vauthier, directories management
14
 *  @author Julio Montoya <[email protected]> BeezNest 2011 LOTS of bug fixes
15
 *  @todo   this lib should be convert in a static class and moved to main/inc/lib
16
 */
17
18
/**
19
 * Displays action links (for admins, authorized groups members and authorized students)
20
 * @param   string  Current dir
21
 * @param   integer Whether to show tool options
22
 * @param   integer Whether to show upload form option
23
 * @return  void
24
 */
25
function display_action_links($id, $cur_dir_path, $action)
26
{
27
    global $gradebook;
28
29
    $id = $my_back_id = intval($id);
30
    if ($action == 'list') {
31
        $my_back_id = 0;
32
    }
33
34
    $display_output = '';
35
    $origin = isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '';
36
37
    if (!empty($id)) {
38
        $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&gradebook='.$gradebook.'&id='.$my_back_id.'">'.
39
            Display::return_icon('back.png', get_lang('BackToWorksList'),'',ICON_SIZE_MEDIUM).'</a>';
40
    }
41
42
    if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath') {
43
        // Create dir
44
        if (empty($id)) {
45
            $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=create_dir&gradebook='.$gradebook.'">';
46
            $display_output .= Display::return_icon('new_work.png', get_lang('CreateAssignment'),'',ICON_SIZE_MEDIUM).'</a>';
47
        }
48
        if (empty($id)) {
49
            // Options
50
            $display_output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=settings&gradebook='.$gradebook.'">';
51
            $display_output .= Display::return_icon('settings.png', get_lang('EditToolOptions'),'',ICON_SIZE_MEDIUM).'</a>';
52
        }
53
        $display_output .= '<a id="open-view-list" href="#">' . Display::return_icon('listwork.png', get_lang('ViewStudents'),'',ICON_SIZE_MEDIUM) . '</a>';
54
55
    }
56
57
    if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath' && api_is_allowed_to_session_edit(false, true)) {
58
        // Delete all files
59
        if (api_get_setting('permanently_remove_deleted_files') == 'true'){
60
            $message = get_lang('ConfirmYourChoiceDeleteAllfiles');
61
        } else {
62
            $message = get_lang('ConfirmYourChoice');
63
        }
64
    }
65
66
    if ($display_output != '') {
67
        echo '<div class="actions">';
68
        echo $display_output;
69
        echo '</div>';
70
    }
71
}
72
73
/**
74
 * Returns a form displaying all options for this tool.
75
 * These are
76
 * - make all files visible / invisible
77
 * - set the default visibility of uploaded files
78
 * @param $defaults
79
 * @return string The HTML form
80
 */
81
function settingsForm($defaults)
82
{
83
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
84
85
    if (!$is_allowed_to_edit) {
86
        return;
87
    }
88
89
    $url = api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'&action=settings';
90
    $form = new FormValidator('edit_settings', 'post', $url);
91
    $form->addElement('hidden', 'changeProperties', 1);
92
    $form->addElement('header', get_lang('EditToolOptions'));
93
94
    $group = array(
95
        $form->createElement('radio', 'show_score', null, get_lang('NewVisible'), 0),
96
        $form->createElement('radio', 'show_score', null, get_lang('NewUnvisible'), 1)
97
    );
98
    $form->addGroup($group, '', get_lang('DefaultUpload'));
99
100
    $group = array(
101
        $form->createElement('radio', 'student_delete_own_publication', null, get_lang('Yes'), 1),
102
        $form->createElement('radio', 'student_delete_own_publication', null, get_lang('No'), 0)
103
    );
104
    $form->addGroup($group, '', get_lang('StudentAllowedToDeleteOwnPublication'));
105
    $form->addButtonSave(get_lang('Save'));
106
    $form->setDefaults($defaults);
107
108
    return $form->returnForm();
109
}
110
111
/**
112
 * converts 1-9 to 01-09
113
 */
114
function two_digits($number)
115
{
116
    $number = (int)$number;
117
    return ($number < 10) ? '0'.$number : $number;
118
}
119
120
/**
121
 * @param string $path
122
 * @param int $courseId
123
 *
124
 * @return array
125
 */
126 View Code Duplication
function get_work_data_by_path($path, $courseId = null)
127
{
128
    $path = Database::escape_string($path);
129
    if (empty($courseId)) {
130
        $courseId = api_get_course_int_id();
131
    } else {
132
        $courseId = intval($courseId);
133
    }
134
135
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
136
    $sql = "SELECT *  FROM  ".$work_table."
137
            WHERE url = '$path' AND c_id = $courseId ";
138
    $result = Database::query($sql);
139
    $return = array();
140
    if (Database::num_rows($result)) {
141
        $return = Database::fetch_array($result, 'ASSOC');
142
    }
143
144
    return $return;
145
}
146
147
/**
148
 * @param int $id
149
 * @param int $courseId
150
 * @param int $sessionId
151
 * @return array
152
 */
153
function get_work_data_by_id($id, $courseId = null, $sessionId = null)
154
{
155
    $id = intval($id);
156
157
    if (!empty($courseId)) {
158
        $courseId = intval($courseId);
159
    } else {
160
        $courseId = api_get_course_int_id();
161
    }
162
163
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
164
165
    $sessionCondition = null;
166
    if (!empty($sessionId)) {
167
        $sessionCondition = api_get_session_condition($sessionId, true);
168
    }
169
170
    $sql = "SELECT * FROM $table
171
            WHERE
172
                id = $id AND c_id = $courseId
173
                $sessionCondition";
174
    $result = Database::query($sql);
175
    $work = array();
176
    if (Database::num_rows($result)) {
177
        $work = Database::fetch_array($result, 'ASSOC');
178
        if (empty($work['title'])) {
179
            $work['title'] = basename($work['url']);
180
        }
181
        $work['download_url'] = api_get_path(WEB_CODE_PATH).'work/download.php?id='.$work['id'].'&'.api_get_cidreq();
182
        $work['view_url'] = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&'.api_get_cidreq();
183
        $work['show_url'] = api_get_path(WEB_CODE_PATH).'work/show_file.php?id='.$work['id'].'&'.api_get_cidreq();
184
        $work['show_content'] = '';
185
        if ($work['contains_file']) {
186
            $fileInfo = pathinfo($work['title']);
187
            if (is_array($fileInfo) &&
188
                !empty($fileInfo['extension']) &&
189
                in_array($fileInfo['extension'], array('jpg', 'png', 'gif'))
190
            ) {
191
                $work['show_content'] = '<img src="'.$work['show_url'].'"/>';
192
            }
193
        }
194
195
        $fieldValue = new ExtraFieldValue('work');
196
        $work['extra'] = $fieldValue->getAllValuesForAnItem(
197
            $id,
198
            true
199
        );
200
201
    }
202
203
    return $work;
204
}
205
206
/**
207
 * @param int $user_id
208
 * @param int $work_id
209
 *
210
 * @return int
211
 */
212
function get_work_count_by_student($user_id, $work_id)
213
{
214
    $user_id = intval($user_id);
215
    $work_id = intval($work_id);
216
    $course_id = api_get_course_int_id();
217
    $session_id = api_get_session_id();
218
    $sessionCondition = api_get_session_condition($session_id);
219
220
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
221
    $sql = "SELECT COUNT(*) as count
222
            FROM  $table
223
            WHERE
224
                c_id = $course_id AND
225
                parent_id = $work_id AND
226
                user_id = $user_id AND
227
                active IN (0, 1)
228
                $sessionCondition";
229
    $result = Database::query($sql);
230
    $return = 0;
231
    if (Database::num_rows($result)) {
232
        $return = Database::fetch_row($result, 'ASSOC');
233
        $return = intval($return[0]);
234
    }
235
236
    return $return;
237
}
238
239
/**
240
 * @param int $id
241
 * @param int $courseId
242
 *
243
 * @return array
244
 */
245 View Code Duplication
function get_work_assignment_by_id($id, $courseId = null)
246
{
247
    if (empty($courseId)) {
248
        $courseId = api_get_course_int_id();
249
    } else {
250
        $courseId = intval($courseId);
251
    }
252
    $id = intval($id);
253
254
    $table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
255
    $sql = "SELECT * FROM $table
256
            WHERE c_id = $courseId AND publication_id = $id";
257
    $result = Database::query($sql);
258
    $return = array();
259
    if (Database::num_rows($result)) {
260
        $return = Database::fetch_array($result, 'ASSOC');
261
    }
262
263
    return $return;
264
}
265
266
/**
267
 * @param int $id
268
 * @param array $my_folder_data
269
 * @param string $add_in_where_query
270
 *
271
 * @return array
272
 */
273
function getWorkList($id, $my_folder_data, $add_in_where_query = null)
274
{
275
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
276
277
    $course_id = api_get_course_int_id();
278
    $session_id = api_get_session_id();
279
    $condition_session = api_get_session_condition($session_id);
280
    $group_id = api_get_group_id();
281
282
    $groupIid = 0;
283
    if ($group_id) {
284
        $groupInfo = GroupManager::get_group_properties($group_id);
285
        $groupIid = $groupInfo['iid'];
286
    }
287
288
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
289
290
    $linkInfo = GradebookUtils::isResourceInCourseGradebook(
291
        api_get_course_id(),
292
        3,
293
        $id,
294
        api_get_session_id()
295
    );
296
297
    if ($linkInfo) {
298
        $workInGradeBookLinkId = $linkInfo['id'];
299
        if ($workInGradeBookLinkId) {
300
            if ($is_allowed_to_edit) {
301
                if (intval($my_folder_data['qualification']) == 0) {
302
                    Display::display_warning_message(
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_warning_message() has been deprecated with message: use Display::addFlash with Display::return_message

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

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

Loading history...
303
                        get_lang('MaxWeightNeedToBeProvided')
304
                    );
305
                }
306
            }
307
        }
308
    }
309
310
    $contains_file_query = '';
311
312
    // Get list from database
313
    if ($is_allowed_to_edit) {
314
        $active_condition = ' active IN (0, 1)';
315
        $sql = "SELECT * FROM $work_table
316
                WHERE
317
                    c_id = $course_id
318
                    $add_in_where_query
319
                    $condition_session AND
320
                    $active_condition AND
321
                    (parent_id = 0)
322
                    $contains_file_query AND 
323
                    post_group_id = $groupIid
324
                ORDER BY sent_date DESC";
325
    } else {
326 View Code Duplication
        if (!empty($group_id)) {
327
            // set to select only messages posted by the user's group
328
            $group_query = " WHERE c_id = $course_id AND post_group_id = $groupIid";
329
            $subdirs_query = " AND parent_id = 0";
330
        } else {
331
            $group_query = " WHERE c_id = $course_id AND (post_group_id = '0' OR post_group_id is NULL) ";
332
            $subdirs_query = " AND parent_id = 0";
333
        }
334
        //@todo how we can active or not an assignment?
335
        $active_condition = ' AND active IN (1, 0)';
336
        $sql = "SELECT * FROM  $work_table
337
                $group_query
338
                $subdirs_query
339
                $add_in_where_query
340
                $active_condition
341
                $condition_session
342
                ORDER BY title";
343
    }
344
345
    $work_parents = array();
346
347
    $sql_result = Database::query($sql);
348
    if (Database::num_rows($sql_result)) {
349
        while ($work = Database::fetch_object($sql_result)) {
350
            if ($work->parent_id == 0) {
351
                $work_parents[] = $work;
352
            }
353
        }
354
    }
355
356
    return $work_parents;
357
}
358
359
/**
360
 * @param int $userId
361
 * @return array
362
 */
363
function getWorkPerUser($userId)
364
{
365
    $works = getWorkList(null, null, null);
366
    $result = array();
367
    if (!empty($works)) {
368
        foreach ($works as $workData) {
369
            $workId = $workData->id;
370
            $result[$workId]['work'] = $workData;
371
            $result[$workId]['work']->user_results = get_work_user_list(
372
                0,
373
                100,
374
                null,
375
                null,
376
                $workId,
377
                null,
378
                $userId
379
            );
380
        }
381
    }
382
    return $result;
383
}
384
385
/**
386
 * @param int $workId
387
 * @param int $groupId
388
 * @param int $course_id
389
 * @param int $sessionId
390
 * @return mixed
391
 */
392
function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
393
{
394
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
395
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
396
    $course_id = intval($course_id);
397
    $workId = intval($workId);
398
    $sessionId = intval($sessionId);
399
    $groupId = intval($groupId);
400
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
401
402
    $groupIid = 0;
403
    if ($groupId) {
404
        $groupInfo = GroupManager::get_group_properties($groupId);
405
        $groupIid = $groupInfo['iid'];
406
    }
407
408
    $sql = "SELECT count(DISTINCT u.user_id)
409
            FROM $work_table w
410
            INNER JOIN $user_table u
411
            ON w.user_id = u.user_id
412
            WHERE
413
                w.c_id = $course_id
414
                $sessionCondition AND
415
                w.parent_id = $workId AND
416
                w.post_group_id = $groupIid AND
417
                w.active IN (0, 1)
418
            ";
419
420
    $res_document = Database::query($sql);
421
    $rowCount = Database::fetch_row($res_document);
422
423
    return $rowCount[0];
424
}
425
426
/**
427
 * @param mixed $workId
428
 * @param int $groupId
429
 * @param int $course_id
430
 * @param int $sessionId
431
 * @param int $userId user id to filter
432
 * @param array $onlyUserList only parse this user list
433
 * @return mixed
434
 */
435
function getUniqueStudentAttempts(
436
    $workId,
437
    $groupId,
438
    $course_id,
439
    $sessionId,
440
    $userId = null,
441
    $onlyUserList = array()
442
) {
443
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
444
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
445
446
    $course_id = intval($course_id);
447
    $workCondition = null;
448
    if (is_array($workId)) {
449
        $workId = array_map('intval', $workId);
450
        $workId = implode("','", $workId);
451
        $workCondition = " w.parent_id IN ('".$workId."') AND";
452
    } else {
453
        $workId = intval($workId);
454
        $workCondition = " w.parent_id = ".$workId." AND";
455
    }
456
457
    $sessionId = intval($sessionId);
458
    $groupId = intval($groupId);
459
    $studentCondition = null;
460
461
    if (!empty($onlyUserList)) {
462
        $onlyUserList = array_map('intval', $onlyUserList);
463
        $studentCondition = "AND u.user_id IN ('".implode("', '", $onlyUserList)."') ";
464
    } else {
465
        if (empty($userId)) {
466
            return 0;
467
        }
468
    }
469
470
    $groupIid = 0;
471
    if ($groupId) {
472
        $groupInfo = GroupManager::get_group_properties($groupId);
473
        $groupIid = $groupInfo['iid'];
474
    }
475
476
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
477
478
    $sql = "SELECT count(*) FROM (
479
                SELECT count(*), w.parent_id
480
                FROM $work_table w
481
                INNER JOIN $user_table u
482
                ON w.user_id = u.user_id
483
                WHERE
484
                    w.filetype = 'file' AND
485
                    w.c_id = $course_id
486
                    $sessionCondition AND
487
                    $workCondition
488
                    w.post_group_id = $groupIid AND
489
                    w.active IN (0, 1) $studentCondition
490
                ";
491
    if (!empty($userId)) {
492
        $userId = intval($userId);
493
        $sql .= " AND u.user_id = ".$userId;
494
    }
495
    $sql .= " GROUP BY u.user_id, w.parent_id) as t";
496
    $result = Database::query($sql);
497
    $row = Database::fetch_row($result);
498
499
    return $row[0];
500
}
501
502
/**
503
 * Shows the work list (student view)
504
 * @return string
505
 */
506
function showStudentWorkGrid()
507
{
508
    $courseInfo = api_get_course_info();
509
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student&'.api_get_cidreq();
510
511
    $columns = array(
512
        get_lang('Type'),
513
        get_lang('Title'),
514
        get_lang('HandOutDateLimit'),
515
        get_lang('Feedback'),
516
        get_lang('LastUpload')
517
    );
518
519
    $columnModel = array(
520
        array('name'=>'type', 'index'=>'type', 'width'=>'30', 'align'=>'center', 'sortable' => 'false'),
521
        array('name'=>'title', 'index'=>'title', 'width'=>'250',   'align'=>'left'),
522
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
523
        array('name'=>'feedback', 'index'=>'feedback', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
524
        array('name'=>'last_upload', 'index'=>'feedback', 'width'=>'125',  'align'=>'center', 'sortable'=>'false')
525
    );
526
527 View Code Duplication
    if ($courseInfo['show_score'] == 0) {
528
        $columnModel[] = array(
529
            'name' => 'others',
530
            'index' => 'others',
531
            'width' => '80',
532
            'align' => 'left',
533
            'sortable' => 'false'
534
        );
535
        $columns[] = get_lang('Others');
536
    }
537
538
    $params = array(
539
        'autowidth' => 'true',
540
        'height' => 'auto'
541
    );
542
543
    $html = '<script>
544
        $(function() {
545
            '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
546
        });
547
    </script>';
548
549
    $html .= Display::grid_html('workList');
550
    return $html;
551
}
552
553
/**
554
 * Shows the work list (teacher view)
555
 * @return string
556
 */
557
function showTeacherWorkGrid()
558
{
559
    $columnModel = array(
560
        array('name'=>'type', 'index'=>'type', 'width'=>'35', 'align'=>'center', 'sortable' => 'false'),
561
        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left', 'wrap_cell' => "true"),
562
        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'125',  'align'=>'center'),
563
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'125',  'align'=>'center'),
564
        array('name'=>'amount', 'index'=>'amount', 'width'=>'110',  'align'=>'center', 'sortable' => 'false'),
565
        array('name'=>'actions', 'index'=>'actions', 'width'=>'110', 'align'=>'left', 'sortable'=>'false')
566
    );
567
568
    $token = null;
569
570
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
571
    $deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
572
573
    $columns = array(
574
        get_lang('Type'),
575
        get_lang('Title'),
576
        get_lang('SentDate'),
577
        get_lang('HandOutDateLimit'),
578
        get_lang('AmountSubmitted'),
579
        get_lang('Actions')
580
    );
581
582
    $params = array(
583
        'multiselect' => true,
584
        'autowidth' => 'true',
585
        'height' => 'auto'
586
    );
587
588
    $html = '<script>
589
    $(function() {
590
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
591
        $("#workList").jqGrid(
592
            "navGrid",
593
            "#workList_pager",
594
            { edit: false, add: false, del: true },
595
            { height:280, reloadAfterSubmit:false }, // edit options
596
            { height:280, reloadAfterSubmit:false }, // add options
597
            { reloadAfterSubmit:false, url: "'.$deleteUrl.'" }, // del options
598
            { width:500 } // search options
599
        );
600
    });
601
    </script>';
602
    $html .= Display::grid_html('workList');
603
    return $html;
604
}
605
606
/**
607
 * Builds the form thats enables the user to
608
 * select a directory to browse/upload in
609
 * This function has been copied from the document/document.inc.php library
610
 *
611
 * @param array $folders
612
 * @param string $curdirpath
613
 * @param string $group_dir
614
 * @return string html form
615
 */
616
// TODO: This function is a candidate for removal, it is not used anywhere.
617
function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
618
{
619
    $form = '<form name="selector" action="'.api_get_self().'?'.api_get_cidreq().'" method="POST">';
620
    $form .= get_lang('CurrentDirectory').' <select name="curdirpath" onchange="javascript: document.selector.submit();">';
621
    //group documents cannot be uploaded in the root
622
    if ($group_dir == '') {
623
        $form .= '<option value="/">/ ('.get_lang('Root').')</option>';
624
        if (is_array($folders)) {
625
            foreach ($folders as $folder) {
626
                $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
627
                $form .= '<option'.$selected.' value="'.$folder.'">'.$folder.'</option>'."\n";
628
            }
629
        }
630
    } else {
631
        foreach ($folders as $folder) {
632
            $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
633
            $display_folder = substr($folder, strlen($group_dir));
634
            $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
635
            $form .= '<option'.$selected.' value="'.$folder.'">'.$display_folder.'</option>'."\n";
636
        }
637
    }
638
639
    $form .= '</select>';
640
    $form .= '<noscript><input type="submit" name="change_path" value="'.get_lang('Ok').'" /></noscript>';
641
    $form .= '</form>';
642
643
    return $form;
644
}
645
646
/**
647
 * Builds the form thats enables the user to
648
 * move a document from one directory to another
649
 * This function has been copied from the document/document.inc.php library
650
 *
651
 * @param array $folders
652
 * @param string $curdirpath
653
 * @param string $move_file
654
 * @param string $group_dir
655
 * @return string html form
656
 */
657
function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_dir = '')
658
{
659
    $course_id = api_get_course_int_id();
660
    $move_file = intval($move_file);
661
    $tbl_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
662
    $sql = "SELECT title, url FROM $tbl_work
663
            WHERE c_id = $course_id AND id ='".$move_file."'";
664
    $result = Database::query($sql);
665
    $row = Database::fetch_array($result, 'ASSOC');
666
    $title = empty($row['title']) ? basename($row['url']) : $row['title'];
667
668
    $form = new FormValidator(
669
        'move_to_form',
670
        'post',
671
        api_get_self().'?'.api_get_cidreq().'&curdirpath='.Security::remove_XSS($curdirpath)
672
    );
673
674
    $form->addHeader(get_lang('MoveFile').' - '.Security::remove_XSS($title));
675
    $form->addHidden('item_id', $move_file);
676
    $form->addHidden('action', 'move_to');
677
678
    //group documents cannot be uploaded in the root
679
    if ($group_dir == '') {
680
        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...
681
            //$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
682
        }
683
        if (is_array($folders)) {
684
            foreach ($folders as $fid => $folder) {
685
                //you cannot move a file to:
686
                //1. current directory
687
                //2. inside the folder you want to move
688
                //3. inside a subfolder of the folder you want to move
689
                if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
690
                    //$form .= '<option value="'.$fid.'">'.$folder.'</option>';
691
                    $options[$fid] = $folder;
692
                }
693
            }
694
        }
695
    } else {
696
        if ($curdirpath != '/') {
697
            $form .= '<option value="0">/ ('.get_lang('Root').')</option>';
698
        }
699
        foreach ($folders as $fid => $folder) {
700
            if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
701
                //cannot copy dir into his own subdir
702
                $display_folder = substr($folder, strlen($group_dir));
703
                $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
704
                //$form .= '<option value="'.$fid.'">'.$display_folder.'</option>'."\n";
705
                $options[$fid] = $display_folder;
706
            }
707
        }
708
    }
709
710
    $form->addSelect('move_to_id', get_lang('Select'), $options);
711
    $form->addButtonSend(get_lang('MoveFile'), 'move_file_submit');
712
713
    return $form->returnForm();
714
}
715
716
/**
717
 * creates a new directory trying to find a directory name
718
 * that doesn't already exist
719
 *
720
 * @author Hugues Peeters <[email protected]>
721
 * @author Bert Vanderkimpen
722
 * @author Yannick Warnier <[email protected]> Adaptation for work tool
723
 * @param   string $base_work_dir Base work dir (.../work)
724
 * @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...
725
 *
726
 * @return  string actual directory name if it succeeds, boolean false otherwise
727
 */
728
function create_unexisting_work_directory($base_work_dir, $desired_dir_name)
729
{
730
    $nb = '';
731
    $base_work_dir = (substr($base_work_dir, -1, 1) == '/' ? $base_work_dir : $base_work_dir.'/');
732
    while (file_exists($base_work_dir.$desired_dir_name.$nb)) {
733
        $nb += 1;
734
    }
735
736
    if (@mkdir($base_work_dir.$desired_dir_name.$nb, api_get_permissions_for_new_directories())) {
737
        return $desired_dir_name.$nb;
738
    } else {
739
        return false;
740
    }
741
}
742
743
/**
744
 * Delete a work-tool directory
745
 * @param   int  $id work directory id to delete
746
 * @return  integer -1 on error
747
 */
748
function deleteDirWork($id)
749
{
750
    $locked = api_resource_is_locked_by_gradebook($id, LINK_STUDENTPUBLICATION);
751
752
    if ($locked == true) {
753
        Display::display_warning_message(get_lang('ResourceLockedByGradebook'));
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_warning_message() has been deprecated with message: use Display::addFlash with Display::return_message

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

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

Loading history...
754
        return false;
755
    }
756
757
    $_course = api_get_course_info();
758
    $id = intval($id);
759
    $work_data = get_work_data_by_id($id);
760
761
    if (empty($work_data)) {
762
        return false;
763
    }
764
765
    $base_work_dir = api_get_path(SYS_COURSE_PATH) .$_course['path'].'/work';
766
    $work_data_url = $base_work_dir.$work_data['url'];
767
    $check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
768
769
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
770
    $TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
771
    $t_agenda = Database::get_course_table(TABLE_AGENDA);
772
773
    $course_id = api_get_course_int_id();
774
775
    if (!empty($work_data['url'])) {
776
        if ($check) {
777
            // Deleting all contents inside the folder
778
            $sql = "UPDATE $table SET active = 2
779
                    WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
780
            Database::query($sql);
781
782
            $sql = "UPDATE $table SET active = 2
783
                    WHERE c_id = $course_id AND parent_id = $id";
784
            Database::query($sql);
785
786
            $new_dir = $work_data_url.'_DELETED_'.$id;
787
788 View Code Duplication
            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
789
                my_delete($work_data_url);
790
            } else {
791
                if (file_exists($work_data_url)) {
792
                    rename($work_data_url, $new_dir);
793
                }
794
            }
795
796
            // Gets calendar_id from student_publication_assigment
797
            $sql = "SELECT add_to_calendar FROM $TSTDPUBASG
798
                    WHERE c_id = $course_id AND publication_id = $id";
799
            $res = Database::query($sql);
800
            $calendar_id = Database::fetch_row($res);
801
802
            // delete from agenda if it exists
803
            if (!empty($calendar_id[0])) {
804
                $sql = "DELETE FROM $t_agenda
805
                        WHERE c_id = $course_id AND id = '".$calendar_id[0]."'";
806
                Database::query($sql);
807
            }
808
            $sql = "DELETE FROM $TSTDPUBASG
809
                    WHERE c_id = $course_id AND publication_id = $id";
810
            Database::query($sql);
811
812
            Event::addEvent(
813
                LOG_WORK_DIR_DELETE,
814
                LOG_WORK_DATA,
815
                [
816
                    'id' => $work_data['id'],
817
                    'url' => $work_data['url'],
818
                    'title' => $work_data['title']
819
                ],
820
                null,
821
                api_get_user_id(),
822
                api_get_course_int_id(),
823
                api_get_session_id()
824
            );
825
826
            $link_info = GradebookUtils::isResourceInCourseGradebook(
827
                api_get_course_id(),
828
                3,
829
                $id,
830
                api_get_session_id()
831
            );
832
            $link_id = $link_info['id'];
833
            if ($link_info !== false) {
834
                GradebookUtils::remove_resource_from_course_gradebook($link_id);
835
            }
836
            return true;
837
        }
838
    }
839
}
840
841
/**
842
 * Get the path of a document in the student_publication table (path relative to the course directory)
843
 * @param   integer $id
844
 * @return  string  Path (or -1 on error)
845
 */
846
function get_work_path($id)
847
{
848
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
849
    $course_id  = api_get_course_int_id();
850
    $sql = 'SELECT url FROM '.$table.'
851
            WHERE c_id = '.$course_id.' AND id='.intval($id);
852
    $res = Database::query($sql);
853
    if (Database::num_rows($res)) {
854
        $row = Database::fetch_array($res);
855
        return $row['url'];
856
    }
857
    return -1;
858
}
859
860
/**
861
 * Update the url of a work in the student_publication table
862
 * @param integer $id of the work to update
863
 * @param string  $new_path Destination directory where the work has been moved (must end with a '/')
864
 * @param int $parent_id
865
 *
866
 * @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...
867
 */
868
function updateWorkUrl($id, $new_path, $parent_id)
869
{
870
    if (empty($id)) {
871
        return -1;
872
    }
873
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
874
    $course_id = api_get_course_int_id();
875
    $id = intval($id);
876
    $parent_id = intval($parent_id);
877
878
    $sql = "SELECT * FROM $table
879
            WHERE c_id = $course_id AND id = $id";
880
    $res = Database::query($sql);
881
    if (Database::num_rows($res) != 1) {
882
        return -1;
883
    } else {
884
        $row = Database::fetch_array($res);
885
        $filename = basename($row['url']);
886
        $new_url = $new_path.$filename;
887
        $new_url = Database::escape_string($new_url);
888
889
        $sql = "UPDATE $table SET
890
                   url = '$new_url',
891
                   parent_id = '$parent_id'
892
                WHERE c_id = $course_id AND id = $id";
893
        $res = Database::query($sql);
894
895
        return $res;
896
    }
897
}
898
899
/**
900
 * Update the url of a dir in the student_publication table
901
 * @param  array $work_data work original data
902
 * @param  string $newPath Example: "folder1"
903
 * @return bool
904
 */
905
function updateDirName($work_data, $newPath)
906
{
907
    $course_id = $work_data['c_id'];
908
    $sessionId = intval($work_data['session_id']);
909
    $work_id = intval($work_data['iid']);
910
    $oldPath = $work_data['url'];
911
    $originalNewPath = Database::escape_string($newPath);
912
    $newPath = Database::escape_string($newPath);
913
    $newPath = api_replace_dangerous_char($newPath);
914
    $newPath = disable_dangerous_file($newPath);
915
916
    if ($oldPath == '/'.$newPath) {
917
        return true;
918
    }
919
920 View Code Duplication
    if (!empty($newPath)) {
921
        $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
922
        $sql = "UPDATE $table SET
923
                    title = '".$originalNewPath."'
924
                WHERE
925
                    c_id = $course_id AND
926
                    iid = $work_id";
927
        Database::query($sql);
928
    }
929
}
930
931
/**
932
 * Return an array with all the folder's ids that are in the given path
933
 * @param   string Path of the directory
934
 * @return  array The list of ids of all the directories in the path
935
 * @author  Julio Montoya
936
 * @version April 2008
937
 */
938
function get_parent_directories($id)
939
{
940
    $course_id = api_get_course_int_id();
941
    $em = Database::getManager();
942
943
    $directories = $em
944
        ->getRepository('ChamiloCourseBundle:CStudentPublication')
945
        ->findBy([
946
            'cId' => $course_id,
947
            'parentId' => $id
948
        ]);
949
950
    $list_id = array();
951
952
    foreach ($directories as $directory) {
953
        $list_id[] = $directory->getId();
954
    }
955
956
    return $list_id;
957
}
958
959
/**
960
 * Transform an all directory structure (only directories) in an array
961
 * @param   string path of the directory
962
 * @return  array the directory structure into an array
963
 * @author  Julio Montoya
964
 * @version April 2008
965
 */
966 View Code Duplication
function directory_to_array($directory)
967
{
968
    $array_items = array();
969
    if ($handle = @opendir($directory)) {
970
        while (false !== ($file = readdir($handle))) {
971
            if ($file != '.' && $file != '..') {
972
                if (is_dir($directory. '/' . $file)) {
973
                    $array_items = array_merge($array_items, directory_to_array($directory. '/' . $file));
974
                    $file = $directory . '/' . $file;
975
                    $array_items[] = preg_replace("/\/\//si", '/', $file);
976
                }
977
            }
978
        }
979
        closedir($handle);
980
    }
981
982
    return $array_items;
983
}
984
985
/**
986
 * Insert into the DB of the course all the directories
987
 * @param   string path of the /work directory of the course
988
 * @return  -1 on error, sql query result on success
989
 * @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...
990
 * @version April 2008
991
 * @param string $base_work_dir
992
 */
993
994
function insert_all_directory_in_course_table($base_work_dir)
995
{
996
    $dir_to_array = directory_to_array($base_work_dir, true);
997
    $only_dir = array();
998
999
    for ($i = 0; $i < count($dir_to_array); $i++) {
1000
        $only_dir[] = substr($dir_to_array[$i], strlen($base_work_dir), strlen($dir_to_array[$i]));
1001
    }
1002
    $course_id = api_get_course_int_id();
1003
    $group_id  = api_get_group_id();
1004
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
1005
    $groupIid = 0;
1006
    if ($group_id) {
1007
        $groupInfo = GroupManager::get_group_properties($group_id);
1008
        $groupIid = $groupInfo['iid'];
1009
    }
1010
1011
    for ($i = 0; $i < count($only_dir); $i++) {
1012
        $url = $only_dir[$i];
1013
1014
        $params = [
1015
            'c_id' => $course_id,
1016
            'url' => $url,
1017
            'title' => '',
1018
            'description' => '',
1019
            'author' => '',
1020
            'active' => '1',
1021
            'accepted' => '1',
1022
            'filetype' => 'folder',
1023
            'post_group_id' => $groupIid,
1024
        ];
1025
1026
        Database::insert($work_table, $params);
1027
    }
1028
}
1029
1030
/**
1031
 * This function displays the number of files contained in a directory
1032
 *
1033
 * @param   string the path of the directory
1034
 * @param   boolean true if we want the total quantity of files
1035
 * include in others child directories, false only  files in the directory
1036
 * @return  array the first element is an integer with the number of files
1037
 * in the folder, the second element is the number of directories
1038
 * @author  Julio Montoya
1039
 * @version April 2008
1040
 */
1041
function count_dir($path_dir, $recurse)
1042
{
1043
    $count = 0;
1044
    $count_dir = 0;
1045
    $d = dir($path_dir);
1046
    while ($entry = $d->Read()) {
1047
        if (!(($entry == '..') || ($entry == '.'))) {
1048
            if (is_dir($path_dir.'/'.$entry)) {
1049
                $count_dir++;
1050
                if ($recurse) {
1051
                    $count += count_dir($path_dir . '/' . $entry, $recurse);
1052
                }
1053
            } else {
1054
                $count++;
1055
            }
1056
        }
1057
    }
1058
    $return_array = array();
1059
    $return_array[] = $count;
1060
    $return_array[] = $count_dir;
1061
    return $return_array;
1062
}
1063
1064
/**
1065
 * returns all the javascript that is required for easily
1066
 * validation when you create a work
1067
 * this goes into the $htmlHeadXtra[] array
1068
 */
1069
function to_javascript_work()
1070
{
1071
    $js = '<script>
1072
        function updateDocumentTitle(value) {
1073
            var temp = value.indexOf("/");
1074
            //linux path
1075
            if(temp!=-1){
1076
                var temp=value.split("/");
1077
            } else {
1078
                var temp=value.split("\\\");
1079
            }
1080
            document.getElementById("file_upload").value=temp[temp.length-1];
1081
            $("#contains_file_id").attr("value", 1);
1082
        }
1083
1084
        function checkDate(month, day, year) {
1085
          var monthLength =
1086
            new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1087
1088
          if (!day || !month || !year)
1089
            return false;
1090
1091
          // check for bisestile year
1092
          if (year/4 == parseInt(year/4))
1093
            monthLength[1] = 29;
1094
1095
          if (month < 1 || month > 12)
1096
            return false;
1097
1098
          if (day > monthLength[month-1])
1099
            return false;
1100
1101
          return true;
1102
        }
1103
1104
        function mktime() {
1105
1106
            var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
1107
            d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
1108
1109
            var dateManip = {
1110
                0: function(tt){ return d.setHours(tt); },
1111
                1: function(tt){ return d.setMinutes(tt); },
1112
                2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
1113
                3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
1114
                4: function(tt){ return d.setDate(tt+mb); },
1115
                5: function(tt){ return d.setYear(tt+ma); }
1116
            };
1117
1118
            for( i = 0; i < argc; i++ ){
1119
                no = parseInt(argv[i]*1);
1120
                if (isNaN(no)) {
1121
                    return false;
1122
                } else {
1123
                    // arg is number, lets manipulate date object
1124
                    if(!dateManip[i](no)){
1125
                        // failed
1126
                        return false;
1127
                    }
1128
                }
1129
            }
1130
            return Math.floor(d.getTime()/1000);
1131
        }
1132
1133
        function setFocus() {
1134
            $("#work_title").focus();
1135
        }
1136
1137
        $(document).ready(function() {
1138
            setFocus();
1139
1140
            var checked = $("#expiry_date").attr("checked");
1141
            if (checked) {
1142
                $("#option2").show();                
1143
            } else {
1144
                $("#option2").hide();                
1145
            }
1146
            
1147
            var checkedEndDate = $("#end_date").attr("checked");            
1148
            if (checkedEndDate) {                
1149
                $("#option3").show();
1150
                $("#ends_on").attr("checked", true);
1151
            } else {
1152
                $("#option3").hide();                
1153
                $("#ends_on").attr("checked", false);
1154
            }
1155
1156
            $("#expiry_date").click(function() {
1157
                $("#option2").toggle();
1158
            });
1159
1160
            $("#end_date").click(function() {
1161
                $("#option3").toggle();
1162
            });
1163
        });
1164
    </script>';
1165
1166
    return $js;
1167
}
1168
1169
/**
1170
 * Gets the id of a student publication with a given path
1171
 * @param string $path
1172
 * @return true if is found / false if not found
1173
 */
1174
// TODO: The name of this function does not fit with the kind of information it returns. Maybe check_work_id() or is_work_id()?
1175
function get_work_id($path)
1176
{
1177
    $TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1178
    $TBL_PROP_TABLE = Database::get_course_table(TABLE_ITEM_PROPERTY);
1179
    $course_id = api_get_course_int_id();
1180
    $path = Database::escape_string($path);
1181
1182
    if (api_is_allowed_to_edit()) {
1183
        $sql = "SELECT work.id
1184
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1185
                WHERE
1186
                    props.c_id = $course_id AND
1187
                    work.c_id = $course_id AND
1188
                    props.tool='work' AND
1189
                    work.id=props.ref AND
1190
                    work.url LIKE 'work/".$path."%' AND
1191
                    work.filetype='file' AND
1192
                    props.visibility<>'2'";
1193
    } else {
1194
        $sql = "SELECT work.id
1195
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1196
                WHERE
1197
                    props.c_id = $course_id AND
1198
                    work.c_id = $course_id AND
1199
                    props.tool='work' AND
1200
                    work.id=props.ref AND
1201
                    work.url LIKE 'work/".$path."%' AND
1202
                    work.filetype='file' AND
1203
                    props.visibility<>'2' AND
1204
                    props.lastedit_user_id = '".api_get_user_id()."'";
1205
    }
1206
    $result = Database::query($sql);
1207
    $num_rows = Database::num_rows($result);
1208
1209
    if ($result && $num_rows > 0) {
1210
        return true;
1211
    } else {
1212
        return false;
1213
    }
1214
}
1215
1216
/**
1217
 * @param int $work_id
1218
 * @param int $onlyMeUserId show only my works
1219
 * @param int $notMeUserId show works from everyone except me
1220
 * @return int
1221
 */
1222
function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
1223
{
1224
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1225
    $iprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1226
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1227
1228
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
1229
    $session_id = api_get_session_id();
1230
    $condition_session = api_get_session_condition($session_id, true, false, 'work.session_id');
1231
1232
    $group_id = api_get_group_id();
1233
    $course_info = api_get_course_info();
1234
    $course_id = $course_info['real_id'];
1235
    $work_id = intval($work_id);
1236
1237
    $groupIid = 0;
1238
    if ($group_id) {
1239
        $groupInfo = GroupManager::get_group_properties($group_id);
1240
        $groupIid = $groupInfo['iid'];
1241
    }
1242
1243
1244 View Code Duplication
    if (!empty($group_id)) {
1245
        // set to select only messages posted by the user's group
1246
        $extra_conditions = " work.post_group_id = '".intval($groupIid)."' ";
1247
    } else {
1248
        $extra_conditions = " (work.post_group_id = '0' or work.post_group_id IS NULL) ";
1249
    }
1250
1251 View Code Duplication
    if ($is_allowed_to_edit) {
1252
        $extra_conditions .= ' AND work.active IN (0, 1) ';
1253
    } else {
1254
        $extra_conditions .= ' AND work.active IN (0, 1) AND accepted = 1';
1255
        if (isset($course_info['show_score']) && $course_info['show_score'] == 1) {
1256
            $extra_conditions .= " AND work.user_id = ".api_get_user_id()." ";
1257
        } else {
1258
            $extra_conditions .= '';
1259
        }
1260
    }
1261
1262
    $extra_conditions .= " AND parent_id  = ".$work_id."  ";
1263
1264
    $where_condition = null;
1265
1266
    if (!empty($notMeUserId)) {
1267
        $where_condition .= " AND u.user_id <> ".intval($notMeUserId);
1268
    }
1269
1270
    if (!empty($onlyMeUserId)) {
1271
        $where_condition .= " AND u.user_id =  ".intval($onlyMeUserId);
1272
    }
1273
1274
    $sql = "SELECT count(*) as count
1275
            FROM $iprop_table prop
1276
            INNER JOIN $work_table work
1277
            ON (
1278
                prop.ref = work.id AND
1279
                prop.c_id = $course_id AND
1280
                prop.tool='work' AND
1281
                prop.visibility <> 2 AND
1282
                work.c_id = $course_id
1283
            )
1284
            INNER JOIN $user_table u 
1285
            ON (work.user_id = u.user_id)
1286
            WHERE $extra_conditions $where_condition $condition_session";
1287
1288
    $result = Database::query($sql);
1289
1290
    $users_with_work = 0;
1291
    if (Database::num_rows($result)) {
1292
        $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...
1293
        $users_with_work = $result['count'];
1294
    }
1295
    return $users_with_work;
1296
}
1297
1298
/**
1299
 * @param int $start
1300
 * @param int $limit
1301
 * @param string $column
1302
 * @param string $direction
1303
 * @param string $where_condition
1304
 * @param bool $getCount
1305
 * @return array
1306
 */
1307
function getWorkListStudent(
1308
    $start,
1309
    $limit,
1310
    $column,
1311
    $direction,
1312
    $where_condition,
1313
    $getCount = false
1314
) {
1315
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1316
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1317
    $courseInfo = api_get_course_info();
1318
    $course_id = $courseInfo['real_id'];
1319
    $session_id = api_get_session_id();
1320
    $condition_session = api_get_session_condition($session_id);
1321
    $group_id = api_get_group_id();
1322
    $userId = api_get_user_id();
1323
1324
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1325
        api_get_user_id(),
1326
        $courseInfo
1327
    );
1328
1329
    if (!in_array($direction, array('asc','desc'))) {
1330
        $direction = 'desc';
1331
    }
1332
    if (!empty($where_condition)) {
1333
        $where_condition = ' AND ' . $where_condition;
1334
    }
1335
1336
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1337
    $start = intval($start);
1338
    $limit = intval($limit);
1339
1340
    $groupIid = 0;
1341
    if ($group_id) {
1342
        $groupInfo = GroupManager::get_group_properties($group_id);
1343
        $groupIid = $groupInfo['iid'];
1344
    }
1345
    $groupIid = (int) $groupIid;
1346
1347
    // Get list from database
1348 View Code Duplication
    if (!empty($groupIid)) {
1349
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = $groupIid";
1350
        $subdirs_query = "AND parent_id = 0";
1351
    } else {
1352
        $group_query = " WHERE w.c_id = $course_id AND (post_group_id = '0' or post_group_id is NULL)  ";
1353
        $subdirs_query = "AND parent_id = 0";
1354
    }
1355
1356
    $active_condition = ' AND active IN (1, 0)';
1357
1358
    if ($getCount) {
1359
        $select = "SELECT count(w.id) as count ";
1360
    } else {
1361
        $select = "SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1362
    }
1363
1364
    $sql = "$select
1365
            FROM $workTable w
1366
            LEFT JOIN $workTableAssignment a
1367
            ON (a.publication_id = w.id AND a.c_id = w.c_id)
1368
                $group_query
1369
                $subdirs_query
1370
                $active_condition
1371
                $condition_session
1372
                $where_condition
1373
            ";
1374
1375
    $sql .= " ORDER BY $column $direction ";
1376
1377
    if (!empty($start) && !empty($limit)) {
1378
        $sql .= " LIMIT $start, $limit";
1379
    }
1380
1381
    $result = Database::query($sql);
1382
1383
    if ($getCount) {
1384
        $row = Database::fetch_array($result);
1385
        return $row['count'];
1386
    }
1387
1388
    $works = array();
1389
    $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
1390
    if ($isDrhOfCourse) {
1391
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1392
    }
1393
1394
    $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
1395
    while ($work = Database::fetch_array($result, 'ASSOC')) {
1396
        $isSubscribed = userIsSubscribedToWork($userId, $work['id'], $course_id);
1397
        if ($isSubscribed == false) {
1398
            continue;
1399
        }
1400
1401
        $visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $session_id);
1402
1403
        if ($visibility != 1) {
1404
            continue;
1405
        }
1406
1407
        $work['type'] = Display::return_icon('work.png');
1408
        $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1409
1410
        if (empty($work['title'])) {
1411
            $work['title'] = basename($work['url']);
1412
        }
1413
1414
        $whereCondition = " AND u.user_id = ".intval($userId);
1415
1416
        $workList = get_work_user_list(
1417
            0,
1418
            1000,
1419
            null,
1420
            null,
1421
            $work['id'],
1422
            $whereCondition
1423
        );
1424
1425
        $count = getTotalWorkComment($workList, $courseInfo);
1426
1427 View Code Duplication
        if (!is_null($count) && !empty($count)) {
1428
            $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info');
1429
        }
1430
1431
        $lastWork = getLastWorkStudentFromParentByUser($userId, $work['id'], $courseInfo);
1432
1433
        if (!empty($lastWork)) {
1434
            $work['last_upload'] = (!empty($lastWork['qualification'])) ? Display::label($lastWork['qualification'], 'warning').' - ' : '';
1435
            $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1436
        }
1437
1438
        $work['title'] = Display::url($work['title'], $url.'&id='.$work['id']);
1439
        $work['others'] = Display::url(
1440
            Display::return_icon('group.png', get_lang('Others')),
1441
            $urlOthers.$work['id']
1442
        );
1443
        $works[] = $work;
1444
    }
1445
1446
    return $works;
1447
}
1448
1449
/**
1450
 * @param int $start
1451
 * @param int $limit
1452
 * @param string $column
1453
 * @param string $direction
1454
 * @param string $where_condition
1455
 * @param bool $getCount
1456
 * @return array
1457
 */
1458
function getWorkListTeacher(
1459
    $start,
1460
    $limit,
1461
    $column,
1462
    $direction,
1463
    $where_condition,
1464
    $getCount = false
1465
) {
1466
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1467
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1468
1469
    $courseInfo = api_get_course_info();
1470
    $course_id = api_get_course_int_id();
1471
    $session_id = api_get_session_id();
1472
    $condition_session = api_get_session_condition($session_id);
1473
    $group_id = api_get_group_id();
1474
    $groupIid = 0;
1475
    if ($group_id) {
1476
        $groupInfo = GroupManager::get_group_properties($group_id);
1477
        $groupIid = $groupInfo['iid'];
1478
    }
1479
    $groupIid = (int) $groupIid;
1480
1481
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1482
    if (!in_array($direction, array('asc', 'desc'))) {
1483
        $direction = 'desc';
1484
    }
1485
    if (!empty($where_condition)) {
1486
        $where_condition = ' AND ' . $where_condition;
1487
    }
1488
1489
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1490
    $start = intval($start);
1491
    $limit = intval($limit);
1492
    $works = array();
1493
1494
    // Get list from database
1495
    if ($is_allowed_to_edit) {
1496
        $active_condition = ' active IN (0, 1)';
1497
        if ($getCount) {
1498
            $select = " SELECT count(w.id) as count";
1499
        } else {
1500
            $select = " SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1501
        }
1502
        $sql = " $select
1503
                FROM $workTable w
1504
                LEFT JOIN $workTableAssignment a
1505
                ON (a.publication_id = w.id AND a.c_id = w.c_id)
1506
                WHERE
1507
                    w.c_id = $course_id
1508
                    $condition_session AND
1509
                    $active_condition AND
1510
                    parent_id = 0 AND
1511
                    post_group_id = $groupIid
1512
                    $where_condition
1513
                ORDER BY $column $direction
1514
                LIMIT $start, $limit";
1515
1516
        $result = Database::query($sql);
1517
1518
        if ($getCount) {
1519
            $row = Database::fetch_array($result);
1520
1521
            return $row['count'];
1522
        }
1523
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1524
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1525
            $workId = $work['id'];
1526
            $work['type'] = Display::return_icon('work.png');
1527
            $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1528
1529
            $countUniqueAttempts = getUniqueStudentAttemptsTotal(
1530
                $workId,
1531
                $group_id,
1532
                $course_id,
1533
                $session_id
1534
            );
1535
1536
            $totalUsers = getStudentSubscribedToWork(
1537
                $workId,
1538
                $course_id,
1539
                $group_id,
1540
                $session_id,
1541
                true
1542
            );
1543
1544
            $work['amount'] = Display::label(
1545
                $countUniqueAttempts . '/' .
1546
                $totalUsers,
1547
                'success'
1548
            );
1549
1550
            $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1551
1552
            if ($visibility == 1) {
1553
                $icon = 'visible.png';
1554
                $text = get_lang('Visible');
1555
                $action = 'invisible';
1556
                $class = '';
1557
            } else {
1558
                $icon = 'invisible.png';
1559
                $text = get_lang('Invisible');
1560
                $action = 'visible';
1561
                $class = 'muted';
1562
            }
1563
1564
            $visibilityLink = Display::url(
1565
                Display::return_icon($icon, $text, array(), ICON_SIZE_SMALL),
1566
                api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action='.$action.'&'.api_get_cidreq()
1567
            );
1568
1569
            if (empty($work['title'])) {
1570
                $work['title'] = basename($work['url']);
1571
            }
1572
            $work['title'] = Display::url($work['title'], $url.'&id='.$workId, ['class' => $class]);
1573
            $work['title'] .= ' '.Display::label(get_count_work($work['id']), 'success');
1574
            $work['sent_date'] = api_get_local_time($work['sent_date']);
1575
1576
            $editLink = Display::url(
1577
                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL),
1578
                api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq()
1579
            );
1580
1581
            $correctionLink = Display::url(
1582
                Display::return_icon('upload_file.png', get_lang('UploadCorrections'), '', ICON_SIZE_SMALL),
1583
                api_get_path(WEB_CODE_PATH).'work/upload_corrections.php?'.api_get_cidreq().'&id='.$workId
1584
            );
1585
1586
            if ($countUniqueAttempts > 0) {
1587
                $downloadLink = Display::url(
1588
                    Display::return_icon(
1589
                        'save_pack.png',
1590
                        get_lang('Save'),
1591
                        array(),
1592
                        ICON_SIZE_SMALL
1593
                    ),
1594
                    api_get_path(WEB_CODE_PATH) . 'work/downloadfolder.inc.php?id=' . $workId . '&' . api_get_cidreq()
1595
                );
1596
            } else {
1597
                $downloadLink = Display::url(
1598
                    Display::return_icon(
1599
                        'save_pack_na.png',
1600
                        get_lang('Save'),
1601
                        array(),
1602
                        ICON_SIZE_SMALL
1603
                    ),
1604
                    '#'
1605
                );
1606
            }
1607
            // Remove Delete Work Button from action List
1608
            // Because removeXSS "removes" the onClick JS Event to do the action (See model.ajax.php - Line 1639)
1609
            // But still can use the another jqgrid button to remove works (trash icon)
1610
            //
1611
            // $deleteUrl = api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action=delete_dir&'.api_get_cidreq();
1612
            // $deleteLink = '<a href="#" onclick="showConfirmationPopup(this, \'' . $deleteUrl . '\' ) " >' .
1613
            //     Display::return_icon(
1614
            //         'delete.png',
1615
            //         get_lang('Delete'),
1616
            //         array(),
1617
            //         ICON_SIZE_SMALL
1618
            //     ) . '</a>';
1619
1620
            if (!api_is_allowed_to_edit()) {
1621
                // $deleteLink = null;
1622
                $editLink = null;
1623
            }
1624
            $work['actions'] = $visibilityLink.$correctionLink.$downloadLink.$editLink;
1625
            $works[] = $work;
1626
        }
1627
    }
1628
1629
    return $works;
1630
}
1631
1632
/**
1633
 * @param int $start
1634
 * @param int $limit
1635
 * @param string $column
1636
 * @param string $direction
1637
 * @param int $workId
1638
 * @param int $studentId
1639
 * @param string $whereCondition
1640
 * @param bool $getCount
1641
 * @return array
1642
 */
1643
function get_work_user_list_from_documents(
1644
    $start,
1645
    $limit,
1646
    $column,
1647
    $direction,
1648
    $workId,
1649
    $studentId = null,
1650
    $whereCondition,
1651
    $getCount = false
1652
) {
1653
    if ($getCount) {
1654
        $select1 = " SELECT count(u.user_id) as count ";
1655
        $select2 = " SELECT count(u.user_id) as count ";
1656
    } else {
1657
        $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";
1658
        $select2 = " SELECT DISTINCT u.firstname, u.lastname, u.user_id, d.title, w.parent_id, d.id document_id, 0, 0, 0";
1659
    }
1660
1661
    $documentTable = Database::get_course_table(TABLE_DOCUMENT);
1662
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1663
    $workRelDocument = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
1664
    $userTable = Database::get_main_table(TABLE_MAIN_USER);
1665
1666
    $courseId = api_get_course_int_id();
1667
    $sessionId = api_get_session_id();
1668
1669
    if (empty($studentId)) {
1670
        $studentId = api_get_user_id();
1671
    }
1672
    $studentId = intval($studentId);
1673
    $workId = intval($workId);
1674
1675
    $userCondition = " AND u.user_id = $studentId ";
1676
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
1677
    $workCondition = " AND w_rel.work_id = $workId";
1678
    $workParentCondition  = " AND w.parent_id = $workId";
1679
1680
    $sql = "(
1681
                $select1 FROM $userTable u
1682
                INNER JOIN $workTable w
1683
                ON (u.user_id = w.user_id AND w.active IN (0, 1) AND w.filetype = 'file')
1684
                WHERE
1685
                    w.c_id = $courseId
1686
                    $userCondition
1687
                    $sessionCondition
1688
                    $whereCondition
1689
                    $workParentCondition
1690
            ) UNION (
1691
                $select2 FROM $workTable w
1692
                INNER JOIN $workRelDocument w_rel
1693
                ON (w_rel.work_id = w.id AND w.active IN (0, 1) AND w_rel.c_id = w.c_id)
1694
                INNER JOIN $documentTable d
1695
                ON (w_rel.document_id = d.id AND d.c_id = w.c_id)
1696
                INNER JOIN $userTable u ON (u.user_id = $studentId)
1697
                WHERE
1698
                    w.c_id = $courseId
1699
                    $workCondition
1700
                    $sessionCondition AND
1701
                    d.id NOT IN (
1702
                        SELECT w.document_id id
1703
                        FROM $workTable w
1704
                        WHERE
1705
                            user_id = $studentId AND
1706
                            c_id = $courseId AND
1707
                            filetype = 'file' AND
1708
                            active IN (0, 1)
1709
                            $sessionCondition
1710
                            $workParentCondition
1711
                    )
1712
            )";
1713
1714
    $start = intval($start);
1715
    $limit = intval($limit);
1716
1717
    $direction = in_array(strtolower($direction), array('desc', 'asc')) ? $direction : 'desc';
1718
    $column = Database::escape_string($column);
1719
1720
    if ($getCount) {
1721
        $result = Database::query($sql);
1722
        $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...
1723
        return $result['count'];
1724
    }
1725
1726
    $sql .= " ORDER BY $column $direction";
1727
    $sql .= " LIMIT $start, $limit";
1728
1729
    $result = Database::query($sql);
1730
1731
    $currentUserId = api_get_user_id();
1732
    $work_data = get_work_data_by_id($workId);
1733
1734
    $qualificationExists = false;
1735
1736 View Code Duplication
    if (!empty($work_data['qualification']) && intval($work_data['qualification']) > 0) {
1737
        $qualificationExists = true;
1738
    }
1739
1740
    $urlAdd = api_get_path(WEB_CODE_PATH).'work/upload_from_template.php?'.api_get_cidreq();
1741
    $urlEdit = api_get_path(WEB_CODE_PATH).'work/edit.php?'.api_get_cidreq();
1742
    $urlDelete = api_get_path(WEB_CODE_PATH).'work/work_list.php?action=delete&'.api_get_cidreq();
1743
    $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq();
1744
1745
    $editIcon = Display::return_icon('edit.png', get_lang('Edit'));
1746
    $addIcon = Display::return_icon('add.png', get_lang('Add'));
1747
    $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'));
1748
    $viewIcon = Display::return_icon('default.png', get_lang('View'));
1749
    $allowEdition = api_get_course_setting('student_delete_own_publication');
1750
1751
    $workList = array();
1752
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1753
        $userId = $row['user_id'];
1754
        $documentId = $row['document_id'];
1755
        $itemId = $row['id'];
1756
        $addLinkShowed = false;
1757
1758
        if (empty($documentId)) {
1759
            $url = $urlEdit.'&item_id='.$row['id'].'&id='.$workId;
1760
            $editLink = Display::url($editIcon, $url);
1761
            if ($allowEdition == false) {
1762
                $editLink = null;
1763
            }
1764
        } else {
1765
            $documentToWork = getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId);
1766
1767
            if (empty($documentToWork)) {
1768
                $url = $urlAdd.'&document_id='.$documentId.'&id='.$workId;
1769
                $editLink = Display::url($addIcon, $url);
1770
                $addLinkShowed = true;
1771
            } else {
1772
                $row['title'] = $documentToWork['title'];
1773
                $row['sent_date'] = $documentToWork['sent_date'];
1774
                $newWorkId = $documentToWork['id'];
1775
                $url = $urlEdit.'&item_id='.$newWorkId.'&id='.$workId;
1776
                $editLink = Display::url($editIcon, $url);
1777
1778
                if ($allowEdition == false) {
1779
                    $editLink = null;
1780
                }
1781
            }
1782
        }
1783
1784
        if ($allowEdition && !empty($itemId)) {
1785
            $deleteLink  = Display::url($deleteIcon, $urlDelete.'&item_id='.$itemId.'&id='.$workId);
1786
        } else {
1787
            $deleteLink = null;
1788
        }
1789
1790
        $viewLink = null;
1791
        if (!empty($itemId)) {
1792
            $viewLink = Display::url($viewIcon, $urlView.'&id='.$itemId);
1793
        }
1794
1795
        $row['type'] = null;
1796
1797
        if ($qualificationExists) {
1798 View Code Duplication
            if (empty($row['qualificator_id'])) {
1799
                $status = Display::label(get_lang('NotRevised'), 'warning');
1800
            } else {
1801
                $status = Display::label(get_lang('Revised'), 'success');
1802
            }
1803
            $row['qualificator_id'] = $status;
1804
        }
1805
1806
        if (!empty($row['qualification'])) {
1807
            $row['qualification'] = Display::label($row['qualification'], 'info');
1808
        }
1809
1810
        if (!empty($row['sent_date'])) {
1811
            $row['sent_date'] = api_get_local_time($row['sent_date']);
1812
        }
1813
1814
        if ($userId == $currentUserId) {
1815
            $row['actions'] = $viewLink.$editLink.$deleteLink;
1816
        }
1817
1818
        if ($addLinkShowed) {
1819
            $row['qualification'] = '';
1820
            $row['qualificator_id'] = '';
1821
        }
1822
1823
        $workList[] = $row;
1824
    }
1825
1826
    return $workList;
1827
}
1828
1829
/**
1830
 * @param int $start
1831
 * @param int $limit
1832
 * @param int $column
1833
 * @param string $direction
1834
 * @param int $work_id
1835
 * @param array $where_condition
1836
 * @param int $studentId
1837
 * @param bool $getCount
1838
 * @return array
1839
 */
1840
function get_work_user_list(
1841
    $start,
1842
    $limit,
1843
    $column,
1844
    $direction,
1845
    $work_id,
1846
    $where_condition = null,
1847
    $studentId = null,
1848
    $getCount = false
1849
) {
1850
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1851
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1852
1853
    $session_id = api_get_session_id();
1854
    $group_id = api_get_group_id();
1855
    $course_info = api_get_course_info();
1856
    $course_id = $course_info['real_id'];
1857
1858
    $work_id = intval($work_id);
1859
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1860
    $start = intval($start);
1861
    $limit = intval($limit);
1862
1863
    if (!in_array($direction, array('asc','desc'))) {
1864
        $direction = 'desc';
1865
    }
1866
1867
    $work_data = get_work_data_by_id($work_id);
1868
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1869
    $condition_session  = api_get_session_condition($session_id, true, false, 'work.session_id');
1870
    $locked = api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION);
1871
1872
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1873
        api_get_user_id(),
1874
        $course_info
1875
    );
1876
1877
    $groupIid = 0;
1878
    if ($group_id) {
1879
        $groupInfo = GroupManager::get_group_properties($group_id);
1880
        $groupIid = $groupInfo['iid'];
1881
    }
1882
1883
    if (!empty($work_data)) {
1884 View Code Duplication
        if (!empty($group_id)) {
1885
            $extra_conditions = " work.post_group_id = '".intval($groupIid)."' ";
1886
            // set to select only messages posted by the user's group
1887
        } else {
1888
            $extra_conditions = " (work.post_group_id = '0' OR work.post_group_id is NULL) ";
1889
        }
1890
1891 View Code Duplication
        if ($is_allowed_to_edit || $isDrhOfCourse) {
1892
            $extra_conditions .= ' AND work.active IN (0, 1) ';
1893
        } else {
1894
            if (isset($course_info['show_score']) &&
1895
                $course_info['show_score'] == 1
1896
            ) {
1897
                $extra_conditions .= " AND (u.user_id = ".api_get_user_id()." AND work.active IN (0, 1)) ";
1898
            } else {
1899
                $extra_conditions .= ' AND work.active IN (0, 1) ';
1900
            }
1901
        }
1902
1903
        $extra_conditions .= " AND parent_id  = ".$work_id." ";
1904
1905
        $select = 'SELECT DISTINCT
1906
                        u.user_id,
1907
                        work.id as id,
1908
                        title as title,
1909
                        description,
1910
                        url,
1911
                        sent_date,
1912
                        contains_file,
1913
                        has_properties,
1914
                        view_properties,
1915
                        qualification,
1916
                        weight,
1917
                        allow_text_assignment,
1918
                        CONCAT (u.firstname," ",u.lastname) as fullname,
1919
                        u.username,
1920
                        parent_id,
1921
                        accepted,
1922
                        qualificator_id,
1923
                        url_correction
1924
                        ';
1925
        if ($getCount) {
1926
            $select = "SELECT DISTINCT count(u.user_id) as count ";
1927
        }
1928
1929
        $user_condition = "INNER JOIN $user_table u  ON (work.user_id = u.user_id) ";
1930
        $work_assignment = get_work_assignment_by_id($work_id);
1931
1932
        if (!empty($studentId)) {
1933
            $where_condition.= " AND u.user_id = ".intval($studentId);
1934
        }
1935
1936
        $sql = " $select
1937
                FROM $work_table work  $user_condition
1938
                WHERE
1939
                    work.c_id = $course_id AND
1940
                    $extra_conditions 
1941
                    $where_condition 
1942
                    $condition_session
1943
                    AND u.status != " . INVITEE . "
1944
                ORDER BY $column $direction";
1945
1946
        if (!empty($start) && !empty($limit)) {
1947
            $sql .= " LIMIT $start, $limit";
1948
        }
1949
        $result = Database::query($sql);
1950
        $works = array();
1951
1952
        if ($getCount) {
1953
            $work = Database::fetch_array($result, 'ASSOC');
1954
            return $work['count'];
1955
        }
1956
1957
        $url = api_get_path(WEB_CODE_PATH).'work/';
1958
        $unoconv = api_get_configuration_value('unoconv.binaries');
1959
1960
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1961
            $item_id = $work['id'];
1962
1963
            // Get the author ID for that document from the item_property table
1964
            $is_author  = false;
1965
            $can_read   = false;
1966
            $owner_id = $work['user_id'];
1967
1968
            /* Because a bug found when saving items using the api_item_property_update()
1969
               the field $item_property_data['insert_user_id'] is not reliable. */
1970
1971
            if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
1972
                $is_author = true;
1973
            }
1974
1975
            if ($course_info['show_score'] == 0) {
1976
                $can_read = true;
1977
            }
1978
1979
            if ($work['accepted'] == '0') {
1980
                $class = 'text-muted';
1981
            } else {
1982
                $class = '';
1983
            }
1984
1985
            $qualification_exists = false;
1986 View Code Duplication
            if (!empty($work_data['qualification']) &&
1987
                intval($work_data['qualification']) > 0
1988
            ) {
1989
                $qualification_exists = true;
1990
            }
1991
1992
            $qualification_string = '';
1993
            if ($qualification_exists) {
1994
                if ($work['qualification'] == '') {
1995
                    $qualification_string = Display::label('-');
1996
                } else {
1997
                    $label = 'info';
1998
                    $relativeScore = $work['qualification']/$work_data['qualification'];
1999
                    if ($relativeScore < 0.5) {
2000
                        $label = 'important';
2001
                    } elseif ($relativeScore < 0.75) {
2002
                        $label = 'warning';
2003
                    }
2004
                    $qualification_string = Display::label(
2005
                        $work['qualification'].' / '.$work_data['qualification'],
2006
                        $label
2007
                    );
2008
                }
2009
            }
2010
2011
            $work['qualification_score'] = $work['qualification'];
2012
2013
            $add_string = '';
2014
            $time_expires = '';
2015
            if (!empty($work_assignment['expires_on'])) {
2016
                $time_expires = api_strtotime(
2017
                    $work_assignment['expires_on'],
2018
                    'UTC'
2019
                );
2020
            }
2021
2022
            if (!empty($work_assignment['expires_on']) &&
2023
                !empty($time_expires) && ($time_expires < api_strtotime($work['sent_date'], 'UTC'))) {
2024
                $add_string = Display::label(get_lang('Expired'), 'important');
2025
            }
2026
2027
            if (($can_read && $work['accepted'] == '1') ||
2028
                ($is_author && in_array($work['accepted'], array('1', '0'))) ||
2029
                ($is_allowed_to_edit || api_is_drh())
2030
            ) {
2031
                // Firstname, lastname, username
2032
                $work['fullname'] = Display::div($work['fullname'], array('class' => 'work-name'));
2033
                $work['title_clean'] = $work['title'];
2034
2035
                if (strlen($work['title']) > 30) {
2036
                    $short_title = substr($work['title'], 0, 27).'...';
2037
                    $work['title'] = Display::span($short_title, array('class' => 'work-title', 'title' => $work['title']));
2038
                } else {
2039
                    $work['title'] = Display::div($work['title'], array('class' => 'work-title'));
2040
                }
2041
2042
                // Type.
2043
                $work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
2044
2045
                // File name.
2046
                $link_to_download = null;
2047
2048
                // If URL is present then there's a file to download keep BC.
2049 View Code Duplication
                if ($work['contains_file'] || !empty($work['url'])) {
2050
                    $link_to_download = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.
2051
                        Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
2052
                }
2053
2054
                $send_to = Portfolio::share('work', $work['id'],  array('style' => 'white-space:nowrap;'));
2055
2056
                $feedback = null;
2057
                $count = getWorkCommentCount($item_id, $course_info);
2058
                if (!is_null($count) && !empty($count)) {
2059
                    if ($qualification_exists) {
2060
                        $feedback .= ' ';
2061
                    }
2062
                    $feedback .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2063
                    $count . ' ' . Display::returnFontAwesomeIcon('comments-o') . '</a> ';
2064
                }
2065
2066
                $work['qualification'] = $qualification_string.$feedback;
2067
                $work['qualification_only'] = $qualification_string;
2068
2069
                // Date.
2070
                $work_date = api_convert_and_format_date($work['sent_date']);
2071
                $date = date_to_str_ago($work['sent_date']). ' ' . $work_date;
2072
                $work['formatted_date'] = $work_date . ' - ' . $add_string;
2073
2074
                $work['sent_date_from_db'] = $work['sent_date'];
2075
                $work['sent_date'] = '<div class="work-date" title="'.$date.'">' . $add_string . ' - ' . $work['sent_date'] . '</div>';
2076
2077
                // Actions.
2078
                $correction = '';
2079
2080
                $action = '';
2081
                if (api_is_allowed_to_edit()) {
2082
                    if (!empty($work['url_correction'])) {
2083
                        $action .= Display::url(
2084
                            Display::return_icon('check-circle.png', get_lang('Correction'), null, ICON_SIZE_SMALL),
2085
                            api_get_path(WEB_CODE_PATH).'work/download.php?id='.$item_id.'&'.api_get_cidreq().'&correction=1'
2086
                        );
2087
                    }
2088
2089
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2090
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a> ';
2091
2092
                    if ($unoconv && empty($work['contains_file'])) {
2093
                        $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').'" >'.
2094
                            Display::return_icon('export_doc.png', get_lang('ExportToDoc'),array(), ICON_SIZE_SMALL).'</a> ';
2095
                    }
2096
                    $loadingText = addslashes(get_lang('Loading'));
2097
                    $uploadedText = addslashes(get_lang('Uploaded'));
2098
                    $failsUploadText = addslashes(get_lang('UplNoFileUploaded'));
2099
                    $failsUploadIcon = Display::return_icon('closed-circle.png', '', [], ICON_SIZE_TINY);
2100
                    $correction = '
2101
                        <form
2102
                        id="file_upload_'.$item_id.'"
2103
                        class="work_correction_file_upload file_upload_small fileinput-button"
2104
                        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"
2105
                        >
2106
                        <div id="progress_'.$item_id.'" class="text-center button-load">
2107
                            '.addslashes(get_lang('ClickOrDropOneFileHere')).'
2108
                            '.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
2109
                        </div>
2110
                        <input id="file_'.$item_id.'" type="file" name="file" class="" multiple>
2111
                        </form>
2112
                    ';
2113
2114
                    $correction .= "<script>
2115
                    $(document).ready(function() {
2116
                        $('.work_correction_file_upload').each(function () {
2117
                            $(this).fileupload({
2118
                                dropZone: $(this)
2119
                            });
2120
                        });
2121
                        $('#file_upload_".$item_id."').fileupload({
2122
                            add: function (e, data) {
2123
                                $('#progress_$item_id').html();
2124
                                //$('#file_$item_id').remove();
2125
                                data.context = $('#progress_$item_id').html('$loadingText <br /> <em class=\"fa fa-spinner fa-pulse fa-fw\"></em>');
2126
                                data.submit();
2127
                            },
2128
                            done: function (e, data) {
2129
                                if (data._response.result.name) {
2130
                                    $('#progress_$item_id').html('$uploadedText '+data._response.result.result+'<br />'+data._response.result.name);
2131
                                } else {
2132
                                    $('#progress_$item_id').html('$failsUploadText $failsUploadIcon');
2133
                                }
2134
                            }
2135
                        });
2136
                    });
2137
                    </script>";
2138
2139
                    if ($locked) {
2140
                        if ($qualification_exists) {
2141
                            $action .= Display::return_icon('rate_work_na.png', get_lang('CorrectAndRate'),array(), ICON_SIZE_SMALL);
2142
                        } else {
2143
                            $action .= Display::return_icon('edit_na.png', get_lang('Comment'), array(), ICON_SIZE_SMALL);
2144
                        }
2145 View Code Duplication
                    } else {
2146
                        if ($qualification_exists) {
2147
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Edit').'"  >'.
2148
                                Display::return_icon('rate_work.png', get_lang('CorrectAndRate'), array(), ICON_SIZE_SMALL).'</a>';
2149
                        } else {
2150
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2151
                                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
2152
                        }
2153
                    }
2154
2155 View Code Duplication
                    if ($work['contains_file']) {
2156
                        if ($locked) {
2157
                            $action .= Display::return_icon('move_na.png', get_lang('Move'),array(), ICON_SIZE_SMALL);
2158
                        } else {
2159
                            $action .= '<a href="'.$url.'work.php?'.api_get_cidreq().'&action=move&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Move').'">'.
2160
                                Display::return_icon('move.png', get_lang('Move'),array(), ICON_SIZE_SMALL).'</a>';
2161
                        }
2162
                    }
2163
2164 View Code Duplication
                    if ($work['accepted'] == '1') {
2165
                        $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').'" >'.
2166
                            Display::return_icon('visible.png', get_lang('Invisible'),array(), ICON_SIZE_SMALL).'</a>';
2167
                    } else {
2168
                        $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').'" >'.
2169
                            Display::return_icon('invisible.png', get_lang('Visible'),array(), ICON_SIZE_SMALL).'</a> ';
2170
                    }
2171
2172
                    if ($locked) {
2173
                        $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2174
                    } else {
2175
                        $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').'" >'.
2176
                            Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2177
                    }
2178
                } elseif ($is_author && (empty($work['qualificator_id']) || $work['qualificator_id'] == 0)) {
2179
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2180
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a>';
2181
2182
                    if (api_get_course_setting('student_delete_own_publication') == 1) {
2183 View Code Duplication
                        if (api_is_allowed_to_session_edit(false, true)) {
2184
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2185
                                Display::return_icon('edit.png', get_lang('Comment'), array(), ICON_SIZE_SMALL).'</a>';
2186
                        }
2187
                        $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').'"  >'.
2188
                            Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2189
                    } else {
2190
                        $action .= Display::return_icon('edit_na.png', get_lang('Modify'), array(), ICON_SIZE_SMALL);
2191
                    }
2192
                } else {
2193
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2194
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a>';
2195
                    $action .= Display::return_icon('edit_na.png', get_lang('Modify'), array(), ICON_SIZE_SMALL);
2196
                }
2197
2198
                // Status.
2199 View Code Duplication
                if (empty($work['qualificator_id'])) {
2200
                    $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
2201
                } else {
2202
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2203
                }
2204
                $work['qualificator_id'] = $qualificator_id;
2205
                $work['actions'] = '<div class="work-action">'.$send_to.$link_to_download.$action.'</div>';
2206
                $work['correction'] = $correction;
2207
2208
                $works[] = $work;
2209
            }
2210
        }
2211
2212
        return $works;
2213
    }
2214
}
2215
2216
/**
2217
 * Send reminder to users who have not given the task
2218
 *
2219
 * @param int
2220
 * @return array
2221
 * @author cvargas [email protected] cfasanando, [email protected]
2222
 */
2223
function send_reminder_users_without_publication($task_data)
2224
{
2225
    $_course = api_get_course_info();
2226
    $task_id = $task_data['id'];
2227
    $task_title = !empty($task_data['title']) ? $task_data['title'] : basename($task_data['url']);
2228
    $subject = '[' . api_get_setting('siteName') . '] ';
2229
2230
    // The body can be as long as you wish, and any combination of text and variables
2231
    $content = get_lang('ReminderToSubmitPendingTask')."\n".get_lang('CourseName').' : '.$_course['name']."\n";
2232
    $content .= get_lang('WorkName').' : '.$task_title."\n";
2233
    $list_users = get_list_users_without_publication($task_id);
2234
    $mails_sent_to = array();
2235
    foreach ($list_users as $user) {
2236
        $name_user = api_get_person_name($user[1], $user[0], null, PERSON_NAME_EMAIL_ADDRESS);
2237
        $dear_line = get_lang('Dear')." ".api_get_person_name($user[1], $user[0]) .", \n\n";
2238
        $body      = $dear_line.$content;
2239
        MessageManager::send_message($user[3], $subject, $body);
2240
        $mails_sent_to[] = $name_user;
2241
    }
2242
    return $mails_sent_to;
2243
}
2244
2245
/**
2246
 * Sends an email to the students of a course when a homework is created
2247
 *
2248
 * @param int $courseId course_id
2249
 * @param int $sessionId session_id
2250
 * @param int $workId work_id
2251
 *
2252
 *
2253
 * @author Guillaume Viguier <[email protected]>
2254
 * @author Julio Montoya <[email protected]> Adding session support - 2011
2255
 */
2256
function send_email_on_homework_creation($courseId, $sessionId = 0, $workId)
2257
{
2258
    $courseInfo = api_get_course_info_by_id($courseId);
2259
    $courseCode = $courseInfo['code'];
2260
    // Get the students of the course
2261 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...
2262
        $students = CourseManager::get_student_list_from_course_code($courseCode);
2263
    } else {
2264
        $students = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionId);
2265
    }
2266
    $emailsubject = '[' . api_get_setting('siteName') . '] '.get_lang('HomeworkCreated');
2267
    $currentUser = api_get_user_info(api_get_user_id());
2268
    if (!empty($students)) {
2269
        foreach($students as $student) {
2270
            $user_info = api_get_user_info($student["user_id"]);
2271
            if(!empty($user_info["mail"])) {
2272
                $name_user = api_get_person_name(
2273
                    $user_info["firstname"],
2274
                    $user_info["lastname"],
2275
                    null,
2276
                    PERSON_NAME_EMAIL_ADDRESS
2277
                );
2278
                $link = api_get_path(WEB_CODE_PATH) . 'work/work_list_all.php?' . api_get_cidreq() . '&id=' . $workId;
2279
                $emailbody = get_lang('Dear')." ".$name_user.",\n\n";
2280
                $emailbody .= get_lang('HomeworkHasBeenCreatedForTheCourse')." ".$courseCode.". "."\n\n".
2281
                    '<a href="'. $link . '">' . get_lang('PleaseCheckHomeworkPage') . '</a>';
2282
                $emailbody .= "\n\n".api_get_person_name($currentUser["firstname"], $currentUser["lastname"]);
2283
2284
                $additionalParameters = array(
2285
                    'smsType' => SmsPlugin::ASSIGNMENT_BEEN_CREATED_COURSE,
2286
                    'userId' => $student["user_id"],
2287
                    'courseTitle' => $courseCode,
2288
                    'link' => $link
2289
                );
2290
2291
                api_mail_html(
2292
                    $name_user,
2293
                    $user_info["mail"],
2294
                    $emailsubject,
2295
                    $emailbody,
2296
                    api_get_person_name(
2297
                        $currentUser["firstname"],
2298
                        $currentUser["lastname"],
2299
                        null,
2300
                        PERSON_NAME_EMAIL_ADDRESS
2301
                    ),
2302
                    $currentUser["mail"],
2303
                    null,
2304
                    null,
2305
                    null,
2306
                    $additionalParameters
2307
                );
2308
            }
2309
        }
2310
    }
2311
}
2312
2313
/**
2314
 * @param string $url
2315
 * @return bool
2316
 */
2317
function is_work_exist_by_url($url)
2318
{
2319
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2320
    $url = Database::escape_string($url);
2321
    $sql = "SELECT id FROM $work_table WHERE url='$url'";
2322
    $result = Database::query($sql);
2323
    if (Database::num_rows($result)> 0) {
2324
        $row = Database::fetch_row($result);
2325
        if (empty($row)) {
2326
            return false;
2327
        } else {
2328
            return true;
2329
        }
2330
    } else {
2331
        return false;
2332
    }
2333
}
2334
2335
/**
2336
 * Check if a user is the author of a work document.
2337
 * @param int $itemId
2338
 * @param int $userId
2339
 * @param int $courseId
2340
 * @param int $sessionId
2341
 * @return bool
2342
 */
2343
function user_is_author($itemId, $userId = null, $courseId = null, $sessionId = null)
2344
{
2345
    if (empty($itemId)) {
2346
        return false;
2347
    }
2348
2349
    if (empty($userId)) {
2350
        $userId = api_get_user_id();
2351
    }
2352
2353
    $isAuthor = false;
2354
    $is_allowed_to_edit = api_is_allowed_to_edit();
2355
2356
    if ($is_allowed_to_edit) {
2357
        $isAuthor = true;
2358
    } else {
2359
2360
        if (empty($courseId)) {
2361
            $courseId = api_get_course_int_id();
2362
        }
2363
        if (empty($sessionId)) {
2364
            $sessionId = api_get_session_id();
2365
        }
2366
2367
        $data = api_get_item_property_info($courseId, 'work', $itemId, $sessionId);
2368
        if ($data['insert_user_id'] == $userId) {
2369
            $isAuthor = true;
2370
        }
2371
2372
        $workData = get_work_data_by_id($itemId);
2373
        if ($workData['user_id'] == $userId) {
2374
            $isAuthor = true;
2375
        }
2376
    }
2377
2378
    if (!$isAuthor) {
2379
        return false;
2380
    }
2381
2382
    return $isAuthor;
2383
}
2384
2385
/**
2386
 * Get list of users who have not given the task
2387
 * @param int
2388
 * @param int
2389
 * @return array
2390
 * @author cvargas
2391
 * @author Julio Montoya <[email protected]> Fixing query
2392
 */
2393
function get_list_users_without_publication($task_id, $studentId = null)
2394
{
2395
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2396
    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2397
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
2398
    $session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2399
2400
    $users = getAllUserToWork($task_id, api_get_course_int_id());
2401
    $users = array_column($users, 'user_id');
2402
2403
    // Condition for the session
2404
    $session_id = api_get_session_id();
2405
    $course_id = api_get_course_int_id();
2406
    $task_id = intval($task_id);
2407
    $sessionCondition = api_get_session_condition($session_id);
2408
2409
    if ($session_id == 0) {
2410
        $sql = "SELECT user_id as id FROM $work_table
2411
                WHERE
2412
                    c_id = $course_id AND
2413
                    parent_id = '$task_id' AND
2414
                    active IN (0, 1)";
2415
    } else {
2416
        $sql = "SELECT user_id as id FROM $work_table
2417
                WHERE
2418
                    c_id = $course_id AND
2419
                    parent_id = '$task_id' $sessionCondition AND
2420
                    active IN (0, 1)";
2421
    }
2422
2423
    $result = Database::query($sql);
2424
    $users_with_tasks = array();
2425
    while ($row = Database::fetch_array($result)) {
2426
        $users_with_tasks[] = $row['id'];
2427
    }
2428
2429
    if ($session_id == 0) {
2430
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2431
                      FROM $table_course_user AS cu, $table_user AS u
2432
                      WHERE u.status != 1 and cu.c_id='".$course_id."' AND u.user_id = cu.user_id";
2433
    } else {
2434
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2435
                      FROM $session_course_rel_user AS cu, $table_user AS u
2436
                      WHERE
2437
                        u.status != 1 AND
2438
                        cu.c_id='".$course_id."' AND
2439
                        u.user_id = cu.user_id AND
2440
                        cu.session_id = '".$session_id."'";
2441
    }
2442
2443
    if (!empty($studentId)) {
2444
        $sql_users.= " AND u.user_id = ".intval($studentId);
2445
    }
2446
2447
    $group_id = api_get_group_id();
2448
    $new_group_user_list = array();
2449
2450 View Code Duplication
    if ($group_id) {
2451
        $groupInfo = GroupManager::get_group_properties($group_id);
2452
        $group_user_list = GroupManager::get_subscribed_users($groupInfo['iid']);
2453
        if (!empty($group_user_list)) {
2454
            foreach($group_user_list as $group_user) {
2455
                $new_group_user_list[] = $group_user['user_id'];
2456
            }
2457
        }
2458
    }
2459
2460
    $result_users = Database::query($sql_users);
2461
    $users_without_tasks = array();
2462
    while ($rowUsers = Database::fetch_array($result_users)) {
2463
        $userId = $rowUsers['user_id'];
2464
        if (in_array($userId, $users_with_tasks)) {
2465
            continue;
2466
        }
2467
2468
        if ($group_id && !in_array($userId, $new_group_user_list)) {
2469
            continue;
2470
        }
2471
2472
        if (!empty($users)) {
2473
            if (!in_array($userId, $users)) {
2474
                continue;
2475
            }
2476
        }
2477
2478
        $row_users = [];
2479
        $row_users[0] = $rowUsers['lastname'];
2480
        $row_users[1] = $rowUsers['firstname'];
2481
        $row_users[2] = Display::encrypted_mailto_link($rowUsers['email']);
2482
        $row_users[3] = $userId;
2483
        $users_without_tasks[] = $row_users;
2484
    }
2485
2486
    return $users_without_tasks;
2487
}
2488
2489
/**
2490
 * Display list of users who have not given the task
2491
 *
2492
 * @param int task id
2493
 * @param int $studentId
2494
 * @return array
2495
 * @author cvargas [email protected] cfasanando, [email protected]
2496
 * @author Julio Montoya <[email protected]> Fixes
2497
 */
2498
function display_list_users_without_publication($task_id, $studentId = null)
2499
{
2500
    global $origin;
2501
    $table_header[] = array(get_lang('LastName'), true);
2502
    $table_header[] = array(get_lang('FirstName'), true);
2503
    $table_header[] = array(get_lang('Email'), true);
2504
2505
    $data = get_list_users_without_publication($task_id);
2506
2507
    $sorting_options = array();
2508
    $sorting_options['column'] = 1;
2509
    $paging_options = array();
2510
    $my_params = array();
2511
2512
    if (isset($_GET['edit_dir'])) {
2513
        $my_params['edit_dir'] = Security::remove_XSS($_GET['edit_dir']);
2514
    }
2515
    if (isset($_GET['list'])) {
2516
        $my_params['list'] = Security::remove_XSS($_GET['list']);
2517
    }
2518
    $my_params['origin'] = $origin;
2519
    $my_params['id'] = intval($_GET['id']);
2520
2521
    //$column_show
2522
    $column_show[] = 1;
2523
    $column_show[] = 1;
2524
    $column_show[] = 1;
2525
    Display::display_sortable_config_table(
2526
        'work',
2527
        $table_header,
2528
        $data,
2529
        $sorting_options,
2530
        $paging_options,
2531
        $my_params,
2532
        $column_show
2533
    );
2534
}
2535
2536
/**
2537
 * @param int $documentId
2538
 * @param int $workId
2539
 * @param int $courseId
2540
 */
2541 View Code Duplication
function addDocumentToWork($documentId, $workId, $courseId)
2542
{
2543
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2544
    $params = array(
2545
        'document_id' => $documentId,
2546
        'work_id' => $workId,
2547
        'c_id' => $courseId
2548
    );
2549
    Database::insert($table, $params);
2550
}
2551
2552
/**
2553
 * @param int $documentId
2554
 * @param int $workId
2555
 * @param int $courseId
2556
 * @return array
2557
 */
2558 View Code Duplication
function getDocumentToWork($documentId, $workId, $courseId)
2559
{
2560
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2561
    $params = array(
2562
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2563
    );
2564
    return Database::select('*', $table, array('where' => $params));
2565
}
2566
2567
/**
2568
 * @param int $documentId
2569
 * @param int $workId
2570
 * @param int $courseId
2571
 * @param int $sessionId
2572
 * @param int $userId
2573
 * @param int $active
2574
 * @return array
2575
 */
2576
function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId, $active = 1)
2577
{
2578
    $workRel = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2579
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2580
2581
    $documentId = intval($documentId);
2582
    $workId = intval($workId);
2583
    $courseId = intval($courseId);
2584
    $userId = intval($userId);
2585
    $sessionId = intval($sessionId);
2586
    $active = intval($active);
2587
    $sessionCondition = api_get_session_condition($sessionId);
2588
2589
    $sql = "SELECT w.* FROM $work w INNER JOIN $workRel rel ON (w.parent_id = rel.work_id)
2590
            WHERE
2591
                w.document_id = $documentId AND
2592
                w.parent_id = $workId AND
2593
                w.c_id = $courseId
2594
                $sessionCondition AND
2595
                user_id = $userId AND
2596
                active = $active
2597
            ";
2598
2599
    $result = Database::query($sql);
2600
    $workInfo = array();
2601
    if (Database::num_rows($result)) {
2602
        $workInfo = Database::fetch_array($result, 'ASSOC');
2603
    }
2604
    return $workInfo;
2605
}
2606
2607
/**
2608
 *
2609
 * @param int $workId
2610
 * @param int $courseId
2611
 * @return array
2612
 */
2613 View Code Duplication
function getAllDocumentToWork($workId, $courseId)
2614
{
2615
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2616
    $params = array(
2617
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2618
    );
2619
    return Database::select('*', $table, array('where' => $params));
2620
}
2621
2622
/**
2623
 * @param int $documentId
2624
 * @param int $workId
2625
 * @param int $courseId
2626
 */
2627 View Code Duplication
function deleteDocumentToWork($documentId, $workId, $courseId)
2628
{
2629
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2630
    $params = array(
2631
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2632
    );
2633
    Database::delete($table, $params);
2634
}
2635
2636
/**
2637
 * @param int $userId
2638
 * @param int $workId
2639
 * @param int $courseId
2640
 */
2641 View Code Duplication
function addUserToWork($userId, $workId, $courseId)
2642
{
2643
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2644
    $params = array(
2645
        'user_id' => $userId,
2646
        'work_id' => $workId,
2647
        'c_id' => $courseId
2648
    );
2649
    Database::insert($table, $params);
2650
}
2651
2652
/**
2653
 * @param int $userId
2654
 * @param int $workId
2655
 * @param int $courseId
2656
 * @return array
2657
 */
2658 View Code Duplication
function getUserToWork($userId, $workId, $courseId)
2659
{
2660
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2661
    $params = array(
2662
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2663
    );
2664
    return Database::select('*', $table, array('where' => $params));
2665
}
2666
2667
/**
2668
 * @param int $workId
2669
 * @param int $courseId
2670
 * @param bool $getCount
2671
 * @return array|int
2672
 */
2673
function getAllUserToWork($workId, $courseId, $getCount = false)
2674
{
2675
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2676
    $params = array(
2677
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2678
    );
2679
    if ($getCount) {
2680
        $count = 0;
2681
        $result = Database::select(
2682
            'count(user_id) as count',
2683
            $table,
2684
            array('where' => $params),
2685
            'simple'
2686
        );
2687
        if (!empty($result)) {
2688
            $count = intval($result['count']);
2689
        }
2690
        return $count;
2691
    } else {
2692
        return Database::select('*', $table, array('where' => $params));
2693
    }
2694
}
2695
2696
/**
2697
 * @param int $userId
2698
 * @param int $workId
2699
 * @param int $courseId
2700
 */
2701 View Code Duplication
function deleteUserToWork($userId, $workId, $courseId)
2702
{
2703
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2704
    $params = array(
2705
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2706
    );
2707
    Database::delete($table, $params);
2708
}
2709
2710
/**
2711
 * @param int $userId
2712
 * @param int $workId
2713
 * @param int $courseId
2714
 * @return bool
2715
 */
2716
function userIsSubscribedToWork($userId, $workId, $courseId)
2717
{
2718
    $subscribedUsers = getAllUserToWork($workId, $courseId);
2719
2720
    if (empty($subscribedUsers)) {
2721
        return true;
2722
    } else {
2723
        $subscribedUsersList = array();
2724
        foreach ($subscribedUsers as $item) {
0 ignored issues
show
Bug introduced by
The expression $subscribedUsers of type integer|array 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...
2725
            $subscribedUsersList[] = $item['user_id'];
2726
        }
2727
        if (in_array($userId, $subscribedUsersList)) {
2728
            return true;
2729
        }
2730
    }
2731
    return false;
2732
}
2733
2734
/**
2735
 * Get the list of students that have to submit their work
2736
 * @param integer $workId The internal ID of the assignment
2737
 * @param integer $courseId The course ID
2738
 * @param integer $groupId The group ID, if any
2739
 * @param integer $sessionId The session ID, if any
2740
 * @param bool $getCount Whether we want just the amount or the full result
2741
 * @return array|int An integer (if we just asked for the count) or an array of users
2742
 */
2743
function getStudentSubscribedToWork(
2744
    $workId,
2745
    $courseId,
2746
    $groupId = null,
2747
    $sessionId = null,
2748
    $getCount = false
2749
) {
2750
    $usersInWork = null;
2751
    $usersInCourse = null;
2752
2753
    if (empty($groupId)) {
2754
        $courseInfo = api_get_course_info_by_id($courseId);
2755
        $status = STUDENT;
2756
        if (!empty($sessionId)) {
2757
            $status = 0;
2758
        }
2759
        $usersInCourse = CourseManager::get_user_list_from_course_code(
2760
            $courseInfo['code'],
2761
            $sessionId,
2762
            null,
2763
            null,
2764
            $status,
2765
            $getCount
2766
        );
2767
    } else {
2768
        $usersInCourse = GroupManager::get_users(
2769
            $groupId,
2770
            false,
2771
            null,
2772
            null,
2773
            $getCount,
2774
            $courseId
2775
        );
2776
    }
2777
2778
    $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
2779
2780
    if (empty($usersInWork)) {
2781
        return $usersInCourse;
2782
    } else {
2783
        return $usersInWork;
2784
    }
2785
2786
}
2787
2788
/**
2789
 * @param int $userId
2790
 * @param int $workId
2791
 * @param int $courseId
2792
 * @return bool
2793
 */
2794
function allowOnlySubscribedUser($userId, $workId, $courseId)
2795
{
2796
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2797
        return true;
2798
    }
2799
2800
    if (userIsSubscribedToWork($userId, $workId, $courseId) == false) {
2801
        api_not_allowed(true);
2802
    }
2803
}
2804
2805
/**
2806
 * @param int $workId
2807
 * @param array $courseInfo
2808
 * @param int $documentId
2809
 * @return array
2810
 */
2811
function getDocumentTemplateFromWork($workId, $courseInfo, $documentId)
2812
{
2813
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2814
    if (!empty($documents)) {
2815
        foreach ($documents as $doc) {
2816
            if ($documentId != $doc['document_id']) {
2817
                continue;
2818
            }
2819
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2820
            $fileInfo = pathinfo($docData['path']);
2821
            if ($fileInfo['extension'] == 'html') {
2822
                if (file_exists($docData['absolute_path']) && is_file($docData['absolute_path'])) {
2823
                    $docData['file_content'] = file_get_contents($docData['absolute_path']);
2824
                    return $docData;
2825
                }
2826
            }
2827
        }
2828
    }
2829
    return array();
2830
}
2831
2832
/**
2833
 * @param int $workId
2834
 * @param array $courseInfo
2835
 * @return string
2836
 */
2837
function getAllDocumentsFromWorkToString($workId, $courseInfo)
2838
{
2839
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2840
    $content = null;
2841
    if (!empty($documents)) {
2842
        $content .= '<ul class="nav nav-list well">';
2843
        $content .= '<li class="nav-header">'.get_lang('Documents').'</li>';
2844
        foreach ($documents as $doc) {
2845
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2846
            if ($docData) {
2847
                $content .= '<li><a target="_blank" href="'.$docData['url'].'">'.$docData['title'].'</a></li>';
2848
            }
2849
        }
2850
        $content .= '</ul><br />';
2851
    }
2852
    return $content;
2853
}
2854
2855
/**
2856
 * Returns fck editor toolbar
2857
 * @return array
2858
 */
2859
function getWorkDescriptionToolbar()
2860
{
2861
    return array(
2862
        'ToolbarStartExpanded' => 'true',
2863
        'ToolbarSet' => 'Work',
2864
        'Width' => '100%',
2865
        'Height' => '400'
2866
    );
2867
}
2868
2869
/**
2870
 * @param array $work
2871
 * @return array
2872
 */
2873
function getWorkComments($work)
2874
{
2875
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2876
    $userTable= Database::get_main_table(TABLE_MAIN_USER);
2877
2878
    $courseId = intval($work['c_id']);
2879
    $workId = intval($work['id']);
2880
2881
    if (empty($courseId) || empty($workId)) {
2882
        return array();
2883
    }
2884
2885
    $sql = "SELECT
2886
                c.id, 
2887
                c.user_id
2888
            FROM $commentTable c
2889
            INNER JOIN $userTable u 
2890
            ON (u.id = c.user_id)
2891
            WHERE c_id = $courseId AND work_id = $workId
2892
            ORDER BY sent_at
2893
            ";
2894
    $result = Database::query($sql);
2895
    $comments = Database::store_result($result, 'ASSOC');
2896
    if (!empty($comments)) {
2897
        foreach ($comments as &$comment) {
2898
            $userInfo = api_get_user_info($comment['user_id']);
2899
            $comment['picture'] = $userInfo['avatar'];
2900
            $comment['complete_name'] = $userInfo['complete_name_with_username'];
2901
            $commentInfo = getWorkComment($comment['id']);
2902
            if (!empty($commentInfo)) {
2903
                $comment = array_merge($comment, $commentInfo);
2904
            }
2905
        }
2906
    }
2907
    return $comments;
2908
}
2909
2910
/**
2911
 * Get total score from a work list
2912
 * @param $workList
2913
 * @return int|null
2914
 */
2915
function getTotalWorkScore($workList)
2916
{
2917
    $count = 0;
2918
    foreach ($workList as $data) {
2919
        $count += $data['qualification_score'];
2920
    }
2921
    return $count;
2922
}
2923
2924
2925
/**
2926
 * Get comment count from a work list (docs sent by students)
2927
 * @param array $workList
2928
 * @param array $courseInfo
2929
 * @return int|null
2930
 */
2931
function getTotalWorkComment($workList, $courseInfo = array())
2932
{
2933
    if (empty($courseInfo)) {
2934
        $courseInfo = api_get_course_info();
2935
    }
2936
2937
    $count = 0;
2938
    foreach ($workList as $data) {
2939
        $count += getWorkCommentCount($data['id'], $courseInfo);
2940
    }
2941
    return $count;
2942
}
2943
2944
/**
2945
 * Get comment count for a specific work sent by a student.
2946
 * @param int $id
2947
 * @param array $courseInfo
2948
 * @return int
2949
 */
2950
function getWorkCommentCount($id, $courseInfo = array())
2951
{
2952
    if (empty($courseInfo)) {
2953
        $courseInfo = api_get_course_info();
2954
    }
2955
2956
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2957
    $id = intval($id);
2958
2959
    $sql = "SELECT count(*) as count
2960
            FROM $commentTable
2961
            WHERE work_id = $id AND c_id = ".$courseInfo['real_id'];
2962
2963
    $result = Database::query($sql);
2964
    if (Database::num_rows($result)) {
2965
        $comment = Database::fetch_array($result);
2966
        return $comment['count'];
2967
    }
2968
2969
    return 0;
2970
}
2971
2972
/**
2973
 * Get comment count for a specific parent
2974
 * @param int $parentId
2975
 * @param array $courseInfo
2976
 * @param int $sessionId
2977
 * @return int
2978
 */
2979 View Code Duplication
function getWorkCommentCountFromParent(
2980
    $parentId,
2981
    $courseInfo = array(),
2982
    $sessionId = 0
2983
) {
2984
    if (empty($courseInfo)) {
2985
        $courseInfo = api_get_course_info();
2986
    }
2987
2988
    if (empty($sessionId)) {
2989
        $sessionId = api_get_session_id();
2990
    } else {
2991
        $sessionId = intval($sessionId);
2992
    }
2993
2994
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2995
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2996
    $parentId = intval($parentId);
2997
    $sessionCondition = api_get_session_condition($sessionId, false, false, 'w.session_id');
2998
2999
    $sql = "SELECT count(*) as count
3000
            FROM $commentTable c INNER JOIN $work w
3001
            ON c.c_id = w.c_id AND w.id = c.work_id
3002
            WHERE
3003
                $sessionCondition AND
3004
                parent_id = $parentId AND
3005
                w.c_id = ".$courseInfo['real_id'];
3006
3007
    $result = Database::query($sql);
3008
    if (Database::num_rows($result)) {
3009
        $comment = Database::fetch_array($result);
3010
        return $comment['count'];
3011
    }
3012
3013
    return 0;
3014
}
3015
3016
/**
3017
 * Get last work information from parent
3018
 * @param int $parentId
3019
 * @param array $courseInfo
3020
 * @param int $sessionId
3021
 * @return int
3022
 */
3023 View Code Duplication
function getLastWorkStudentFromParent(
3024
    $parentId,
3025
    $courseInfo = array(),
3026
    $sessionId = 0
3027
) {
3028
    if (empty($courseInfo)) {
3029
        $courseInfo = api_get_course_info();
3030
    }
3031
3032
    if (empty($sessionId)) {
3033
        $sessionId = api_get_session_id();
3034
    } else {
3035
        $sessionId = intval($sessionId);
3036
    }
3037
3038
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3039
    $sessionCondition = api_get_session_condition($sessionId, false);
3040
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3041
    $parentId = intval($parentId);
3042
3043
    $sql = "SELECT w.*
3044
            FROM $commentTable c INNER JOIN $work w
3045
            ON c.c_id = w.c_id AND w.id = c.work_id
3046
            WHERE
3047
                $sessionCondition AND
3048
                parent_id = $parentId AND
3049
                w.c_id = ".$courseInfo['real_id']."
3050
            ORDER BY w.sent_date
3051
            LIMIT 1
3052
            ";
3053
3054
    $result = Database::query($sql);
3055
    if (Database::num_rows($result)) {
3056
        $comment = Database::fetch_array($result, 'ASSOC');
3057
3058
        return $comment;
3059
    }
3060
3061
    return array();
3062
}
3063
3064
/**
3065
 * Get last work information from parent
3066
 * @param int $parentId
3067
 * @param array $courseInfo
3068
 * @param int $sessionId
3069
 * @return int
3070
 */
3071
function getLastWorkStudentFromParentByUser(
3072
    $userId,
3073
    $parentId,
3074
    $courseInfo = array(),
3075
    $sessionId = 0
3076
) {
3077
    if (empty($courseInfo)) {
3078
        $courseInfo = api_get_course_info();
3079
    }
3080
3081
    if (empty($sessionId)) {
3082
        $sessionId = api_get_session_id();
3083
    } else {
3084
        $sessionId = intval($sessionId);
3085
    }
3086
3087
    $userId = intval($userId);
3088
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3089
    $parentId = intval($parentId);
3090
    $sessionCondition = api_get_session_condition($sessionId);
3091
3092
    $sql = "SELECT *
3093
            FROM $work
3094
            WHERE
3095
                user_id = $userId
3096
                $sessionCondition AND
3097
                parent_id = $parentId AND
3098
                c_id = ".$courseInfo['real_id']."
3099
            ORDER BY sent_date DESC
3100
            LIMIT 1
3101
            ";
3102
    $result = Database::query($sql);
3103
    if (Database::num_rows($result)) {
3104
        $work = Database::fetch_array($result, 'ASSOC');
3105
3106
        return $work;
3107
    }
3108
3109
    return array();
3110
}
3111
3112
/**
3113
 * @param int $id comment id
3114
 * @param array $courseInfo
3115
 * @return string
3116
 */
3117
function getWorkComment($id, $courseInfo = array())
3118
{
3119
    if (empty($courseInfo)) {
3120
        $courseInfo = api_get_course_info();
3121
    }
3122
3123
    if (empty($courseInfo['real_id'])) {
3124
        return array();
3125
    }
3126
3127
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3128
    $id = intval($id);
3129
3130
    $sql = "SELECT * FROM $commentTable
3131
            WHERE id = $id AND c_id = ".$courseInfo['real_id'];
3132
    $result = Database::query($sql);
3133
    $comment = array();
3134
    if (Database::num_rows($result)) {
3135
        $comment = Database::fetch_array($result, 'ASSOC');
3136
        $filePath = null;
3137
        $fileUrl = null;
3138
        $deleteUrl = null;
3139
        $fileName = null;
3140
        if (!empty($comment['file'])) {
3141
            $work = get_work_data_by_id($comment['work_id']);
3142
            $workParent = get_work_data_by_id($work['parent_id']);
3143
            $filePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/'.$workParent['url'].'/'.$comment['file'];
3144
            $fileUrl = api_get_path(WEB_CODE_PATH).'work/download_comment_file.php?comment_id='.$id.'&'.api_get_cidreq();
3145
            $deleteUrl = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$comment['work_id'].'&action=delete_attachment&comment_id='.$id;
3146
            $fileParts = explode('_', $comment['file']);
3147
            $fileName = str_replace($fileParts[0].'_'.$fileParts[1].'_', '', $comment['file']);
3148
        }
3149
        $comment['delete_file_url'] = $deleteUrl;
3150
        $comment['file_path'] = $filePath;
3151
        $comment['file_url'] = $fileUrl;
3152
        $comment['file_name_to_show'] = $fileName;
3153
    }
3154
3155
    return $comment;
3156
}
3157
3158
/**
3159
 * @param int $id
3160
 * @param array $courseInfo
3161
 */
3162
function deleteCommentFile($id, $courseInfo = array())
3163
{
3164
    $workComment = getWorkComment($id, $courseInfo);
3165
    if (isset($workComment['file']) && !empty($workComment['file'])) {
3166
        if (file_exists($workComment['file_path'])) {
3167
            $result = my_delete($workComment['file_path']);
3168
            if ($result) {
3169
                $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3170
                $params = array('file' => '');
3171
                Database::update(
3172
                    $commentTable,
3173
                    $params,
3174
                    array('id = ? AND c_id = ? ' => array($workComment['id'], $workComment['c_id']))
3175
                );
3176
            }
3177
        }
3178
    }
3179
}
3180
3181
/**
3182
 * Adds a comments to the work document
3183
 * @param array $courseInfo
3184
 * @param int $userId
3185
 * @param array $work
3186
 * @param array $data
3187
 * @return int
3188
 */
3189
function addWorkComment($courseInfo, $userId, $parentWork, $work, $data)
3190
{
3191
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3192
3193
    $params = array(
3194
        'work_id' => $work['id'],
3195
        'c_id' => $work['c_id'],
3196
        'user_id' => $userId,
3197
        'comment' => $data['comment'],
3198
        'sent_at' => api_get_utc_datetime()
3199
    );
3200
3201
    $commentId = Database::insert($commentTable, $params);
3202
3203
    if ($commentId) {
3204
        $sql = "UPDATE $commentTable SET id = iid WHERE iid = $commentId";
3205
        Database::query($sql);
3206
    }
3207
3208
    $userIdListToSend = array();
3209
3210
    if (api_is_allowed_to_edit()) {
3211
        if (isset($data['send_mail']) && $data['send_mail']) {
3212
            // Teacher sends a feedback
3213
            $userIdListToSend = array($work['user_id']);
3214
        }
3215
    } else {
3216
        $sessionId = api_get_session_id();
3217
        if (empty($sessionId)) {
3218
            $teachers = CourseManager::get_teacher_list_from_course_code(
3219
                $courseInfo['code']
3220
            );
3221
            if (!empty($teachers)) {
3222
                $userIdListToSend = array_keys($teachers);
3223
            }
3224
        } else {
3225
            $teachers = SessionManager::getCoachesByCourseSession(
3226
                $sessionId,
3227
                $courseInfo['code']
3228
            );
3229
3230
            if (!empty($teachers)) {
3231
                $userIdListToSend = array_values($teachers);
3232
            }
3233
        }
3234
    }
3235
3236
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$work['id'];
3237
    $subject = sprintf(get_lang('ThereIsANewWorkFeedback'), $parentWork['title']);
3238
    $content = sprintf(get_lang('ThereIsANewWorkFeedbackInWorkXHere'), $work['title'], $url);
3239
3240
    if (!empty($userIdListToSend)) {
3241
        foreach ($userIdListToSend as $userIdToSend) {
3242
            MessageManager::send_message_simple(
3243
                $userIdToSend,
3244
                $subject,
3245
                $content
3246
            );
3247
        }
3248
    }
3249
3250
    $fileData = isset($data['file']) ? $data['file'] : null;
3251
    if (!empty($commentId) && !empty($fileData)) {
3252
        $workParent = get_work_data_by_id($work['parent_id']);
3253
        if (!empty($workParent)) {
3254
            $uploadDir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work'.$workParent['url'];
3255
            $newFileName = 'comment_'.$commentId.'_'.php2phps(api_replace_dangerous_char($fileData['name']));
3256
            $newFilePath = $uploadDir.'/'.$newFileName;
3257
            $result = move_uploaded_file($fileData['tmp_name'], $newFilePath);
3258
            if ($result) {
3259
                $params = array('file' => $newFileName);
3260
                Database::update(
3261
                    $commentTable,
3262
                    $params,
3263
                    array('id = ? AND c_id = ? ' => array($commentId, $work['c_id']))
3264
                );
3265
            }
3266
        }
3267
    }
3268
}
3269
3270
/**
3271
 * @param array $work
3272
 * @param string $page
3273
 * @return string
3274
 */
3275
function getWorkCommentForm($work, $page = 'view')
3276
{
3277
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&action=send_comment&'.api_get_cidreq().'&page='.$page;
3278
    $form = new FormValidator(
3279
        'work_comment',
3280
        'post',
3281
        $url
3282
    );
3283
3284
    $form->addElement('file', 'file', get_lang('Attachment'));
3285
    $form->addHtmlEditor('comment', get_lang('Comment'));
3286
    $form->addElement('hidden', 'id', $work['id']);
3287
    $form->addElement('hidden', 'page', $page);
3288
    if (api_is_allowed_to_edit()) {
3289
        $form->addElement('checkbox', 'send_mail', null, get_lang('SendMail'));
3290
    }
3291
    $form->addButtonSend(get_lang('Send'), 'button');
3292
3293
    return $form->returnForm();
3294
}
3295
3296
/**
3297
 * @param array $homework result of get_work_assignment_by_id()
3298
 * @return string
3299
 */
3300
function getWorkDateValidationStatus($homework)
3301
{
3302
    $message = null;
3303
    $has_expired = false;
3304
    $has_ended = false;
3305
3306
    if (!empty($homework)) {
3307 View Code Duplication
        if (!empty($homework['expires_on']) || !empty($homework['ends_on'])) {
3308
            $time_now = time();
3309
3310
            if (!empty($homework['expires_on'])) {
3311
                $time_expires = api_strtotime($homework['expires_on'], 'UTC');
3312
                $difference = $time_expires - $time_now;
3313
                if ($difference < 0) {
3314
                    $has_expired = true;
3315
                }
3316
            }
3317
3318
            if (empty($homework['expires_on'])) {
3319
                $has_expired = false;
3320
            }
3321
3322
            if (!empty($homework['ends_on'])) {
3323
                $time_ends = api_strtotime($homework['ends_on'], 'UTC');
3324
                $difference2 = $time_ends - $time_now;
3325
                if ($difference2 < 0) {
3326
                    $has_ended = true;
3327
                }
3328
            }
3329
3330
            $ends_on = api_convert_and_format_date($homework['ends_on']);
3331
            $expires_on = api_convert_and_format_date($homework['expires_on']);
3332
        }
3333
3334
        if ($has_ended) {
3335
            $message = Display::return_message(get_lang('EndDateAlreadyPassed').' '.$ends_on, 'error');
3336
        } elseif ($has_expired) {
3337
            $message = Display::return_message(get_lang('ExpiryDateAlreadyPassed').' '.$expires_on, 'warning');
3338
        } else {
3339
            if ($has_expired) {
3340
                $message = Display::return_message(get_lang('ExpiryDateToSendWorkIs').' '.$expires_on);
3341
            }
3342
        }
3343
    }
3344
3345
    return array(
3346
        'message' => $message,
3347
        'has_ended' => $has_ended,
3348
        'has_expired' => $has_expired
3349
    );
3350
}
3351
3352
/**
3353
 * @param FormValidator $form
3354
 * @param int $uploadFormType
3355
 */
3356
function setWorkUploadForm($form, $uploadFormType = 0)
3357
{
3358
    $form->addElement('header', get_lang('UploadADocument'));
3359
    $form->addElement('hidden', 'contains_file', 0, array('id'=>'contains_file_id'));
3360
    $form->addElement('hidden', 'active', 1);
3361
    $form->addElement('hidden', 'accepted', 1);
3362
    $form->addElement('text', 'title', get_lang('Title'), array('id' => 'file_upload'));
3363
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
3364
3365
    switch ($uploadFormType) {
3366 View Code Duplication
        case 0:
3367
            // File and text.
3368
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3369
            $form->addProgress();
3370
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3371
            break;
3372 View Code Duplication
        case 1:
3373
            // Only text.
3374
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3375
            $form->addRule('description', get_lang('ThisFieldIsRequired'), 'required');
3376
            break;
3377
        case 2:
3378
            // Only file.
3379
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3380
            $form->addProgress();
3381
            $form->addRule('file', get_lang('ThisFieldIsRequired'), 'required');
3382
            break;
3383
    }
3384
3385
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
3386
}
3387
3388
/**
3389
 * @param array $my_folder_data
3390
 * @param array $_course
3391
 * @param bool $isCorrection
3392
 * @param array $workInfo
3393
 * @param array $file
3394
 *
3395
 * @return array
3396
 */
3397
function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo = [], $file = [])
3398
{
3399
    if (isset($_FILES['file']) && !empty($_FILES['file'])) {
3400
        $file = $_FILES['file'];
3401
    }
3402
3403
    if (empty($file['size'])) {
3404
        return array(
3405
            'error' => Display:: return_message(
3406
                get_lang('UplUploadFailedSizeIsZero'),
3407
                'error'
3408
            ),
3409
        );
3410
    }
3411
    $updir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work/'; //directory path to upload
3412
3413
    // Try to add an extension to the file if it has'nt one
3414
    $filename = add_ext_on_mime(stripslashes($file['name']), $file['type']);
3415
3416
    // Replace dangerous characters
3417
    $filename = api_replace_dangerous_char($filename);
3418
3419
    // Transform any .php file in .phps fo security
3420
    $filename = php2phps($filename);
3421
    $filesize = filesize($file['tmp_name']);
3422
3423
    if (empty($filesize)) {
3424
        return array(
3425
            'error' => Display:: return_message(
3426
                get_lang('UplUploadFailedSizeIsZero'),
3427
                'error'
3428
            )
3429
        );
3430
    } elseif (!filter_extension($new_file_name)) {
3431
        return array(
3432
            'error' => Display:: return_message(
3433
                get_lang('UplUnableToSaveFileFilteredExtension'),
3434
                'error'
3435
            )
3436
        );
3437
    }
3438
3439
    $totalSpace = DocumentManager::documents_total_space($_course['real_id']);
3440
    $course_max_space = DocumentManager::get_course_quota($_course['code']);
3441
    $total_size = $filesize + $totalSpace;
3442
3443
    if ($total_size > $course_max_space) {
3444
        return array(
3445
            'error' => Display :: return_message(get_lang('NoSpace'), 'error')
3446
        );
3447
    }
3448
3449
    // Compose a unique file name to avoid any conflict
3450
    $new_file_name = api_get_unique_id();
3451
3452
    if ($isCorrection) {
3453
        if (!empty($workInfo['url'])) {
3454
            $new_file_name = basename($workInfo['url']).'_correction';
3455
        } else {
3456
            $new_file_name = $new_file_name.'_correction';
3457
        }
3458
    }
3459
3460
    $curdirpath = basename($my_folder_data['url']);
3461
    // If we come from the group tools the groupid will be saved in $work_table
3462
    if (is_dir($updir.$curdirpath) || empty($curdirpath)) {
3463
        $result = move_uploaded_file(
3464
            $file['tmp_name'],
3465
            $updir.$curdirpath.'/'.$new_file_name
3466
        );
3467
    } else {
3468
        return array(
3469
            'error' => Display :: return_message(
3470
                get_lang('FolderDoesntExistsInFileSystem'),
3471
                'error'
3472
            )
3473
        );
3474
    }
3475
3476
    $url = null;
3477
    if ($result) {
3478
        $url = 'work/'.$curdirpath.'/'.$new_file_name;
3479
    } else {
3480
        return false;
3481
    }
3482
3483
    return array(
3484
        'url' => $url,
3485
        'filename' => $filename,
3486
        'filesize' => $filesize,
3487
        'error' => null
3488
    );
3489
}
3490
3491
/**
3492
 * Send an e-mail to users related to this work (course teachers, usually, but
3493
 * might include other group members)
3494
 * @param int $workId
3495
 * @param array $courseInfo
3496
 * @param int $session_id
3497
 */
3498
function sendAlertToUsers($workId, $courseInfo, $session_id)
3499
{
3500
    $user_list = array();
3501
    //$workData = get_work_assignment_by_id($workId, $courseInfo['real_id']);
3502
    $workData = get_work_data_by_id($workId, $courseInfo['real_id'], $session_id);
3503
    //last value is to check this is not "just" an edit
3504
    //YW Tis part serve to send a e-mail to the tutors when a new file is sent
3505
    $send = api_get_course_setting('email_alert_manager_on_new_doc');
3506
3507
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_TEACHERS) {
3508
        // Lets predefine some variables. Be sure to change the from address!
3509
        if (empty($session_id)) {
3510
            //Teachers
3511
            $user_list = CourseManager::get_user_list_from_course_code(
3512
                api_get_course_id(),
3513
                null,
3514
                null,
3515
                null,
3516
                COURSEMANAGER
3517
            );
3518
        } else {
3519
            // Coaches
3520
            $user_list = CourseManager::get_user_list_from_course_code(
3521
                api_get_course_id(),
3522
                $session_id,
3523
                null,
3524
                null,
3525
                2
3526
            );
3527
        }
3528
    }
3529
3530
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_STUDENTS) {
3531
        if (!$session_id) {
3532
            $session_id = null;
3533
        }
3534
        $student = CourseManager::get_user_list_from_course_code(
3535
            api_get_course_id(),
3536
            $session_id,
3537
            null,
3538
            null,
3539
            STUDENT,
3540
            null,
3541
            null,
3542
            null,
3543
            null,
3544
            null,
3545
            array(api_get_user_id())
3546
        );
3547
        $user_list = array_merge($user_list, $student);
3548
    }
3549
3550
    if ($send) {
3551
        $senderEmail = api_get_setting('emailAdministrator');
3552
        $senderName = api_get_person_name(
3553
            api_get_setting('administratorName'),
3554
            api_get_setting('administratorSurname'),
3555
            null,
3556
            PERSON_NAME_EMAIL_ADDRESS
3557
        );
3558
        $subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n ".get_lang('CourseName').": ".$courseInfo['name']."  ";
3559
        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...
3560
            $to_user_id = $user_data['user_id'];
3561
            $user_info = api_get_user_info($to_user_id);
3562
            $message = get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']."\n";
3563
            $message .= get_lang('UserName')." : ".api_get_person_name($user_info['firstname'], $user_info['lastname'])."\n";
3564
            $message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."\n";
3565
            $url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
3566
            $message .= get_lang('WorkName')." : ".$workData['title']."\n\n".'<a href="'.$url.'">'.get_lang('DownloadLink')."</a>\n";
3567
            //$message .= $url;
3568
            MessageManager::send_message_simple($to_user_id, $subject, $message);
3569
            api_mail_html(
3570
                api_get_person_name(
3571
                    $user_info['firstname'].' '.$user_info['lastname'],
3572
                    null,
3573
                    PERSON_NAME_EMAIL_ADDRESS
3574
                ),
3575
                $user_info['email'],
3576
                $subject,
3577
                $message,
3578
                $senderName,
3579
                $senderEmail
3580
            );
3581
        }
3582
    }
3583
}
3584
3585
/**
3586
 * Check if the current uploaded work filename already exists in the current assement
3587
 *
3588
 * @param $filename
3589
 * @param $workId
3590
 * @return mixed
3591
 */
3592 View Code Duplication
function checkExistingWorkFileName($filename, $workId)
3593
{
3594
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3595
    $filename = Database::escape_string($filename);
3596
    $sql = "SELECT title FROM $work_table
3597
                        WHERE parent_id = $workId AND title = '$filename' AND active = 1";
3598
    $result = Database::query($sql);
3599
    return Database::fetch_assoc($result);
3600
}
3601
3602
/**
3603
 * @param array $workInfo
3604
 * @param array $values
3605
 * @param array $courseInfo
3606
 * @param int $sessionId
3607
 * @param int $groupId
3608
 * @param int $userId
3609
 * @param array $file
3610
 * @param bool  $checkDuplicated
3611
 * @param bool  $showFlashMessage
3612
 *
3613
 * @return null|string
3614
 */
3615
function processWorkForm(
3616
    $workInfo,
3617
    $values,
3618
    $courseInfo,
3619
    $sessionId,
3620
    $groupId,
3621
    $userId,
3622
    $file = [],
3623
    $checkDuplicated = false,
3624
    $showFlashMessage = true
3625
) {
3626
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3627
3628
    $courseId = $courseInfo['real_id'];
3629
    $groupId = intval($groupId);
3630
    $sessionId = intval($sessionId);
3631
    $userId = intval($userId);
3632
3633
    $title = $values['title'];
3634
    $description = $values['description'];
3635
    $contains_file = isset($values['contains_file']) && !empty($values['contains_file']) ? intval($values['contains_file']): 0;
3636
3637
    $saveWork = true;
3638
    $filename = null;
3639
    $url = null;
3640
    $filesize = null;
3641
    $workData = [];
3642
3643
    if ($values['contains_file']) {
3644
        if ($checkDuplicated) {
3645
            if (checkExistingWorkFileName($file['name'], $workInfo['id'])) {
3646
                $saveWork = false;
3647
                $workData['error'] = get_lang('YouAlreadySentThisFile');
3648
            } else {
3649
                $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3650
            }
3651
        } else {
3652
            $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3653
        }
3654
3655
        if (isset($result['error'])) {
3656
            if ($showFlashMessage) {
3657
                $message = $result['error'];
3658
                Display::addFlash($message);
3659
            }
3660
3661
            $saveWork = false;
3662
        }
3663
    }
3664
3665
    $workData = [];
3666
    if ($saveWork) {
3667
        $filename = isset($result['filename']) ? $result['filename'] : null;
3668
        if (empty($title)) {
3669
            $title = isset($result['title']) && !empty($result['title']) ? $result['title'] : get_lang('Untitled');
3670
        }
3671
        $filesize = isset($result['filesize']) ? $result['filesize'] : null;
3672
        $url = isset($result['url']) ? $result['url'] : null;
3673
    }
3674
3675
    if (empty($title)) {
3676
        $title = get_lang('Untitled');
3677
    }
3678
3679
    $groupIid = 0;
3680
    if ($groupId) {
3681
        $groupInfo = GroupManager::get_group_properties($groupId);
3682
        $groupIid = $groupInfo['iid'];
3683
    }
3684
3685
    if ($saveWork) {
3686
        $active = '1';
3687
        $params = [
3688
            'c_id' => $courseId,
3689
            'url' => $url,
3690
            'filetype' => 'file',
3691
            'title' => $title,
3692
            'description' => $description,
3693
            'contains_file' => $contains_file,
3694
            'active' => $active,
3695
            'accepted' => '1',
3696
            'qualificator_id' => 0,
3697
            'document_id' => 0,
3698
            'weight' => 0,
3699
            'allow_text_assignment' => 0,
3700
            'post_group_id' => $groupIid,
3701
            'sent_date' => api_get_utc_datetime(),
3702
            'parent_id' => $workInfo['id'],
3703
            'session_id' => $sessionId ? $sessionId : null,
3704
            'user_id' => $userId,
3705
            'has_properties' => 0,
3706
            'qualification' => 0
3707
            //'filesize' => $filesize
3708
        ];
3709
        $workId = Database::insert($work_table, $params);
3710
3711
        if ($workId) {
3712
            $sql = "UPDATE $work_table SET id = iid WHERE iid = $workId ";
3713
            Database::query($sql);
3714
3715 View Code Duplication
            if (array_key_exists('filename', $workInfo) && !empty($filename)) {
3716
                $filename = Database::escape_string($filename);
3717
                $sql = "UPDATE $work_table SET
3718
                            filename = '$filename'
3719
                        WHERE iid = $workId";
3720
                Database::query($sql);
3721
            }
3722
3723
            if (array_key_exists('document_id', $workInfo)) {
3724
                $documentId = isset($values['document_id']) ? intval($values['document_id']) : 0;
3725
                $sql = "UPDATE $work_table SET
3726
                            document_id = '$documentId'
3727
                        WHERE iid = $workId";
3728
                Database::query($sql);
3729
            }
3730
            api_item_property_update(
3731
                $courseInfo,
3732
                'work',
3733
                $workId,
3734
                'DocumentAdded',
3735
                $userId,
3736
                $groupIid
3737
            );
3738
            sendAlertToUsers($workId, $courseInfo, $sessionId);
3739
            Event::event_upload($workId);
3740
            $workData = get_work_data_by_id($workId);
3741
            if ($showFlashMessage) {
3742
                Display::addFlash(Display::return_message(get_lang('DocAdd')));
3743
            }
3744
        }
3745
    } else {
3746
        if ($showFlashMessage) {
3747
            Display::addFlash(
3748
                Display::return_message(
3749
                    get_lang('IsNotPosibleSaveTheDocument'),
3750
                    'error'
3751
                )
3752
            );
3753
        }
3754
    }
3755
3756
    return $workData;
3757
}
3758
3759
/**
3760
 * Creates a new task (directory) in the assignment tool
3761
 * @param array $formValues
3762
 * @param int $user_id
3763
 * @param array $courseInfo
3764
 * @param int $group_id
0 ignored issues
show
Bug introduced by
There is no parameter named $group_id. 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...
3765
 * @param int $session_id
3766
 * @return bool|int
3767
 * @note $params can have the following elements, but should at least have the 2 first ones: (
3768
 *       'new_dir' => 'some-name',
3769
 *       'description' => 'some-desc',
3770
 *       'qualification' => 20 (e.g. 20),
3771
 *       'weight' => 50 (percentage) to add to gradebook (e.g. 50),
3772
 *       'allow_text_assignment' => 0/1/2,
3773
 * @todo Rename createAssignment or createWork, or something like that
3774
 */
3775
function addDir($formValues, $user_id, $courseInfo, $groupId, $session_id)
3776
{
3777
    $em = Database::getManager();
3778
3779
    $user_id = intval($user_id);
3780
    $groupId = intval($groupId);
3781
3782
    $groupIid = 0;
3783
    if (!empty($groupId)) {
3784
        $groupInfo = GroupManager::get_group_properties($groupId);
3785
        $groupIid = $groupInfo['iid'];
3786
    }
3787
    $session = $em->find('ChamiloCoreBundle:Session', $session_id);
3788
3789
    $base_work_dir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work';
3790
    $course_id = $courseInfo['real_id'];
3791
3792
    $directory = api_replace_dangerous_char($formValues['new_dir']);
3793
    $directory = disable_dangerous_file($directory);
3794
    $created_dir = create_unexisting_work_directory($base_work_dir, $directory);
3795
3796
    if (empty($created_dir)) {
3797
        return false;
3798
    }
3799
3800
    $dirName = '/'.$created_dir;
3801
    $today = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
3802
3803
    $workTable = new CStudentPublication();
3804
    $workTable
3805
        ->setCId($course_id)
3806
        ->setUrl($dirName)
3807
        ->setTitle($formValues['new_dir'])
3808
        ->setDescription($formValues['description'])
3809
        ->setActive(true)
3810
        ->setAccepted(true)
3811
        ->setFiletype('folder')
3812
        ->setPostGroupId($groupIid)
3813
        ->setSentDate($today)
3814
        ->setQualification($formValues['qualification'] != '' ? $formValues['qualification'] : 0)
3815
        ->setParentId(0)
3816
        ->setQualificatorId(0)
3817
        ->setWeight(!empty($formValues['weight']) ? $formValues['weight'] : 0)
3818
        ->setSession($session)
0 ignored issues
show
Bug introduced by
It seems like $session defined by $em->find('ChamiloCoreBu...:Session', $session_id) on line 3787 can also be of type object; however, Chamilo\CourseBundle\Ent...blication::setSession() does only seem to accept null|object<Chamilo\CoreBundle\Entity\Session>, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
3819
        ->setAllowTextAssignment($formValues['allow_text_assignment'])
3820
        ->setContainsFile(0)
3821
        ->setUserId($user_id)
3822
        ->setHasProperties(0)
3823
        ->setDocumentId(0);
3824
3825
    $em->persist($workTable);
3826
    $em->flush();
3827
3828
    $workTable->setId($workTable->getIid());
3829
    $em->merge($workTable);
3830
    $em->flush();
3831
3832
    // Folder created
3833
    api_item_property_update(
3834
        $courseInfo,
3835
        'work',
3836
        $workTable->getIid(),
3837
        'DirectoryCreated',
3838
        $user_id,
3839
        $groupIid
3840
    );
3841
3842
    updatePublicationAssignment(
3843
        $workTable->getIid(),
3844
        $formValues,
3845
        $courseInfo,
3846
        $groupIid
3847
    );
3848
3849
    // Added the new Work ID to the extra field values
3850
    $formValues['item_id'] = $workTable->getIid();
3851
3852
    $workFieldValue = new ExtraFieldValue('work');
3853
    $workFieldValue->saveFieldValues($formValues);
3854
3855
    if (api_get_course_setting('email_alert_students_on_new_homework') == 1) {
3856
        send_email_on_homework_creation(
3857
            $course_id,
3858
            $session ? $session->getId() : 0,
3859
            $workTable->getIid()
3860
        );
3861
    }
3862
3863
    return $workTable->getIid();
3864
}
3865
3866
/**
3867
 * @param int $workId
3868
 * @param array $courseInfo
3869
 * @return int
3870
 */
3871 View Code Duplication
function agendaExistsForWork($workId, $courseInfo)
3872
{
3873
    $workTable = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3874
    $courseId = $courseInfo['real_id'];
3875
    $workId = intval($workId);
3876
3877
    $sql = "SELECT add_to_calendar FROM $workTable
3878
            WHERE c_id = $courseId AND publication_id = ".$workId;
3879
    $res = Database::query($sql);
3880
    if (Database::num_rows($res)) {
3881
        $row = Database::fetch_array($res, 'ASSOC');
3882
        if (!empty($row['add_to_calendar'])) {
3883
            return $row['add_to_calendar'];
3884
        }
3885
    }
3886
    return 0;
3887
}
3888
3889
/**
3890
 * Update work description, qualification, weight, allow_text_assignment
3891
 * @param int $workId (iid)
3892
 * @param array $params
3893
 * @param array $courseInfo
3894
 * @param int $sessionId
3895
 */
3896
function updateWork($workId, $params, $courseInfo, $sessionId = 0)
3897
{
3898
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3899
    $filteredParams = array(
3900
        'description' => $params['description'],
3901
        'qualification' => $params['qualification'],
3902
        'weight' => $params['weight'],
3903
        'allow_text_assignment' => $params['allow_text_assignment']
3904
    );
3905
3906
    Database::update(
3907
        $workTable,
3908
        $filteredParams,
3909
        array(
3910
            'iid = ? AND c_id = ?' => array(
3911
                $workId,
3912
                $courseInfo['real_id']
3913
            )
3914
        )
3915
    );
3916
3917
    $workFieldValue = new ExtraFieldValue('work');
3918
    $workFieldValue->saveFieldValues($params);
3919
}
3920
3921
/**
3922
 * @param int $workId
3923
 * @param array $params
3924
 * @param array $courseInfo
3925
 * @param int $groupId
3926
 */
3927
function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
3928
{
3929
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3930
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3931
    $workId = intval($workId);
3932
    $now = api_get_utc_datetime();
3933
    $course_id = $courseInfo['real_id'];
3934
3935
    // Insert into agenda
3936
    $agendaId = 0;
3937
    if (isset($params['add_to_calendar']) && $params['add_to_calendar'] == 1) {
3938
        // Setting today date
3939
        $date = $end_date = $now;
3940
3941
        if (isset($params['enableExpiryDate'])) {
3942
            $end_date = $params['expires_on'];
3943
            $date = $end_date;
3944
        }
3945
3946
        $title = sprintf(get_lang('HandingOverOfTaskX'), $params['new_dir']);
3947
        $description = isset($params['description']) ? $params['description'] : '';
3948
        $content = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq().'&id='.$workId.'">'
3949
            .$params['new_dir'].'</a>'.$description;
3950
3951
        $agendaId = agendaExistsForWork($workId, $courseInfo);
3952
3953
        // Add/edit agenda
3954
        $agenda = new Agenda('course');
3955
        $agenda->set_course($courseInfo);
3956
3957
        if (!empty($agendaId)) {
3958
            // add_to_calendar is set but it doesnt exists then invalidate
3959
            $eventInfo = $agenda->get_event($agendaId);
3960
            if (empty($eventInfo)) {
3961
                $agendaId = 0;
3962
            }
3963
        }
3964
3965
        if (empty($agendaId)) {
3966
            $agendaId = $agenda->addEvent(
3967
                $date,
3968
                $end_date,
3969
                'false',
3970
                $title,
3971
                $content,
3972
                array('GROUP:'.$groupId)
3973
            );
3974
        } else {
3975
            $agenda->editEvent(
3976
                $agendaId,
3977
                $end_date,
3978
                $end_date,
3979
                'false',
3980
                $title,
3981
                $content
3982
            );
3983
        }
3984
    }
3985
3986
    $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
3987
    $expiryDate = isset($params['enableExpiryDate']) && (int) $params['enableExpiryDate'] == 1 ? api_get_utc_datetime($params['expires_on']) : '';
3988
    $endDate = isset($params['enableEndDate']) && (int) $params['enableEndDate'] == 1 ? api_get_utc_datetime($params['ends_on']) : '';
3989
3990
    $data = get_work_assignment_by_id($workId, $course_id);
3991
3992
    if (!empty($expiryDate)) {
3993
        $expiryDateCondition = "expires_on = '".Database::escape_string($expiryDate)."', ";
3994
    } else {
3995
        $expiryDateCondition = "expires_on = null, ";
3996
    }
3997
3998
    if (!empty($endDate)) {
3999
        $endOnCondition = "ends_on = '".Database::escape_string($endDate)."', ";
4000
    } else {
4001
        $endOnCondition = "ends_on = null, ";
4002
    }
4003
4004
    if (empty($data)) {
4005
        $sql = "INSERT INTO $table SET
4006
                c_id = $course_id ,
4007
                $expiryDateCondition
4008
                $endOnCondition
4009
                add_to_calendar = $agendaId,
4010
                enable_qualification = '$qualification',
4011
                publication_id = '$workId'";
4012
        Database::query($sql);
4013
        $my_last_id = Database::insert_id();
4014
4015
        if ($my_last_id) {
4016
            $sql = "UPDATE $table SET
4017
                        id = iid
4018
                    WHERE iid = $my_last_id";
4019
            Database::query($sql);
4020
4021
            $sql = "UPDATE $workTable SET
4022
                        has_properties  = $my_last_id,
4023
                        view_properties = 1
4024
                    WHERE c_id = $course_id AND id = $workId";
4025
            Database::query($sql);
4026
        }
4027
    } else {
4028
        $sql = "UPDATE $table SET
4029
                    $expiryDateCondition
4030
                    $endOnCondition
4031
                    add_to_calendar  = $agendaId,
4032
                    enable_qualification = '".$qualification."'
4033
                WHERE
4034
                    publication_id = $workId AND
4035
                    c_id = $course_id AND
4036
                    iid = ".$data['iid'];
4037
        Database::query($sql);
4038
    }
4039
4040
    if (!empty($params['category_id'])) {
4041
        $link_info = GradebookUtils::isResourceInCourseGradebook(
4042
            $courseInfo['code'],
4043
            LINK_STUDENTPUBLICATION,
4044
            $workId,
4045
            api_get_session_id()
4046
        );
4047
4048
        $linkId = null;
4049
        if (!empty($link_info)) {
4050
            $linkId = $link_info['id'];
4051
        }
4052
4053
        if (isset($params['make_calification']) &&
4054
            $params['make_calification'] == 1
4055
        ) {
4056
            if (empty($linkId)) {
4057
                GradebookUtils::add_resource_to_course_gradebook(
4058
                    $params['category_id'],
4059
                    $courseInfo['code'],
4060
                    LINK_STUDENTPUBLICATION,
4061
                    $workId,
4062
                    $params['new_dir'],
4063
                    api_float_val($params['weight']),
4064
                    api_float_val($params['qualification']),
4065
                    $params['description'],
4066
                    1,
4067
                    api_get_session_id()
4068
                );
4069
            } else {
4070
                GradebookUtils::update_resource_from_course_gradebook(
4071
                    $linkId,
4072
                    $courseInfo['code'],
4073
                    $params['weight']
4074
                );
4075
            }
4076
        } else {
4077
            // Delete everything of the gradebook for this $linkId
4078
            GradebookUtils::remove_resource_from_course_gradebook($linkId);
4079
        }
4080
    }
4081
}
4082
4083
/**
4084
 * Delete all work by student
4085
 * @param int $userId
4086
 * @param array $courseInfo
4087
 * @return array return deleted items
4088
 */
4089
function deleteAllWorkPerUser($userId, $courseInfo)
4090
{
4091
    $deletedItems = array();
4092
    $workPerUser = getWorkPerUser($userId);
4093
    if (!empty($workPerUser)) {
4094
        foreach ($workPerUser as $work) {
4095
            $work = $work['work'];
4096
            foreach ($work->user_results as $userResult) {
4097
                $result = deleteWorkItem($userResult['id'], $courseInfo);
4098
                if ($result) {
4099
                    $deletedItems[] = $userResult;
4100
                }
4101
            }
4102
        }
4103
    }
4104
    return $deletedItems;
4105
}
4106
4107
/**
4108
 * @param int $item_id
4109
 * @param array course info
4110
 * @return bool
4111
 */
4112
function deleteWorkItem($item_id, $courseInfo)
4113
{
4114
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4115
    $TSTDPUBASG = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
4116
4117
    $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
4118
4119
    $is_allowed_to_edit = api_is_allowed_to_edit();
4120
    $file_deleted = false;
4121
    $item_id = intval($item_id);
4122
4123
    $is_author = user_is_author($item_id);
4124
    $work_data = get_work_data_by_id($item_id);
4125
    $locked = api_resource_is_locked_by_gradebook($work_data['parent_id'], LINK_STUDENTPUBLICATION);
4126
    $course_id = $courseInfo['real_id'];
4127
4128
    if (($is_allowed_to_edit && $locked == false) ||
4129
        (
4130
            $locked == false &&
4131
            $is_author &&
4132
            api_get_course_setting('student_delete_own_publication') == 1 &&
4133
            $work_data['qualificator_id'] == 0
4134
        )
4135
    ) {
4136
        // We found the current user is the author
4137
        $sql = "SELECT url, contains_file FROM $work_table
4138
                WHERE c_id = $course_id AND id = $item_id";
4139
        $result = Database::query($sql);
4140
        $row = Database::fetch_array($result);
4141
4142
        if (Database::num_rows($result) > 0) {
4143
            $sql = "UPDATE $work_table SET active = 2
4144
                    WHERE c_id = $course_id AND id = $item_id";
4145
            Database::query($sql);
4146
            $sql = "DELETE FROM $TSTDPUBASG
4147
                    WHERE c_id = $course_id AND publication_id = $item_id";
4148
            Database::query($sql);
4149
4150
            api_item_property_update(
4151
                $courseInfo,
4152
                'work',
4153
                $item_id,
4154
                'DocumentDeleted',
4155
                api_get_user_id()
4156
            );
4157
4158
            Event::addEvent(
4159
                LOG_WORK_FILE_DELETE,
4160
                LOG_WORK_DATA,
4161
                [
4162
                    'id' => $work_data['id'],
4163
                    'url' => $work_data['url'],
4164
                    'title' => $work_data['title']
4165
                ],
4166
                null,
4167
                api_get_user_id(),
4168
                api_get_course_int_id(),
4169
                api_get_session_id()
4170
            );
4171
4172
            $work = $row['url'];
4173
4174
            if ($row['contains_file'] == 1) {
4175
                if (!empty($work)) {
4176
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
4177
                        my_delete($currentCourseRepositorySys.'/'.$work);
4178
                        $file_deleted = true;
4179
                    } else {
4180
                        $extension = pathinfo($work, PATHINFO_EXTENSION);
4181
                        $new_dir = $work.'_DELETED_'.$item_id.'.'.$extension;
4182
4183
                        if (file_exists($currentCourseRepositorySys.'/'.$work)) {
4184
                            rename($currentCourseRepositorySys.'/'.$work, $currentCourseRepositorySys.'/'.$new_dir);
4185
                            $file_deleted = true;
4186
                        }
4187
                    }
4188
                }
4189
            } else {
4190
                $file_deleted = true;
4191
            }
4192
        }
4193
    }
4194
    return $file_deleted;
4195
}
4196
4197
/**
4198
 * @param FormValidator $form
4199
 * @param array $defaults
4200
 * @param integer $workId
4201
 * @return FormValidator
4202
 */
4203
function getFormWork($form, $defaults = array(), $workId = 0)
4204
{
4205
    $sessionId = api_get_session_id();
4206
    if (!empty($defaults)) {
4207
        if (isset($defaults['submit'])) {
4208
            unset($defaults['submit']);
4209
        }
4210
    }
4211
4212
    // Create the form that asks for the directory name
4213
    $form->addElement('text', 'new_dir', get_lang('AssignmentName'));
4214
    $form->addRule('new_dir', get_lang('ThisFieldIsRequired'), 'required');
4215
    $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
4216
    $form->addButtonAdvancedSettings('advanced_params', get_lang('AdvancedParameters'));
4217
4218
    if (!empty($defaults) && (isset($defaults['enableEndDate']) || isset($defaults['enableExpiryDate']))) {
4219
        $form->addHtml('<div id="advanced_params_options" style="display:block">');
4220
    } else {
4221
        $form->addHtml('<div id="advanced_params_options" style="display:none">');
4222
    }
4223
4224
    // QualificationOfAssignment
4225
    $form->addElement('text', 'qualification', get_lang('QualificationNumeric'));
4226
4227
    if (($sessionId != 0 && Gradebook::is_active()) || $sessionId == 0) {
4228
        $form->addElement(
4229
            'checkbox',
4230
            'make_calification',
4231
            null,
4232
            get_lang('MakeQualifiable'),
4233
            array(
4234
                'id' =>'make_calification_id',
4235
                'onclick' => "javascript: if(this.checked) { document.getElementById('option1').style.display='block';}else{document.getElementById('option1').style.display='none';}"
4236
            )
4237
        );
4238
    } else {
4239
        // QualificationOfAssignment
4240
        $form->addElement('hidden', 'make_calification', false);
4241
    }
4242
4243
    if (!empty($defaults) && isset($defaults['category_id'])) {
4244
        $form->addHtml('<div id=\'option1\' style="display:block">');
4245
    } else {
4246
        $form->addHtml('<div id=\'option1\' style="display:none">');
4247
    }
4248
4249
    // Loading Gradebook select
4250
    GradebookUtils::load_gradebook_select_in_tool($form);
4251
4252
    $form->addElement('text', 'weight', get_lang('WeightInTheGradebook'));
4253
    $form->addHtml('</div>');
4254
4255
    $form->addElement('checkbox', 'enableExpiryDate', null, get_lang('EnableExpiryDate'), 'id="expiry_date"');
4256
    if (isset($defaults['enableExpiryDate']) && $defaults['enableExpiryDate']) {
4257
        $form->addHtml('<div id="option2" style="display: block;">');
4258
    } else {
4259
        $form->addHtml('<div id="option2" style="display: none;">');
4260
    }
4261
4262
    $currentDate = substr(api_get_local_time(), 0, 10);
4263 View Code Duplication
    if (!isset($defaults['expires_on'])) {
4264
        $date = substr($currentDate, 0, 10);
4265
        $defaults['expires_on'] = $date.' 23:59';
4266
    }
4267
4268
    $form->addElement('date_time_picker', 'expires_on', get_lang('ExpiresAt'));
4269
    $form->addHtml('</div>');
4270
    $form->addElement('checkbox', 'enableEndDate', null, get_lang('EnableEndDate'), 'id="end_date"');
4271
4272 View Code Duplication
    if (!isset($defaults['ends_on'])) {
4273
        $date = substr($currentDate, 0, 10);
4274
        $defaults['ends_on'] = $date.' 23:59';
4275
    }
4276
    if (isset($defaults['enableEndDate']) && $defaults['enableEndDate']) {
4277
        $form->addHtml('<div id="option3" style="display: block;">');
4278
    } else {
4279
        $form->addHtml('<div id="option3" style="display: none;">');
4280
    }
4281
4282
    $form->addElement('date_time_picker', 'ends_on', get_lang('EndsAt'));
4283
    $form->addHtml('</div>');
4284
4285
    $form->addElement('checkbox', 'add_to_calendar', null, get_lang('AddToCalendar'));
4286
    $form->addElement('select', 'allow_text_assignment', get_lang('DocumentType'), getUploadDocumentType());
4287
4288
    //Extra fields
4289
    $extra_field = new ExtraField('work');
4290
    $extra = $extra_field->addElements($form, $workId);
4291
4292
    $htmlHeadXtra[] = '
4293
        <script>
4294
        $(function() {
4295
            ' . $extra['jquery_ready_content'] . '
4296
        });
4297
        </script>';
4298
4299
    $form->addHtml('</div>');
4300
4301
    if (isset($defaults['enableExpiryDate']) && isset($defaults['enableEndDate'])) {
4302
        $form->addRule(array('expires_on', 'ends_on'), get_lang('DateExpiredNotBeLessDeadLine'), 'comparedate');
4303
    }
4304
    if (!empty($defaults)) {
4305
        $form->setDefaults($defaults);
4306
    }
4307
4308
    return $form;
4309
}
4310
4311
/**
4312
 * @return array
4313
 */
4314
function getUploadDocumentType()
4315
{
4316
    return array(
4317
        0 => get_lang('AllowFileOrText'),
4318
        1 => get_lang('AllowOnlyText'),
4319
        2 => get_lang('AllowOnlyFiles')
4320
    );
4321
}
4322
4323
/**
4324
 * @param array $courseInfo
4325
 * @param bool $showScore
4326
 * @param bool $studentDeleteOwnPublication
4327
 */
4328
function updateSettings($courseInfo, $showScore, $studentDeleteOwnPublication)
4329
{
4330
    $showScore = intval($showScore);
4331
    $courseId = api_get_course_int_id();
4332
    $main_course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
4333
    $table_course_setting = Database :: get_course_table(TOOL_COURSE_SETTING);
4334
4335
    if (empty($courseId)) {
4336
        return false;
4337
    }
4338
4339
    $query = "UPDATE $main_course_table 
4340
              SET show_score = '$showScore'
4341
              WHERE id = $courseId";
4342
    Database::query($query);
4343
4344
    /**
4345
     * Course data are cached in session so we need to update both the database
4346
     * and the session data
4347
     */
4348
    $_course['show_score'] = $showScore;
4349
    Session::write('_course', $courseInfo);
4350
4351
    // changing the tool setting: is a student allowed to delete his/her own document
4352
4353
    // counting the number of occurrences of this setting (if 0 => add, if 1 => update)
4354
    $query = "SELECT * FROM $table_course_setting
4355
              WHERE 
4356
                c_id = $courseId AND 
4357
                variable = 'student_delete_own_publication'";
4358
4359
    $result = Database::query($query);
4360
    $number_of_setting = Database::num_rows($result);
4361
4362
    if ($number_of_setting == 1) {
4363
        $query = "UPDATE " . $table_course_setting . " SET
4364
                  value='" . Database::escape_string($studentDeleteOwnPublication) . "'
4365
                  WHERE variable = 'student_delete_own_publication' AND c_id = $courseId";
4366
        Database::query($query);
4367
    } else {
4368
        $params = [
4369
            'c_id' => $courseId,
4370
            'variable' => 'student_delete_own_publication',
4371
            'value' => $studentDeleteOwnPublication,
4372
            'category' => 'work'
4373
        ];
4374
        Database::insert($table_course_setting, $params);
4375
    }
4376
}
4377
4378
/**
4379
 * @param int $item_id
4380
 * @param array $course_info
4381
 */
4382
function makeVisible($item_id, $course_info)
4383
{
4384
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4385
    $course_id = $course_info['real_id'];
4386
    $item_id = intval($item_id);
4387
4388
    $sql = "UPDATE $work_table SET accepted = 1
4389
            WHERE c_id = $course_id AND id = $item_id";
4390
    Database::query($sql);
4391
    api_item_property_update($course_info, 'work', $item_id, 'visible', api_get_user_id());
4392
}
4393
4394
/**
4395
 * @param int $item_id
4396
 * @param array $course_info
4397
 */
4398 View Code Duplication
function makeInvisible($item_id, $course_info)
4399
{
4400
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4401
    $item_id = intval($item_id);
4402
    $course_id = $course_info['real_id'];
4403
    $sql = "UPDATE  " . $work_table . "
4404
            SET accepted = 0
4405
            WHERE c_id = $course_id AND id = '" . $item_id . "'";
4406
    Database::query($sql);
4407
    api_item_property_update(
4408
        $course_info,
4409
        'work',
4410
        $item_id,
4411
        'invisible',
4412
        api_get_user_id()
4413
    );
4414
}
4415
4416
/**
4417
 * @param int $item_id
4418
 * @param string $path
4419
 * @param array $courseInfo
4420
 * @param int $groupId iid
4421
 * @param int $sessionId
4422
 * @return string
4423
 */
4424
function generateMoveForm($item_id, $path, $courseInfo, $groupId, $sessionId)
4425
{
4426
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4427
    $courseId = $courseInfo['real_id'];
4428
    $folders = array();
4429
    $session_id = intval($sessionId);
4430
    $groupId = intval($groupId);
4431
    $sessionCondition = empty($sessionId) ? " AND (session_id = 0 OR session_id IS NULL) " : " AND session_id='".$session_id."'";
4432
4433
    $groupIid = 0;
4434
    if ($groupId) {
4435
        $groupInfo = GroupManager::get_group_properties($groupId);
4436
        $groupIid = $groupInfo['iid'];
4437
    }
4438
4439
    $sql = "SELECT id, url, title
4440
            FROM $work_table
4441
            WHERE
4442
                c_id = $courseId AND
4443
                active IN (0, 1) AND
4444
                url LIKE '/%' AND
4445
                post_group_id = $groupIid
4446
                $sessionCondition";
4447
    $res = Database::query($sql);
4448
    while ($folder = Database::fetch_array($res)) {
4449
        $title = empty($folder['title']) ? basename($folder['url']) : $folder['title'];
4450
        $folders[$folder['id']] = $title;
4451
    }
4452
4453
    return build_work_move_to_selector($folders, $path, $item_id);
4454
}
4455
4456
/**
4457
 * @param int $workId
4458
 * @return string
4459
 */
4460
function showStudentList($workId)
4461
{
4462
    $columnModel = array(
4463
        array(
4464
            'name' => 'student',
4465
            'index' => 'student',
4466
            'width' => '350px',
4467
            'align' => 'left',
4468
            'sortable' => 'false',
4469
        ),
4470
        array(
4471
            'name' => 'works',
4472
            'index' => 'works',
4473
            'align' => 'center',
4474
            'sortable' => 'false',
4475
        ),
4476
    );
4477
    $token = null;
4478
4479
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student_list_overview&work_id='.$workId.'&'.api_get_cidreq();
4480
4481
    $columns = array(
4482
        get_lang('Students'),
4483
        get_lang('Works')
4484
    );
4485
4486
    $order = api_is_western_name_order() ? 'firstname' : 'lastname';
4487
    $params = array(
4488
        'autowidth' => 'true',
4489
        'height' => 'auto',
4490
        'rowNum' => 5,
4491
        'sortname' => $order,
4492
        'sortorder' => 'asc'
4493
    );
4494
4495
    $html = '<script>
4496
    $(function() {
4497
        '.Display::grid_js('studentList', $url, $columns, $columnModel, $params, array(), null, true).'
4498
        $("#workList").jqGrid(
4499
            "navGrid",
4500
            "#studentList_pager",
4501
            { edit: false, add: false, del: false },
4502
            { height:280, reloadAfterSubmit:false }, // edit options
4503
            { height:280, reloadAfterSubmit:false }, // add options
4504
            { width:500 } // search options
4505
        );
4506
    });
4507
    </script>';
4508
    $html .= Display::grid_html('studentList');
4509
    return $html;
4510
}
4511
4512
/**
4513
 * @param string $courseCode
4514
 * @param int $sessionId
4515
 * @param int $groupId
4516
 * @param int $start
4517
 * @param int $limit
4518
 * @param string $sidx
4519
 * @param string $sord
4520
 * @param $getCount
4521
 * @return array|int
4522
 */
4523
function getWorkUserList($courseCode, $sessionId, $groupId, $start, $limit, $sidx, $sord, $getCount = false)
4524
{
4525
    if (!empty($groupId)) {
4526
        $userList = GroupManager::get_users(
4527
            $groupId,
4528
            false,
4529
            $start,
4530
            $limit,
4531
            $getCount,
4532
            null,
4533
            $sidx,
4534
            $sord
4535
        );
4536
    } else {
4537
        $limitString = null;
4538 View Code Duplication
        if (!empty($start) && !empty($limit)) {
4539
            $start = intval($start);
4540
            $limit = intval($limit);
4541
            $limitString = " LIMIT $start, $limit";
4542
        }
4543
4544
        $orderBy = null;
4545
4546
        if (!empty($sidx) && !empty($sord)) {
4547
            if (in_array($sidx, array('firstname', 'lastname'))) {
4548
                $orderBy = "ORDER BY $sidx $sord";
4549
            }
4550
        }
4551
4552
        if (empty($sessionId)) {
4553
            $userList = CourseManager::get_user_list_from_course_code(
4554
                $courseCode,
4555
                $sessionId,
4556
                $limitString,
4557
                $orderBy ,
4558
                STUDENT,
4559
                $getCount
4560
            );
4561
        } else {
4562
            $userList = CourseManager::get_user_list_from_course_code(
4563
                $courseCode,
4564
                $sessionId,
4565
                $limitString,
4566
                $orderBy,
4567
                0,
4568
                $getCount
4569
            );
4570
        }
4571
4572
        if ($getCount == false) {
4573
            $userList = array_keys($userList);
4574
        }
4575
    }
4576
    return $userList;
4577
}
4578
4579
/**
4580
 * @param int $workId
4581
 * @param string $courseCode
4582
 * @param int $sessionId
4583
 * @param int $groupId
4584
 * @param int $start
4585
 * @param int $limit
4586
 * @param int $sidx
4587
 * @param string $sord
4588
 * @param bool $getCount
4589
 * @return array|int
4590
 */
4591
function getWorkUserListData(
4592
    $workId,
4593
    $courseCode,
4594
    $sessionId,
4595
    $groupId,
4596
    $start,
4597
    $limit,
4598
    $sidx,
4599
    $sord,
4600
    $getCount = false
4601
) {
4602
    $my_folder_data = get_work_data_by_id($workId);
4603
    $workParents = array();
4604
    if (empty($my_folder_data)) {
4605
        $workParents = getWorkList($workId, $my_folder_data, null);
4606
    }
4607
4608
    $workIdList = array();
4609
    if (!empty($workParents)) {
4610
        foreach ($workParents as $work) {
4611
            $workIdList[] = $work->id;
4612
        }
4613
    }
4614
4615
    $courseInfo = api_get_course_info($courseCode);
4616
4617
    $userList = getWorkUserList(
4618
        $courseCode,
4619
        $sessionId,
4620
        $groupId,
4621
        $start,
4622
        $limit,
4623
        $sidx,
4624
        $sord,
4625
        $getCount
4626
    );
4627
4628
    if ($getCount) {
4629
        return $userList;
4630
    }
4631
    $results = array();
4632
    if (!empty($userList)) {
4633
        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...
4634
            $user = api_get_user_info($userId);
4635
            $link = api_get_path(WEB_CODE_PATH).'work/student_work.php?'.api_get_cidreq().'&studentId='.$user['user_id'];
4636
            $url = Display::url(api_get_person_name($user['firstname'], $user['lastname']), $link);
4637
            $userWorks = 0;
4638
            if (!empty($workIdList)) {
4639
                $userWorks = getUniqueStudentAttempts(
4640
                    $workIdList,
4641
                    $groupId,
4642
                    $courseInfo['real_id'],
4643
                    $sessionId,
4644
                    $user['user_id']
4645
                );
4646
            }
4647
            $works = $userWorks." / ".count($workParents);
4648
            $results[] = array(
4649
                'student' => $url,
4650
                'works' => Display::url($works, $link),
4651
            );
4652
        }
4653
    }
4654
4655
    return $results;
4656
}
4657
4658
/**
4659
 * @param int $id
4660
 * @param array $course_info
4661
 * @param bool $isCorrection
4662
 *
4663
 * @return bool
4664
 */
4665
function downloadFile($id, $course_info, $isCorrection)
4666
{
4667
    return getFile($id, $course_info, true, $isCorrection);
4668
}
4669
4670
/**
4671
 * @param int $id
4672
 * @param array $course_info
4673
 * @param bool $download
4674
 * @param bool $isCorrection
4675
 *
4676
 * @return bool
4677
 */
4678
function getFile($id, $course_info, $download = true, $isCorrection = false)
4679
{
4680
    $file = getFileContents($id, $course_info, 0, $isCorrection);
4681
    if (!empty($file) && is_array($file)) {
4682
        return DocumentManager::file_send_for_download(
4683
            $file['path'],
4684
            $download,
4685
            $file['title']
4686
        );
4687
    }
4688
4689
    return false;
4690
}
4691
4692
4693
/**
4694
 * Get the file contents for an assigment
4695
 * @param int $id
4696
 * @param array $course_info
4697
 * @param int Session ID
4698
 * @param $correction
4699
 *
4700
 * @return array|bool
4701
 */
4702
function getFileContents($id, $course_info, $sessionId = 0, $correction = false)
4703
{
4704
    $id = intval($id);
4705
    if (empty($course_info) || empty($id)) {
4706
        return false;
4707
    }
4708
    if (empty($sessionId)) {
4709
        $sessionId = api_get_session_id();
4710
    }
4711
4712
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4713
4714
    if (!empty($course_info['real_id'])) {
4715
        $sql = 'SELECT *
4716
                FROM '.$table.'
4717
                WHERE c_id = '.$course_info['real_id'].' AND id = "'.$id.'"';
4718
        $result = Database::query($sql);
4719
        if ($result && Database::num_rows($result)) {
4720
            $row = Database::fetch_array($result, 'ASSOC');
4721
4722
            if ($correction) {
4723
                $row['url'] = $row['url_correction'];
4724
            }
4725
4726
            if (empty($row['url'])) {
4727
                return false;
4728
            }
4729
4730
            $full_file_name = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.$row['url'];
4731
4732
            $item_info = api_get_item_property_info(
4733
                api_get_course_int_id(),
4734
                'work',
4735
                $row['id'],
4736
                $sessionId
4737
            );
4738
4739
            allowOnlySubscribedUser(
4740
                api_get_user_id(),
4741
                $row['parent_id'],
4742
                $course_info['real_id']
4743
            );
4744
4745
            if (empty($item_info)) {
4746
                api_not_allowed();
4747
            }
4748
4749
            /*
4750
            field show_score in table course :
4751
                0 =>    New documents are visible for all users
4752
                1 =>    New documents are only visible for the teacher(s)
4753
            field visibility in table item_property :
4754
                0 => eye closed, invisible for all students
4755
                1 => eye open
4756
            field accepted in table c_student_publication :
4757
                0 => eye closed, invisible for all students
4758
                1 => eye open
4759
            ( We should have visibility == accepted, otherwise there is an
4760
            inconsistency in the Database)
4761
            field value in table c_course_setting :
4762
                0 => Allow learners to delete their own publications = NO
4763
                1 => Allow learners to delete their own publications = YES
4764
4765
            +------------------+-------------------------+------------------------+
4766
            |Can download work?| doc visible for all = 0 | doc visible for all = 1|
4767
            +------------------+-------------------------+------------------------+
4768
            |  visibility = 0  | editor only             | editor only            |
4769
            |                  |                         |                        |
4770
            +------------------+-------------------------+------------------------+
4771
            |  visibility = 1  | editor                  | editor                 |
4772
            |                  | + owner of the work     | + any student          |
4773
            +------------------+-------------------------+------------------------+
4774
            (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
4775
            */
4776
4777
            $work_is_visible = $item_info['visibility'] == 1 && $row['accepted'] == 1;
4778
            $doc_visible_for_all = ($course_info['show_score'] == 1);
4779
4780
            $is_editor = api_is_allowed_to_edit(true, true, true);
4781
            $student_is_owner_of_work = user_is_author($row['id'], $row['user_id']);
4782
4783
            if ($is_editor ||
4784
                ($student_is_owner_of_work) ||
4785
                ($doc_visible_for_all && $work_is_visible)
4786
            ) {
4787
                $title = $row['title'];
4788
                if ($correction) {
4789
                    $title = $row['title_correction'];
4790
                }
4791
                if (array_key_exists('filename', $row) && !empty($row['filename'])) {
4792
                    $title = $row['filename'];
4793
                }
4794
4795
                $title = str_replace(' ', '_', $title);
4796
                Event::event_download($title);
4797
                if (Security::check_abs_path(
4798
                    $full_file_name,
4799
                    api_get_path(SYS_COURSE_PATH).api_get_course_path().'/')
4800
                ) {
4801
                    return array(
4802
                        'path' => $full_file_name,
4803
                        'title' => $title,
4804
                        'title_correction' => $row['title_correction']
4805
                    );
4806
                }
4807
            }
4808
        }
4809
    }
4810
4811
    return false;
4812
}
4813
4814
/**
4815
 * @param int $userId
4816
 * @param array $courseInfo
4817
 * @param string $format
4818
 * @return bool
4819
 */
4820
function exportAllWork($userId, $courseInfo, $format = 'pdf')
4821
{
4822
    $userInfo = api_get_user_info($userId);
4823
    if (empty($userInfo) || empty($courseInfo)) {
4824
        return false;
4825
    }
4826
4827
    $workPerUser = getWorkPerUser($userId);
4828
4829
    switch ($format) {
4830
        case 'pdf':
4831
            if (!empty($workPerUser)) {
4832
                $pdf = new PDF();
4833
4834
                $content = null;
4835
                foreach ($workPerUser as $work) {
4836
                    $work = $work['work'];
4837
                    foreach ($work->user_results as $userResult) {
4838
                        $content .= $userResult['title'];
4839
                        // No need to use api_get_local_time()
4840
                        $content .= $userResult['sent_date'];
4841
                        $content .= $userResult['qualification'];
4842
                        $content .= $userResult['description'];
4843
                    }
4844
                }
4845
4846
                if (!empty($content)) {
4847
                    $pdf->content_to_pdf(
4848
                        $content,
4849
                        null,
4850
                        api_replace_dangerous_char($userInfo['complete_name']),
4851
                        $courseInfo['code']
4852
                    );
4853
                }
4854
            }
4855
            break;
4856
    }
4857
}
4858
4859
/**
4860
 * @param int $workId
4861
 * @param array $courseInfo
4862
 * @param int $sessionId
4863
 * @param string $format
4864
 * @return bool
4865
 */
4866
function exportAllStudentWorkFromPublication(
4867
    $workId,
4868
    $courseInfo,
4869
    $sessionId,
4870
    $format = 'pdf'
4871
) {
4872
    if (empty($courseInfo)) {
4873
        return false;
4874
    }
4875
4876
    $workData = get_work_data_by_id($workId);
4877
4878
    if (empty($workData)) {
4879
        return false;
4880
    }
4881
4882
    $assignment = get_work_assignment_by_id($workId);
4883
4884
    $courseCode = $courseInfo['code'];
4885
    $header = get_lang('Course').': '.$courseInfo['title'];
4886
    $teachers = CourseManager::get_teacher_list_from_course_code_to_string(
4887
        $courseCode
4888
    );
4889
4890
    if (!empty($sessionId)) {
4891
        $sessionInfo = api_get_session_info($sessionId);
4892
        if (!empty($sessionInfo)) {
4893
            $header .= ' - ' . $sessionInfo['name'];
4894
            $header .= '<br />' . $sessionInfo['description'];
4895
            $teachers = SessionManager::getCoachesByCourseSessionToString(
4896
                $sessionId,
4897
                $courseInfo['real_id']
4898
            );
4899
        }
4900
    }
4901
4902
    $header .= '<br />'.get_lang('Teachers').': '.$teachers.'<br />';
4903
    $header .= '<br />'.get_lang('Date').': '.api_get_local_time().'<br />';
4904
    $header .= '<br />'.get_lang('WorkName').': '.$workData['title'].'<br />';
4905
4906
    $content = null;
4907
    $expiresOn = null;
4908
4909
    if (!empty($assignment) && isset($assignment['expires_on'])) {
4910
        $content .= '<br /><strong>' . get_lang('ExpirationDate') . '</strong>: ' . api_get_local_time($assignment['expires_on']);
4911
        $expiresOn = api_get_local_time($assignment['expires_on']);
4912
    }
4913
4914
    if (!empty($workData['description'])) {
4915
        $content .= '<br /><strong>' . get_lang('Description') . '</strong>: ' . $workData['description'];
4916
    }
4917
4918
    $workList = get_work_user_list(null, null, null, null, $workId);
4919
4920
    switch ($format) {
4921
        case 'pdf':
4922
            if (!empty($workList)) {
4923
4924
                $table = new HTML_Table(array('class' => 'data_table'));
4925
                $headers = array(
4926
                    get_lang('Name'),
4927
                    get_lang('User'),
4928
                    get_lang('HandOutDateLimit'),
4929
                    get_lang('SentDate'),
4930
                    get_lang('FileName'),
4931
                    get_lang('Score'),
4932
                    get_lang('Feedback')
4933
                );
4934
4935
                $column = 0;
4936
                foreach($headers as $header) {
4937
                    $table->setHeaderContents(0, $column, $header);
4938
                    $column++;
4939
                }
4940
4941
                $row = 1;
4942
4943
                //$pdf->set_custom_header($header);
4944
                foreach ($workList as $work) {
4945
                    $content .= '<hr />';
4946
                    // getWorkComments need c_id
4947
                    $work['c_id'] = $courseInfo['real_id'];
4948
4949
                    //$content .= get_lang('Date').': '.api_get_local_time($work['sent_date_from_db']).'<br />';
4950
                    $score = null;
4951
                    if (!empty($work['qualification_only'])) {
4952
                        $score = $work['qualification_only'];
4953
                    }
4954
                    //$content .= get_lang('Description').': '.$work['description'].'<br />';
4955
                    $comments = getWorkComments($work);
4956
4957
                    $feedback = null;
4958
                    if (!empty($comments)) {
4959
                        $content .= '<h4>'.get_lang('Feedback').': </h4>';
4960
                        foreach ($comments as $comment) {
4961
                            $feedback .= get_lang('User').': '.api_get_person_name(
4962
                                    $comment['firstname'],
4963
                                    $comment['lastname']
4964
                                ).'<br />';
4965
                            $feedback .= $comment['comment'].'<br />';
4966
                        }
4967
                    }
4968
4969
                    $table->setCellContents($row, 0, strip_tags($workData['title']));
4970
                    $table->setCellContents($row, 1, api_get_person_name(strip_tags($work['firstname']), strip_tags($work['lastname'])));
4971
                    $table->setCellContents($row, 2, $expiresOn);
4972
                    $table->setCellContents($row, 3, api_get_local_time($work['sent_date_from_db']));
4973
                    $table->setCellContents($row, 4, strip_tags($work['title']));
4974
                    $table->setCellContents($row, 5, $score);
4975
                    $table->setCellContents($row, 6, $feedback);
4976
4977
                    $row++;
4978
                }
4979
4980
                $content = $table->toHtml();
4981
4982
                if (!empty($content)) {
4983
                    $params = array(
4984
                        'filename' => $workData['title'] . '_' . api_get_local_time(),
4985
                        'pdf_title' => api_replace_dangerous_char($workData['title']),
4986
                        'course_code' => $courseInfo['code'],
4987
                        'add_signatures' => false
4988
                    );
4989
                    $pdf = new PDF('A4', null, $params);
4990
                    $pdf->html_to_pdf_with_template($content);
4991
                }
4992
                exit;
4993
            }
4994
            break;
4995
    }
4996
}
4997
4998
/**
4999
 * Downloads all user files per user
5000
 * @param int $userId
5001
 * @param array $courseInfo
5002
 * @return bool
5003
 */
5004
function downloadAllFilesPerUser($userId, $courseInfo)
5005
{
5006
    $userInfo = api_get_user_info($userId);
5007
5008
    if (empty($userInfo) || empty($courseInfo)) {
5009
        return false;
5010
    }
5011
5012
    $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
5013
    $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
5014
5015
    $zip  = new PclZip($tempZipFile);
5016
5017
    $workPerUser = getWorkPerUser($userId);
5018
5019
    if (!empty($workPerUser)) {
5020
        $files = array();
5021
        foreach ($workPerUser as $work) {
5022
            $work = $work['work'];
5023
            foreach ($work->user_results as $userResult) {
5024
                if (empty($userResult['url']) || empty($userResult['contains_file'])) {
5025
                    continue;
5026
                }
5027
                $data = getFileContents($userResult['id'], $courseInfo);
5028
                if (!empty($data) && isset($data['path'])) {
5029
                    $files[basename($data['path'])] = array(
5030
                        'title' => $data['title'],
5031
                        'path' => $data['path']
5032
                    );
5033
                }
5034
            }
5035
        }
5036
5037
        if (!empty($files)) {
5038
            Session::write('files', $files);
5039
            foreach ($files as $data) {
5040
                $zip->add(
5041
                    $data['path'],
5042
                    PCLZIP_OPT_REMOVE_PATH,
5043
                    $coursePath,
5044
                    PCLZIP_CB_PRE_ADD,
5045
                    'preAddAllWorkStudentCallback'
5046
                );
5047
            }
5048
        }
5049
5050
        // Start download of created file
5051
        $name = basename(api_replace_dangerous_char($userInfo['complete_name'])).'.zip';
5052
        Event::event_download($name.'.zip (folder)');
5053 View Code Duplication
        if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) {
5054
            DocumentManager::file_send_for_download($tempZipFile, true, $name);
5055
            @unlink($tempZipFile);
5056
            exit;
5057
        }
5058
    }
5059
    exit;
5060
}
5061
5062
/**
5063
 * @param $p_event
5064
 * @param array $p_header
5065
 * @return int
5066
 */
5067 View Code Duplication
function preAddAllWorkStudentCallback($p_event, &$p_header)
5068
{
5069
    $files = Session::read('files');
5070
    if (isset($files[basename($p_header['stored_filename'])])) {
5071
        $p_header['stored_filename'] = $files[basename($p_header['stored_filename'])]['title'];
5072
        return 1;
5073
    }
5074
    return 0;
5075
}
5076
5077
/**
5078
 * Get all work created by a user
5079
 * @param int $user_id
5080
 * @param int $courseId
5081
 * @param int $sessionId
5082
 * @return array
5083
 */
5084
function getWorkCreatedByUser($user_id, $courseId, $sessionId)
5085
{
5086
    $items = api_get_item_property_list_by_tool_by_user(
5087
        $user_id,
5088
        'work',
5089
        $courseId,
5090
        $sessionId
5091
    );
5092
5093
    $forumList = array();
5094 View Code Duplication
    if (!empty($items)) {
5095
        foreach ($items as $forum) {
5096
            $item = get_work_data_by_id(
5097
                $forum['ref'],
5098
                $courseId,
5099
                $sessionId
5100
            );
5101
5102
            $forumList[] = array(
5103
                $item['title'],
5104
                api_get_local_time($forum['insert_date']),
5105
                api_get_local_time($forum['lastedit_date'])
5106
            );
5107
        }
5108
    }
5109
5110
    return $forumList;
5111
}
5112
5113
/**
5114
 * @param array $courseInfo
5115
 * @param int $workId
5116
 * @return bool
5117
 */
5118
function protectWork($courseInfo, $workId)
5119
{
5120
    $userId = api_get_user_id();
5121
    $groupId = api_get_group_id();
5122
    $sessionId = api_get_session_id();
5123
    $workData = get_work_data_by_id($workId);
5124
5125
    if (empty($workData) || empty($courseInfo)) {
5126
        api_not_allowed(true);
5127
    }
5128
5129
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
5130
        return true;
5131
    }
5132
5133
    $workId = $workData['id'];
5134
5135
    if ($workData['active'] != 1) {
5136
        api_not_allowed(true);
5137
    }
5138
5139
    $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $sessionId);
5140
5141
    if ($visibility != 1) {
5142
        api_not_allowed(true);
5143
    }
5144
5145
    allowOnlySubscribedUser($userId, $workId, $courseInfo['real_id']);
5146
    $groupInfo = GroupManager::get_group_properties($groupId);
5147
5148
    if (!empty($groupId)) {
5149
        $showWork = GroupManager::user_has_access(
5150
            $userId,
5151
            $groupInfo['iid'],
5152
            GroupManager::GROUP_TOOL_WORK
5153
        );
5154
        if (!$showWork) {
5155
            api_not_allowed(true);
5156
        }
5157
    }
5158
}
5159
5160
/**
5161
 * @param array $courseInfo
5162
 * @param array $work
5163
 */
5164
function deleteCorrection($courseInfo, $work)
5165
{
5166
    if (isset($work['url_correction']) && !empty($work['url_correction']) && isset($work['iid'])) {
5167
        $id = $work['iid'];
5168
        $table = Database:: get_course_table(TABLE_STUDENT_PUBLICATION);
5169
        $sql = "UPDATE $table SET
5170
                    url_correction = '',
5171
                    title_correction = ''
5172
                WHERE iid = $id";
5173
        Database::query($sql);
5174
        $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
5175
        if (file_exists($coursePath.$work['url_correction'])) {
5176
            if (Security::check_abs_path($coursePath.$work['url_correction'], $coursePath)) {
5177
                unlink($coursePath.$work['url_correction']);
5178
            }
5179
        }
5180
    }
5181
}
5182