Completed
Push — 1.11.x ( 39b001...e53f2f )
by José
67:52 queued 35:49
created

work.lib.php ➔ getWorkPerUser()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 19
nc 2
nop 3
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
 * @param int $course_id
271
 * @param int $session_id
272
 *
273
 * @return array
274
 */
275
function getWorkList($id, $my_folder_data, $add_in_where_query = null, $course_id = 0, $session_id = 0)
276
{
277
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
278
279
    $course_id = $course_id ? $course_id : api_get_course_int_id();
280
    $session_id = $session_id ? $session_id : api_get_session_id();
281
    $condition_session = api_get_session_condition($session_id);
282
    $group_id = api_get_group_id();
283
284
    $groupIid = 0;
285
    if ($group_id) {
286
        $groupInfo = GroupManager::get_group_properties($group_id);
287
        $groupIid = $groupInfo['iid'];
288
    }
289
290
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
291
292
    $linkInfo = GradebookUtils::isResourceInCourseGradebook(
293
        api_get_course_id(),
294
        3,
295
        $id,
296
        api_get_session_id()
297
    );
298
299
    if ($linkInfo) {
300
        $workInGradeBookLinkId = $linkInfo['id'];
301
        if ($workInGradeBookLinkId) {
302
            if ($is_allowed_to_edit) {
303
                if (intval($my_folder_data['qualification']) == 0) {
304
                    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...
305
                        get_lang('MaxWeightNeedToBeProvided')
306
                    );
307
                }
308
            }
309
        }
310
    }
311
312
    $contains_file_query = '';
313
314
    // Get list from database
315
    if ($is_allowed_to_edit) {
316
        $active_condition = ' active IN (0, 1)';
317
        $sql = "SELECT * FROM $work_table
318
                WHERE
319
                    c_id = $course_id
320
                    $add_in_where_query
321
                    $condition_session AND
322
                    $active_condition AND
323
                    (parent_id = 0)
324
                    $contains_file_query AND 
325
                    post_group_id = $groupIid
326
                ORDER BY sent_date DESC";
327
    } else {
328 View Code Duplication
        if (!empty($group_id)) {
329
            // set to select only messages posted by the user's group
330
            $group_query = " WHERE c_id = $course_id AND post_group_id = $groupIid";
331
            $subdirs_query = " AND parent_id = 0";
332
        } else {
333
            $group_query = " WHERE c_id = $course_id AND (post_group_id = '0' OR post_group_id is NULL) ";
334
            $subdirs_query = " AND parent_id = 0";
335
        }
336
        //@todo how we can active or not an assignment?
337
        $active_condition = ' AND active IN (1, 0)';
338
        $sql = "SELECT * FROM  $work_table
339
                $group_query
340
                $subdirs_query
341
                $add_in_where_query
342
                $active_condition
343
                $condition_session
344
                ORDER BY title";
345
    }
346
347
    $work_parents = array();
348
349
    $sql_result = Database::query($sql);
350
    if (Database::num_rows($sql_result)) {
351
        while ($work = Database::fetch_object($sql_result)) {
352
            if ($work->parent_id == 0) {
353
                $work_parents[] = $work;
354
            }
355
        }
356
    }
357
358
    return $work_parents;
359
}
360
361
/**
362
 * @param int $userId
363
 * @param int $courseId
364
 * @param int $sessionId
365
 * @return array
366
 */
367
function getWorkPerUser($userId, $courseId = 0, $sessionId = 0)
368
{
369
    $works = getWorkList(null, null, null, $courseId, $sessionId);
370
    $result = array();
371
    if (!empty($works)) {
372
        foreach ($works as $workData) {
373
            $workId = $workData->id;
374
            $result[$workId]['work'] = $workData;
375
            $result[$workId]['work']->user_results = get_work_user_list(
376
                0,
377
                100,
378
                null,
379
                null,
380
                $workId,
381
                null,
382
                $userId,
383
                false,
384
                $courseId,
385
                $sessionId
386
            );
387
        }
388
    }
389
    return $result;
390
}
391
392
/**
393
 * @param int $workId
394
 * @param int $groupId
395
 * @param int $course_id
396
 * @param int $sessionId
397
 * @return mixed
398
 */
399
function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
400
{
401
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
402
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
403
    $course_id = intval($course_id);
404
    $workId = intval($workId);
405
    $sessionId = intval($sessionId);
406
    $groupId = intval($groupId);
407
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
408
409
    $groupIid = 0;
410
    if ($groupId) {
411
        $groupInfo = GroupManager::get_group_properties($groupId);
412
        $groupIid = $groupInfo['iid'];
413
    }
414
415
    $sql = "SELECT count(DISTINCT u.user_id)
416
            FROM $work_table w
417
            INNER JOIN $user_table u
418
            ON w.user_id = u.user_id
419
            WHERE
420
                w.c_id = $course_id
421
                $sessionCondition AND
422
                w.parent_id = $workId AND
423
                w.post_group_id = $groupIid AND
424
                w.active IN (0, 1)
425
            ";
426
427
    $res_document = Database::query($sql);
428
    $rowCount = Database::fetch_row($res_document);
429
430
    return $rowCount[0];
431
}
432
433
/**
434
 * @param mixed $workId
435
 * @param int $groupId
436
 * @param int $course_id
437
 * @param int $sessionId
438
 * @param int $userId user id to filter
439
 * @param array $onlyUserList only parse this user list
440
 * @return mixed
441
 */
442
function getUniqueStudentAttempts(
443
    $workId,
444
    $groupId,
445
    $course_id,
446
    $sessionId,
447
    $userId = null,
448
    $onlyUserList = array()
449
) {
450
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
451
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
452
453
    $course_id = intval($course_id);
454
    $workCondition = null;
455
    if (is_array($workId)) {
456
        $workId = array_map('intval', $workId);
457
        $workId = implode("','", $workId);
458
        $workCondition = " w.parent_id IN ('".$workId."') AND";
459
    } else {
460
        $workId = intval($workId);
461
        $workCondition = " w.parent_id = ".$workId." AND";
462
    }
463
464
    $sessionId = intval($sessionId);
465
    $groupId = intval($groupId);
466
    $studentCondition = null;
467
468
    if (!empty($onlyUserList)) {
469
        $onlyUserList = array_map('intval', $onlyUserList);
470
        $studentCondition = "AND u.user_id IN ('".implode("', '", $onlyUserList)."') ";
471
    } else {
472
        if (empty($userId)) {
473
            return 0;
474
        }
475
    }
476
477
    $groupIid = 0;
478
    if ($groupId) {
479
        $groupInfo = GroupManager::get_group_properties($groupId);
480
        $groupIid = $groupInfo['iid'];
481
    }
482
483
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
484
485
    $sql = "SELECT count(*) FROM (
486
                SELECT count(*), w.parent_id
487
                FROM $work_table w
488
                INNER JOIN $user_table u
489
                ON w.user_id = u.user_id
490
                WHERE
491
                    w.filetype = 'file' AND
492
                    w.c_id = $course_id
493
                    $sessionCondition AND
494
                    $workCondition
495
                    w.post_group_id = $groupIid AND
496
                    w.active IN (0, 1) $studentCondition
497
                ";
498
    if (!empty($userId)) {
499
        $userId = intval($userId);
500
        $sql .= " AND u.user_id = ".$userId;
501
    }
502
    $sql .= " GROUP BY u.user_id, w.parent_id) as t";
503
    $result = Database::query($sql);
504
    $row = Database::fetch_row($result);
505
506
    return $row[0];
507
}
508
509
/**
510
 * Shows the work list (student view)
511
 * @return string
512
 */
513
function showStudentWorkGrid()
514
{
515
    $courseInfo = api_get_course_info();
516
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student&'.api_get_cidreq();
517
518
    $columns = array(
519
        get_lang('Type'),
520
        get_lang('Title'),
521
        get_lang('HandOutDateLimit'),
522
        get_lang('Feedback'),
523
        get_lang('LastUpload')
524
    );
525
526
    $columnModel = array(
527
        array('name'=>'type', 'index'=>'type', 'width'=>'30', 'align'=>'center', 'sortable' => 'false'),
528
        array('name'=>'title', 'index'=>'title', 'width'=>'250',   'align'=>'left'),
529
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
530
        array('name'=>'feedback', 'index'=>'feedback', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
531
        array('name'=>'last_upload', 'index'=>'feedback', 'width'=>'125',  'align'=>'center', 'sortable'=>'false')
532
    );
533
534 View Code Duplication
    if ($courseInfo['show_score'] == 0) {
535
        $columnModel[] = array(
536
            'name' => 'others',
537
            'index' => 'others',
538
            'width' => '80',
539
            'align' => 'left',
540
            'sortable' => 'false'
541
        );
542
        $columns[] = get_lang('Others');
543
    }
544
545
    $params = array(
546
        'autowidth' => 'true',
547
        'height' => 'auto'
548
    );
549
550
    $html = '<script>
551
        $(function() {
552
            '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
553
        });
554
    </script>';
555
556
    $html .= Display::grid_html('workList');
557
    return $html;
558
}
559
560
/**
561
 * Shows the work list (teacher view)
562
 * @return string
563
 */
564
function showTeacherWorkGrid()
565
{
566
    $columnModel = array(
567
        array('name'=>'type', 'index'=>'type', 'width'=>'35', 'align'=>'center', 'sortable' => 'false'),
568
        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left', 'wrap_cell' => "true"),
569
        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'125',  'align'=>'center'),
570
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'125',  'align'=>'center'),
571
        array('name'=>'amount', 'index'=>'amount', 'width'=>'110',  'align'=>'center', 'sortable' => 'false'),
572
        array('name'=>'actions', 'index'=>'actions', 'width'=>'110', 'align'=>'left', 'sortable'=>'false')
573
    );
574
575
    $token = null;
576
577
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
578
    $deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
579
580
    $columns = array(
581
        get_lang('Type'),
582
        get_lang('Title'),
583
        get_lang('SentDate'),
584
        get_lang('HandOutDateLimit'),
585
        get_lang('AmountSubmitted'),
586
        get_lang('Actions')
587
    );
588
589
    $params = array(
590
        'multiselect' => true,
591
        'autowidth' => 'true',
592
        'height' => 'auto'
593
    );
594
595
    $html = '<script>
596
    $(function() {
597
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
598
        $("#workList").jqGrid(
599
            "navGrid",
600
            "#workList_pager",
601
            { edit: false, add: false, del: true },
602
            { height:280, reloadAfterSubmit:false }, // edit options
603
            { height:280, reloadAfterSubmit:false }, // add options
604
            { reloadAfterSubmit:false, url: "'.$deleteUrl.'" }, // del options
605
            { width:500 } // search options
606
        );
607
    });
608
    </script>';
609
    $html .= Display::grid_html('workList');
610
    return $html;
611
}
612
613
/**
614
 * Builds the form thats enables the user to
615
 * select a directory to browse/upload in
616
 * This function has been copied from the document/document.inc.php library
617
 *
618
 * @param array $folders
619
 * @param string $curdirpath
620
 * @param string $group_dir
621
 * @return string html form
622
 */
623
// TODO: This function is a candidate for removal, it is not used anywhere.
624
function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
625
{
626
    $form = '<form name="selector" action="'.api_get_self().'?'.api_get_cidreq().'" method="POST">';
627
    $form .= get_lang('CurrentDirectory').' <select name="curdirpath" onchange="javascript: document.selector.submit();">';
628
    //group documents cannot be uploaded in the root
629
    if ($group_dir == '') {
630
        $form .= '<option value="/">/ ('.get_lang('Root').')</option>';
631
        if (is_array($folders)) {
632
            foreach ($folders as $folder) {
633
                $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
634
                $form .= '<option'.$selected.' value="'.$folder.'">'.$folder.'</option>'."\n";
635
            }
636
        }
637
    } else {
638
        foreach ($folders as $folder) {
639
            $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
640
            $display_folder = substr($folder, strlen($group_dir));
641
            $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
642
            $form .= '<option'.$selected.' value="'.$folder.'">'.$display_folder.'</option>'."\n";
643
        }
644
    }
645
646
    $form .= '</select>';
647
    $form .= '<noscript><input type="submit" name="change_path" value="'.get_lang('Ok').'" /></noscript>';
648
    $form .= '</form>';
649
650
    return $form;
651
}
652
653
/**
654
 * Builds the form thats enables the user to
655
 * move a document from one directory to another
656
 * This function has been copied from the document/document.inc.php library
657
 *
658
 * @param array $folders
659
 * @param string $curdirpath
660
 * @param string $move_file
661
 * @param string $group_dir
662
 * @return string html form
663
 */
664
function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_dir = '')
665
{
666
    $course_id = api_get_course_int_id();
667
    $move_file = intval($move_file);
668
    $tbl_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
669
    $sql = "SELECT title, url FROM $tbl_work
670
            WHERE c_id = $course_id AND id ='".$move_file."'";
671
    $result = Database::query($sql);
672
    $row = Database::fetch_array($result, 'ASSOC');
673
    $title = empty($row['title']) ? basename($row['url']) : $row['title'];
674
675
    $form = new FormValidator(
676
        'move_to_form',
677
        'post',
678
        api_get_self().'?'.api_get_cidreq().'&curdirpath='.Security::remove_XSS($curdirpath)
679
    );
680
681
    $form->addHeader(get_lang('MoveFile').' - '.Security::remove_XSS($title));
682
    $form->addHidden('item_id', $move_file);
683
    $form->addHidden('action', 'move_to');
684
685
    //group documents cannot be uploaded in the root
686
    if ($group_dir == '') {
687
        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...
688
            //$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
689
        }
690
        if (is_array($folders)) {
691
            foreach ($folders as $fid => $folder) {
692
                //you cannot move a file to:
693
                //1. current directory
694
                //2. inside the folder you want to move
695
                //3. inside a subfolder of the folder you want to move
696
                if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
697
                    //$form .= '<option value="'.$fid.'">'.$folder.'</option>';
698
                    $options[$fid] = $folder;
699
                }
700
            }
701
        }
702
    } else {
703
        if ($curdirpath != '/') {
704
            $form .= '<option value="0">/ ('.get_lang('Root').')</option>';
705
        }
706
        foreach ($folders as $fid => $folder) {
707
            if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
708
                //cannot copy dir into his own subdir
709
                $display_folder = substr($folder, strlen($group_dir));
710
                $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
711
                //$form .= '<option value="'.$fid.'">'.$display_folder.'</option>'."\n";
712
                $options[$fid] = $display_folder;
713
            }
714
        }
715
    }
716
717
    $form->addSelect('move_to_id', get_lang('Select'), $options);
718
    $form->addButtonSend(get_lang('MoveFile'), 'move_file_submit');
719
720
    return $form->returnForm();
721
}
722
723
/**
724
 * creates a new directory trying to find a directory name
725
 * that doesn't already exist
726
 *
727
 * @author Hugues Peeters <[email protected]>
728
 * @author Bert Vanderkimpen
729
 * @author Yannick Warnier <[email protected]> Adaptation for work tool
730
 * @param   string $base_work_dir Base work dir (.../work)
731
 * @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...
732
 *
733
 * @return  string actual directory name if it succeeds, boolean false otherwise
734
 */
735
function create_unexisting_work_directory($base_work_dir, $desired_dir_name)
736
{
737
    $nb = '';
738
    $base_work_dir = (substr($base_work_dir, -1, 1) == '/' ? $base_work_dir : $base_work_dir.'/');
739
    while (file_exists($base_work_dir.$desired_dir_name.$nb)) {
740
        $nb += 1;
741
    }
742
743
    if (@mkdir($base_work_dir.$desired_dir_name.$nb, api_get_permissions_for_new_directories())) {
744
        return $desired_dir_name.$nb;
745
    } else {
746
        return false;
747
    }
748
}
749
750
/**
751
 * Delete a work-tool directory
752
 * @param   int  $id work directory id to delete
753
 * @return  integer -1 on error
754
 */
755
function deleteDirWork($id)
756
{
757
    $locked = api_resource_is_locked_by_gradebook($id, LINK_STUDENTPUBLICATION);
758
759
    if ($locked == true) {
760
        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...
761
        return false;
762
    }
763
764
    $_course = api_get_course_info();
765
    $id = intval($id);
766
    $work_data = get_work_data_by_id($id);
767
768
    if (empty($work_data)) {
769
        return false;
770
    }
771
772
    $base_work_dir = api_get_path(SYS_COURSE_PATH) .$_course['path'].'/work';
773
    $work_data_url = $base_work_dir.$work_data['url'];
774
    $check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
775
776
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
777
    $TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
778
    $t_agenda = Database::get_course_table(TABLE_AGENDA);
779
780
    $course_id = api_get_course_int_id();
781
782
    if (!empty($work_data['url'])) {
783
        if ($check) {
784
            // Deleting all contents inside the folder
785
            $sql = "UPDATE $table SET active = 2
786
                    WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
787
            Database::query($sql);
788
789
            $sql = "UPDATE $table SET active = 2
790
                    WHERE c_id = $course_id AND parent_id = $id";
791
            Database::query($sql);
792
793
            $new_dir = $work_data_url.'_DELETED_'.$id;
794
795 View Code Duplication
            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
796
                my_delete($work_data_url);
797
            } else {
798
                if (file_exists($work_data_url)) {
799
                    rename($work_data_url, $new_dir);
800
                }
801
            }
802
803
            // Gets calendar_id from student_publication_assigment
804
            $sql = "SELECT add_to_calendar FROM $TSTDPUBASG
805
                    WHERE c_id = $course_id AND publication_id = $id";
806
            $res = Database::query($sql);
807
            $calendar_id = Database::fetch_row($res);
808
809
            // delete from agenda if it exists
810
            if (!empty($calendar_id[0])) {
811
                $sql = "DELETE FROM $t_agenda
812
                        WHERE c_id = $course_id AND id = '".$calendar_id[0]."'";
813
                Database::query($sql);
814
            }
815
            $sql = "DELETE FROM $TSTDPUBASG
816
                    WHERE c_id = $course_id AND publication_id = $id";
817
            Database::query($sql);
818
819
            Event::addEvent(
820
                LOG_WORK_DIR_DELETE,
821
                LOG_WORK_DATA,
822
                [
823
                    'id' => $work_data['id'],
824
                    'url' => $work_data['url'],
825
                    'title' => $work_data['title']
826
                ],
827
                null,
828
                api_get_user_id(),
829
                api_get_course_int_id(),
830
                api_get_session_id()
831
            );
832
833
            $link_info = GradebookUtils::isResourceInCourseGradebook(
834
                api_get_course_id(),
835
                3,
836
                $id,
837
                api_get_session_id()
838
            );
839
            $link_id = $link_info['id'];
840
            if ($link_info !== false) {
841
                GradebookUtils::remove_resource_from_course_gradebook($link_id);
842
            }
843
            return true;
844
        }
845
    }
846
}
847
848
/**
849
 * Get the path of a document in the student_publication table (path relative to the course directory)
850
 * @param   integer $id
851
 * @return  string  Path (or -1 on error)
852
 */
853
function get_work_path($id)
854
{
855
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
856
    $course_id  = api_get_course_int_id();
857
    $sql = 'SELECT url FROM '.$table.'
858
            WHERE c_id = '.$course_id.' AND id='.intval($id);
859
    $res = Database::query($sql);
860
    if (Database::num_rows($res)) {
861
        $row = Database::fetch_array($res);
862
        return $row['url'];
863
    }
864
    return -1;
865
}
866
867
/**
868
 * Update the url of a work in the student_publication table
869
 * @param integer $id of the work to update
870
 * @param string  $new_path Destination directory where the work has been moved (must end with a '/')
871
 * @param int $parent_id
872
 *
873
 * @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...
874
 */
875
function updateWorkUrl($id, $new_path, $parent_id)
876
{
877
    if (empty($id)) {
878
        return -1;
879
    }
880
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
881
    $course_id = api_get_course_int_id();
882
    $id = intval($id);
883
    $parent_id = intval($parent_id);
884
885
    $sql = "SELECT * FROM $table
886
            WHERE c_id = $course_id AND id = $id";
887
    $res = Database::query($sql);
888
    if (Database::num_rows($res) != 1) {
889
        return -1;
890
    } else {
891
        $row = Database::fetch_array($res);
892
        $filename = basename($row['url']);
893
        $new_url = $new_path.$filename;
894
        $new_url = Database::escape_string($new_url);
895
896
        $sql = "UPDATE $table SET
897
                   url = '$new_url',
898
                   parent_id = '$parent_id'
899
                WHERE c_id = $course_id AND id = $id";
900
        $res = Database::query($sql);
901
902
        return $res;
903
    }
904
}
905
906
/**
907
 * Update the url of a dir in the student_publication table
908
 * @param  array $work_data work original data
909
 * @param  string $newPath Example: "folder1"
910
 * @return bool
911
 */
