Passed
Push — master ( f02335...e72130 )
by Julito
10:41
created

exportAllStudentWorkFromPublication()   F

Complexity

Conditions 16
Paths 266

Size

Total Lines 117
Code Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 78
nc 266
nop 4
dl 0
loc 117
rs 3.6066
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
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Course;
6
use Chamilo\CoreBundle\Entity\ResourceLink;
7
use Chamilo\CoreBundle\Framework\Container;
8
use Chamilo\CourseBundle\Entity\CDocument;
9
use Chamilo\CourseBundle\Entity\CStudentPublication;
10
use Chamilo\CourseBundle\Entity\CStudentPublicationComment;
11
use ChamiloSession as Session;
12
13
/**
14
 *  @author Thomas, Hugues, Christophe - original version
15
 *  @author Patrick Cool <[email protected]>, Ghent University -
16
 * ability for course admins to specify wether uploaded documents are visible or invisible by default.
17
 *  @author Roan Embrechts, code refactoring and virtual course support
18
 *  @author Frederic Vauthier, directories management
19
 *  @author Julio Montoya <[email protected]> BeezNest 2011 LOTS of bug fixes
20
 *
21
 *  @todo   this lib should be convert in a static class and moved to main/inc/lib
22
 */
23
24
/**
25
 * Displays action links (for admins, authorized groups members and authorized students).
26
 *
27
 * @param   int Whether to show tool options
28
 * @param   int Whether to show upload form option
29
 * @param bool $isTutor
30
 */
31
function displayWorkActionLinks($id, $action, $isTutor)
32
{
33
    $id = $my_back_id = (int) $id;
34
    if ('list' === $action) {
35
        $my_back_id = 0;
36
    }
37
38
    $output = '';
39
    $origin = api_get_origin();
40
41
    if (!empty($id)) {
42
        $output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&id='.$my_back_id.'">'.
43
            Display::return_icon('back.png', get_lang('Back to Assignments list'), '', ICON_SIZE_MEDIUM).
44
            '</a>';
45
    }
46
47
    if (($isTutor || api_is_allowed_to_edit(null, true)) &&
48
        'learnpath' !== $origin
49
    ) {
50
        // Create dir
51
        if (empty($id)) {
52
            $output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=create_dir">';
53
            $output .= Display::return_icon(
54
                'new_work.png',
55
                get_lang('Create assignment'),
56
                '',
57
                ICON_SIZE_MEDIUM
58
            );
59
            $output .= '</a>';
60
        }
61
    }
62
63
    if (api_is_allowed_to_edit(null, true) && 'learnpath' !== $origin && 'list' === $action) {
64
        $output .= '<a id="open-view-list" href="#">'.
65
            Display::return_icon(
66
                'listwork.png',
67
                get_lang('View students'),
68
                '',
69
                ICON_SIZE_MEDIUM
70
            ).
71
            '</a>';
72
    }
73
74
    if ('' !== $output) {
75
        echo '<div class="actions">';
76
        echo $output;
77
        echo '</div>';
78
    }
79
}
80
81
/**
82
 * @param string $path
83
 * @param int    $courseId
84
 *
85
 * @return array
86
 */
87
function get_work_data_by_path($path, $courseId = 0)
88
{
89
    $path = Database::escape_string($path);
90
    $courseId = (int) $courseId;
91
    if (empty($courseId)) {
92
        $courseId = api_get_course_int_id();
93
    }
94
95
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
96
    $sql = "SELECT *  FROM $table
97
            WHERE url = '$path' AND c_id = $courseId ";
98
    $result = Database::query($sql);
99
    $return = [];
100
    if (Database::num_rows($result)) {
101
        $return = Database::fetch_array($result, 'ASSOC');
102
    }
103
104
    return $return;
105
}
106
107
/**
108
 * @param int $id
109
 * @param int $courseId
110
 * @param int $sessionId
111
 *
112
 * @return array
113
 */
