Passed
Push — 1.10.x ( fcbc7e...d1416f )
by Angel Fernando Quiroz
51:56 queued 22:08
created

work.lib.php ➔ deleteDirWork()   D

Complexity

Conditions 15
Paths 88

Size

Total Lines 139
Code Lines 91

Duplication

Lines 15
Ratio 10.79 %

Importance

Changes 0
Metric Value
cc 15
eloc 91
nc 88
nop 1
dl 15
loc 139
rs 4.9121
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

Loading history...
142
}
143
144
/**
145
 * get date from a group of date
146
 */
147 View Code Duplication
function get_date_from_group($group)
148
{
149
    return
150
        $_POST[$group]['year'].'-'.
151
        two_digits($_POST[$group]['month']).'-'.
152
        two_digits($_POST[$group]['day']).' '.
153
        two_digits($_POST[$group]['hour']).':'.
154
        two_digits($_POST[$group]['minute']).':00';
155
}
156
157
/**
158
 * Create a group of select from a date
159
 * @param FormValidator $form
160
 * @param string $prefix
161
 * @return array
162
 */
163
function create_group_date_select($form, $prefix = '')
164
{
165
    $minute = range(10, 59);
166
    $d_year = date('Y');
167
    array_unshift($minute, '00', '01', '02', '03', '04', '05', '06', '07', '08', '09');
168
169
    $group_name = array(
170
        $form->createElement('select', $prefix.'day', '', array_combine(range(1, 31), range(1, 31))),
171
        $form->createElement('select', $prefix.'month', '', array_combine(range(1, 12), api_get_months_long())),
172
        $form->createElement('select', $prefix.'year', '', array($d_year => $d_year, $d_year + 1 => $d_year + 1)),
173
        $form->createElement('select', $prefix.'hour', '', array_combine(range(0, 23), range(0, 23))),
174
        $form->createElement('select', $prefix.'minute', '', $minute)
175
    );
176
    return $group_name;
177
}
178
179
/**
180
 * @param string $path
181
 * @param int $courseId
182
 *
183
 * @return array
184
 */
185 View Code Duplication
function get_work_data_by_path($path, $courseId = null)
186
{
187
    $path = Database::escape_string($path);
188
    if (empty($courseId)) {
189
        $courseId = api_get_course_int_id();
190
    } else {
191
        $courseId = intval($courseId);
192
    }
193
194
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
195
    $sql = "SELECT *  FROM  ".$work_table."
196
            WHERE url = '$path' AND c_id = $courseId ";
197
    $result = Database::query($sql);
198
    $return = array();
199
    if (Database::num_rows($result)) {
200
        $return = Database::fetch_array($result, 'ASSOC');
201
    }
202
203
    return $return;
204
}
205
206
/**
207
 * @param int $id
208
 * @param int $courseId
209
 * @param int $sessionId
210
 * @return array
211
 */
212
function get_work_data_by_id($id, $courseId = null, $sessionId = null)
213
{
214
    $id = intval($id);
215
216
    if (!empty($courseId)) {
217
        $courseId = intval($courseId);
218
    } else {
219
        $courseId = api_get_course_int_id();
220
    }
221
222
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
223
224
    $sessionCondition = null;
225
    if (!empty($sessionId)) {
226
        $sessionCondition = api_get_session_condition($sessionId, true);
227
    }
228
229
    $sql = "SELECT * FROM $table
230
            WHERE
231
                id = $id AND c_id = $courseId
232
                $sessionCondition";
233
    $result = Database::query($sql);
234
    $work = array();
235
    if (Database::num_rows($result)) {
236
        $work = Database::fetch_array($result, 'ASSOC');
237
        if (empty($work['title'])) {
238
            $work['title'] = basename($work['url']);
239
        }
240
        $work['download_url'] = api_get_path(WEB_CODE_PATH).'work/download.php?id='.$work['id'].'&'.api_get_cidreq();
241
        $work['view_url'] = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&'.api_get_cidreq();
242
        $work['show_url'] = api_get_path(WEB_CODE_PATH).'work/show_file.php?id='.$work['id'].'&'.api_get_cidreq();
243
        $work['show_content'] = '';
244
        if ($work['contains_file']) {
245
            $fileInfo = pathinfo($work['title']);
246
            if (is_array($fileInfo) &&
247
                !empty($fileInfo['extension']) &&
248
                in_array($fileInfo['extension'], array('jpg', 'png', 'gif'))
249
            ) {
250
                $work['show_content'] = '<img src="'.$work['show_url'].'"/>';
251
            }
252
        }
253
254
        $fieldValue = new ExtraFieldValue('work');
255
        $work['extra'] = $fieldValue->getAllValuesForAnItem(
256
            $id,
257
            true
258
        );
259
260
    }
261
262
    return $work;
263
}
264
265
/**
266
 * @param int $user_id
267
 * @param int $work_id
268
 *
269
 * @return int
270
 */
271
function get_work_count_by_student($user_id, $work_id)
272
{
273
    $user_id = intval($user_id);
274
    $work_id = intval($work_id);
275
    $course_id = api_get_course_int_id();
276
    $session_id = api_get_session_id();
277
278
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
279
    $sql = "SELECT COUNT(*) as count
280
            FROM  $table
281
            WHERE
282
                c_id = $course_id AND
283
                parent_id = $work_id AND
284
                user_id = $user_id AND
285
                active IN (0, 1) AND
286
                session_id = $session_id ";
287
    $result = Database::query($sql);
288
    $return = 0;
289
    if (Database::num_rows($result)) {
290
        $return = Database::fetch_row($result, 'ASSOC');
291
        $return = intval($return[0]);
292
    }
293
294
    return $return;
295
}
296
297
/**
298
 * @param int $id
299
 * @param int $courseId
300
 *
301
 * @return array
302
 */
303 View Code Duplication
function get_work_assignment_by_id($id, $courseId = null)
304
{
305
    if (empty($courseId)) {
306
        $courseId = api_get_course_int_id();
307
    } else {
308
        $courseId = intval($courseId);
309
    }
310
    $id = intval($id);
311
312
    $table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
313
    $sql = "SELECT * FROM $table
314
            WHERE c_id = $courseId AND publication_id = $id";
315
    $result = Database::query($sql);
316
    $return = array();
317
    if (Database::num_rows($result)) {
318
        $return = Database::fetch_array($result, 'ASSOC');
319
    }
320
321
    return $return;
322
}
323
324
/**
325
 * @param int $id
326
 * @param array $my_folder_data
327
 * @param string $add_in_where_query
328
 * @param int $course_id
329
 * @param int $session_id
330
 *
331
 * @return array
332
 */
333
function getWorkList($id, $my_folder_data, $add_in_where_query = null, $course_id = 0, $session_id = 0)
334
{
335
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
336
337
    $course_id = $course_id ? $course_id : api_get_course_int_id();
338
    $session_id = $session_id ? $session_id : api_get_session_id();
339
    $condition_session = api_get_session_condition($session_id);
340
    $group_id = api_get_group_id();
341
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
342
343
    $linkInfo = GradebookUtils::is_resource_in_course_gradebook(
344
        api_get_course_id(),
345
        3,
346
        $id,
347
        api_get_session_id()
348
    );
349
350
    if ($linkInfo) {
351
        $workInGradeBookLinkId = $linkInfo['id'];
352
        if ($workInGradeBookLinkId) {
353
            if ($is_allowed_to_edit) {
354
                if (intval($my_folder_data['qualification']) == 0) {
355
                    Display::display_warning_message(
356
                        get_lang('MaxWeightNeedToBeProvided')
357
                    );
358
                }
359
            }
360
        }
361
    }
362
363
    $contains_file_query = '';
364
365
    // Get list from database
366
    if ($is_allowed_to_edit) {
367
        $active_condition = ' active IN (0, 1)';
368
        $sql = "SELECT * FROM $work_table
369
                WHERE
370
                    c_id = $course_id
371
                    $add_in_where_query
372
                    $condition_session AND
373
                    $active_condition AND
374
                    (parent_id = 0)
375
                    $contains_file_query AND
376
                    post_group_id = '".$group_id."'
377
                ORDER BY sent_date DESC";
378
    } else {
379 View Code Duplication
        if (!empty($group_id)) {
380
            // set to select only messages posted by the user's group
381
            $group_query = " WHERE c_id = $course_id AND post_group_id = '".$group_id."' ";
382
            $subdirs_query = "AND parent_id = 0";
383
        } else {
384
            $group_query = " WHERE c_id = $course_id AND  post_group_id = '0' ";
385
            $subdirs_query = "AND parent_id = 0";
386
        }
387
        //@todo how we can active or not an assignment?
388
        $active_condition = ' AND active IN (1, 0)';
389
        $sql = "SELECT * FROM  $work_table
390
                $group_query
391
                $subdirs_query
392
                $add_in_where_query
393
                $active_condition
394
                $condition_session
395
                ORDER BY title";
396
    }
397
398
    $work_parents = array();
399
400
    $sql_result = Database::query($sql);
401
    if (Database::num_rows($sql_result)) {
402
        while ($work = Database::fetch_object($sql_result)) {
403
            if ($work->parent_id == 0) {
404
                $work_parents[] = $work;
405
            }
406
        }
407
    }
408
409
    return $work_parents;
410
}
411
412
/**
413
 * @param int $userId
414
 * @param int $courseId
415
 * @param int $sessionId
416
 * @return array
417
 */
418
function getWorkPerUser($userId, $courseId = 0, $sessionId = 0)
419
{
420
    $works = getWorkList(null, null, null, $courseId, $sessionId);
421
    $result = array();
422
    if (!empty($works)) {
423
        foreach ($works as $workData) {
424
            $workId = $workData->id;
425
            $result[$workId]['work'] = $workData;
426
            $result[$workId]['work']->user_results = get_work_user_list(
427
                0,
428
                100,
429
                null,
430
                null,
431
                $workId,
432
                null,
433
                $userId,
434
                false,
435
                $courseId,
436
                $sessionId
437
            );
438
        }
439
    }
440
    return $result;
441
}
442
443
/**
444
 * @param int $workId
445
 * @param int $groupId
446
 * @param int $course_id
447
 * @param int $sessionId
448
 * @return mixed
449
 */
450
function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
451
{
452
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
453
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
454
    $course_id = intval($course_id);
455
    $workId = intval($workId);
456
    $sessionId = intval($sessionId);
457
    $groupId = intval($groupId);
458
459
    $sql = "SELECT count(DISTINCT u.user_id)
460
            FROM $work_table w
461
            INNER JOIN $user_table u
462
                ON w.user_id = u.user_id
463
            WHERE
464
                w.c_id = $course_id AND
465
                w.session_id = $sessionId AND
466
                w.parent_id = ".$workId." AND
467
                w.post_group_id = ".$groupId." AND
468
                w.active IN (0, 1)
469
            ";
470
471
    $res_document = Database::query($sql);
472
    $rowCount = Database::fetch_row($res_document);
473
474
    return $rowCount[0];
475
}
476
477
/**
478
 * @param mixed $workId
479
 * @param int $groupId
480
 * @param int $course_id
481
 * @param int $sessionId
482
 * @param int $userId user id to filter
483
 * @param array $onlyUserList only parse this user list
484
 * @return mixed
485
 */
486
function getUniqueStudentAttempts(
487
    $workId,
488
    $groupId,
489
    $course_id,
490
    $sessionId,
491
    $userId = null,
492
    $onlyUserList = array()
493
) {
494
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
495
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
496
497
    $course_id = intval($course_id);
498
    $workCondition = null;
499
    if (is_array($workId)) {
500
        $workId = array_map('intval', $workId);
501
        $workId = implode("','", $workId);
502
        $workCondition = " w.parent_id IN ('".$workId."') AND";
503
    } else {
504
        $workId = intval($workId);
505
        $workCondition = " w.parent_id = ".$workId." AND";
506
    }
507
508
    $sessionId = intval($sessionId);
509
    $groupId = intval($groupId);
510
511
    $studentCondition = null;
512
513 View Code Duplication
    if (!empty($onlyUserList)) {
514
        $onlyUserList = array_map('intval', $onlyUserList);
515
        $studentCondition = "AND u.user_id IN ('".implode("', '", $onlyUserList)."') ";
516
    } else {
517
        if (empty($userId)) {
518
            return 0;
519
        }
520
    }
521
522
    $sql = "SELECT count(*) FROM (
523
                SELECT count(*), w.parent_id
524
                FROM $work_table w
525
                INNER JOIN $user_table u
526
                    ON w.user_id = u.user_id
527
                WHERE
528
                    w.filetype = 'file' AND
529
                    w.c_id = $course_id AND
530
                    w.session_id = $sessionId AND
531
                    $workCondition
532
                    w.post_group_id = ".$groupId." AND
533
                    w.active IN (0, 1) $studentCondition
534
                ";
535
    if (!empty($userId)) {
536
        $userId = intval($userId);
537
        $sql .= " AND u.user_id = ".$userId;
538
    }
539
    $sql .= " GROUP BY u.user_id, w.parent_id) as t";
540
    $result = Database::query($sql);
541
    $row = Database::fetch_row($result);
542
543
    return $row[0];
544
}
545
546
/**
547
 * Shows the work list (student view)
548
 * @return string
549
 */
550
function showStudentWorkGrid()
551
{
552
    $courseInfo = api_get_course_info();
553
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student&'.api_get_cidreq();
554
555
    $columns = array(
556
        get_lang('Type'),
557
        get_lang('Title'),
558
        get_lang('HandOutDateLimit'),
559
        get_lang('Feedback'),
560
        get_lang('LastUpload')
561
    );
562
563
    $columnModel = array(
564
        array('name'=>'type', 'index'=>'type', 'width'=>'30',   'align'=>'center', 'sortable' => 'false'),
565
        array('name'=>'title', 'index'=>'title', 'width'=>'250',   'align'=>'left'),
566
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'80',  'align'=>'center', 'sortable'=>'false'),
567
        array('name'=>'feedback', 'index'=>'feedback', 'width'=>'80',  'align'=>'center'),
568
        array('name'=>'last_upload', 'index'=>'feedback', 'width'=>'125',  'align'=>'center'),
569
    );
570
571 View Code Duplication
    if ($courseInfo['show_score'] == 0) {
572
        $columnModel[] = array(
573
            'name' => 'others',
574
            'index' => 'others',
575
            'width' => '80',
576
            'align' => 'left',
577
            'sortable' => 'false'
578
        );
579
        $columns[] = get_lang('Others');
580
    }
581
582
    $params = array(
583
        'autowidth' => 'true',
584
        'height' => 'auto'
585
    );
586
587
    $html = '<script>
588
    $(function() {
589
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
590
    });
591
    </script>';
592
593
    $html .= Display::grid_html('workList');
594
    return $html;
595
}
596
597
/**
598
 * Shows the work list (teacher view)
599
 * @return string
600
 */
601
function showTeacherWorkGrid()
602
{
603
    $columnModel = array(
604
        array('name'=>'type', 'index'=>'type', 'width'=>'35', 'align'=>'center', 'sortable' => 'false'),
605
        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left', 'wrap_cell' => "true"),
606
        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'125',  'align'=>'center'),
607
        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'125',  'align'=>'center'),
608
        array('name'=>'amount', 'index'=>'end_on', 'width'=>'110',  'align'=>'center'),
609
        array('name'=>'actions', 'index'=>'actions', 'width'=>'110', 'align'=>'left', 'sortable'=>'false')
610
    );
611
612
    $token = null;
613
614
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
615
    $deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
616
617
    $columns = array(
618
        get_lang('Type'),
619
        get_lang('Title'),
620
        get_lang('SentDate'),
621
        get_lang('HandOutDateLimit'),
622
        get_lang('AmountSubmitted'),
623
        get_lang('Actions')
624
    );
625
626
    $params = array(
627
        'multiselect' => true,
628
        'autowidth' => 'true',
629
        'height' => 'auto'
630
    );
631
632
    $html = '<script>
633
    $(function() {
634
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, array(), null, true).'
635
        $("#workList").jqGrid(
636
            "navGrid",
637
            "#workList_pager",
638
            { edit: false, add: false, del: true },
639
            { height:280, reloadAfterSubmit:false }, // edit options
640
            { height:280, reloadAfterSubmit:false }, // add options
641
            { reloadAfterSubmit:false, url: "'.$deleteUrl.'" }, // del options
642
            { width:500 } // search options
643
        );
644
    });