912
function updateDirName($work_data, $newPath)
913
{
914
    $course_id = $work_data['c_id'];
915
    $sessionId = intval($work_data['session_id']);
916
    $work_id = intval($work_data['iid']);
917
    $oldPath = $work_data['url'];
918
    $originalNewPath = Database::escape_string($newPath);
919
    $newPath = Database::escape_string($newPath);
920
    $newPath = api_replace_dangerous_char($newPath);
921
    $newPath = disable_dangerous_file($newPath);
922
923
    if ($oldPath == '/'.$newPath) {
924
        return true;
925
    }
926
927 View Code Duplication
    if (!empty($newPath)) {
928
        $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
929
        $sql = "UPDATE $table SET
930
                    title = '".$originalNewPath."'
931
                WHERE
932
                    c_id = $course_id AND
933
                    iid = $work_id";
934
        Database::query($sql);
935
    }
936
}
937
938
/**
939
 * Return an array with all the folder's ids that are in the given path
940
 * @param   string Path of the directory
941
 * @return  array The list of ids of all the directories in the path
942
 * @author  Julio Montoya
943
 * @version April 2008
944
 */
945
function get_parent_directories($id)
946
{
947
    $course_id = api_get_course_int_id();
948
    $em = Database::getManager();
949
950
    $directories = $em
951
        ->getRepository('ChamiloCourseBundle:CStudentPublication')
952
        ->findBy([
953
            'cId' => $course_id,
954
            'parentId' => $id
955
        ]);
956
957
    $list_id = array();
958
959
    foreach ($directories as $directory) {
960
        $list_id[] = $directory->getId();
961
    }
962
963
    return $list_id;
964
}
965
966
/**
967
 * Transform an all directory structure (only directories) in an array
968
 * @param   string path of the directory
969
 * @return  array the directory structure into an array
970
 * @author  Julio Montoya
971
 * @version April 2008
972
 */
973 View Code Duplication
function directory_to_array($directory)
974
{
975
    $array_items = array();
976
    if ($handle = @opendir($directory)) {
977
        while (false !== ($file = readdir($handle))) {
978
            if ($file != '.' && $file != '..') {
979
                if (is_dir($directory. '/' . $file)) {
980
                    $array_items = array_merge($array_items, directory_to_array($directory. '/' . $file));
981
                    $file = $directory . '/' . $file;
982
                    $array_items[] = preg_replace("/\/\//si", '/', $file);
983
                }
984
            }
985
        }
986
        closedir($handle);
987
    }
988
989
    return $array_items;
990
}
991
992
/**
993
 * Insert into the DB of the course all the directories
994
 * @param   string path of the /work directory of the course
995
 * @return  -1 on error, sql query result on success
996
 * @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...
997
 * @version April 2008
998
 * @param string $base_work_dir
999
 */
1000
1001
function insert_all_directory_in_course_table($base_work_dir)
1002
{
1003
    $dir_to_array = directory_to_array($base_work_dir, true);
1004
    $only_dir = array();
1005
1006
    for ($i = 0; $i < count($dir_to_array); $i++) {
1007
        $only_dir[] = substr($dir_to_array[$i], strlen($base_work_dir), strlen($dir_to_array[$i]));
1008
    }
1009
    $course_id = api_get_course_int_id();
1010
    $group_id  = api_get_group_id();
1011
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
1012
    $groupIid = 0;
1013
    if ($group_id) {
1014
        $groupInfo = GroupManager::get_group_properties($group_id);
1015
        $groupIid = $groupInfo['iid'];
1016
    }
1017
1018
    for ($i = 0; $i < count($only_dir); $i++) {
1019
        $url = $only_dir[$i];
1020
1021
        $params = [
1022
            'c_id' => $course_id,
1023
            'url' => $url,
1024
            'title' => '',
1025
            'description' => '',
1026
            'author' => '',
1027
            'active' => '1',
1028
            'accepted' => '1',
1029
            'filetype' => 'folder',
1030
            'post_group_id' => $groupIid,
1031
        ];
1032
1033
        Database::insert($work_table, $params);
1034
    }
1035
}
1036
1037
/**
1038
 * This function displays the number of files contained in a directory
1039
 *
1040
 * @param   string the path of the directory
1041
 * @param   boolean true if we want the total quantity of files
1042
 * include in others child directories, false only  files in the directory
1043
 * @return  array the first element is an integer with the number of files
1044
 * in the folder, the second element is the number of directories
1045
 * @author  Julio Montoya
1046
 * @version April 2008
1047
 */
1048
function count_dir($path_dir, $recurse)
1049
{
1050
    $count = 0;
1051
    $count_dir = 0;
1052
    $d = dir($path_dir);
1053
    while ($entry = $d->Read()) {
1054
        if (!(($entry == '..') || ($entry == '.'))) {
1055
            if (is_dir($path_dir.'/'.$entry)) {
1056
                $count_dir++;
1057
                if ($recurse) {
1058
                    $count += count_dir($path_dir . '/' . $entry, $recurse);
1059
                }
1060
            } else {
1061
                $count++;
1062
            }
1063
        }
1064
    }
1065
    $return_array = array();
1066
    $return_array[] = $count;
1067
    $return_array[] = $count_dir;
1068
    return $return_array;
1069
}
1070
1071
/**
1072
 * returns all the javascript that is required for easily
1073
 * validation when you create a work
1074
 * this goes into the $htmlHeadXtra[] array
1075
 */
1076
function to_javascript_work()
1077
{
1078
    $js = '<script>
1079
        function updateDocumentTitle(value) {
1080
            var temp = value.indexOf("/");
1081
            //linux path
1082
            if(temp!=-1){
1083
                var temp=value.split("/");
1084
            } else {
1085
                var temp=value.split("\\\");
1086
            }
1087
            document.getElementById("file_upload").value=temp[temp.length-1];
1088
            $("#contains_file_id").attr("value", 1);
1089
        }
1090
1091
        function checkDate(month, day, year) {
1092
          var monthLength =
1093
            new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1094
1095
          if (!day || !month || !year)
1096
            return false;
1097
1098
          // check for bisestile year
1099
          if (year/4 == parseInt(year/4))
1100
            monthLength[1] = 29;
1101
1102
          if (month < 1 || month > 12)
1103
            return false;
1104
1105
          if (day > monthLength[month-1])
1106
            return false;
1107
1108
          return true;
1109
        }
1110
1111
        function mktime() {
1112
1113
            var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
1114
            d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
1115
1116
            var dateManip = {
1117
                0: function(tt){ return d.setHours(tt); },
1118
                1: function(tt){ return d.setMinutes(tt); },
1119
                2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
1120
                3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
1121
                4: function(tt){ return d.setDate(tt+mb); },
1122
                5: function(tt){ return d.setYear(tt+ma); }
1123
            };
1124
1125
            for( i = 0; i < argc; i++ ){
1126
                no = parseInt(argv[i]*1);
1127
                if (isNaN(no)) {
1128
                    return false;
1129
                } else {
1130
                    // arg is number, lets manipulate date object
1131
                    if(!dateManip[i](no)){
1132
                        // failed
1133
                        return false;
1134
                    }
1135
                }
1136
            }
1137
            return Math.floor(d.getTime()/1000);
1138
        }
1139
1140
        function setFocus() {
1141
            $("#work_title").focus();
1142
        }
1143
1144
        $(document).ready(function() {
1145
            setFocus();
1146
1147
            var checked = $("#expiry_date").attr("checked");
1148
            if (checked) {
1149
                $("#option2").show();                
1150
            } else {
1151
                $("#option2").hide();                
1152
            }
1153
            
1154
            var checkedEndDate = $("#end_date").attr("checked");            
1155
            if (checkedEndDate) {                
1156
                $("#option3").show();
1157
                $("#ends_on").attr("checked", true);
1158
            } else {
1159
                $("#option3").hide();                
1160
                $("#ends_on").attr("checked", false);
1161
            }
1162
1163
            $("#expiry_date").click(function() {
1164
                $("#option2").toggle();
1165
            });
1166
1167
            $("#end_date").click(function() {
1168
                $("#option3").toggle();
1169
            });
1170
        });
1171
    </script>';
1172
1173
    return $js;
1174
}
1175
1176
/**
1177
 * Gets the id of a student publication with a given path
1178
 * @param string $path
1179
 * @return true if is found / false if not found
1180
 */
1181
// TODO: The name of this function does not fit with the kind of information it returns. Maybe check_work_id() or is_work_id()?
1182
function get_work_id($path)
1183
{
1184
    $TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1185
    $TBL_PROP_TABLE = Database::get_course_table(TABLE_ITEM_PROPERTY);
1186
    $course_id = api_get_course_int_id();
1187
    $path = Database::escape_string($path);
1188
1189
    if (api_is_allowed_to_edit()) {
1190
        $sql = "SELECT work.id
1191
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1192
                WHERE
1193
                    props.c_id = $course_id AND
1194
                    work.c_id = $course_id AND
1195
                    props.tool='work' AND
1196
                    work.id=props.ref AND
1197
                    work.url LIKE 'work/".$path."%' AND
1198
                    work.filetype='file' AND
1199
                    props.visibility<>'2'";
1200
    } else {
1201
        $sql = "SELECT work.id
1202
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1203
                WHERE
1204
                    props.c_id = $course_id AND
1205
                    work.c_id = $course_id AND
1206
                    props.tool='work' AND
1207
                    work.id=props.ref AND
1208
                    work.url LIKE 'work/".$path."%' AND
1209
                    work.filetype='file' AND
1210
                    props.visibility<>'2' AND
1211
                    props.lastedit_user_id = '".api_get_user_id()."'";
1212
    }
1213
    $result = Database::query($sql);
1214
    $num_rows = Database::num_rows($result);
1215
1216
    if ($result && $num_rows > 0) {
1217
        return true;
1218
    } else {
1219
        return false;
1220
    }
1221
}
1222
1223
/**
1224
 * @param int $work_id
1225
 * @param int $onlyMeUserId show only my works
1226
 * @param int $notMeUserId show works from everyone except me
1227
 * @return int
1228
 */
1229
function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
1230
{
1231
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1232
    $iprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1233
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1234
1235
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
1236
    $session_id = api_get_session_id();
1237
    $condition_session = api_get_session_condition($session_id, true, false, 'work.session_id');
1238
1239
    $group_id = api_get_group_id();
1240
    $course_info = api_get_course_info();
1241
    $course_id = $course_info['real_id'];
1242
    $work_id = intval($work_id);
1243
1244
    $groupIid = 0;
1245
    if ($group_id) {
1246
        $groupInfo = GroupManager::get_group_properties($group_id);
1247
        $groupIid = $groupInfo['iid'];
1248
    }
1249
1250
1251 View Code Duplication
    if (!empty($group_id)) {
1252
        // set to select only messages posted by the user's group
1253
        $extra_conditions = " work.post_group_id = '".intval($groupIid)."' ";
1254
    } else {
1255
        $extra_conditions = " (work.post_group_id = '0' or work.post_group_id IS NULL) ";
1256
    }
1257
1258 View Code Duplication
    if ($is_allowed_to_edit) {
1259
        $extra_conditions .= ' AND work.active IN (0, 1) ';
1260
    } else {
1261
        $extra_conditions .= ' AND work.active IN (0, 1) AND accepted = 1';
1262
        if (isset($course_info['show_score']) && $course_info['show_score'] == 1) {
1263
            $extra_conditions .= " AND work.user_id = ".api_get_user_id()." ";
1264
        } else {
1265
            $extra_conditions .= '';
1266
        }
1267
    }
1268
1269
    $extra_conditions .= " AND parent_id  = ".$work_id."  ";
1270
1271
    $where_condition = null;
1272
1273
    if (!empty($notMeUserId)) {
1274
        $where_condition .= " AND u.user_id <> ".intval($notMeUserId);
1275
    }
1276
1277
    if (!empty($onlyMeUserId)) {
1278
        $where_condition .= " AND u.user_id =  ".intval($onlyMeUserId);
1279
    }
1280
1281
    $sql = "SELECT count(*) as count
1282
            FROM $iprop_table prop
1283
            INNER JOIN $work_table work
1284
            ON (
1285
                prop.ref = work.id AND
1286
                prop.c_id = $course_id AND
1287
                prop.tool='work' AND
1288
                prop.visibility <> 2 AND
1289
                work.c_id = $course_id
1290
            )
1291
            INNER JOIN $user_table u 
1292
            ON (work.user_id = u.user_id)
1293
            WHERE $extra_conditions $where_condition $condition_session";
1294
1295
    $result = Database::query($sql);
1296
1297
    $users_with_work = 0;
1298
    if (Database::num_rows($result)) {
1299
        $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...
1300
        $users_with_work = $result['count'];
1301
    }
1302
    return $users_with_work;
1303
}
1304
1305
/**
1306
 * @param int $start
1307
 * @param int $limit
1308
 * @param string $column
1309
 * @param string $direction
1310
 * @param string $where_condition
1311
 * @param bool $getCount
1312
 * @return array
1313
 */
1314
function getWorkListStudent(
1315
    $start,
1316
    $limit,
1317
    $column,
1318
    $direction,
1319
    $where_condition,
1320
    $getCount = false
1321
) {
1322
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1323
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1324
    $courseInfo = api_get_course_info();
1325
    $course_id = $courseInfo['real_id'];
1326
    $session_id = api_get_session_id();
1327
    $condition_session = api_get_session_condition($session_id);
1328
    $group_id = api_get_group_id();
1329
    $userId = api_get_user_id();
1330
1331
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1332
        api_get_user_id(),
1333
        $courseInfo
1334
    );
1335
1336
    if (!in_array($direction, array('asc','desc'))) {
1337
        $direction = 'desc';
1338
    }
1339
    if (!empty($where_condition)) {
1340
        $where_condition = ' AND ' . $where_condition;
1341
    }
1342
1343
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1344
    $start = intval($start);
1345
    $limit = intval($limit);
1346
1347
    $groupIid = 0;
1348
    if ($group_id) {
1349
        $groupInfo = GroupManager::get_group_properties($group_id);
1350
        $groupIid = $groupInfo['iid'];
1351
    }
1352
    $groupIid = (int) $groupIid;
1353
1354
    // Get list from database
1355 View Code Duplication
    if (!empty($groupIid)) {
1356
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = $groupIid";
1357
        $subdirs_query = "AND parent_id = 0";
1358
    } else {
1359
        $group_query = " WHERE w.c_id = $course_id AND (post_group_id = '0' or post_group_id is NULL)  ";
1360
        $subdirs_query = "AND parent_id = 0";
1361
    }
1362
1363
    $active_condition = ' AND active IN (1, 0)';
1364
1365
    if ($getCount) {
1366
        $select = "SELECT count(w.id) as count ";
1367
    } else {
1368
        $select = "SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1369
    }
1370
1371
    $sql = "$select
1372
            FROM $workTable w
1373
            LEFT JOIN $workTableAssignment a
1374
            ON (a.publication_id = w.id AND a.c_id = w.c_id)
1375
                $group_query
1376
                $subdirs_query
1377
                $active_condition
1378
                $condition_session
1379
                $where_condition
1380
            ";
1381
1382
    $sql .= " ORDER BY $column $direction ";
1383
1384
    if (!empty($start) && !empty($limit)) {
1385
        $sql .= " LIMIT $start, $limit";
1386
    }
1387
1388
    $result = Database::query($sql);
1389
1390
    if ($getCount) {
1391
        $row = Database::fetch_array($result);
1392
        return $row['count'];
1393
    }
1394
1395
    $works = array();
1396
    $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
1397
    if ($isDrhOfCourse) {
1398
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1399
    }
1400
1401
    $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
1402
    while ($work = Database::fetch_array($result, 'ASSOC')) {
1403
        $isSubscribed = userIsSubscribedToWork($userId, $work['id'], $course_id);
1404
        if ($isSubscribed == false) {
1405
            continue;
1406
        }
1407
1408
        $visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $session_id);
1409
1410
        if ($visibility != 1) {
1411
            continue;
1412
        }
1413
1414
        $work['type'] = Display::return_icon('work.png');
1415
        $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1416
1417
        if (empty($work['title'])) {
1418
            $work['title'] = basename($work['url']);
1419
        }
1420
1421
        $whereCondition = " AND u.user_id = ".intval($userId);
1422
1423
        $workList = get_work_user_list(
1424
            0,
1425
            1000,
1426
            null,
1427
            null,
1428
            $work['id'],
1429
            $whereCondition
1430
        );
1431
1432
        $count = getTotalWorkComment($workList, $courseInfo);
1433
1434 View Code Duplication
        if (!is_null($count) && !empty($count)) {
1435
            $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info');
1436
        }
1437
1438
        $lastWork = getLastWorkStudentFromParentByUser($userId, $work['id'], $courseInfo);
1439
1440
        if (!empty($lastWork)) {
1441
            $work['last_upload'] = (!empty($lastWork['qualification'])) ? Display::label($lastWork['qualification'], 'warning').' - ' : '';
1442
            $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1443
        }
1444
1445
        $work['title'] = Display::url($work['title'], $url.'&id='.$work['id']);
1446
        $work['others'] = Display::url(
1447
            Display::return_icon('group.png', get_lang('Others')),
1448
            $urlOthers.$work['id']
1449
        );
1450
        $works[] = $work;
1451
    }
1452
1453
    return $works;
1454
}
1455
1456
/**
1457
 * @param int $start
1458
 * @param int $limit
1459
 * @param string $column
1460
 * @param string $direction
1461
 * @param string $where_condition
1462
 * @param bool $getCount
1463
 * @return array
1464
 */
1465
function getWorkListTeacher(
1466
    $start,
1467
    $limit,
1468
    $column,
1469
    $direction,
1470
    $where_condition,
1471
    $getCount = false
1472
) {
1473
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1474
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1475
1476
    $courseInfo = api_get_course_info();
1477
    $course_id = api_get_course_int_id();
1478
    $session_id = api_get_session_id();
1479
    $condition_session = api_get_session_condition($session_id);
1480
    $group_id = api_get_group_id();
1481
    $groupIid = 0;
1482
    if ($group_id) {
1483
        $groupInfo = GroupManager::get_group_properties($group_id);
1484
        $groupIid = $groupInfo['iid'];
1485
    }
1486
    $groupIid = (int) $groupIid;
1487
1488
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1489
    if (!in_array($direction, array('asc', 'desc'))) {
1490
        $direction = 'desc';
1491
    }
1492
    if (!empty($where_condition)) {
1493
        $where_condition = ' AND ' . $where_condition;
1494
    }
1495
1496
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1497
    $start = intval($start);
1498
    $limit = intval($limit);
1499
    $works = array();
1500
1501
    // Get list from database
1502
    if ($is_allowed_to_edit) {
1503
        $active_condition = ' active IN (0, 1)';
1504
        if ($getCount) {
1505
            $select = " SELECT count(w.id) as count";
1506
        } else {
1507
            $select = " SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1508
        }
1509
        $sql = " $select
1510
                FROM $workTable w
1511
                LEFT JOIN $workTableAssignment a
1512
                ON (a.publication_id = w.id AND a.c_id = w.c_id)
1513
                WHERE
1514
                    w.c_id = $course_id
1515
                    $condition_session AND
1516
                    $active_condition AND
1517
                    parent_id = 0 AND
1518
                    post_group_id = $groupIid
1519
                    $where_condition
1520
                ORDER BY $column $direction
1521
                LIMIT $start, $limit";
1522
1523
        $result = Database::query($sql);
1524
1525
        if ($getCount) {
1526
            $row = Database::fetch_array($result);
1527
1528
            return $row['count'];
1529
        }
1530
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1531
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1532
            $workId = $work['id'];
1533
            $work['type'] = Display::return_icon('work.png');
1534
            $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1535
1536
            $countUniqueAttempts = getUniqueStudentAttemptsTotal(
1537
                $workId,
1538
                $group_id,
1539
                $course_id,
1540
                $session_id
1541
            );
1542
1543
            $totalUsers = getStudentSubscribedToWork(
1544
                $workId,
1545
                $course_id,
1546
                $group_id,
1547
                $session_id,
1548
                true
1549
            );
1550
1551
            $work['amount'] = Display::label(
1552
                $countUniqueAttempts . '/' .
1553
                $totalUsers,
1554
                'success'
1555
            );
1556
1557
            $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1558
1559
            if ($visibility == 1) {
1560
                $icon = 'visible.png';
1561
                $text = get_lang('Visible');
1562
                $action = 'invisible';
1563
                $class = '';
1564
            } else {
1565
                $icon = 'invisible.png';
1566
                $text = get_lang('Invisible');
1567
                $action = 'visible';
1568
                $class = 'muted';
1569
            }
1570
1571
            $visibilityLink = Display::url(
1572
                Display::return_icon($icon, $text, array(), ICON_SIZE_SMALL),
1573
                api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action='.$action.'&'.api_get_cidreq()
1574
            );
1575
1576
            if (empty($work['title'])) {
1577
                $work['title'] = basename($work['url']);
1578
            }
1579
            $work['title'] = Display::url($work['title'], $url.'&id='.$workId, ['class' => $class]);
1580
            $work['title'] .= ' '.Display::label(get_count_work($work['id']), 'success');
1581
            $work['sent_date'] = api_get_local_time($work['sent_date']);
1582
1583
            $editLink = Display::url(
1584
                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL),
1585
                api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq()
1586
            );
1587
1588
            $correctionLink = Display::url(
1589
                Display::return_icon('upload_file.png', get_lang('UploadCorrections'), '', ICON_SIZE_SMALL),
1590
                api_get_path(WEB_CODE_PATH).'work/upload_corrections.php?'.api_get_cidreq().'&id='.$workId
1591
            );
1592
1593
            if ($countUniqueAttempts > 0) {
1594
                $downloadLink = Display::url(
1595
                    Display::return_icon(
1596
                        'save_pack.png',
1597
                        get_lang('Save'),
1598
                        array(),
1599
                        ICON_SIZE_SMALL
1600
                    ),
1601
                    api_get_path(WEB_CODE_PATH) . 'work/downloadfolder.inc.php?id=' . $workId . '&' . api_get_cidreq()
1602
                );
1603
            } else {
1604
                $downloadLink = Display::url(
1605
                    Display::return_icon(
1606
                        'save_pack_na.png',
1607
                        get_lang('Save'),
1608
                        array(),
1609
                        ICON_SIZE_SMALL
1610
                    ),
1611
                    '#'
1612
                );
1613
            }
1614
            // Remove Delete Work Button from action List
1615
            // Because removeXSS "removes" the onClick JS Event to do the action (See model.ajax.php - Line 1639)
1616
            // But still can use the another jqgrid button to remove works (trash icon)
1617
            //
1618
            // $deleteUrl = api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action=delete_dir&'.api_get_cidreq();
1619
            // $deleteLink = '<a href="#" onclick="showConfirmationPopup(this, \'' . $deleteUrl . '\' ) " >' .
1620
            //     Display::return_icon(
1621
            //         'delete.png',
1622
            //         get_lang('Delete'),
1623
            //         array(),
1624
            //         ICON_SIZE_SMALL
1625
            //     ) . '</a>';
1626
1627
            if (!api_is_allowed_to_edit()) {
1628
                // $deleteLink = null;
1629
                $editLink = null;
1630
            }
1631
            $work['actions'] = $visibilityLink.$correctionLink.$downloadLink.$editLink;
1632
            $works[] = $work;
1633
        }