114
function get_work_data_by_id($id, $courseId = 0, $sessionId = 0)
115
{
116
    $id = (int) $id;
117
    $webCodePath = api_get_path(WEB_CODE_PATH);
118
119
    $repo = Container::getStudentPublicationRepository();
120
    /** @var CStudentPublication $studentPublication */
121
    $studentPublication = $repo->find($id);
122
123
    if (null === $studentPublication) {
124
        return [];
125
    }
126
127
    $router = Container::getRouter();
128
129
    $work = [];
130
    if ($studentPublication) {
0 ignored issues
show
introduced by
$studentPublication is of type Chamilo\CourseBundle\Entity\CStudentPublication, thus it always evaluated to true.
Loading history...
131
        $workId = $studentPublication->getIid();
132
        $work['iid'] = $workId;
133
        $work['description'] = $studentPublication->getDescription();
134
        $work['url'] = $router->generate(
135
            'chamilo_core_resource_download',
136
            [
137
                'id' => $studentPublication->getResourceNode()->getId(),
138
                'tool' => 'student_publication',
139
                'type' => 'student_publications',
140
            ]
141
        );
142
143
        $work['active'] = $studentPublication->getActive();
144
        $work['allow_text_assignment'] = $studentPublication->getAllowTextAssignment();
145
        //$work['c_id'] = $studentPublication->getCId();
146
        $work['user_id'] = $studentPublication->getUser()->getId();
147
        $work['parent_id'] = 0;
148
        if (null !== $studentPublication->getPublicationParent()) {
149
            $work['parent_id'] = $studentPublication->getPublicationParent()->getIid();
150
        }
151
152
        $work['qualification'] = $studentPublication->getQualification();
153
        $work['contains_file'] = $studentPublication->getContainsFile();
154
        $work['title'] = $studentPublication->getTitle();
155
        $url = $router->generate(
156
            'chamilo_core_resource_download',
157
            [
158
                'id' => $studentPublication->getResourceNode()->getId(),
159
                'tool' => 'student_publication',
160
                'type' => 'student_publications',
161
            ]
162
        );
163
        $work['download_url'] = $url.'?'.api_get_cidreq();
164
        $work['view_url'] = $webCodePath.'work/view.php?id='.$workId.'&'.api_get_cidreq();
165
        $showUrl = $work['show_url'] = $webCodePath.'work/show_file.php?id='.$workId.'&'.api_get_cidreq();
166
        $work['show_content'] = '';
167
        if ($studentPublication->getContainsFile()) {
168
            $fileType = '';
169
            if (in_array($fileType, ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'])) {
170
                $work['show_content'] = Display::img($showUrl, $studentPublication->getTitle(), null, false);
171
            } elseif (false !== strpos($fileType, 'video/')) {
172
                $work['show_content'] = Display::tag(
173
                    'video',
174
                    get_lang('File format not supported'),
175
                    ['src' => $showUrl]
176
                );
177
            }
178
        }
179
180
        $fieldValue = new ExtraFieldValue('work');
181
        $work['extra'] = $fieldValue->getAllValuesForAnItem($id, true);
182
    }
183
184
    return $work;
185
}
186
187
/**
188
 * @param int $user_id
189
 * @param int $work_id
190
 *
191
 * @return int
192
 */
193
function get_work_count_by_student($user_id, $work_id)
194
{
195
    $user_id = (int) $user_id;
196
    $work_id = (int) $work_id;
197
    $course_id = api_get_course_int_id();
198
    $session_id = api_get_session_id();
199
    $sessionCondition = api_get_session_condition($session_id);
200
201
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
202
    $sql = "SELECT COUNT(*) as count
203
            FROM  $table
204
            WHERE
205
                c_id = $course_id AND
206
                parent_id = $work_id AND
207
                user_id = $user_id AND
208
                active IN (0, 1)
209
                $sessionCondition";
210
    $result = Database::query($sql);
211
    $return = 0;
212
    if (Database::num_rows($result)) {
213
        $return = Database::fetch_row($result, 'ASSOC');
214
        $return = (int) ($return[0]);
215
    }
216
217
    return $return;
218
}
219
220
/**
221
 * @param int $id
222
 * @param int $courseId
223
 *
224
 * @return array
225
 */
226
function get_work_assignment_by_id($id, $courseId = 0)
227
{
228
    $courseId = (int) $courseId;
229
    if (empty($courseId)) {
230
        $courseId = api_get_course_int_id();
231
    }
232
    $id = (int) $id;
233
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
234
    $sql = "SELECT * FROM $table
235
            WHERE c_id = $courseId AND publication_id = $id";
236
    $result = Database::query($sql);
237
    $return = [];
238
    if (Database::num_rows($result)) {
239
        $return = Database::fetch_array($result, 'ASSOC');
240
    }
241
242
    return $return;
243
}
244
245
/**
246
 * @param int    $id
247
 * @param array  $my_folder_data
248
 * @param string $add_in_where_query
249
 * @param int    $course_id
250
 * @param int    $session_id
251
 *
252
 * @return CStudentPublication[]
253
 */
254
function getWorkList($id, $my_folder_data, $add_in_where_query = null, $course_id = 0, $session_id = 0)
255
{
256
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
257
258
    $course_id = $course_id ?: api_get_course_int_id();
259
    $session_id = $session_id ?: api_get_session_id();
260
    $condition_session = api_get_session_condition($session_id);
261
    $group_id = api_get_group_id();
262
263
    $groupIid = 0;
264
    if ($group_id) {
265
        $groupInfo = GroupManager::get_group_properties($group_id);
266
        if ($groupInfo) {
267
            $groupIid = $groupInfo['iid'];
268
        }
269
    }
270
271
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
272
    $linkInfo = GradebookUtils::isResourceInCourseGradebook(
273
        api_get_course_id(),
274
        3,
275
        $id,
276
        api_get_session_id()
277
    );
278
279
    if ($linkInfo) {
280
        $workInGradeBookLinkId = $linkInfo['id'];
281
        if ($workInGradeBookLinkId && $is_allowed_to_edit) {
282
            if (0 == (int) ($my_folder_data['qualification'])) {
283
                echo Display::return_message(
284
                    get_lang('Max weight need to be provided'),
285
                    'warning'
286
                );
287
            }
288
        }
289
    }
290
291
    $repo = Container::getStudentPublicationRepository();
292
    $course = api_get_course_entity($course_id);
293
    $session = api_get_session_entity($session_id);
294
    $group = api_get_group_entity($group_id);
295
296
    $qb = $repo->getResourcesByCourse($course, $session, $group);
297
298
    $contains_file_query = '';
299
    // Get list from database
300
    if ($is_allowed_to_edit) {
301
        $qb->andWhere($qb->expr()->in('resource.active', [1, 0]));
302
        $qb->andWhere($qb->expr()->isNull('resource.publicationParent'));
303
        /*$active_condition = ' active IN (0, 1)';
304
        $sql = "SELECT * FROM $work_table
305
                WHERE
306
                    c_id = $course_id
307
                    $add_in_where_query
308
                    $condition_session AND
309
                    $active_condition AND
310
                    (parent_id = 0)
311
                    $contains_file_query AND
312
                    post_group_id = $groupIid
313
                ORDER BY sent_date DESC";*/
314
    } else {
315
        if (!empty($group_id)) {
316
            // set to select only messages posted by the user's group
317
            $group_query = " WHERE c_id = $course_id AND post_group_id = $groupIid";
318
            $subdirs_query = ' AND parent_id = 0';
319
        } else {
320
            $group_query = " WHERE c_id = $course_id AND (post_group_id = '0' OR post_group_id is NULL) ";
321
            $subdirs_query = ' AND parent_id = 0';
322
        }
323
        //@todo how we can active or not an assignment?
324
        $active_condition = ' AND active IN (1, 0)';
325
        $sql = "SELECT * FROM  $work_table
326
                $group_query
327
                $subdirs_query
328
                $add_in_where_query
329
                $active_condition
330
                $condition_session
331
                ORDER BY title";
332
    }
333
334
    return $qb->getQuery()->getResult();
335
336
    $work_parents = [];
0 ignored issues
show
Unused Code introduced by
$work_parents = array() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
337
338
    $sql_result = Database::query($sql);
339
    if (Database::num_rows($sql_result)) {
340
        while ($work = Database::fetch_object($sql_result)) {
341
            if (0 == $work->parent_id) {
342
                $work_parents[] = $work;
343
            }
344
        }
345
    }
346
347
    return $work_parents;
348
}
349
350
/**
351
 * @param int $userId
352
 * @param int $courseId
353
 * @param int $sessionId
354
 *
355
 * @return array
356
 */
357
function getWorkPerUser($userId, $courseId = 0, $sessionId = 0)
358
{
359
    $works = getWorkList(null, null, null, $courseId, $sessionId);
360
    $result = [];
361
    if (!empty($works)) {
362
        foreach ($works as $workData) {
363
            $workId = $workData->getIid();
364
            $result[$workId]['work'] = $workData;
365
            $result[$workId]['work']->user_results = get_work_user_list(
366
                0,
367
                100,
368
                null,
369
                null,
370
                $workId,
371
                null,
372
                $userId,
373
                false,
374
                $courseId,
375
                $sessionId
376
            );
377
        }
378
    }
379
380
    return $result;
381
}
382
383
/**
384
 * @param int $workId
385
 * @param int $groupId
386
 * @param int $course_id
387
 * @param int $sessionId
388
 */
389
function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
390
{
391
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
392
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
393
    $course_id = (int) $course_id;
394
    $workId = (int) $workId;
395
    $sessionId = (int) $sessionId;
396
    $groupId = (int) $groupId;
397
    $sessionCondition = api_get_session_condition(
398
        $sessionId,
399
        true,
400
        false,
401
        'w.session_id'
402
    );
403
404
    $groupIid = 0;
405
    if ($groupId) {
406
        $groupInfo = GroupManager::get_group_properties($groupId);
407
        $groupIid = $groupInfo['iid'];
408
    }
409
410
    $sql = "SELECT count(DISTINCT u.id)
411
            FROM $work_table w
412
            INNER JOIN $user_table u
413
            ON w.user_id = u.id
414
            WHERE
415
                w.c_id = $course_id
416
                $sessionCondition AND
417
                w.parent_id = $workId AND
418
                w.post_group_id = $groupIid AND
419
                w.active IN (0, 1)
420
            ";
421
422
    $res_document = Database::query($sql);
423
    $rowCount = Database::fetch_row($res_document);
424
425
    return $rowCount[0];
426
}
427
428
/**
429
 * @param mixed $workId
430
 * @param int   $groupId
431
 * @param int   $course_id
432
 * @param int   $sessionId
433
 * @param int   $userId       user id to filter
434
 * @param array $onlyUserList only parse this user list
435
 *
436
 * @return mixed
437
 */
438
function getUniqueStudentAttempts(
439
    $workId,
440
    $groupId,
441
    $course_id,
442
    $sessionId,
443
    $userId = null,
444
    $onlyUserList = []
445
) {
446
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
447
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
448
449
    $course_id = (int) $course_id;
450
    $workCondition = null;
451
    if (is_array($workId)) {
452
        $workId = array_map('intval', $workId);
453
        $workId = implode("','", $workId);
454
        $workCondition = " w.parent_id IN ('".$workId."') AND";
455
    } else {
456
        $workId = (int) $workId;
457
        $workCondition = ' w.parent_id = '.$workId.' AND';
458
    }
459
460
    $sessionId = (int) $sessionId;
461
    $groupId = (int) $groupId;
462
    $studentCondition = null;
463
464
    if (!empty($onlyUserList)) {
465
        $onlyUserList = array_map('intval', $onlyUserList);
466
        $studentCondition = "AND u.id IN ('".implode("', '", $onlyUserList)."') ";
467
    } else {
468
        if (empty($userId)) {
469
            return 0;
470
        }
471
    }
472
473
    $groupIid = 0;
474
    if ($groupId) {
475
        $groupInfo = GroupManager::get_group_properties($groupId);
476
        $groupIid = $groupInfo['iid'];
477
    }
478
479
    $sessionCondition = api_get_session_condition(
480
        $sessionId,
481
        true,
482
        false,
483
        'w.session_id'
484
    );
485
486
    $sql = "SELECT count(*) FROM (
487
                SELECT count(*), w.parent_id
488
                FROM $work_table w
489
                INNER JOIN $user_table u
490
                ON w.user_id = u.id
491
                WHERE
492
                    w.filetype = 'file' AND
493
                    w.c_id = $course_id
494
                    $sessionCondition AND
495
                    $workCondition
496
                    w.post_group_id = $groupIid AND
497
                    w.active IN (0, 1) $studentCondition
498
                ";
499
    if (!empty($userId)) {
500
        $userId = (int) $userId;
501
        $sql .= ' AND u.id = '.$userId;
502
    }
503
    $sql .= ' GROUP BY u.id, w.parent_id) as t';
504
    $result = Database::query($sql);
505
    $row = Database::fetch_row($result);
506
507
    return $row[0];
508
}
509
510
/**
511
 * Shows the work list (student view).
512
 *
513
 * @return string
514
 */
515
function showStudentWorkGrid()
516
{
517
    $courseInfo = api_get_course_info();
518
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student&'.api_get_cidreq();
519
520
    $columns = [
521
        get_lang('Type'),
522
        get_lang('Title'),
523
        get_lang('Deadline'),
524
        get_lang('Feedback'),
525
        get_lang('Last upload'),
526
    ];
527
528
    $columnModel = [
529
        ['name' => 'type', 'index' => 'type', 'width' => '30', 'align' => 'center', 'sortable' => 'false'],
530
        ['name' => 'title', 'index' => 'title', 'width' => '250', 'align' => 'left'],
531
        ['name' => 'expires_on', 'index' => 'expires_on', 'width' => '80', 'align' => 'center', 'sortable' => 'false'],
532
        ['name' => 'feedback', 'index' => 'feedback', 'width' => '80', 'align' => 'center', 'sortable' => 'false'],
533
        ['name' => 'last_upload', 'index' => 'feedback', 'width' => '125', 'align' => 'center', 'sortable' => 'false'],
534
    ];
535
536
    if (0 == $courseInfo['show_score']) {
537
        $columnModel[] = [
538
            'name' => 'others',
539
            'index' => 'others',
540
            'width' => '80',
541
            'align' => 'left',
542
            'sortable' => 'false',
543
        ];
544
        $columns[] = get_lang('Others');
545
    }
546
547
    $params = [
548
        'autowidth' => 'true',
549
        'height' => 'auto',
550
    ];
551
552
    $html = '<script>
553
        $(function() {
554
            '.Display::grid_js('workList', $url, $columns, $columnModel, $params, [], null, true).'
555
        });
556
    </script>';
557
558
    $html .= Display::grid_html('workList');
559
560
    return $html;
561
}
562
563
/**
564
 * Shows the work list (student view).
565
 *
566
 * @return string
567
 */
568
function showStudentAllWorkGrid($withResults = 1)
569
{
570
    $withResults = (int) $withResults;
571
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_all_work_student&with_results='.$withResults;
572
573
    $columns = [
574
        get_lang('Type'),
575
        get_lang('Title'),
576
        get_lang('HandOutDateLimit'),
577
    ];
578
579
    $id = 'workList';
580
    if ($withResults) {
581
        $id = 'workListWithResults';
582
        $columns[] = get_lang('Feedback');
583
        $columns[] = get_lang('LastUpload');
584
    }
585
586
    $columnModel = [
587
        ['name' => 'type', 'index' => 'type', 'width' => '50', 'align' => 'center', 'sortable' => 'false'],
588
        ['name' => 'title', 'index' => 'title', 'width' => '600', 'align' => 'left'],
589
        ['name' => 'expires_on', 'index' => 'expires_on', 'width' => '125', 'align' => 'center', 'sortable' => 'false'],
590
    ];
591
592
    if ($withResults) {
593
        $columnModel[] = [
594
            'name' => 'feedback',
595
            'index' => 'feedback',
596
            'width' => '150',
597
            'align' => 'center',
598
            'sortable' => 'false',
599
        ];
600
        $columnModel[] = [
601
            'name' => 'last_upload',
602
            'index' => 'last_upload',
603
            'width' => '150',
604
            'align' => 'center',
605
            'sortable' => 'false',
606
        ];
607
    }
608
609
    $params = [
610
        'autowidth' => 'true',
611
        'height' => 'auto',
612
    ];
613
614
    $html = '<script>
615
        $(function() {
616
            '.Display::grid_js($id, $url, $columns, $columnModel, $params, [], null, true).'
617
        });
618
    </script>';
619
620
    $html .= Display::grid_html($id);
621
622
    return $html;
623
}
624
625
/**
626
 * Shows the work list (teacher view).
627
 *
628
 * @return string
629
 */
630
function showTeacherWorkGrid()
631
{
632
    $columnModel = [
633
        [
634
            'name' => 'type',
635
            'index' => 'type',
636
            'width' => '35',
637
            'align' => 'center',
638
            'sortable' => 'false',
639
        ],
640
        [
641
            'name' => 'title',
642
            'index' => 'title',
643
            'width' => '300',
644
            'align' => 'left',
645
            'wrap_cell' => 'true',
646
        ],
647
        ['name' => 'sent_date', 'index' => 'sent_date', 'width' => '125', 'align' => 'center'],
648
        ['name' => 'expires_on', 'index' => 'expires_on', 'width' => '125', 'align' => 'center'],
649
        [
650
            'name' => 'amount',
651
            'index' => 'amount',
652
            'width' => '110',
653
            'align' => 'center',
654
            'sortable' => 'false',
655
        ],
656
        [
657
            'name' => 'actions',
658
            'index' => 'actions',
659
            'width' => '110',
660
            'align' => 'left',
661
            'sortable' => 'false',
662
        ],
663
    ];
664
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
665
    $deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
666
667
    $columns = [
668
        get_lang('Type'),
669
        get_lang('Title'),
670
        get_lang('Sent date'),
671
        get_lang('Deadline'),
672
        get_lang('Number submitted'),
673
        get_lang('Detail'),
674
    ];
675
676
    $params = [
677
        'multiselect' => true,
678
        'autowidth' => 'true',
679
        'height' => 'auto',
680
    ];
681
682
    $html = '<script>
683
    $(function() {
684
        '.Display::grid_js('workList', $url, $columns, $columnModel, $params, [], null, true).'
685
        $("#workList").jqGrid(
686
            "navGrid",
687
            "#workList_pager",
688
            { edit: false, add: false, del: true },
689
            { height:280, reloadAfterSubmit:false }, // edit options
690
            { height:280, reloadAfterSubmit:false }, // add options
691
            { reloadAfterSubmit:false, url: "'.$deleteUrl.'" }, // del options
692
            { width:500 } // search options
693
        );
694
    });
695
    </script>';
696
    $html .= Display::grid_html('workList');
697
698
    return $html;
699
}
700
701
/**
702
 * Builds the form that enables the user to
703
 * move a document from one directory to another
704
 * This function has been copied from the document/document.inc.php library.
705
 *
706
 * @param array  $folders
707
 * @param string $curdirpath
708
 * @param string $move_file
709
 * @param string $group_dir
710
 *
711
 * @return string html form
712
 */
713
function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_dir = '')
714
{
715
    $course_id = api_get_course_int_id();
716
    $move_file = (int) $move_file;
717
    $tbl_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
718
    $sql = "SELECT title, url FROM $tbl_work
719
            WHERE c_id = $course_id AND iid ='".$move_file."'";
720
    $result = Database::query($sql);
721
    $row = Database::fetch_array($result, 'ASSOC');
722
    $title = empty($row['title']) ? basename($row['url']) : $row['title'];
723
724
    $form = new FormValidator(
725
        'move_to_form',
726
        'post',
727
        api_get_self().'?'.api_get_cidreq().'&curdirpath='.Security::remove_XSS($curdirpath)
728
    );
729
730
    $form->addHeader(get_lang('Move the file').' - '.Security::remove_XSS($title));
731
    $form->addHidden('item_id', $move_file);
732
    $form->addHidden('action', 'move_to');
733
734
    // Group documents cannot be uploaded in the root
735
    $options = [];
736
    if ('' == $group_dir) {
737
        if (is_array($folders)) {
738
            foreach ($folders as $fid => $folder) {
739
                //you cannot move a file to:
740
                //1. current directory
741
                //2. inside the folder you want to move
742
                //3. inside a subfolder of the folder you want to move
743
                if (($curdirpath != $folder) &&
744
                    ($folder != $move_file) &&
745
                    (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')
746
                ) {
747
                    $options[$fid] = $folder;
748
                }
749
            }
750
        }
751
    } else {
752
        if ('/' != $curdirpath) {
753
            $form .= '<option value="0">/ ('.get_lang('root').')</option>';
754
        }
755
        foreach ($folders as $fid => $folder) {
756
            if (($curdirpath != $folder) && ($folder != $move_file) &&
757
                (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')
758
            ) {
759
                //cannot copy dir into his own subdir
760
                $display_folder = substr($folder, strlen($group_dir));
761
                $display_folder = '' == $display_folder ? '/ ('.get_lang('root').')' : $display_folder;
762
                //$form .= '<option value="'.$fid.'">'.$display_folder.'</option>'."\n";
763
                $options[$fid] = $display_folder;
764
            }
765
        }
766
    }
767
768
    $form->addSelect('move_to_id', get_lang('Select'), $options);
769
    $form->addButtonSend(get_lang('Move the file'), 'move_file_submit');
770
771
    return $form->returnForm();
772
}
773
774
/**
775
 * creates a new directory trying to find a directory name
776
 * that doesn't already exist.
777
 *
778
 * @author Hugues Peeters <[email protected]>
779
 * @author Bert Vanderkimpen
780
 * @author Yannick Warnier <[email protected]> Adaptation for work tool
781
 *
782
 * @param string $workDir        Base work dir (.../work)
783
 * @param string $desiredDirName complete path of the desired name
784
 *
785
 * @return string actual directory name if it succeeds, boolean false otherwise
786
 */
787
function create_unexisting_work_directory($workDir, $desiredDirName)
788
{
789
    $counter = 0;
790
    $workDir = ('/' == substr($workDir, -1, 1) ? $workDir : $workDir.'/');
791
    $checkDirName = $desiredDirName;
792
    while (file_exists($workDir.$checkDirName)) {
793
        $counter++;
794
        $checkDirName = $desiredDirName.$counter;
795
    }
796
797
    /*if (@mkdir($workDir.$checkDirName, api_get_permissions_for_new_directories())) {
798
        return $checkDirName;
799
    } else {
800
        return false;
801
    }*/
802
}
803
804
/**
805
 * Delete a work-tool directory.
806
 *
807
 * @param int $id work directory id to delete
808
 *
809
 * @return int -1 on error
810
 */
811
function deleteDirWork($id)
812
{
813
    $locked = api_resource_is_locked_by_gradebook($id, LINK_STUDENTPUBLICATION);
814
    if ($locked) {
815
        echo Display::return_message(
816
            get_lang(
817
                'This option is not available because this activity is contained by an assessment, which is currently locked. To unlock the assessment, ask your platform administrator.'
818
            ),
819
            'warning'
820
        );
821
822
        return false;
823
    }
824
825
    $_course = api_get_course_info();
826
    $id = (int) $id;
827
    $work_data = get_work_data_by_id($id);
828
829
    if (empty($work_data)) {
830
        return false;
831
    }
832
833
    //$base_work_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work';
834
    //$work_data_url = $base_work_dir.$work_data['url'];
835
    //$check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
836
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
837
    $TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
838
    $t_agenda = Database::get_course_table(TABLE_AGENDA);
839
    $course_id = api_get_course_int_id();
840
    $sessionId = api_get_session_id();
841
    $check = true;
842
843
    if ($check) {
844
        $consideredWorkingTime = api_get_configuration_value('considered_working_time');
845
        if (!empty($consideredWorkingTime)) {
846
            $fieldValue = new ExtraFieldValue('work');
847
            $resultExtra = $fieldValue->getAllValuesForAnItem(
848
                $work_data['id'],
849
                true
850
            );
851
852
            $workingTime = null;
853
            foreach ($resultExtra as $field) {
854
                $field = $field['value'];
855
                if ($consideredWorkingTime == $field->getField()->getVariable()) {
856
                    $workingTime = $field->getValue();
857
858
                    break;
859
                }
860
            }
861
862
            $courseUsers = CourseManager::get_user_list_from_course_code($_course['code'], $sessionId);
863
            if (!empty($workingTime)) {
864
                foreach ($courseUsers as $user) {
865
                    $userWorks = get_work_user_list(
866
                        0,
867
                        100,
868
                        null,
869
                        null,
870
                        $work_data['iid'],
871
                        null,
872
                        $user['user_id'],
873
                        false,
874
                        $course_id,
875
                        $sessionId
876
                    );
877
878
                    if (1 != count($userWorks)) {
879
                        continue;
880
                    }
881
                    Event::eventRemoveVirtualCourseTime(
882
                        $course_id,
883
                        $user['user_id'],
884
                        $sessionId,
885
                        $workingTime,
886
                        $work_data['iid']
887
                    );
888
                }
889
            }
890
        }
891
892
        // Deleting all contents inside the folder
893
        $sql = "UPDATE $table SET active = 2
894
                WHERE filetype = 'folder' AND iid = $id";
895
        Database::query($sql);
896
897
        $sql = "UPDATE $table SET active = 2
898
                WHERE parent_id = $id";
899
        Database::query($sql);
900
901
        /*$new_dir = $work_data_url.'_DELETED_'.$id;
902
903
        if ('true' == api_get_setting('permanently_remove_deleted_files')) {
904
            my_delete($work_data_url);
905
        } else {
906
            if (file_exists($work_data_url)) {
907
                rename($work_data_url, $new_dir);
908
            }
909
        }*/
910
911
        // Gets calendar_id from student_publication_assigment
912
        $sql = "SELECT add_to_calendar FROM $TSTDPUBASG
913
                WHERE c_id = $course_id AND publication_id = $id";
914
        $res = Database::query($sql);
915
        $calendar_id = Database::fetch_row($res);
916
917
        // delete from agenda if it exists
918
        if (!empty($calendar_id[0])) {
919
            $sql = "DELETE FROM $t_agenda
920
                    WHERE c_id = $course_id AND id = '".$calendar_id[0]."'";
921
            Database::query($sql);
922
        }
923
        $sql = "DELETE FROM $TSTDPUBASG
924
                WHERE c_id = $course_id AND publication_id = $id";
925
        Database::query($sql);
926
927
        Skill::deleteSkillsFromItem($id, ITEM_TYPE_STUDENT_PUBLICATION);
928
929
        Event::addEvent(
930
            LOG_WORK_DIR_DELETE,
931
            LOG_WORK_DATA,
932
            [
933
                'id' => $work_data['iid'],
934
                'url' => $work_data['url'],
935
                'title' => $work_data['title'],
936
            ],
937
            null,
938
            api_get_user_id(),
939
            api_get_course_int_id(),
940
            $sessionId
941
        );
942
943
        $linkInfo = GradebookUtils::isResourceInCourseGradebook(
944
            api_get_course_id(),
945
            3,
946
            $id,
947
            $sessionId
948
        );
949
950
        if (false !== $linkInfo) {
951
            $link_id = $linkInfo['id'];
952
            GradebookUtils::remove_resource_from_course_gradebook($link_id);
953
        }
954
955
        return true;
956
    }
957
}
958
959
/**
960
 * Get the path of a document in the student_publication table (path relative to the course directory).
961
 *
962
 * @param int $id
963
 *
964
 * @return string Path (or -1 on error)
965
 */
966
function get_work_path($id)
967
{
968
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
969
    $course_id = api_get_course_int_id();
970
    $sql = 'SELECT url FROM '.$table.'
971
            WHERE c_id = '.$course_id.' AND id='.(int) $id;
972
    $res = Database::query($sql);
973
    if (Database::num_rows($res)) {
974
        $row = Database::fetch_array($res);
975
976
        return $row['url'];
977
    }
978
979
    return -1;
980
}
981
982
/**
983
 * Update the url of a work in the student_publication table.
984
 *
985
 * @param int    $id        of the work to update
986
 * @param string $new_path  Destination directory where the work has been moved (must end with a '/')
987
 * @param int    $parent_id
988
 *
989
 * @return mixed Int -1 on error, sql query result on success
990
 */
991
function updateWorkUrl($id, $new_path, $parent_id)
992
{
993
    if (empty($id)) {
994
        return -1;
995
    }
996
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
997
    $course_id = api_get_course_int_id();
998
    $id = (int) $id;
999
    $parent_id = (int) $parent_id;
1000
1001
    $sql = "SELECT * FROM $table
1002
            WHERE c_id = $course_id AND id = $id";
1003
    $res = Database::query($sql);
1004
    if (1 != Database::num_rows($res)) {
1005
        return -1;
1006
    } else {
1007
        $row = Database::fetch_array($res);
1008
        $filename = basename($row['url']);
1009
        $new_url = $new_path.$filename;
1010
        $new_url = Database::escape_string($new_url);
1011
1012
        $sql = "UPDATE $table SET
1013
                   url = '$new_url',
1014
                   parent_id = '$parent_id'
1015
                WHERE iid = $id";
1016
1017
        return Database::query($sql);
1018
    }
1019
}
1020
1021
/**
1022
 * Update the url of a dir in the student_publication table.
1023
 *
1024
 * @param array  $work_data work original data
1025
 * @param string $newPath   Example: "folder1"
1026
 *
1027
 * @return bool
1028
 */
1029
function updateDirName($work_data, $newPath)
1030
{
1031
    $course_id = $work_data['c_id'];
1032
    $work_id = (int) ($work_data['iid']);
1033
    $oldPath = $work_data['url'];
1034
    $originalNewPath = Database::escape_string($newPath);
1035
    $newPath = Database::escape_string($newPath);
1036
    $newPath = api_replace_dangerous_char($newPath);
1037
    $newPath = disable_dangerous_file($newPath);
1038
1039
    if ($oldPath == '/'.$newPath) {
1040
        return true;
1041
    }
1042
1043
    if (!empty($newPath)) {
1044
        $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1045
        $sql = "UPDATE $table SET
1046
                    title = '".$originalNewPath."'
1047
                WHERE
1048
                    iid = $work_id";
1049
        Database::query($sql);
1050
    }
1051
}
1052
1053
/**
1054
 * returns all the javascript that is required for easily
1055
 * validation when you create a work
1056
 * this goes into the $htmlHeadXtra[] array.
1057
 */
1058
function to_javascript_work()
1059
{
1060
    return '<script>
1061
        function updateDocumentTitle(value) {
1062
            var temp = value.indexOf("/");
1063
            //linux path
1064
            if(temp != -1){
1065
                temp=value.split("/");
1066
            } else {
1067
                temp=value.split("\\\");
1068
            }
1069
1070
            var fullFilename = temp[temp.length - 1];
1071
            var baseFilename = fullFilename;
1072
1073
            // get file extension
1074
            var fileExtension = "";
1075
            if (fullFilename.match(/\..+/)) {
1076
                fileInfo = fullFilename.match(/(.*)\.([^.]+)$/);
1077
                if (fileInfo.length > 1) {
1078
                    fileExtension = "."+fileInfo[fileInfo.length - 1];
1079
                    baseFilename = fileInfo[fileInfo.length - 2];
1080
                }
1081
            }
1082
1083
            document.getElementById("file_upload").value = baseFilename;
1084
            document.getElementById("file_extension").value = fileExtension;
1085
            $("#contains_file_id").attr("value", 1);
1086
        }
1087
        function setFocus() {
1088
            $("#work_title").focus();
1089
        }
1090
1091
        $(function() {
1092
            setFocus();
1093
            var checked = $("#expiry_date").attr("checked");
1094
            if (checked) {
1095
                $("#option2").show();
1096
            } else {
1097
                $("#option2").hide();
1098
            }
1099
1100
            var checkedEndDate = $("#end_date").attr("checked");
1101
            if (checkedEndDate) {
1102
                $("#option3").show();
1103
                $("#ends_on").attr("checked", true);
1104
            } else {
1105
                $("#option3").hide();
1106
                $("#ends_on").attr("checked", false);
1107
            }
1108
1109
            $("#expiry_date").click(function() {
1110
                $("#option2").toggle();
1111
            });
1112
1113
            $("#end_date").click(function() {
1114
                $("#option3").toggle();
1115
            });
1116
        });
1117
    </script>';
1118
}
1119
1120
/**
1121
 * Gets the id of a student publication with a given path.
1122
 *
1123
 * @param string $path
1124
 *
1125
 * @return true if is found / false if not found
1126
 */
1127
// TODO: The name of this function does not fit with the kind of information it returns.
1128
// Maybe check_work_id() or is_work_id()?
1129
function get_work_id($path)
1130
{
1131
    $TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1132
    $TBL_PROP_TABLE = Database::get_course_table(TABLE_ITEM_PROPERTY);
1133
    $course_id = api_get_course_int_id();
1134
    $path = Database::escape_string($path);
1135
1136
    if (api_is_allowed_to_edit()) {
1137
        $sql = "SELECT work.iid
1138
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1139
                WHERE
1140
                    props.c_id = $course_id AND
1141
                    work.c_id = $course_id AND
1142
                    props.tool='work' AND
1143
                    work.id=props.ref AND
1144
                    work.url LIKE 'work/".$path."%' AND
1145
                    work.filetype='file' AND
1146
                    props.visibility<>'2'";
1147
    } else {
1148
        $sql = "SELECT work.iid
1149
                FROM $TBL_STUDENT_PUBLICATION AS work, $TBL_PROP_TABLE AS props
1150
                WHERE
1151
                    props.c_id = $course_id AND
1152
                    work.c_id = $course_id AND
1153
                    props.tool='work' AND
1154
                    work.id=props.ref AND
1155
                    work.url LIKE 'work/".$path."%' AND
1156
                    work.filetype='file' AND
1157
                    props.visibility<>'2' AND
1158
                    props.lastedit_user_id = '".api_get_user_id()."'";
1159
    }
1160
    $result = Database::query($sql);
1161
    $num_rows = Database::num_rows($result);
1162
1163
    if ($result && $num_rows > 0) {
1164
        return true;
1165
    } else {
1166
        return false;
1167
    }
1168
}
1169
1170
/**
1171
 * @param int $work_id
1172
 * @param int $onlyMeUserId show only my works
1173
 * @param int $notMeUserId  show works from everyone except me
1174
 *
1175
 * @return int
1176
 */
1177
function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
1178
{
1179
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1180
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
1181
1182
    $is_allowed_to_edit = api_is_allowed_to_edit(null, true) || api_is_coach();
1183
    $session_id = api_get_session_id();
1184
    $condition_session = api_get_session_condition(
1185
        $session_id,
1186
        true,
1187
        false,
1188
        'link.session_id'
1189
    );
1190
1191
    $group_id = api_get_group_id();
1192
    $course_info = api_get_course_info();
1193
    $course_id = $course_info['real_id'];
1194
    $work_id = (int) $work_id;
1195
1196
    $groupIid = 0;
1197
    if ($group_id) {
1198
        $groupInfo = GroupManager::get_group_properties($group_id);
1199
        if ($groupInfo && isset($groupInfo['iid'])) {
1200
            $groupIid = (int) $groupInfo['iid'];
1201
        }
1202
    }
1203
1204
    if (!empty($group_id)) {
1205
        // set to select only messages posted by the user's group
1206
        $extra_conditions = " work.post_group_id = '".$groupIid."' ";
1207
    } else {
1208
        $extra_conditions = " (work.post_group_id = '0' or work.post_group_id IS NULL) ";
1209
    }
1210
1211
    if ($is_allowed_to_edit) {
1212
        $extra_conditions .= ' AND work.active IN (0, 1) ';
1213
    } else {
1214
        $extra_conditions .= ' AND work.active IN (0, 1) AND accepted = 1';
1215
        if (isset($course_info['show_score']) && 1 == $course_info['show_score']) {
1216
            $extra_conditions .= ' AND work.user_id = '.api_get_user_id().' ';
1217
        } else {
1218
            $extra_conditions .= '';
1219
        }
1220
    }
1221
1222
    $extra_conditions .= ' AND work.parent_id  = '.$work_id.'  ';
1223
    $where_condition = null;
1224
    if (!empty($notMeUserId)) {
1225
        $where_condition .= ' AND u.id <> '.(int) $notMeUserId;
1226
    }
1227
1228
    if (!empty($onlyMeUserId)) {
1229
        $where_condition .= ' AND u.id =  '.(int) $onlyMeUserId;
1230
    }
1231
1232
    $repo = Container::getStudentPublicationRepository();
1233
    $typeId = $repo->getResourceType()->getId();
1234
    $visibility = ResourceLink::VISIBILITY_PUBLISHED;
1235
1236
    $sql = "SELECT count(*) as count
1237
            FROM resource_node node
1238
            INNER JOIN resource_link link
1239
            ON (link.resource_node_id = node.id)
1240
            INNER JOIN $work_table work
1241
            ON (node.id = work.resource_node_id)
1242
            INNER JOIN $user_table u
1243
            ON (work.user_id = u.id)
1244
            WHERE
1245
                link.c_id = $course_id AND
1246
                resource_type_id = $typeId AND
1247
                link.visibility = $visibility AND
1248
            $extra_conditions $where_condition $condition_session";
1249
1250
    $result = Database::query($sql);
1251
1252
    $users_with_work = 0;
1253
    if (Database::num_rows($result)) {
1254
        $result = Database::fetch_array($result);
1255
        $users_with_work = $result['count'];
1256
    }
1257
1258
    return $users_with_work;
1259
}
1260
1261
/**
1262
 * @param int    $start
1263
 * @param int    $limit
1264
 * @param string $column
1265
 * @param string $direction
1266
 * @param string $where_condition
1267
 * @param bool   $getCount
1268
 *
1269
 * @return array
1270
 */
1271
function getWorkListStudent(
1272
    $start,
1273
    $limit,
1274
    $column,
1275
    $direction,
1276
    $where_condition,
1277
    $getCount = false
1278
) {
1279
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1280
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1281
    $courseInfo = api_get_course_info();
1282
    $course_id = $courseInfo['real_id'];
1283
    $session_id = api_get_session_id();
1284
    $condition_session = api_get_session_condition($session_id);
1285
    $group_id = api_get_group_id();
1286
    $userId = api_get_user_id();
1287
1288
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh($userId, $courseInfo);
1289
1290
    if (!in_array($direction, ['asc', 'desc'])) {
1291
        $direction = 'desc';
1292
    }
1293
    if (!empty($where_condition)) {
1294
        $where_condition = ' AND '.$where_condition;
1295
    }
1296
1297
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1298
    $start = (int) $start;
1299
    $limit = (int) $limit;
1300
1301
    $groupIid = 0;
1302
    if ($group_id) {
1303
        $groupInfo = GroupManager::get_group_properties($group_id);
1304
        if ($groupInfo) {
1305
            $groupIid = (int) $groupInfo['iid'];
1306
        }
1307
    }
1308
1309
    if (!empty($groupIid)) {
1310
        $group_query = " WHERE w.c_id = $course_id AND post_group_id = $groupIid";
1311
        $subdirs_query = 'AND w.parent_id = 0';
1312
    } else {
1313
        $group_query = " WHERE w.c_id = $course_id AND (post_group_id = '0' or post_group_id is NULL)  ";
1314
        $subdirs_query = 'AND w.parent_id = 0';
1315
    }
1316
1317
    $active_condition = ' AND active IN (1, 0)';
1318
1319
    if ($getCount) {
1320
        $select = 'SELECT count(w.iid) as count ';
1321
    } else {
1322
        $select = 'SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ';
1323
    }
1324
1325
    $repo = Container::getStudentPublicationRepository();
1326
    $course = api_get_course_entity($course_id);
1327
    $session = api_get_session_entity($session_id);
1328
    $group = api_get_group_entity($group_id);
1329
1330
    $qb = $repo->getResourcesByCourse($course, $session, $group);
1331
    $qb->andWhere($qb->expr()->in('resource.active', [1, 0]));
1332
    $qb->andWhere($qb->expr()->isNull('resource.publicationParent'));
1333
1334
    if ($getCount) {
1335
        $qb->select('count(resource)');
1336
1337
        return (int) $qb->getQuery()->getSingleScalarResult();
1338
    }
1339
1340
    $qb
1341
        ->setFirstResult($start)
1342
        ->setMaxResults($limit)
1343
    ;
1344
1345
1346
    /*$sql = "$select
1347
            FROM $workTable w
1348
            LEFT JOIN $workTableAssignment a
1349
            ON (a.publication_id = w.iid AND a.c_id = w.c_id)
1350
                $group_query
1351
                $subdirs_query
1352
                $active_condition
1353
                $condition_session
1354
                $where_condition
1355
            ";
1356
1357
    $sql .= " ORDER BY $column $direction ";
1358
1359
    if (!empty($start) && !empty($limit)) {
1360
        $sql .= " LIMIT $start, $limit";
1361
    }
1362
1363
    $result = Database::query($sql);
1364
1365
    if ($getCount) {
1366
        $row = Database::fetch_array($result);
1367
1368
        return $row['count'];
1369
    }*/
1370
1371
    $works = [];
1372
    $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
1373
    if ($isDrhOfCourse) {
1374
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1375
    }
1376
1377
    $studentPublications = $qb->getQuery()->getResult();
1378
    $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
1379
    //while ($work = Database::fetch_array($result, 'ASSOC')) {
1380
    $icon = Display::return_icon('work.png');
1381
1382
    /** @var CStudentPublication $studentPublication */
1383
    foreach ($studentPublications as $studentPublication) {
1384
        $workId = $studentPublication->getIid();
1385
        $assignment = $studentPublication->getAssignment();
1386
        $isSubscribed = userIsSubscribedToWork($userId, $workId, $course_id);
1387
        if (false === $isSubscribed) {
1388
            continue;
1389
        }
1390
1391
        /*$visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1392
        if ($visibility != 1) {
1393
            continue;
1394
        }*/
1395
1396
        $work['type'] = $icon;
1397
        $work['expires_on'] = '';
1398
        if ($assignment) {
1399
            $work['expires_on'] = api_get_local_time($assignment->getExpiresOn());
1400
        }
1401
1402
        $title = $studentPublication->getTitle();
1403
1404
        /*$whereCondition = " AND u.id = $userId ";
1405
        $workList = get_work_user_list(
1406
            0,
1407
            1000,
1408
            null,
1409
            null,
1410
            $workId,
1411
            $whereCondition
1412
        );
1413
        $count = getTotalWorkComment($workList, $courseInfo);*/
1414
        $count = 0;
1415
        //$lastWork = getLastWorkStudentFromParentByUser($userId, $work, $courseInfo);
1416
        $lastWork = null;
1417
        if (null !== $count && !empty($count)) {
1418
            $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$lastWork['iid'].'&'.api_get_cidreq();
1419
            $feedback = '&nbsp;'.Display::url(
1420
                Display::returnFontAwesomeIcon('comments-o'),
1421
                $urlView,
1422
                ['title' => get_lang('View')]
1423
            );
1424
1425
            $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info').$feedback;
1426
        }
1427
1428
        if (!empty($lastWork)) {
1429
            $work['last_upload'] = !empty($lastWork['qualification']) ? $lastWork['qualification_rounded'].' - ' : '';
1430
            $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1431
        }
1432
1433
        $work['title'] = Display::url($title, $url.'&id='.$workId);
1434
        $work['others'] = Display::url(
1435
            Display::return_icon('group.png', get_lang('Others')),
1436
            $urlOthers.$workId
1437
        );
1438
        $works[] = $work;
1439
    }
1440
1441
    return $works;
1442
}
1443
1444
/**
1445
 * @param int    $start
1446
 * @param int    $limit
1447
 * @param string $column
1448
 * @param string $direction
1449
 * @param string $where_condition
1450
 * @param bool   $getCount
1451
 * @param int    $withResults
1452
 *
1453
 * @return array
1454
 */
1455
function getAllWorkListStudent(
1456
    $start,
1457
    $limit,
1458
    $column,
1459
    $direction,
1460
    $where_condition,
1461
    $getCount = false,
1462
    $withResults = 1
1463
) {
1464
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1465
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1466
    $userId = api_get_user_id();
1467
1468
    if (empty($userId)) {
1469
        return [];
1470
    }
1471
1472
    $courses = CourseManager::get_courses_list_by_user_id($userId, true);
1473
1474
    if (!empty($where_condition)) {
1475
        $where_condition = ' AND '.$where_condition;
1476
    }
1477
1478
    if (!in_array($direction, ['asc', 'desc'])) {
1479
        $direction = 'desc';
1480
    }
1481
1482
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1483
    $start = (int) $start;
1484
    $limit = (int) $limit;
1485
    $courseQuery = [];
1486
    $courseList = [];
1487
    foreach ($courses as $course) {
1488
        $course_id = $course['real_id'];
1489
        $courseInfo = api_get_course_info_by_id($course_id);
1490
        $session_id = isset($course['session_id']) ? $course['session_id'] : 0;
1491
        $conditionSession = api_get_session_condition($session_id, true, false, 'w.session_id');
1492
        $parentCondition = '';
1493
        if ($withResults) {
1494
            $parentCondition = 'AND ww.parent_id is NOT NULL';
1495
        }
1496
        $courseQuery[] = " (w.c_id = $course_id $conditionSession $parentCondition )";
1497
        $courseList[$course_id] = $courseInfo;
1498
    }
1499
1500
    $courseQueryToString = implode(' OR ', $courseQuery);
1501
1502
    if ($getCount) {
1503
        if (empty($courseQuery)) {
1504
            return 0;
1505
        }
1506
        $select = 'SELECT count(DISTINCT(w.iid)) as count ';
1507
    } else {
1508
        if (empty($courseQuery)) {
1509
            return [];
1510
        }
1511
        $select = 'SELECT DISTINCT
1512
                        w.url,
1513
                        w.iid,
1514
                        w.c_id,
1515
                        w.session_id,
1516
                        a.expires_on,
1517
                        a.ends_on,
1518
                        a.enable_qualification,
1519
                        w.qualification,
1520
                        a.publication_id';
1521
    }
1522
1523
    $checkSentWork = " LEFT JOIN $workTable ww
1524
                       ON (ww.c_id = w.c_id AND ww.parent_id = w.iid AND ww.user_id = $userId ) ";
1525
    $where = ' AND ww.url IS NULL ';
1526
    $expirationCondition = " AND (a.expires_on IS NULL OR a.expires_on > '".api_get_utc_datetime()."') ";
1527
    if ($withResults) {
1528
        $where = '';
1529
        $checkSentWork = " LEFT JOIN $workTable ww
1530
                           ON (
1531
                            ww.c_id = w.c_id AND
1532
                            ww.parent_id = w.iid AND
1533
                            ww.user_id = $userId AND
1534
                            a.expires_on IS NULL AND
1535
                            ww.parent_id is NOT NULL
1536
                        ) ";
1537
        $expirationCondition = " OR (
1538
                ww.parent_id is NULL AND
1539
                a.expires_on IS NOT NULL AND
1540
                a.expires_on < '".api_get_utc_datetime()."'
1541
            ) ";
1542
    }
1543
1544
    $sql = "$select
1545
            FROM $workTable w
1546
            LEFT JOIN $workTableAssignment a
1547
            ON (a.publication_id = w.iid AND a.c_id = w.c_id)
1548
            $checkSentWork
1549
            WHERE
1550
                w.parent_id = 0 AND
1551
                w.active IN (1, 0) AND
1552
                ($courseQueryToString)
1553
                $where_condition
1554
                $expirationCondition
1555
                $where
1556
            ";
1557
1558
    $sql .= " ORDER BY $column $direction ";
1559
1560
    if (!empty($start) && !empty($limit)) {
1561
        $sql .= " LIMIT $start, $limit";
1562
    }
1563
1564
    $result = Database::query($sql);
1565
1566
    if ($getCount) {
1567
        $row = Database::fetch_array($result);
1568
1569
        if ($row) {
1570
            return (int) $row['count'];
1571
        }
1572
1573
        return 0;
1574
    }
1575
1576
    $works = [];
1577
    while ($work = Database::fetch_array($result, 'ASSOC')) {
1578
        $courseId = $work['c_id'];
1579
        $courseInfo = $courseList[$work['c_id']];
1580
        $courseCode = $courseInfo['code'];
1581
        $sessionId = $work['session_id'];
1582
1583
        $cidReq = api_get_cidreq_params($courseCode, $sessionId);
1584
        $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.$cidReq;
1585
        $isSubscribed = userIsSubscribedToWork($userId, $work['iid'], $courseId);
1586
        if (false == $isSubscribed) {
1587
            continue;
1588
        }
1589
1590
        /*$visibility = api_get_item_visibility($courseInfo, 'work', $work['iid'], $sessionId);
1591
1592
        if (1 != $visibility) {
1593
            continue;
1594
        }*/
1595
1596
        $work['type'] = Display::return_icon('work.png');
1597
        $work['expires_on'] = empty($work['expires_on']) ? null : api_get_local_time($work['expires_on']);
1598
1599
        if (empty($work['title'])) {
1600
            $work['title'] = basename($work['url']);
1601
        }
1602
1603
        if ($withResults) {
1604
            $whereCondition = " AND u.user_id = $userId ";
1605
            $workList = get_work_user_list(
1606
                0,
1607
                1000,
1608
                null,
1609
                null,
1610
                $work['iid'],
1611
                $whereCondition,
1612
                null,
1613
                false,
1614
                $courseId,
1615
                $sessionId
1616
            );
1617
1618
            $count = getTotalWorkComment($workList, $courseInfo);
1619
            $lastWork = getLastWorkStudentFromParentByUser($userId, $work, $courseInfo);
1620
1621
            if (!is_null($count) && !empty($count)) {
1622
                $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$lastWork['iid'].'&'.$cidReq;
1623
1624
                $feedback = '&nbsp;'.Display::url(
1625
                        Display::returnFontAwesomeIcon('comments-o'),
1626
                        $urlView,
1627
                        ['title' => get_lang('View')]
1628
                    );
1629
1630
                $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info').$feedback;
1631
            }
1632
1633
            if (!empty($lastWork)) {
1634
                $work['last_upload'] = (!empty($lastWork['qualification'])) ? $lastWork['qualification_rounded'].' - ' : '';
1635
                $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
1636
            }
1637
        }
1638
1639
        $work['title'] = Display::url($work['title'], $url.'&id='.$work['iid']);
1640
        $works[] = $work;
1641
    }
1642
1643
    return $works;
1644
}
1645
1646
/**
1647
 * @param int    $start
1648
 * @param int    $limit
1649
 * @param string $column
1650
 * @param string $direction
1651
 * @param string $where_condition
1652
 * @param bool   $getCount
1653
 *
1654
 * @return array
1655
 */
1656
function getWorkListTeacher(
1657
    $start,
1658
    $limit,
1659
    $column,
1660
    $direction,
1661
    $where_condition,
1662
    $getCount = false
1663
) {
1664
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1665
    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1666
1667
    $courseInfo = api_get_course_info();
1668
    $course_id = api_get_course_int_id();
1669
    $session_id = api_get_session_id();
1670
    $condition_session = api_get_session_condition($session_id);
1671
    $group_id = api_get_group_id();
1672
    $groupIid = 0;
1673
    if ($group_id) {
1674
        $groupInfo = GroupManager::get_group_properties($group_id);
1675
        $groupIid = $groupInfo['iid'];
1676
    }
1677
    $groupIid = (int) $groupIid;
1678
1679
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
1680
    if (!in_array($direction, ['asc', 'desc'])) {
1681
        $direction = 'desc';
1682
    }
1683
    if (!empty($where_condition)) {
1684
        $where_condition = ' AND '.$where_condition;
1685
    }
1686
1687
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
1688
    $start = (int) $start;
1689
    $limit = (int) $limit;
1690
    $works = [];
1691
1692
    $repo = Container::getStudentPublicationRepository();
1693
    $course = api_get_course_entity($course_id);
1694
    $session = api_get_session_entity($session_id);
1695
    $group = api_get_group_entity($group_id);
1696
1697
    // Get list from database
1698
    if ($is_allowed_to_edit) {
1699
        $active_condition = ' active IN (0, 1)';
1700
        if ($getCount) {
1701
            $select = ' SELECT count(w.iid) as count';
1702
        } else {
1703
            $select = ' SELECT w.*, a.expires_on, expires_on, ends_on, enable_qualification ';
1704
        }
1705
1706
        $qb = $repo->getResourcesByCourse($course, $session, $group);
1707
1708
        $qb->andWhere($qb->expr()->in('resource.active', [1, 0]));
1709
        $qb->andWhere($qb->expr()->isNull('resource.publicationParent'));
1710
        if ($getCount) {
1711
            $qb->select('count(resource)');
1712
        }
1713
1714
        $qb
1715
            ->setFirstResult($start)
1716
            ->setMaxResults($limit)
1717
        ;
1718
1719
        /*$sql = " $select
1720
                FROM $workTable w
1721
                LEFT JOIN $workTableAssignment a
1722
                ON (a.publication_id = w.iid AND a.c_id = w.c_id)
1723
                WHERE
1724
                    w.c_id = $course_id
1725
                    $condition_session AND
1726
                    $active_condition AND
1727
                    parent_id = 0 AND
1728
                    post_group_id = $groupIid
1729
                    $where_condition
1730
                ORDER BY $column $direction
1731
                LIMIT $start, $limit";
1732
        $result = Database::query($sql);*/
1733
1734
        if ($getCount) {
1735
            return (int) $qb->getQuery()->getSingleScalarResult();
1736
            /*$row = Database::fetch_array($result);
1737
            return (int) $row['count'];*/
1738
        }
1739
1740
        $studentPublications = $qb->getQuery()->getResult();
1741
1742
        $url = api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq();
1743
        $blockEdition = api_get_configuration_value('block_student_publication_edition');
1744
1745
        //while ($work = Database::fetch_array($result, 'ASSOC')) {
1746
        $icon = Display::return_icon('work.png');
1747
        /** @var CStudentPublication $studentPublication */
1748
        foreach ($studentPublications as $studentPublication) {
1749
            $workId = $studentPublication->getIid();
1750
            $work = [];
1751
            $work['type'] = $icon;
1752
            $assignment = $studentPublication->getAssignment();
1753
            $work['expires_on'] = '';
1754
            if ($assignment) {
1755
                $work['expires_on'] = api_get_local_time($assignment->getExpiresOn());
1756
            }
1757
1758
            /*$countUniqueAttempts = getUniqueStudentAttemptsTotal(
1759
                $workId,
1760
                $group_id,
1761
                $course_id,
1762
                $session_id
1763
            );*/
1764
            $countUniqueAttempts = 0;
1765
            $totalUsers = getStudentSubscribedToWork(
1766
                $workId,
1767
                $course_id,
1768
                $group_id,
1769
                $session_id,
1770
                true
1771
            );
1772
1773
            $work['amount'] = Display::label($countUniqueAttempts.'/'.$totalUsers, 'success');
1774
1775
            //$visibility = api_get_item_visibility($courseInfo, 'work', $workId, $session_id);
1776
            $isVisible = $studentPublication->isVisible($course, $session);
1777
            if ($isVisible) {
1778
                $icon = 'visible.png';
1779
                $text = get_lang('Visible');
1780
                $action = 'invisible';
1781
                $class = '';
1782
            } else {
1783
                $icon = 'invisible.png';
1784
                $text = get_lang('invisible');
1785
                $action = 'visible';
1786
                $class = 'muted';
1787
            }
1788
1789
            $visibilityLink = Display::url(
1790
                Display::return_icon($icon, $text, [], ICON_SIZE_SMALL),
1791
                api_get_path(WEB_CODE_PATH).'work/work.php?id='.$workId.'&action='.$action.'&'.api_get_cidreq()
1792
            );
1793
1794
            $title = $studentPublication->getTitle();
1795
            $work['title'] = Display::url($title, $url.'&id='.$workId, ['class' => $class]);
1796
            $work['title'] .= ' '.Display::label(get_count_work($workId), 'success');
1797
            $work['sent_date'] = api_get_local_time($studentPublication->getSentDate());
1798
1799
            if ($blockEdition && !api_is_platform_admin()) {
1800
                $editLink = '';
1801
            } else {
1802
                $editLink = Display::url(
1803
                    Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL),
1804
                    api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq()
1805
                );
1806
            }
1807
1808
            $correctionLink = '&nbsp;'.Display::url(
1809
                Display::return_icon('upload_package.png', get_lang('Upload corrections'), '', ICON_SIZE_SMALL),
1810
                api_get_path(WEB_CODE_PATH).'work/upload_corrections.php?'.api_get_cidreq().'&id='.$workId
1811
            ).'&nbsp;';
1812
1813
            if ($countUniqueAttempts > 0) {
1814
                $downloadLink = Display::url(
1815
                    Display::return_icon(
1816
                        'save_pack.png',
1817
                        get_lang('Save'),
1818
                        [],
1819
                        ICON_SIZE_SMALL
1820
                    ),
1821
                    api_get_path(WEB_CODE_PATH).'work/downloadfolder.inc.php?id='.$workId.'&'.api_get_cidreq()
1822
                );
1823
            } else {
1824
                $downloadLink = Display::url(
1825
                    Display::return_icon(
1826
                        'save_pack_na.png',
1827
                        get_lang('Save'),
1828
                        [],
1829
                        ICON_SIZE_SMALL
1830
                    ),
1831
                    '#'
1832
                );
1833
            }
1834
            if (!api_is_allowed_to_edit()) {
1835
                $editLink = null;
1836
            }
1837
            $work['actions'] = $visibilityLink.$correctionLink.$downloadLink.$editLink;
1838
            $works[] = $work;
1839
        }
1840
    }
1841
1842
    return $works;
1843
}
1844
1845
/**
1846
 * @param int    $start
1847
 * @param int    $limit
1848
 * @param string $column
1849
 * @param string $direction
1850
 * @param int    $workId
1851
 * @param int    $studentId
1852
 * @param string $whereCondition
1853
 * @param bool   $getCount
1854
 *
1855
 * @return array
1856
 */
1857
function get_work_user_list_from_documents(
1858
    $start,
1859
    $limit,
1860
    $column,
1861
    $direction,
1862
    $workId,
1863
    $studentId = null,
1864
    $whereCondition = '',
1865
    $getCount = false
1866
) {
1867
    if ($getCount) {
1868
        $select1 = ' SELECT count(u.id) as count ';
1869
        $select2 = ' SELECT count(u.id) as count ';
1870
    } else {
1871
        $select1 = ' SELECT DISTINCT
1872
                        u.firstname,
1873
                        u.lastname,
1874
                        u.id as user_id,
1875
                        w.title,
1876
                        w.parent_id,
1877
                        w.document_id document_id,
1878
                        w.iid,
1879
                        qualification,
1880
                        qualificator_id,
1881
                        w.sent_date,
1882
                        w.contains_file,
1883
                        w.url
1884
                    ';
1885
        $select2 = ' SELECT DISTINCT
1886
                        u.firstname, u.lastname,
1887
                        u.id as user_id,
1888
                        d.title,
1889
                        w.parent_id,
1890
                        d.iid document_id,
1891
                        0,
1892
                        0,
1893
                        0,
1894
                        w.sent_date,
1895
                        w.contains_file,
1896
                        w.url
1897
                    ';
1898
    }
1899
1900
    $documentTable = Database::get_course_table(TABLE_DOCUMENT);
1901
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1902
    $workRelDocument = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
1903
    $userTable = Database::get_main_table(TABLE_MAIN_USER);
1904
1905
    $courseId = api_get_course_int_id();
1906
    $sessionId = api_get_session_id();
1907
1908
    if (empty($studentId)) {
1909
        $studentId = api_get_user_id();
1910
    }
1911
1912
    $studentId = (int) $studentId;
1913
    $workId = (int) $workId;
1914
1915
    $userCondition = " AND u.id = $studentId ";
1916
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'w.session_id');
1917
    $workCondition = " AND w_rel.work_id = $workId";
1918
    $workParentCondition = " AND w.parent_id = $workId";
1919
1920
    $sql = "(
1921
                $select1 FROM $userTable u
1922
                INNER JOIN $workTable w
1923
                ON (u.id = w.user_id AND w.active IN (0, 1) AND w.filetype = 'file')
1924
                WHERE
1925
                    w.c_id = $courseId
1926
                    $userCondition
1927
                    $sessionCondition
1928
                    $whereCondition
1929
                    $workParentCondition
1930
            ) UNION (
1931
                $select2 FROM $workTable w
1932
                INNER JOIN $workRelDocument w_rel
1933
                ON (w_rel.work_id = w.iid AND w.active IN (0, 1) AND w_rel.c_id = w.c_id)
1934
                INNER JOIN $documentTable d
1935
                ON (w_rel.document_id = d.iid AND d.c_id = w.c_id)
1936
                INNER JOIN $userTable u ON (u.id = $studentId)
1937
                WHERE
1938
                    w.c_id = $courseId
1939
                    $workCondition
1940
                    $sessionCondition AND
1941
                    d.iid NOT IN (
1942
                        SELECT w.document_id id
1943
                        FROM $workTable w
1944
                        WHERE
1945
                            user_id = $studentId AND
1946
                            c_id = $courseId AND
1947
                            filetype = 'file' AND
1948
                            active IN (0, 1)
1949
                            $sessionCondition
1950
                            $workParentCondition
1951
                    )
1952
            )";