645
    </script>';
646
    $html .= Display::grid_html('workList');
647
    return $html;
648
}
649
650
/**
651
 * Builds the form thats enables the user to
652
 * select a directory to browse/upload in
653
 * This function has been copied from the document/document.inc.php library
654
 *
655
 * @param array $folders
656
 * @param string $curdirpath
657
 * @param string $group_dir
658
 * @return string html form
659
 */
660
// TODO: This function is a candidate for removal, it is not used anywhere.
661
function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
662
{
663
    $form = '<form name="selector" action="'.api_get_self().'?'.api_get_cidreq().'" method="POST">';
664
    $form .= get_lang('CurrentDirectory').' <select name="curdirpath" onchange="javascript: document.selector.submit();">';
665
    //group documents cannot be uploaded in the root
666
    if ($group_dir == '') {
667
        $form .= '<option value="/">/ ('.get_lang('Root').')</option>';
668
        if (is_array($folders)) {
669
            foreach ($folders as $folder) {
670
                $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
671
                $form .= '<option'.$selected.' value="'.$folder.'">'.$folder.'</option>'."\n";
672
            }
673
        }
674
    } else {
675
        foreach ($folders as $folder) {
676
            $selected = ($curdirpath == $folder) ? ' selected="selected"' : '';
677
            $display_folder = substr($folder, strlen($group_dir));
678
            $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
679
            $form .= '<option'.$selected.' value="'.$folder.'">'.$display_folder.'</option>'."\n";
680
        }
681
    }
682
683
    $form .= '</select>';
684
    $form .= '<noscript><input type="submit" name="change_path" value="'.get_lang('Ok').'" /></noscript>';
685
    $form .= '</form>';
686
687
    return $form;
688
}
689
690
/**
691
 * Builds the form thats enables the user to
692
 * move a document from one directory to another
693
 * This function has been copied from the document/document.inc.php library
694
 *
695
 * @param array $folders
696
 * @param string $curdirpath
697
 * @param string $move_file
698
 * @param string $group_dir
699
 * @return string html form
700
 */
701
function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_dir = '')
702
{
703
    $course_id = api_get_course_int_id();
704
    $move_file = intval($move_file);
705
    $tbl_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
706
    $sql = "SELECT title, url FROM $tbl_work
707
            WHERE c_id = $course_id AND id ='".$move_file."'";
708
    $result = Database::query($sql);
709
    $row = Database::fetch_array($result, 'ASSOC');
710
    $title = empty($row['title']) ? basename($row['url']) : $row['title'];
711
712
    $form = new FormValidator(
713
        'move_to_form',
714
        'post',
715
        api_get_self().'?'.api_get_cidreq().'&curdirpath='.Security::remove_XSS($curdirpath)
716
    );
717
718
    $form->addHeader(get_lang('MoveFile').' - '.Security::remove_XSS($title));
719
    $form->addHidden('item_id', $move_file);
720
    $form->addHidden('action', 'move_to');
721
722
    //group documents cannot be uploaded in the root
723
    if ($group_dir == '') {
724
        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...
725
            //$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
726
        }
727
        if (is_array($folders)) {
728
            foreach ($folders as $fid => $folder) {
729
                //you cannot move a file to:
730
                //1. current directory
731
                //2. inside the folder you want to move
732
                //3. inside a subfolder of the folder you want to move
733
                if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
734
                    //$form .= '<option value="'.$fid.'">'.$folder.'</option>';
735
                    $options[$fid] = $folder;
736
                }
737
            }
738
        }
739
    } else {
740
        if ($curdirpath != '/') {
741
            $form .= '<option value="0">/ ('.get_lang('Root').')</option>';
742
        }
743
        foreach ($folders as $fid => $folder) {
744
            if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
745
                //cannot copy dir into his own subdir
746
                $display_folder = substr($folder, strlen($group_dir));
747
                $display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
748
                //$form .= '<option value="'.$fid.'">'.$display_folder.'</option>'."\n";
749
                $options[$fid] = $display_folder;
750
            }
751
        }
752
    }
753
754
    $form->addSelect('move_to_id', get_lang('Select'), $options);
755
    $form->addButtonSend(get_lang('MoveFile'), 'move_file_submit');
756
757
    return $form->returnForm();
758
}
759
760
/**
761
 * creates a new directory trying to find a directory name
762
 * that doesn't already exist
763
 * (we could use unique_name() here...)
764
 *
765
 * @author Hugues Peeters <[email protected]>
766
 * @author Bert Vanderkimpen
767
 * @author Yannick Warnier <[email protected]> Adaptation for work tool
768
 * @param   string $base_work_dir Base work dir (.../work)
769
 * @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...
770
 *
771
 * @return  string actual directory name if it succeeds, boolean false otherwise
772
 */
773
function create_unexisting_work_directory($base_work_dir, $desired_dir_name)
774
{
775
    $nb = '';
776
    $base_work_dir = (substr($base_work_dir, -1, 1) == '/' ? $base_work_dir : $base_work_dir.'/');
777
    while (file_exists($base_work_dir.$desired_dir_name.$nb)) {
778
        $nb += 1;
779
    }
780
781
    if (@mkdir($base_work_dir.$desired_dir_name.$nb, api_get_permissions_for_new_directories())) {
782
        return $desired_dir_name.$nb;
783
    } else {
784
        return false;
785
    }
786
}
787
788
/**
789
 * Delete a work-tool directory
790
 * @param   int  $id work directory id to delete
791
 * @return  integer -1 on error
792
 */
793
function deleteDirWork($id)
794
{
795
    $locked = api_resource_is_locked_by_gradebook($id, LINK_STUDENTPUBLICATION);
796
797
    if ($locked == true) {
798
        Display::display_warning_message(get_lang('ResourceLockedByGradebook'));
799
        return false;
800
    }
801
802
    $_course = api_get_course_info();
803
    $id = intval($id);
804
    $work_data = get_work_data_by_id($id);
805
806
    if (empty($work_data)) {
807
        return false;
808
    }
809
810
    $base_work_dir = api_get_path(SYS_COURSE_PATH) .$_course['path'].'/work';
811
    $work_data_url = $base_work_dir.$work_data['url'];
812
    $check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
813
814
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
815
    $TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
816
    $t_agenda = Database::get_course_table(TABLE_AGENDA);
817
818
    $course_id = api_get_course_int_id();
819
    $sessionId = api_get_session_id();
820
821
    if (!empty($work_data['url'])) {
822
        if ($check) {
823
            $consideredWorkingTime = api_get_configuration_value('considered_working_time');
824
825
            if (!empty($consideredWorkingTime)) {
826
                $fieldValue = new ExtraFieldValue('work');
827
                $resultExtra = $fieldValue->getAllValuesForAnItem(
828
                    $work_data['id'],
829
                    true
830
                );
831
832
                $workingTime = null;
833
834 View Code Duplication
                foreach ($resultExtra as $field) {
835
                    $field = $field['value'];
836
                    if ($consideredWorkingTime == $field->getField()->getVariable()) {
837
                        $workingTime = $field->getValue();
838
839
                        break;
840
                    }
841
                }
842
843
                $courseUsers = CourseManager::get_user_list_from_course_code($_course['code'], $sessionId);
844
845
                if (!empty($workingTime)) {
846
                    foreach ($courseUsers as $user) {
0 ignored issues
show
Bug introduced by
The expression $courseUsers 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...
847
                        $userWorks = get_work_user_list(
848
                            0,
849
                            100,
850
                            null,
851
                            null,
852
                            $work_data['id'],
853
                            null,
854
                            $user['user_id'],
855
                            false,
856
                            $course_id,
857
                            $sessionId
858
                        );
859
860
                        if (count($userWorks) != 1) {
861
                            continue;
862
                        }
863
864
                        Event::eventRemoveVirtualCourseTime($course_id, $user['user_id'], $sessionId, $workingTime);
865
                    }
866
                }
867
            }
868
869
            // Deleting all contents inside the folder
870
            $sql = "UPDATE $table SET active = 2
871
                    WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
872
            Database::query($sql);
873
874
            $sql = "UPDATE $table SET active = 2
875
                    WHERE c_id = $course_id AND parent_id = $id";
876
            Database::query($sql);
877
878
            $new_dir = $work_data_url.'_DELETED_'.$id;
879
880 View Code Duplication
            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
881
                my_delete($work_data_url);
882
            } else {
883
                if (file_exists($work_data_url)) {
884
                    rename($work_data_url, $new_dir);
885
                }
886
            }
887
888
            // Gets calendar_id from student_publication_assigment
889
            $sql = "SELECT add_to_calendar FROM $TSTDPUBASG
890
                    WHERE c_id = $course_id AND publication_id = $id";
891
            $res = Database::query($sql);
892
            $calendar_id = Database::fetch_row($res);
893
894
            // delete from agenda if it exists
895
            if (!empty($calendar_id[0])) {
896
                $sql = "DELETE FROM $t_agenda
897
                        WHERE c_id = $course_id AND id = '".$calendar_id[0]."'";
898
                Database::query($sql);
899
            }
900
            $sql = "DELETE FROM $TSTDPUBASG
901
                    WHERE c_id = $course_id AND publication_id = $id";
902
            Database::query($sql);
903
904
            Event::addEvent(
905
                LOG_WORK_DIR_DELETE,
906
                LOG_WORK_DATA,
907
                [
908
                    'id' => $work_data['id'],
909
                    'url' => $work_data['url'],
910
                    'title' => $work_data['title']
911
                ],
912
                null,
913
                api_get_user_id(),
914
                api_get_course_int_id(),
915
                $sessionId
916
            );
917
918
            $link_info = GradebookUtils::is_resource_in_course_gradebook(
919
                api_get_course_id(),
920
                3,
921
                $id,
922
                api_get_session_id()
923
            );
924
            $link_id = $link_info['id'];
925
            if ($link_info !== false) {
926
                GradebookUtils::remove_resource_from_course_gradebook($link_id);
927
            }
928
            return true;
929
        }
930
    }
931
}
932
933
/**
934
 * Get the path of a document in the student_publication table (path relative to the course directory)
935
 * @param   integer $id
936
 * @return  string  Path (or -1 on error)
937
 */
938
function get_work_path($id)
939
{
940
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
941
    $course_id  = api_get_course_int_id();
942
    $sql = 'SELECT url FROM '.$table.'
943
            WHERE c_id = '.$course_id.' AND id='.intval($id);
944
    $res = Database::query($sql);
945
    if (Database::num_rows($res)) {
946
        $row = Database::fetch_array($res);
947
        return $row['url'];
948
    }
949
    return -1;
950
}
951
952
/**
953
 * Update the url of a work in the student_publication table
954
 * @param integer $id of the work to update
955
 * @param string  $new_path Destination directory where the work has been moved (must end with a '/')
956
 * @param int $parent_id
957
 *
958
 * @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...
959
 */
960
function updateWorkUrl($id, $new_path, $parent_id)
961
{
962
    if (empty($id)) {
963
        return -1;
964
    }
965
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
966
    $course_id = api_get_course_int_id();
967
    $id = intval($id);
968
    $parent_id = intval($parent_id);
969
970
    $sql = "SELECT * FROM $table
971
            WHERE c_id = $course_id AND id = $id";
972
    $res = Database::query($sql);
973
    if (Database::num_rows($res) != 1) {
974
        return -1;
975
    } else {
976
        $row = Database::fetch_array($res);
977
        $filename = basename($row['url']);
978
        $new_url = $new_path.$filename;
979
        $new_url = Database::escape_string($new_url);
980
981
        $sql = "UPDATE $table SET
982
                   url = '$new_url',
983
                   parent_id = '$parent_id'
984
                WHERE c_id = $course_id AND id = $id";
985
        $res = Database::query($sql);
986
987
        return $res;
988
    }
989
}
990
991
/**
992
 * Update the url of a dir in the student_publication table
993
 * @param  array $work_data work original data
994
 * @param  string $newPath Example: "folder1"
995
 * @return bool
996
 */
997
function updateDirName($work_data, $newPath)
998
{
999
    $course_id = $work_data['c_id'];
1000
    $sessionId = intval($work_data['session_id']);
1001
    $work_id = intval($work_data['id']);
1002
    $oldPath = $work_data['url'];
1003
    $originalNewPath = Database::escape_string($newPath);
1004
    $newPath = Database::escape_string($newPath);
1005
    $newPath = api_replace_dangerous_char($newPath);
1006
    $newPath = disable_dangerous_file($newPath);
1007
1008
    if ($oldPath == '/'.$newPath) {
1009
        return true;
1010
    }
1011
1012
    if (!empty($newPath)) {
1013
        $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1014
        $sql = "UPDATE $table SET
1015
                    title = '".$originalNewPath."'
1016
                WHERE
1017
                    c_id = $course_id AND
1018
                    id = $work_id AND
1019
                    session_id = $sessionId
1020
                ";
1021
        Database::query($sql);
1022
    }
1023
}
1024
1025
/**
1026
 * Return an array with all the folder's ids that are in the given path
1027
 * @param   string Path of the directory
1028
 * @return  array The list of ids of all the directories in the path
1029
 * @author  Julio Montoya Dokeos
1030
 * @version April 2008
1031
 */
1032
1033
function get_parent_directories($id)
1034
{
1035
    $course_id = api_get_course_int_id();
1036
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1037
    $id = intval($id);
1038
    $sql = "SELECT id FROM $work_table WHERE c_id = $course_id AND parent_id = $id";
1039
    $result = Database::query($sql);
1040
    $list_id = array();
1041
    if (Database::num_rows($result)) {
1042
        while ($row = Database::fetch_array($result)) {
1043
            $list_id[] = $row['id'];
1044
        }
1045
    }
1046
    return $list_id;
1047
}
1048
1049
/**
1050
 * Transform an all directory structure (only directories) in an array
1051
 * @param   string path of the directory
1052
 * @return  array the directory structure into an array
1053
 * @author  Julio Montoya Dokeos
1054
 * @version April 2008
1055
 */
1056 View Code Duplication
function directory_to_array($directory)
1057
{
1058
    $array_items = array();
1059
    if ($handle = @opendir($directory)) {
1060
        while (false !== ($file = readdir($handle))) {
1061
            if ($file != '.' && $file != '..') {
1062
                if (is_dir($directory. '/' . $file)) {
1063
                    $array_items = array_merge($array_items, directory_to_array($directory. '/' . $file));
1064
                    $file = $directory . '/' . $file;
1065
                    $array_items[] = preg_replace("/\/\//si", '/', $file);
1066
                }
1067
            }
1068
        }
1069
        closedir($handle);
1070
    }
1071
    return $array_items;
1072
}
1073
1074
/**
1075
 * Insert into the DB of the course all the directories
1076
 * @param   string path of the /work directory of the course
1077
 * @return  -1 on error, sql query result on success
1078
 * @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...
1079
 * @version April 2008
1080
 * @param string $base_work_dir
1081
 */
1082
1083
function insert_all_directory_in_course_table($base_work_dir)
1084
{
1085
    $dir_to_array = directory_to_array($base_work_dir, true);
1086
    $only_dir = array();
1087
1088
    for ($i = 0; $i < count($dir_to_array); $i++) {
1089
        $only_dir[] = substr($dir_to_array[$i], strlen($base_work_dir), strlen($dir_to_array[$i]));
1090
    }
1091
    $course_id = api_get_course_int_id();
1092
    $group_id  = api_get_group_id();
1093
1094
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
1095
1096
    for($i = 0; $i < count($only_dir); $i++) {
1097
        $url = $only_dir[$i];
1098
1099
        $params = [
1100
            'c_id' => $course_id,
1101
            'url' => $url,
1102
            'title' => '',
1103
            'description' => '',
1104
            'author' => '',
1105
            'active' => '1',
1106
            'accepted' => '1',
1107
            'filetype' => 'folder',
1108
            'post_group_id' => $group_id,
1109
        ];
1110
1111
        Database::insert($work_table, $params);
1112
    }
1113
}
1114
1115
/**
1116
 * This function displays the number of files contained in a directory
1117
 *
1118
 * @param   string the path of the directory
1119
 * @param   boolean true if we want the total quantity of files
1120
 * include in others child directories, false only  files in the directory
1121
 * @return  array the first element is an integer with the number of files
1122
 * in the folder, the second element is the number of directories
1123
 * @author  Julio Montoya
1124
 * @version April 2008
1125
 */