1634
    }
1635
1636
    return $works;
1637
}
1638
1639
/**
1640
 * @param int $start
1641
 * @param int $limit
1642
 * @param string $column
1643
 * @param string $direction
1644
 * @param int $workId
1645
 * @param int $studentId
1646
 * @param string $whereCondition
1647
 * @param bool $getCount
1648
 * @return array
1649
 */
1650
function get_work_user_list_from_documents(
1651
    $start,
1652
    $limit,
1653
    $column,
1654
    $direction,
1655
    $workId,
1656
    $studentId = null,
1657
    $whereCondition,
1658
    $getCount = false
1659
) {
1660
    if ($getCount) {
1661
        $select1 = " SELECT count(u.user_id) as count ";
1662
        $select2 = " SELECT count(u.user_id) as count ";
1663
    } else {
1664
        $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";
1665
        $select2 = " SELECT DISTINCT u.firstname, u.lastname, u.user_id, d.title, w.parent_id, d.id document_id, 0, 0, 0";
1666
    }
1667
1668
    $documentTable = Database::get_course_table(TABLE_DOCUMENT);
1669
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1670
    $workRelDocument = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
1671
    $userTable = Database::get_main_table(TABLE_MAIN_USER);
1672
1673
    $courseId = api_get_course_int_id();
1674
    $sessionId = api_get_session_id();
1675
1676
    if (empty($studentId)) {
1677
        $studentId = api_get_user_id();
1678
    }
1679
    $studentId = intval($studentId);
1680
    $workId = intval($workId);
1681
1682
    $userCondition = " AND u.user_id = $studentId ";
1683
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
1684
    $workCondition = " AND w_rel.work_id = $workId";
1685
    $workParentCondition  = " AND w.parent_id = $workId";
1686
1687
    $sql = "(
1688
                $select1 FROM $userTable u
1689
                INNER JOIN $workTable w
1690
                ON (u.user_id = w.user_id AND w.active IN (0, 1) AND w.filetype = 'file')
1691
                WHERE
1692
                    w.c_id = $courseId
1693
                    $userCondition
1694
                    $sessionCondition
1695
                    $whereCondition
1696
                    $workParentCondition
1697
            ) UNION (
1698
                $select2 FROM $workTable w
1699
                INNER JOIN $workRelDocument w_rel
1700
                ON (w_rel.work_id = w.id AND w.active IN (0, 1) AND w_rel.c_id = w.c_id)
1701
                INNER JOIN $documentTable d
1702
                ON (w_rel.document_id = d.id AND d.c_id = w.c_id)
1703
                INNER JOIN $userTable u ON (u.user_id = $studentId)
1704
                WHERE
1705
                    w.c_id = $courseId
1706
                    $workCondition
1707
                    $sessionCondition AND
1708
                    d.id NOT IN (
1709
                        SELECT w.document_id id
1710
                        FROM $workTable w
1711
                        WHERE
1712
                            user_id = $studentId AND
1713
                            c_id = $courseId AND
1714
                            filetype = 'file' AND
1715
                            active IN (0, 1)
1716
                            $sessionCondition
1717
                            $workParentCondition
1718
                    )
1719
            )";
1720
1721
    $start = intval($start);
1722
    $limit = intval($limit);
1723
1724
    $direction = in_array(strtolower($direction), array('desc', 'asc')) ? $direction : 'desc';
1725
    $column = Database::escape_string($column);
1726
1727
    if ($getCount) {
1728
        $result = Database::query($sql);
1729
        $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...
1730
        return $result['count'];
1731
    }
1732
1733
    $sql .= " ORDER BY $column $direction";
1734
    $sql .= " LIMIT $start, $limit";
1735
1736
    $result = Database::query($sql);
1737
1738
    $currentUserId = api_get_user_id();
1739
    $work_data = get_work_data_by_id($workId);
1740
1741
    $qualificationExists = false;
1742
1743 View Code Duplication
    if (!empty($work_data['qualification']) && intval($work_data['qualification']) > 0) {
1744
        $qualificationExists = true;
1745
    }
1746
1747
    $urlAdd = api_get_path(WEB_CODE_PATH).'work/upload_from_template.php?'.api_get_cidreq();
1748
    $urlEdit = api_get_path(WEB_CODE_PATH).'work/edit.php?'.api_get_cidreq();
1749
    $urlDelete = api_get_path(WEB_CODE_PATH).'work/work_list.php?action=delete&'.api_get_cidreq();
1750
    $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq();
1751
1752
    $editIcon = Display::return_icon('edit.png', get_lang('Edit'));
1753
    $addIcon = Display::return_icon('add.png', get_lang('Add'));
1754
    $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'));
1755
    $viewIcon = Display::return_icon('default.png', get_lang('View'));
1756
    $allowEdition = api_get_course_setting('student_delete_own_publication');
1757
1758
    $workList = array();
1759
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1760
        $userId = $row['user_id'];
1761
        $documentId = $row['document_id'];
1762
        $itemId = $row['id'];
1763
        $addLinkShowed = false;
1764
1765
        if (empty($documentId)) {
1766
            $url = $urlEdit.'&item_id='.$row['id'].'&id='.$workId;
1767
            $editLink = Display::url($editIcon, $url);
1768
            if ($allowEdition == false) {
1769
                $editLink = null;
1770
            }
1771
        } else {
1772
            $documentToWork = getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId);
1773
1774
            if (empty($documentToWork)) {
1775
                $url = $urlAdd.'&document_id='.$documentId.'&id='.$workId;
1776
                $editLink = Display::url($addIcon, $url);
1777
                $addLinkShowed = true;
1778
            } else {
1779
                $row['title'] = $documentToWork['title'];
1780
                $row['sent_date'] = $documentToWork['sent_date'];
1781
                $newWorkId = $documentToWork['id'];
1782
                $url = $urlEdit.'&item_id='.$newWorkId.'&id='.$workId;
1783
                $editLink = Display::url($editIcon, $url);
1784
1785
                if ($allowEdition == false) {
1786
                    $editLink = null;
1787
                }
1788
            }
1789
        }
1790
1791
        if ($allowEdition && !empty($itemId)) {
1792
            $deleteLink  = Display::url($deleteIcon, $urlDelete.'&item_id='.$itemId.'&id='.$workId);
1793
        } else {
1794
            $deleteLink = null;
1795
        }
1796
1797
        $viewLink = null;
1798
        if (!empty($itemId)) {
1799
            $viewLink = Display::url($viewIcon, $urlView.'&id='.$itemId);
1800
        }
1801
1802
        $row['type'] = null;
1803
1804
        if ($qualificationExists) {
1805 View Code Duplication
            if (empty($row['qualificator_id'])) {
1806
                $status = Display::label(get_lang('NotRevised'), 'warning');
1807
            } else {
1808
                $status = Display::label(get_lang('Revised'), 'success');
1809
            }
1810
            $row['qualificator_id'] = $status;
1811
        }
1812
1813
        if (!empty($row['qualification'])) {
1814
            $row['qualification'] = Display::label($row['qualification'], 'info');
1815
        }
1816
1817
        if (!empty($row['sent_date'])) {
1818
            $row['sent_date'] = api_get_local_time($row['sent_date']);
1819
        }
1820
1821
        if ($userId == $currentUserId) {
1822
            $row['actions'] = $viewLink.$editLink.$deleteLink;
1823
        }
1824
1825
        if ($addLinkShowed) {
1826
            $row['qualification'] = '';
1827
            $row['qualificator_id'] = '';
1828
        }
1829
1830
        $workList[] = $row;
1831
    }
1832
1833
    return $workList;
1834
}
1835
1836
/**
1837
 * @param int $start
1838
 * @param int $limit
1839
 * @param int $column
1840
 * @param string $direction
1841
 * @param int $work_id
1842
 * @param array $where_condition
1843
 * @param int $studentId
1844
 * @param bool $getCount
1845
 * @param int $courseId
1846
 * @param int $sessionId
1847
 * @return array
1848
 */
1849
function get_work_user_list(
1850
    $start,
1851
    $limit,
1852
    $column,
1853
    $direction,
1854
    $work_id,
1855
    $where_condition = null,
1856
    $studentId = null,
1857
    $getCount = false,
1858
    $courseId = 0,
1859
    $sessionId = 0
1860
) {
1861
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1862
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1863
1864
    $session_id = $sessionId ? $sessionId : api_get_session_id();
1865
    $group_id = api_get_group_id();
1866
    $course_info = api_get_course_info();
1867
    $course_info = empty($course_info) ? api_get_course_info_by_id($courseId) : $course_info;
1868
    $course_id = isset($course_info['real_id']) ? $course_info['real_id'] : $courseId;
1869
1870
    $work_id = intval($work_id);
1871
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1872
    $start = intval($start);
1873
    $limit = intval($limit);
1874
1875
    if (!in_array($direction, array('asc','desc'))) {
1876
        $direction = 'desc';
1877
    }
1878
1879
    $work_data = get_work_data_by_id($work_id, $courseId, $sessionId);
1880
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1881
    $condition_session  = api_get_session_condition($session_id, true, false, 'work.session_id');
1882
    $locked = api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION, $course_info['code']);
1883
1884
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1885
        api_get_user_id(),
1886
        $course_info
1887
    );
1888
1889
    $groupIid = 0;
1890
    if ($group_id) {
1891
        $groupInfo = GroupManager::get_group_properties($group_id);
1892
        $groupIid = $groupInfo['iid'];
1893
    }
1894
1895
    if (!empty($work_data)) {
1896 View Code Duplication
        if (!empty($group_id)) {
1897
            $extra_conditions = " work.post_group_id = '".intval($groupIid)."' ";
1898
            // set to select only messages posted by the user's group
1899
        } else {
1900
            $extra_conditions = " (work.post_group_id = '0' OR work.post_group_id is NULL) ";
1901
        }
1902
1903 View Code Duplication
        if ($is_allowed_to_edit || $isDrhOfCourse) {
1904
            $extra_conditions .= ' AND work.active IN (0, 1) ';
1905
        } else {
1906
            if (isset($course_info['show_score']) &&
1907
                $course_info['show_score'] == 1
1908
            ) {
1909
                $extra_conditions .= " AND (u.user_id = ".api_get_user_id()." AND work.active IN (0, 1)) ";
1910
            } else {
1911
                $extra_conditions .= ' AND work.active IN (0, 1) ';
1912
            }
1913
        }
1914
1915
        $extra_conditions .= " AND parent_id  = ".$work_id." ";
1916
1917
        $select = 'SELECT DISTINCT
1918
                        u.user_id,
1919
                        work.id as id,
1920
                        title as title,
1921
                        description,
1922
                        url,
1923
                        sent_date,
1924
                        contains_file,
1925
                        has_properties,
1926
                        view_properties,
1927
                        qualification,
1928
                        weight,
1929
                        allow_text_assignment,
1930
                        CONCAT (u.firstname," ",u.lastname) as fullname,
1931
                        u.username,
1932
                        parent_id,
1933
                        accepted,
1934
                        qualificator_id,
1935
                        url_correction
1936
                        ';
1937
        if ($getCount) {
1938
            $select = "SELECT DISTINCT count(u.user_id) as count ";
1939
        }
1940
1941
        $user_condition = "INNER JOIN $user_table u  ON (work.user_id = u.user_id) ";
1942
        $work_assignment = get_work_assignment_by_id($work_id, $courseId);
1943
1944
        if (!empty($studentId)) {
1945
            $where_condition.= " AND u.user_id = ".intval($studentId);
1946
        }
1947
1948
        $sql = " $select
1949
                FROM $work_table work  $user_condition
1950
                WHERE
1951
                    work.c_id = $course_id AND
1952
                    $extra_conditions 
1953
                    $where_condition 
1954
                    $condition_session
1955
                    AND u.status != " . INVITEE . "
1956
                ORDER BY $column $direction";
1957
1958
        if (!empty($start) && !empty($limit)) {
1959
            $sql .= " LIMIT $start, $limit";
1960
        }
1961
        $result = Database::query($sql);
1962
        $works = array();
1963
1964
        if ($getCount) {
1965
            $work = Database::fetch_array($result, 'ASSOC');
1966
            return $work['count'];
1967
        }
1968
1969
        $url = api_get_path(WEB_CODE_PATH).'work/';
1970
        $unoconv = api_get_configuration_value('unoconv.binaries');
1971
1972
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1973
            $item_id = $work['id'];
1974
1975
            // Get the author ID for that document from the item_property table
1976
            $is_author  = false;
1977
            $can_read   = false;
1978
            $owner_id = $work['user_id'];
1979
1980
            /* Because a bug found when saving items using the api_item_property_update()
1981
               the field $item_property_data['insert_user_id'] is not reliable. */
1982
1983
            if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
1984
                $is_author = true;
1985
            }
1986
1987
            if ($course_info['show_score'] == 0) {
1988
                $can_read = true;
1989
            }
1990
1991
            if ($work['accepted'] == '0') {
1992
                $class = 'text-muted';
1993
            } else {
1994
                $class = '';
1995
            }
1996
1997
            $qualification_exists = false;
1998 View Code Duplication
            if (!empty($work_data['qualification']) &&
1999
                intval($work_data['qualification']) > 0
2000
            ) {
2001
                $qualification_exists = true;
2002
            }
2003
2004
            $qualification_string = '';
2005
            if ($qualification_exists) {
2006
                if ($work['qualification'] == '') {
2007
                    $qualification_string = Display::label('-');
2008
                } else {
2009
                    $label = 'info';
2010
                    $relativeScore = $work['qualification']/$work_data['qualification'];
2011
                    if ($relativeScore < 0.5) {
2012
                        $label = 'important';
2013
                    } elseif ($relativeScore < 0.75) {
2014
                        $label = 'warning';
2015
                    }
2016
                    $qualification_string = Display::label(
2017
                        $work['qualification'].' / '.$work_data['qualification'],
2018
                        $label
2019
                    );
2020
                }
2021
            }
2022
2023
            $work['qualification_score'] = $work['qualification'];
2024
2025
            $add_string = '';
2026
            $time_expires = '';
2027
            if (!empty($work_assignment['expires_on'])) {
2028
                $time_expires = api_strtotime(
2029
                    $work_assignment['expires_on'],
2030
                    'UTC'
2031
                );
2032
            }
2033
2034
            if (!empty($work_assignment['expires_on']) &&
2035
                !empty($time_expires) && ($time_expires < api_strtotime($work['sent_date'], 'UTC'))) {
2036
                $add_string = Display::label(get_lang('Expired'), 'important');
2037
            }
2038
2039
            if (($can_read && $work['accepted'] == '1') ||
2040
                ($is_author && in_array($work['accepted'], array('1', '0'))) ||
2041
                ($is_allowed_to_edit || api_is_drh())
2042
            ) {
2043
                // Firstname, lastname, username
2044
                $work['fullname'] = Display::div($work['fullname'], array('class' => 'work-name'));
2045
                $work['title_clean'] = $work['title'];
2046
2047
                if (strlen($work['title']) > 30) {
2048
                    $short_title = substr($work['title'], 0, 27).'...';
2049
                    $work['title'] = Display::span($short_title, array('class' => 'work-title', 'title' => $work['title']));
2050
                } else {
2051
                    $work['title'] = Display::div($work['title'], array('class' => 'work-title'));
2052
                }
2053
2054
                // Type.
2055
                $work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
2056
2057
                // File name.
2058
                $link_to_download = null;
2059
2060
                // If URL is present then there's a file to download keep BC.
2061 View Code Duplication
                if ($work['contains_file'] || !empty($work['url'])) {
2062
                    $link_to_download = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.
2063
                        Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
2064
                }
2065
2066
                $send_to = Portfolio::share('work', $work['id'],  array('style' => 'white-space:nowrap;'));
2067
2068
                $feedback = null;
2069
                $count = getWorkCommentCount($item_id, $course_info);
2070
                if (!is_null($count) && !empty($count)) {
2071
                    if ($qualification_exists) {
2072
                        $feedback .= ' ';
2073
                    }
2074
                    $feedback .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2075
                    $count . ' ' . Display::returnFontAwesomeIcon('comments-o') . '</a> ';
2076
                }
2077
2078
                $work['qualification'] = $qualification_string.$feedback;
2079
                $work['qualification_only'] = $qualification_string;
2080
2081
                // Date.
2082
                $work_date = api_convert_and_format_date($work['sent_date']);
2083
                $date = date_to_str_ago($work['sent_date']). ' ' . $work_date;
2084
                $work['formatted_date'] = $work_date . ' - ' . $add_string;
2085
2086
                $work['sent_date_from_db'] = $work['sent_date'];
2087
                $work['sent_date'] = '<div class="work-date" title="'.$date.'">' . $add_string . ' - ' . $work['sent_date'] . '</div>';
2088
2089
                // Actions.
2090
                $correction = '';
2091
2092
                $action = '';
2093
                if (api_is_allowed_to_edit()) {
2094
                    if (!empty($work['url_correction'])) {
2095
                        $action .= Display::url(
2096
                            Display::return_icon('check-circle.png', get_lang('Correction'), null, ICON_SIZE_SMALL),
2097
                            api_get_path(WEB_CODE_PATH).'work/download.php?id='.$item_id.'&'.api_get_cidreq().'&correction=1'
2098
                        );
2099
                    }
2100
2101
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2102
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a> ';
2103
2104
                    if ($unoconv && empty($work['contains_file'])) {
2105
                        $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').'" >'.
2106
                            Display::return_icon('export_doc.png', get_lang('ExportToDoc'),array(), ICON_SIZE_SMALL).'</a> ';
2107
                    }
2108
                    $loadingText = addslashes(get_lang('Loading'));
2109
                    $uploadedText = addslashes(get_lang('Uploaded'));
2110
                    $failsUploadText = addslashes(get_lang('UplNoFileUploaded'));
2111
                    $failsUploadIcon = Display::return_icon('closed-circle.png', '', [], ICON_SIZE_TINY);
2112
                    $correction = '
2113
                        <form
2114
                        id="file_upload_'.$item_id.'"
2115
                        class="work_correction_file_upload file_upload_small fileinput-button"
2116
                        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"
2117
                        >
2118
                        <div id="progress_'.$item_id.'" class="text-center button-load">
2119
                            '.addslashes(get_lang('ClickOrDropOneFileHere')).'
2120
                            '.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
2121
                        </div>
2122
                        <input id="file_'.$item_id.'" type="file" name="file" class="" multiple>
2123
                        </form>
2124
                    ';
2125
2126
                    $correction .= "<script>
2127
                    $(document).ready(function() {
2128
                        $('.work_correction_file_upload').each(function () {
2129
                            $(this).fileupload({
2130
                                dropZone: $(this)
2131
                            });
2132
                        });
2133
                        $('#file_upload_".$item_id."').fileupload({
2134
                            add: function (e, data) {
2135
                                $('#progress_$item_id').html();
2136
                                //$('#file_$item_id').remove();
2137
                                data.context = $('#progress_$item_id').html('$loadingText <br /> <em class=\"fa fa-spinner fa-pulse fa-fw\"></em>');
2138
                                data.submit();
2139
                            },
2140
                            done: function (e, data) {
2141
                                if (data._response.result.name) {
2142
                                    $('#progress_$item_id').html('$uploadedText '+data._response.result.result+'<br />'+data._response.result.name);
2143
                                } else {
2144
                                    $('#progress_$item_id').html('$failsUploadText $failsUploadIcon');
2145
                                }
2146
                            }
2147
                        });
2148
                    });
2149
                    </script>";
2150
2151
                    if ($locked) {
2152
                        if ($qualification_exists) {
2153
                            $action .= Display::return_icon('rate_work_na.png', get_lang('CorrectAndRate'),array(), ICON_SIZE_SMALL);
2154
                        } else {
2155
                            $action .= Display::return_icon('edit_na.png', get_lang('Comment'), array(), ICON_SIZE_SMALL);
2156
                        }
2157 View Code Duplication
                    } else {
2158
                        if ($qualification_exists) {
2159
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Edit').'"  >'.
2160
                                Display::return_icon('rate_work.png', get_lang('CorrectAndRate'), array(), ICON_SIZE_SMALL).'</a>';
2161
                        } else {
2162
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2163
                                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
2164
                        }
2165
                    }
2166
2167 View Code Duplication
                    if ($work['contains_file']) {
2168
                        if ($locked) {
2169
                            $action .= Display::return_icon('move_na.png', get_lang('Move'),array(), ICON_SIZE_SMALL);
2170
                        } else {
2171
                            $action .= '<a href="'.$url.'work.php?'.api_get_cidreq().'&action=move&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Move').'">'.
2172
                                Display::return_icon('move.png', get_lang('Move'),array(), ICON_SIZE_SMALL).'</a>';
2173
                        }
2174
                    }
2175
2176 View Code Duplication
                    if ($work['accepted'] == '1') {
2177
                        $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').'" >'.
2178
                            Display::return_icon('visible.png', get_lang('Invisible'),array(), ICON_SIZE_SMALL).'</a>';
2179
                    } else {
2180
                        $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').'" >'.
2181
                            Display::return_icon('invisible.png', get_lang('Visible'),array(), ICON_SIZE_SMALL).'</a> ';
2182
                    }
2183
2184
                    if ($locked) {
2185
                        $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2186
                    } else {
2187
                        $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').'" >'.
2188
                            Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2189
                    }
2190
                } elseif ($is_author && (empty($work['qualificator_id']) || $work['qualificator_id'] == 0)) {
2191
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2192
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a>';
2193
2194
                    if (api_get_course_setting('student_delete_own_publication') == 1) {
2195 View Code Duplication
                        if (api_is_allowed_to_session_edit(false, true)) {
2196
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2197
                                Display::return_icon('edit.png', get_lang('Comment'), array(), ICON_SIZE_SMALL).'</a>';
2198
                        }
2199
                        $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').'"  >'.
2200
                            Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2201
                    } else {
2202
                        $action .= Display::return_icon('edit_na.png', get_lang('Modify'), array(), ICON_SIZE_SMALL);
2203
                    }
2204
                } else {
2205
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2206
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a>';
2207
                    $action .= Display::return_icon('edit_na.png', get_lang('Modify'), array(), ICON_SIZE_SMALL);
2208
                }