1953
1954
    $start = (int) $start;
1955
    $limit = (int) $limit;
1956
1957
    $direction = in_array(strtolower($direction), ['desc', 'asc']) ? $direction : 'desc';
1958
    $column = Database::escape_string($column);
1959
1960
    if ($getCount) {
1961
        $result = Database::query($sql);
1962
        $result = Database::fetch_array($result);
1963
1964
        return $result['count'];
1965
    }
1966
1967
    $sql .= " ORDER BY $column $direction";
1968
    $sql .= " LIMIT $start, $limit";
1969
1970
    $result = Database::query($sql);
1971
1972
    $currentUserId = api_get_user_id();
1973
    $work_data = get_work_data_by_id($workId);
1974
    $qualificationExists = false;
1975
1976
    if (!empty($work_data['qualification']) && (int) ($work_data['qualification']) > 0) {
1977
        $qualificationExists = true;
1978
    }
1979
1980
    $urlAdd = api_get_path(WEB_CODE_PATH).'work/upload_from_template.php?'.api_get_cidreq();
1981
    $urlEdit = api_get_path(WEB_CODE_PATH).'work/edit.php?'.api_get_cidreq();
1982
    $urlDelete = api_get_path(WEB_CODE_PATH).'work/work_list.php?action=delete&'.api_get_cidreq();
1983
    $urlView = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq();
1984
    $urlDownload = api_get_path(WEB_CODE_PATH).'work/download.php?'.api_get_cidreq();
1985
1986
    $editIcon = Display::return_icon('edit.png', get_lang('Edit'));
1987
    $addIcon = Display::return_icon('add.png', get_lang('Add'));
1988
    $deleteIcon = Display::return_icon('delete.png', get_lang('Delete'));
1989
    $viewIcon = Display::return_icon('default.png', get_lang('View'));
1990
    $saveIcon = Display::return_icon(
1991
        'save.png',
1992
        get_lang('Save'),
1993
        [],
1994
        ICON_SIZE_SMALL
1995
    );
1996
    $allowEdition = 1 == api_get_course_setting('student_delete_own_publication');
1997
1998
    $workList = [];
1999
    while ($row = Database::fetch_array($result, 'ASSOC')) {
2000
        $userId = $row['user_id'];
2001
        $documentId = $row['document_id'];
2002
        $itemId = $row['iid'];
2003
        $addLinkShowed = false;
2004
2005
        if (empty($documentId)) {
2006
            $url = $urlEdit.'&item_id='.$row['iid'].'&id='.$workId;
2007
            $editLink = Display::url($editIcon, $url);
2008
            if (1 != $allowEdition) {
2009
                $editLink = null;
2010
            }
2011
        } else {
2012
            $documentToWork = getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId);
2013
2014
            if (empty($documentToWork)) {
2015
                $url = $urlAdd.'&document_id='.$documentId.'&id='.$workId;
2016
                $editLink = Display::url($addIcon, $url);
2017
                $addLinkShowed = true;
2018
            } else {
2019
                $row['title'] = $documentToWork['title'];
2020
                $row['sent_date'] = $documentToWork['sent_date'];
2021
                $newWorkId = $documentToWork['iid'];
2022
                $url = $urlEdit.'&item_id='.$newWorkId.'&id='.$workId;
2023
                $editLink = Display::url($editIcon, $url);
2024
2025
                if (1 != $allowEdition) {
2026
                    $editLink = '';
2027
                }
2028
            }
2029
        }
2030
2031
        $downloadLink = '';
2032
        // If URL is present then there's a file to download keep BC.
2033
        if ($row['contains_file'] || !empty($row['url'])) {
2034
            $downloadLink = Display::url($saveIcon, $urlDownload.'&id='.$row['iid']).'&nbsp;';
2035
        }
2036
2037
        $viewLink = '';
2038
        if (!empty($itemId)) {
2039
            $viewLink = Display::url($viewIcon, $urlView.'&id='.$itemId);
2040
        }
2041
2042
        $deleteLink = '';
2043
        if (1 == $allowEdition && !empty($itemId)) {
2044
            $deleteLink = Display::url($deleteIcon, $urlDelete.'&item_id='.$itemId.'&id='.$workId);
2045
        }
2046
2047
        $row['type'] = null;
2048
2049
        if ($qualificationExists) {
2050
            if (empty($row['qualificator_id'])) {
2051
                $status = Display::label(get_lang('Not reviewed'), 'warning');
2052
            } else {
2053
                $status = Display::label(get_lang('Revised'), 'success');
2054
            }
2055
            $row['qualificator_id'] = $status;
2056
        }
2057
2058
        if (!empty($row['qualification'])) {
2059
            $row['qualification'] = Display::label($row['qualification'], 'info');
2060
        }
2061
2062
        if (!empty($row['sent_date'])) {
2063
            $row['sent_date'] = Display::dateToStringAgoAndLongDate($row['sent_date']);
2064
        }
2065
2066
        if ($userId == $currentUserId) {
2067
            $row['actions'] = $downloadLink.$viewLink.$editLink.$deleteLink;
2068
        }
2069
2070
        if ($addLinkShowed) {
2071
            $row['qualification'] = '';
2072
            $row['qualificator_id'] = '';
2073
        }
2074
2075
        $workList[] = $row;
2076
    }
2077
2078
    return $workList;
2079
}
2080
2081
/**
2082
 * @param int    $start
2083
 * @param int    $limit
2084
 * @param int    $column
2085
 * @param string $direction
2086
 * @param int    $work_id
2087
 * @param string $whereCondition
2088
 * @param int    $studentId
2089
 * @param bool   $getCount
2090
 * @param int    $courseId
2091
 * @param int    $sessionId
2092
 *
2093
 * @return array
2094
 */
2095
function get_work_user_list(
2096
    $start,
2097
    $limit,
2098
    $column,
2099
    $direction,
2100
    $workId,
2101
    $whereCondition = '',
2102
    $studentId = null,
2103
    $getCount = false,
2104
    $courseId = 0,
2105
    $sessionId = 0
2106
) {
2107
    $session_id = $sessionId ? (int) $sessionId : api_get_session_id();
2108
    $groupId = api_get_group_id();
2109
    $course_info = api_get_course_info();
2110
    $course_info = empty($course_info) ? api_get_course_info_by_id($courseId) : $course_info;
2111
    $courseId = isset($course_info['real_id']) ? $course_info['real_id'] : $courseId;
2112
2113
    $course = api_get_course_entity($courseId);
2114
    $session = api_get_session_entity($sessionId);
2115
    $group = api_get_group_entity($groupId);
2116
2117
    $workId = (int) $workId;
2118
    $start = (int) $start;
2119
    $limit = (int) $limit;
2120
2121
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
2122
    $compilation = null;
2123
    if (api_get_configuration_value('allow_compilatio_tool')) {
2124
        $compilation = new Compilatio();
2125
    }
2126
2127
    if (!in_array($direction, ['asc', 'desc'])) {
2128
        $direction = 'desc';
2129
    }
2130
2131
    //$work_data = get_work_data_by_id($workId, $courseId, $sessionId);
2132
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
2133
    $condition_session = api_get_session_condition(
2134
        $session_id,
2135
        true,
2136
        false,
2137
        'work.session_id'
2138
    );
2139
2140
    $locked = api_resource_is_locked_by_gradebook(
2141
        $workId,
2142
        LINK_STUDENTPUBLICATION,
2143
        $course_info['code']
2144
    );
2145
2146
    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
2147
        api_get_user_id(),
2148
        $course_info
2149
    );
2150
2151
    $isDrhOfSession = !empty(SessionManager::getSessionFollowedByDrh(api_get_user_id(), $session_id));
2152
2153
    $repo = Container::getStudentPublicationRepository();
2154
    /** @var CStudentPublication $studentPublication */
2155
    $studentPublication = $repo->find($workId);
2156
2157
    if (null !== $studentPublication) {
2158
        /*if (!empty($group_id)) {
2159
            // set to select only messages posted by the user's group
2160
            $extra_conditions = " work.post_group_id = '".$groupIid."' ";
2161
        } else {
2162
            $extra_conditions = " (work.post_group_id = '0' OR work.post_group_id is NULL) ";
2163
        }*/
2164
2165
        /*if ($is_allowed_to_edit || $isDrhOfCourse || $isDrhOfSession) {
2166
            $extra_conditions .= ' AND work.active IN (0, 1) ';
2167
        } else {
2168
            if (isset($course_info['show_score']) &&
2169
                1 == $course_info['show_score']
2170
            ) {
2171
                $extra_conditions .= ' AND (u.id = '.api_get_user_id().' AND work.active IN (0, 1)) ';
2172
            } else {
2173
                $extra_conditions .= ' AND work.active IN (0, 1) ';
2174
            }
2175
        }
2176
2177
        $extra_conditions .= " AND parent_id  = $workId ";*/
2178
2179
        $select = 'SELECT DISTINCT
2180
                        u.id as user_id,
2181
                        work.iid as id,
2182
                        title as title,
2183
                        description,
2184
                        url,
2185
                        sent_date,
2186
                        contains_file,
2187
                        has_properties,
2188
                        view_properties,
2189
                        qualification,
2190
                        weight,
2191
                        allow_text_assignment,
2192
                        u.firstname,
2193
                        u.lastname,
2194
                        u.username,
2195
                        parent_id,
2196
                        accepted,
2197
                        qualificator_id
2198
                        ';
2199
        if ($getCount) {
2200
            $select = 'SELECT DISTINCT count(u.id) as count ';
2201
        }
2202
2203
        /*$work_assignment = get_work_assignment_by_id($workId, $courseId);
2204
        if (!empty($studentId)) {
2205
            $studentId = (int) $studentId;
2206
            $whereCondition .= " AND u.id = $studentId ";
2207
        }*/
2208
2209
        $qb = $repo->getStudentAssignments($studentPublication, $course, $session, $group);
2210
2211
        if ($getCount) {
2212
            $qb->select('count(resource)');
2213
2214
            return $qb->getQuery()->getSingleScalarResult();
2215
        }
2216
2217
        $qb->setFirstResult($start);
2218
        $qb->setMaxResults($limit);
2219
2220
        $assignments = $qb->getQuery()->getResult();
2221
2222
        /*$sql = " $select
2223
                FROM $work_table work
2224
                INNER JOIN $user_table u
2225
                ON (work.user_id = u.id)
2226
                WHERE
2227
                    work.c_id = $course_id AND
2228
                    $extra_conditions
2229
                    $whereCondition
2230
                    $condition_session
2231
                    AND u.status != ".INVITEE."
2232
                ORDER BY $column $direction";
2233
2234
        if (!empty($start) && !empty($limit)) {
2235
            $sql .= " LIMIT $start, $limit";
2236
        }
2237
        $result = Database::query($sql);*/
2238
        $works = [];
2239
        /*if ($getCount) {
2240
            $work = Database::fetch_array($result, 'ASSOC');
2241
            if ($work) {
2242
                return (int) $work['count'];
2243
            }
2244
2245
            return 0;
2246
        }*/
2247
2248
        $url = api_get_path(WEB_CODE_PATH).'work/';
2249
        $unoconv = api_get_configuration_value('unoconv.binaries');
2250
        $loadingText = addslashes(get_lang('Loading'));
2251
        $uploadedText = addslashes(get_lang('Uploaded.'));
2252
        $failsUploadText = addslashes(get_lang('No file was uploaded..'));
2253
        $failsUploadIcon = Display::return_icon(
2254
            'closed-circle.png',
2255
            '',
2256
            [],
2257
            ICON_SIZE_TINY
2258
        );
2259
        $saveIcon = Display::return_icon(
2260
            'save.png',
2261
            get_lang('Save'),
2262
            [],
2263
            ICON_SIZE_SMALL
2264
        );
2265
2266
        $correctionIcon = Display::return_icon(
2267
            'check-circle.png',
2268
            get_lang('Correction'),
2269
            null,
2270
            ICON_SIZE_SMALL
2271
        );
2272
2273
        $correctionIconSmall = Display::return_icon(
2274
            'check-circle.png',
2275
            get_lang('Correction'),
2276
            null,
2277
            ICON_SIZE_TINY
2278
        );
2279
2280
        $rateIcon = Display::return_icon(
2281
            'rate_work.png',
2282
            get_lang('Correct and rate'),
2283
            [],
2284
            ICON_SIZE_SMALL
2285
        );
2286
2287
        $blockEdition = api_get_configuration_value('block_student_publication_edition');
2288
        $blockScoreEdition = api_get_configuration_value('block_student_publication_score_edition');
2289
        $loading = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
2290
        $router = Container::getRouter();
2291
        $studentDeleteOwnPublication = api_get_course_setting('student_delete_own_publication');
2292
        /** @var CStudentPublication $assignment */
2293
        foreach ($assignments as $assignment) {
2294
            $item_id = $assignment->getIid();
2295
            // Get the author ID for that document from the item_property table
2296
            $is_author = false;
2297
            $can_read = false;
2298
            $owner_id = $assignment->getUser()->getId();
2299
            /* Because a bug found when saving items using the api_item_property_update()
2300
               the field $item_property_data['insert_user_id'] is not reliable. */
2301
            if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
2302
                $is_author = true;
2303
            }
2304
2305
            if (0 == $course_info['show_score']) {
2306
                $can_read = true;
2307
            }
2308
            $qualification = $assignment->getQualification();
2309
            $qualification_exists = false;
2310
            if (!empty($qualification) &&
2311
                (int) ($qualification) > 0
2312
            ) {
2313
                $qualification_exists = true;
2314
            }
2315
2316
            $qualification_string = '';
2317
            if ($qualification_exists) {
2318
                if ('' == $qualification) {
2319
                    $qualification_string = Display::label('-');
2320
                } else {
2321
                    $qualification_string = formatWorkScore($qualification, $qualification);
2322
                }
2323
            }
2324
2325
            $work['qualification_score'] = $studentPublication->getQualification();
2326
            $add_string = '';
2327
            $time_expires = '';
2328
            $assignmentConfiguration = $studentPublication->getAssignment();
2329
            $expiresOn = null;
2330
            if (!empty($assignmentConfiguration)) {
2331
                $expiresOn = $assignmentConfiguration->getExpiresOn();
2332
                $time_expires = api_strtotime(
2333
                    $expiresOn->format('Y-m-d H:i:s'),
2334
                    'UTC'
2335
                );
2336
            }
2337
2338
            if (!empty($expiresOn) &&
2339
                !empty($time_expires) &&
2340
                ($time_expires < api_strtotime($studentPublication->getSentDate(), 'UTC'))
2341
            ) {
2342
                $add_string = Display::label(get_lang('Expired'), 'important').' - ';
2343
            }
2344
2345
            $accepted = $studentPublication->getAccepted();
2346
            if (($can_read && $accepted) ||
2347
                $is_author ||
2348
                ($is_allowed_to_edit || api_is_drh())
2349
            ) {
2350
                // Firstname, lastname, username
2351
                $work['fullname'] = Display::div(
2352
                    UserManager::formatUserFullName($assignment->getUser()),
2353
                    ['class' => 'work-name']
2354
                );
2355
                // Title
2356
                $title = $assignment->getTitle();
2357
                $work['title_clean'] = $title;
2358
                $title = Security::remove_XSS($title);
2359
                if (strlen($title) > 30) {
2360
                    $short_title = substr($title, 0, 27).'...';
2361
                    $work['title'] = Display::span($short_title, ['class' => 'work-title', 'title' => $title]);
2362
                } else {
2363
                    $work['title'] = Display::div($title, ['class' => 'work-title']);
2364
                }
2365
2366
                // Type.
2367
                //$work['type'] = DocumentManager::build_document_icon_tag('file', $studentPublication->getUrl());
2368
                $work['type'] = '';
2369
2370
                // File name.
2371
                $linkToDownload = '';
2372
                // If URL is present then there's a file to download keep BC.
2373
                if ($studentPublication->getContainsFile()) {
2374
                    $downloadUrl = $router->generate('chamilo_core_resource_download',
2375
                        [
2376
                            'id' => $assignment->getResourceNode()->getId(),
2377
                            'tool' => 'student_publication',
2378
                            'type' => 'student_publications',
2379
                        ]
2380
                    ).'?'.api_get_cidreq();
2381
                    $linkToDownload = '<a href="'.$downloadUrl.'">'.$saveIcon.'</a> ';
2382
                }
2383
2384
                $feedback = '';
2385
                $count = count($studentPublication->getComments());// getWorkCommentCount($item_id, $course_info);
2386
                if (null !== $count && !empty($count)) {
2387
                    if ($qualification_exists) {
2388
                        $feedback .= ' ';
2389
                    }
2390
                    $feedback .= Display::url(
2391
                        $count.' '.Display::returnFontAwesomeIcon('comments-o'),
2392
                        $url.'view.php?'.api_get_cidreq().'&id='.$item_id
2393
                    );
2394
                }
2395
2396
                $correction = '';
2397
                $hasCorrection = '';
2398
                $correctionEntity = $assignment->getCorrection();
2399
                if (null !== $correctionEntity) {
2400
                    $downloadUrl = $router->generate('chamilo_core_resource_download',
2401
                            [
2402
                                'id' => $assignment->getResourceNode()->getId(),
2403
                                'tool' => 'student_publication',
2404
                                'type' => 'student_publications',
2405
                            ]
2406
                        ).'?'.api_get_cidreq();
2407
                    $hasCorrection = Display::url(
2408
                        $correctionIcon,
2409
                        $downloadUrl
2410
                    );
2411
                }
2412
2413
                if ($qualification_exists) {
2414
                    $work['qualification'] = $qualification_string.$feedback;
2415
                } else {
2416
                    $work['qualification'] = $qualification_string.$feedback.$hasCorrection;
2417
                }
2418
2419
                $work['qualification_only'] = $qualification_string;
2420
2421
                // Date.
2422
                $sendDate = $studentPublication->getSentDate();
2423
                $sendDateToString = $studentPublication->getSentDate()->format('Y-m-d H:i:s');
2424
2425
                $work_date = api_get_local_time($sendDate);
2426
                $date = date_to_str_ago($sendDate).' '.$work_date;
2427
                $work['formatted_date'] = $work_date.' '.$add_string;
2428
                $work['expiry_note'] = $add_string;
2429
                $work['sent_date_from_db'] = $sendDateToString;
2430
                $work['sent_date'] = '<div class="work-date" title="'.$date.'">'.
2431
                    $add_string.' '.Display::dateToStringAgoAndLongDate($sendDate).
2432
                    '</div>';
2433
                $work['status'] = $hasCorrection;
2434
                $work['has_correction'] = $hasCorrection;
2435
2436
                // Actions.
2437
                $action = '';
2438
                $qualificatorId = $assignment->getQualificatorId();
2439
                if (api_is_allowed_to_edit()) {
2440
                    if ($blockScoreEdition && !api_is_platform_admin() && !empty($studentPublication->getQualification())) {
2441
                        $rateLink = '';
2442
                    } else {
2443
                        $rateLink = '<a
2444
                            href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.
2445
                            $rateIcon.'</a> ';
2446
                    }
2447
                    $action .= $rateLink;
2448
2449
                    if ($unoconv && empty($assignment->getContainsFile())) {
2450
                        $action .= '<a
2451
                            href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$workId.'&action=export_to_doc&item_id='.$item_id.'"
2452
                            title="'.get_lang('Export to .doc').'" >'.
2453
                            Display::return_icon('export_doc.png', get_lang('Export to .doc'), [], ICON_SIZE_SMALL).'</a> ';
2454
                    }
2455
2456
                    $alreadyUploaded = '';
2457
                    if ($correctionEntity) {
2458
                        $alreadyUploaded = '<br />'.
2459
                            $assignment->getResourceNode()->getTitle().' '.$correctionIconSmall;
2460
                    }
2461
2462
                    $correction = '
2463
                        <form
2464
                        id="file_upload_'.$item_id.'"
2465
                        class="work_correction_file_upload file_upload_small fileinput-button"
2466
                        action="'.api_get_path(WEB_AJAX_PATH).'work.ajax.php?'.api_get_cidreq().'&a=upload_correction_file&item_id='.$item_id.'"
2467
                        method="POST"
2468
                        enctype="multipart/form-data"
2469
                        >
2470
                        <div id="progress_'.$item_id.'" class="text-center button-load">
2471
                            '.addslashes(get_lang('Click or drop one file here')).'
2472
                            '.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
2473
                            '.$alreadyUploaded.'
2474
                        </div>
2475
                        <input id="file_'.$item_id.'" type="file" name="file" class="" multiple>
2476
                        </form>
2477
                    ';
2478
2479
                    $correction .= "<script>
2480
                    $(function() {
2481
                        $('.work_correction_file_upload').each(function () {
2482
                            $(this).fileupload({
2483
                                dropZone: $(this)
2484
                            });
2485
                        });
2486
2487
                        $('#file_upload_".$item_id."').fileupload({
2488
                            add: function (e, data) {
2489
                                $('#progress_$item_id').html();
2490
                                data.context = $('#progress_$item_id').html('$loadingText <br /> <em class=\"fa fa-spinner fa-pulse fa-fw\"></em>');
2491
                                data.submit();
2492
                                $(this).removeClass('hover');
2493
                            },
2494
                            dragover: function (e, data) {
2495
                                $(this).addClass('hover');
2496
                            },
2497
                            done: function (e, data) {
2498
                                if (data._response.result.name) {
2499
                                    $('#progress_$item_id').html('$uploadedText '+data._response.result.result+'<br />'+data._response.result.name);
2500
                                } else {
2501
                                    $('#progress_$item_id').html('$failsUploadText $failsUploadIcon');
2502
                                }
2503
                                $(this).removeClass('hover');
2504
                            }
2505
                        });
2506
                        $('#file_upload_".$item_id."').on('dragleave', function (e) {
2507
                            // dragleave callback implementation
2508
                            $(this).removeClass('hover');
2509
                        });
2510
                    });
2511
                    </script>";
2512
2513
                    if ($locked) {
2514
                        if ($qualification_exists) {
2515
                            $action .= Display::return_icon(
2516
                                'edit_na.png',
2517
                                get_lang('Correct and rate'),
2518
                                [],
2519
                                ICON_SIZE_SMALL
2520
                            );
2521
                        } else {
2522
                            $action .= Display::return_icon('edit_na.png', get_lang('Comment'), [], ICON_SIZE_SMALL);
2523
                        }
2524
                    } else {
2525
                        if ($blockEdition && !api_is_platform_admin()) {
2526
                            $editLink = '';
2527
                        } else {
2528
                            if ($qualification_exists) {
2529
                                $editLink = '<a
2530
                                    href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$workId.'"
2531
                                    title="'.get_lang('Edit').'"  >'.
2532
                                    Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL).'</a>';
2533
                            } else {
2534
                                $editLink = '<a
2535
                                    href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$workId.'"
2536
                                    title="'.get_lang('Edit').'">'.
2537
                                    Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL).'</a>';
2538
                            }
2539
                        }
2540
                        $action .= $editLink;
2541
                    }
2542
2543
                    if ($assignment->getContainsFile()) {
2544
                        if ($locked) {
2545
                            $action .= Display::return_icon(
2546
                                'move_na.png',
2547
                                get_lang('Move'),
2548
                                [],
2549
                                ICON_SIZE_SMALL
2550
                            );
2551
                        } else {
2552
                            $action .= '<a
2553
                                href="'.$url.'work.php?'.api_get_cidreq().'&action=move&item_id='.$item_id.'&id='.$workId.'"
2554
                                title="'.get_lang('Move').'">'.
2555
                                Display::return_icon('move.png', get_lang('Move'), [], ICON_SIZE_SMALL).'</a>';
2556
                        }
2557
                    }
2558
2559
                    if ($assignment->getAccepted()) {
2560
                        $action .= '<a
2561
                            href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$workId.'&action=make_invisible&item_id='.$item_id.'"
2562
                            title="'.get_lang('invisible').'" >'.
2563
                            Display::return_icon('visible.png', get_lang('invisible'), [], ICON_SIZE_SMALL).
2564
                            '</a>';
2565
                    } else {
2566
                        $action .= '<a
2567
                            href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$workId.'&action=make_visible&item_id='.$item_id.'"
2568
                            title="'.get_lang('Visible').'" >'.
2569
                            Display::return_icon('invisible.png', get_lang('Visible'), [], ICON_SIZE_SMALL).
2570
                            '</a> ';
2571
                    }
2572
2573
                    if ($locked) {
2574
                        $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
2575
                    } else {
2576
                        $action .= '<a
2577
                            href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$workId.'&action=delete&item_id='.$item_id.'"
2578
                            onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('Please confirm your choice'), ENT_QUOTES))."'".')) return false;"