1126
function count_dir($path_dir, $recurse)
1127
{
1128
    $count = 0;
1129
    $count_dir = 0;
1130
    $d = dir($path_dir);
1131
    while ($entry = $d->Read()) {
1132
        if (!(($entry == '..') || ($entry == '.'))) {
1133
            if (is_dir($path_dir.'/'.$entry)) {
1134
                $count_dir++;
1135
                if ($recurse) {
1136
                    $count += count_dir($path_dir . '/' . $entry, $recurse);
1137
                }
1138
            } else {
1139
                $count++;
1140
            }
1141
        }
1142
    }
1143
    $return_array = array();
1144
    $return_array[] = $count;
1145
    $return_array[] = $count_dir;
1146
    return $return_array;
1147
}
1148
1149
/**
1150
 * returns all the javascript that is required for easily
1151
 * validation when you create a work
1152
 * this goes into the $htmlHeadXtra[] array
1153
 */
1154
function to_javascript_work()
1155
{
1156
    $js = '<script>
1157
        function updateDocumentTitle(value) {
1158
            var temp = value.indexOf("/");
1159
            //linux path
1160
            if(temp!=-1){
1161
                var temp=value.split("/");
1162
            } else {
1163
                var temp=value.split("\\\");
1164
            }
1165
            document.getElementById("file_upload").value=temp[temp.length-1];
1166
            $("#contains_file_id").attr("value", 1);
1167
        }
1168
1169
        function checkDate(month, day, year) {
1170
          var monthLength =
1171
            new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1172
1173
          if (!day || !month || !year)
1174
            return false;
1175
1176
          // check for bisestile year
1177
          if (year/4 == parseInt(year/4))
1178
            monthLength[1] = 29;
1179
1180
          if (month < 1 || month > 12)
1181
            return false;
1182
1183
          if (day > monthLength[month-1])
1184
            return false;
1185
1186
          return true;
1187
        }
1188
1189
        function mktime() {
1190
1191
            var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
1192
            d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
1193
1194
            var dateManip = {
1195
                0: function(tt){ return d.setHours(tt); },
1196
                1: function(tt){ return d.setMinutes(tt); },
1197
                2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
1198
                3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
1199
                4: function(tt){ return d.setDate(tt+mb); },
1200
                5: function(tt){ return d.setYear(tt+ma); }
1201
            };
1202
1203
            for( i = 0; i < argc; i++ ){
1204
                no = parseInt(argv[i]*1);
1205
                if (isNaN(no)) {
1206
                    return false;
1207
                } else {
1208
                    // arg is number, lets manipulate date object
1209
                    if(!dateManip[i](no)){
1210
                        // failed
1211
                        return false;
1212
                    }
1213
                }
1214
            }
1215
            return Math.floor(d.getTime()/1000);
1216
        }
1217
1218
        function setFocus() {
1219
            $("#work_title").focus();
1220
        }
1221
1222
        $(document).ready(function() {
1223
            setFocus();
1224
1225
            var checked = $("#expiry_date").attr("checked");
1226
            if (checked) {
1227
                $("#option2").show();
1228
                $("#option3").show();
1229
                $("#end_date").attr("checked", true);
1230
            } else {
1231
                $("#option2").hide();
1232
                $("#option3").hide();
1233
                $("#end_date").attr("checked", false);
1234
            }
1235
1236
            $("#expiry_date").click(function() {
1237
                $("#option2").toggle();
1238
            });
1239
1240
            $("#end_date").click(function() {
1241
                $("#option3").toggle();
1242
            });
1243
        });
1244
    </script>';
1245
1246
    return $js;
1247
}
1248
1249
/**
1250
 * Gets the id of a student publication with a given path
1251
 * @param string $path
1252
 * @return true if is found / false if not found
1253
 */
1254
// TODO: The name of this function does not fit with the kind of information it returns. Maybe check_work_id() or is_work_id()?
1255
function get_work_id($path)
1256
{
1257
    $TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1258
    $TBL_PROP_TABLE = Database::get_course_table(TABLE_ITEM_PROPERTY);
1259
    $course_id = api_get_course_int_id();
1260
    $path = Database::escape_string($path);
1261
1262
    if (api_is_allowed_to_edit()) {
1263
        $sql = "SELECT work.id
1264
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1265
                WHERE
1266
                    props.c_id = $course_id AND
1267
                    work.c_id = $course_id AND
1268
                    props.tool='work' AND
1269
                    work.id=props.ref AND
1270
                    work.url LIKE 'work/".$path."%' AND
1271
                    work.filetype='file' AND
1272
                    props.visibility<>'2'";
1273
    } else {
1274
        $sql = "SELECT work.id
1275
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1276
                WHERE
1277
                    props.c_id = $course_id AND
1278
                    work.c_id = $course_id AND
1279
                    props.tool='work' AND
1280
                    work.id=props.ref AND
1281
                    work.url LIKE 'work/".$path."%' AND
1282
                    work.filetype='file' AND
1283
                    props.visibility<>'2' AND
1284
                    props.lastedit_user_id = '".api_get_user_id()."'";
1285
    }
1286
    $result = Database::query($sql);
1287
    $num_rows = Database::num_rows($result);
1288
1289
    if ($result && $num_rows > 0) {
1290
        return true;
1291
    } else {
1292
        return false;
1293
    }
1294
}
1295
1296
/**
1297
 * @param int $work_id
1298
 * @param int $onlyMeUserId show only my works
1299
 * @param int $notMeUserId show works from everyone except me
1300
 * @return int
1301
 */
1302
function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
1303
{
1304
    $work_table      = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1305
    $iprop_table     = Database::get_course_table(TABLE_ITEM_PROPERTY);
1306
    $user_table      = Database::get_main_table(TABLE_MAIN_USER);
1307
1308
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
1309
    $session_id = api_get_session_id();
1310
    $condition_session = api_get_session_condition($session_id, true, false, 'work.session_id');
1311
1312
    $group_id = api_get_group_id();
1313
    $course_info = api_get_course_info();
1314
    $course_id = $course_info['real_id'];
1315
    $work_id = intval($work_id);
1316
1317 View Code Duplication
    if (!empty($group_id)) {
1318
        // set to select only messages posted by the user's group
1319
        $extra_conditions = " work.post_group_id = '".intval($group_id)."' ";
1320
    } else {
1321
        $extra_conditions = " work.post_group_id = '0' ";
1322
    }
1323
1324 View Code Duplication
    if ($is_allowed_to_edit) {
1325
        $extra_conditions .= ' AND work.active IN (0, 1) ';
1326
    } else {
1327
        $extra_conditions .= ' AND work.active IN (0, 1) AND accepted = 1';
1328
        if (isset($course_info['show_score']) && $course_info['show_score'] == 1) {
1329
            $extra_conditions .= " AND work.user_id = ".api_get_user_id()." ";
1330
        } else {
1331
            $extra_conditions .= '';
1332
        }
1333
    }
1334
1335
    $extra_conditions .= " AND parent_id  = ".$work_id."  ";
1336
1337
    $where_condition = null;
1338
1339
    if (!empty($notMeUserId)) {
1340
        $where_condition .= " AND u.user_id <> ".intval($notMeUserId);
1341
    }
1342
1343
    if (!empty($onlyMeUserId)) {
1344
        $where_condition .= " AND u.user_id =  ".intval($onlyMeUserId);
1345
    }
1346
1347
    $sql = "SELECT count(*) as count
1348
            FROM $iprop_table prop
1349
            INNER JOIN $work_table work
1350
            ON (
1351
                prop.ref = work.id AND
1352
                prop.c_id = $course_id AND
1353
                prop.tool='work' AND
1354
                prop.visibility <> 2 AND
1355
                work.c_id = $course_id
1356
            )
1357
            INNER JOIN $user_table u ON (work.user_id = u.user_id)
1358
            WHERE $extra_conditions $where_condition $condition_session";
1359
1360
    $result = Database::query($sql);
1361
1362
    $users_with_work = 0;
1363
    if (Database::num_rows($result)) {
1364
        $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...
1365
        $users_with_work = $result['count'];
1366
    }
1367
    return $users_with_work;
1368
}
1369
1370
/**
1371
 * @param int $start
1372
 * @param int $limit
1373
 * @param string $column
1374
 * @param string $direction
1375
 * @param string $where_condition
1376
 * @param bool $getCount
1377
 * @return array
1378
 */
1379
function getWorkListStudent(
1380
    $start,
1381
    $limit,
1382
    $column,
1383
    $direction,
1384
    $where_condition,
1385
    $getCount = false
1386
) {
1387
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1388
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1389
    $courseInfo = api_get_course_info();
1390
    $course_id = $courseInfo['real_id'];
1391
    $session_id = api_get_session_id();
1392
    $condition_session = api_get_session_condition($session_id);
1393
    $group_id = api_get_group_id();
1394
    $userId = api_get_user_id();
1395
1396
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1397
        api_get_user_id(),
1398
        $courseInfo
1399
    );
1400
1401
    if (!in_array($direction, array('asc','desc'))) {
1402
        $direction = 'desc';
1403
    }
1404
    if (!empty($where_condition)) {
1405
        $where_condition = ' AND ' . $where_condition;
1406
    }
1407
1408
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1409
    $start = intval($start);
1410
    $limit = intval($limit);
1411
1412
    // Get list from database
1413
1414 View Code Duplication
    if (!empty($group_id)) {
1415
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = '".$group_id."' ";
1416
        $subdirs_query = "AND parent_id = 0";
1417
    } else {
1418
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = '0' ";
1419
        $subdirs_query = "AND parent_id = 0";
1420
    }
1421
1422
    $active_condition = ' AND active IN (1, 0)';
1423
1424
    if ($getCount) {
1425
        $select = "SELECT count(w.id) as count ";
1426
    } else {
1427
        $select = "SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1428
    }
1429
1430
    $sql = "$select
1431
            FROM $workTable w
1432
            LEFT JOIN $workTableAssignment a
1433
            ON (a.publication_id = w.id AND a.c_id = w.c_id)
1434
                $group_query
1435
                $subdirs_query
1436
                $active_condition
1437
                $condition_session
1438
                $where_condition
1439
            ";
1440
1441
    $sql .= " ORDER BY $column $direction ";
1442
1443
    if (!empty($start) && !empty($limit)) {
1444
        $sql .= " LIMIT $start, $limit";
1445
    }
1446
1447
    $result = Database::query($sql);
1448
1449
    if ($getCount) {
1450
        $row = Database::fetch_array($result);
1451
        return $row['count'];
1452
    }
1453
1454
    $works = array();
1455
1456
    $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
1457
    if ($isDrhOfCourse) {
1458
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1459
    }
1460
1461
    $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
1462
    while ($work = Database::fetch_array($result, 'ASSOC')) {
1463
        $isSubscribed = userIsSubscribedToWork($userId, $work['id'], $course_id);
1464
        if ($isSubscribed == false) {
1465
            continue;
1466
        }
1467
1468
        $visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $session_id);
1469
1470
        if ($visibility != 1) {
1471
            continue;
1472
        }
1473
1474
        $work['type'] = Display::return_icon('work.png');
1475
        $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1476
1477
        if (empty($work['title'])) {
1478
            $work['title'] = basename($work['url']);
1479
        }
1480
1481
        $whereCondition = " AND u.user_id = ".intval($userId);
1482
1483
        $workList = get_work_user_list(
1484
            0,
1485
            1000,
1486
            null,
1487
            null,
1488
            $work['id'],
1489
            $whereCondition
1490
        );
1491
1492
        $count = getTotalWorkComment($workList, $courseInfo);
1493
1494 View Code Duplication
        if (!is_null($count) && !empty($count)) {
1495
            $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info');
1496
        }
1497
1498
        $lastWork = getLastWorkStudentFromParentByUser($userId, $work['id'], $courseInfo);
1499
1500
        if (!empty($lastWork)) {
1501
            $work['last_upload'] = (!empty($lastWork['qualification'])) ? Display::label($lastWork['qualification'], 'warning').' - ' : '';
1502
            $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1503
        }
1504
1505
1506
        $work['title'] = Display::url($work['title'], $url.'&id='.$work['id']);
1507
        $work['others'] = Display::url(
1508
            Display::return_icon('group.png', get_lang('Others')),
1509
            $urlOthers.$work['id']
1510
        );
1511
        $works[] = $work;
1512
    }
1513
1514
    return $works;
1515
}
1516
1517
/**
1518
 * @param int $start
1519
 * @param int $limit
1520
 * @param string $column
1521
 * @param string $direction
1522
 * @param string $where_condition
1523
 * @param bool $getCount
1524
 * @return array
1525
 */
1526
function getWorkListTeacher(
1527
    $start,
1528
    $limit,
1529
    $column,
1530
    $direction,
1531
    $where_condition,
1532
    $getCount = false
1533
) {
1534
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1535
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1536
1537
    $courseInfo = api_get_course_info();
1538
    $course_id = api_get_course_int_id();
1539
    $session_id = api_get_session_id();
1540
    $condition_session = api_get_session_condition($session_id);
1541
    $group_id = api_get_group_id();
1542
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1543
1544
    if (!in_array($direction, array('asc', 'desc'))) {
1545
        $direction = 'desc';
1546
    }
1547
    if (!empty($where_condition)) {
1548
        $where_condition = ' AND ' . $where_condition;
1549
    }
1550
1551
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1552
    $start = intval($start);
1553
    $limit = intval($limit);
1554
    $works = array();
1555
1556
    // Get list from database
1557
    if ($is_allowed_to_edit) {
1558
        $active_condition = ' active IN (0, 1)';
1559
        if ($getCount) {
1560
            $select = " SELECT count(w.id) as count";
1561
        } else {
1562
            $select = " SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ";
1563
        }
1564
        $sql = " $select
1565
                FROM $workTable w
1566
                LEFT JOIN $workTableAssignment a
1567
                ON (a.publication_id = w.id AND a.c_id = w.c_id)
1568
                WHERE
1569
                    w.c_id = $course_id
1570
                    $condition_session AND
1571
                    $active_condition AND
1572
                    (parent_id = 0) AND
1573
                    post_group_id = '".$group_id."'
1574
                    $where_condition
1575
                ORDER BY $column $direction
1576
                LIMIT $start, $limit";
1577
        $result = Database::query($sql);
1578
1579
        if ($getCount) {
1580
            $row = Database::fetch_array($result);
1581
1582
            return $row['count'];
1583
        }
1584
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1585
        while ($work = Database::fetch_array($result, 'ASSOC')) {
1586
            $workId = $work['id'];
1587
            $work['type'] = Display::return_icon('work.png');
1588
            $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1589
1590
            $totalUsers = getStudentSubscribedToWork(
1591
                $workId,
1592
                $course_id,
1593
                $group_id,
1594
                $session_id,
1595
                true
1596
            );
1597
1598
            $countUniqueAttempts = getUniqueStudentAttemptsTotal(
1599
                $workId,
1600
                $group_id,
1601
                $course_id,
1602
                $session_id
1603
            );
1604
1605
            $work['amount'] = Display::label(
1606
                $countUniqueAttempts . '/' .
1607
                $totalUsers,
1608
                'success'
1609
            );
1610
1611
            $visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1612
1613
            if ($visibility == 1) {
1614
                $icon = 'visible.png';
1615
                $text = get_lang('Visible');
1616
                $action = 'invisible';
1617
                $class = '';
1618
            } else {
1619
                $icon = 'invisible.png';
1620
                $text = get_lang('Invisible');
1621
                $action = 'visible';
1622
                $class = 'muted';
1623
            }
1624
1625
            $visibilityLink = Display::url(
1626
                Display::return_icon($icon, $text, array(), ICON_SIZE_SMALL),
1627
                api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action='.$action.'&'.api_get_cidreq()
1628
            );
1629
1630
            if (empty($work['title'])) {
1631
                $work['title'] = basename($work['url']);
1632
            }
1633
            $work['title'] = Display::url($work['title'], $url.'&id='.$workId, ['class' => $class]);
1634
            $work['title'] .= ' '.Display::label(get_count_work($work['id']), 'success');
1635
            $work['sent_date'] = api_get_local_time($work['sent_date']);
1636
1637
            $editLink = Display::url(
1638
                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL),
1639
                api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq()
1640
            );
1641
1642
            $correctionLink = Display::url(
1643
                Display::return_icon('upload_file.png', get_lang('UploadCorrections'), '', ICON_SIZE_SMALL),
1644
                api_get_path(WEB_CODE_PATH).'work/upload_corrections.php?'.api_get_cidreq().'&id='.$workId
1645
            );
1646
1647
            if ($countUniqueAttempts > 0) {
1648
                $downloadLink = Display::url(
1649
                    Display::return_icon(
1650
                        'save_pack.png',
1651
                        get_lang('Save'),
1652
                        array(),
1653
                        ICON_SIZE_SMALL
1654
                    ),
1655
                    api_get_path(WEB_CODE_PATH) . 'work/downloadfolder.inc.php?id=' . $workId . '&' . api_get_cidreq()
1656
                );
1657
            } else {
1658
                $downloadLink = Display::url(
1659
                    Display::return_icon(
1660
                        'save_pack_na.png',
1661
                        get_lang('Save'),
1662
                        array(),
1663
                        ICON_SIZE_SMALL
1664
                    ),
1665
                    '#'
1666
                );
1667
            }
1668
            // Remove Delete Work Button from action List
1669
            // Because removeXSS "removes" the onClick JS Event to do the action (See model.ajax.php - Line 1639)
1670
            // But still can use the another jqgrid button to remove works (trash icon)
1671
            //
1672
            // $deleteUrl = api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action=delete_dir&'.api_get_cidreq();
1673
            // $deleteLink = '<a href="#" onclick="showConfirmationPopup(this, \'' . $deleteUrl . '\' ) " >' .
1674
            //     Display::return_icon(
1675
            //         'delete.png',
1676
            //         get_lang('Delete'),
1677
            //         array(),
1678
            //         ICON_SIZE_SMALL
1679
            //     ) . '</a>';
1680
1681
            if (!api_is_allowed_to_edit()) {
1682
                // $deleteLink = null;
1683
                $editLink = null;
1684
            }
1685
            $work['actions'] = $visibilityLink.$correctionLink.$downloadLink.$editLink;
1686
            $works[] = $work;
1687
        }
1688
    }