2209
2210
                // Status.
2211 View Code Duplication
                if (empty($work['qualificator_id'])) {
2212
                    $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
2213
                } else {
2214
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2215
                }
2216
                $work['qualificator_id'] = $qualificator_id;
2217
                $work['actions'] = '<div class="work-action">'.$send_to.$link_to_download.$action.'</div>';
2218
                $work['correction'] = $correction;
2219
2220
                $works[] = $work;
2221
            }
2222
        }
2223
2224
        return $works;
2225
    }
2226
}
2227
2228
/**
2229
 * Send reminder to users who have not given the task
2230
 *
2231
 * @param int
2232
 * @return array
2233
 * @author cvargas [email protected] cfasanando, [email protected]
2234
 */
2235
function send_reminder_users_without_publication($task_data)
2236
{
2237
    $_course = api_get_course_info();
2238
    $task_id = $task_data['id'];
2239
    $task_title = !empty($task_data['title']) ? $task_data['title'] : basename($task_data['url']);
2240
    $subject = '[' . api_get_setting('siteName') . '] ';
2241
2242
    // The body can be as long as you wish, and any combination of text and variables
2243
    $content = get_lang('ReminderToSubmitPendingTask')."\n".get_lang('CourseName').' : '.$_course['name']."\n";
2244
    $content .= get_lang('WorkName').' : '.$task_title."\n";
2245
    $list_users = get_list_users_without_publication($task_id);
2246
    $mails_sent_to = array();
2247
    foreach ($list_users as $user) {
2248
        $name_user = api_get_person_name($user[1], $user[0], null, PERSON_NAME_EMAIL_ADDRESS);
2249
        $dear_line = get_lang('Dear')." ".api_get_person_name($user[1], $user[0]) .", \n\n";
2250
        $body      = $dear_line.$content;
2251
        MessageManager::send_message($user[3], $subject, $body);
2252
        $mails_sent_to[] = $name_user;
2253
    }
2254
    return $mails_sent_to;
2255
}
2256
2257
/**
2258
 * Sends an email to the students of a course when a homework is created
2259
 *
2260
 * @param int $courseId course_id
2261
 * @param int $sessionId session_id
2262
 * @param int $workId work_id
2263
 *
2264
 *
2265
 * @author Guillaume Viguier <[email protected]>
2266
 * @author Julio Montoya <[email protected]> Adding session support - 2011
2267
 */
2268
function send_email_on_homework_creation($courseId, $sessionId = 0, $workId)
2269
{
2270
    $courseInfo = api_get_course_info_by_id($courseId);
2271
    $courseCode = $courseInfo['code'];
2272
    // Get the students of the course
2273 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...
2274
        $students = CourseManager::get_student_list_from_course_code($courseCode);
2275
    } else {
2276
        $students = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionId);
2277
    }
2278
    $emailsubject = '[' . api_get_setting('siteName') . '] '.get_lang('HomeworkCreated');
2279
    $currentUser = api_get_user_info(api_get_user_id());
2280
    if (!empty($students)) {
2281
        foreach($students as $student) {
2282
            $user_info = api_get_user_info($student["user_id"]);
2283
            if(!empty($user_info["mail"])) {
2284
                $name_user = api_get_person_name(
2285
                    $user_info["firstname"],
2286
                    $user_info["lastname"],
2287
                    null,
2288
                    PERSON_NAME_EMAIL_ADDRESS
2289
                );
2290
                $link = api_get_path(WEB_CODE_PATH) . 'work/work_list_all.php?' . api_get_cidreq() . '&id=' . $workId;
2291
                $emailbody = get_lang('Dear')." ".$name_user.",\n\n";
2292
                $emailbody .= get_lang('HomeworkHasBeenCreatedForTheCourse')." ".$courseCode.". "."\n\n".
2293
                    '<a href="'. $link . '">' . get_lang('PleaseCheckHomeworkPage') . '</a>';
2294
                $emailbody .= "\n\n".api_get_person_name($currentUser["firstname"], $currentUser["lastname"]);
2295
2296
                $additionalParameters = array(
2297
                    'smsType' => SmsPlugin::ASSIGNMENT_BEEN_CREATED_COURSE,
2298
                    'userId' => $student["user_id"],
2299
                    'courseTitle' => $courseCode,
2300
                    'link' => $link
2301
                );
2302
2303
                api_mail_html(
2304
                    $name_user,
2305
                    $user_info["mail"],
2306
                    $emailsubject,
2307
                    $emailbody,
2308
                    api_get_person_name(
2309
                        $currentUser["firstname"],
2310
                        $currentUser["lastname"],
2311
                        null,
2312
                        PERSON_NAME_EMAIL_ADDRESS
2313
                    ),
2314
                    $currentUser["mail"],
2315
                    null,
2316
                    null,
2317
                    null,
2318
                    $additionalParameters
2319
                );
2320
            }
2321
        }
2322
    }
2323
}
2324
2325
/**
2326
 * @param string $url
2327
 * @return bool
2328
 */
2329
function is_work_exist_by_url($url)
2330
{
2331
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2332
    $url = Database::escape_string($url);
2333
    $sql = "SELECT id FROM $work_table WHERE url='$url'";
2334
    $result = Database::query($sql);
2335
    if (Database::num_rows($result)> 0) {
2336
        $row = Database::fetch_row($result);
2337
        if (empty($row)) {
2338
            return false;
2339
        } else {
2340
            return true;
2341
        }
2342
    } else {
2343
        return false;
2344
    }
2345
}
2346
2347
/**
2348
 * Check if a user is the author of a work document.
2349
 * @param int $itemId
2350
 * @param int $userId
2351
 * @param int $courseId
2352
 * @param int $sessionId
2353
 * @return bool
2354
 */
2355
function user_is_author($itemId, $userId = null, $courseId = null, $sessionId = null)
2356
{
2357
    if (empty($itemId)) {
2358
        return false;
2359
    }
2360
2361
    if (empty($userId)) {
2362
        $userId = api_get_user_id();
2363
    }
2364
2365
    $isAuthor = false;
2366
    $is_allowed_to_edit = api_is_allowed_to_edit();
2367
2368
    if ($is_allowed_to_edit) {
2369
        $isAuthor = true;
2370
    } else {
2371
2372
        if (empty($courseId)) {
2373
            $courseId = api_get_course_int_id();
2374
        }
2375
        if (empty($sessionId)) {
2376
            $sessionId = api_get_session_id();
2377
        }
2378
2379
        $data = api_get_item_property_info($courseId, 'work', $itemId, $sessionId);
2380
        if ($data['insert_user_id'] == $userId) {
2381
            $isAuthor = true;
2382
        }
2383
2384
        $workData = get_work_data_by_id($itemId);
2385
        if ($workData['user_id'] == $userId) {
2386
            $isAuthor = true;
2387
        }
2388
    }
2389
2390
    if (!$isAuthor) {
2391
        return false;
2392
    }
2393
2394
    return $isAuthor;
2395
}
2396
2397
/**
2398
 * Get list of users who have not given the task
2399
 * @param int
2400
 * @param int
2401
 * @return array
2402
 * @author cvargas
2403
 * @author Julio Montoya <[email protected]> Fixing query
2404
 */
2405
function get_list_users_without_publication($task_id, $studentId = null)
2406
{
2407
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2408
    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2409
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
2410
    $session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2411
2412
    $users = getAllUserToWork($task_id, api_get_course_int_id());
2413
    $users = array_column($users, 'user_id');
2414
2415
    // Condition for the session
2416
    $session_id = api_get_session_id();
2417
    $course_id = api_get_course_int_id();
2418
    $task_id = intval($task_id);
2419
    $sessionCondition = api_get_session_condition($session_id);
2420
2421
    if ($session_id == 0) {
2422
        $sql = "SELECT user_id as id FROM $work_table
2423
                WHERE
2424
                    c_id = $course_id AND
2425
                    parent_id = '$task_id' AND
2426
                    active IN (0, 1)";
2427
    } else {
2428
        $sql = "SELECT user_id as id FROM $work_table
2429
                WHERE
2430
                    c_id = $course_id AND
2431
                    parent_id = '$task_id' $sessionCondition AND
2432
                    active IN (0, 1)";
2433
    }
2434
2435
    $result = Database::query($sql);
2436
    $users_with_tasks = array();
2437
    while ($row = Database::fetch_array($result)) {
2438
        $users_with_tasks[] = $row['id'];
2439
    }
2440
2441
    if ($session_id == 0) {
2442
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2443
                      FROM $table_course_user AS cu, $table_user AS u
2444
                      WHERE u.status != 1 and cu.c_id='".$course_id."' AND u.user_id = cu.user_id";
2445
    } else {
2446
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2447
                      FROM $session_course_rel_user AS cu, $table_user AS u
2448
                      WHERE
2449
                        u.status != 1 AND
2450
                        cu.c_id='".$course_id."' AND
2451
                        u.user_id = cu.user_id AND
2452
                        cu.session_id = '".$session_id."'";
2453
    }
2454
2455
    if (!empty($studentId)) {
2456
        $sql_users.= " AND u.user_id = ".intval($studentId);
2457
    }
2458
2459
    $group_id = api_get_group_id();
2460
    $new_group_user_list = array();
2461
2462 View Code Duplication
    if ($group_id) {
2463
        $groupInfo = GroupManager::get_group_properties($group_id);
2464
        $group_user_list = GroupManager::get_subscribed_users($groupInfo['iid']);
2465
        if (!empty($group_user_list)) {
2466
            foreach($group_user_list as $group_user) {
2467
                $new_group_user_list[] = $group_user['user_id'];
2468
            }
2469
        }
2470
    }
2471
2472
    $result_users = Database::query($sql_users);
2473
    $users_without_tasks = array();
2474
    while ($rowUsers = Database::fetch_array($result_users)) {
2475
        $userId = $rowUsers['user_id'];
2476
        if (in_array($userId, $users_with_tasks)) {
2477
            continue;
2478
        }
2479
2480
        if ($group_id && !in_array($userId, $new_group_user_list)) {
2481
            continue;
2482
        }
2483
2484
        if (!empty($users)) {
2485
            if (!in_array($userId, $users)) {
2486
                continue;
2487
            }
2488
        }
2489
2490
        $row_users = [];
2491
        $row_users[0] = $rowUsers['lastname'];
2492
        $row_users[1] = $rowUsers['firstname'];
2493
        $row_users[2] = Display::encrypted_mailto_link($rowUsers['email']);
2494
        $row_users[3] = $userId;
2495
        $users_without_tasks[] = $row_users;
2496
    }
2497
2498
    return $users_without_tasks;
2499
}
2500
2501
/**
2502
 * Display list of users who have not given the task
2503
 *
2504
 * @param int task id
2505
 * @param int $studentId
2506
 * @return array
2507
 * @author cvargas [email protected] cfasanando, [email protected]
2508
 * @author Julio Montoya <[email protected]> Fixes
2509
 */
2510
function display_list_users_without_publication($task_id, $studentId = null)
2511
{
2512
    global $origin;
2513
    $table_header[] = array(get_lang('LastName'), true);
2514
    $table_header[] = array(get_lang('FirstName'), true);
2515
    $table_header[] = array(get_lang('Email'), true);
2516
2517
    $data = get_list_users_without_publication($task_id);
2518
2519
    $sorting_options = array();
2520
    $sorting_options['column'] = 1;
2521
    $paging_options = array();
2522
    $my_params = array();
2523
2524
    if (isset($_GET['edit_dir'])) {
2525
        $my_params['edit_dir'] = Security::remove_XSS($_GET['edit_dir']);
2526
    }
2527
    if (isset($_GET['list'])) {
2528
        $my_params['list'] = Security::remove_XSS($_GET['list']);
2529
    }
2530
    $my_params['origin'] = $origin;
2531
    $my_params['id'] = intval($_GET['id']);
2532
2533
    //$column_show
2534
    $column_show[] = 1;
2535
    $column_show[] = 1;
2536
    $column_show[] = 1;
2537
    Display::display_sortable_config_table(
2538
        'work',
2539
        $table_header,
2540
        $data,
2541
        $sorting_options,
2542
        $paging_options,
2543
        $my_params,
2544
        $column_show
2545
    );
2546
}
2547
2548
/**
2549
 * @param int $documentId
2550
 * @param int $workId
2551
 * @param int $courseId
2552
 */
2553 View Code Duplication
function addDocumentToWork($documentId, $workId, $courseId)
2554
{
2555
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2556
    $params = array(
2557
        'document_id' => $documentId,
2558
        'work_id' => $workId,
2559
        'c_id' => $courseId
2560
    );
2561
    Database::insert($table, $params);
2562
}
2563
2564
/**
2565
 * @param int $documentId
2566
 * @param int $workId
2567
 * @param int $courseId
2568
 * @return array
2569
 */
2570 View Code Duplication
function getDocumentToWork($documentId, $workId, $courseId)
2571
{
2572
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2573
    $params = array(
2574
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2575
    );
2576
    return Database::select('*', $table, array('where' => $params));
2577
}
2578
2579
/**
2580
 * @param int $documentId
2581
 * @param int $workId
2582
 * @param int $courseId
2583
 * @param int $sessionId
2584
 * @param int $userId
2585
 * @param int $active
2586
 * @return array
2587
 */
2588
function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId, $active = 1)
2589
{
2590
    $workRel = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2591
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2592
2593
    $documentId = intval($documentId);
2594
    $workId = intval($workId);
2595
    $courseId = intval($courseId);
2596
    $userId = intval($userId);
2597
    $sessionId = intval($sessionId);
2598
    $active = intval($active);
2599
    $sessionCondition = api_get_session_condition($sessionId);
2600
2601
    $sql = "SELECT w.* FROM $work w INNER JOIN $workRel rel ON (w.parent_id = rel.work_id)
2602
            WHERE
2603
                w.document_id = $documentId AND
2604
                w.parent_id = $workId AND
2605
                w.c_id = $courseId
2606
                $sessionCondition AND
2607
                user_id = $userId AND
2608
                active = $active
2609
            ";
2610
2611
    $result = Database::query($sql);
2612
    $workInfo = array();
2613
    if (Database::num_rows($result)) {
2614
        $workInfo = Database::fetch_array($result, 'ASSOC');
2615
    }
2616
    return $workInfo;
2617
}
2618
2619
/**
2620
 *
2621
 * @param int $workId
2622
 * @param int $courseId
2623
 * @return array
2624
 */
2625 View Code Duplication
function getAllDocumentToWork($workId, $courseId)
2626
{
2627
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2628
    $params = array(
2629
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2630
    );
2631
    return Database::select('*', $table, array('where' => $params));
2632
}
2633
2634
/**
2635
 * @param int $documentId
2636
 * @param int $workId
2637
 * @param int $courseId
2638
 */
2639 View Code Duplication
function deleteDocumentToWork($documentId, $workId, $courseId)
2640
{
2641
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2642
    $params = array(
2643
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2644
    );
2645
    Database::delete($table, $params);
2646
}
2647
2648
/**
2649
 * @param int $userId
2650
 * @param int $workId
2651
 * @param int $courseId
2652
 */
2653 View Code Duplication
function addUserToWork($userId, $workId, $courseId)
2654
{
2655
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2656
    $params = array(
2657
        'user_id' => $userId,
2658
        'work_id' => $workId,
2659
        'c_id' => $courseId
2660
    );
2661
    Database::insert($table, $params);
2662
}
2663
2664
/**
2665
 * @param int $userId
2666
 * @param int $workId
2667
 * @param int $courseId
2668
 * @return array
2669
 */
2670 View Code Duplication
function getUserToWork($userId, $workId, $courseId)
2671
{
2672
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2673
    $params = array(
2674
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2675
    );
2676
    return Database::select('*', $table, array('where' => $params));
2677
}
2678
2679
/**
2680
 * @param int $workId
2681
 * @param int $courseId
2682
 * @param bool $getCount
2683
 * @return array|int
2684
 */
2685
function getAllUserToWork($workId, $courseId, $getCount = false)
2686
{
2687
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2688
    $params = array(
2689
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2690
    );
2691
    if ($getCount) {
2692
        $count = 0;
2693
        $result = Database::select(
2694
            'count(user_id) as count',
2695
            $table,
2696
            array('where' => $params),
2697
            'simple'
2698
        );
2699
        if (!empty($result)) {
2700
            $count = intval($result['count']);
2701
        }
2702
        return $count;
2703
    } else {
2704
        return Database::select('*', $table, array('where' => $params));
2705
    }
2706
}
2707
2708
/**
2709
 * @param int $userId
2710
 * @param int $workId
2711
 * @param int $courseId
2712
 */
2713 View Code Duplication
function deleteUserToWork($userId, $workId, $courseId)
2714
{
2715
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2716
    $params = array(
2717
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2718
    );
2719
    Database::delete($table, $params);
2720
}
2721
2722
/**
2723
 * @param int $userId
2724
 * @param int $workId
2725
 * @param int $courseId
2726
 * @return bool
2727
 */