2579
                            title="'.get_lang('Delete').'" >'.
2580
                            Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
2581
                    }
2582
                } elseif ($is_author && (empty($qualificatorId) || 0 == $qualificatorId)) {
2583
                    $action .= '<a
2584
                            href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'"
2585
                            title="'.get_lang('View').'">'.
2586
                        Display::return_icon('default.png', get_lang('View'), [], ICON_SIZE_SMALL).
2587
                        '</a>';
2588
2589
                    if (1 == $studentDeleteOwnPublication) {
2590
                        if (api_is_allowed_to_session_edit(false, true)) {
2591
                            $action .= '<a
2592
                                href="'.$url.'edit.php?'.api_get_cidreq().'&item_id='.$item_id.'&id='.$workId.'"
2593
                                title="'.get_lang('Edit').'">'.
2594
                                Display::return_icon('edit.png', get_lang('Comment'), [], ICON_SIZE_SMALL).
2595
                                '</a>';
2596
                        }
2597
                        $action .= ' <a
2598
                            href="'.$url.'work_list.php?'.api_get_cidreq().'&action=delete&item_id='.$item_id.'&id='.$workId.'"
2599
                            onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('Please confirm your choice'), ENT_QUOTES))."'".')) return false;"
2600
                            title="'.get_lang('Delete').'"  >'.
2601
                            Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
2602
                    }
2603
                } else {
2604
                    $action .= '<a
2605
                        href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'"
2606
                        title="'.get_lang('View').'">'.
2607
                        Display::return_icon('default.png', get_lang('View'), [], ICON_SIZE_SMALL).
2608
                        '</a>';
2609
                }
2610
2611
                // Status.
2612
                if (empty($qualificatorId)) {
2613
                    $qualificator_id = Display::label(get_lang('Not reviewed'), 'warning');
2614
                } else {
2615
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2616
                }
2617
                $work['qualificator_id'] = $qualificator_id.' '.$hasCorrection;
2618
                $work['actions'] = '<div class="work-action">'.$linkToDownload.$action.'</div>';
2619
                $work['correction'] = $correction;
2620
2621
                if (!empty($compilation)) {
2622
                    throw new Exception('compilatio');
2623
                    /*
2624
                    $compilationId = $compilation->getCompilatioId($item_id, $course_id);
2625
                    if ($compilationId) {
2626
                        $actionCompilatio = "<div id='id_avancement".$item_id."' class='compilation_block'>
2627
                            ".$loading.'&nbsp;'.get_lang('Connecting with the Compilatio server').'</div>';
2628
                    } else {
2629
                        $workDirectory = api_get_path(SYS_COURSE_PATH).$course_info['directory'];
2630
                        if (!Compilatio::verifiFileType($dbTitle)) {
2631
                            $actionCompilatio = get_lang('File format not supported');
2632
                        } elseif (filesize($workDirectory.'/'.$work['url']) > $compilation->getMaxFileSize()) {
2633
                            $sizeFile = round(filesize($workDirectory.'/'.$work['url']) / 1000000);
2634
                            $actionCompilatio = get_lang('The file is too big to upload.').': '.format_file_size($sizeFile).'<br />';
2635
                        } else {
2636
                            $actionCompilatio = "<div id='id_avancement".$item_id."' class='compilation_block'>";
2637
                            $actionCompilatio .= Display::url(
2638
                                get_lang('Analyse'),
2639
                                'javascript:void(0)',
2640
                                [
2641
                                    'class' => 'getSingleCompilatio btn btn-primary btn-xs',
2642
                                    'onclick' => "getSingleCompilatio($item_id);",
2643
                                ]
2644
                            );
2645
                            $actionCompilatio .= get_lang('with Compilatio');
2646
                        }
2647
                    }
2648
                    $work['compilatio'] = $actionCompilatio;*/
2649
                }
2650
                $works[] = $work;
2651
            }
2652
        }
2653
2654
        return $works;
2655
    }
2656
}
2657
2658
function getAllWork(
2659
    $start,
2660
    $limit,
2661
    $column,
2662
    $direction,
2663
    $whereCondition = '',
2664
    $getCount = false,
2665
    $courseId = 0,
2666
    $status = 0
2667
) {
2668
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2669
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
2670
    $userId = api_get_user_id();
2671
    if (empty($userId)) {
2672
        return [];
2673
    }
2674
2675
    $courses = CourseManager::get_courses_list_by_user_id($userId, false, false, false);
2676
2677
    if (!empty($whereCondition)) {
2678
        $whereCondition = ' AND '.$whereCondition;
2679
    }
2680
    $whereCondition = Database::escape_string($whereCondition);
2681
2682
    if (!in_array($direction, ['asc', 'desc'])) {
2683
        $direction = 'desc';
2684
    }
2685
2686
    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
2687
    $start = (int) $start;
2688
    $limit = (int) $limit;
2689
    $courseQuery = [];
2690
    $courseList = [];
2691
    $withResults = 0;
2692
    foreach ($courses as $course) {
2693
        $courseIdItem = $course['real_id'];
2694
        if (!empty($courseId) && $courseIdItem != $courseId) {
2695
            continue;
2696
        }
2697
        $courseInfo = api_get_course_info_by_id($courseIdItem);
2698
        $session_id = isset($course['session_id']) ? $course['session_id'] : 0;
2699
        //$conditionSession = api_get_session_condition($session_id, true, false, 'w.session_id');
2700
        $conditionSession = '';
2701
        $parentCondition = '';
2702
        if ($withResults) {
2703
            $parentCondition = 'AND ww.parent_id is NOT NULL';
2704
        }
2705
        $courseQuery[] = " (work.c_id = $courseIdItem $conditionSession $parentCondition )";
2706
        $courseList[$courseIdItem] = $courseInfo;
2707
    }
2708
2709
    $courseQueryToString = implode(' OR ', $courseQuery);
2710
    $compilation = null;
2711
    /*if (api_get_configuration_value('allow_compilatio_tool')) {
2712
        $compilation = new Compilatio();
2713
    }*/
2714
2715
    $is_allowed_to_edit = api_is_allowed_to_edit() || api_is_coach();
2716
2717
    if ($getCount) {
2718
        if (empty($courseQuery)) {
2719
            return 0;
2720
        }
2721
        $select = 'SELECT DISTINCT count(u.id) as count ';
2722
    } else {
2723
        $select = 'SELECT DISTINCT
2724
                    u.id as user_id,
2725
                    work.id as id,
2726
                    title as title,
2727
                    description,
2728
                    url,
2729
                    sent_date,
2730
                    contains_file,
2731
                    has_properties,
2732
                    view_properties,
2733
                    qualification,
2734
                    weight,
2735
                    allow_text_assignment,
2736
                    u.firstname,
2737
                    u.lastname,
2738
                    u.username,
2739
                    parent_id,
2740
                    accepted,
2741
                    qualificator_id,
2742
                    url_correction,
2743
                    title_correction,
2744
                    work.c_id,
2745
                    work.session_id ';
2746
    }
2747
2748
    $statusCondition = '';
2749
    if (!empty($status)) {
2750
        switch ($status) {
2751
            case 2:
2752
                $statusCondition = ' AND (qualificator_id IS NULL OR qualificator_id = 0) ';
2753
                break;
2754
            case 3:
2755
                $statusCondition = ' AND (qualificator_id <> 0 AND qualificator_id IS NOT NULL) ';
2756
                break;
2757
        }
2758
    }
2759
2760
    $sql = " $select
2761
            FROM $work_table work
2762
            INNER JOIN $user_table u
2763
            ON (work.user_id = u.id)
2764
            WHERE
2765
                work.parent_id <> 0 AND
2766
                work.active IN (1, 0)
2767
                $whereCondition AND
2768
                ($courseQueryToString)
2769
                $statusCondition
2770
                AND u.status != ".INVITEE;
2771
2772
    $sql .= " ORDER BY $column $direction ";
2773
2774
    if (!empty($start) && !empty($limit)) {
2775
        $sql .= " LIMIT $start, $limit";
2776
    }
2777
2778
    $result = Database::query($sql);
2779
    $works = [];
2780
    if ($getCount) {
2781
        $work = Database::fetch_array($result, 'ASSOC');
2782
        if ($work) {
2783
            return (int) $work['count'];
2784
        }
2785
2786
        return 0;
2787
    }
2788
2789
    $url = api_get_path(WEB_CODE_PATH).'work/';
2790
    $unoconv = api_get_configuration_value('unoconv.binaries');
2791
    $loadingText = addslashes(get_lang('Loading'));
2792
    $uploadedText = addslashes(get_lang('Uploaded'));
2793
    $failsUploadText = addslashes(get_lang('UplNoFileUploaded'));
2794
    $failsUploadIcon = Display::return_icon(
2795
        'closed-circle.png',
2796
        '',
2797
        [],
2798
        ICON_SIZE_TINY
2799
    );
2800
    $saveIcon = Display::return_icon(
2801
        'save.png',
2802
        get_lang('Save'),
2803
        [],
2804
        ICON_SIZE_SMALL
2805
    );
2806
2807
    $correctionIcon = Display::return_icon(
2808
        'check-circle.png',
2809
        get_lang('Correction'),
2810
        null,
2811
        ICON_SIZE_SMALL
2812
    );
2813
2814
    $correctionIconSmall = Display::return_icon(
2815
        'check-circle.png',
2816
        get_lang('Correction'),
2817
        null,
2818
        ICON_SIZE_TINY
2819
    );
2820
2821
    $rateIcon = Display::return_icon(
2822
        'rate_work.png',
2823
        get_lang('CorrectAndRate'),
2824
        [],
2825
        ICON_SIZE_SMALL
2826
    );
2827
    $parentList = [];
2828
    $blockEdition = api_get_configuration_value('block_student_publication_edition');
2829
    $blockScoreEdition = api_get_configuration_value('block_student_publication_score_edition');
2830
    $loading = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
2831
    $qualification_exists = true;
2832
    $repo = Container::getStudentPublicationRepository();
2833
    while ($work = Database::fetch_array($result, 'ASSOC')) {
2834
        $courseId = $work['c_id'];
2835
        $courseInfo = $courseList[$work['c_id']];
2836
        $sessionId = $work['session_id'];
2837
        $cidReq = 'cidReq='.$courseInfo['code'].'&id_session='.$sessionId;
2838
2839
        $item_id = $workId = $work['id'];
2840
        $dbTitle = $work['title'];
2841
        // Get the author ID for that document from the item_property table
2842
        $is_author = false;
2843
        $can_read = false;
2844
        $owner_id = $work['user_id'];
2845
        //$visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $sessionId);
2846
        $studentPublication = $repo->find($work['iid']);
2847
        $workId = $studentPublication->getIid();
2848
        $isVisible = $studentPublication->isVisible($courseEntity, $sessionEntity);
2849
        if (false === $isVisible) {
2850
            continue;
2851
        }
2852
        /*$locked = api_resource_is_locked_by_gradebook(
2853
            $item_id,
2854
            LINK_STUDENTPUBLICATION,
2855
            $courseInfo['code']
2856
        );*/
2857
        $locked = false;
2858
2859
        /* Because a bug found when saving items using the api_item_property_update()
2860
           the field $item_property_data['insert_user_id'] is not reliable. */
2861
        if (!$is_allowed_to_edit && $owner_id == api_get_user_id()) {
2862
            $is_author = true;
2863
        }
2864
2865
        /*if ($course_info['show_score'] == 0) {
2866
            $can_read = true;
2867
        }*/
2868
2869
        $qualification_string = '';
2870
        if ($qualification_exists) {
2871
            if ('' == $work['qualification']) {
2872
                $qualification_string = Display::label('-');
2873
            } else {
2874
                $qualification_string = formatWorkScore($work['qualification'], $work['qualification']);
2875
            }
2876
        }
2877
2878
        $work_assignment = get_work_assignment_by_id($workId, $courseId);
2879
2880
        $work['qualification_score'] = $work['qualification'];
2881
        $add_string = '';
2882
        $time_expires = '';
2883
        if (!empty($work_assignment['expires_on'])) {
2884
            $time_expires = api_strtotime(
2885
                $work_assignment['expires_on'],
2886
                'UTC'
2887
            );
2888
        }
2889
2890
        if (!empty($work_assignment['expires_on']) &&
2891
            !empty($time_expires) && ($time_expires < api_strtotime($work['sent_date'], 'UTC'))) {
2892
            $add_string = Display::label(get_lang('Expired'), 'important').' - ';
2893
        }
2894
2895
        if (($can_read && '1' == $work['accepted']) ||
2896
            ($is_author && in_array($work['accepted'], ['1', '0'])) ||
2897
            ($is_allowed_to_edit || api_is_drh())
2898
        ) {
2899
            // Firstname, lastname, username
2900
            $work['fullname'] = Display::div(
2901
                api_get_person_name($work['firstname'], $work['lastname']),
2902
                ['class' => 'work-name']
2903
            );
2904
            // Title
2905
            $work['title_clean'] = $work['title'];
2906
            $work['title'] = Security::remove_XSS($work['title']);
2907
            if (strlen($work['title']) > 30) {
2908
                $short_title = substr($work['title'], 0, 27).'...';
2909
                $work['title'] = Display::span($short_title, ['class' => 'work-title', 'title' => $work['title']]);
2910
            } else {
2911
                $work['title'] = Display::div($work['title'], ['class' => 'work-title']);
2912
            }
2913
2914
            // Type.
2915
            $work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
2916
2917
            // File name.
2918
            $linkToDownload = '';
2919
            // If URL is present then there's a file to download keep BC.
2920
            if ($work['contains_file'] || !empty($work['url'])) {
2921
                $linkToDownload = '<a href="'.$url.'download.php?id='.$item_id.'&'.$cidReq.'">'.$saveIcon.'</a> ';
2922
            }
2923
2924
            $feedback = '';
2925
            $count = getWorkCommentCount($item_id, $courseInfo);
2926
            if (!is_null($count) && !empty($count)) {
2927
                if ($qualification_exists) {
2928
                    $feedback .= ' ';
2929
                }
2930
                $feedback .= Display::url(
2931
                    $count.' '.Display::returnFontAwesomeIcon('comments-o'),
2932
                    $url.'view.php?'.$cidReq.'&id='.$item_id
2933
                );
2934
            }
2935
2936
            $correction = '';
2937
            $hasCorrection = '';
2938
            if (!empty($work['url_correction'])) {
2939
                $hasCorrection = Display::url(
2940
                    $correctionIcon,
2941
                    api_get_path(WEB_CODE_PATH).'work/download.php?id='.$item_id.'&'.$cidReq.'&correction=1'
2942
                );
2943
            }
2944
2945
            if ($qualification_exists) {
2946
                $work['qualification'] = $qualification_string.$feedback;
2947
            } else {
2948
                $work['qualification'] = $qualification_string.$feedback.$hasCorrection;
2949
            }
2950
2951
            $work['qualification_only'] = $qualification_string;
2952
2953
            // Date.
2954
            $work_date = api_get_local_time($work['sent_date']);
2955
            $date = date_to_str_ago($work['sent_date']).' '.$work_date;
2956
            $work['formatted_date'] = $work_date.' '.$add_string;
2957
            $work['expiry_note'] = $add_string;
2958
            $work['sent_date_from_db'] = $work['sent_date'];
2959
            $work['sent_date'] = '<div class="work-date" title="'.$date.'">'.
2960
                $add_string.' '.Display::dateToStringAgoAndLongDate($work['sent_date']).'</div>';
2961
            $work['status'] = $hasCorrection;
2962
            $work['has_correction'] = $hasCorrection;
2963
            $work['course'] = $courseInfo['title'];
2964
2965
            if (isset($parentList[$work['parent_id']])) {
2966
                $parent = $parentList[$work['parent_id']];
2967
            } else {
2968
                $parent = get_work_data_by_id($work['parent_id'], $courseId);
2969
                $parentList[$work['parent_id']] = $parent;
2970
            }
2971
            $work['work_name'] = $parent['title'];
2972
2973
            // Actions.
2974
            $action = '';
2975
            if (api_is_allowed_to_edit()) {
2976
                if ($blockScoreEdition && !api_is_platform_admin() && !empty($work['qualification_score'])) {
2977
                    $rateLink = '';
2978
                } else {
2979
                    $rateLink = '<a href="'.$url.'view.php?'.$cidReq.'&id='.$item_id.'" title="'.get_lang('View').'">'.
2980
                        $rateIcon.'</a> ';
2981
                }
2982
                $action .= $rateLink;
2983
2984
                if ($unoconv && empty($work['contains_file'])) {
2985
                    $action .= '<a
2986
                        href="'.$url.'work_list_all.php?'.$cidReq.'&id='.$workId.'&action=export_to_doc&item_id='.$item_id.'"
2987
                        title="'.get_lang('ExportToDoc').'" >'.
2988
                        Display::return_icon('export_doc.png', get_lang('ExportToDoc'), [], ICON_SIZE_SMALL).'</a> ';
2989
                }
2990
2991
                $alreadyUploaded = '';
2992
                if (!empty($work['url_correction'])) {
2993
                    $alreadyUploaded = '<br />'.$work['title_correction'].' '.$correctionIconSmall;
2994
                }
2995
2996
                $correction = '
2997
                    <form
2998
                    id="file_upload_'.$item_id.'"
2999
                    class="work_correction_file_upload file_upload_small fileinput-button"
3000
                    action="'.api_get_path(WEB_AJAX_PATH).'work.ajax.php?'.$cidReq.'&a=upload_correction_file&item_id='.$item_id.'"
3001
                    method="POST"
3002
                    enctype="multipart/form-data"
3003
                    >
3004
                    <div id="progress_'.$item_id.'" class="text-center button-load">
3005
                        '.addslashes(get_lang('ClickOrDropOneFileHere')).'
3006
                        '.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
3007
                        '.$alreadyUploaded.'
3008
                    </div>
3009
                    <input id="file_'.$item_id.'" type="file" name="file" class="" multiple>
3010
                    </form>
3011
                ';
3012
3013
                $correction .= "<script>
3014
                $(function() {
3015
                    $('.work_correction_file_upload').each(function () {
3016
                        $(this).fileupload({
3017
                            dropZone: $(this)
3018
                        });
3019
                    });
3020
3021
                    $('#file_upload_".$item_id."').fileupload({
3022
                        add: function (e, data) {
3023
                            $('#progress_$item_id').html();
3024
                            data.context = $('#progress_$item_id').html('$loadingText <br /> <em class=\"fa fa-spinner fa-pulse fa-fw\"></em>');
3025
                            data.submit();
3026
                            $(this).removeClass('hover');
3027
                        },
3028
                        dragover: function (e, data) {
3029
                            $(this).addClass('hover');
3030
                        },
3031
                        done: function (e, data) {
3032
                            if (data._response.result.name) {
3033
                                $('#progress_$item_id').html('$uploadedText '+data._response.result.result+'<br />'+data._response.result.name);
3034
                            } else {
3035
                                $('#progress_$item_id').html('$failsUploadText $failsUploadIcon');
3036
                            }
3037
                            $(this).removeClass('hover');
3038
                        }
3039
                    });
3040
                    $('#file_upload_".$item_id."').on('dragleave', function (e) {
3041
                        // dragleave callback implementation
3042
                        $(this).removeClass('hover');
3043
                    });
3044
                });
3045
                </script>";
3046
3047
                if ($locked) {
3048
                    if ($qualification_exists) {
3049
                        $action .= Display::return_icon(
3050
                            'edit_na.png',
3051
                            get_lang('CorrectAndRate'),
3052
                            [],
3053
                            ICON_SIZE_SMALL
3054
                        );
3055
                    } else {
3056
                        $action .= Display::return_icon('edit_na.png', get_lang('Comment'), [], ICON_SIZE_SMALL);
3057
                    }
3058
                } else {
3059
                    if ($blockEdition && !api_is_platform_admin()) {
3060
                        $editLink = '';
3061
                    } else {
3062
                        $editIcon = Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL);
3063
                        if ($qualification_exists) {
3064
                            $editLink = '<a
3065
                                href="'.$url.'edit.php?'.$cidReq.'&item_id='.$item_id.'&id='.$work['parent_id'].'"
3066
                                title="'.get_lang('Edit').'"  >'.
3067
                                $editIcon.
3068
                            '</a>';
3069
                        } else {
3070
                            $editLink = '<a
3071
                                href="'.$url.'edit.php?'.$cidReq.'&item_id='.$item_id.'&id='.$work['parent_id'].'"
3072
                                title="'.get_lang('Modify').'">'.
3073
                                $editIcon.'</a>';
3074
                        }
3075
                    }
3076
                    $action .= $editLink;
3077
                }
3078
3079
                /*if ($work['contains_file']) {
3080
                    if ($locked) {
3081
                        $action .= Display::return_icon(
3082
                            'move_na.png',
3083
                            get_lang('Move'),
3084
                            [],
3085
                            ICON_SIZE_SMALL
3086
                        );
3087
                    } else {
3088
                        $action .= '<a href="'.$url.'work.php?'.$cidReq.'&action=move&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Move').'">'.
3089
                            Display::return_icon('move.png', get_lang('Move'), [], ICON_SIZE_SMALL).'</a>';
3090
                    }
3091
                }*/
3092
3093
                /*if ($work['accepted'] == '1') {
3094
                    $action .= '<a href="'.$url.'work_list_all.php?'.$cidReq.'&id='.$workId.'&action=make_invisible&item_id='.$item_id.'" title="'.get_lang('Invisible').'" >'.
3095
                        Display::return_icon('visible.png', get_lang('Invisible'), [], ICON_SIZE_SMALL).'</a>';
3096
                } else {
3097
                    $action .= '<a href="'.$url.'work_list_all.php?'.$cidReq.'&id='.$workId.'&action=make_visible&item_id='.$item_id.'" title="'.get_lang('Visible').'" >'.
3098
                        Display::return_icon('invisible.png', get_lang('Visible'), [], ICON_SIZE_SMALL).'</a> ';
3099
                }*/
3100
                /*if ($locked) {
3101
                    $action .= Display::return_icon('delete_na.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
3102
                } else {
3103
                    $action .= '<a href="'.$url.'work_list_all.php?'.$cidReq.'&id='.$workId.'&action=delete&item_id='.$item_id.'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'" >'.
3104
                        Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
3105
                }*/
3106
            } elseif ($is_author && (empty($work['qualificator_id']) || 0 == $work['qualificator_id'])) {
3107
                $action .= '<a href="'.$url.'view.php?'.$cidReq.'&id='.$item_id.'" title="'.get_lang('View').'">'.
3108
                    Display::return_icon('default.png', get_lang('View'), [], ICON_SIZE_SMALL).'</a>';
3109
3110
                if (1 == api_get_course_setting('student_delete_own_publication')) {
3111
                    if (api_is_allowed_to_session_edit(false, true)) {
3112
                        $action .= '<a href="'.$url.'edit.php?'.$cidReq.'&item_id='.$item_id.'&id='.$work['parent_id'].'" title="'.get_lang('Modify').'">'.
3113
                            Display::return_icon('edit.png', get_lang('Comment'), [], ICON_SIZE_SMALL).'</a>';
3114
                    }
3115
                    $action .= ' <a href="'.$url.'work_list.php?'.$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').'"  >'.
3116
                        Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
3117
                }
3118
            } else {
3119
                $action .= '<a href="'.$url.'view.php?'.$cidReq.'&id='.$item_id.'" title="'.get_lang('View').'">'.
3120
                    Display::return_icon('default.png', get_lang('View'), [], ICON_SIZE_SMALL).'</a>';
3121
            }
3122
3123
            // Status.
3124
            if (empty($work['qualificator_id'])) {
3125
                $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
3126
            } else {
3127
                $qualificator_id = Display::label(get_lang('Revised'), 'success');
3128
            }
3129
            $work['qualificator_id'] = $qualificator_id.' '.$hasCorrection;
3130
            $work['actions'] = '<div class="work-action">'.$linkToDownload.$action.'</div>';
3131
            $work['correction'] = $correction;
3132
3133
            /*if (!empty($compilation) && $is_allowed_to_edit) {
3134
                $compilationId = $compilation->getCompilatioId($item_id, $courseId);
3135
                if ($compilationId) {
3136
                    $actionCompilatio = "<div id='id_avancement".$item_id."' class='compilation_block'>
3137
                        ".$loading.'&nbsp;'.get_lang('CompilatioConnectionWithServer').'</div>';
3138
                } else {
3139
                    $workDirectory = api_get_path(SYS_COURSE_PATH).$courseInfo['directory'];
3140
                    if (!Compilatio::verifiFileType($dbTitle)) {
3141
                        $actionCompilatio = get_lang('FileFormatNotSupported');
3142
                    } elseif (filesize($workDirectory.'/'.$work['url']) > $compilation->getMaxFileSize()) {
3143
                        $sizeFile = round(filesize($workDirectory.'/'.$work['url']) / 1000000);
3144
                        $actionCompilatio = get_lang('UplFileTooBig').': '.format_file_size($sizeFile).'<br />';
3145
                    } else {
3146
                        $actionCompilatio = "<div id='id_avancement".$item_id."' class='compilation_block'>";
3147
                        $actionCompilatio .= Display::url(
3148
                            get_lang('CompilatioAnalysis'),
3149
                            'javascript:void(0)',
3150
                            [
3151
                                'class' => 'getSingleCompilatio btn btn-primary btn-xs',
3152
                                'onclick' => "getSingleCompilatio($item_id);",
3153
                            ]
3154
                        );
3155
                        $actionCompilatio .= get_lang('CompilatioWithCompilatio');
3156
                    }
3157
                }
3158
                $work['compilatio'] = $actionCompilatio;
3159
            }*/
3160
            $works[] = $work;
3161
        }
3162
    }