1689
1690
    return $works;
1691
}
1692
1693
/**
1694
 * @param int $start
1695
 * @param int $limit
1696
 * @param string $column
1697
 * @param string $direction
1698
 * @param int $workId
1699
 * @param int $studentId
1700
 * @param string $whereCondition
1701
 * @param bool $getCount
1702
 * @return array
1703
 */
1704
function get_work_user_list_from_documents(
1705
    $start,
1706
    $limit,
1707
    $column,
1708
    $direction,
1709
    $workId,
1710
    $studentId = null,
1711
    $whereCondition,
1712
    $getCount = false
1713
) {
1714
    if ($getCount) {
1715
        $select1 = " SELECT count(u.user_id) as count ";
1716
        $select2 = " SELECT count(u.user_id) as count ";
1717
    } else {
1718
        $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";
1719
        $select2 = " SELECT DISTINCT u.firstname, u.lastname, u.user_id, d.title, w.parent_id, d.id document_id, 0, 0, 0";
1720
    }
1721
1722
    $documentTable = Database::get_course_table(TABLE_DOCUMENT);
1723
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1724
    $workRelDocument = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
1725
    $userTable = Database::get_main_table(TABLE_MAIN_USER);
1726
1727
    $courseId = api_get_course_int_id();
1728
    $sessionId = api_get_session_id();
1729
1730
    if (empty($studentId)) {
1731
        $studentId = api_get_user_id();
1732
    }
1733
    $studentId = intval($studentId);
1734
    $workId = intval($workId);
1735
1736
    $userCondition = " AND u.user_id = $studentId ";
1737
    $sessionCondition = " AND w.session_id = $sessionId ";
1738
    $workCondition = " AND w_rel.work_id = $workId";
1739
    $workParentCondition  = " AND w.parent_id = $workId";
1740
1741
    $sql = "(
1742
                $select1 FROM $userTable u
1743
                INNER JOIN $workTable w
1744
                ON (u.user_id = w.user_id AND w.active IN (0, 1) AND w.filetype = 'file')
1745
                WHERE
1746
                    w.c_id = $courseId
1747
                    $userCondition
1748
                    $sessionCondition
1749
                    $whereCondition
1750
                    $workParentCondition
1751
            ) UNION (
1752
                $select2 FROM $workTable w
1753
                INNER JOIN $workRelDocument w_rel
1754
                ON (w_rel.work_id = w.id AND w.active IN (0, 1) AND w_rel.c_id = w.c_id)
1755
                INNER JOIN $documentTable d
1756
                ON (w_rel.document_id = d.id AND d.c_id = w.c_id)
1757
                INNER JOIN $userTable u ON (u.user_id = $studentId)
1758
                WHERE
1759
                    w.c_id = $courseId
1760
                    $workCondition
1761
                    $sessionCondition AND
1762
                    d.id NOT IN (
1763
                        SELECT w.document_id id
1764
                        FROM $workTable w
1765
                        WHERE
1766
                            user_id = $studentId AND
1767
                            c_id = $courseId AND
1768
                            filetype = 'file' AND
1769
                            active IN (0, 1)
1770
                            $sessionCondition
1771
                            $workParentCondition
1772
                    )
1773
            )";
1774
1775
    $start = intval($start);
1776
    $limit = intval($limit);
1777
1778
    $direction = in_array(strtolower($direction), array('desc', 'asc')) ? $direction : 'desc';
1779
    $column = Database::escape_string($column);
1780
1781 View Code Duplication
    if ($getCount) {
1782
        $result = Database::query($sql);
1783
        $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...
1784
        return $result['count'];
1785
    }
1786
1787
    $sql .= " ORDER BY $column $direction";
1788
    $sql .= " LIMIT $start, $limit";
1789
1790
    $result = Database::query($sql);
1791
1792
    $currentUserId = api_get_user_id();
1793
    $work_data = get_work_data_by_id($workId);
1794
1795
    $qualificationExists = false;
1796
1797 View Code Duplication
    if (!empty($work_data['qualification']) && intval($work_data['qualification']) > 0) {
1798
        $qualificationExists = true;
1799
    }
1800
1801
    $urlAdd = api_get_path(WEB_CODE_PATH).'work/upload_from_template.php?'.api_get_cidreq();
1802
    $urlEdit = api_get_path(WEB_CODE_PATH).'work/edit.php?'.api_get_cidreq();
1803
    $urlDelete = api_get_path(WEB_CODE_PATH).'work/work_list.php?action=delete&'.api_get_cidreq();
1804
    $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq();
1805
1806
    $editIcon = Display::return_icon('edit.png', get_lang('Edit'));
1807
    $addIcon = Display::return_icon('add.png', get_lang('Add'));
1808
    $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'));
1809
    $viewIcon = Display::return_icon('default.png', get_lang('View'));
1810
    $allowEdition = api_get_course_setting('student_delete_own_publication');
1811
1812
    $workList = array();
1813
    while ($row = Database::fetch_array($result, 'ASSOC')) {
1814
        $userId = $row['user_id'];
1815
        $documentId = $row['document_id'];
1816
        $itemId = $row['id'];
1817
        $addLinkShowed = false;
1818
1819
        if (empty($documentId)) {
1820
            $url = $urlEdit.'&item_id='.$row['id'].'&id='.$workId;
1821
            $editLink = Display::url($editIcon, $url);
1822
            if ($allowEdition == false) {
1823
                $editLink = null;
1824
            }
1825
        } else {
1826
            $documentToWork = getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId);
1827
1828
            if (empty($documentToWork)) {
1829
                $url = $urlAdd.'&document_id='.$documentId.'&id='.$workId;
1830
                $editLink = Display::url($addIcon, $url);
1831
                $addLinkShowed = true;
1832
            } else {
1833
1834
                $row['title'] = $documentToWork['title'];
1835
                $row['sent_date'] = $documentToWork['sent_date'];
1836
                $newWorkId = $documentToWork['id'];
1837
                $url = $urlEdit.'&item_id='.$newWorkId.'&id='.$workId;
1838
                $editLink = Display::url($editIcon, $url);
1839
1840
                if ($allowEdition == false) {
1841
                    $editLink = null;
1842
                }
1843
            }
1844
        }
1845
1846
        if ($allowEdition && !empty($itemId)) {
1847
            $deleteLink  = Display::url($deleteIcon, $urlDelete.'&item_id='.$itemId.'&id='.$workId);
1848
        } else {
1849
            $deleteLink = null;
1850
        }
1851
1852
        $viewLink = null;
1853
1854
        if (!empty($itemId)) {
1855
            $viewLink = Display::url($viewIcon, $urlView.'&id='.$itemId);
1856
        }
1857
1858
        //$row['type'] = build_document_icon_tag('file', $row['url']);
1859
        $row['type'] = null;
1860
1861
        if ($qualificationExists) {
1862 View Code Duplication
            if (empty($row['qualificator_id'])) {
1863
                $status = Display::label(get_lang('NotRevised'), 'warning');
1864
            } else {
1865
                $status = Display::label(get_lang('Revised'), 'success');
1866
            }
1867
            $row['qualificator_id'] = $status;
1868
        }
1869
1870
        if (!empty($row['qualification'])) {
1871
            $row['qualification'] = Display::label($row['qualification'], 'info');
1872
        }
1873
1874
        if (!empty($row['sent_date'])) {
1875
            $row['sent_date'] = api_get_local_time($row['sent_date']);
1876
        }
1877
1878
        if ($userId == $currentUserId) {
1879
            $row['actions'] = $viewLink.$editLink.$deleteLink;
1880
        }
1881
1882
        if ($addLinkShowed) {
1883
            $row['qualification'] = '';
1884
            $row['qualificator_id'] = '';
1885
        }
1886
1887
        $workList[] = $row;
1888
    }
1889
1890
    return $workList;
1891
}
1892
1893
/**
1894
 * @param int $start
1895
 * @param int $limit
1896
 * @param int $column
1897
 * @param string $direction
1898
 * @param int $work_id
1899
 * @param array $where_condition
1900
 * @param int $studentId
1901
 * @param bool $getCount
1902
 * @param int $courseId
1903
 * @param int $sessionId
1904
 * @return array
1905
 */
1906
function get_work_user_list(
1907
    $start,
1908
    $limit,
1909
    $column,
1910
    $direction,
1911
    $work_id,
1912
    $where_condition = null,
1913
    $studentId = null,
1914
    $getCount = false,
1915
    $courseId = 0,
1916
    $sessionId = 0
1917
) {
1918
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1919
    $iprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1920
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1921
1922
    $session_id = $sessionId ? $sessionId : api_get_session_id();
1923
    $group_id = api_get_group_id();
1924
    $course_info = api_get_course_info();
1925
    $course_info = empty($course_info) ? api_get_course_info_by_id($courseId) : $course_info;
1926
    $course_id = isset($course_info['real_id']) ? $course_info['real_id'] : $courseId;
1927
1928
    $work_id = intval($work_id);
1929
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1930
    $start = intval($start);
1931
    $limit = intval($limit);
1932
1933
    if (!in_array($direction, array('asc','desc'))) {
1934
        $direction = 'desc';
1935
    }
1936
1937
    $work_data = get_work_data_by_id($work_id, $courseId, $sessionId);
1938
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1939
    $condition_session  = api_get_session_condition($session_id, true, false, 'work.session_id');
1940
    $locked = api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION, $course_info['code']);
1941
1942
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
1943
        api_get_user_id(),
1944
        $course_info
1945
    );