2728
function userIsSubscribedToWork($userId, $workId, $courseId)
2729
{
2730
    $subscribedUsers = getAllUserToWork($workId, $courseId);
2731
2732
    if (empty($subscribedUsers)) {
2733
        return true;
2734
    } else {
2735
        $subscribedUsersList = array();
2736
        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...
2737
            $subscribedUsersList[] = $item['user_id'];
2738
        }
2739
        if (in_array($userId, $subscribedUsersList)) {
2740
            return true;
2741
        }
2742
    }
2743
    return false;
2744
}
2745
2746
/**
2747
 * Get the list of students that have to submit their work
2748
 * @param integer $workId The internal ID of the assignment
2749
 * @param integer $courseId The course ID
2750
 * @param integer $groupId The group ID, if any
2751
 * @param integer $sessionId The session ID, if any
2752
 * @param bool $getCount Whether we want just the amount or the full result
2753
 * @return array|int An integer (if we just asked for the count) or an array of users
2754
 */
2755
function getStudentSubscribedToWork(
2756
    $workId,
2757
    $courseId,
2758
    $groupId = null,
2759
    $sessionId = null,
2760
    $getCount = false
2761
) {
2762
    $usersInWork = null;
2763
    $usersInCourse = null;
2764
2765
    if (empty($groupId)) {
2766
        $courseInfo = api_get_course_info_by_id($courseId);
2767
        $status = STUDENT;
2768
        if (!empty($sessionId)) {
2769
            $status = 0;
2770
        }
2771
        $usersInCourse = CourseManager::get_user_list_from_course_code(
2772
            $courseInfo['code'],
2773
            $sessionId,
2774
            null,
2775
            null,
2776
            $status,
2777
            $getCount
2778
        );
2779
    } else {
2780
        $usersInCourse = GroupManager::get_users(
2781
            $groupId,
2782
            false,
2783
            null,
2784
            null,
2785
            $getCount,
2786
            $courseId
2787
        );
2788
    }
2789
2790
    $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
2791
2792
    if (empty($usersInWork)) {
2793
        return $usersInCourse;
2794
    } else {
2795
        return $usersInWork;
2796
    }
2797
2798
}
2799
2800
/**
2801
 * @param int $userId
2802
 * @param int $workId
2803
 * @param int $courseId
2804
 * @return bool
2805
 */
2806
function allowOnlySubscribedUser($userId, $workId, $courseId)
2807
{
2808
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2809
        return true;
2810
    }
2811
2812
    if (userIsSubscribedToWork($userId, $workId, $courseId) == false) {
2813
        api_not_allowed(true);
2814
    }
2815
}
2816
2817
/**
2818
 * @param int $workId
2819
 * @param array $courseInfo
2820
 * @param int $documentId
2821
 * @return array
2822
 */
2823
function getDocumentTemplateFromWork($workId, $courseInfo, $documentId)
2824
{
2825
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2826
    if (!empty($documents)) {
2827
        foreach ($documents as $doc) {
2828
            if ($documentId != $doc['document_id']) {
2829
                continue;
2830
            }
2831
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2832
            $fileInfo = pathinfo($docData['path']);
2833
            if ($fileInfo['extension'] == 'html') {
2834
                if (file_exists($docData['absolute_path']) && is_file($docData['absolute_path'])) {
2835
                    $docData['file_content'] = file_get_contents($docData['absolute_path']);
2836
                    return $docData;
2837
                }
2838
            }
2839
        }
2840
    }
2841
    return array();
2842
}
2843
2844
/**
2845
 * @param int $workId
2846
 * @param array $courseInfo
2847
 * @return string
2848
 */
2849
function getAllDocumentsFromWorkToString($workId, $courseInfo)
2850
{
2851
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2852
    $content = null;
2853
    if (!empty($documents)) {
2854
        $content .= '<ul class="nav nav-list well">';
2855
        $content .= '<li class="nav-header">'.get_lang('Documents').'</li>';
2856
        foreach ($documents as $doc) {
2857
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2858
            if ($docData) {
2859
                $content .= '<li><a target="_blank" href="'.$docData['url'].'">'.$docData['title'].'</a></li>';
2860
            }
2861
        }
2862
        $content .= '</ul><br />';
2863
    }
2864
    return $content;
2865
}
2866
2867
/**
2868
 * Returns fck editor toolbar
2869
 * @return array
2870
 */
2871
function getWorkDescriptionToolbar()
2872
{
2873
    return array(
2874
        'ToolbarStartExpanded' => 'true',
2875
        'ToolbarSet' => 'Work',
2876
        'Width' => '100%',
2877
        'Height' => '400'
2878
    );
2879
}
2880
2881
/**
2882
 * @param array $work
2883
 * @return array
2884
 */
2885
function getWorkComments($work)
2886
{
2887
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2888
    $userTable= Database::get_main_table(TABLE_MAIN_USER);
2889
2890
    $courseId = intval($work['c_id']);
2891
    $workId = intval($work['id']);
2892
2893
    if (empty($courseId) || empty($workId)) {
2894
        return array();
2895
    }
2896
2897
    $sql = "SELECT
2898
                c.id, 
2899
                c.user_id
2900
            FROM $commentTable c
2901
            INNER JOIN $userTable u 
2902
            ON (u.id = c.user_id)
2903
            WHERE c_id = $courseId AND work_id = $workId
2904
            ORDER BY sent_at
2905
            ";
2906
    $result = Database::query($sql);
2907
    $comments = Database::store_result($result, 'ASSOC');
2908
    if (!empty($comments)) {
2909
        foreach ($comments as &$comment) {
2910
            $userInfo = api_get_user_info($comment['user_id']);
2911
            $comment['picture'] = $userInfo['avatar'];
2912
            $comment['complete_name'] = $userInfo['complete_name_with_username'];
2913
            $commentInfo = getWorkComment($comment['id']);
2914
            if (!empty($commentInfo)) {
2915
                $comment = array_merge($comment, $commentInfo);
2916
            }
2917
        }
2918
    }
2919
    return $comments;
2920
}
2921
2922
/**
2923
 * Get total score from a work list
2924
 * @param $workList
2925
 * @return int|null
2926
 */
2927
function getTotalWorkScore($workList)
2928
{
2929
    $count = 0;
2930
    foreach ($workList as $data) {
2931
        $count += $data['qualification_score'];
2932
    }
2933
    return $count;
2934
}
2935
2936
2937
/**
2938
 * Get comment count from a work list (docs sent by students)
2939
 * @param array $workList
2940
 * @param array $courseInfo
2941
 * @return int|null
2942
 */
2943
function getTotalWorkComment($workList, $courseInfo = array())
2944
{
2945
    if (empty($courseInfo)) {
2946
        $courseInfo = api_get_course_info();
2947
    }
2948
2949
    $count = 0;
2950
    foreach ($workList as $data) {
2951
        $count += getWorkCommentCount($data['id'], $courseInfo);
2952
    }
2953
    return $count;
2954
}
2955
2956
/**
2957
 * Get comment count for a specific work sent by a student.
2958
 * @param int $id
2959
 * @param array $courseInfo
2960
 * @return int
2961
 */
2962
function getWorkCommentCount($id, $courseInfo = array())
2963
{
2964
    if (empty($courseInfo)) {
2965
        $courseInfo = api_get_course_info();
2966
    }
2967
2968
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
2969
    $id = intval($id);
2970
2971
    $sql = "SELECT count(*) as count
2972
            FROM $commentTable
2973
            WHERE work_id = $id AND c_id = ".$courseInfo['real_id'];
2974
2975
    $result = Database::query($sql);
2976
    if (Database::num_rows($result)) {
2977
        $comment = Database::fetch_array($result);
2978
        return $comment['count'];
2979
    }
2980
2981
    return 0;
2982
}
2983
2984
/**
2985
 * Get comment count for a specific parent
2986
 * @param int $parentId
2987
 * @param array $courseInfo
2988
 * @param int $sessionId
2989
 * @return int
2990
 */
2991 View Code Duplication
function getWorkCommentCountFromParent(
2992
    $parentId,
2993
    $courseInfo = array(),
2994
    $sessionId = 0
2995
) {
2996
    if (empty($courseInfo)) {
2997
        $courseInfo = api_get_course_info();
2998
    }
2999
3000
    if (empty($sessionId)) {
3001
        $sessionId = api_get_session_id();
3002
    } else {
3003
        $sessionId = intval($sessionId);
3004
    }
3005
3006
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3007
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3008
    $parentId = intval($parentId);
3009
    $sessionCondition = api_get_session_condition($sessionId, false, false, 'w.session_id');
3010
3011
    $sql = "SELECT count(*) as count
3012
            FROM $commentTable c INNER JOIN $work w
3013
            ON c.c_id = w.c_id AND w.id = c.work_id
3014
            WHERE
3015
                $sessionCondition AND
3016
                parent_id = $parentId AND
3017
                w.c_id = ".$courseInfo['real_id'];
3018
3019
    $result = Database::query($sql);
3020
    if (Database::num_rows($result)) {
3021
        $comment = Database::fetch_array($result);
3022
        return $comment['count'];
3023
    }
3024
3025
    return 0;
3026
}
3027
3028
/**
3029
 * Get last work information from parent
3030
 * @param int $parentId
3031
 * @param array $courseInfo
3032
 * @param int $sessionId
3033
 * @return int
3034
 */
3035 View Code Duplication
function getLastWorkStudentFromParent(
3036
    $parentId,
3037
    $courseInfo = array(),
3038
    $sessionId = 0
3039
) {
3040
    if (empty($courseInfo)) {
3041
        $courseInfo = api_get_course_info();
3042
    }
3043
3044
    if (empty($sessionId)) {
3045
        $sessionId = api_get_session_id();
3046
    } else {
3047
        $sessionId = intval($sessionId);
3048
    }
3049
3050
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3051
    $sessionCondition = api_get_session_condition($sessionId, false);
3052
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3053
    $parentId = intval($parentId);
3054
3055
    $sql = "SELECT w.*
3056
            FROM $commentTable c INNER JOIN $work w
3057
            ON c.c_id = w.c_id AND w.id = c.work_id
3058
            WHERE
3059
                $sessionCondition AND
3060
                parent_id = $parentId AND
3061
                w.c_id = ".$courseInfo['real_id']."
3062
            ORDER BY w.sent_date
3063
            LIMIT 1
3064
            ";
3065
3066
    $result = Database::query($sql);
3067
    if (Database::num_rows($result)) {
3068
        $comment = Database::fetch_array($result, 'ASSOC');
3069
3070
        return $comment;
3071
    }
3072
3073
    return array();
3074
}
3075
3076
/**
3077
 * Get last work information from parent
3078
 * @param int $parentId
3079
 * @param array $courseInfo
3080
 * @param int $sessionId
3081
 * @return int
3082
 */
3083
function getLastWorkStudentFromParentByUser(
3084
    $userId,
3085
    $parentId,
3086
    $courseInfo = array(),
3087
    $sessionId = 0
3088
) {
3089
    if (empty($courseInfo)) {
3090
        $courseInfo = api_get_course_info();
3091
    }
3092
3093
    if (empty($sessionId)) {
3094
        $sessionId = api_get_session_id();
3095
    } else {
3096
        $sessionId = intval($sessionId);
3097
    }
3098
3099
    $userId = intval($userId);
3100
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3101
    $parentId = intval($parentId);
3102
    $sessionCondition = api_get_session_condition($sessionId);
3103
3104
    $sql = "SELECT *
3105
            FROM $work
3106
            WHERE
3107
                user_id = $userId
3108
                $sessionCondition AND
3109
                parent_id = $parentId AND
3110
                c_id = ".$courseInfo['real_id']."
3111
            ORDER BY sent_date DESC
3112
            LIMIT 1
3113
            ";
3114
    $result = Database::query($sql);
3115
    if (Database::num_rows($result)) {
3116
        $work = Database::fetch_array($result, 'ASSOC');
3117
3118
        return $work;
3119
    }
3120
3121
    return array();
3122
}
3123
3124
/**
3125
 * @param int $id comment id
3126
 * @param array $courseInfo
3127
 * @return string
3128
 */
3129
function getWorkComment($id, $courseInfo = array())
3130
{
3131
    if (empty($courseInfo)) {
3132
        $courseInfo = api_get_course_info();
3133
    }
3134
3135
    if (empty($courseInfo['real_id'])) {
3136
        return array();
3137
    }
3138
3139
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3140
    $id = intval($id);
3141
3142
    $sql = "SELECT * FROM $commentTable
3143
            WHERE id = $id AND c_id = ".$courseInfo['real_id'];
3144
    $result = Database::query($sql);
3145
    $comment = array();
3146
    if (Database::num_rows($result)) {
3147
        $comment = Database::fetch_array($result, 'ASSOC');
3148
        $filePath = null;
3149
        $fileUrl = null;
3150
        $deleteUrl = null;
3151
        $fileName = null;
3152
        if (!empty($comment['file'])) {
3153
            $work = get_work_data_by_id($comment['work_id']);
3154
            $workParent = get_work_data_by_id($work['parent_id']);
3155
            $filePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/'.$workParent['url'].'/'.$comment['file'];
3156
            $fileUrl = api_get_path(WEB_CODE_PATH).'work/download_comment_file.php?comment_id='.$id.'&'.api_get_cidreq();
3157
            $deleteUrl = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$comment['work_id'].'&action=delete_attachment&comment_id='.$id;
3158
            $fileParts = explode('_', $comment['file']);
3159
            $fileName = str_replace($fileParts[0].'_'.$fileParts[1].'_', '', $comment['file']);
3160
        }
3161
        $comment['delete_file_url'] = $deleteUrl;
3162
        $comment['file_path'] = $filePath;
3163
        $comment['file_url'] = $fileUrl;
3164
        $comment['file_name_to_show'] = $fileName;
3165
    }
3166
3167
    return $comment;
3168
}
3169
3170
/**
3171
 * @param int $id
3172
 * @param array $courseInfo
3173
 */
3174
function deleteCommentFile($id, $courseInfo = array())
3175
{
3176
    $workComment = getWorkComment($id, $courseInfo);
3177
    if (isset($workComment['file']) && !empty($workComment['file'])) {
3178
        if (file_exists($workComment['file_path'])) {
3179
            $result = my_delete($workComment['file_path']);
3180
            if ($result) {
3181
                $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3182
                $params = array('file' => '');
3183
                Database::update(
3184
                    $commentTable,
3185
                    $params,
3186
                    array('id = ? AND c_id = ? ' => array($workComment['id'], $workComment['c_id']))
3187
                );
3188
            }
3189
        }
3190
    }
3191
}
3192
3193
/**
3194
 * Adds a comments to the work document
3195
 * @param array $courseInfo
3196
 * @param int $userId
3197
 * @param array $work
3198
 * @param array $data
3199
 * @return int
3200
 */
3201
function addWorkComment($courseInfo, $userId, $parentWork, $work, $data)
3202
{
3203
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3204
3205
    $params = array(
3206
        'work_id' => $work['id'],
3207
        'c_id' => $work['c_id'],
3208
        'user_id' => $userId,
3209
        'comment' => $data['comment'],
3210
        'sent_at' => api_get_utc_datetime()
3211
    );
3212
3213
    $commentId = Database::insert($commentTable, $params);
3214
3215
    if ($commentId) {
3216
        $sql = "UPDATE $commentTable SET id = iid WHERE iid = $commentId";
3217
        Database::query($sql);
3218
    }
3219
3220
    $userIdListToSend = array();
3221
3222
    if (api_is_allowed_to_edit()) {
3223
        if (isset($data['send_mail']) && $data['send_mail']) {
3224
            // Teacher sends a feedback
3225
            $userIdListToSend = array($work['user_id']);
3226
        }
3227
    } else {
3228
        $sessionId = api_get_session_id();
3229
        if (empty($sessionId)) {
3230
            $teachers = CourseManager::get_teacher_list_from_course_code(
3231
                $courseInfo['code']
3232
            );
3233
            if (!empty($teachers)) {
3234
                $userIdListToSend = array_keys($teachers);
3235
            }
3236
        } else {
3237
            $teachers = SessionManager::getCoachesByCourseSession(
3238
                $sessionId,
3239
                $courseInfo['code']
3240
            );
3241
3242
            if (!empty($teachers)) {
3243
                $userIdListToSend = array_values($teachers);
3244
            }
3245
        }
3246
    }
3247
3248
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$work['id'];
3249
    $subject = sprintf(get_lang('ThereIsANewWorkFeedback'), $parentWork['title']);
3250
    $content = sprintf(get_lang('ThereIsANewWorkFeedbackInWorkXHere'), $work['title'], $url);
3251
3252
    if (!empty($userIdListToSend)) {
3253
        foreach ($userIdListToSend as $userIdToSend) {
3254
            MessageManager::send_message_simple(
3255
                $userIdToSend,
3256
                $subject,
3257
                $content
3258
            );
3259
        }
3260
    }
3261
3262
    $fileData = isset($data['file']) ? $data['file'] : null;
3263
    if (!empty($commentId) && !empty($fileData)) {
3264
        $workParent = get_work_data_by_id($work['parent_id']);
3265
        if (!empty($workParent)) {
3266
            $uploadDir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work'.$workParent['url'];
3267
            $newFileName = 'comment_'.$commentId.'_'.php2phps(api_replace_dangerous_char($fileData['name']));
3268
            $newFilePath = $uploadDir.'/'.$newFileName;
3269
            $result = move_uploaded_file($fileData['tmp_name'], $newFilePath);
3270
            if ($result) {
3271
                $params = array('file' => $newFileName);
3272
                Database::update(
3273
                    $commentTable,
3274
                    $params,
3275
                    array('id = ? AND c_id = ? ' => array($commentId, $work['c_id']))
3276
                );
3277
            }
3278
        }
3279
    }
3280
}
3281
3282
/**
3283
 * @param array $work
3284
 * @param string $page
3285
 * @return string
3286
 */
3287
function getWorkCommentForm($work, $page = 'view')
3288
{
3289
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&action=send_comment&'.api_get_cidreq().'&page='.$page;
3290
    $form = new FormValidator(
3291
        'work_comment',
3292
        'post',
3293
        $url
3294
    );
3295
3296
    $form->addElement('file', 'file', get_lang('Attachment'));
3297
    $form->addHtmlEditor('comment', get_lang('Comment'));
3298
    $form->addElement('hidden', 'id', $work['id']);
3299
    $form->addElement('hidden', 'page', $page);
3300
    if (api_is_allowed_to_edit()) {
3301
        $form->addElement('checkbox', 'send_mail', null, get_lang('SendMail'));
3302
    }
3303
    $form->addButtonSend(get_lang('Send'), 'button');
3304
3305
    return $form->returnForm();
3306
}
3307
3308
/**
3309
 * @param array $homework result of get_work_assignment_by_id()
3310
 * @return string
3311
 */
3312
function getWorkDateValidationStatus($homework)
3313
{
3314
    $message = null;
3315
    $has_expired = false;
3316
    $has_ended = false;
3317
3318
    if (!empty($homework)) {
3319 View Code Duplication
        if (!empty($homework['expires_on']) || !empty($homework['ends_on'])) {
3320
            $time_now = time();
3321
3322
            if (!empty($homework['expires_on'])) {
3323
                $time_expires = api_strtotime($homework['expires_on'], 'UTC');
3324
                $difference = $time_expires - $time_now;
3325
                if ($difference < 0) {
3326
                    $has_expired = true;
3327
                }
3328
            }
3329
3330
            if (empty($homework['expires_on'])) {
3331
                $has_expired = false;
3332
            }
3333
3334
            if (!empty($homework['ends_on'])) {
3335
                $time_ends = api_strtotime($homework['ends_on'], 'UTC');
3336
                $difference2 = $time_ends - $time_now;
3337
                if ($difference2 < 0) {
3338
                    $has_ended = true;
3339
                }
3340
            }
3341
3342
            $ends_on = api_convert_and_format_date($homework['ends_on']);
3343
            $expires_on = api_convert_and_format_date($homework['expires_on']);
3344
        }
3345
3346
        if ($has_ended) {
3347
            $message = Display::return_message(get_lang('EndDateAlreadyPassed').' '.$ends_on, 'error');
3348
        } elseif ($has_expired) {
3349
            $message = Display::return_message(get_lang('ExpiryDateAlreadyPassed').' '.$expires_on, 'warning');
3350
        } else {
3351
            if ($has_expired) {
3352
                $message = Display::return_message(get_lang('ExpiryDateToSendWorkIs').' '.$expires_on);
3353
            }
3354
        }
3355
    }
3356
3357
    return array(
3358
        'message' => $message,
3359
        'has_ended' => $has_ended,
3360
        'has_expired' => $has_expired
3361
    );
3362
}
3363
3364
/**
3365
 * @param FormValidator $form
3366
 * @param int $uploadFormType
3367
 */