3163
3164
    return $works;
3165
}
3166
/**
3167
 * Send reminder to users who have not given the task.
3168
 *
3169
 * @param int
3170
 *
3171
 * @return array
3172
 *
3173
 * @author cvargas [email protected] cfasanando, [email protected]
3174
 */
3175
function send_reminder_users_without_publication($task_data)
3176
{
3177
    $_course = api_get_course_info();
3178
    $task_id = $task_data['iid'];
3179
    $task_title = !empty($task_data['title']) ? $task_data['title'] : basename($task_data['url']);
3180
    $subject = '['.api_get_setting('siteName').'] ';
3181
3182
    // The body can be as long as you wish, and any combination of text and variables
3183
    $content = get_lang('Please remember you still have to send an assignment')."\n".get_lang('Course name').' : '.$_course['name']."\n";
3184
    $content .= get_lang('Assignment name').' : '.$task_title."\n";
3185
    $list_users = get_list_users_without_publication($task_id);
3186
    $mails_sent_to = [];
3187
    foreach ($list_users as $user) {
3188
        $name_user = api_get_person_name($user[1], $user[0], null, PERSON_NAME_EMAIL_ADDRESS);
3189
        $dear_line = get_lang('Dear').' '.api_get_person_name($user[1], $user[0]).", \n\n";
3190
        $body = $dear_line.$content;
3191
        MessageManager::send_message($user[3], $subject, $body);
3192
        $mails_sent_to[] = $name_user;
3193
    }
3194
3195
    return $mails_sent_to;
3196
}
3197
3198
/**
3199
 * @param int $workId    The work ID
3200
 * @param int $courseId  The course ID
3201
 * @param int $sessionId Optional. The session ID
3202
 */
3203
function sendEmailToDrhOnHomeworkCreation($workId, $courseId, $sessionId = 0)
3204
{
3205
    $courseInfo = api_get_course_info_by_id($courseId);
3206
    $assignment = get_work_assignment_by_id($workId, $courseId);
3207
    $work = get_work_data_by_id($workId, $courseId, $sessionId);
3208
    $workInfo = array_merge($assignment, $work);
3209
3210
    if (empty($sessionId)) {
3211
        $students = CourseManager::get_student_list_from_course_code($courseInfo['code']);
3212
    } else {
3213
        $students = CourseManager::get_student_list_from_course_code($courseInfo['code'], true, $sessionId);
3214
    }
3215
3216
    $bodyView = new Template(null, false, false, false, false, false);
3217
3218
    foreach ($students as $student) {
3219
        $studentInfo = api_get_user_info($student['user_id']);
3220
        if (empty($studentInfo)) {
3221
            continue;
3222
        }
3223
3224
        $hrms = UserManager::getDrhListFromUser($student['id']);
3225
        foreach ($hrms as $hrm) {
3226
            $hrmName = api_get_person_name($hrm['firstname'], $hrm['lastname'], null, PERSON_NAME_EMAIL_ADDRESS);
3227
3228
            $bodyView->assign('hrm_name', $hrmName);
3229
            $bodyView->assign('student', $studentInfo);
3230
            $bodyView->assign('course', $courseInfo);
3231
            $bodyView->assign('course_link', api_get_course_url($courseInfo['code'], $sessionId));
3232
            $bodyView->assign('work', $workInfo);
3233
3234
            $bodyTemplate = $bodyView->get_template('mail/new_work_alert_hrm.tpl');
3235
3236
            MessageManager::send_message(
3237
                $hrm['id'],
3238
                sprintf(
3239
                    get_lang('%s got a new assignment in course %s'),
3240
                    $student['firstname'],
3241
                    $courseInfo['title']
3242
                ),
3243
                $bodyView->fetch($bodyTemplate)
3244
            );
3245
        }
3246
    }
3247
}
3248
3249
/**
3250
 * Sends an email to the students of a course when a homework is created.
3251
 *
3252
 * @param int $workId
3253
 * @param int $courseId
3254
 * @param int $sessionId
3255
 *
3256
 * @author Guillaume Viguier <[email protected]>
3257
 * @author Julio Montoya <[email protected]> Adding session support - 2011
3258
 */
3259
function sendEmailToStudentsOnHomeworkCreation($workId, $courseId, $sessionId = 0)
3260
{
3261
    $courseInfo = api_get_course_info_by_id($courseId);
3262
    $courseCode = $courseInfo['code'];
3263
    // Get the students of the course
3264
    if (empty($sessionId)) {
3265
        $students = CourseManager::get_student_list_from_course_code($courseCode);
3266
    } else {
3267
        $students = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionId);
3268
    }
3269
    $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('An assignment was created');
3270
    $currentUser = api_get_user_info(api_get_user_id());
3271
    if (!empty($students)) {
3272
        foreach ($students as $student) {
3273
            $user_info = api_get_user_info($student['user_id']);
3274
            if (!empty($user_info)) {
3275
                $link = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq().'&id='.$workId;
3276
                $emailbody = get_lang('Dear').' '.$user_info['complete_name'].",\n\n";
3277
                $emailbody .= get_lang('An assignment has been added to course').' '.$courseCode.'. '."\n\n".
3278
                    '<a href="'.$link.'">'.get_lang('Please check the assignments page.').'</a>';
3279
                $emailbody .= "\n\n".$currentUser['complete_name'];
3280
3281
                $additionalParameters = [
3282
                    'smsType' => SmsPlugin::ASSIGNMENT_BEEN_CREATED_COURSE,
3283
                    'userId' => $student['user_id'],
3284
                    'courseTitle' => $courseCode,
3285
                    'link' => $link,
3286
                ];
3287
3288
                MessageManager::send_message_simple(
3289
                    $student['user_id'],
3290
                    $emailsubject,
3291
                    $emailbody,
3292
                    null,
3293
                    false,
3294
                    false,
3295
                    $additionalParameters,
3296
                    false
3297
                );
3298
            }
3299
        }
3300
    }
3301
}
3302
3303
/**
3304
 * @param string $url
3305
 *
3306
 * @return bool
3307
 */
3308
function is_work_exist_by_url($url)
3309
{
3310
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3311
    $url = Database::escape_string($url);
3312
    $sql = "SELECT id FROM $table WHERE url='$url'";
3313
    $result = Database::query($sql);
3314
    if (Database::num_rows($result) > 0) {
3315
        $row = Database::fetch_row($result);
3316
        if (empty($row)) {
3317
            return false;
3318
        } else {
3319
            return true;
3320
        }
3321
    } else {
3322
        return false;
3323
    }
3324
}
3325
3326
/**
3327
 * Check if a user is the author of a work document.
3328
 *
3329
 * @param int $itemId
3330
 * @param int $userId
3331
 * @param int $courseId
3332
 * @param int $sessionId
3333
 *
3334
 * @return bool
3335
 */
3336
function user_is_author($itemId, $userId = null, $courseId = 0, $sessionId = 0)
3337
{
3338
    $userId = (int) $userId;
3339
3340
    if (empty($itemId)) {
3341
        return false;
3342
    }
3343
3344
    if (empty($userId)) {
3345
        $userId = api_get_user_id();
3346
    }
3347
3348
    $isAuthor = false;
3349
    $is_allowed_to_edit = api_is_allowed_to_edit();
3350
3351
    if ($is_allowed_to_edit) {
3352
        $isAuthor = true;
3353
    } else {
3354
        if (empty($courseId)) {
3355
            $courseId = api_get_course_int_id();
3356
        }
3357
        if (empty($sessionId)) {
3358
            $sessionId = api_get_session_id();
3359
        }
3360
3361
        $repo = Container::getStudentPublicationRepository();
3362
        /** @var CStudentPublication $studentPublication */
3363
        $studentPublication = $repo->find($itemId);
3364
        if ($studentPublication->getResourceNode()->getCreator()->getId() === $userId) {
3365
            $isAuthor = true;
3366
        }
3367
3368
        /*$data = api_get_item_property_info($courseId, 'work', $itemId, $sessionId);
3369
        if ($data['insert_user_id'] == $userId) {
3370
            $isAuthor = true;
3371
        }*/
3372
3373
        $workData = get_work_data_by_id($itemId);
3374
        if ($workData['user_id'] == $userId) {
3375
            $isAuthor = true;
3376
        }
3377
    }
3378
3379
    if (!$isAuthor) {
3380
        return false;
3381
    }
3382
3383
    return $isAuthor;
3384
}
3385
3386
/**
3387
 * Get list of users who have not given the task.
3388
 *
3389
 * @param int
3390
 * @param int
3391
 *
3392
 * @return array
3393
 *
3394
 * @author cvargas
3395
 * @author Julio Montoya <[email protected]> Fixing query
3396
 */
3397
function get_list_users_without_publication($task_id, $studentId = 0)
3398
{
3399
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3400
    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3401
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
3402
    $session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3403
3404
    $users = getAllUserToWork($task_id, api_get_course_int_id());
3405
    $users = array_column($users, 'user_id');
3406
3407
    // Condition for the session
3408
    $session_id = api_get_session_id();
3409
    $course_id = api_get_course_int_id();
3410
    $task_id = (int) $task_id;
3411
    $sessionCondition = api_get_session_condition($session_id);
3412
3413
    if (0 == $session_id) {
3414
        $sql = "SELECT user_id as id FROM $work_table
3415
                WHERE
3416
                    c_id = $course_id AND
3417
                    parent_id = '$task_id' AND
3418
                    active IN (0, 1)";
3419
    } else {
3420
        $sql = "SELECT user_id as id FROM $work_table
3421
                WHERE
3422
                    c_id = $course_id AND
3423
                    parent_id = '$task_id' $sessionCondition AND
3424
                    active IN (0, 1)";
3425
    }
3426
3427
    $result = Database::query($sql);
3428
    $users_with_tasks = [];
3429
    while ($row = Database::fetch_array($result)) {
3430
        $users_with_tasks[] = $row['id'];
3431
    }
3432
3433
    if (0 == $session_id) {
3434
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
3435
                      FROM $table_course_user AS cu, $table_user AS u
3436
                      WHERE u.status != 1 and cu.c_id='".$course_id."' AND u.id = cu.user_id";
3437
    } else {
3438
        $sql_users = "SELECT cu.user_id, u.lastname, u.firstname, u.email
3439
                      FROM $session_course_rel_user AS cu, $table_user AS u
3440
                      WHERE
3441
                        u.status != 1 AND
3442
                        cu.c_id='".$course_id."' AND
3443
                        u.id = cu.user_id AND
3444
                        cu.session_id = '".$session_id."'";
3445
    }
3446
3447
    if (!empty($studentId)) {
3448
        $sql_users .= ' AND u.id = '.(int) $studentId;
3449
    }
3450
3451
    $group_id = api_get_group_id();
3452
    $new_group_user_list = [];
3453
3454
    if ($group_id) {
3455
        $groupInfo = GroupManager::get_group_properties($group_id);
3456
        $group_user_list = GroupManager::get_subscribed_users($groupInfo);
3457
        if (!empty($group_user_list)) {
3458
            foreach ($group_user_list as $group_user) {
3459
                $new_group_user_list[] = $group_user['user_id'];
3460
            }
3461
        }
3462
    }
3463
3464
    $result_users = Database::query($sql_users);
3465
    $users_without_tasks = [];
3466
    while ($rowUsers = Database::fetch_array($result_users)) {
3467
        $userId = $rowUsers['user_id'];
3468
        if (in_array($userId, $users_with_tasks)) {
3469
            continue;
3470
        }
3471
3472
        if ($group_id && !in_array($userId, $new_group_user_list)) {
3473
            continue;
3474
        }
3475
3476
        if (!empty($users)) {
3477
            if (!in_array($userId, $users)) {
3478
                continue;
3479
            }
3480
        }
3481
3482
        $row_users = [];
3483
        $row_users[0] = $rowUsers['lastname'];
3484
        $row_users[1] = $rowUsers['firstname'];
3485
        $row_users[2] = Display::encrypted_mailto_link($rowUsers['email']);
3486
        $row_users[3] = $userId;
3487
        $users_without_tasks[] = $row_users;
3488
    }
3489
3490
    return $users_without_tasks;
3491
}
3492
3493
/**
3494
 * Display list of users who have not given the task.
3495
 *
3496
 * @param int task id
3497
 * @param int $studentId
3498
 *
3499
 * @author cvargas [email protected] cfasanando, [email protected]
3500
 * @author Julio Montoya <[email protected]> Fixes
3501
 */
3502
function display_list_users_without_publication($task_id, $studentId = null)
3503
{
3504
    $origin = api_get_origin();
3505
    $table_header[] = [get_lang('Last name'), true];
3506
    $table_header[] = [get_lang('First name'), true];
3507
    $table_header[] = [get_lang('e-mail'), true];
3508
3509
    $data = get_list_users_without_publication($task_id);
3510
3511
    $sorting_options = [];
3512
    $sorting_options['column'] = 1;
3513
    $paging_options = [];
3514
    $my_params = [];
3515
3516
    if (isset($_GET['edit_dir'])) {
3517
        $my_params['edit_dir'] = Security::remove_XSS($_GET['edit_dir']);
3518
    }
3519
    if (isset($_GET['list'])) {
3520
        $my_params['list'] = Security::remove_XSS($_GET['list']);
3521
    }
3522
    $my_params['origin'] = $origin;
3523
    $my_params['id'] = (int) ($_GET['id']);
3524
3525
    //$column_show
3526
    $column_show[] = 1;
3527
    $column_show[] = 1;
3528
    $column_show[] = 1;
3529
    Display::display_sortable_config_table(
3530
        'work',
3531
        $table_header,
3532
        $data,
3533
        $sorting_options,
3534
        $paging_options,
3535
        $my_params,
3536
        $column_show
3537
    );
3538
}
3539
3540
/**
3541
 * @param int $documentId
3542
 * @param int $workId
3543
 * @param int $courseId
3544
 */
3545
function addDocumentToWork($documentId, $workId, $courseId)
3546
{
3547
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
3548
    $params = [
3549
        'document_id' => $documentId,
3550
        'work_id' => $workId,
3551
        'c_id' => $courseId,
3552
    ];
3553
    Database::insert($table, $params);
3554
}
3555
3556
/**
3557
 * @param int $documentId
3558
 * @param int $workId
3559
 * @param int $courseId
3560
 *
3561
 * @return array
3562
 */
3563
function getDocumentToWork($documentId, $workId, $courseId)
3564
{
3565
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
3566
    $params = [
3567
        'document_id = ? and work_id = ? and c_id = ?' => [$documentId, $workId, $courseId],
3568
    ];
3569
3570
    return Database::select('*', $table, ['where' => $params]);
3571
}
3572
3573
/**
3574
 * @param int $documentId
3575
 * @param int $workId
3576
 * @param int $courseId
3577
 * @param int $sessionId
3578
 * @param int $userId
3579
 * @param int $active
3580
 *
3581
 * @return array
3582
 */
3583
function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $userId, $active = 1)
3584
{
3585
    $workRel = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
3586
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
3587
3588
    $documentId = (int) $documentId;
3589
    $workId = (int) $workId;
3590
    $courseId = (int) $courseId;
3591
    $userId = (int) $userId;
3592
    $sessionId = (int) $sessionId;
3593
    $active = (int) $active;
3594
    $sessionCondition = api_get_session_condition($sessionId);
3595
3596
    $sql = "SELECT w.* FROM $work w
3597
            INNER JOIN $workRel rel
3598
            ON (w.parent_id = rel.work_id)
3599
            WHERE
3600
                w.document_id = $documentId AND
3601
                w.parent_id = $workId AND
3602
                w.c_id = $courseId
3603
                $sessionCondition AND
3604
                user_id = $userId AND
3605
                active = $active
3606
            ";
3607
3608
    $result = Database::query($sql);
3609
    $workInfo = [];
3610
    if (Database::num_rows($result)) {
3611
        $workInfo = Database::fetch_array($result, 'ASSOC');
3612
    }
3613
3614
    return $workInfo;
3615
}
3616
3617
/**
3618
 * @param int $workId
3619
 * @param int $courseId
3620
 *
3621
 * @return array
3622
 */
3623
function getAllDocumentToWork($workId, $courseId)
3624
{
3625
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
3626
    $params = [
3627
        'work_id = ? and c_id = ?' => [$workId, $courseId],
3628
    ];
3629
3630
    return Database::select('*', $table, ['where' => $params]);
3631
}
3632
3633
/**
3634
 * @param int $documentId
3635
 * @param int $workId
3636
 * @param int $courseId
3637
 */
3638
function deleteDocumentToWork($documentId, $workId, $courseId)
3639
{
3640
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_DOCUMENT);
3641
    $params = [
3642
        'document_id = ? and work_id = ? and c_id = ?' => [$documentId, $workId, $courseId],
3643
    ];
3644
    Database::delete($table, $params);
3645
}
3646
3647
/**
3648
 * @param int $userId
3649
 * @param int $workId
3650
 * @param int $courseId
3651
 */
3652
function addUserToWork($userId, $workId, $courseId)
3653
{
3654
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
3655
    $params = [
3656
        'user_id' => $userId,
3657
        'work_id' => $workId,
3658
        'c_id' => $courseId,
3659
    ];
3660
    Database::insert($table, $params);
3661
}
3662
3663
/**
3664
 * @param int $userId
3665
 * @param int $workId
3666
 * @param int $courseId
3667
 *
3668
 * @return array
3669
 */
3670
function getUserToWork($userId, $workId, $courseId)
3671
{
3672
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
3673
    $params = [
3674
        'user_id = ? and work_id = ? and c_id = ?' => [$userId, $workId, $courseId],
3675
    ];
3676
3677
    return Database::select('*', $table, ['where' => $params]);
3678
}
3679
3680
/**
3681
 * @param int  $workId
3682
 * @param int  $courseId
3683
 * @param bool $getCount
3684
 *
3685
 * @return array|int
3686
 */
3687
function getAllUserToWork($workId, $courseId, $getCount = false)
3688
{
3689
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
3690
    $params = [
3691
        'work_id = ? and c_id = ?' => [$workId, $courseId],
3692
    ];
3693
    if ($getCount) {
3694
        $count = 0;
3695
        $result = Database::select(
3696
            'count(user_id) as count',
3697
            $table,
3698
            ['where' => $params],
3699
            'simple'
3700
        );
3701
        if (!empty($result)) {
3702
            $count = (int) ($result['count']);
3703
        }
3704
3705
        return $count;
3706
    } else {
3707
        return Database::select('*', $table, ['where' => $params]);
3708
    }
3709
}
3710
3711
/**
3712
 * @param int $userId
3713
 * @param int $workId
3714
 * @param int $courseId
3715
 */
3716
function deleteUserToWork($userId, $workId, $courseId)
3717
{
3718
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
3719
    $params = [
3720
        'user_id = ? and work_id = ? and c_id = ?' => [$userId, $workId, $courseId],
3721
    ];
3722
    Database::delete($table, $params);
3723
}
3724
3725
/**
3726
 * @param int $userId
3727
 * @param int $workId
3728
 * @param int $courseId
3729
 *
3730
 * @return bool
3731
 */
3732
function userIsSubscribedToWork($userId, $workId, $courseId)
3733
{
3734
    $subscribedUsers = getAllUserToWork($workId, $courseId);
3735
3736
    if (empty($subscribedUsers)) {
3737
        return true;
3738
    } else {
3739
        $subscribedUsersList = [];
3740
        foreach ($subscribedUsers as $item) {
3741
            $subscribedUsersList[] = $item['user_id'];
3742
        }
3743
        if (in_array($userId, $subscribedUsersList)) {
3744
            return true;
3745
        }
3746
    }
3747
3748
    return false;
3749
}
3750
3751
/**
3752
 * Get the list of students that have to submit their work.
3753
 *
3754
 * @param int  $workId    The internal ID of the assignment
3755
 * @param int  $courseId  The course ID
3756
 * @param int  $groupId   The group ID, if any
3757
 * @param int  $sessionId The session ID, if any
3758
 * @param bool $getCount  Whether we want just the amount or the full result
3759
 *
3760
 * @return array|int An integer (if we just asked for the count) or an array of users
3761
 */
3762
function getStudentSubscribedToWork(
3763
    $workId,
3764
    $courseId,
3765
    $groupId = null,
3766
    $sessionId = null,
3767
    $getCount = false
3768
) {
3769
    $usersInWork = null;
3770
    $usersInCourse = null;
3771
3772
    if (empty($groupId)) {
3773
        $courseInfo = api_get_course_info_by_id($courseId);
3774
        $status = STUDENT;
3775
        if (!empty($sessionId)) {
3776
            $status = 0;
3777
        }
3778
        $usersInCourse = CourseManager::get_user_list_from_course_code(
3779
            $courseInfo['code'],
3780
            $sessionId,
3781
            null,
3782
            null,
3783
            $status,
3784
            $getCount
3785
        );
3786
    } else {
3787
        $usersInCourse = GroupManager::get_users(
3788
            $groupId,
3789
            false,
3790
            null,
3791
            null,
3792
            $getCount,
3793
            $courseId
3794
        );
3795
    }
3796
3797
    $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
3798
3799
    if (empty($usersInWork)) {
3800
        return $usersInCourse;
3801
    } else {
3802
        return $usersInWork;
3803
    }
3804
}
3805
3806
/**
3807
 * @param int  $userId
3808
 * @param int  $workId
3809
 * @param int  $courseId
3810
 * @param bool $forceAccessForCourseAdmins
3811
 *
3812
 * @return bool
3813
 */
3814
function allowOnlySubscribedUser($userId, $workId, $courseId, $forceAccessForCourseAdmins = false)
3815
{
3816
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
3817
        return true;
3818
    }
3819
3820
    if ($forceAccessForCourseAdmins) {
3821
        if (api_is_course_admin() || api_is_coach()) {
3822
            return true;
3823
        }
3824
    }
3825
3826
    return userIsSubscribedToWork($userId, $workId, $courseId);
3827
}
3828
3829
/**
3830
 * @param int   $workId
3831
 * @param array $courseInfo
3832
 * @param int   $documentId
3833
 *
3834
 * @return CDocument
3835
 */
3836
function getDocumentTemplateFromWork($workId, $courseInfo, $documentId)
3837
{
3838
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
3839
    $docRepo = Container::getDocumentRepository();
3840
    if (!empty($documents)) {
3841
        foreach ($documents as $doc) {
3842
            if ($documentId !== $doc['document_id']) {
3843
                continue;
3844
            }
3845
3846
            /** @var CDocument $docData */
3847
            $docData = $docRepo->find($doc['document_id']);
3848
3849
            return $docData;
3850
3851
            /*$fileInfo = pathinfo($docData['path']);
3852
            if ('html' == $fileInfo['extension']) {
3853
                if (file_exists($docData['absolute_path']) && is_file($docData['absolute_path'])) {
3854
                    $docData['file_content'] = file_get_contents($docData['absolute_path']);
3855
3856
                    return $docData;
3857
                }
3858
            }*/
3859
        }
3860
    }
3861
3862
    return null;
3863
}
3864
3865
/**
3866
 * @param int   $workId
3867
 * @param array $courseInfo
3868
 *
3869
 * @return string
3870
 */
3871
function getAllDocumentsFromWorkToString($workId, $courseInfo)
3872
{
3873
    $documents = getAllDocumentToWork($workId, $courseInfo['real_id']);
3874
    $docRepo = Container::getDocumentRepository();
3875
    $content = null;
3876
    if (!empty($documents)) {
3877
        $content .= '<ul class="nav nav-list well">';
3878
        $content .= '<li class="nav-header">'.get_lang('Documents').'</li>';
3879
        foreach ($documents as $doc) {
3880
            /** @var CDocument $docData */
3881
            $docData = $docRepo->find($doc['document_id']);
3882
            $url = $docRepo->getResourceFileUrl($docData);
3883
            if ($docData) {
3884
                $content .= '<li>
3885
                                <a class="link_to_download" target="_blank" href="'.$url.'">'.
3886
                                    $docData->getTitle().'
3887
                                </a>
3888
                            </li>';
3889
            }
3890
        }
3891
        $content .= '</ul><br />';
3892
    }
3893
3894
    return $content;
3895
}
3896
3897
/**
3898
 * Returns fck editor toolbar.
3899
 *
3900
 * @return array
3901
 */
3902
function getWorkDescriptionToolbar()
3903
{
3904
    return [
3905
        'ToolbarStartExpanded' => 'true',
3906
        'ToolbarSet' => 'Work',
3907
        'Width' => '100%',
3908
        'Height' => '400',
3909
    ];
3910
}
3911
3912
function getWorkComments(CStudentPublication $work)
3913
{
3914
   $comments = $work->getComments();
3915
   $commentList = [];
3916
    if (!empty($comments)) {
3917
        foreach ($comments as $comment) {
3918
            //$userInfo = api_get_user_info($comment['user_id']);
3919
            //$comment['picture'] = $userInfo['avatar'];
3920
            //$comment['complete_name'] = $userInfo['complete_name_with_username'];
3921
            $commentList[] = getWorkComment($comment);
3922
        }
3923
    }
3924
3925
    return $commentList;
3926
}
3927
3928
/**
3929
 * Get total score from a work list.
3930
 *
3931
 * @param $workList
3932
 *
3933
 * @return int|null
3934
 */
3935
function getTotalWorkScore($workList)
3936
{
3937
    $count = 0;
3938
    foreach ($workList as $data) {
3939
        $count += $data['qualification_score'];
3940
    }
3941
3942
    return $count;
3943
}
3944
3945
/**
3946
 * Get comment count from a work list (docs sent by students).
3947
 *
3948
 * @param array $workList
3949
 * @param array $courseInfo
3950
 *
3951
 * @return int|null
3952
 */
3953
function getTotalWorkComment($workList, $courseInfo = [])
3954
{
3955
    if (empty($courseInfo)) {
3956
        $courseInfo = api_get_course_info();
3957
    }
3958
3959
    $count = 0;
3960
    foreach ($workList as $data) {
3961
        $count += getWorkCommentCount($data['id'], $courseInfo);
3962
    }
3963
3964
    return $count;
3965
}
3966
3967
/**
3968
 * Get comment count for a specific work sent by a student.
3969
 *
3970
 * @param int   $id
3971
 * @param array $courseInfo
3972
 *
3973
 * @return int
3974
 */
3975
function getWorkCommentCount($id, $courseInfo = [])
3976
{
3977
    if (empty($courseInfo)) {
3978
        $courseInfo = api_get_course_info();
3979
    }
3980
3981
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
3982
    $id = (int) $id;
3983
3984
    $sql = "SELECT count(*) as count
3985
            FROM $commentTable
3986
            WHERE work_id = $id AND c_id = ".$courseInfo['real_id'];
3987
3988
    $result = Database::query($sql);
3989
    if (Database::num_rows($result)) {
3990
        $comment = Database::fetch_array($result);
3991
3992
        return $comment['count'];
3993
    }
3994
3995
    return 0;
3996
}
3997
3998
/**
3999
 * Get comment count for a specific parent.
4000
 *
4001
 * @param int   $parentId
4002
 * @param array $courseInfo
4003
 * @param int   $sessionId
4004
 *
4005
 * @return int
4006
 */
4007
function getWorkCommentCountFromParent(
4008
    $parentId,
4009
    $courseInfo = [],
4010
    $sessionId = 0
4011
) {
4012
    if (empty($courseInfo)) {
4013
        $courseInfo = api_get_course_info();
4014
    }
4015
4016
    if (empty($sessionId)) {
4017
        $sessionId = api_get_session_id();
4018
    } else {
4019
        $sessionId = (int) $sessionId;
4020
    }
4021
4022
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4023
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
4024
    $parentId = (int) $parentId;
4025
    $sessionCondition = api_get_session_condition($sessionId, false, false, 'w.session_id');
4026
4027
    $sql = "SELECT count(*) as count
4028
            FROM $commentTable c
4029
            INNER JOIN $work w
4030
            ON c.c_id = w.c_id AND w.iid = c.work_id
4031
            WHERE
4032
                $sessionCondition AND
4033
                parent_id = $parentId AND
4034
                w.c_id = ".$courseInfo['real_id'];
4035
4036
    $result = Database::query($sql);
4037
    if (Database::num_rows($result)) {
4038
        $comment = Database::fetch_array($result);
4039
4040
        return $comment['count'];
4041
    }
4042
4043
    return 0;
4044
}
4045
4046
/**
4047
 * Get last work information from parent.
4048
 *
4049
 * @param int   $parentId
4050
 * @param array $courseInfo
4051
 * @param int   $sessionId
4052
 *
4053
 * @return int
4054
 */