1946
1947
    if (!empty($work_data)) {
1948 View Code Duplication
        if (!empty($group_id)) {
1949
            $extra_conditions = " work.post_group_id = '".intval($group_id)."' ";
1950
            // set to select only messages posted by the user's group
1951
        } else {
1952
            $extra_conditions = " work.post_group_id = '0' ";
1953
        }
1954
1955 View Code Duplication
        if ($is_allowed_to_edit || $isDrhOfCourse) {
1956
            $extra_conditions .= ' AND work.active IN (0, 1) ';
1957
        } else {
1958
            if (isset($course_info['show_score']) &&
1959
                $course_info['show_score'] == 1
1960
            ) {
1961
                $extra_conditions .= " AND (u.user_id = ".api_get_user_id()." AND work.active IN (0, 1)) ";
1962
            } else {
1963
                $extra_conditions .= ' AND work.active IN (0, 1) ';
1964
            }
1965
        }
1966
1967
        $extra_conditions .= " AND parent_id  = ".$work_id." ";
1968
1969
        $select = 'SELECT DISTINCT
1970
                        u.user_id,
1971
                        work.id as id,
1972
                        title as title,
1973
                        description,
1974
                        url,
1975
                        sent_date,
1976
                        contains_file,
1977
                        has_properties,
1978
                        view_properties,
1979
                        qualification,
1980
                        weight,
1981
                        allow_text_assignment,
1982
                        u.firstname,
1983
                        u.lastname,
1984
                        u.username,
1985
                        parent_id,
1986
                        accepted,
1987
                        qualificator_id,
1988
                        url_correction
1989
                        ';
1990
        if ($getCount) {
1991
            $select = "SELECT DISTINCT count(u.user_id) as count ";
1992
        }
1993
1994
        $user_condition = "INNER JOIN $user_table u  ON (work.user_id = u.user_id) ";
1995
        $work_condition = "$iprop_table prop INNER JOIN $work_table work
1996
                           ON (prop.ref = work.id AND prop.c_id = $course_id AND work.c_id = $course_id ) ";
1997
        $work_assignment = get_work_assignment_by_id($work_id, $courseId);
1998
1999
        if (!empty($studentId)) {
2000
            $where_condition.= " AND u.user_id = ".intval($studentId);
2001
        }
2002
2003
        $sql = " $select
2004
                FROM $work_condition  $user_condition
2005
                WHERE $extra_conditions $where_condition $condition_session
2006
                    AND u.status != " . INVITEE . "
2007
                ORDER BY $column $direction";
2008
2009
        if (!empty($start) && !empty($limit)) {
2010
            $sql .= " LIMIT $start, $limit";
2011
        }
2012
        $result = Database::query($sql);
2013
        $works = array();
2014
2015
        if ($getCount) {
2016
            $work = Database::fetch_array($result, 'ASSOC');
2017
            return $work['count'];
2018
        }
2019
2020
        $url = api_get_path(WEB_CODE_PATH).'work/';
2021
2022
        $unoconv = api_get_configuration_value('unoconv.binaries');
2023
2024
        while ($work = Database::fetch_array($result, 'ASSOC')) {
2025
            $item_id = $work['id'];
2026
2027
            // Get the author ID for that document from the item_property table
2028
            $is_author  = false;
2029
            $can_read   = false;
2030
2031
            $owner_id = $work['user_id'];
2032
2033
            /* Because a bug found when saving items using the api_item_property_update()
2034
               the field $item_property_data['insert_user_id'] is not reliable. */
2035
2036
            if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
2037
                $is_author = true;
2038
            }
2039
2040
            if ($course_info['show_score'] == 0) {
2041
                $can_read = true;
2042
            }
2043
2044
            if ($work['accepted'] == '0') {
2045
                $class = 'invisible';
2046
            } else {
2047
                $class = '';
2048
            }
2049
2050
            $qualification_exists = false;
2051 View Code Duplication
            if (!empty($work_data['qualification']) &&
2052
                intval($work_data['qualification']) > 0
2053
            ) {
2054
                $qualification_exists = true;
2055
            }
2056
2057
            $qualification_string = '';
2058
            if ($qualification_exists) {
2059
                if ($work['qualification'] == '') {
2060
                    $qualification_string = Display::label('-');
2061
                } else {
2062
                    $label = 'info';
2063
                    $relativeScore = $work['qualification']/$work_data['qualification'];
2064
                    if ($relativeScore < 0.5) {
2065
                        $label = 'important';
2066
                    } elseif ($relativeScore < 0.75) {
2067
                        $label = 'warning';
2068
                    }
2069
                    $qualification_string = Display::label(
2070
                        $work['qualification'].' / '.$work_data['qualification'],
2071
                        $label
2072
                    );
2073
                }
2074
            }
2075
2076
            $work['qualification_score'] = $work['qualification'];
2077
2078
            $add_string = '';
2079
2080
            $time_expires = '';
2081
            if (!empty($work_assignment['expires_on'])) {
2082
                $time_expires = api_strtotime(
2083
                    $work_assignment['expires_on'],
2084
                    'UTC'
2085
                );
2086
            }
2087
2088
            if (!empty($work_assignment['expires_on']) &&
2089
                !empty($time_expires) && ($time_expires < api_strtotime($work['sent_date'], 'UTC'))) {
2090
                $add_string = Display::label(get_lang('Expired'), 'important');
2091
            }
2092
2093
            if (($can_read && $work['accepted'] == '1') ||
2094
                ($is_author && in_array($work['accepted'], array('1', '0'))) ||
2095
                ($is_allowed_to_edit || api_is_drh())
2096
            ) {
2097
                // Firstname, lastname, username
2098
                $work['firstname'] = Display::div($work['firstname'], array('class' => $class));
2099
                $work['lastname'] = Display::div($work['lastname'], array('class' => $class));
2100
2101
                $work['title_clean'] = $work['title'];
2102
2103
                if (strlen($work['title']) > 30) {
2104
                    $short_title = substr($work['title'], 0, 27).'...';
2105
                    $work['title'] = Display::span($short_title, array('class' => $class, 'title' => $work['title']));
2106
                } else {
2107
                    $work['title'] = Display::div($work['title'], array('class' => $class));
2108
                }
2109
2110
                // Type.
2111
                $work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
2112
2113
                // File name.
2114
                $link_to_download = null;
2115
2116
                // If URL is present then there's a file to download keep BC.
2117 View Code Duplication
                if ($work['contains_file'] || !empty($work['url'])) {
2118
                    $link_to_download = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.
2119
                        Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
2120
                }
2121
2122
                $send_to = Portfolio::share('work', $work['id'],  array('style' => 'white-space:nowrap;'));
2123
2124
                $feedback = null;
2125
                $count = getWorkCommentCount($item_id, $course_info);
2126
                if (!is_null($count) && !empty($count)) {
2127
                    if ($qualification_exists) {
2128
                        $feedback .= "<br />";
2129
                    }
2130
                    $feedback .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2131
                        Display::label($count.' '.get_lang('Feedback'), 'info').'</a> ';
2132
                }
2133
2134
                $work['qualification'] = $qualification_string.$feedback;
2135
                $work['qualification_only'] = $qualification_string;
2136
2137
                // Date.
2138
                $work_date = api_convert_and_format_date($work['sent_date']);
2139
                $date = date_to_str_ago($work['sent_date']). ' ' . $work_date;
2140
                $work['formatted_date'] = $work_date . ' - ' . $add_string;
2141
2142
                $work['sent_date_from_db'] = $work['sent_date'];
2143
                $work['sent_date'] = '<div class="work-date" title="'.$date.'">' . $add_string . ' - ' . $work['sent_date'] . '</div>';
2144
2145
                // Actions.
2146
                $correction = '';
2147
2148
                $action = '';
2149
                if (api_is_allowed_to_edit()) {
2150
                    if (!empty($work['url_correction'])) {
2151
                        $action .= Display::url(
2152
                            Display::return_icon('check-circle.png', get_lang('Correction'), null, ICON_SIZE_SMALL),
2153
                            api_get_path(WEB_CODE_PATH).'work/download.php?id='.$item_id.'&'.api_get_cidreq().'&correction=1'
2154
                        );
2155
                    }
2156
2157
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2158
                        Display::return_icon('default.png', get_lang('View'), array(), ICON_SIZE_SMALL).'</a> ';
2159
2160
                    if ($unoconv && empty($work['contains_file'])) {
2161
                        $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').'" >'.
2162
                            Display::return_icon('export_doc.png', get_lang('ExportToDoc'),array(), ICON_SIZE_SMALL).'</a> ';
2163
                    }
2164
2165
                    $correction = '
2166
                        <form
2167
                            id="file_upload_'.$item_id.'"
2168
                            class="work_correction_file_upload file_upload_small fileinput-button"
2169
                            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"                            
2170
                        >
2171
                        <div id="progress_'.$item_id.'" class="text-center button-load">
2172
                            '.addslashes(get_lang('ClickOrDropOneFileHere')).'
2173
                            '.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
2174
                        </div>
2175
                        <input id="file_'.$item_id.'" type="file" name="file" multiple>                        
2176
                        </form>
2177
                    ';
2178
2179
                    $loadingText = addslashes(get_lang('Loading'));
2180
                    $uploadedText = addslashes(get_lang('Uploaded'));
2181
                    $failsUploadText = addslashes(get_lang('UplNoFileUploaded'));
2182
                    $failsUploadIcon = Display::return_icon('closed-circle.png', '', [], ICON_SIZE_TINY);
2183
2184
                    $correction .= "<script>
2185
                        $(document).ready(function() {
2186
                            $('.work_correction_file_upload').each(function () {
2187
                                $(this).fileupload({
2188
                                    dropZone: $(this)
2189
                                });
2190
                            });
2191
                            $('#file_upload_".$item_id."').fileupload({
2192
                                add: function (e, data) {
2193
                                    $('#progress_$item_id').html();
2194
                                    //$('#file_$item_id').remove();
2195
                                    console.log('#file_upload_".$item_id."');
2196
                                    data.context = $('#progress_$item_id').html('$loadingText <br /> <em class=\"fa fa-spinner fa-pulse fa-fw\"></em>');
2197
                                    data.submit();
2198
                                },
2199
                                done: function (e, data) {
2200
                                    if (data._response.result.name) {
2201
                                        $('#progress_$item_id').html('$uploadedText '+data._response.result.result+'<br />'+data._response.result.name);
2202
                                    } else {
2203
                                        $('#progress_$item_id').html('$failsUploadText $failsUploadIcon');
2204
                                    }
2205
                                }
2206
                            });
2207
                        });
2208
                    </script>";
2209
2210
                    if ($locked) {
2211
                        if ($qualification_exists) {
2212
                            $action .= Display::return_icon('rate_work_na.png', get_lang('CorrectAndRate'),array(), ICON_SIZE_SMALL);
2213
                        } else {
2214
                            $action .= Display::return_icon('edit_na.png', get_lang('Comment'),array(), ICON_SIZE_SMALL);
2215
                        }
2216 View Code Duplication
                    } else {
2217
                        if ($qualification_exists) {
2218
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Edit').'"  >'.
2219
                                Display::return_icon('rate_work.png', get_lang('CorrectAndRate'), array(), ICON_SIZE_SMALL).'</a>';
2220
                        } else {
2221
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2222
                                Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
2223
                        }
2224
                    }
2225
2226 View Code Duplication
                    if ($work['contains_file']) {
2227
                        if ($locked) {
2228
                            $action .= Display::return_icon('move_na.png', get_lang('Move'),array(), ICON_SIZE_SMALL);
2229
                        } else {
2230
                            $action .= '<a href="'.$url.'work.php?'.api_get_cidreq().'&action=move&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Move').'">'.
2231
                                Display::return_icon('move.png', get_lang('Move'),array(), ICON_SIZE_SMALL).'</a>';
2232
                        }
2233
                    }
2234
2235 View Code Duplication
                    if ($work['accepted'] == '1') {
2236
                        $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').'" >'.
2237
                            Display::return_icon('visible.png', get_lang('Invisible'),array(), ICON_SIZE_SMALL).'</a>';
2238
                    } else {
2239
                        $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').'" >'.
2240
                            Display::return_icon('invisible.png', get_lang('Visible'),array(), ICON_SIZE_SMALL).'</a> ';
2241
                    }
2242
2243
                    if ($locked) {
2244
                        $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2245
                    } else {
2246
                        $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').'" >'.
2247
                            Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2248
                    }
2249
                } elseif ($is_author && (empty($work['qualificator_id']) || $work['qualificator_id'] == 0)) {
2250
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2251
                        Display::return_icon('default.png', get_lang('View'),array(), ICON_SIZE_SMALL).'</a>';
2252
2253
                    if (api_get_course_setting('student_delete_own_publication') == 1) {
2254 View Code Duplication
                        if (api_is_allowed_to_session_edit(false, true)) {
2255
                            $action .= '<a href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
2256
                                Display::return_icon('edit.png', get_lang('Comment'),array(), ICON_SIZE_SMALL).'</a>';
2257
                        }
2258
                        $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').'"  >'.
2259
                            Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
2260
                    } else {
2261
                        $action .= Display::return_icon('edit_na.png', get_lang('Modify'),array(), ICON_SIZE_SMALL);
2262
                    }
2263
                } else {
2264
                    $action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2265
                        Display::return_icon('default.png', get_lang('View'),array(), ICON_SIZE_SMALL).'</a>';
2266
                    $action .= Display::return_icon('edit_na.png', get_lang('Modify'),array(), ICON_SIZE_SMALL);
2267
                }
2268
2269
                // Status.
2270 View Code Duplication
                if (empty($work['qualificator_id'])) {
2271
                    $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
2272
                } else {
2273
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2274
                }
2275
                $work['qualificator_id'] = $qualificator_id;
2276
                $work['actions'] = $send_to.$link_to_download.$action;
2277
                $work['correction'] = $correction;
2278
2279
                $works[] = $work;
2280
            }
2281
        }
2282
2283
        return $works;
2284
    }
2285
}
2286
2287
/**
2288
 * Send reminder to users who have not given the task
2289
 *
2290
 * @param int
2291
 * @return array
2292
 * @author cvargas [email protected] cfasanando, [email protected]
2293
 */
2294
function send_reminder_users_without_publication($task_data)
2295
{
2296
    $_course = api_get_course_info();
2297
    $task_id = $task_data['id'];
2298
    $task_title = !empty($task_data['title']) ? $task_data['title'] : basename($task_data['url']);
2299
    $subject = '[' . api_get_setting('siteName') . '] ';
2300
2301
    // The body can be as long as you wish, and any combination of text and variables
2302
    $content = get_lang('ReminderToSubmitPendingTask')."\n".get_lang('CourseName').' : '.$_course['name']."\n";
2303
    $content .= get_lang('WorkName').' : '.$task_title."\n";
2304
2305
    $list_users = get_list_users_without_publication($task_id);
2306
2307
    $mails_sent_to = array();
2308
    foreach ($list_users as $user) {
2309
        $name_user = api_get_person_name($user[1], $user[0], null, PERSON_NAME_EMAIL_ADDRESS);
2310
        $dear_line = get_lang('Dear')." ".api_get_person_name($user[1], $user[0]) .", \n\n";
2311
        $body      = $dear_line.$content;
2312
        MessageManager::send_message($user[3], $subject, $body);
2313
        $mails_sent_to[] = $name_user;
2314
    }
2315
    return $mails_sent_to;
2316
}
2317
2318
/**
2319
 * Sends an email to the students of a course when a homework is created
2320
 *
2321
 * @param int $courseId course_id
2322
 * @param int $sessionId session_id
2323
 * @param int $workId work_id
2324
 *
2325
 *
2326
 * @author Guillaume Viguier <[email protected]>
2327
 * @author Julio Montoya <[email protected]> Adding session support - 2011
2328
 */
2329
function send_email_on_homework_creation($courseId, $sessionId = 0, $workId)
2330
{
2331
    $courseInfo = api_get_course_info_by_id($courseId);
2332
    $courseCode = $courseInfo['code'];
2333
    // Get the students of the course
2334 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...
2335
        $students = CourseManager::get_student_list_from_course_code($courseCode);
2336
    } else {
2337
        $students = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionId);
2338
    }
2339
    $emailsubject = '[' . api_get_setting('siteName') . '] '.get_lang('HomeworkCreated');
2340
    $currentUser = api_get_user_info(api_get_user_id());
2341
    if (!empty($students)) {
2342
        foreach($students as $student) {
2343
            $user_info = api_get_user_info($student["user_id"]);
2344
            if(!empty($user_info["mail"])) {
2345
                $name_user = api_get_person_name(
2346
                    $user_info["firstname"],
2347
                    $user_info["lastname"],
2348
                    null,
2349
                    PERSON_NAME_EMAIL_ADDRESS
2350
                );
2351
                $link = api_get_path(WEB_CODE_PATH) . 'work/work_list_all.php?' . api_get_cidreq() . '&id=' . $workId;
2352
                $emailbody = get_lang('Dear')." ".$name_user.",\n\n";
2353
                $emailbody .= get_lang('HomeworkHasBeenCreatedForTheCourse')." ".$courseCode.". "."\n\n".
2354
                    '<a href="'. $link . '">' . get_lang('PleaseCheckHomeworkPage') . '</a>';
2355
                $emailbody .= "\n\n".api_get_person_name($currentUser["firstname"], $currentUser["lastname"]);
2356
2357
                $additionalParameters = array(
2358
                    'smsType' => SmsPlugin::ASSIGNMENT_BEEN_CREATED_COURSE,
2359
                    'userId' => $student["user_id"],
2360
                    'courseTitle' => $courseCode,
2361
                    'link' => $link
2362
                );
2363
2364
                api_mail_html(
2365
                    $name_user,
2366
                    $user_info["mail"],
2367
                    $emailsubject,
2368
                    $emailbody,
2369
                    api_get_person_name(
2370
                        $currentUser["firstname"],
2371
                        $currentUser["lastname"],
2372
                        null,
2373
                        PERSON_NAME_EMAIL_ADDRESS
2374
                    ),
2375
                    $currentUser["mail"],
2376
                    null,
2377
                    null,
2378
                    null,
2379
                    $additionalParameters
2380
                );
2381
            }
2382
        }
2383
    }
2384
}
2385
2386
/**
2387
 * @param string $url
2388
 * @return bool
2389
 */
2390
function is_work_exist_by_url($url)
2391
{
2392
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2393
    $url = Database::escape_string($url);
2394
    $sql = "SELECT id FROM $work_table WHERE url='$url'";
2395
    $result = Database::query($sql);
2396
    if (Database::num_rows($result)> 0) {
2397
        $row = Database::fetch_row($result);
2398
        if (empty($row)) {
2399
            return false;
2400
        } else {
2401
            return true;
2402
        }
2403
    } else {
2404
        return false;
2405
    }
2406
}
2407
2408
/**
2409
 * @param $name
2410
 * @param $values
2411
 * @param string $checked
2412
 * @return string
2413
 */
2414 View Code Duplication
function make_select($name, $values, $checked = '')
2415
{
2416
    $output = '<select name="'.$name.'" id="'.$name.'">';
2417
    foreach ($values as $key => $value) {
2418
        $output .= '<option value="'.$key.'" '.(($checked==$key) ? 'selected="selected"' : '').'>'.$value.'</option>';
2419
    }
2420
    $output .= '</select>';
2421
    return $output;
2422
}
2423
2424
/**
2425
 * @param $name
2426
 * @param string $checked
2427
 * @param null $label
2428
 * @return string
2429
 */
2430
function make_checkbox($name, $checked = '', $label = null)
2431
{
2432
    $check = '<input id ="'.$name.'" type="checkbox" value="1" name="'.$name.'" '.((!empty($checked))?'checked="checked"':'').'/>';
2433
    if (!empty($label)) {
2434
        $check .="<label for ='$name'>$label</label>";
2435
    }
2436
    return $check;
2437
}
2438
2439
/**
2440
 * @param $prefix
2441
 * @param string $default
2442
 * @return string
2443
 */
2444
function draw_date_picker($prefix, $default = '')
2445
{
2446
    if (empty($default)) {
2447
        $default = api_get_local_time();
2448
    }
2449
    $parts = explode(' ', $default);
2450
    list($d_year, $d_month, $d_day) = explode('-', $parts[0]);
2451
    list($d_hour, $d_minute) = explode(':', $parts[1]);
2452
2453
    $minute = range(10, 59);
2454
    array_unshift($minute, '00', '01', '02', '03', '04', '05', '06', '07', '08', '09');
2455
    $date_form = make_select($prefix.'_day', array_combine(range(1, 31), range(1, 31)), $d_day);
2456
    $date_form .= make_select($prefix.'_month', array_combine(range(1, 12), api_get_months_long()), $d_month);
2457
    $date_form .= make_select($prefix.'_year', array($d_year => $d_year, $d_year + 1 => $d_year + 1), $d_year).'&nbsp;&nbsp;&nbsp;&nbsp;';
2458
    $date_form .= make_select($prefix.'_hour', array_combine(range(0, 23), range(0, 23)), $d_hour).' : ';
2459
    $date_form .= make_select($prefix.'_minute', $minute, $d_minute);
2460
    return $date_form;
2461
}
2462
2463
/**
2464
 * @param string $prefix
2465
 * @param array of values
2466
 * @return string
2467
 *
2468
 */