3368
function setWorkUploadForm($form, $uploadFormType = 0)
3369
{
3370
    $form->addElement('header', get_lang('UploadADocument'));
3371
    $form->addElement('hidden', 'contains_file', 0, array('id'=>'contains_file_id'));
3372
    $form->addElement('hidden', 'active', 1);
3373
    $form->addElement('hidden', 'accepted', 1);
3374
    $form->addElement('text', 'title', get_lang('Title'), array('id' => 'file_upload'));
3375
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
3376
3377
    switch ($uploadFormType) {
3378 View Code Duplication
        case 0:
3379
            // File and text.
3380
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3381
            $form->addProgress();
3382
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3383
            break;
3384 View Code Duplication
        case 1:
3385
            // Only text.
3386
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3387
            $form->addRule('description', get_lang('ThisFieldIsRequired'), 'required');
3388
            break;
3389
        case 2:
3390
            // Only file.
3391
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3392
            $form->addProgress();
3393
            $form->addRule('file', get_lang('ThisFieldIsRequired'), 'required');
3394
            break;
3395
    }
3396
3397
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
3398
}
3399
3400
/**
3401
 * @param array $my_folder_data
3402
 * @param array $_course
3403
 * @param bool $isCorrection
3404
 * @param array $workInfo
3405
 * @param array $file
3406
 *
3407
 * @return array
3408
 */
3409
function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo = [], $file = [])
3410
{
3411
    if (isset($_FILES['file']) && !empty($_FILES['file'])) {
3412
        $file = $_FILES['file'];
3413
    }
3414
3415
    if (empty($file['size'])) {
3416
        return array(
3417
            'error' => Display:: return_message(
3418
                get_lang('UplUploadFailedSizeIsZero'),
3419
                'error'
3420
            ),
3421
        );
3422
    }
3423
    $updir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work/'; //directory path to upload
3424
3425
    // Try to add an extension to the file if it has'nt one
3426
    $filename = add_ext_on_mime(stripslashes($file['name']), $file['type']);
3427
3428
    // Replace dangerous characters
3429
    $filename = api_replace_dangerous_char($filename);
3430
3431
    // Transform any .php file in .phps fo security
3432
    $filename = php2phps($filename);
3433
    $filesize = filesize($file['tmp_name']);
3434
3435
    if (empty($filesize)) {
3436
        return array(
3437
            'error' => Display:: return_message(
3438
                get_lang('UplUploadFailedSizeIsZero'),
3439
                'error'
3440
            )
3441
        );
3442
    } elseif (!filter_extension($new_file_name)) {
3443
        return array(
3444
            'error' => Display:: return_message(
3445
                get_lang('UplUnableToSaveFileFilteredExtension'),
3446
                'error'
3447
            )
3448
        );
3449
    }
3450
3451
    $totalSpace = DocumentManager::documents_total_space($_course['real_id']);
3452
    $course_max_space = DocumentManager::get_course_quota($_course['code']);
3453
    $total_size = $filesize + $totalSpace;
3454
3455
    if ($total_size > $course_max_space) {
3456
        return array(
3457
            'error' => Display :: return_message(get_lang('NoSpace'), 'error')
3458
        );
3459
    }
3460
3461
    // Compose a unique file name to avoid any conflict
3462
    $new_file_name = api_get_unique_id();
3463
3464
    if ($isCorrection) {
3465
        if (!empty($workInfo['url'])) {
3466
            $new_file_name = basename($workInfo['url']).'_correction';
3467
        } else {
3468
            $new_file_name = $new_file_name.'_correction';
3469
        }
3470
    }
3471
3472
    $curdirpath = basename($my_folder_data['url']);
3473
    // If we come from the group tools the groupid will be saved in $work_table
3474
    if (is_dir($updir.$curdirpath) || empty($curdirpath)) {
3475
        $result = move_uploaded_file(
3476
            $file['tmp_name'],
3477
            $updir.$curdirpath.'/'.$new_file_name
3478
        );
3479
    } else {
3480
        return array(
3481
            'error' => Display :: return_message(
3482
                get_lang('FolderDoesntExistsInFileSystem'),
3483
                'error'
3484
            )
3485
        );
3486
    }
3487
3488
    $url = null;
3489
    if ($result) {
3490
        $url = 'work/'.$curdirpath.'/'.$new_file_name;
3491
    } else {
3492
        return false;
3493
    }
3494
3495
    return array(
3496
        'url' => $url,
3497
        'filename' => $filename,
3498
        'filesize' => $filesize,
3499
        'error' => null
3500
    );
3501
}
3502
3503
/**
3504
 * Send an e-mail to users related to this work (course teachers, usually, but
3505
 * might include other group members)
3506
 * @param int $workId
3507
 * @param array $courseInfo
3508
 * @param int $session_id
3509
 */
3510
function sendAlertToUsers($workId, $courseInfo, $session_id)
3511
{
3512
    $user_list = array();
3513
    //$workData = get_work_assignment_by_id($workId, $courseInfo['real_id']);
3514
    $workData = get_work_data_by_id($workId, $courseInfo['real_id'], $session_id);
3515
    //last value is to check this is not "just" an edit
3516
    //YW Tis part serve to send a e-mail to the tutors when a new file is sent
3517
    $send = api_get_course_setting('email_alert_manager_on_new_doc');
3518
3519
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_TEACHERS) {
3520
        // Lets predefine some variables. Be sure to change the from address!
3521
        if (empty($session_id)) {
3522
            //Teachers
3523
            $user_list = CourseManager::get_user_list_from_course_code(
3524
                api_get_course_id(),
3525
                null,
3526
                null,
3527
                null,
3528
                COURSEMANAGER
3529
            );
3530
        } else {
3531
            // Coaches
3532
            $user_list = CourseManager::get_user_list_from_course_code(
3533
                api_get_course_id(),
3534
                $session_id,
3535
                null,
3536
                null,
3537
                2
3538
            );
3539
        }
3540
    }
3541
3542
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_STUDENTS) {
3543
        if (!$session_id) {
3544
            $session_id = null;
3545
        }
3546
        $student = CourseManager::get_user_list_from_course_code(
3547
            api_get_course_id(),
3548
            $session_id,
3549
            null,
3550
            null,
3551
            STUDENT,
3552
            null,
3553
            null,
3554
            null,
3555
            null,
3556
            null,
3557
            array(api_get_user_id())
3558
        );
3559
        $user_list = array_merge($user_list, $student);
3560
    }
3561
3562
    if ($send) {
3563
        $senderEmail = api_get_setting('emailAdministrator');
3564
        $senderName = api_get_person_name(
3565
            api_get_setting('administratorName'),
3566
            api_get_setting('administratorSurname'),
3567
            null,
3568
            PERSON_NAME_EMAIL_ADDRESS
3569
        );
3570
        $subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n ".get_lang('CourseName').": ".$courseInfo['name']."  ";
3571
        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...
3572
            $to_user_id = $user_data['user_id'];
3573
            $user_info = api_get_user_info($to_user_id);
3574
            $message = get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']."\n";
3575
            $message .= get_lang('UserName')." : ".api_get_person_name($user_info['firstname'], $user_info['lastname'])."\n";
3576
            $message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."\n";
3577
            $url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
3578
            $message .= get_lang('WorkName')." : ".$workData['title']."\n\n".'<a href="'.$url.'">'.get_lang('DownloadLink')."</a>\n";
3579
            //$message .= $url;
3580
            MessageManager::send_message_simple($to_user_id, $subject, $message);
3581
            api_mail_html(
3582
                api_get_person_name(
3583
                    $user_info['firstname'].' '.$user_info['lastname'],
3584
                    null,
3585
                    PERSON_NAME_EMAIL_ADDRESS
3586
                ),
3587
                $user_info['email'],
3588
                $subject,
3589
                $message,
3590
                $senderName,
3591
                $senderEmail
3592
            );
3593
        }
3594
    }
3595
}
3596
3597
/**
3598
 * Check if the current uploaded work filename already exists in the current assement
3599
 *
3600
 * @param $filename
3601
 * @param $workId
3602
 * @return mixed
3603
 */
3604 View Code Duplication
function checkExistingWorkFileName($filename, $workId)
3605
{
3606
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3607
    $filename = Database::escape_string($filename);
3608
    $sql = "SELECT title FROM $work_table
3609
                        WHERE parent_id = $workId AND title = '$filename' AND active = 1";
3610
    $result = Database::query($sql);
3611
    return Database::fetch_assoc($result);
3612
}
3613
3614
/**
3615
 * @param array $workInfo
3616
 * @param array $values
3617
 * @param array $courseInfo
3618
 * @param int $sessionId
3619
 * @param int $groupId
3620
 * @param int $userId
3621
 * @param array $file
3622
 * @param bool  $checkDuplicated
3623
 * @param bool  $showFlashMessage
3624
 *
3625
 * @return null|string
3626
 */
3627
function processWorkForm(
3628
    $workInfo,
3629
    $values,
3630
    $courseInfo,
3631
    $sessionId,
3632
    $groupId,
3633
    $userId,
3634
    $file = [],
3635
    $checkDuplicated = false,
3636
    $showFlashMessage = true
3637
) {
3638
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3639
3640
    $courseId = $courseInfo['real_id'];
3641
    $groupId = intval($groupId);
3642
    $sessionId = intval($sessionId);
3643
    $userId = intval($userId);
3644
3645
    $title = $values['title'];
3646
    $description = $values['description'];
3647
    $contains_file = isset($values['contains_file']) && !empty($values['contains_file']) ? intval($values['contains_file']): 0;
3648
3649
    $saveWork = true;
3650
    $filename = null;
3651
    $url = null;
3652
    $filesize = null;
3653
    $workData = [];
3654
3655
    if ($values['contains_file']) {
3656
        if ($checkDuplicated) {
3657
            if (checkExistingWorkFileName($file['name'], $workInfo['id'])) {
3658
                $saveWork = false;
3659
                $workData['error'] = get_lang('YouAlreadySentThisFile');
3660
            } else {
3661
                $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3662
            }
3663
        } else {
3664
            $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3665
        }
3666
3667
        if (isset($result['error'])) {
3668
            if ($showFlashMessage) {
3669
                $message = $result['error'];
3670
                Display::addFlash($message);
3671
            }
3672
3673
            $saveWork = false;
3674
        }
3675
    }
3676
3677
    $workData = [];
3678
    if ($saveWork) {
3679
        $filename = isset($result['filename']) ? $result['filename'] : null;
3680
        if (empty($title)) {
3681
            $title = isset($result['title']) && !empty($result['title']) ? $result['title'] : get_lang('Untitled');
3682
        }
3683
        $filesize = isset($result['filesize']) ? $result['filesize'] : null;
3684
        $url = isset($result['url']) ? $result['url'] : null;
3685
    }
3686
3687
    if (empty($title)) {
3688
        $title = get_lang('Untitled');
3689
    }
3690
3691
    $groupIid = 0;
3692
    if ($groupId) {
3693
        $groupInfo = GroupManager::get_group_properties($groupId);
3694
        $groupIid = $groupInfo['iid'];
3695
    }
3696
3697
    if ($saveWork) {
3698
        $active = '1';
3699
        $params = [
3700
            'c_id' => $courseId,
3701
            'url' => $url,
3702
            'filetype' => 'file',
3703
            'title' => $title,
3704
            'description' => $description,
3705
            'contains_file' => $contains_file,
3706
            'active' => $active,
3707
            'accepted' => '1',
3708
            'qualificator_id' => 0,
3709
            'document_id' => 0,
3710
            'weight' => 0,
3711
            'allow_text_assignment' => 0,
3712
            'post_group_id' => $groupIid,
3713
            'sent_date' => api_get_utc_datetime(),
3714
            'parent_id' => $workInfo['id'],
3715
            'session_id' => $sessionId ? $sessionId : null,
3716
            'user_id' => $userId,
3717
            'has_properties' => 0,
3718
            'qualification' => 0
3719
            //'filesize' => $filesize
3720
        ];
3721
        $workId = Database::insert($work_table, $params);
3722
3723
        if ($workId) {
3724
            $sql = "UPDATE $work_table SET id = iid WHERE iid = $workId ";
3725
            Database::query($sql);
3726
3727 View Code Duplication
            if (array_key_exists('filename', $workInfo) && !empty($filename)) {
3728
                $filename = Database::escape_string($filename);
3729
                $sql = "UPDATE $work_table SET
3730
                            filename = '$filename'
3731
                        WHERE iid = $workId";
3732
                Database::query($sql);
3733
            }
3734
3735
            if (array_key_exists('document_id', $workInfo)) {
3736
                $documentId = isset($values['document_id']) ? intval($values['document_id']) : 0;
3737
                $sql = "UPDATE $work_table SET
3738
                            document_id = '$documentId'
3739
                        WHERE iid = $workId";
3740
                Database::query($sql);
3741
            }
3742
            api_item_property_update(
3743
                $courseInfo,
3744
                'work',
3745
                $workId,
3746
                'DocumentAdded',
3747
                $userId,
3748
                $groupIid
3749
            );
3750
            sendAlertToUsers($workId, $courseInfo, $sessionId);
3751
            Event::event_upload($workId);
3752
            $workData = get_work_data_by_id($workId);
3753
            if ($showFlashMessage) {
3754
                Display::addFlash(Display::return_message(get_lang('DocAdd')));
3755
            }
3756
        }
3757
    } else {
3758
        if ($showFlashMessage) {
3759
            Display::addFlash(
3760
                Display::return_message(
3761
                    get_lang('IsNotPosibleSaveTheDocument'),
3762
                    'error'
3763
                )
3764
            );
3765
        }
3766
    }
3767
3768
    return $workData;
3769
}
3770
3771
/**
3772
 * Creates a new task (directory) in the assignment tool
3773
 * @param array $formValues
3774
 * @param int $user_id
3775
 * @param array $courseInfo
3776
 * @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...
3777
 * @param int $session_id
3778
 * @return bool|int
3779
 * @note $params can have the following elements, but should at least have the 2 first ones: (
3780
 *       'new_dir' => 'some-name',
3781
 *       'description' => 'some-desc',
3782
 *       'qualification' => 20 (e.g. 20),
3783
 *       'weight' => 50 (percentage) to add to gradebook (e.g. 50),
3784
 *       'allow_text_assignment' => 0/1/2,
3785
 * @todo Rename createAssignment or createWork, or something like that
3786
 */
3787
function addDir($formValues, $user_id, $courseInfo, $groupId, $session_id)
3788
{
3789
    $em = Database::getManager();
3790
3791
    $user_id = intval($user_id);
3792
    $groupId = intval($groupId);
3793
3794
    $groupIid = 0;
3795
    if (!empty($groupId)) {
3796
        $groupInfo = GroupManager::get_group_properties($groupId);
3797
        $groupIid = $groupInfo['iid'];
3798
    }
3799
    $session = $em->find('ChamiloCoreBundle:Session', $session_id);
3800
3801
    $base_work_dir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work';
3802
    $course_id = $courseInfo['real_id'];
3803
3804
    $directory = api_replace_dangerous_char($formValues['new_dir']);
3805
    $directory = disable_dangerous_file($directory);
3806
    $created_dir = create_unexisting_work_directory($base_work_dir, $directory);
3807
3808
    if (empty($created_dir)) {
3809
        return false;
3810
    }
3811
3812
    $dirName = '/'.$created_dir;
3813
    $today = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
3814
3815
    $workTable = new CStudentPublication();
3816
    $workTable
3817
        ->setCId($course_id)
3818
        ->setUrl($dirName)
3819
        ->setTitle($formValues['new_dir'])
3820
        ->setDescription($formValues['description'])
3821
        ->setActive(true)
3822
        ->setAccepted(true)
3823
        ->setFiletype('folder')
3824
        ->setPostGroupId($groupIid)
3825
        ->setSentDate($today)
3826
        ->setQualification($formValues['qualification'] != '' ? $formValues['qualification'] : 0)
3827
        ->setParentId(0)
3828
        ->setQualificatorId(0)
3829
        ->setWeight(!empty($formValues['weight']) ? $formValues['weight'] : 0)
3830
        ->setSession($session)
0 ignored issues
show
Bug introduced by
It seems like $session defined by $em->find('ChamiloCoreBu...:Session', $session_id) on line 3799 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...
3831
        ->setAllowTextAssignment($formValues['allow_text_assignment'])
3832
        ->setContainsFile(0)
3833
        ->setUserId($user_id)
3834
        ->setHasProperties(0)
3835
        ->setDocumentId(0);
3836
3837
    $em->persist($workTable);
3838
    $em->flush();
3839
3840
    $workTable->setId($workTable->getIid());
3841
    $em->merge($workTable);
3842
    $em->flush();
3843
3844
    // Folder created
3845
    api_item_property_update(
3846
        $courseInfo,
3847
        'work',
3848
        $workTable->getIid(),
3849
        'DirectoryCreated',
3850
        $user_id,
3851
        $groupIid
3852
    );
3853
3854
    updatePublicationAssignment(
3855
        $workTable->getIid(),
3856
        $formValues,
3857
        $courseInfo,
3858
        $groupIid
3859
    );
3860
3861
    // Added the new Work ID to the extra field values
3862
    $formValues['item_id'] = $workTable->getIid();
3863
3864
    $workFieldValue = new ExtraFieldValue('work');
3865
    $workFieldValue->saveFieldValues($formValues);
3866
3867
    if (api_get_course_setting('email_alert_students_on_new_homework') == 1) {
3868
        send_email_on_homework_creation(
3869
            $course_id,
3870
            $session ? $session->getId() : 0,
3871
            $workTable->getIid()
3872
        );
3873
    }
3874
3875
    return $workTable->getIid();
3876
}
3877
3878
/**
3879
 * @param int $workId
3880
 * @param array $courseInfo
3881
 * @return int
3882
 */
3883 View Code Duplication
function agendaExistsForWork($workId, $courseInfo)
3884
{
3885
    $workTable = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3886
    $courseId = $courseInfo['real_id'];
3887
    $workId = intval($workId);
3888
3889
    $sql = "SELECT add_to_calendar FROM $workTable
3890
            WHERE c_id = $courseId AND publication_id = ".$workId;
3891
    $res = Database::query($sql);
3892
    if (Database::num_rows($res)) {
3893
        $row = Database::fetch_array($res, 'ASSOC');
3894
        if (!empty($row['add_to_calendar'])) {
3895
            return $row['add_to_calendar'];
3896
        }
3897
    }
3898
    return 0;
3899
}
3900
3901
/**
3902
 * Update work description, qualification, weight, allow_text_assignment
3903
 * @param int $workId (iid)
3904
 * @param array $params
3905
 * @param array $courseInfo
3906
 * @param int $sessionId
3907
 */
3908
function updateWork($workId, $params, $courseInfo, $sessionId = 0)
3909
{
3910
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3911
    $filteredParams = array(
3912
        'description' => $params['description'],
3913
        'qualification' => $params['qualification'],
3914
        'weight' => $params['weight'],
3915
        'allow_text_assignment' => $params['allow_text_assignment']
3916
    );
3917
3918
    Database::update(
3919
        $workTable,
3920
        $filteredParams,
3921
        array(
3922
            'iid = ? AND c_id = ?' => array(
3923
                $workId,
3924
                $courseInfo['real_id']
3925
            )
3926
        )
3927
    );
3928
3929
    $workFieldValue = new ExtraFieldValue('work');
3930
    $workFieldValue->saveFieldValues($params);
3931
}
3932
3933
/**
3934
 * @param int $workId
3935
 * @param array $params
3936
 * @param array $courseInfo
3937
 * @param int $groupId
3938
 */