4055
function getLastWorkStudentFromParent(
4056
    $parentId,
4057
    $courseInfo = [],
4058
    $sessionId = 0
4059
) {
4060
    if (empty($courseInfo)) {
4061
        $courseInfo = api_get_course_info();
4062
    }
4063
4064
    if (empty($sessionId)) {
4065
        $sessionId = api_get_session_id();
4066
    } else {
4067
        $sessionId = (int) $sessionId;
4068
    }
4069
4070
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4071
    $sessionCondition = api_get_session_condition($sessionId, false);
4072
    $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
4073
    $parentId = (int) $parentId;
4074
4075
    $sql = "SELECT w.*
4076
            FROM $commentTable c INNER JOIN $work w
4077
            ON c.c_id = w.c_id AND w.iid = c.work_id
4078
            WHERE
4079
                $sessionCondition AND
4080
                parent_id = $parentId AND
4081
                w.c_id = ".$courseInfo['real_id'].'
4082
            ORDER BY w.sent_date
4083
            LIMIT 1
4084
            ';
4085
4086
    $result = Database::query($sql);
4087
    if (Database::num_rows($result)) {
4088
        return Database::fetch_array($result, 'ASSOC');
4089
    }
4090
4091
    return [];
4092
}
4093
4094
/**
4095
 * Get last work information from parent.
4096
 *
4097
 * @param int   $userId
4098
 * @param array $parentInfo
4099
 * @param array $courseInfo
4100
 * @param int   $sessionId
4101
 *
4102
 * @return int
4103
 */
4104
function getLastWorkStudentFromParentByUser(
4105
    $userId,
4106
    $parentInfo,
4107
    $courseInfo = [],
4108
    $sessionId = 0
4109
) {
4110
    if (empty($courseInfo)) {
4111
        $courseInfo = api_get_course_info();
4112
    }
4113
4114
    if (empty($sessionId)) {
4115
        $sessionId = api_get_session_id();
4116
    } else {
4117
        $sessionId = (int) $sessionId;
4118
    }
4119
4120
    $userId = (int) $userId;
4121
    $work = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4122
    if (empty($parentInfo)) {
4123
        return false;
4124
    }
4125
    $parentId = $parentInfo['iid'];
4126
4127
    $sessionCondition = api_get_session_condition($sessionId);
4128
4129
    $sql = "SELECT *
4130
            FROM $work
4131
            WHERE
4132
                user_id = $userId
4133
                $sessionCondition AND
4134
                parent_id = $parentId AND
4135
                c_id = ".$courseInfo['real_id'].'
4136
            ORDER BY sent_date DESC
4137
            LIMIT 1
4138
            ';
4139
    $result = Database::query($sql);
4140
    if (Database::num_rows($result)) {
4141
        $work = Database::fetch_array($result, 'ASSOC');
4142
        $work['qualification_rounded'] = formatWorkScore($work['qualification'], $parentInfo['qualification']);
4143
4144
        return $work;
4145
    }
4146
4147
    return [];
4148
}
4149
4150
/**
4151
 * @param float $score
4152
 * @param int   $weight
4153
 *
4154
 * @return string
4155
 */
4156
function formatWorkScore($score, $weight)
4157
{
4158
    $label = 'info';
4159
    $weight = (int) $weight;
4160
    $relativeScore = 0;
4161
    if (!empty($weight)) {
4162
        $relativeScore = $score / $weight;
4163
    }
4164
4165
    if ($relativeScore < 0.5) {
4166
        $label = 'important';
4167
    } elseif ($relativeScore < 0.75) {
4168
        $label = 'warning';
4169
    }
4170
4171
    $scoreBasedInModel = ExerciseLib::convertScoreToModel($relativeScore * 100);
4172
    if (empty($scoreBasedInModel)) {
4173
        $finalScore = api_number_format($score, 1).' / '.$weight;
4174
4175
        return Display::label(
4176
            $finalScore,
4177
            $label
4178
        );
4179
    }
4180
4181
    return $scoreBasedInModel;
4182
}
4183
4184
function getWorkComment(CStudentPublicationComment $commentEntity, array $courseInfo = []): array
4185
{
4186
    if (empty($courseInfo)) {
4187
        $courseInfo = api_get_course_info();
4188
    }
4189
4190
    if (empty($courseInfo['real_id'])) {
4191
        return [];
4192
    }
4193
4194
    $repo = Container::getStudentPublicationCommentRepository();
4195
4196
    $comment = [];
4197
    if ($commentEntity) {
4198
        $filePath = null;
4199
        $fileUrl = null;
4200
        $deleteUrl = null;
4201
        $fileName = null;
4202
        $id = $commentEntity->getIid();
4203
        if ($commentEntity->getResourceNode()->hasResourceFile()) {
4204
            $fileUrl = $repo->getResourceFileDownloadUrl($commentEntity);
4205
            $workId = $commentEntity->getPublication()->getIid();
4206
            $filePath = '';
4207
            $deleteUrl = api_get_path(WEB_CODE_PATH).
4208
                'work/view.php?'.api_get_cidreq().'&id='.$workId.'&action=delete_attachment&comment_id='.$id;
4209
            $fileName = $commentEntity->getResourceNode()->getResourceFile()->getName();
4210
        }
4211
        $comment['comment'] = $commentEntity->getComment();
4212
        $comment['delete_file_url'] = $deleteUrl;
4213
        $comment['file_path'] = $filePath;
4214
        $comment['file_url'] = $fileUrl;
4215
        $comment['file_name_to_show'] = $fileName;
4216
        $comment['sent_at_with_label'] = Display::dateToStringAgoAndLongDate($commentEntity->getSentAt());
4217
    }
4218
4219
    return $comment;
4220
}
4221
4222
/**
4223
 * @param int   $id
4224
 * @param array $courseInfo
4225
 */
4226
function deleteCommentFile($id, $courseInfo = [])
4227
{
4228
    $repo = Container::getStudentPublicationCommentRepository();
4229
    $em = Database::getManager();
4230
    $criteria = [
4231
        'iid' => $id,
4232
        'cId' => $courseInfo['real_id'],
4233
    ];
4234
4235
    /** @var CStudentPublicationComment $commentEntity */
4236
    $commentEntity = $repo->findOneBy($criteria);
4237
4238
    if ($commentEntity->getResourceNode()->hasResourceFile()) {
4239
        $file = $commentEntity->getResourceNode()->getResourceFile();
4240
4241
        $commentEntity->getResourceNode()->setResourceFile(null);
4242
        $em->remove($file);
4243
        $em->flush();
4244
    }
4245
4246
    /*
4247
    if (isset($workComment['file']) && !empty($workComment['file'])) {
4248
        if (file_exists($workComment['file_path'])) {
4249
            $result = my_delete($workComment['file_path']);
4250
            if ($result) {
4251
                $commentTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT_COMMENT);
4252
                $params = ['file' => ''];
4253
                Database::update(
4254
                    $commentTable,
4255
                    $params,
4256
                    ['id = ? AND c_id = ? ' => [$workComment['iid'], $workComment['c_id']]]
4257
                );
4258
            }
4259
        }
4260
    }*/
4261
}
4262
4263
/**
4264
 * Adds a comments to the work document.
4265
 *
4266
 * @param array               $courseInfo
4267
 * @param int                 $userId
4268
 * @param array               $parentWork
4269
 * @param CStudentPublication $work
4270
 * @param array               $data
4271
 *
4272
 * @return int
4273
 */
4274
function addWorkComment($courseInfo, $userId, $parentWork, CStudentPublication $studentPublication, $data)
4275
{
4276
    $fileData = isset($data['attachment']) ? $data['attachment'] : null;
4277
    // If no attachment and no comment then don't save comment
4278
    if (empty($fileData['name']) && empty($data['comment'])) {
4279
        return false;
4280
    }
4281
    $courseId = $courseInfo['real_id'];
4282
    $courseEntity = api_get_course_entity($courseId);
4283
4284
    $request = Container::getRequest();
4285
    $file = $request->files->get('attachment');
4286
    if (is_array($file)) {
4287
        $file = $file[0];
4288
    }
4289
4290
    $em = Database::getManager();
4291
    $comment = new CStudentPublicationComment();
4292
    $comment
4293
        ->setComment($data['comment'])
4294
        ->setUser(api_get_user_entity($userId))
4295
        ->setPublication($studentPublication)
4296
        ->setParent($studentPublication)
4297
        ->addCourseLink(
4298
            $courseEntity,
4299
            api_get_session_entity(),
4300
            api_get_group_entity()
4301
        );
4302
4303
    $repo = Container::getStudentPublicationCommentRepository();
4304
    $repo->create($comment);
4305
4306
    if ($file) {
4307
        $repo->addFile($comment, $file);
4308
        $em->flush();
4309
    }
4310
4311
    $userIdListToSend = [];
4312
    if (api_is_allowed_to_edit()) {
4313
        if (isset($data['send_email']) && $data['send_email']) {
4314
            // Teacher sends a feedback
4315
            $userIdListToSend = [$studentPublication->getUser()->getId()];
4316
        }
4317
    } else {
4318
        $sessionId = api_get_session_id();
4319
        if (empty($sessionId)) {
4320
            $teachers = CourseManager::get_teacher_list_from_course_code(
4321
                $courseInfo['code']
4322
            );
4323
            if (!empty($teachers)) {
4324
                $userIdListToSend = array_keys($teachers);
4325
            }
4326
        } else {
4327
            $teachers = SessionManager::getCoachesByCourseSession(
4328
                $sessionId,
4329
                $courseInfo['real_id']
4330
            );
4331
4332
            if (!empty($teachers)) {
4333
                $userIdListToSend = array_values($teachers);
4334
            }
4335
        }
4336
4337
        $sendNotification = api_get_course_setting('email_to_teachers_on_new_work_feedback');
4338
        if (1 != $sendNotification) {
4339
            $userIdListToSend = [];
4340
        }
4341
    }
4342
    $id = $studentPublication->getIid();
4343
    $title = $studentPublication->getTitle();
4344
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?'.api_get_cidreq().'&id='.$id;
4345
    $subject = sprintf(get_lang('There\'s a new feedback in work: %s'), $parentWork['title']);
4346
    $content = sprintf(get_lang('There\'s a new feedback in work: %sInWorkXHere'), $title, $url);
4347
4348
    if (!empty($data['comment'])) {
4349
        $content .= '<br /><b>'.get_lang('Comment').':</b><br />'.$data['comment'];
4350
    }
4351
4352
    if (!empty($userIdListToSend)) {
4353
        foreach ($userIdListToSend as $userIdToSend) {
4354
            MessageManager::send_message_simple(
4355
                $userIdToSend,
4356
                $subject,
4357
                $content
4358
            );
4359
        }
4360
    }
4361
4362
    /*if (!empty($commentId) && !empty($fileData)) {
4363
        $workParent = get_work_data_by_id($work['parent_id']);
4364
        if (!empty($workParent)) {
4365
            //$newFileName = 'comment_'.$commentId.'_'.php2phps(api_replace_dangerous_char($fileData['name']));
4366
            //$newFilePath = $uploadDir.'/'.$newFileName;
4367
            $result = move_uploaded_file($fileData['tmp_name'], $newFilePath);
4368
            if ($result) {
4369
                $params = ['file' => $newFileName];
4370
                Database::update(
4371
                    $commentTable,
4372
                    $params,
4373
                    ['id = ? AND c_id = ? ' => [$commentId, $work['c_id']]]
4374
                );
4375
            }
4376
        }
4377
    }*/
4378
}
4379
4380
/**
4381
 * @param array $workParent
4382
 *
4383
 * @return string
4384
 */
4385
function getWorkCommentForm(CStudentPublication $work, $workParent)
4386
{
4387
    $id = $work->getIid();
4388
4389
    $url = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$id.'&action=send_comment&'.api_get_cidreq();
4390
    $form = new FormValidator(
4391
        'work_comment',
4392
        'post',
4393
        $url,
4394
        '',
4395
        ['enctype' => 'multipart/form-data']
4396
    );
4397
4398
    $qualification = $workParent['qualification'];
4399
4400
    $isCourseManager = api_is_platform_admin() || api_is_coach() || api_is_allowed_to_edit(false, false, true);
4401
    $allowEdition = false;
4402
    if ($isCourseManager) {
4403
        $allowEdition = true;
4404
        if (!empty($work->getQualification()) &&
4405
            api_get_configuration_value('block_student_publication_score_edition')
4406
        ) {
4407
            $allowEdition = false;
4408
        }
4409
    }
4410
4411
    if (api_is_platform_admin()) {
4412
        $allowEdition = true;
4413
    }
4414
4415
    if ($allowEdition) {
4416
        if (!empty($qualification) && intval($qualification) > 0) {
4417
            $model = ExerciseLib::getCourseScoreModel();
4418
            if (empty($model)) {
4419
                $form->addFloat(
4420
                    'qualification',
4421
                    [get_lang('Score'), ' / '.$qualification],
4422
                    false,
4423
                    [],
4424
                    false,
4425
                    0,
4426
                    $qualification
4427
                );
4428
            } else {
4429
                ExerciseLib::addScoreModelInput(
4430
                    $form,
4431
                    'qualification',
4432
                    $qualification,
4433
                    $work->getQualification()
4434
                );
4435
            }
4436
            $form->addFile('file', get_lang('Correction'));
4437
            $form->setDefaults(['qualification' => $work->getQualification()]);
4438
        }
4439
    }
4440
4441
    Skill::addSkillsToUserForm(
4442
        $form,
4443
        ITEM_TYPE_STUDENT_PUBLICATION,
4444
        $workParent['iid'],
4445
        $work->getUser()->getId(),
4446
        $id
4447
    );
4448
    $form->addHtmlEditor('comment', get_lang('Comment'), false);
4449
    $form->addFile('attachment', get_lang('Attachment'));
4450
    $form->addElement('hidden', 'iid', $id);
4451
4452
    if (api_is_allowed_to_edit()) {
4453
        $form->addCheckBox(
4454
            'send_email',
4455
            null,
4456
            get_lang('Send message mail to student')
4457
        );
4458
    }
4459
4460
    $form->addButtonSend(get_lang('Send'), 'button');
4461
4462
    return $form->returnForm();
4463
}
4464
4465
/**
4466
 * @param array $homework result of get_work_assignment_by_id()
4467
 *
4468
 * @return array
4469
 */
4470
function getWorkDateValidationStatus($homework)
4471
{
4472
    $message = null;
4473
    $has_expired = false;
4474
    $has_ended = false;
4475
4476
    if (!empty($homework)) {
4477
        if (!empty($homework['expires_on']) || !empty($homework['ends_on'])) {
4478
            $time_now = time();
4479
4480
            if (!empty($homework['expires_on'])) {
4481
                $time_expires = api_strtotime($homework['expires_on'], 'UTC');
4482
                $difference = $time_expires - $time_now;
4483
                if ($difference < 0) {
4484
                    $has_expired = true;
4485
                }
4486
            }
4487
4488
            if (empty($homework['expires_on'])) {
4489
                $has_expired = false;
4490
            }
4491
4492
            if (!empty($homework['ends_on'])) {
4493
                $time_ends = api_strtotime($homework['ends_on'], 'UTC');
4494
                $difference2 = $time_ends - $time_now;
4495
                if ($difference2 < 0) {
4496
                    $has_ended = true;
4497
                }
4498
            }
4499
4500
            $ends_on = api_convert_and_format_date($homework['ends_on']);
4501
            $expires_on = api_convert_and_format_date($homework['expires_on']);
4502
        }
4503
4504
        if ($has_ended) {
4505
            $message = Display::return_message(get_lang('End date already passed').' '.$ends_on, 'error');
4506
        } elseif ($has_expired) {
4507
            $message = Display::return_message(get_lang('Expiry date already passed').' '.$expires_on, 'warning');
4508
        } else {
4509
            if ($has_expired) {
4510
                $message = Display::return_message(get_lang('ExpiryDateToSend messageWorkIs').' '.$expires_on);
4511
            }
4512
        }
4513
    }
4514
4515
    return [
4516
        'message' => $message,
4517
        'has_ended' => $has_ended,
4518
        'has_expired' => $has_expired,
4519
    ];
4520
}
4521
4522
/**
4523
 * @param FormValidator $form
4524
 * @param int           $uploadFormType
4525
 */
4526
function setWorkUploadForm($form, $uploadFormType = 0)
4527
{
4528
    $form->addHeader(get_lang('Upload a document'));
4529
    $form->addHidden('contains_file', 0, ['id' => 'contains_file_id']);
4530
    $form->addHidden('active', 1);
4531
    $form->addHidden('accepted', 1);
4532
    $form->addElement('text', 'title', get_lang('Title'), ['id' => 'file_upload']);
4533
    $form->addElement(
4534
        'text',
4535
        'extension',
4536
        get_lang('File extension'),
4537
        ['id' => 'file_extension', 'readonly' => 'readonly']
4538
    );
4539
    $form->addRule('title', get_lang('Required field'), 'required');
4540
4541
    switch ($uploadFormType) {
4542
        case 0:
4543
            // File and text.
4544
            $form->addElement(
4545
                'file',
4546
                'file',
4547
                get_lang('Upload a document'),
4548
                'size="40" onchange="updateDocumentTitle(this.value)"'
4549
            );
4550
            $form->addProgress();
4551
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
4552
4553
            break;
4554
        case 1:
4555
            // Only text.
4556
            $form->addHtmlEditor('description', get_lang('Description'), false, false, getWorkDescriptionToolbar());
4557
            $form->addRule('description', get_lang('Required field'), 'required');
4558
4559
            break;
4560
        case 2:
4561
            // Only file.
4562
            $form->addElement(
4563
                'file',
4564
                'file',
4565
                get_lang('Upload a document'),
4566
                'size="40" onchange="updateDocumentTitle(this.value)"'
4567
            );
4568
            $form->addProgress();
4569
            $form->addRule('file', get_lang('Required field'), 'required');
4570
4571
            break;
4572
    }
4573
4574
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
4575
}
4576
4577
/**
4578
 * @param array  $my_folder_data
4579
 * @param Course $course
4580
 * @param bool   $isCorrection
4581
 * @param array  $workInfo
4582
 * @param array  $file
4583
 *
4584
 * @return array
4585
 */
4586
function uploadWork($my_folder_data, $course, $isCorrection = false, $workInfo = [], $file = [])
4587
{
4588
    if (isset($_FILES['file']) && !empty($_FILES['file'])) {
4589
        $file = $_FILES['file'];
4590
    }
4591
4592
    if (empty($file['size'])) {
4593
        return [
4594
            'error' => Display:: return_message(
4595
                get_lang(
4596
                    'There was a problem uploading your document: the received file had a 0 bytes size on the server. Please, review your local file for any corruption or damage, then try again.'
4597
                ),
4598
                'error'
4599
            ),
4600
        ];
4601
    }
4602
    //$updir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work/'; //directory path to upload
4603
4604
    // Try to add an extension to the file if it has'nt one
4605
    $filename = add_ext_on_mime(stripslashes($file['name']), $file['type']);
4606
4607
    // Replace dangerous characters
4608
    $filename = api_replace_dangerous_char($filename);
4609
    //$filename = api_replace_dangerous_char($filename);
4610
4611
    $filename = php2phps($filename);
4612
    $filesize = filesize($file['tmp_name']);
4613
4614
    if (empty($filesize)) {
4615
        return [
4616
            'error' => Display::return_message(
4617
                get_lang(
4618
                    'There was a problem uploading your document: the received file had a 0 bytes size on the server. Please, review your local file for any corruption or damage, then try again.'
4619
                ),
4620
                'error'
4621
            ),
4622
        ];
4623
    }
4624
4625
    /*if (!filter_extension($new_file_name)) {
4626
        return [
4627
            'error' => Display::return_message(
4628
                get_lang('File upload failed: this file extension or file type is prohibited'),
4629
                'error'
4630
            ),
4631
        ];
4632
    }*/
4633
4634
    $repo = Container::getDocumentRepository();
4635
    $totalSpace = $repo->getTotalSpaceByCourse($course);
4636
    $course_max_space = DocumentManager::get_course_quota($course->getCode());
4637
    $total_size = $filesize + $totalSpace;
4638
4639
    if ($total_size > $course_max_space) {
4640
        return [
4641
            'error' => Display::return_message(
4642
                get_lang(
4643
                    'The upload has failed. Either you have exceeded your maximum quota, or there is not enough disk space.'
4644
                ),
4645
                'error'
4646
            ),
4647
        ];
4648
    }
4649
4650
    // Compose a unique file name to avoid any conflict
4651
    $new_file_name = api_get_unique_id();
4652
4653
    if ($isCorrection) {
4654
        if (!empty($workInfo['url'])) {
4655
            $new_file_name = basename($workInfo['url']).'_correction';
4656
        } else {
4657
            $new_file_name .= '_correction';
4658
        }
4659
    }
4660
4661
    //$curdirpath = basename($my_folder_data['url']);
4662
    // If we come from the group tools the groupid will be saved in $work_table
4663
    /*if (is_dir($updir.$curdirpath) || empty($curdirpath)) {
4664
        $result = move_uploaded_file(
4665
            $file['tmp_name'],
4666
            $updir.$curdirpath.'/'.$new_file_name
4667
        );
4668
    } else {
4669
        return [
4670
            'error' => Display :: return_message(
4671
                get_lang('Target folder doesn\'t exist on the server.'),
4672
                'error'
4673
            ),
4674
        ];
4675
    }*/
4676
4677
    /*if ($result) {
4678
        //$url = 'work/'.$curdirpath.'/'.$new_file_name;
4679
    } else {
4680
        return false;
4681
    }*/
4682
4683
    return [
4684
        //'url' => $url,
4685
        'filename' => $filename,
4686
        'filesize' => $filesize,
4687
        'error' => '',
4688
        'file' => $file,
4689
    ];
4690
}
4691
4692
/**
4693
 * Send an e-mail to users related to this work.
4694
 *
4695
 * @param array $workInfo
4696
 * @param int   $workId
4697
 * @param array $courseInfo
4698
 * @param int   $sessionId
4699
 */
4700
function sendAlertToUsers($workInfo, $workId, $courseInfo, $sessionId = 0)
4701
{
4702
    $sessionId = (int) $sessionId;
4703
4704
    if (empty($workInfo) || empty($courseInfo) || empty($workId)) {
4705
        return false;
4706
    }
4707
4708
    $courseCode = $courseInfo['code'];
4709
4710
    $workData = get_work_data_by_id($workId, $courseInfo['real_id'], $sessionId);
4711
    // last value is to check this is not "just" an edit
4712
    // YW Tis part serve to send a e-mail to the tutors when a new file is sent
4713
    $send = api_get_course_setting('email_alert_manager_on_new_doc');
4714
4715
    $userList = [];
4716
    if (SEND_EMAIL_EVERYONE == $send || SEND_EMAIL_TEACHERS == $send) {
4717
        // Lets predefine some variables. Be sure to change the from address!
4718
        if (empty($sessionId)) {
4719
            // Teachers
4720
            $userList = CourseManager::get_user_list_from_course_code(
4721
                $courseCode,
4722
                null,
4723
                null,
4724
                null,
4725
                COURSEMANAGER
4726
            );
4727
        } else {
4728
            // Coaches
4729
            $userList = CourseManager::get_user_list_from_course_code(
4730
                $courseCode,
4731
                $sessionId,
4732
                null,
4733
                null,
4734
                2
4735
            );
4736
        }
4737
    }
4738
4739
    if (SEND_EMAIL_EVERYONE == $send || SEND_EMAIL_STUDENTS == $send) {
4740
        // Send mail only to sender
4741
        $studentList = [[
4742
           'user_id' => api_get_user_id(),
4743
        ]];
4744
        $userList = array_merge($userList, $studentList);
4745
    }
4746
4747
    if ($send) {
4748
        $folderUrl = api_get_path(WEB_CODE_PATH).
4749
            "work/work_list_all.php?cid=".$courseInfo['real_id']."&sid=".$sessionId."&id=".$workInfo['iid'];
4750
        $fileUrl = api_get_path(WEB_CODE_PATH).
4751
            "work/view.php?cid=".$courseInfo['real_id']."&sid=".$sessionId."&id=".$workData['iid'];
4752
4753
        foreach ($userList as $userData) {
4754
            $userId = $userData['user_id'];
4755
            $userInfo = api_get_user_info($userId);
4756
            if (empty($userInfo)) {
4757
                continue;
4758
            }
4759
4760
            $userPostedADocument = sprintf(
4761
                get_lang('UserXPostedADocumentInCourseX'),
4762
                $userInfo['complete_name'],
4763
                $courseInfo['name']
4764
            );
4765
4766
            $subject = "[".api_get_setting('siteName')."] ".$userPostedADocument;
4767
            $message = $userPostedADocument."<br />";
4768
            $message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."<br />";
4769
            $message .= get_lang('AssignmentName')." : ".Display::url($workInfo['title'], $folderUrl)."<br />";
4770
            $message .= get_lang('Filename')." : ".$workData['title']."<br />";
4771
            $message .= '<a href="'.$fileUrl.'">'.get_lang('DownloadLink')."</a><br />";
4772
4773
            MessageManager::send_message_simple(
4774
                $userId,
4775
                $subject,
4776
                $message,
4777
                0,
4778
                false,
4779
                false,
4780
                [],
4781
                false
4782
            );
4783
        }
4784
    }
4785
}
4786
4787
/**
4788
 * Check if the current uploaded work filename already exists in the current assement.
4789
 *
4790
 * @param string $filename
4791
 * @param int    $workId
4792
 *
4793
 * @return array
4794
 */
4795
function checkExistingWorkFileName($filename, $workId)
4796
{
4797
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
4798
    $filename = Database::escape_string($filename);
4799
    $workId = (int) $workId;
4800
4801
    $sql = "SELECT title FROM $table
4802
            WHERE parent_id = $workId AND title = '$filename' AND active = 1";
4803
    $result = Database::query($sql);
4804
4805
    return Database::fetch_assoc($result);
4806
}
4807
4808
/**
4809
 * @param array $workInfo
4810
 * @param array $values
4811
 * @param array $courseInfo
4812
 * @param int   $sessionId
4813
 * @param int   $groupId
4814
 * @param int   $userId
4815
 * @param array $file
4816
 * @param bool  $checkDuplicated
4817
 * @param bool  $showFlashMessage
4818
 *
4819
 * @return CStudentPublication|null
4820
 */