2469 View Code Duplication
function get_date_from_select($prefix, $array = array())
2470
{
2471
    return
2472
        $array[$prefix]['year'].'-'.
2473
        two_digits($array[$prefix]['month']).'-'.
2474
        two_digits($array[$prefix]['day']).' '.
2475
        two_digits($array[$prefix]['hour']).':'.
2476
        two_digits($array[$prefix]['minute']).':00';
2477
}
2478
2479
/**
2480
 * Check if a user is the author of a work document.
2481
 * @param int $itemId
2482
 * @param int $userId
2483
 * @param int $courseId
2484
 * @param int $sessionId
2485
 * @return bool
2486
 */
2487
function user_is_author($itemId, $userId = null, $courseId = null, $sessionId = null)
2488
{
2489
    if (empty($itemId)) {
2490
        return false;
2491
    }
2492
2493
    if (empty($userId)) {
2494
        $userId = api_get_user_id();
2495
    }
2496
2497
    $isAuthor = false;
2498
    $is_allowed_to_edit = api_is_allowed_to_edit();
2499
2500
    if ($is_allowed_to_edit) {
2501
        $isAuthor = true;
2502
    } else {
2503
2504
        if (empty($courseId)) {
2505
            $courseId = api_get_course_int_id();
2506
        }
2507
        if (empty($sessionId)) {
2508
            $sessionId = api_get_session_id();
2509
        }
2510
2511
        $data = api_get_item_property_info($courseId, 'work', $itemId, $sessionId);
2512
        if ($data['insert_user_id'] == $userId) {
2513
            $isAuthor = true;
2514
        }
2515
2516
        $workData = get_work_data_by_id($itemId);
2517
        if ($workData['user_id'] == $userId) {
2518
            $isAuthor = true;
2519
        }
2520
    }
2521
2522
    if (!$isAuthor) {
2523
        return false;
2524
    }
2525
2526
    return $isAuthor;
2527
}
2528
2529
/**
2530
 * Get list of users who have not given the task
2531
 * @param int
2532
 * @param int
2533
 * @return array
2534
 * @author cvargas
2535
 * @author Julio Montoya <[email protected]> Fixing query
2536
 */
2537
function get_list_users_without_publication($task_id, $studentId = null)
2538
{
2539
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2540
    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2541
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
2542
    $session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2543
2544
    $users = getAllUserToWork($task_id, api_get_course_int_id());
2545
    $users = array_column($users, 'user_id');
2546
2547
    // Condition for the session
2548
    $session_id = api_get_session_id();
2549
    $course_id = api_get_course_int_id();
2550
    $task_id = intval($task_id);
2551
2552
    if ($session_id == 0) {
2553
        $sql = "SELECT user_id as id FROM $work_table
2554
                WHERE
2555
                    c_id = $course_id AND
2556
                    parent_id = '$task_id' AND
2557
                    active IN (0, 1)";
2558
    } else {
2559
        $sql = "SELECT user_id as id FROM $work_table
2560
                WHERE
2561
                    c_id = $course_id AND
2562
                    parent_id = '$task_id' AND
2563
                    session_id = '".$session_id."' AND
2564
                    active IN (0, 1)";
2565
    }
2566
2567
    $result = Database::query($sql);
2568
    $users_with_tasks = array();
2569
    while ($row = Database::fetch_array($result)) {
2570
        $users_with_tasks[] = $row['id'];
2571
    }
2572
2573
    if ($session_id == 0) {
2574
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2575
                      FROM $table_course_user AS cu, $table_user AS u
2576
                      WHERE u.status != 1 and cu.c_id='".$course_id."' AND u.user_id = cu.user_id";
2577
    } else {
2578
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
2579
                      FROM $session_course_rel_user AS cu, $table_user AS u
2580
                      WHERE
2581
                        u.status != 1 AND
2582
                        cu.c_id='".$course_id."' AND
2583
                        u.user_id = cu.user_id AND
2584
                        cu.session_id = '".$session_id."'";
2585
    }
2586
2587
    if (!empty($studentId)) {
2588
        $sql_users.= " AND u.user_id = ".intval($studentId);
2589
    }
2590
2591
    $group_id = api_get_group_id();
2592
2593
    $new_group_user_list = array();
2594
2595
    if ($group_id) {
2596
        $group_user_list = GroupManager::get_subscribed_users($group_id);
2597
        if (!empty($group_user_list)) {
2598
            foreach($group_user_list as $group_user) {
2599
                $new_group_user_list[] = $group_user['user_id'];
2600
            }
2601
        }
2602
    }
2603
2604
    $result_users = Database::query($sql_users);
2605
    $users_without_tasks = array();
2606
    while ($rowUsers = Database::fetch_array($result_users)) {
2607
        $userId = $rowUsers['user_id'];
2608
        if (in_array($userId, $users_with_tasks)) {
2609
            continue;
2610
        }
2611
2612
        if ($group_id && !in_array($userId, $new_group_user_list)) {
2613
            continue;
2614
        }
2615
2616
        if (!empty($users)) {
2617
            if (!in_array($userId, $users)) {
2618
                continue;
2619
            }
2620
        }
2621
2622
        $row_users = [];
2623
        $row_users[0] = $rowUsers['lastname'];
2624
        $row_users[1] = $rowUsers['firstname'];
2625
        $row_users[2] = Display::encrypted_mailto_link($rowUsers['email']);
2626
        $row_users[3] = $userId;
2627
        $users_without_tasks[] = $row_users;
2628
    }
2629
2630
    return $users_without_tasks;
2631
}
2632
2633
/**
2634
 * Display list of users who have not given the task
2635
 *
2636
 * @param int task id
2637
 * @param int $studentId
2638
 * @return array
2639
 * @author cvargas [email protected] cfasanando, [email protected]
2640
 * @author Julio Montoya <[email protected]> Fixes
2641
 */
2642
function display_list_users_without_publication($task_id, $studentId = null)
2643
{
2644
    global $origin;
2645
    $table_header[] = array(get_lang('LastName'), true);
2646
    $table_header[] = array(get_lang('FirstName'), true);
2647
    $table_header[] = array(get_lang('Email'), true);
2648
2649
    $data = get_list_users_without_publication($task_id);
2650
2651
    $sorting_options = array();
2652
    $sorting_options['column'] = 1;
2653
    $paging_options = array();
2654
    $my_params = array();
2655
2656
    if (isset($_GET['edit_dir'])) {
2657
        $my_params['edit_dir'] = Security::remove_XSS($_GET['edit_dir']);
2658
    }
2659
    if (isset($_GET['list'])) {
2660
        $my_params['list'] = Security::remove_XSS($_GET['list']);
2661
    }
2662
    $my_params['origin'] = $origin;
2663
    $my_params['id'] = intval($_GET['id']);
2664
2665
    //$column_show
2666
    $column_show[] = 1;
2667
    $column_show[] = 1;
2668
    $column_show[] = 1;
2669
    Display::display_sortable_config_table(
2670
        'work',
2671
        $table_header,
2672
        $data,
2673
        $sorting_options,
2674
        $paging_options,
2675
        $my_params,
2676
        $column_show
2677
    );
2678
}
2679
2680
/**
2681
 * @param int $documentId
2682
 * @param int $workId
2683
 * @param int $courseId
2684
 */
2685 View Code Duplication
function addDocumentToWork($documentId, $workId, $courseId)
2686
{
2687
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2688
    $params = array(
2689
        'document_id' => $documentId,
2690
        'work_id' => $workId,
2691
        'c_id' => $courseId
2692
    );
2693
    Database::insert($table, $params);
2694
}
2695
2696
/**
2697
 * @param int $documentId
2698
 * @param int $workId
2699
 * @param int $courseId
2700
 * @return array
2701
 */
2702 View Code Duplication
function getDocumentToWork($documentId, $workId, $courseId)
2703
{
2704
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2705
    $params = array(
2706
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2707
    );
2708
    return Database::select('*', $table, array('where' => $params));
2709
}
2710
2711
/**
2712
 * @param int $documentId
2713
 * @param int $workId
2714
 * @param int $courseId
2715
 * @param int $sessionId
2716
 * @param int $userId
2717
 * @param int $active
2718
 * @return array
2719
 */
2720
function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId, $active = 1)
2721
{
2722
    $workRel = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2723
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2724
2725
    $documentId = intval($documentId);
2726
    $workId = intval($workId);
2727
    $courseId = intval($courseId);
2728
    $userId = intval($userId);
2729
    $sessionId = intval($sessionId);
2730
    $active = intval($active);
2731
2732
    $sql = "SELECT w.* FROM $work w INNER JOIN $workRel rel ON (w.parent_id = rel.work_id)
2733
            WHERE
2734
                w.document_id = $documentId AND
2735
                w.parent_id = $workId AND
2736
                w.c_id = $courseId AND
2737
                w.session_id = $sessionId AND
2738
                user_id = $userId AND
2739
                active = $active
2740
            ";
2741
2742
    $result = Database::query($sql);
2743
    $workInfo = array();
2744
    if (Database::num_rows($result)) {
2745
        $workInfo = Database::fetch_array($result, 'ASSOC');
2746
    }
2747
    return $workInfo;
2748
}
2749
2750
/**
2751
 *
2752
 * @param int $workId
2753
 * @param int $courseId
2754
 * @return array
2755
 */
2756 View Code Duplication
function getAllDocumentToWork($workId, $courseId)
2757
{
2758
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2759
    $params = array(
2760
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2761
    );
2762
    return Database::select('*', $table, array('where' => $params));
2763
}
2764
2765
/**
2766
 * @param int $documentId
2767
 * @param int $workId
2768
 * @param int $courseId
2769
 */
2770 View Code Duplication
function deleteDocumentToWork($documentId, $workId, $courseId)
2771
{
2772
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
2773
    $params = array(
2774
        'document_id = ? and work_id = ? and c_id = ?' => array($documentId, $workId, $courseId)
2775
    );
2776
    Database::delete($table, $params);
2777
}
2778
2779
/**
2780
 * @param int $userId
2781
 * @param int $workId
2782
 * @param int $courseId
2783
 */
2784 View Code Duplication
function addUserToWork($userId, $workId, $courseId)
2785
{
2786
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2787
    $params = array(
2788
        'user_id' => $userId,
2789
        'work_id' => $workId,
2790
        'c_id' => $courseId
2791
    );
2792
    Database::insert($table, $params);
2793
}
2794
2795
/**
2796
 * @param int $userId
2797
 * @param int $workId
2798
 * @param int $courseId
2799
 * @return array
2800
 */
2801 View Code Duplication
function getUserToWork($userId, $workId, $courseId)
2802
{
2803
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2804
    $params = array(
2805
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2806
    );
2807
    return Database::select('*', $table, array('where' => $params));
2808
}
2809
2810
/**
2811
 * @param int $workId
2812
 * @param int $courseId
2813
 * @param bool $getCount
2814
 * @return array
2815
 */
2816
function getAllUserToWork($workId, $courseId, $getCount = false)
2817
{
2818
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2819
    $params = array(
2820
        'work_id = ? and c_id = ?' => array($workId, $courseId)
2821
    );
2822
    if ($getCount) {
2823
        $count = 0;
2824
        $result = Database::select(
2825
            'count(user_id) as count',
2826
            $table,
2827
            array('where' => $params),
2828
            'simple'
2829
        );
2830
        if (!empty($result)) {
2831
            $count = intval($result['count']);
2832
        }
2833
        return $count;
2834
    } else {
2835
        return Database::select('*', $table, array('where' => $params));
2836
    }
2837
}
2838
2839
/**
2840
 * @param int $userId
2841
 * @param int $workId
2842
 * @param int $courseId
2843
 */
2844 View Code Duplication
function deleteUserToWork($userId, $workId, $courseId)
2845
{
2846
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
2847
    $params = array(
2848
        'user_id = ? and work_id = ? and c_id = ?' => array($userId, $workId, $courseId)
2849
    );
2850
    Database::delete($table, $params);
2851
}
2852
2853
/**
2854
 * @param int $userId
2855
 * @param int $workId
2856
 * @param int $courseId
2857
 * @return bool
2858
 */
2859
function userIsSubscribedToWork($userId, $workId, $courseId)
2860
{
2861
    $subscribedUsers = getAllUserToWork($workId, $courseId);
2862
2863
    if (empty($subscribedUsers)) {
2864
        return true;
2865
    } else {
2866
        $subscribedUsersList = array();
2867
        foreach ($subscribedUsers as $item) {
2868
            $subscribedUsersList[] = $item['user_id'];
2869
        }
2870
        if (in_array($userId, $subscribedUsersList)) {
2871
            return true;
2872
        }
2873
    }
2874
    return false;
2875
}
2876
2877
/**
2878
 * Get the list of students that have to submit their work
2879
 * @param integer $workId The internal ID of the assignment
2880
 * @param integer $courseId The course ID
2881
 * @param integer $groupId The group ID, if any
2882
 * @param integer $sessionId The session ID, if any
2883
 * @param bool $getCount Whether we want just the amount or the full result
2884
 * @return array|int An integer (if we just asked for the count) or an array of users
2885
 */
2886
function getStudentSubscribedToWork(
2887
    $workId,
2888
    $courseId,
2889
    $groupId = null,
2890
    $sessionId = null,
2891
    $getCount = false
2892
) {
2893
    $usersInWork = null;
2894
    $usersInCourse = null;
2895
2896
    if (empty($groupId)) {
2897
        $courseInfo = api_get_course_info_by_id($courseId);
2898
        $status = STUDENT;
2899
        if (!empty($sessionId)) {
2900
            $status = 0;
2901
        }
2902
        $usersInCourse = CourseManager::get_user_list_from_course_code(
2903
            $courseInfo['code'],
2904
            $sessionId,
2905
            null,
2906
            null,
2907
            $status,
2908
            $getCount
2909
        );
2910
    } else {
2911
        $usersInCourse = GroupManager::get_users(
2912
            $groupId,
2913
            false,
2914
            null,
2915
            null,
2916
            $getCount,
2917
            $courseId
2918
        );
2919
    }
2920
2921
    $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
2922
2923
    if (empty($usersInWork)) {
2924
        return $usersInCourse;
2925
    } else {
2926
        return $usersInWork;
2927
    }
2928
2929
}
2930
2931
/**
2932
 * @param int $userId
2933
 * @param int $workId
2934
 * @param int $courseId
2935
 * @return bool
2936
 */
2937
function allowOnlySubscribedUser($userId, $workId, $courseId)
2938
{
2939
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2940
        return true;
2941
    }
2942
2943
    if (userIsSubscribedToWork($userId, $workId, $courseId) == false) {
2944
        api_not_allowed(true);
2945
    }
2946
}
2947
2948
/**
2949
 * @param int $workId
2950
 * @param array $courseInfo
2951
 * @param int $documentId
2952
 * @return array
2953
 */
2954
function getDocumentTemplateFromWork($workId, $courseInfo, $documentId)
2955
{
2956
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2957
    if (!empty($documents)) {
2958
        foreach ($documents as $doc) {
2959
            if ($documentId != $doc['document_id']) {
2960
                continue;
2961
            }
2962
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2963
            $fileInfo = pathinfo($docData['path']);
2964
            if ($fileInfo['extension'] == 'html') {
2965
                if (file_exists($docData['absolute_path']) && is_file($docData['absolute_path'])) {
2966
                    $docData['file_content'] = file_get_contents($docData['absolute_path']);
2967
                    return $docData;
2968
                }
2969
            }
2970
        }
2971
    }
2972
    return array();
2973
}
2974
2975
/**
2976
 * @param int $workId
2977
 * @param array $courseInfo
2978
 * @return string
2979
 */
2980
function getAllDocumentsFromWorkToString($workId, $courseInfo)
2981
{
2982
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
2983
    $content = null;
2984
    if (!empty($documents)) {
2985
        $content .= '<ul class="nav nav-list well">';
2986
        $content .= '<li class="nav-header">'.get_lang('Documents').'</li>';
2987
        foreach ($documents as $doc) {
2988
            $docData = DocumentManager::get_document_data_by_id($doc['document_id'], $courseInfo['code']);
2989
            if ($docData) {
2990
                $content .= '<li><a target="_blank" href="'.$docData['url'].'">'.$docData['title'].'</a></li>';
2991
            }
2992
        }
2993
        $content .= '</ul><br />';
2994
    }
2995
    return $content;
2996
}
2997
2998
/**
2999
 * Returns fck editor toolbar
3000
 * @return array
3001
 */