3939
function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
3940
{
3941
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3942
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3943
    $workId = intval($workId);
3944
    $now = api_get_utc_datetime();
3945
    $course_id = $courseInfo['real_id'];
3946
3947
    // Insert into agenda
3948
    $agendaId = 0;
3949
    if (isset($params['add_to_calendar']) && $params['add_to_calendar'] == 1) {
3950
        // Setting today date
3951
        $date = $end_date = $now;
3952
3953
        if (isset($params['enableExpiryDate'])) {
3954
            $end_date = $params['expires_on'];
3955
            $date = $end_date;
3956
        }
3957
3958
        $title = sprintf(get_lang('HandingOverOfTaskX'), $params['new_dir']);
3959
        $description = isset($params['description']) ? $params['description'] : '';
3960
        $content = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq().'&id='.$workId.'">'
3961
            .$params['new_dir'].'</a>'.$description;
3962
3963
        $agendaId = agendaExistsForWork($workId, $courseInfo);
3964
3965
        // Add/edit agenda
3966
        $agenda = new Agenda('course');
3967
        $agenda->set_course($courseInfo);
3968
3969
        if (!empty($agendaId)) {
3970
            // add_to_calendar is set but it doesnt exists then invalidate
3971
            $eventInfo = $agenda->get_event($agendaId);
3972
            if (empty($eventInfo)) {
3973
                $agendaId = 0;
3974
            }
3975
        }
3976
3977
        if (empty($agendaId)) {
3978
            $agendaId = $agenda->addEvent(
3979
                $date,
3980
                $end_date,
3981
                'false',
3982
                $title,
3983
                $content,
3984
                array('GROUP:'.$groupId)
3985
            );
3986
        } else {
3987
            $agenda->editEvent(
3988
                $agendaId,
3989
                $end_date,
3990
                $end_date,
3991
                'false',
3992
                $title,
3993
                $content
3994
            );
3995
        }
3996
    }
3997
3998
    $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
3999
    $expiryDate = isset($params['enableExpiryDate']) && (int) $params['enableExpiryDate'] == 1 ? api_get_utc_datetime($params['expires_on']) : '';
4000
    $endDate = isset($params['enableEndDate']) && (int) $params['enableEndDate'] == 1 ? api_get_utc_datetime($params['ends_on']) : '';
4001
4002
    $data = get_work_assignment_by_id($workId, $course_id);
4003
4004
    if (!empty($expiryDate)) {
4005
        $expiryDateCondition = "expires_on = '".Database::escape_string($expiryDate)."', ";
4006
    } else {
4007
        $expiryDateCondition = "expires_on = null, ";
4008
    }
4009
4010
    if (!empty($endDate)) {
4011
        $endOnCondition = "ends_on = '".Database::escape_string($endDate)."', ";
4012
    } else {
4013
        $endOnCondition = "ends_on = null, ";
4014
    }
4015
4016
    if (empty($data)) {
4017
        $sql = "INSERT INTO $table SET
4018
                c_id = $course_id ,
4019
                $expiryDateCondition
4020
                $endOnCondition
4021
                add_to_calendar = $agendaId,
4022
                enable_qualification = '$qualification',
4023
                publication_id = '$workId'";
4024
        Database::query($sql);
4025
        $my_last_id = Database::insert_id();
4026
4027
        if ($my_last_id) {
4028
            $sql = "UPDATE $table SET
4029
                        id = iid
4030
                    WHERE iid = $my_last_id";
4031
            Database::query($sql);
4032
4033
            $sql = "UPDATE $workTable SET
4034
                        has_properties  = $my_last_id,
4035
                        view_properties = 1
4036
                    WHERE c_id = $course_id AND id = $workId";
4037
            Database::query($sql);
4038
        }
4039
    } else {
4040
        $sql = "UPDATE $table SET
4041
                    $expiryDateCondition
4042
                    $endOnCondition
4043
                    add_to_calendar  = $agendaId,
4044
                    enable_qualification = '".$qualification."'
4045
                WHERE
4046
                    publication_id = $workId AND
4047
                    c_id = $course_id AND
4048
                    iid = ".$data['iid'];
4049
        Database::query($sql);
4050
    }
4051
4052
    if (!empty($params['category_id'])) {
4053
        $link_info = GradebookUtils::isResourceInCourseGradebook(
4054
            $courseInfo['code'],
4055
            LINK_STUDENTPUBLICATION,
4056
            $workId,
4057
            api_get_session_id()
4058
        );
4059
4060
        $linkId = null;
4061
        if (!empty($link_info)) {
4062
            $linkId = $link_info['id'];
4063
        }
4064
4065
        if (isset($params['make_calification']) &&
4066
            $params['make_calification'] == 1
4067
        ) {
4068
            if (empty($linkId)) {
4069
                GradebookUtils::add_resource_to_course_gradebook(
4070
                    $params['category_id'],
4071
                    $courseInfo['code'],
4072
                    LINK_STUDENTPUBLICATION,
4073
                    $workId,
4074
                    $params['new_dir'],
4075
                    api_float_val($params['weight']),
4076
                    api_float_val($params['qualification']),
4077
                    $params['description'],
4078
                    1,
4079
                    api_get_session_id()
4080
                );
4081
            } else {
4082
                GradebookUtils::update_resource_from_course_gradebook(
4083
                    $linkId,
4084
                    $courseInfo['code'],
4085
                    $params['weight']
4086
                );
4087
            }
4088
        } else {
4089
            // Delete everything of the gradebook for this $linkId
4090
            GradebookUtils::remove_resource_from_course_gradebook($linkId);
4091
        }
4092
    }
4093
}
4094
4095
/**
4096
 * Delete all work by student
4097
 * @param int $userId
4098
 * @param array $courseInfo
4099
 * @return array return deleted items
4100
 */
4101
function deleteAllWorkPerUser($userId, $courseInfo)
4102
{
4103
    $deletedItems = array();
4104
    $workPerUser = getWorkPerUser($userId);
4105
    if (!empty($workPerUser)) {
4106
        foreach ($workPerUser as $work) {
4107
            $work = $work['work'];
4108
            foreach ($work->user_results as $userResult) {
4109
                $result = deleteWorkItem($userResult['id'], $courseInfo);
4110
                if ($result) {
4111
                    $deletedItems[] = $userResult;
4112
                }
4113
            }
4114
        }
4115
    }
4116
    return $deletedItems;
4117
}
4118
4119
/**
4120
 * @param int $item_id
4121
 * @param array course info
4122
 * @return bool
4123
 */
4124
function deleteWorkItem($item_id, $courseInfo)
4125
{
4126
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4127
    $TSTDPUBASG = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
4128
4129
    $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
4130
4131
    $is_allowed_to_edit = api_is_allowed_to_edit();
4132
    $file_deleted = false;
4133
    $item_id = intval($item_id);
4134
4135
    $is_author = user_is_author($item_id);
4136
    $work_data = get_work_data_by_id($item_id);
4137
    $locked = api_resource_is_locked_by_gradebook($work_data['parent_id'], LINK_STUDENTPUBLICATION);
4138
    $course_id = $courseInfo['real_id'];
4139
4140
    if (($is_allowed_to_edit && $locked == false) ||
4141
        (
4142
            $locked == false &&
4143
            $is_author &&
4144
            api_get_course_setting('student_delete_own_publication') == 1 &&
4145
            $work_data['qualificator_id'] == 0
4146
        )
4147
    ) {
4148
        // We found the current user is the author
4149
        $sql = "SELECT url, contains_file FROM $work_table
4150
                WHERE c_id = $course_id AND id = $item_id";
4151
        $result = Database::query($sql);
4152
        $row = Database::fetch_array($result);
4153
4154
        if (Database::num_rows($result) > 0) {
4155
            $sql = "UPDATE $work_table SET active = 2
4156
                    WHERE c_id = $course_id AND id = $item_id";
4157
            Database::query($sql);
4158
            $sql = "DELETE FROM $TSTDPUBASG
4159
                    WHERE c_id = $course_id AND publication_id = $item_id";
4160
            Database::query($sql);
4161
4162
            api_item_property_update(
4163
                $courseInfo,
4164
                'work',
4165
                $item_id,
4166
                'DocumentDeleted',
4167
                api_get_user_id()
4168
            );
4169
4170
            Event::addEvent(
4171
                LOG_WORK_FILE_DELETE,
4172
                LOG_WORK_DATA,
4173
                [
4174
                    'id' => $work_data['id'],
4175
                    'url' => $work_data['url'],
4176
                    'title' => $work_data['title']
4177
                ],
4178
                null,
4179
                api_get_user_id(),
4180
                api_get_course_int_id(),
4181
                api_get_session_id()
4182
            );
4183
4184
            $work = $row['url'];
4185
4186
            if ($row['contains_file'] == 1) {
4187
                if (!empty($work)) {
4188
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
4189
                        my_delete($currentCourseRepositorySys.'/'.$work);
4190
                        $file_deleted = true;
4191
                    } else {
4192
                        $extension = pathinfo($work, PATHINFO_EXTENSION);
4193
                        $new_dir = $work.'_DELETED_'.$item_id.'.'.$extension;
4194
4195
                        if (file_exists($currentCourseRepositorySys.'/'.$work)) {
4196
                            rename($currentCourseRepositorySys.'/'.$work, $currentCourseRepositorySys.'/'.$new_dir);
4197
                            $file_deleted = true;
4198
                        }
4199
                    }
4200
                }
4201
            } else {
4202
                $file_deleted = true;
4203
            }
4204
        }
4205
    }
4206
    return $file_deleted;
4207
}
4208
4209
/**
4210
 * @param FormValidator $form
4211
 * @param array $defaults
4212
 * @param integer $workId
4213
 * @return FormValidator
4214
 */
4215
function getFormWork($form, $defaults = array(), $workId = 0)
4216
{
4217
    $sessionId = api_get_session_id();
4218
    if (!empty($defaults)) {
4219
        if (isset($defaults['submit'])) {
4220
            unset($defaults['submit']);
4221
        }
4222
    }
4223
4224
    // Create the form that asks for the directory name
4225
    $form->addElement('text', 'new_dir', get_lang('AssignmentName'));
4226
    $form->addRule('new_dir', get_lang('ThisFieldIsRequired'), 'required');
4227
    $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
4228
    $form->addButtonAdvancedSettings('advanced_params', get_lang('AdvancedParameters'));
4229
4230
    if (!empty($defaults) && (isset($defaults['enableEndDate']) || isset($defaults['enableExpiryDate']))) {
4231
        $form->addHtml('<div id="advanced_params_options" style="display:block">');
4232
    } else {
4233
        $form->addHtml('<div id="advanced_params_options" style="display:none">');
4234
    }
4235
4236
    // QualificationOfAssignment
4237
    $form->addElement('text', 'qualification', get_lang('QualificationNumeric'));
4238
4239
    if (($sessionId != 0 && Gradebook::is_active()) || $sessionId == 0) {
4240
        $form->addElement(
4241
            'checkbox',
4242
            'make_calification',
4243
            null,
4244
            get_lang('MakeQualifiable'),
4245
            array(
4246
                'id' =>'make_calification_id',
4247
                'onclick' => "javascript: if(this.checked) { document.getElementById('option1').style.display='block';}else{document.getElementById('option1').style.display='none';}"
4248
            )
4249
        );
4250
    } else {
4251
        // QualificationOfAssignment
4252
        $form->addElement('hidden', 'make_calification', false);
4253
    }
4254
4255
    if (!empty($defaults) && isset($defaults['category_id'])) {
4256
        $form->addHtml('<div id=\'option1\' style="display:block">');
4257
    } else {
4258
        $form->addHtml('<div id=\'option1\' style="display:none">');
4259
    }
4260
4261
    // Loading Gradebook select
4262
    GradebookUtils::load_gradebook_select_in_tool($form);
4263
4264
    $form->addElement('text', 'weight', get_lang('WeightInTheGradebook'));
4265
    $form->addHtml('</div>');
4266
4267
    $form->addElement('checkbox', 'enableExpiryDate', null, get_lang('EnableExpiryDate'), 'id="expiry_date"');
4268
    if (isset($defaults['enableExpiryDate']) && $defaults['enableExpiryDate']) {
4269
        $form->addHtml('<div id="option2" style="display: block;">');
4270
    } else {
4271
        $form->addHtml('<div id="option2" style="display: none;">');
4272
    }
4273
4274
    $currentDate = substr(api_get_local_time(), 0, 10);
4275 View Code Duplication
    if (!isset($defaults['expires_on'])) {
4276
        $date = substr($currentDate, 0, 10);
4277
        $defaults['expires_on'] = $date.' 23:59';
4278
    }
4279
4280
    $form->addElement('date_time_picker', 'expires_on', get_lang('ExpiresAt'));
4281
    $form->addHtml('</div>');
4282
    $form->addElement('checkbox', 'enableEndDate', null, get_lang('EnableEndDate'), 'id="end_date"');
4283
4284 View Code Duplication
    if (!isset($defaults['ends_on'])) {
4285
        $date = substr($currentDate, 0, 10);
4286
        $defaults['ends_on'] = $date.' 23:59';
4287
    }
4288
    if (isset($defaults['enableEndDate']) && $defaults['enableEndDate']) {
4289
        $form->addHtml('<div id="option3" style="display: block;">');
4290
    } else {
4291
        $form->addHtml('<div id="option3" style="display: none;">');
4292
    }
4293
4294
    $form->addElement('date_time_picker', 'ends_on', get_lang('EndsAt'));
4295
    $form->addHtml('</div>');
4296
4297
    $form->addElement('checkbox', 'add_to_calendar', null, get_lang('AddToCalendar'));
4298
    $form->addElement('select', 'allow_text_assignment', get_lang('DocumentType'), getUploadDocumentType());
4299
4300
    //Extra fields
4301
    $extra_field = new ExtraField('work');
4302
    $extra = $extra_field->addElements($form, $workId);
4303
4304
    $htmlHeadXtra[] = '
4305
        <script>
4306
        $(function() {
4307
            ' . $extra['jquery_ready_content'] . '
4308
        });
4309
        </script>';
4310
4311
    $form->addHtml('</div>');
4312
4313
    if (isset($defaults['enableExpiryDate']) && isset($defaults['enableEndDate'])) {
4314
        $form->addRule(array('expires_on', 'ends_on'), get_lang('DateExpiredNotBeLessDeadLine'), 'comparedate');
4315
    }
4316
    if (!empty($defaults)) {
4317
        $form->setDefaults($defaults);
4318
    }
4319
4320
    return $form;
4321
}
4322
4323
/**
4324
 * @return array
4325
 */
4326
function getUploadDocumentType()
4327
{
4328
    return array(
4329
        0 => get_lang('AllowFileOrText'),
4330
        1 => get_lang('AllowOnlyText'),
4331
        2 => get_lang('AllowOnlyFiles')
4332
    );
4333
}
4334
4335
/**
4336
 * @param array $courseInfo
4337
 * @param bool $showScore
4338
 * @param bool $studentDeleteOwnPublication
4339
 */
4340
function updateSettings($courseInfo, $showScore, $studentDeleteOwnPublication)
4341
{
4342
    $showScore = intval($showScore);
4343
    $courseId = api_get_course_int_id();
4344
    $main_course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
4345
    $table_course_setting = Database :: get_course_table(TOOL_COURSE_SETTING);
4346
4347
    if (empty($courseId)) {
4348
        return false;
4349
    }
4350
4351
    $query = "UPDATE $main_course_table 
4352
              SET show_score = '$showScore'
4353
              WHERE id = $courseId";
4354
    Database::query($query);
4355
4356
    /**
4357
     * Course data are cached in session so we need to update both the database
4358
     * and the session data
4359
     */
4360
    $_course['show_score'] = $showScore;
4361
    Session::write('_course', $courseInfo);
4362
4363
    // changing the tool setting: is a student allowed to delete his/her own document
4364
4365
    // counting the number of occurrences of this setting (if 0 => add, if 1 => update)
4366
    $query = "SELECT * FROM $table_course_setting
4367
              WHERE 
4368
                c_id = $courseId AND 
4369
                variable = 'student_delete_own_publication'";
4370
4371
    $result = Database::query($query);
4372
    $number_of_setting = Database::num_rows($result);
4373
4374
    if ($number_of_setting == 1) {
4375
        $query = "UPDATE " . $table_course_setting . " SET
4376
                  value='" . Database::escape_string($studentDeleteOwnPublication) . "'
4377
                  WHERE variable = 'student_delete_own_publication' AND c_id = $courseId";
4378
        Database::query($query);
4379
    } else {
4380
        $params = [
4381
            'c_id' => $courseId,
4382
            'variable' => 'student_delete_own_publication',
4383
            'value' => $studentDeleteOwnPublication,
4384
            'category' => 'work'
4385
        ];
4386
        Database::insert($table_course_setting, $params);
4387
    }
4388
}
4389
4390
/**
4391
 * @param int $item_id
4392
 * @param array $course_info
4393
 */
4394
function makeVisible($item_id, $course_info)
4395
{
4396
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4397
    $course_id = $course_info['real_id'];
4398
    $item_id = intval($item_id);
4399
4400
    $sql = "UPDATE $work_table SET accepted = 1
4401
            WHERE c_id = $course_id AND id = $item_id";
4402
    Database::query($sql);
4403
    api_item_property_update($course_info, 'work', $item_id, 'visible', api_get_user_id());
4404
}
4405
4406
/**
4407
 * @param int $item_id
4408
 * @param array $course_info
4409
 */
4410 View Code Duplication
function makeInvisible($item_id, $course_info)
4411
{
4412
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4413
    $item_id = intval($item_id);
4414
    $course_id = $course_info['real_id'];
4415
    $sql = "UPDATE  " . $work_table . "
4416
            SET accepted = 0
4417
            WHERE c_id = $course_id AND id = '" . $item_id . "'";
4418
    Database::query($sql);
4419
    api_item_property_update(
4420
        $course_info,
4421
        'work',
4422
        $item_id,
4423
        'invisible',
4424
        api_get_user_id()
4425
    );
4426
}
4427
4428
/**
4429
 * @param int $item_id
4430
 * @param string $path
4431
 * @param array $courseInfo
4432
 * @param int $groupId iid
4433
 * @param int $sessionId
4434
 * @return string
4435
 */
4436
function generateMoveForm($item_id, $path, $courseInfo, $groupId, $sessionId)
4437
{
4438
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
4439
    $courseId = $courseInfo['real_id'];
4440
    $folders = array();
4441
    $session_id = intval($sessionId);
4442
    $groupId = intval($groupId);
4443
    $sessionCondition = empty($sessionId) ? " AND (session_id = 0 OR session_id IS NULL) " : " AND session_id='".$session_id."'";
4444
4445
    $groupIid = 0;
4446
    if ($groupId) {
4447
        $groupInfo = GroupManager::get_group_properties($groupId);
4448
        $groupIid = $groupInfo['iid'];
4449
    }
4450
4451
    $sql = "SELECT id, url, title
4452
            FROM $work_table
4453
            WHERE
4454
                c_id = $courseId AND
4455
                active IN (0, 1) AND
4456
                url LIKE '/%' AND
4457
                post_group_id = $groupIid
4458
                $sessionCondition";
4459
    $res = Database::query($sql);
4460
    while ($folder = Database::fetch_array($res)) {
4461
        $title = empty($folder['title']) ? basename($folder['url']) : $folder['title'];
4462
        $folders[$folder['id']] = $title;
4463
    }
4464
4465
    return build_work_move_to_selector($folders, $path, $item_id);
4466
}
4467
4468
/**
4469
 * @param int $workId
4470
 * @return string
4471
 */
4472
function showStudentList($workId)
4473
{
4474
    $columnModel = array(
4475
        array(
4476
            'name' => 'student',
4477
            'index' => 'student',
4478
            'width' => '350px',
4479
            'align' => 'left',
4480
            'sortable' => 'false',
4481
        ),
4482
        array(
4483
            'name' => 'works',
4484
            'index' => 'works',
4485
            'align' => 'center',
4486
            'sortable' => 'false',
4487
        ),
4488
    );
4489
    $token = null;
4490
4491
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student_list_overview&work_id='.$workId.'&'.api_get_cidreq();
4492
4493
    $columns = array(
4494
        get_lang('Students'),
4495
        get_lang('Works')
4496
    );
4497
4498
    $order = api_is_western_name_order() ? 'firstname' : 'lastname';
4499
    $params = array(
4500
        'autowidth' => 'true',
4501
        'height' => 'auto',
4502
        'rowNum' => 5,
4503
        'sortname' => $order,
4504
        'sortorder' => 'asc'
4505
    );
4506
4507
    $html = '<script>
4508
    $(function() {
4509
        '.Display::grid_js('studentList', $url, $columns, $columnModel, $params, array(), null, true).'
4510
        $("#workList").jqGrid(
4511
            "navGrid",
4512
            "#studentList_pager",
4513
            { edit: false, add: false, del: false },
4514
            { height:280, reloadAfterSubmit:false }, // edit options
4515
            { height:280, reloadAfterSubmit:false }, // add options
4516
            { width:500 } // search options
4517
        );
4518
    });
4519
    </script>';
4520
    $html .= Display::grid_html('studentList');
4521
    return $html;
4522
}
4523
4524
/**
4525
 * @param string $courseCode
4526
 * @param int $sessionId
4527
 * @param int $groupId
4528
 * @param int $start
4529
 * @param int $limit
4530
 * @param string $sidx
4531
 * @param string $sord
4532
 * @param $getCount
4533
 * @return array|int
4534
 */