4821
function processWorkForm(
4822
    $workInfo,
4823
    $values,
4824
    $courseInfo,
4825
    $sessionId,
4826
    $groupId,
4827
    $userId,
4828
    $file = [],
4829
    $checkDuplicated = false,
4830
    $showFlashMessage = true
4831
) {
4832
    $courseId = $courseInfo['real_id'];
4833
    $courseEntity = api_get_course_entity($courseId);
4834
    $groupId = (int) $groupId;
4835
    $sessionId = (int) $sessionId;
4836
    $userId = (int) $userId;
4837
4838
    $extension = '';
4839
    if (isset($values['extension'])) {
4840
        $extension = $values['extension'];
4841
    } else {
4842
        $fileInfo = pathinfo($values['title']);
4843
        if (isset($fileInfo['extension']) && !empty($fileInfo['extension'])) {
4844
            $extension = '.'.$fileInfo['extension'];
4845
            $values['title'] = $fileInfo['filename'];
4846
        }
4847
    }
4848
4849
    $title = $values['title'].$extension;
4850
    $description = isset($values['description']) ? $values['description'] : '';
4851
    $containsFile = isset($values['contains_file']) && !empty($values['contains_file']) ? (int) $values['contains_file'] : 0;
4852
4853
    $saveWork = true;
4854
    $filename = null;
4855
    $url = null;
4856
    $filesize = null;
4857
    $workData = [];
4858
    $message = null;
4859
4860
    if ($containsFile) {
4861
        $saveWork = false;
4862
        if ($checkDuplicated) {
4863
            if (checkExistingWorkFileName($file['name'], $workInfo['iid'])) {
4864
                $saveWork = false;
4865
                $result['error'] = get_lang(
4866
                    'You have already sent this file or another file with the same name. Please make sure you only upload each file once.'
4867
                );
4868
                $workData['error'] = get_lang(' already exists.');
4869
            } else {
4870
                $result = uploadWork($workInfo, $courseEntity, false, [], $file);
4871
            }
4872
        } else {
4873
            $result = uploadWork($workInfo, $courseEntity, false, [], $file);
4874
        }
4875
4876
        if (isset($result['error'])) {
4877
            $saveWork = false;
4878
            if ($showFlashMessage) {
4879
                $message = $result['error'];
4880
            }
4881
            if (empty($result['error'])) {
4882
                $saveWork = true;
4883
            }
4884
        }
4885
    }
4886
4887
    if ($saveWork) {
4888
        $filename = isset($result['filename']) ? $result['filename'] : null;
4889
        if (empty($title)) {
4890
            $title = isset($result['title']) && !empty($result['title']) ? $result['title'] : get_lang('Untitled');
4891
        }
4892
        $filesize = isset($result['filesize']) ? $result['filesize'] : null;
4893
        $url = isset($result['url']) ? $result['url'] : null;
4894
    }
4895
4896
    if (empty($title)) {
4897
        $title = get_lang('Untitled');
4898
    }
4899
4900
    $studentPublication = null;
4901
    if ($saveWork) {
4902
        $documentId = isset($values['document_id']) ? (int) $values['document_id'] : 0;
4903
4904
        $request = Container::getRequest();
4905
        $content = $request->files->get('file');
4906
        if (is_array($content)) {
4907
            $content = $content[0];
4908
        }
4909
4910
        if (empty($content)) {
4911
            $content = $request->files->get('files');
4912
            if (is_array($content)) {
4913
                $content = $content[0];
4914
            }
4915
        }
4916
4917
        $session = api_get_session_entity($sessionId);
4918
4919
        $repo = Container::getStudentPublicationRepository();
4920
        $parentResource = $repo->find($workInfo['iid']);
4921
        $user = api_get_user_entity($userId);
4922
4923
        $studentPublication = new CStudentPublication();
4924
        $studentPublication
4925
            ->setFiletype('file')
4926
            ->setTitle($title)
4927
            ->setDescription($description)
4928
            ->setContainsFile($containsFile)
4929
            ->setActive(1)
4930
            ->setAccepted(true)
4931
            ->setQualificatorId(0)
4932
            ->setWeight(0)
4933
            ->setAllowTextAssignment(0)
4934
            ->setPostGroupId(api_get_group_id())
4935
            ->setPublicationParent($parentResource)
4936
            ->setFilesize($filesize)
4937
            ->setUser($user)
4938
            ->setDocumentId($documentId)
4939
            ->setParent($parentResource)
4940
            ->addCourseLink($courseEntity, $session, api_get_group_entity())
4941
        ;
4942
4943
        $em = Database::getManager();
4944
        $em->persist($studentPublication);
4945
        $repo->addFile($studentPublication, $content);
4946
        $em->flush();
4947
4948
        $workId = $studentPublication->getIid();
4949
4950
        if ($workId) {
4951
            sendAlertToUsers($workInfo, $workId, $courseInfo, $sessionId);
4952
            Event::event_upload($workId);
4953
4954
            // The following feature requires the creation of a work-type
4955
            // extra_field and the following setting in the configuration file
4956
            // (until moved to the database). It allows te teacher to set a
4957
            // "considered work time", meaning the time we assume a student
4958
            // would have spent, approximately, to prepare the task before
4959
            // handing it in Chamilo, adding this time to the student total
4960
            // course use time, as a register of time spent *before* his
4961
            // connection to the platform to hand the work in.
4962
            $consideredWorkingTime = api_get_configuration_value('considered_working_time');
4963
4964
            if (!empty($consideredWorkingTime)) {
4965
                // Get the "considered work time" defined for this work
4966
                $fieldValue = new ExtraFieldValue('work');
4967
                $resultExtra = $fieldValue->getAllValuesForAnItem(
4968
                    $workInfo['iid'], //the ID of the work *folder*, not the document uploaded by the student
4969
                    true
4970
                );
4971
4972
                $workingTime = null;
4973
                foreach ($resultExtra as $field) {
4974
                    $field = $field['value'];
4975
                    if ($consideredWorkingTime == $field->getField()->getVariable()) {
4976
                        $workingTime = $field->getValue();
4977
                    }
4978
                }
4979
4980
                // If no time was defined, or a time of "0" was set, do nothing
4981
                if (!empty($workingTime)) {
4982
                    // If some time is set, get the list of docs handed in by
4983
                    // this student (to make sure we count the time only once)
4984
                    $userWorks = get_work_user_list(
4985
                        0,
4986
                        100,
4987
                        null,
4988
                        null,
4989
                        $workInfo['iid'],
4990
                        null,
4991
                        $userId,
4992
                        false,
4993
                        $courseId,
4994
                        $sessionId
4995
                    );
4996
4997
                    if (1 === count($userWorks)) {
4998
                        // The student only uploaded one doc so far, so add the
4999
                        // considered work time to his course connection time
5000
                        Event::eventAddVirtualCourseTime(
5001
                            $courseId,
5002
                            $userId,
5003
                            $sessionId,
5004
                            $workingTime,
5005
                            $workInfo['iid']
5006
                        );
5007
                    }
5008
                }
5009
            }
5010
5011
            if ($showFlashMessage) {
5012
                Display::addFlash(Display::return_message(get_lang('The file has been added to the list of publications.')));
5013
            }
5014
        }
5015
    } else {
5016
        if ($showFlashMessage) {
5017
            Display::addFlash(
5018
                Display::return_message(
5019
                    $message ?: get_lang('Impossible to save the document'),
5020
                    'error'
5021
                )
5022
            );
5023
        }
5024
    }
5025
5026
    return $studentPublication;
5027
}
5028
5029
/**
5030
 * Creates a new task (directory) in the assignment tool.
5031
 *
5032
 * @param array $formValues
5033
 * @param int   $user_id
5034
 * @param array $courseInfo
5035
 * @param int   $groupId
5036
 * @param int   $sessionId
5037
 *
5038
 * @return bool|int
5039
 * @note $params can have the following elements, but should at least have the 2 first ones: (
5040
 *       'new_dir' => 'some-name',
5041
 *       'description' => 'some-desc',
5042
 *       'qualification' => 20 (e.g. 20),
5043
 *       'weight' => 50 (percentage) to add to gradebook (e.g. 50),
5044
 *       'allow_text_assignment' => 0/1/2,
5045
 *
5046
 * @todo Rename createAssignment or createWork, or something like that
5047
 */
5048
function addDir($formValues, $user_id, $courseInfo, $groupId, $sessionId = 0)
5049
{
5050
    $user_id = (int) $user_id;
5051
    $groupId = (int) $groupId;
5052
    $sessionId = (int) $sessionId;
5053
5054
    $groupIid = 0;
5055
    $groupInfo = [];
5056
    if (!empty($groupId)) {
5057
        $groupInfo = GroupManager::get_group_properties($groupId);
5058
        $groupIid = $groupInfo['iid'];
5059
    }
5060
    $session = api_get_session_entity($sessionId);
5061
    $course_id = $courseInfo['real_id'];
5062
5063
    $enableEndDate = isset($formValues['enableEndDate']) ? true : false;
5064
    $enableExpiryDate = isset($formValues['enableExpiryDate']) ? true : false;
5065
5066
    if ($enableEndDate && $enableExpiryDate) {
5067
        if ($formValues['expires_on'] > $formValues['ends_on']) {
5068
            Display::addFlash(
5069
                Display::return_message(
5070
                    get_lang('The date of effective blocking of sending the work can not be before the displayed posting deadline.'),
5071
                    'warning'
5072
                )
5073
            );
5074
5075
            return false;
5076
        }
5077
    }
5078
5079
    $today = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
5080
    $title = isset($formValues['work_title']) ? $formValues['work_title'] : $formValues['new_dir'];
5081
    $courseEntity = api_get_course_entity($course_id);
5082
5083
    $studentPublication = new CStudentPublication();
5084
    $studentPublication
5085
        ->setTitle($title)
5086
        ->setDescription($formValues['description'])
5087
        ->setActive(1)
5088
        ->setAccepted(true)
5089
        ->setFiletype('folder')
5090
        ->setPostGroupId($groupIid)
5091
        ->setSentDate($today)
5092
        ->setQualification('' != $formValues['qualification'] ? $formValues['qualification'] : 0)
5093
        ->setWeight(!empty($formValues['weight']) ? $formValues['weight'] : 0)
5094
        ->setAllowTextAssignment(1 === (int) $formValues['allow_text_assignment'] ? 1 : 0)
5095
        ->setUser(api_get_user_entity($user_id))
5096
        ->setParent($courseEntity)
5097
        ->addCourseLink(
5098
            $courseEntity,
5099
            api_get_session_entity(),
5100
            api_get_group_entity()
5101
        )
5102
    ;
5103
5104
    $repo = Container::getStudentPublicationRepository();
5105
    $repo->create($studentPublication);
5106
5107
    // Folder created
5108
    /*api_item_property_update(
5109
        $courseInfo,
5110
        'work',
5111
        $studentPublication->getIid(),
5112
        'DirectoryCreated',
5113
        $user_id,
5114
        $groupInfo
5115
    );
5116
5117
    updatePublicationAssignment(
5118
        $studentPublication->getIid(),
5119
        $formValues,
5120
        $courseInfo,
5121
        $groupIid
5122
    );*/
5123
5124
    // Added the new Work ID to the extra field values
5125
    $formValues['item_id'] = $studentPublication->getIid();
5126
5127
    $workFieldValue = new ExtraFieldValue('work');
5128
    $workFieldValue->saveFieldValues($formValues);
5129
5130
    $sendEmailAlert = api_get_course_setting('email_alert_students_on_new_homework');
5131
5132
    switch ($sendEmailAlert) {
5133
        case 1:
5134
            sendEmailToStudentsOnHomeworkCreation(
5135
                $studentPublication->getIid(),
5136
                $course_id,
5137
                $sessionId
5138
            );
5139
            //no break
5140
        case 2:
5141
            sendEmailToDrhOnHomeworkCreation(
5142
                $studentPublication->getIid(),
5143
                $course_id,
5144
                $sessionId
5145
            );
5146
5147
            break;
5148
    }
5149
5150
    return $studentPublication->getIid();
5151
}
5152
5153
/**
5154
 * @param int   $workId
5155
 * @param array $courseInfo
5156
 *
5157
 * @return int
5158
 */
5159
function agendaExistsForWork($workId, $courseInfo)
5160
{
5161
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
5162
    $courseId = $courseInfo['real_id'];
5163
    $workId = (int) $workId;
5164
5165
    $sql = "SELECT add_to_calendar FROM $workTable
5166
            WHERE c_id = $courseId AND publication_id = ".$workId;
5167
    $res = Database::query($sql);
5168
    if (Database::num_rows($res)) {
5169
        $row = Database::fetch_array($res, 'ASSOC');
5170
        if (!empty($row['add_to_calendar'])) {
5171
            return $row['add_to_calendar'];
5172
        }
5173
    }
5174
5175
    return 0;
5176
}
5177
5178
/**
5179
 * Update work description, qualification, weight, allow_text_assignment.
5180
 *
5181
 * @param int   $workId     (iid)
5182
 * @param array $params
5183
 * @param array $courseInfo
5184
 * @param int   $sessionId
5185
 */
5186
function updateWork($workId, $params, $courseInfo, $sessionId = 0)
5187
{
5188
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
5189
    $filteredParams = [
5190
        'description' => $params['description'],
5191
        'qualification' => $params['qualification'],
5192
        'weight' => (float) $params['weight'],
5193
        'allow_text_assignment' => $params['allow_text_assignment'],
5194
    ];
5195
5196
    Database::update(
5197
        $workTable,
5198
        $filteredParams,
5199
        [
5200
            'iid = ? AND c_id = ?' => [
5201
                $workId,
5202
                $courseInfo['real_id'],
5203
            ],
5204
        ]
5205
    );
5206
5207
    $workFieldValue = new ExtraFieldValue('work');
5208
    $workFieldValue->saveFieldValues($params);
5209
}
5210
5211
/**
5212
 * @param int   $workId
5213
 * @param array $params
5214
 * @param array $courseInfo
5215
 * @param int   $groupId
5216
 */
5217
function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
5218
{
5219
    $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
5220
    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
5221
    $workId = (int) $workId;
5222
    $now = api_get_utc_datetime();
5223
    $course_id = $courseInfo['real_id'];
5224
5225
    // Insert into agenda
5226
    $agendaId = 0;
5227
    if (isset($params['add_to_calendar']) && 1 == $params['add_to_calendar']) {
5228
        // Setting today date
5229
        $date = $end_date = $now;
5230
5231
        if (isset($params['enableExpiryDate'])) {
5232
            $end_date = $params['expires_on'];
5233
            $date = $end_date;
5234
        }
5235
5236
        $title = sprintf(get_lang('Handing over of task %s'), $params['new_dir']);
5237
        $description = isset($params['description']) ? $params['description'] : '';
5238
        $content = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq().'&id='.$workId.'">'
5239
            .$params['new_dir'].'</a>'.$description;
5240
5241
        $agendaId = agendaExistsForWork($workId, $courseInfo);
5242
5243
        // Add/edit agenda
5244
        $agenda = new Agenda('course');
5245
        $agenda->set_course($courseInfo);
5246
5247
        if (!empty($agendaId)) {
5248
            // add_to_calendar is set but it doesnt exists then invalidate
5249
            $eventInfo = $agenda->get_event($agendaId);
5250
            if (empty($eventInfo)) {
5251
                $agendaId = 0;
5252
            }
5253
        }
5254
5255
        $eventColor = $agenda->eventStudentPublicationColor;
5256
5257
        if (empty($agendaId)) {
5258
            $agendaId = $agenda->addEvent(
5259
                $date,
5260
                $end_date,
5261
                'false',
5262
                $title,
5263
                $content,
5264
                ['GROUP:'.$groupId],
5265
                false,
5266
                null,
5267
                [],
5268
                [],
5269
                null,
5270
                $eventColor
5271
            );
5272
        } else {
5273
            $agenda->editEvent(
5274
                $agendaId,
5275
                $end_date,
5276
                $end_date,
5277
                'false',
5278
                $title,
5279
                $content,
5280
                [],
5281
                [],
5282
                [],
5283
                null,
5284
                $eventColor
5285
            );
5286
        }
5287
    }
5288
5289
    $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
5290
    $expiryDate = isset($params['enableExpiryDate']) && 1 == (int) $params['enableExpiryDate'] ? api_get_utc_datetime($params['expires_on']) : '';
5291
    $endDate = isset($params['enableEndDate']) && 1 == (int) $params['enableEndDate'] ? api_get_utc_datetime($params['ends_on']) : '';
5292
    $data = get_work_assignment_by_id($workId, $course_id);
5293
    if (!empty($expiryDate)) {
5294
        $expiryDateCondition = "expires_on = '".Database::escape_string($expiryDate)."', ";
5295
    } else {
5296
        $expiryDateCondition = 'expires_on = null, ';
5297
    }
5298
5299
    if (!empty($endDate)) {
5300
        $endOnCondition = "ends_on = '".Database::escape_string($endDate)."', ";
5301
    } else {
5302
        $endOnCondition = 'ends_on = null, ';
5303
    }
5304
5305
    if (empty($data)) {
5306
        $sql = "INSERT INTO $table SET
5307
                c_id = $course_id ,
5308
                $expiryDateCondition
5309
                $endOnCondition
5310
                add_to_calendar = $agendaId,
5311
                enable_qualification = '$qualification',
5312
                publication_id = '$workId'";
5313
        Database::query($sql);
5314
        $my_last_id = Database::insert_id();
5315
5316
        if ($my_last_id) {
5317
            $sql = "UPDATE $workTable SET
5318
                        has_properties  = $my_last_id,
5319
                        view_properties = 1
5320
                    WHERE iid = $workId";
5321
            Database::query($sql);
5322
        }
5323
    } else {
5324
        $sql = "UPDATE $table SET
5325
                    $expiryDateCondition
5326
                    $endOnCondition
5327
                    add_to_calendar  = $agendaId,
5328
                    enable_qualification = '".$qualification."'
5329
                WHERE
5330
                    publication_id = $workId AND
5331
                    iid = ".$data['iid'];
5332
        Database::query($sql);
5333
    }
5334
5335
    if (!empty($params['category_id'])) {
5336
        $link_info = GradebookUtils::isResourceInCourseGradebook(
5337
            $courseInfo['code'],
5338
            LINK_STUDENTPUBLICATION,
5339
            $workId,
5340
            api_get_session_id()
5341
        );
5342
5343
        $linkId = null;
5344
        if (!empty($link_info)) {
5345
            $linkId = $link_info['id'];
5346
        }
5347
5348
        if (isset($params['make_calification']) &&
5349
            1 == $params['make_calification']
5350
        ) {
5351
            if (empty($linkId)) {
5352
                GradebookUtils::add_resource_to_course_gradebook(
5353
                    $params['category_id'],
5354
                    $courseInfo['code'],
5355
                    LINK_STUDENTPUBLICATION,
5356
                    $workId,
5357
                    $params['new_dir'],
5358
                    api_float_val($params['weight']),
5359
                    api_float_val($params['qualification']),
5360
                    $params['description'],
5361
                    1,
5362
                    api_get_session_id()
5363
                );
5364
            } else {
5365
                GradebookUtils::updateResourceFromCourseGradebook(
5366
                    $linkId,
5367
                    $courseInfo['code'],
5368
                    $params['weight']
5369
                );
5370
            }
5371
        } else {
5372
            // Delete everything of the gradebook for this $linkId
5373
            GradebookUtils::remove_resource_from_course_gradebook($linkId);
5374
        }
5375
    }
5376
}
5377
5378
/**
5379
 * Delete all work by student.
5380
 *
5381
 * @param int   $userId
5382
 * @param array $courseInfo
5383
 *
5384
 * @return array return deleted items
5385
 */
5386
function deleteAllWorkPerUser($userId, $courseInfo)
5387
{
5388
    $deletedItems = [];
5389
    $workPerUser = getWorkPerUser($userId);
5390
    if (!empty($workPerUser)) {
5391
        foreach ($workPerUser as $work) {
5392
            $work = $work['work'];
5393
            foreach ($work->user_results as $userResult) {
5394
                $result = deleteWorkItem($userResult['iid'], $courseInfo);
5395
                if ($result) {
5396
                    $deletedItems[] = $userResult;
5397
                }
5398
            }
5399
        }
5400
    }
5401
5402
    return $deletedItems;
5403
}
5404
5405
/**
5406
 * @param int   $item_id
5407
 * @param array $courseInfo course info
5408
 *
5409
 * @return bool
5410
 */
5411
function deleteWorkItem($item_id, $courseInfo)
5412
{
5413
    $item_id = (int) $item_id;
5414
5415
    if (empty($item_id) || empty($courseInfo)) {
5416
        return false;
5417
    }
5418
5419
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
5420
    $is_allowed_to_edit = api_is_allowed_to_edit();
5421
    $file_deleted = false;
5422
    $is_author = user_is_author($item_id);
5423
    $work_data = get_work_data_by_id($item_id);
5424
    $locked = api_resource_is_locked_by_gradebook($work_data['parent_id'], LINK_STUDENTPUBLICATION);
5425
    $course_id = $courseInfo['real_id'];
5426
5427
    if (($is_allowed_to_edit && false == $locked) ||
5428
        (
5429
            false == $locked &&
5430
            $is_author &&
5431
            1 == api_get_course_setting('student_delete_own_publication') &&
5432
            0 == $work_data['qualificator_id']
5433
        )
5434
    ) {
5435
        // We found the current user is the author
5436
        $sql = "SELECT contains_file, user_id, parent_id
5437
                FROM $work_table
5438
                WHERE iid = $item_id";
5439
        $result = Database::query($sql);
5440
        $row = Database::fetch_array($result);
5441
        $count = Database::num_rows($result);
5442
5443
        if ($count > 0) {
5444
            // If the "considered_working_time" option is enabled, check
5445
            // whether some time should be removed from track_e_course_access
5446
            $consideredWorkingTime = api_get_configuration_value('considered_working_time');
5447
            if ($consideredWorkingTime) {
5448
                $userWorks = get_work_user_list(
5449
                    0,
5450
                    100,
5451
                    null,
5452
                    null,
5453
                    $row['parent_id'],
5454
                    null,
5455
                    $row['user_id'],
5456
                    false,
5457
                    $course_id,
5458
                    $row['session_id']
5459
                );
5460
                // We're only interested in deleting the time if this is the latest work sent
5461
                if (1 == count($userWorks)) {
5462
                    // Get the "considered work time" defined for this work
5463
                    $fieldValue = new ExtraFieldValue('work');
5464
                    $resultExtra = $fieldValue->getAllValuesForAnItem(
5465
                        $row['parent_id'],
5466
                        true
5467
                    );
5468
5469
                    $workingTime = null;
5470
                    foreach ($resultExtra as $field) {
5471
                        $field = $field['value'];
5472
5473
                        if ($consideredWorkingTime == $field->getField()->getVariable()) {
5474
                            $workingTime = $field->getValue();
5475
                        }
5476
                    }
5477
                    // If no time was defined, or a time of "0" was set, do nothing
5478
                    if (!empty($workingTime)) {
5479
                        $sessionId = empty($row['session_id']) ? 0 : $row['session_id'];
5480
                        // Getting false from the following call would mean the
5481
                        // time record
5482
                        Event::eventRemoveVirtualCourseTime(
5483
                            $course_id,
5484
                            $row['user_id'],
5485
                            $sessionId,
5486
                            $workingTime,
5487
                            $row['parent_id']
5488
                        );
5489
                    }
5490
                }
5491
            } // end of considered_working_time check section
5492
5493
            $em = Database::getManager();
5494
            $repo = Container::getStudentPublicationRepository();
5495
            /** @var CStudentPublication $work */
5496
            $work = $repo->find($item_id);
5497
            $work->setActive(2);
5498
            $repo->update($work);
5499
5500
            /*$repo = Container::getStudentPublicationAssignmentRepository();
5501
            $params = ['cId' => $course_id, 'publicationId' => $item_id];
5502
5503
            $items = $repo->findBy($params);
5504
            foreach ($items as $item) {
5505
                $repo->delete($item);
5506
            }*/
5507
5508
            $em->flush();
5509
5510
            /*$sql = "DELETE FROM $TSTDPUBASG
5511
                    WHERE c_id = $course_id AND publication_id = $item_id";
5512
            Database::query($sql);*/
5513
5514
            Compilatio::plagiarismDeleteDoc($course_id, $item_id);
5515
5516
            /*api_item_property_update(
5517
                $courseInfo,
5518
                'work',
5519
                $item_id,
5520
                'DocumentDeleted',
5521
                api_get_user_id()
5522
            );*/
5523
5524
            Event::addEvent(
5525
                LOG_WORK_FILE_DELETE,
5526
                LOG_WORK_DATA,
5527
                [
5528
                    'id' => $work_data['iid'],
5529
                    'url' => $work_data['url'],
5530
                    'title' => $work_data['title'],
5531
                ],
5532
                null,
5533
                api_get_user_id(),
5534
                api_get_course_int_id(),
5535
                api_get_session_id()
5536
            );
5537
            $file_deleted = true;
5538
5539
            if (1 == $row['contains_file']) {
5540
                /*if (!empty($work)) {
5541
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
5542
                        my_delete($currentCourseRepositorySys.'/'.$work);
5543
                        $file_deleted = true;
5544
                    } else {
5545
                        $extension = pathinfo($work, PATHINFO_EXTENSION);
5546
                        $new_dir = $work.'_DELETED_'.$item_id.'.'.$extension;
5547
5548
                        if (file_exists($currentCourseRepositorySys.'/'.$work)) {
5549
                            rename($currentCourseRepositorySys.'/'.$work, $currentCourseRepositorySys.'/'.$new_dir);
5550
                            $file_deleted = true;
5551
                        }
5552
                    }
5553
                }*/
5554
            } else {
5555
                $file_deleted = true;
5556
            }
5557
        }
5558
    }
5559
5560
    return $file_deleted;
5561
}
5562
5563
/**
5564
 * @param FormValidator $form
5565
 * @param array         $defaults
5566
 * @param int           $workId
5567
 *
5568
 * @return FormValidator
5569
 */
5570
function getFormWork($form, $defaults = [], $workId = 0)
5571
{
5572
    $sessionId = api_get_session_id();
5573
    if (!empty($defaults)) {
5574
        if (isset($defaults['submit'])) {
5575
            unset($defaults['submit']);
5576
        }
5577
    }
5578
5579
    // Create the form that asks for the directory name
5580
    $form->addText('new_dir', get_lang('Assignment name'));
5581
    $form->addHtmlEditor(
5582
        'description',
5583
        get_lang('Description'),
5584
        false,
5585
        false,
5586
        getWorkDescriptionToolbar()
5587
    );
5588
    $form->addButtonAdvancedSettings('advanced_params', get_lang('Advanced settings'));
5589
5590
    if (!empty($defaults) && (isset($defaults['enableEndDate']) || isset($defaults['enableExpiryDate']))) {
5591
        $form->addHtml('<div id="advanced_params_options" style="display:block">');
5592
    } else {
5593
        $form->addHtml('<div id="advanced_params_options" style="display:none">');
5594
    }
5595
5596
    // ScoreOfAssignment
5597
    $form->addElement('text', 'qualification', get_lang('ScoreNumeric'));
5598
5599
    if (0 != $sessionId && Gradebook::is_active() || 0 == $sessionId) {
5600
        $form->addElement(
5601
            'checkbox',
5602
            'make_calification',
5603
            null,
5604
            get_lang('Add to gradebook'),
5605
            [
5606
                'id' => 'make_calification_id',
5607
                'onclick' => "javascript: if(this.checked) { document.getElementById('option1').style.display='block';}else{document.getElementById('option1').style.display='none';}",
5608
            ]
5609
        );
5610
    } else {
5611
        // QualificationOfAssignment
5612
        $form->addElement('hidden', 'make_calification', false);
5613
    }
5614
5615
    if (!empty($defaults) && isset($defaults['category_id'])) {
5616
        $form->addHtml('<div id=\'option1\' style="display:block">');
5617
    } else {
5618
        $form->addHtml('<div id=\'option1\' style="display:none">');
5619
    }
5620
5621
    // Loading Gradebook select
5622
    GradebookUtils::load_gradebook_select_in_tool($form);
5623
5624
    $form->addElement('text', 'weight', get_lang('Weight inside assessment'));
5625
    $form->addHtml('</div>');
5626
5627
    $form->addElement('checkbox', 'enableExpiryDate', null, get_lang('Enable handing over deadline (visible to learners)'), 'id="expiry_date"');
5628
    if (isset($defaults['enableExpiryDate']) && $defaults['enableExpiryDate']) {
5629
        $form->addHtml('<div id="option2" style="display: block;">');
5630
    } else {
5631
        $form->addHtml('<div id="option2" style="display: none;">');
5632
    }
5633
5634
    $timeNextWeek = time() + 86400 * 7;
5635
    $nextWeek = substr(api_get_local_time($timeNextWeek), 0, 10);
5636
    if (!isset($defaults['expires_on'])) {
5637
        $date = substr($nextWeek, 0, 10);
5638
        $defaults['expires_on'] = $date.' 23:59';
5639
    }
5640
5641
    $form->addElement('date_time_picker', 'expires_on', get_lang('Posted sending deadline'));
5642
    $form->addHtml('</div>');
5643
    $form->addElement('checkbox', 'enableEndDate', null, get_lang('Enable final acceptance date (invisible to learners)'), 'id="end_date"');
5644
5645
    if (!isset($defaults['ends_on'])) {
5646
        $nextDay = substr(api_get_local_time($timeNextWeek + 86400), 0, 10);
5647
        $date = substr($nextDay, 0, 10);
5648
        $defaults['ends_on'] = $date.' 23:59';
5649
    }
5650
    if (isset($defaults['enableEndDate']) && $defaults['enableEndDate']) {
5651
        $form->addHtml('<div id="option3" style="display: block;">');
5652
    } else {
5653
        $form->addHtml('<div id="option3" style="display: none;">');
5654
    }
5655
5656
    $form->addElement('date_time_picker', 'ends_on', get_lang('Ends at (completely closed)'));
5657
    $form->addHtml('</div>');
5658
5659
    $form->addElement('checkbox', 'add_to_calendar', null, get_lang('Add to calendar'));
5660
    $form->addElement('select', 'allow_text_assignment', get_lang('Document type'), getUploadDocumentType());
5661
5662
    // Extra fields
5663
    $extraField = new ExtraField('work');
5664
    $extra = $extraField->addElements($form, $workId);
5665
5666
    $htmlHeadXtra[] = '
5667
        <script>
5668
        $(function() {
5669
            '.$extra['jquery_ready_content'].'
5670
        });
5671
        </script>';
5672
5673
    $form->addHtml('</div>');
5674
5675
    $skillList = Skill::addSkillsToForm($form, ITEM_TYPE_STUDENT_PUBLICATION, $workId);
5676
5677
    if (!empty($defaults)) {
5678
        $defaults['skills'] = array_keys($skillList);
5679
        $form->setDefaults($defaults);
5680
    }
5681
5682
    return $form;
5683
}
5684
5685
/**
5686
 * @return array
5687
 */