3002
function getWorkDescriptionToolbar()
3003
{
3004
    return array(
3005
        'ToolbarStartExpanded' => 'true',
3006
        'ToolbarSet' => 'Work',
3007
        'Width' => '100%',
3008
        'Height' => '400'
3009
    );
3010
}
3011
3012
/**
3013
 * @param array $work
3014
 * @return array
3015
 */
3016
function getWorkComments($work)
3017
{
3018
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3019
    $userTable= Database::get_main_table(TABLE_MAIN_USER);
3020
3021
    $courseId = intval($work['c_id']);
3022
    $workId = intval($work['id']);
3023
3024
    if (empty($courseId) || empty($workId)) {
3025
        return array();
3026
    }
3027
3028
    $sql = "SELECT
3029
            c.id, c.user_id, u.firstname, u.lastname, u.username, u.picture_uri
3030
            FROM $commentTable c
3031
            INNER JOIN $userTable u ON (u.user_id = c.user_id)
3032
            WHERE c_id = $courseId AND work_id = $workId
3033
            ORDER BY sent_at
3034
            ";
3035
    $result = Database::query($sql);
3036
    $comments = Database::store_result($result, 'ASSOC');
3037
    if (!empty($comments)) {
3038
        foreach ($comments as &$comment) {
3039
            $comment['picture'] = UserManager::getUserPicture($comment['user_id']);
3040
            $commentInfo = getWorkComment($comment['id']);
3041
3042
            if (!empty($commentInfo)) {
3043
                $comment = array_merge($comment, $commentInfo);
3044
            }
3045
        }
3046
    }
3047
    return $comments;
3048
}
3049
3050
/**
3051
 * Get total score from a work list
3052
 * @param $workList
3053
 * @return int|null
3054
 */
3055
function getTotalWorkScore($workList)
3056
{
3057
    $count = 0;
3058
    foreach ($workList as $data) {
3059
        $count += $data['qualification_score'];
3060
    }
3061
    return $count;
3062
}
3063
3064
3065
/**
3066
 * Get comment count from a work list (docs sent by students)
3067
 * @param array $workList
3068
 * @param array $courseInfo
3069
 * @return int|null
3070
 */
3071
function getTotalWorkComment($workList, $courseInfo = array())
3072
{
3073
    if (empty($courseInfo)) {
3074
        $courseInfo = api_get_course_info();
3075
    }
3076
3077
    $count = 0;
3078
    foreach ($workList as $data) {
3079
        $count += getWorkCommentCount($data['id'], $courseInfo);
3080
    }
3081
    return $count;
3082
}
3083
3084
/**
3085
 * Get comment count for a specific work sent by a student.
3086
 * @param int $id
3087
 * @param array $courseInfo
3088
 * @return int
3089
 */
3090 View Code Duplication
function getWorkCommentCount($id, $courseInfo = array())
3091
{
3092
    if (empty($courseInfo)) {
3093
        $courseInfo = api_get_course_info();
3094
    }
3095
3096
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3097
    $id = intval($id);
3098
3099
    $sql = "SELECT count(*) as count
3100
            FROM $commentTable
3101
            WHERE work_id = $id AND c_id = ".$courseInfo['real_id'];
3102
3103
    $result = Database::query($sql);
3104
    if (Database::num_rows($result)) {
3105
        $comment = Database::fetch_array($result);
3106
        return $comment['count'];
3107
    }
3108
3109
    return 0;
3110
}
3111
3112
/**
3113
 * Get comment count for a specific parent
3114
 * @param int $parentId
3115
 * @param array $courseInfo
3116
 * @param int $sessionId
3117
 * @return int
3118
 */
3119 View Code Duplication
function getWorkCommentCountFromParent(
3120
    $parentId,
3121
    $courseInfo = array(),
3122
    $sessionId = 0
3123
) {
3124
    if (empty($courseInfo)) {
3125
        $courseInfo = api_get_course_info();
3126
    }
3127
3128
    if (empty($sessionId)) {
3129
        $sessionId = api_get_session_id();
3130
    } else {
3131
        $sessionId = intval($sessionId);
3132
    }
3133
3134
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3135
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3136
    $parentId = intval($parentId);
3137
3138
    $sql = "SELECT count(*) as count
3139
            FROM $commentTable c INNER JOIN $work w
3140
            ON c.c_id = w.c_id AND w.id = c.work_id
3141
            WHERE
3142
                session_id = $sessionId AND
3143
                parent_id = $parentId AND
3144
                w.c_id = ".$courseInfo['real_id'];
3145
3146
    $result = Database::query($sql);
3147
    if (Database::num_rows($result)) {
3148
        $comment = Database::fetch_array($result);
3149
        return $comment['count'];
3150
    }
3151
3152
    return 0;
3153
}
3154
3155
/**
3156
 * Get last work information from parent
3157
 * @param int $parentId
3158
 * @param array $courseInfo
3159
 * @param int $sessionId
3160
 * @return int
3161
 */
3162 View Code Duplication
function getLastWorkStudentFromParent(
3163
    $parentId,
3164
    $courseInfo = array(),
3165
    $sessionId = 0
3166
) {
3167
    if (empty($courseInfo)) {
3168
        $courseInfo = api_get_course_info();
3169
    }
3170
3171
    if (empty($sessionId)) {
3172
        $sessionId = api_get_session_id();
3173
    } else {
3174
        $sessionId = intval($sessionId);
3175
    }
3176
3177
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3178
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3179
    $parentId = intval($parentId);
3180
3181
    $sql = "SELECT w.*
3182
            FROM $commentTable c INNER JOIN $work w
3183
            ON c.c_id = w.c_id AND w.id = c.work_id
3184
            WHERE
3185
                session_id = $sessionId AND
3186
                parent_id = $parentId AND
3187
                w.c_id = ".$courseInfo['real_id']."
3188
            ORDER BY w.sent_date
3189
            LIMIT 1
3190
            ";
3191
3192
    $result = Database::query($sql);
3193
    if (Database::num_rows($result)) {
3194
        $comment = Database::fetch_array($result, 'ASSOC');
3195
        /*if (!empty($comment)) {
3196
            $comment['assignment'] = get_work_assignment_by_id(
3197
                $comment['id'],
3198
                $courseInfo['real_id']
3199
            );
3200
        }*/
3201
        return $comment;
3202
    }
3203
3204
    return array();
3205
}
3206
3207
/**
3208
 * Get last work information from parent
3209
 * @param int $parentId
3210
 * @param array $courseInfo
3211
 * @param int $sessionId
3212
 * @return int
3213
 */
3214 View Code Duplication
function getLastWorkStudentFromParentByUser(
3215
    $userId,
3216
    $parentId,
3217
    $courseInfo = array(),
3218
    $sessionId = 0
3219
) {
3220
    if (empty($courseInfo)) {
3221
        $courseInfo = api_get_course_info();
3222
    }
3223
3224
    if (empty($sessionId)) {
3225
        $sessionId = api_get_session_id();
3226
    } else {
3227
        $sessionId = intval($sessionId);
3228
    }
3229
3230
    $userId = intval($userId);
3231
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3232
    $parentId = intval($parentId);
3233
3234
    $sql = "SELECT *
3235
            FROM  $work
3236
            WHERE
3237
                user_id = $userId AND
3238
                session_id = $sessionId AND
3239
                parent_id = $parentId AND
3240
                c_id = ".$courseInfo['real_id']."
3241
            ORDER BY sent_date DESC
3242
            LIMIT 1
3243
            ";
3244
    $result = Database::query($sql);
3245
    if (Database::num_rows($result)) {
3246
        $work = Database::fetch_array($result, 'ASSOC');
3247
        /*if (!empty($comment)) {
3248
            $comment['assignment'] = get_work_assignment_by_id(
3249
                $comment['id'],
3250
                $courseInfo['real_id']
3251
            );
3252
        }*/
3253
        return $work;
3254
    }
3255
3256
    return array();
3257
}
3258
3259
/**
3260
 * @param int $id comment id
3261
 * @param array $courseInfo
3262
 * @return string
3263
 */
3264
function getWorkComment($id, $courseInfo = array())
3265
{
3266
    if (empty($courseInfo)) {
3267
        $courseInfo = api_get_course_info();
3268
    }
3269
3270
    if (empty($courseInfo['real_id'])) {
3271
        return array();
3272
    }
3273
3274
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3275
    $id = intval($id);
3276
3277
    $sql = "SELECT * FROM $commentTable
3278
            WHERE id = $id AND c_id = ".$courseInfo['real_id'];
3279
    $result = Database::query($sql);
3280
    $comment = array();
3281
    if (Database::num_rows($result)) {
3282
        $comment = Database::fetch_array($result, 'ASSOC');
3283
        $filePath = null;
3284
        $fileUrl = null;
3285
        $deleteUrl = null;
3286
        $fileName = null;
3287
        if (!empty($comment['file'])) {
3288
            $work = get_work_data_by_id($comment['work_id']);
3289
            $workParent = get_work_data_by_id($work['parent_id']);
3290
            $filePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/'.$workParent['url'].'/'.$comment['file'];
3291
            $fileUrl = api_get_path(WEB_CODE_PATH).'work/download_comment_file.php?comment_id='.$id.'&'.api_get_cidreq();
3292
            $deleteUrl = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$comment['work_id'].'&action=delete_attachment&comment_id='.$id;
3293
            $fileParts = explode('_', $comment['file']);
3294
            $fileName = str_replace($fileParts[0].'_'.$fileParts[1].'_', '', $comment['file']);
3295
        }
3296
        $comment['delete_file_url'] = $deleteUrl;
3297
        $comment['file_path'] = $filePath;
3298
        $comment['file_url'] = $fileUrl;
3299
        $comment['file_name_to_show'] = $fileName;
3300
    }
3301
3302
    return $comment;
3303
}
3304
3305
/**
3306
 * @param int $id
3307
 * @param array $courseInfo
3308
 */
3309
function deleteCommentFile($id, $courseInfo = array())
3310
{
3311
    $workComment = getWorkComment($id, $courseInfo);
3312
    if (isset($workComment['file']) && !empty($workComment['file'])) {
3313
        if (file_exists($workComment['file_path'])) {
3314
            $result = my_delete($workComment['file_path']);
3315
            if ($result) {
3316
                $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3317
                $params = array('file' => '');
3318
                Database::update(
3319
                    $commentTable,
3320
                    $params,
3321
                    array('id = ? AND c_id = ? ' => array($workComment['id'], $workComment['c_id']))
3322
                );
3323
            }
3324
        }
3325
    }
3326
}
3327
3328
/**
3329
 * Adds a comments to the work document
3330
 * @param array $courseInfo
3331
 * @param int $userId
3332
 * @param array $work
3333
 * @param array $data
3334
 * @return int
3335
 */
3336
function addWorkComment($courseInfo, $userId, $parentWork, $work, $data)
3337
{
3338
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3339
3340
    $params = array(
3341
        'work_id' => $work['id'],
3342
        'c_id' => $work['c_id'],
3343
        'user_id' => $userId,
3344
        'comment' => $data['comment'],
3345
        'sent_at' => api_get_utc_datetime()
3346
    );
3347
3348
    $commentId = Database::insert($commentTable, $params);
3349
3350
    if ($commentId) {
3351
        $sql = "UPDATE $commentTable SET id = iid WHERE iid = $commentId";
3352
        Database::query($sql);
3353
    }
3354
3355
    $userIdListToSend = array();
3356
3357
    if (api_is_allowed_to_edit()) {
3358
        if (isset($data['send_mail']) && $data['send_mail']) {
3359
            // Teacher sends a feedback
3360
            $userIdListToSend = array($work['user_id']);
3361
        }
3362
    } else {
3363
        $sessionId = api_get_session_id();
3364
        if (empty($sessionId)) {
3365
            $teachers = CourseManager::get_teacher_list_from_course_code(
3366
                $courseInfo['code']
3367
            );
3368
            if (!empty($teachers)) {
3369
                $userIdListToSend = array_keys($teachers);
3370
            }
3371
        } else {
3372
            $teachers = SessionManager::getCoachesByCourseSession(
3373
                $sessionId,
3374
                $courseInfo['code']
3375
            );
3376
3377
            if (!empty($teachers)) {
3378
                $userIdListToSend = array_values($teachers);
3379
            }
3380
        }
3381
    }
3382
3383
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$work['id'];
3384
    $subject = sprintf(get_lang('ThereIsANewWorkFeedback'), $parentWork['title']);
3385
    $content = sprintf(get_lang('ThereIsANewWorkFeedbackInWorkXHere'), $work['title'], $url);
3386
3387
    if (!empty($userIdListToSend)) {
3388
        foreach ($userIdListToSend as $userId) {
3389
            MessageManager::send_message_simple(
3390
                $userId,
3391
                $subject,
3392
                $content
3393
            );
3394
        }
3395
    }
3396
3397
    $fileData = isset($data['file']) ? $data['file'] : null;
3398
    if (!empty($commentId) && !empty($fileData)) {
3399
        $workParent = get_work_data_by_id($work['parent_id']);
3400
        if (!empty($workParent)) {
3401
            $uploadDir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work'.$workParent['url'];
3402
            $newFileName = 'comment_'.$commentId.'_'.php2phps(
3403
                    api_replace_dangerous_char($fileData['name'])
3404
                );
3405
            $newFilePath = $uploadDir.'/'.$newFileName;
3406
            $result = move_uploaded_file($fileData['tmp_name'], $newFilePath);
3407
            if ($result) {
3408
                $params = array('file' => $newFileName);
3409
                Database::update(
3410
                    $commentTable,
3411
                    $params,
3412
                    array('id = ? AND c_id = ? ' => array($commentId, $work['c_id']))
3413
                );
3414
            }
3415
        }
3416
    }
3417
}
3418
3419
/**
3420
 * @param array $work
3421
 * @param string $page
3422
 * @return string
3423
 */
3424
function getWorkCommentForm($work, $page = 'view')
3425
{
3426
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&action=send_comment&'.api_get_cidreq().'&page='.$page;
3427
    $form = new FormValidator(
3428
        'work_comment',
3429
        'post',
3430
        $url
3431
    );
3432
3433
    $form->addElement('file', 'file', get_lang('Attachment'));
3434
    $form->addHtmlEditor('comment', get_lang('Comment'));
3435
    $form->addElement('hidden', 'id', $work['id']);
3436
    $form->addElement('hidden', 'page', $page);
3437
    if (api_is_allowed_to_edit()) {
3438
        $form->addElement('checkbox', 'send_mail', null, get_lang('SendMail'));
3439
    }
3440
    $form->addButtonSend(get_lang('Send'), 'button');
3441
3442
    return $form->returnForm();
3443
}
3444
3445
/**
3446
 * @param array $homework result of get_work_assignment_by_id()
3447
 * @return string
3448
 */
3449
function getWorkDateValidationStatus($homework)
3450
{
3451
    $message = null;
3452
    $has_expired = false;
3453
    $has_ended = false;
3454
3455
    if (!empty($homework)) {
3456
3457 View Code Duplication
        if (!empty($homework['expires_on']) || !empty($homework['ends_on'])) {
3458
            $time_now = time();
3459
3460
            if (!empty($homework['expires_on'])) {
3461
                $time_expires   = api_strtotime($homework['expires_on'], 'UTC');
3462
                $difference     = $time_expires - $time_now;
3463
                if ($difference < 0) {
3464
                    $has_expired = true;
3465
                }
3466
            }
3467
3468
            if (empty($homework['expires_on'])) {
3469
                $has_expired = false;
3470
            }
3471
3472
            if (!empty($homework['ends_on'])) {
3473
                $time_ends = api_strtotime($homework['ends_on'], 'UTC');
3474
                $difference2 = $time_ends - $time_now;
3475
                if ($difference2 < 0) {
3476
                    $has_ended = true;
3477
                }
3478
            }
3479
3480
            $ends_on = api_convert_and_format_date($homework['ends_on']);
3481
            $expires_on = api_convert_and_format_date($homework['expires_on']);
3482
        }
3483
3484
        if ($has_ended) {
3485
            $message = Display::return_message(get_lang('EndDateAlreadyPassed').' '.$ends_on, 'error');
3486
        } elseif ($has_expired) {
3487
            $message = Display::return_message(get_lang('ExpiryDateAlreadyPassed').' '.$expires_on, 'warning');
3488
        } else {
3489
            if ($has_expired) {
3490
                $message = Display::return_message(get_lang('ExpiryDateToSendWorkIs').' '.$expires_on);
3491
            }
3492
        }
3493
    }
3494
3495
    return array(
3496
        'message' => $message,
3497
        'has_ended' => $has_ended,
3498
        'has_expired' => $has_expired
3499
    );
3500
}
3501
3502
/**
3503
 * @param FormValidator $form
3504
 * @param int $uploadFormType
3505
 */