4535
function getWorkUserList($courseCode, $sessionId, $groupId, $start, $limit, $sidx, $sord, $getCount = false)
4536
{
4537
    if (!empty($groupId)) {
4538
        $userList = GroupManager::get_users(
4539
            $groupId,
4540
            false,
4541
            $start,
4542
            $limit,
4543
            $getCount,
4544
            null,
4545
            $sidx,
4546
            $sord
4547
        );
4548
    } else {
4549
        $limitString = null;
4550 View Code Duplication
        if (!empty($start) && !empty($limit)) {
4551
            $start = intval($start);
4552
            $limit = intval($limit);
4553
            $limitString = " LIMIT $start, $limit";
4554
        }
4555
4556
        $orderBy = null;
4557
4558
        if (!empty($sidx) && !empty($sord)) {
4559
            if (in_array($sidx, array('firstname', 'lastname'))) {
4560
                $orderBy = "ORDER BY $sidx $sord";
4561
            }
4562
        }
4563
4564
        if (empty($sessionId)) {
4565
            $userList = CourseManager::get_user_list_from_course_code(
4566
                $courseCode,
4567
                $sessionId,
4568
                $limitString,
4569
                $orderBy ,
4570
                STUDENT,
4571
                $getCount
4572
            );
4573
        } else {
4574
            $userList = CourseManager::get_user_list_from_course_code(
4575
                $courseCode,
4576
                $sessionId,
4577
                $limitString,
4578
                $orderBy,
4579
                0,
4580
                $getCount
4581
            );
4582
        }
4583
4584
        if ($getCount == false) {
4585
            $userList = array_keys($userList);
4586
        }
4587
    }
4588
    return $userList;
4589
}
4590
4591
/**
4592
 * @param int $workId
4593
 * @param string $courseCode
4594
 * @param int $sessionId
4595
 * @param int $groupId
4596
 * @param int $start
4597
 * @param int $limit
4598
 * @param int $sidx
4599
 * @param string $sord
4600
 * @param bool $getCount
4601
 * @return array|int
4602
 */
4603
function getWorkUserListData(
4604
    $workId,
4605
    $courseCode,
4606
    $sessionId,
4607
    $groupId,
4608
    $start,
4609
    $limit,
4610
    $sidx,
4611
    $sord,
4612
    $getCount = false
4613
) {
4614
    $my_folder_data = get_work_data_by_id($workId);
4615
    $workParents = array();
4616
    if (empty($my_folder_data)) {
4617
        $workParents = getWorkList($workId, $my_folder_data, null);
4618
    }
4619
4620
    $workIdList = array();
4621
    if (!empty($workParents)) {
4622
        foreach ($workParents as $work) {
4623
            $workIdList[] = $work->id;
4624
        }
4625
    }
4626
4627
    $courseInfo = api_get_course_info($courseCode);
4628
4629
    $userList = getWorkUserList(
4630
        $courseCode,
4631
        $sessionId,
4632
        $groupId,
4633
        $start,
4634
        $limit,
4635
        $sidx,
4636
        $sord,
4637
        $getCount
4638
    );
4639
4640
    if ($getCount) {
4641
        return $userList;
4642
    }
4643
    $results = array();
4644
    if (!empty($userList)) {
4645
        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...
4646
            $user = api_get_user_info($userId);
4647
            $link = api_get_path(WEB_CODE_PATH).'work/student_work.php?'.api_get_cidreq().'&studentId='.$user['user_id'];
4648
            $url = Display::url(api_get_person_name($user['firstname'], $user['lastname']), $link);
4649
            $userWorks = 0;
4650
            if (!empty($workIdList)) {
4651
                $userWorks = getUniqueStudentAttempts(
4652
                    $workIdList,
4653
                    $groupId,
4654
                    $courseInfo['real_id'],
4655
                    $sessionId,
4656
                    $user['user_id']
4657
                );
4658
            }
4659
            $works = $userWorks." / ".count($workParents);
4660
            $results[] = array(
4661
                'student' => $url,
4662
                'works' => Display::url($works, $link),
4663
            );
4664
        }
4665
    }
4666
4667
    return $results;
4668
}
4669
4670
/**
4671
 * @param int $id
4672
 * @param array $course_info
4673
 * @param bool $isCorrection
4674
 *
4675
 * @return bool
4676
 */
4677
function downloadFile($id, $course_info, $isCorrection)
4678
{
4679
    return getFile($id, $course_info, true, $isCorrection);
4680
}
4681
4682
/**
4683
 * @param int $id
4684
 * @param array $course_info
4685
 * @param bool $download
4686
 * @param bool $isCorrection
4687
 *
4688
 * @return bool
4689
 */
4690
function getFile($id, $course_info, $download = true, $isCorrection = false)
4691
{
4692
    $file = getFileContents($id, $course_info, 0, $isCorrection);
4693
    if (!empty($file) && is_array($file)) {
4694
        return DocumentManager::file_send_for_download(
4695
            $file['path'],
4696
            $download,
4697
            $file['title']
4698
        );
4699
    }
4700
4701
    return false;
4702
}
4703
4704
4705
/**
4706
 * Get the file contents for an assigment
4707
 * @param int $id
4708
 * @param array $course_info
4709
 * @param int Session ID
4710
 * @param $correction
4711
 *
4712
 * @return array|bool
4713
 */
4714
function getFileContents($id, $course_info, $sessionId = 0, $correction = false)
4715
{
4716
    $id = intval($id);
4717
    if (empty($course_info) || empty($id)) {
4718
        return false;
4719
    }
4720
    if (empty($sessionId)) {
4721
        $sessionId = api_get_session_id();
4722
    }
4723
4724
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4725
4726
    if (!empty($course_info['real_id'])) {
4727
        $sql = 'SELECT *
4728
                FROM '.$table.'
4729
                WHERE c_id = '.$course_info['real_id'].' AND id = "'.$id.'"';
4730
        $result = Database::query($sql);
4731
        if ($result && Database::num_rows($result)) {
4732
            $row = Database::fetch_array($result, 'ASSOC');
4733
4734
            if ($correction) {
4735
                $row['url'] = $row['url_correction'];
4736
            }
4737
4738
            if (empty($row['url'])) {
4739
                return false;
4740
            }
4741
4742
            $full_file_name = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.$row['url'];
4743
4744
            $item_info = api_get_item_property_info(
4745
                api_get_course_int_id(),
4746
                'work',
4747
                $row['id'],
4748
                $sessionId
4749
            );
4750
4751
            allowOnlySubscribedUser(
4752
                api_get_user_id(),
4753
                $row['parent_id'],
4754
                $course_info['real_id']
4755
            );
4756
4757
            if (empty($item_info)) {
4758
                api_not_allowed();
4759
            }
4760
4761
            /*
4762
            field show_score in table course :
4763
                0 =>    New documents are visible for all users
4764
                1 =>    New documents are only visible for the teacher(s)
4765
            field visibility in table item_property :
4766
                0 => eye closed, invisible for all students
4767
                1 => eye open
4768
            field accepted in table c_student_publication :
4769
                0 => eye closed, invisible for all students
4770
                1 => eye open
4771
            ( We should have visibility == accepted, otherwise there is an
4772
            inconsistency in the Database)
4773
            field value in table c_course_setting :
4774
                0 => Allow learners to delete their own publications = NO
4775
                1 => Allow learners to delete their own publications = YES
4776
4777
            +------------------+-------------------------+------------------------+
4778
            |Can download work?| doc visible for all = 0 | doc visible for all = 1|
4779
            +------------------+-------------------------+------------------------+
4780
            |  visibility = 0  | editor only             | editor only            |
4781
            |                  |                         |                        |
4782
            +------------------+-------------------------+------------------------+
4783
            |  visibility = 1  | editor                  | editor                 |
4784
            |                  | + owner of the work     | + any student          |
4785
            +------------------+-------------------------+------------------------+
4786
            (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
4787
            */
4788
4789
            $work_is_visible = $item_info['visibility'] == 1 && $row['accepted'] == 1;
4790
            $doc_visible_for_all = ($course_info['show_score'] == 1);
4791
4792
            $is_editor = api_is_allowed_to_edit(true, true, true);
4793
            $student_is_owner_of_work = user_is_author($row['id'], $row['user_id']);
4794
4795
            if ($is_editor ||
4796
                ($student_is_owner_of_work) ||
4797
                ($doc_visible_for_all && $work_is_visible)
4798
            ) {
4799
                $title = $row['title'];
4800
                if ($correction) {
4801
                    $title = $row['title_correction'];
4802
                }
4803
                if (array_key_exists('filename', $row) && !empty($row['filename'])) {
4804
                    $title = $row['filename'];
4805
                }
4806
4807
                $title = str_replace(' ', '_', $title);
4808
                Event::event_download($title);
4809
                if (Security::check_abs_path(
4810
                    $full_file_name,
4811
                    api_get_path(SYS_COURSE_PATH).api_get_course_path().'/')
4812
                ) {
4813
                    return array(
4814
                        'path' => $full_file_name,
4815
                        'title' => $title,
4816
                        'title_correction' => $row['title_correction']
4817
                    );
4818
                }
4819
            }
4820
        }
4821
    }
4822
4823
    return false;
4824
}
4825
4826
/**
4827
 * @param int $userId
4828
 * @param array $courseInfo
4829
 * @param string $format
4830
 * @return bool
4831
 */
4832
function exportAllWork($userId, $courseInfo, $format = 'pdf')
4833
{
4834
    $userInfo = api_get_user_info($userId);
4835
    if (empty($userInfo) || empty($courseInfo)) {
4836
        return false;
4837
    }
4838
4839
    $workPerUser = getWorkPerUser($userId);
4840
4841
    switch ($format) {
4842
        case 'pdf':
4843
            if (!empty($workPerUser)) {
4844
                $pdf = new PDF();
4845
4846
                $content = null;
4847
                foreach ($workPerUser as $work) {
4848
                    $work = $work['work'];
4849
                    foreach ($work->user_results as $userResult) {
4850
                        $content .= $userResult['title'];
4851
                        // No need to use api_get_local_time()
4852
                        $content .= $userResult['sent_date'];
4853
                        $content .= $userResult['qualification'];
4854
                        $content .= $userResult['description'];
4855
                    }
4856
                }
4857
4858
                if (!empty($content)) {
4859
                    $pdf->content_to_pdf(
4860
                        $content,
4861
                        null,
4862
                        api_replace_dangerous_char($userInfo['complete_name']),
4863
                        $courseInfo['code']
4864
                    );
4865
                }
4866
            }
4867
            break;
4868
    }
4869
}
4870
4871
/**
4872
 * @param int $workId
4873
 * @param array $courseInfo
4874
 * @param int $sessionId
4875
 * @param string $format
4876
 * @return bool
4877
 */
4878
function exportAllStudentWorkFromPublication(
4879
    $workId,
4880
    $courseInfo,
4881
    $sessionId,
4882
    $format = 'pdf'
4883
) {
4884
    if (empty($courseInfo)) {
4885
        return false;
4886
    }
4887
4888
    $workData = get_work_data_by_id($workId);
4889
4890
    if (empty($workData)) {
4891
        return false;
4892
    }
4893
4894
    $assignment = get_work_assignment_by_id($workId);
4895
4896
    $courseCode = $courseInfo['code'];
4897
    $header = get_lang('Course').': '.$courseInfo['title'];
4898
    $teachers = CourseManager::get_teacher_list_from_course_code_to_string(
4899
        $courseCode
4900
    );
4901
4902
    if (!empty($sessionId)) {
4903
        $sessionInfo = api_get_session_info($sessionId);
4904
        if (!empty($sessionInfo)) {
4905
            $header .= ' - ' . $sessionInfo['name'];
4906
            $header .= '<br />' . $sessionInfo['description'];
4907
            $teachers = SessionManager::getCoachesByCourseSessionToString(
4908
                $sessionId,
4909
                $courseInfo['real_id']
4910
            );
4911
        }
4912
    }
4913
4914
    $header .= '<br />'.get_lang('Teachers').': '.$teachers.'<br />';
4915
    $header .= '<br />'.get_lang('Date').': '.api_get_local_time().'<br />';
4916
    $header .= '<br />'.get_lang('WorkName').': '.$workData['title'].'<br />';
4917
4918
    $content = null;
4919
    $expiresOn = null;
4920
4921
    if (!empty($assignment) && isset($assignment['expires_on'])) {
4922
        $content .= '<br /><strong>' . get_lang('ExpirationDate') . '</strong>: ' . api_get_local_time($assignment['expires_on']);
4923
        $expiresOn = api_get_local_time($assignment['expires_on']);
4924
    }
4925
4926
    if (!empty($workData['description'])) {
4927
        $content .= '<br /><strong>' . get_lang('Description') . '</strong>: ' . $workData['description'];
4928
    }
4929
4930
    $workList = get_work_user_list(null, null, null, null, $workId);
4931
4932
    switch ($format) {
4933
        case 'pdf':
4934
            if (!empty($workList)) {
4935
4936
                $table = new HTML_Table(array('class' => 'data_table'));
4937
                $headers = array(
4938
                    get_lang('Name'),
4939
                    get_lang('User'),
4940
                    get_lang('HandOutDateLimit'),
4941
                    get_lang('SentDate'),
4942
                    get_lang('FileName'),
4943
                    get_lang('Score'),
4944
                    get_lang('Feedback')
4945
                );
4946
4947
                $column = 0;
4948
                foreach($headers as $header) {
4949
                    $table->setHeaderContents(0, $column, $header);
4950
                    $column++;
4951
                }
4952
4953
                $row = 1;
4954
4955
                //$pdf->set_custom_header($header);
4956
                foreach ($workList as $work) {
4957
                    $content .= '<hr />';
4958
                    // getWorkComments need c_id
4959
                    $work['c_id'] = $courseInfo['real_id'];
4960
4961
                    //$content .= get_lang('Date').': '.api_get_local_time($work['sent_date_from_db']).'<br />';
4962
                    $score = null;
4963
                    if (!empty($work['qualification_only'])) {
4964
                        $score = $work['qualification_only'];
4965
                    }
4966
                    //$content .= get_lang('Description').': '.$work['description'].'<br />';
4967
                    $comments = getWorkComments($work);
4968
4969
                    $feedback = null;
4970
                    if (!empty($comments)) {
4971
                        $content .= '<h4>'.get_lang('Feedback').': </h4>';
4972
                        foreach ($comments as $comment) {
4973
                            $feedback .= get_lang('User').': '.api_get_person_name(
4974
                                    $comment['firstname'],
4975
                                    $comment['lastname']
4976
                                ).'<br />';
4977
                            $feedback .= $comment['comment'].'<br />';
4978
                        }
4979
                    }
4980
4981
                    $table->setCellContents($row, 0, strip_tags($workData['title']));
4982
                    $table->setCellContents($row, 1, api_get_person_name(strip_tags($work['firstname']), strip_tags($work['lastname'])));
4983
                    $table->setCellContents($row, 2, $expiresOn);
4984
                    $table->setCellContents($row, 3, api_get_local_time($work['sent_date_from_db']));
4985
                    $table->setCellContents($row, 4, strip_tags($work['title']));
4986
                    $table->setCellContents($row, 5, $score);
4987
                    $table->setCellContents($row, 6, $feedback);
4988
4989
                    $row++;
4990
                }
4991
4992
                $content = $table->toHtml();
4993
4994
                if (!empty($content)) {
4995
                    $params = array(
4996
                        'filename' => $workData['title'] . '_' . api_get_local_time(),
4997
                        'pdf_title' => api_replace_dangerous_char($workData['title']),
4998
                        'course_code' => $courseInfo['code'],
4999
                        'add_signatures' => false
5000
                    );
5001
                    $pdf = new PDF('A4', null, $params);
5002
                    $pdf->html_to_pdf_with_template($content);
5003
                }
5004
                exit;
5005
            }
5006
            break;
5007
    }
5008
}
5009
5010
/**
5011
 * Downloads all user files per user
5012
 * @param int $userId
5013
 * @param array $courseInfo
5014
 * @return bool
5015
 */
5016
function downloadAllFilesPerUser($userId, $courseInfo)
5017
{
5018
    $userInfo = api_get_user_info($userId);
5019
5020
    if (empty($userInfo) || empty($courseInfo)) {
5021
        return false;
5022
    }
5023
5024
    $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
5025
    $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
5026
5027
    $zip  = new PclZip($tempZipFile);
5028
5029
    $workPerUser = getWorkPerUser($userId);
5030
5031
    if (!empty($workPerUser)) {
5032
        $files = array();
5033
        foreach ($workPerUser as $work) {
5034
            $work = $work['work'];
5035
            foreach ($work->user_results as $userResult) {
5036
                if (empty($userResult['url']) || empty($userResult['contains_file'])) {
5037
                    continue;
5038
                }
5039
                $data = getFileContents($userResult['id'], $courseInfo);
5040
                if (!empty($data) && isset($data['path'])) {
5041
                    $files[basename($data['path'])] = array(
5042
                        'title' => $data['title'],
5043
                        'path' => $data['path']
5044
                    );
5045
                }
5046
            }
5047
        }
5048
5049
        if (!empty($files)) {
5050
            Session::write('files', $files);
5051
            foreach ($files as $data) {
5052
                $zip->add(
5053
                    $data['path'],
5054
                    PCLZIP_OPT_REMOVE_PATH,
5055
                    $coursePath,
5056
                    PCLZIP_CB_PRE_ADD,
5057
                    'preAddAllWorkStudentCallback'
5058
                );
5059
            }
5060
        }
5061
5062
        // Start download of created file
5063
        $name = basename(api_replace_dangerous_char($userInfo['complete_name'])).'.zip';
5064
        Event::event_download($name.'.zip (folder)');
5065 View Code Duplication
        if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) {
5066
            DocumentManager::file_send_for_download($tempZipFile, true, $name);
5067
            @unlink($tempZipFile);
5068
            exit;
5069
        }
5070
    }
5071
    exit;
5072
}
5073
5074
/**
5075
 * @param $p_event
5076
 * @param array $p_header
5077
 * @return int
5078
 */
5079 View Code Duplication
function preAddAllWorkStudentCallback($p_event, &$p_header)
5080
{
5081
    $files = Session::read('files');
5082
    if (isset($files[basename($p_header['stored_filename'])])) {
5083
        $p_header['stored_filename'] = $files[basename($p_header['stored_filename'])]['title'];
5084
        return 1;
5085
    }
5086
    return 0;
5087
}
5088
5089
/**
5090
 * Get all work created by a user
5091
 * @param int $user_id
5092
 * @param int $courseId
5093
 * @param int $sessionId
5094
 * @return array
5095
 */
5096
function getWorkCreatedByUser($user_id, $courseId, $sessionId)
5097
{
5098
    $items = api_get_item_property_list_by_tool_by_user(
5099
        $user_id,
5100
        'work',
5101
        $courseId,
5102
        $sessionId
5103
    );
5104
5105
    $forumList = array();
5106 View Code Duplication
    if (!empty($items)) {
5107
        foreach ($items as $forum) {
5108
            $item = get_work_data_by_id(
5109
                $forum['ref'],
5110
                $courseId,
5111
                $sessionId
5112
            );
5113
5114
            $forumList[] = array(
5115
                $item['title'],
5116
                api_get_local_time($forum['insert_date']),
5117
                api_get_local_time($forum['lastedit_date'])
5118
            );
5119
        }
5120
    }
5121
5122
    return $forumList;
5123
}
5124
5125
/**
5126
 * @param array $courseInfo
5127
 * @param int $workId
5128
 * @return bool
5129
 */
5130
function protectWork($courseInfo, $workId)
5131
{
5132
    $userId = api_get_user_id();
5133
    $groupId = api_get_group_id();
5134
    $sessionId = api_get_session_id();
5135
    $workData = get_work_data_by_id($workId);
5136
5137
    if (empty($workData) || empty($courseInfo)) {
5138
        api_not_allowed(true);
5139
    }
5140
5141
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
5142
        return true;
5143
    }
5144
5145
    $workId = $workData['id'];
5146
5147
    if ($workData['active'] != 1) {
5148
        api_not_allowed(true);
5149
    }
5150
5151
    $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $sessionId);
5152
5153
    if ($visibility != 1) {
5154
        api_not_allowed(true);
5155
    }
5156
5157
    allowOnlySubscribedUser($userId, $workId, $courseInfo['real_id']);
5158
    $groupInfo = GroupManager::get_group_properties($groupId);
5159
5160
    if (!empty($groupId)) {
5161
        $showWork = GroupManager::user_has_access(
5162
            $userId,
5163
            $groupInfo['iid'],
5164
            GroupManager::GROUP_TOOL_WORK
5165
        );
5166
        if (!$showWork) {
5167
            api_not_allowed(true);
5168
        }
5169
    }
5170
}
5171
5172
/**
5173
 * @param array $courseInfo
5174
 * @param array $work
5175
 */
5176
function deleteCorrection($courseInfo, $work)
5177
{
5178
    if (isset($work['url_correction']) && !empty($work['url_correction']) && isset($work['iid'])) {
5179
        $id = $work['iid'];
5180
        $table = Database:: get_course_table(TABLE_STUDENT_PUBLICATION);
5181
        $sql = "UPDATE $table SET
5182
                    url_correction = '',
5183
                    title_correction = ''
5184
                WHERE iid = $id";
5185
        Database::query($sql);
5186
        $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
5187
        if (file_exists($coursePath.$work['url_correction'])) {
5188
            if (Security::check_abs_path($coursePath.$work['url_correction'], $coursePath)) {
5189
                unlink($coursePath.$work['url_correction']);
5190
            }
5191
        }
5192
    }
5193
}
5194