5688
function getUploadDocumentType()
5689
{
5690
    return [
5691
        0 => get_lang('Allow files or online text'),
5692
        1 => get_lang('Allow only text'),
5693
        2 => get_lang('Allow only files'),
5694
    ];
5695
}
5696
5697
/**
5698
 * @param int   $itemId
5699
 * @param array $course_info
5700
 *
5701
 * @return bool
5702
 */
5703
function makeVisible($itemId, $course_info)
5704
{
5705
    $itemId = (int) $itemId;
5706
    if (empty($course_info) || empty($itemId)) {
5707
        return false;
5708
    }
5709
5710
    $repo = Container::getStudentPublicationRepository();
5711
    /** @var CStudentPublication $studentPublication */
5712
    $studentPublication = $repo->find($itemId);
5713
    if ($studentPublication) {
5714
        $studentPublication->setAccepted(1);
5715
        $repo->update($studentPublication);
5716
    }
5717
    /*
5718
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
5719
    $course_id = $course_info['real_id'];
5720
5721
    $sql = "UPDATE $work_table SET accepted = 1
5722
            WHERE c_id = $course_id AND id = $itemId";
5723
    Database::query($sql);
5724
    api_item_property_update($course_info, 'work', $itemId, 'visible', api_get_user_id());
5725
    */
5726
    return true;
5727
}
5728
5729
/**
5730
 * @param int   $itemId
5731
 * @param array $course_info
5732
 *
5733
 * @return int
5734
 */
5735
function makeInvisible($itemId, $course_info)
5736
{
5737
    $itemId = (int) $itemId;
5738
    if (empty($course_info) || empty($itemId)) {
5739
        return false;
5740
    }
5741
5742
    $repo = Container::getStudentPublicationRepository();
5743
    /** @var CStudentPublication $studentPublication */
5744
    $studentPublication = $repo->find($itemId);
5745
    if ($studentPublication) {
5746
        $studentPublication->setAccepted(0);
5747
        $repo->update($studentPublication);
5748
    }
5749
5750
    /*api_item_property_update(
5751
        $course_info,
5752
        'work',
5753
        $itemId,
5754
        'invisible',
5755
        api_get_user_id()
5756
    );*/
5757
5758
    return true;
5759
}
5760
5761
/**
5762
 * @param int    $item_id
5763
 * @param string $path
5764
 * @param array  $courseInfo
5765
 * @param int    $groupId    iid
5766
 * @param int    $sessionId
5767
 *
5768
 * @return string
5769
 */
5770
function generateMoveForm($item_id, $path, $courseInfo, $groupId, $sessionId)
5771
{
5772
    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
5773
    $courseId = $courseInfo['real_id'];
5774
    $folders = [];
5775
    $session_id = (int) $sessionId;
5776
    $groupId = (int) $groupId;
5777
    $sessionCondition = empty($sessionId) ? ' AND (session_id = 0 OR session_id IS NULL) ' : " AND session_id='".$session_id."'";
5778
5779
    $groupIid = 0;
5780
    if ($groupId) {
5781
        $groupInfo = GroupManager::get_group_properties($groupId);
5782
        $groupIid = $groupInfo['iid'];
5783
    }
5784
5785
    $sql = "SELECT iid, url, title
5786
            FROM $work_table
5787
            WHERE
5788
                c_id = $courseId AND
5789
                active IN (0, 1) AND
5790
                parent_id = 0 AND
5791
                post_group_id = $groupIid
5792
                $sessionCondition";
5793
    $res = Database::query($sql);
5794
    while ($folder = Database::fetch_array($res)) {
5795
        $title = empty($folder['title']) ? basename($folder['url']) : $folder['title'];
5796
        $folders[$folder['iid']] = $title;
5797
    }
5798
5799
    return build_work_move_to_selector($folders, $path, $item_id);
5800
}
5801
5802
/**
5803
 * @param int $workId
5804
 *
5805
 * @return string
5806
 */
5807
function showStudentList($workId)
5808
{
5809
    $columnModel = [
5810
        [
5811
            'name' => 'student',
5812
            'index' => 'student',
5813
            'width' => '350px',
5814
            'align' => 'left',
5815
            'sortable' => 'false',
5816
        ],
5817
        [
5818
            'name' => 'works',
5819
            'index' => 'works',
5820
            'align' => 'center',
5821
            'sortable' => 'false',
5822
        ],
5823
    ];
5824
    $token = null;
5825
    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student_list_overview&work_id='.$workId.'&'.api_get_cidreq();
5826
5827
    $columns = [
5828
        get_lang('Learners'),
5829
        get_lang('Assignments'),
5830
    ];
5831
5832
    $order = api_is_western_name_order() ? 'firstname' : 'lastname';
5833
    $params = [
5834
        'autowidth' => 'true',
5835
        'height' => 'auto',
5836
        'rowNum' => 5,
5837
        'sortname' => $order,
5838
        'sortorder' => 'asc',
5839
    ];
5840
5841
    $html = '<script>
5842
    $(function() {
5843
        '.Display::grid_js('studentList', $url, $columns, $columnModel, $params, [], null, true).'
5844
        $("#workList").jqGrid(
5845
            "navGrid",
5846
            "#studentList_pager",
5847
            { edit: false, add: false, del: false },
5848
            { height:280, reloadAfterSubmit:false }, // edit options
5849
            { height:280, reloadAfterSubmit:false }, // add options
5850
            { width:500 } // search options
5851
        );
5852
    });
5853
    </script>';
5854
    $html .= Display::grid_html('studentList');
5855
5856
    return $html;
5857
}
5858
5859
/**
5860
 * @param string $courseCode
5861
 * @param int    $sessionId
5862
 * @param int    $groupId
5863
 * @param int    $start
5864
 * @param int    $limit
5865
 * @param string $sidx
5866
 * @param string $sord
5867
 * @param $getCount
5868
 *
5869
 * @return array|int
5870
 */
5871
function getWorkUserList($courseCode, $sessionId, $groupId, $start, $limit, $sidx, $sord, $getCount = false)
5872
{
5873
    if (!empty($groupId)) {
5874
        $userList = GroupManager::get_users(
5875
            $groupId,
5876
            false,
5877
            $start,
5878
            $limit,
5879
            $getCount,
5880
            null,
5881
            $sidx,
5882
            $sord
5883
        );
5884
    } else {
5885
        $limitString = null;
5886
        if (!empty($start) && !empty($limit)) {
5887
            $start = (int) $start;
5888
            $limit = (int) $limit;
5889
            $limitString = " LIMIT $start, $limit";
5890
        }
5891
5892
        $orderBy = null;
5893
5894
        if (!empty($sidx) && !empty($sord)) {
5895
            if (in_array($sidx, ['firstname', 'lastname'])) {
5896
                $orderBy = "ORDER BY $sidx $sord";
5897
            }
5898
        }
5899
5900
        if (empty($sessionId)) {
5901
            $userList = CourseManager::get_user_list_from_course_code(
5902
                $courseCode,
5903
                $sessionId,
5904
                $limitString,
5905
                $orderBy,
5906
                STUDENT,
5907
                $getCount
5908
            );
5909
        } else {
5910
            $userList = CourseManager::get_user_list_from_course_code(
5911
                $courseCode,
5912
                $sessionId,
5913
                $limitString,
5914
                $orderBy,
5915
                0,
5916
                $getCount
5917
            );
5918
        }
5919
5920
        if (false == $getCount) {
5921
            $userList = array_keys($userList);
5922
        }
5923
    }
5924
5925
    return $userList;
5926
}
5927
5928
/**
5929
 * @param int    $workId
5930
 * @param string $courseCode
5931
 * @param int    $sessionId
5932
 * @param int    $groupId
5933
 * @param int    $start
5934
 * @param int    $limit
5935
 * @param int    $sidx
5936
 * @param string $sord
5937
 * @param bool   $getCount
5938
 *
5939
 * @return array|int
5940
 */
5941
function getWorkUserListData(
5942
    $workId,
5943
    $courseCode,
5944
    $sessionId,
5945
    $groupId,
5946
    $start,
5947
    $limit,
5948
    $sidx,
5949
    $sord,
5950
    $getCount = false
5951
) {
5952
    $my_folder_data = get_work_data_by_id($workId);
5953
    $workParents = [];
5954
    if (empty($my_folder_data)) {
5955
        $workParents = getWorkList($workId, $my_folder_data, null);
5956
    }
5957
5958
    $workIdList = [];
5959
    if (!empty($workParents)) {
5960
        foreach ($workParents as $work) {
5961
            $workIdList[] = $work->id;
5962
        }
5963
    }
5964
5965
    $courseInfo = api_get_course_info($courseCode);
5966
5967
    $userList = getWorkUserList(
5968
        $courseCode,
5969
        $sessionId,
5970
        $groupId,
5971
        $start,
5972
        $limit,
5973
        $sidx,
5974
        $sord,
5975
        $getCount
5976
    );
5977
5978
    if ($getCount) {
5979
        return $userList;
5980
    }
5981
    $results = [];
5982
    if (!empty($userList)) {
5983
        foreach ($userList as $userId) {
5984
            $user = api_get_user_info($userId);
5985
            $link = api_get_path(WEB_CODE_PATH).'work/student_work.php?'.api_get_cidreq().'&studentId='.$user['user_id'];
5986
            $url = Display::url(api_get_person_name($user['firstname'], $user['lastname']), $link);
5987
            $userWorks = 0;
5988
            if (!empty($workIdList)) {
5989
                $userWorks = getUniqueStudentAttempts(
5990
                    $workIdList,
5991
                    $groupId,
5992
                    $courseInfo['real_id'],
5993
                    $sessionId,
5994
                    $user['user_id']
5995
                );
5996
            }
5997
            $works = $userWorks.' / '.count($workParents);
5998
            $results[] = [
5999
                'student' => $url,
6000
                'works' => Display::url($works, $link),
6001
            ];
6002
        }
6003
    }
6004
6005
    return $results;
6006
}
6007
6008
/**
6009
 * @param int   $id
6010
 * @param array $course_info
6011
 * @param bool  $isCorrection
6012
 *
6013
 * @return bool
6014
 */
6015
function downloadFile($id, $course_info, $isCorrection)
6016
{
6017
    return getFile($id, $course_info, true, $isCorrection, true);
6018
}
6019
6020
/**
6021
 * @param int   $id
6022
 * @param array $course_info
6023
 * @param bool  $download
6024
 * @param bool  $isCorrection
6025
 * @param bool  $forceAccessForCourseAdmins
6026
 *
6027
 * @return bool
6028
 */
6029
function getFile($id, $course_info, $download = true, $isCorrection = false, $forceAccessForCourseAdmins = false)
6030
{
6031
    $file = getFileContents($id, $course_info, 0, $isCorrection, $forceAccessForCourseAdmins);
6032
    var_dump($file);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($file) looks like debug code. Are you sure you do not want to remove it?
Loading history...
6033
    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
6034
    if (!empty($file) && isset($file['entity'])) {
0 ignored issues
show
Unused Code introduced by
IfNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
6035
        /** @var CStudentPublication $studentPublication */
6036
        $studentPublication = $file['entity'];
6037
    }
6038
6039
    return false;
6040
}
6041
6042
/**
6043
 * Get the file contents for an assigment.
6044
 *
6045
 * @param int   $id
6046
 * @param array $courseInfo
6047
 * @param int   $sessionId
6048
 * @param bool  $correction
6049
 * @param bool  $forceAccessForCourseAdmins
6050
 *
6051
 * @return array|bool
6052
 */
6053
function getFileContents($id, $courseInfo, $sessionId = 0, $correction = false, $forceAccessForCourseAdmins = false)
6054
{
6055
    $id = (int) $id;
6056
6057
    if (empty($courseInfo) || empty($id)) {
6058
        return false;
6059
    }
6060
    if (empty($sessionId)) {
6061
        $sessionId = api_get_session_id();
6062
    }
6063
6064
    $courseEntity = api_get_course_entity($courseInfo['real_id']);
6065
    $sessionEntity = api_get_session_entity($sessionId);
6066
6067
    $repo = Container::getStudentPublicationRepository();
6068
    /** @var CStudentPublication $studentPublication */
6069
    $studentPublication = $repo->find($id);
6070
6071
    if (empty($studentPublication)) {
6072
        return false;
6073
    }
6074
6075
    if ($correction) {
6076
        //$row['url'] = $row['url_correction'];
6077
    }
6078
    $hasFile = $studentPublication->getResourceNode()->hasResourceFile();
6079
    if (!$hasFile) {
6080
        return false;
6081
    }
6082
6083
    /*
6084
    $item_info = api_get_item_property_info(
6085
        api_get_course_int_id(),
6086
        'work',
6087
        $row['iid'],
6088
        $sessionId
6089
    );
6090
6091
    if (empty($item_info)) {
6092
        return false;
6093
    }*/
6094
6095
    $isAllow = allowOnlySubscribedUser(
6096
        api_get_user_id(),
6097
        $studentPublication->getPublicationParent()->getIid(),
6098
        $courseInfo['real_id'],
6099
        $forceAccessForCourseAdmins
6100
    );
6101
6102
    if (empty($isAllow)) {
6103
        return false;
6104
    }
6105
6106
    /*
6107
    field show_score in table course :
6108
        0 =>    New documents are visible for all users
6109
        1 =>    New documents are only visible for the teacher(s)
6110
    field visibility in table item_property :
6111
        0 => eye closed, invisible for all students
6112
        1 => eye open
6113
    field accepted in table c_student_publication :
6114
        0 => eye closed, invisible for all students
6115
        1 => eye open
6116
    ( We should have visibility == accepted, otherwise there is an
6117
    inconsistency in the Database)
6118
    field value in table c_course_setting :
6119
        0 => Allow learners to delete their own publications = NO
6120
        1 => Allow learners to delete their own publications = YES
6121
6122
    +------------------+-------------------------+------------------------+
6123
    |Can download work?| doc visible for all = 0 | doc visible for all = 1|
6124
    +------------------+-------------------------+------------------------+
6125
    |  visibility = 0  | editor only             | editor only            |
6126
    |                  |                         |                        |
6127
    +------------------+-------------------------+------------------------+
6128
    |  visibility = 1  | editor                  | editor                 |
6129
    |                  | + owner of the work     | + any student          |
6130
    +------------------+-------------------------+------------------------+
6131
    (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
6132
    */
6133
6134
    $work_is_visible = $studentPublication->isVisible($courseEntity, $sessionEntity) && $studentPublication->getAccepted();
6135
    $doc_visible_for_all = 0 === (int) $courseInfo['show_score'];
6136
6137
    $is_editor = api_is_allowed_to_edit(true, true, true);
6138
    $student_is_owner_of_work = user_is_author($studentPublication->getIid(), api_get_user_id());
6139
6140
    if (($forceAccessForCourseAdmins && $isAllow) ||
6141
        $is_editor ||
6142
        $student_is_owner_of_work ||
6143
        ($doc_visible_for_all && $work_is_visible)
6144
    ) {
6145
        $title = $studentPublication->getTitle();
6146
        $titleCorrection = '';
6147
        if ($correction && $studentPublication->getCorrection()) {
6148
            $title = $titleCorrection = $studentPublication->getCorrection()->getTitle();
6149
        }
6150
        if ($hasFile) {
6151
            $title = $studentPublication->getResourceNode()->getResourceFile()->getName();
6152
        }
6153
6154
        $title = str_replace(' ', '_', $title);
6155
        if (false == $correction) {
6156
            $userInfo = $studentPublication->getUser();
6157
            if ($userInfo) {
6158
                $date = api_get_local_time($studentPublication->getSentDate()->format('Y-m-d H:i:s'));
6159
                $date = str_replace([':', '-', ' '], '_', $date);
6160
                $title = $date.'_'.$studentPublication->getUser()->getUsername().'_'.$title;
6161
            }
6162
        }
6163
6164
        return [
6165
            //'path' => $full_file_name,
6166
            'title' => $title,
6167
            'title_correction' => $titleCorrection,
6168
            'entity' => $studentPublication,
6169
        ];
6170
    }
6171
6172
    return false;
6173
}
6174
6175
/**
6176
 * @param int    $userId
6177
 * @param array  $courseInfo
6178
 * @param string $format
6179
 *
6180
 * @return bool
6181
 */
6182
function exportAllWork($userId, $courseInfo, $format = 'pdf')
6183
{
6184
    $userInfo = api_get_user_info($userId);
6185
    if (empty($userInfo) || empty($courseInfo)) {
6186
        return false;
6187
    }
6188
6189
    $workPerUser = getWorkPerUser($userId);
6190
6191
    switch ($format) {
6192
        case 'pdf':
6193
            if (!empty($workPerUser)) {
6194
                $pdf = new PDF();
6195
6196
                $content = null;
6197
                foreach ($workPerUser as $work) {
6198
                    $work = $work['work'];
6199
                    foreach ($work->user_results as $userResult) {
6200
                        $content .= $userResult['title'];
6201
                        // No need to use api_get_local_time()
6202
                        $content .= $userResult['sent_date'];
6203
                        $content .= $userResult['qualification'];
6204
                        $content .= $userResult['description'];
6205
                    }
6206
                }
6207
6208
                if (!empty($content)) {
6209
                    $pdf->content_to_pdf(
6210
                        $content,
6211
                        null,
6212
                        api_replace_dangerous_char($userInfo['complete_name']),
6213
                        $courseInfo['code']
6214
                    );
6215
                }
6216
            }
6217
6218
            break;
6219
    }
6220
}
6221
6222
/**
6223
 * @param int    $workId
6224
 * @param array  $courseInfo
6225
 * @param int    $sessionId
6226
 * @param string $format
6227
 *
6228
 * @return bool
6229
 */
6230
function exportAllStudentWorkFromPublication(
6231
    $workId,
6232
    $courseInfo,
6233
    $sessionId,
6234
    $format = 'pdf'
6235
) {
6236
    if (empty($courseInfo)) {
6237
        return false;
6238
    }
6239
6240
    $workData = get_work_data_by_id($workId);
6241
    if (empty($workData)) {
6242
        return false;
6243
    }
6244
6245
    $assignment = get_work_assignment_by_id($workId);
6246
    $courseCode = $courseInfo['code'];
6247
    $header = get_lang('Course').': '.$courseInfo['title'];
6248
    $teachers = CourseManager::getTeacherListFromCourseCodeToString($courseCode);
6249
6250
    if (!empty($sessionId)) {
6251
        $sessionInfo = api_get_session_info($sessionId);
6252
        if (!empty($sessionInfo)) {
6253
            $header .= ' - '.$sessionInfo['name'];
6254
            $header .= '<br />'.$sessionInfo['description'];
6255
            $teachers = SessionManager::getCoachesByCourseSessionToString(
6256
                $sessionId,
6257
                $courseInfo['real_id']
6258
            );
6259
        }
6260
    }
6261
6262
    $header .= '<br />'.get_lang('Trainers').': '.$teachers.'<br />';
6263
    $header .= '<br />'.get_lang('Date').': '.api_get_local_time().'<br />';
6264
    $header .= '<br />'.get_lang('Assignment name').': '.$workData['title'].'<br />';
6265
6266
    $content = null;
6267
    $expiresOn = null;
6268
    if (!empty($assignment) && isset($assignment['expires_on'])) {
6269
        $content .= '<br /><strong>'.
6270
            get_lang('Posted deadline for sending the work (Visible to the learner)').'</strong>: '.
6271
            api_get_local_time($assignment['expires_on']);
6272
        $expiresOn = api_get_local_time($assignment['expires_on']);
6273
    }
6274
6275
    if (!empty($workData['description'])) {
6276
        $content .= '<br /><strong>'.get_lang('Description').'</strong>: '.$workData['description'];
6277
    }
6278
6279
    $workList = get_work_user_list(null, null, null, null, $workId);
6280
6281
    switch ($format) {
6282
        case 'pdf':
6283
            if (!empty($workList)) {
6284
                $table = new HTML_Table(['class' => 'data_table']);
6285
                $headers = [
6286
                    get_lang('Name'),
6287
                    get_lang('User'),
6288
                    get_lang('Deadline'),
6289
                    get_lang('Sent date'),
6290
                    get_lang('Filename'),
6291
                    get_lang('Score'),
6292
                    get_lang('Feedback'),
6293
                ];
6294
6295
                $column = 0;
6296
                foreach ($headers as $header) {
6297
                    $table->setHeaderContents(0, $column, $header);
6298
                    $column++;
6299
                }
6300
6301
                $row = 1;
6302
                //$pdf->set_custom_header($header);
6303
                /** @var array $work */
6304
                foreach ($workList as $work) {
6305
                    $content .= '<hr />';
6306
                    // getWorkComments need c_id
6307
                    $work['c_id'] = $courseInfo['real_id'];
6308
                    //$content .= get_lang('Date').': '.api_get_local_time($work['sent_date_from_db']).'<br />';
6309
                    $score = null;
6310
                    if (!empty($work['qualification_only'])) {
6311
                        $score = $work['qualification_only'];
6312
                    }
6313
6314
                    $comments = getWorkComments($work);
6315
                    $feedback = null;
6316
                    if (!empty($comments)) {
6317
                        $content .= '<h4>'.get_lang('Feedback').': </h4>';
6318
                        foreach ($comments as $comment) {
6319
                            $feedback .= get_lang('User').': '.$comment['complete_name'].'<br />';
6320
                            $feedback .= $comment['comment'].'<br />';
6321
                        }
6322
                    }
6323
                    $table->setCellContents($row, 0, strip_tags($workData['title']));
6324
                    $table->setCellContents($row, 1, strip_tags($work['fullname']));
6325
                    $table->setCellContents($row, 2, $expiresOn);
6326
                    $table->setCellContents($row, 3, api_get_local_time($work['sent_date_from_db']));
6327
                    $table->setCellContents($row, 4, strip_tags($work['title']));
6328
                    $table->setCellContents($row, 5, $score);
6329
                    $table->setCellContents($row, 6, $feedback);
6330
                    $row++;
6331
                }
6332
6333
                $content = $table->toHtml();
6334
                if (!empty($content)) {
6335
                    $params = [
6336
                        'filename' => $workData['title'].'_'.api_get_local_time(),
6337
                        'pdf_title' => api_replace_dangerous_char($workData['title']),
6338
                        'course_code' => $courseInfo['code'],
6339
                    ];
6340
                    $pdf = new PDF('A4', null, $params);
6341
                    $pdf->html_to_pdf_with_template($content);
6342
                }
6343
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
6344
            }
6345
6346
            break;
6347
    }
6348
}
6349
6350
/**
6351
 * Downloads all user files per user.
6352
 *
6353
 * @param int   $userId
6354
 * @param array $courseInfo
6355
 *
6356
 * @return bool
6357
 */
6358
function downloadAllFilesPerUser($userId, $courseInfo)
6359
{
6360
    throw new Exception('downloadAllFilesPerUser');
6361
    /*
6362
    $userInfo = api_get_user_info($userId);
6363
6364
    if (empty($userInfo) || empty($courseInfo)) {
6365
        return false;
6366
    }
6367
6368
    $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().'.zip';
6369
    $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
6370
    $zip = new PclZip($tempZipFile);
6371
    $workPerUser = getWorkPerUser($userId);
6372
6373
    if (!empty($workPerUser)) {
6374
        $files = [];
6375
        foreach ($workPerUser as $work) {
6376
            $work = $work['work'];
6377
            foreach ($work->user_results as $userResult) {
6378
                if (empty($userResult['url']) || empty($userResult['contains_file'])) {
6379
                    continue;
6380
                }
6381
                $data = getFileContents($userResult['iid'], $courseInfo);
6382
                if (!empty($data) && isset($data['path'])) {
6383
                    $files[basename($data['path'])] = [
6384
                        'title' => $data['title'],
6385
                        'path' => $data['path'],
6386
                    ];
6387
                }
6388
            }
6389
        }
6390
6391
        if (!empty($files)) {
6392
            Session::write('files', $files);
6393
            foreach ($files as $data) {
6394
                $zip->add(
6395
                    $data['path'],
6396
                    PCLZIP_OPT_REMOVE_PATH,
6397
                    $coursePath,
6398
                    PCLZIP_CB_PRE_ADD,
6399
                    'preAddAllWorkStudentCallback'
6400
                );
6401
            }
6402
        }
6403
6404
        // Start download of created file
6405
        $name = basename(api_replace_dangerous_char($userInfo['complete_name'])).'.zip';
6406
        Event::event_download($name.'.zip (folder)');
6407
        if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) {
6408
            DocumentManager::file_send_for_download($tempZipFile, true, $name);
6409
            @unlink($tempZipFile);
6410
            exit;
6411
        }
6412
    }
6413
    exit;*/
6414
}
6415
6416
/**
6417
 * @param $p_event
6418
 * @param array $p_header
6419
 *
6420
 * @return int
6421
 */
6422
function preAddAllWorkStudentCallback($p_event, &$p_header)
6423
{
6424
    $files = Session::read('files');
6425
    if (isset($files[basename($p_header['stored_filename'])])) {
6426
        $p_header['stored_filename'] = $files[basename($p_header['stored_filename'])]['title'];
6427
6428
        return 1;
6429
    }
6430
6431
    return 0;
6432
}
6433
6434
/**
6435
 * Get all work created by a user.
6436
 *
6437
 * @param int $userId
6438
 * @param int $courseId
6439
 * @param int $sessionId
6440
 *
6441
 * @return array
6442
 */
6443
function getWorkCreatedByUser($userId, $courseId, $sessionId)
6444
{
6445
    $repo = Container::getStudentPublicationRepository();
6446
6447
    $courseEntity = api_get_course_entity($courseId);
6448
    $sessionEntity = api_get_session_entity($sessionId);
6449
6450
    $qb = $repo->getResourcesByCourse($courseEntity, $sessionEntity);
6451
6452
    $qb->andWhere('node.creator = :creator');
6453
    $qb->setParameter('creator', $userId);
6454
    $items = $qb->getQuery()->getResult();
6455
6456
    $list = [];
6457
    if (!empty($items)) {
6458
        /** @var CStudentPublication $work */
6459
        foreach ($items as $work) {
6460
            $list[] = [
6461
                $work->getTitle(),
6462
                api_get_local_time($work->getResourceNode()->getCreatedAt()),
6463
                api_get_local_time($work->getResourceNode()->getUpdatedAt()),
6464
            ];
6465
        }
6466
    }
6467
6468
    return $list;
6469
}
6470
6471
/**
6472
 * @param array $courseInfo
6473
 * @param int   $workId
6474
 *
6475
 * @return bool
6476
 */
6477
function protectWork($courseInfo, $workId)
6478
{
6479
    $userId = api_get_user_id();
6480
    $groupId = api_get_group_id();
6481
    $sessionId = api_get_session_id();
6482
    $workData = get_work_data_by_id($workId);
6483
6484
    if (empty($workData) || empty($courseInfo)) {
6485
        api_not_allowed(true);
6486
    }
6487
6488
    if (api_is_platform_admin() || api_is_allowed_to_edit()) {
6489
        return true;
6490
    }
6491
6492
    $workId = $workData['iid'];
6493
6494
    if (1 != $workData['active']) {
6495
        api_not_allowed(true);
6496
    }
6497
6498
    /*$visibility = api_get_item_visibility($courseInfo, 'work', $workId, $sessionId);
6499
    if ($visibility != 1) {
6500
        api_not_allowed(true);
6501
    }*/
6502
6503
    $isAllow = allowOnlySubscribedUser($userId, $workId, $courseInfo['real_id']);
6504
    if (empty($isAllow)) {
6505
        api_not_allowed(true);
6506
    }
6507
    if (!empty($groupId)) {
6508
        $group = api_get_group_entity($groupId);
6509
        $showWork = GroupManager::userHasAccess(
6510
            $userId,
6511
            $group,
6512
            GroupManager::GROUP_TOOL_WORK
6513
        );
6514
        if (!$showWork) {
6515
            api_not_allowed(true);
6516
        }
6517
    }
6518
}
6519
6520
function deleteCorrection(CStudentPublication $work)
6521
{
6522
    $correctionNode = $work->getCorrection();
6523
    if (null !== $correctionNode) {
6524
        $em = Database::getManager();
6525
        $em->remove($correctionNode);
6526
        $em->flush();
6527
    }
6528
}
6529
6530
/**
6531
 * @param int $workId
6532
 *
6533
 * @return string
6534
 */
6535
function workGetExtraFieldData($workId)
6536
{
6537
    $sessionField = new ExtraField('work');
6538
    $extraFieldData = $sessionField->getDataAndFormattedValues($workId);
6539
    $result = '';
6540
    if (!empty($extraFieldData)) {
6541
        $result .= '<div class="well">';
6542
        foreach ($extraFieldData as $data) {
6543
            $result .= $data['text'].': <b>'.$data['value'].'</b>';
6544
        }
6545
        $result .= '</div>';
6546
    }
6547
6548
    return $result;
6549
}
6550