3506
function setWorkUploadForm($form, $uploadFormType = 0)
3507
{
3508
    $form->addElement('header', get_lang('UploadADocument'));
3509
    $form->addElement('hidden', 'contains_file', 0, array('id'=>'contains_file_id'));
3510
    $form->addElement('hidden', 'active', 1);
3511
    $form->addElement('hidden', 'accepted', 1);
3512
    $form->addElement('text', 'title', get_lang('Title'), array('id' => 'file_upload'));
3513
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
3514
3515
    switch ($uploadFormType) {
3516
        case 0:
3517
            // File and text.
3518
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3519
            $form->add_real_progress_bar('uploadWork', 'file');
3520
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3521
            break;
3522
        case 1:
3523
            // Only text.
3524
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
3525
            $form->addRule('description', get_lang('ThisFieldIsRequired'), 'required');
3526
            break;
3527
        case 2:
3528
            // Only file.
3529
            $form->addElement('file', 'file', get_lang('UploadADocument'), 'size="40" onchange="updateDocumentTitle(this.value)"');
3530
            $form->add_real_progress_bar('uploadWork', 'file');
3531
            $form->addRule('file', get_lang('ThisFieldIsRequired'), 'required');
3532
            break;
3533
    }
3534
3535
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
3536
}
3537
3538
/**
3539
 * @param array $my_folder_data
3540
 * @param array $_course
3541
 * @param bool $isCorrection
3542
 * @param array $workInfo
3543
 * @param array $file
3544
 *
3545
 * @return array
3546
 */
3547
function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo = [], $file = [])
3548
{
3549
    if (isset($_FILES['file']) && !empty($_FILES['file'])) {
3550
        $file = $_FILES['file'];
3551
    }
3552
3553
    if (empty($file['size'])) {
3554
        return array('error' => Display :: return_message(get_lang('UplUploadFailedSizeIsZero'), 'error'));
3555
    }
3556
    $updir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work/'; //directory path to upload
3557
3558
    // Try to add an extension to the file if it has'nt one
3559
    $filename = add_ext_on_mime(stripslashes($file['name']), $file['type']);
3560
3561
    // Replace dangerous characters
3562
    $filename = api_replace_dangerous_char($filename);
3563
3564
    // Transform any .php file in .phps fo security
3565
    $filename = php2phps($filename);
3566
    $filesize = filesize($file['tmp_name']);
3567
3568
    if (empty($filesize)) {
3569
        return array(
3570
            'error' => Display:: return_message(
3571
                get_lang('UplUploadFailedSizeIsZero'),
3572
                'error'
3573
            ),
3574
        );
3575
    } elseif (!filter_extension($new_file_name)) {
3576
        return array(
3577
            'error' => Display:: return_message(
3578
                get_lang('UplUnableToSaveFileFilteredExtension'),
3579
                'error'
3580
            ),
3581
        );
3582
    }
3583
3584
    $totalSpace = DocumentManager::documents_total_space($_course['real_id']);
3585
    $course_max_space = DocumentManager::get_course_quota($_course['code']);
3586
    $total_size = $filesize + $totalSpace;
3587
3588
    if ($total_size > $course_max_space) {
3589
        return array(
3590
            'error' => Display :: return_message(get_lang('NoSpace'), 'error')
3591
        );
3592
    }
3593
3594
    // Compose a unique file name to avoid any conflict
3595
    $new_file_name = api_get_unique_id();
3596
3597
    if ($isCorrection) {
3598
        if (!empty($workInfo['url'])) {
3599
            $new_file_name = basename($workInfo['url']).'_correction';
3600
        } else {
3601
            $new_file_name = $new_file_name.'_correction';
3602
        }
3603
    }
3604
3605
    $curdirpath = basename($my_folder_data['url']);
3606
3607
    // If we come from the group tools the groupid will be saved in $work_table
3608
    if (is_dir($updir.$curdirpath) || empty($curdirpath)) {
3609
        $result = move_uploaded_file(
3610
            $file['tmp_name'],
3611
            $updir.$curdirpath.'/'.$new_file_name
3612
        );
3613
    } else {
3614
        return array(
3615
            'error' => Display :: return_message(
3616
                get_lang('FolderDoesntExistsInFileSystem'),
3617
                'error'
3618
            )
3619
        );
3620
    }
3621
3622
    $url = null;
3623
    if ($result) {
3624
        $url = 'work/'.$curdirpath.'/'.$new_file_name;
3625
    }
3626
3627
    return array(
3628
        'url' => $url,
3629
        'filename' => $filename,
3630
        'filesize' => $filesize,
3631
        'error' => null
3632
    );
3633
}
3634
3635
/**
3636
 * Send an e-mail to users related to this work (course teachers, usually, but
3637
 * might include other group members)
3638
 * @param int $workId
3639
 * @param array $courseInfo
3640
 * @param int $session_id
3641
 */
3642
function sendAlertToUsers($workId, $courseInfo, $session_id)
3643
{
3644
    $user_list = array();
3645
    //$workData = get_work_assignment_by_id($workId, $courseInfo['real_id']);
3646
    $workData = get_work_data_by_id($workId, $courseInfo['real_id'], $session_id);
3647
    //last value is to check this is not "just" an edit
3648
    //YW Tis part serve to send a e-mail to the tutors when a new file is sent
3649
    $send = api_get_course_setting('email_alert_manager_on_new_doc');
3650
3651
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_TEACHERS) {
3652
        // Lets predefine some variables. Be sure to change the from address!
3653
        if (empty($session_id)) {
3654
            //Teachers
3655
            $user_list = CourseManager::get_user_list_from_course_code(
3656
                api_get_course_id(),
3657
                null,
3658
                null,
3659
                null,
3660
                COURSEMANAGER
3661
            );
3662
        } else {
3663
            // Coaches
3664
            $user_list = CourseManager::get_user_list_from_course_code(
3665
                api_get_course_id(),
3666
                $session_id,
3667
                null,
3668
                null,
3669
                2
3670
            );
3671
        }
3672
    }
3673
3674
    if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_STUDENTS) {
3675
        if (!$session_id) {
3676
            $session_id = null;
3677
        }
3678
        $student = CourseManager::get_user_list_from_course_code(
3679
            api_get_course_id(),
3680
            $session_id,
3681
            null,
3682
            null,
3683
            STUDENT,
3684
            null,
3685
            null,
3686
            null,
3687
            null,
3688
            null,
3689
            array(api_get_user_id())
3690
        );
3691
        $user_list = array_merge($user_list, $student);
3692
    }
3693
3694
    if ($send) {
3695
        $senderEmail = api_get_setting('emailAdministrator');
3696
        $senderName = api_get_person_name(
3697
            api_get_setting('administratorName'),
3698
            api_get_setting('administratorSurname'),
3699
            null,
3700
            PERSON_NAME_EMAIL_ADDRESS
3701
        );
3702
        $subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n ".get_lang('CourseName').": ".$courseInfo['name']."  ";
3703
        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...
3704
            $to_user_id = $user_data['user_id'];
3705
            $user_info = api_get_user_info($to_user_id);
3706
            $message = get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']."\n";
3707
            $message .= get_lang('UserName')." : ".api_get_person_name($user_info['firstname'], $user_info['lastname'])."\n";
3708
            $message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."\n";
3709
            $url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
3710
            $message .= get_lang('WorkName')." : ".$workData['title']."\n\n".'<a href="'.$url.'">'.get_lang('DownloadLink')."</a>\n";
3711
            //$message .= $url;
3712
            MessageManager::send_message_simple($to_user_id, $subject, $message);
3713
            api_mail_html(
3714
                api_get_person_name(
3715
                    $user_info['firstname'].' '.$user_info['lastname'],
3716
                    null,
3717
                    PERSON_NAME_EMAIL_ADDRESS
3718
                ),
3719
                $user_info['email'],
3720
                $subject,
3721
                $message,
3722
                $senderName,
3723
                $senderEmail
3724
            );
3725
        }
3726
    }
3727
}
3728
3729
/**
3730
 * Check if the current uploaded work filename already exists in the current assement
3731
 *
3732
 * @param $filename
3733
 * @param $workId
3734
 * @return mixed
3735
 */
3736 View Code Duplication
function checkExistingWorkFileName($filename, $workId)
3737
{
3738
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3739
    $filename = Database::escape_string($filename);
3740
    $sql = "SELECT title FROM $work_table
3741
                        WHERE parent_id = $workId AND title = '$filename'";
3742
    $result = Database::query($sql);
3743
    return Database::fetch_assoc($result);
3744
}
3745
3746
/**
3747
 * @param array $workInfo
3748
 * @param array $values
3749
 * @param array $courseInfo
3750
 * @param int $sessionId
3751
 * @param int $groupId
3752
 * @param int $userId
3753
 * @param array $file
3754
 * @param bool  $checkDuplicated
3755
 *
3756
 * @return null|string
3757
 */
3758
function processWorkForm(
3759
    $workInfo,
3760
    $values,
3761
    $courseInfo,
3762
    $sessionId,
3763
    $groupId,
3764
    $userId,
3765
    $file = [],
3766
    $checkDuplicated = false
3767
) {
3768
    $work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
3769
3770
    $courseId = $courseInfo['real_id'];
3771
    $groupId = intval($groupId);
3772
    $sessionId = intval($sessionId);
3773
    $userId = intval($userId);
3774
3775
    $groupIid = 0;
3776
    if (!empty($groupId)) {
3777
        $groupInfo = GroupManager::get_group_properties($groupId);
3778
        if ($groupInfo) {
3779
            $groupIid = $groupInfo['iid'];
3780
        }
3781
    }
3782
3783
    $title = $values['title'];
3784
    $description = $values['description'];
3785
    $contains_file = isset($values['contains_file']) && !empty($values['contains_file']) ? intval($values['contains_file']): 0;
3786
3787
    $saveWork = true;
3788
    $message = null;
3789
    $filename = null;
3790
    $url = null;
3791
    $filesize = null;
3792
    $workData = [];
3793
3794
    if ($values['contains_file']) {
3795
        if ($checkDuplicated) {
3796
            if (checkExistingWorkFileName($file['name'], $workInfo['id'])) {
3797
                $saveWork = false;
3798
                $workData['error'] = get_lang('YouAlreadySentThisFile');
3799
            } else {
3800
                $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3801
            }
3802
        } else {
3803
            $result = uploadWork($workInfo, $courseInfo, false, [], $file);
3804
        }
3805
3806
        if (isset($result['error'])) {
3807
            $message = $result['error'];
3808
            $saveWork = false;
3809
        }
3810
        $filename = isset($result['filename']) ? $result['filename'] : null;
3811
        if (empty($title)) {
3812
            $title = isset($result['title']) && !empty($result['title']) ? $result['title'] : get_lang('Untitled');
3813
        }
3814
3815
        $filesize = isset($result['filesize']) ? $result['filesize'] : null;
3816
        $url = isset($result['url']) ? $result['url'] : null;
3817
    }
3818
3819
    if (empty($title)) {
3820
        $title = get_lang('Untitled');
3821
    }
3822
3823
    if ($saveWork) {
3824
        $active = '1';
3825
        $params = [
3826
            'c_id' => $courseId,
3827
            'url' => $url,
3828
            'filetype' => 'file',
3829
            'title' => $title,
3830
            'description' => $description,
3831
            'contains_file' => $contains_file,
3832
            'active' => $active,
3833
            'accepted' => '1',
3834
            'qualificator_id' => 0,
3835
            'document_id' => 0,
3836
            'weight' => 0,
3837
            'allow_text_assignment' => 0,
3838
            'post_group_id' => $groupIid,
3839
            'sent_date' => api_get_utc_datetime(),
3840
            'parent_id' => $workInfo['id'],
3841
            'session_id' => $sessionId,
3842
            'user_id' => $userId,
3843
            'has_properties' => 0,
3844
            'qualification' => 0
3845
            //'filesize' => $filesize
3846
        ];
3847
        $workId = Database::insert($work_table, $params);
3848
3849
        if ($workId) {
3850
            $sql = "UPDATE $work_table SET id = iid WHERE iid = $workId ";
3851
            Database::query($sql);
3852
3853
            if (array_key_exists('filename', $workInfo) && !empty($filename)) {
3854
                $filename = Database::escape_string($filename);
3855
                $sql = "UPDATE $work_table SET
3856
                            filename = '$filename'
3857
                        WHERE iid = $workId";
3858
                Database::query($sql);
3859
            }
3860
3861
            if (array_key_exists('document_id', $workInfo)) {
3862
                $documentId = isset($values['document_id']) ? intval($values['document_id']) : 0;
3863
                $sql = "UPDATE $work_table SET
3864
                            document_id = '$documentId'
3865
                        WHERE iid = $workId";
3866
                Database::query($sql);
3867
            }
3868
            api_item_property_update(
3869
                $courseInfo,
3870
                'work',
3871
                $workId,
3872
                'DocumentAdded',
3873
                $userId,
3874
                $groupIid
3875
            );
3876
            sendAlertToUsers($workId, $courseInfo, $sessionId);
3877
            Event::event_upload($workId);
3878
3879
            // The following feature requires the creation of a work-type
3880
            // extra_field and the following setting in the configuration file
3881
            // (until moved to the database). It allows te teacher to set a
3882
            // "considered work time", meaning the time we assume a student
3883
            // would have spent, approximately, to prepare the task before
3884
            // handing it in Chamilo, adding this time to the student total
3885
            // course use time, as a register of time spent *before* his
3886
            // connection to the platform to hand the work in.
3887
            $consideredWorkingTime = api_get_configuration_value('considered_working_time');
3888
3889
            if (!empty($consideredWorkingTime)) {
3890
                // Get the "considered work time" defined for this work
3891
                $fieldValue = new ExtraFieldValue('work');
3892
                $resultExtra = $fieldValue->getAllValuesForAnItem(
3893
                    $workInfo['iid'], //the ID of the work *folder*, not the document uploaded by the student
3894
                    true
3895
                );
3896
3897
                $workingTime = null;
3898 View Code Duplication
                foreach ($resultExtra as $field) {
3899
                    $field = $field['value'];
3900
                    if ($consideredWorkingTime == $field->getField()->getVariable()) {
3901
                        $workingTime = $field->getValue();
3902
                    }
3903
                }
3904
3905
                // If no time was defined, or a time of "0" was set, do nothing
3906
                if (!empty($workingTime)) {
3907
                    // If some time is set, get the list of docs handed in by
3908
                    // this student (to make sure we count the time only once)
3909
                    $userWorks = get_work_user_list(
3910
                        0,
3911
                        100,
3912
                        null,
3913
                        null,
3914
                        $workInfo['id'],
3915
                        null,
3916
                        $userId,
3917
                        false,
3918
                        $courseId,
3919
                        $sessionId
3920
                    );
3921
3922
                    if (count($userWorks) == 1) {
3923
                        // The student only uploaded one doc so far, so add the
3924
                        // considered work time to his course connection time
3925
                        $ip = api_get_real_ip();
3926
                        Event::eventAddVirtualCourseTime($courseId, $userId, $sessionId, $workingTime, $ip);
3927
                    }
3928
                }
3929
            }
3930
            $workData = get_work_data_by_id($workId);
3931
            Display::addFlash(Display::return_message(get_lang('DocAdd')));
3932
        }
3933
    } else {
3934
        Display::addFlash(Display::return_message(get_lang('IsNotPosibleSaveTheDocument'), 'error'));
3935
    }
3936
3937
    return $workData;
3938
}
3939
3940
/**
3941
 * Creates a new task (directory) in the assignment tool
3942
 * @param array $params
0 ignored issues
show
Bug introduced by
There is no parameter named $params. Was it maybe removed?

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

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

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

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

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