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

dropbox_functions.inc.php ➔ display_add_form()   F

Complexity

Conditions 32
Paths 2880

Size

Total Lines 197
Code Lines 129

Duplication

Lines 20
Ratio 10.15 %
Metric Value
cc 32
eloc 129
nc 2880
nop 4
dl 20
loc 197
rs 2

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
* This file contains additional dropbox functions. Initially there were some
6
* functions in the init files also but I have moved them over
7
* to one file -- Patrick Cool <[email protected]>, Ghent University
8
* @author Julio Montoya adding c_id support
9
*/
10
use ChamiloSession as Session;
11
12
$this_section = SECTION_COURSES;
13
14
$htmlHeadXtra[] = '<script>
15
function setFocus(){
16
    $("#category_title").focus();
17
}
18
$(document).ready(function () {
19
    setFocus();
20
});
21
</script>';
22
23
/**
24
* This function is a wrapper function for the multiple actions feature.
25
* @return   Mixed   If there is a problem, return a string message, otherwise nothing
26
* @author   Patrick Cool <[email protected]>, Ghent University
27
* @version  march 2006
28
*/
29
function handle_multiple_actions()
30
{
31
    $_user = api_get_user_info();
32
    $is_courseAdmin = api_is_course_admin();
33
    $is_courseTutor = api_is_course_tutor();
34
35
    // STEP 1: are we performing the actions on the received or on the sent files?
36
    if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'download_received') {
37
        $part = 'received';
38
    } elseif ($_POST['action'] == 'delete_sent' || $_POST['action'] == 'download_sent') {
39
        $part = 'sent';
40
    }
41
42
    // STEP 2: at least one file has to be selected. If not we return an error message
43
    $ids = isset($_GET['id']) ? $_GET['id'] : array();
44
    if (count($ids)>0) {
45
        $checked_file_ids = $_POST['id'];
46
    } else {
47
        foreach ($_POST as $key => $value) {
48
            if (strstr($value, $part.'_') AND $key != 'view_received_category' AND $key != 'view_sent_category') {
49
                $checked_files = true;
50
                $checked_file_ids[] = intval(substr($value, strrpos($value, '_')));
51
            }
52
        }
53
    }
54
    $checked_file_ids = $_POST['id'];
55
56
    if (!is_array($checked_file_ids) || count($checked_file_ids) == 0) {
57
        return get_lang('CheckAtLeastOneFile');
58
    }
59
60
    // STEP 3A: deleting
61
    if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'delete_sent') {
62
        $dropboxfile = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
63
        foreach ($checked_file_ids as $key => $value) {
64
            if ($_GET['view'] == 'received') {
65
                $dropboxfile->deleteReceivedWork($value);
66
                $message = get_lang('ReceivedFileDeleted');
67
            }
68
            if ($_GET['view'] == 'sent' OR empty($_GET['view'])) {
69
                $dropboxfile->deleteSentWork($value);
70
                $message = get_lang('SentFileDeleted');
71
            }
72
        }
73
        return $message;
74
    }
75
76
    // STEP 3B: giving comment
77
    if ($_POST['actions'] == 'comment') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
78
        // This has not been implemented.
79
        // The idea was that it would be possible to write the same feedback for the selected documents.
80
    }
81
82
    // STEP 3C: moving
83
    if (strstr($_POST['action'], 'move_')) {
84
        // check move_received_n or move_sent_n command
85
        if (strstr($_POST['action'], 'received')) {
86
              $part = 'received';
87
              $to_cat_id = str_replace('move_received_', '', $_POST['action']);
88
        } else {
89
              $part = 'sent';
90
              $to_cat_id = str_replace('move_sent_', '', $_POST['action']);
91
        }
92
93
        foreach ($checked_file_ids as $value) {
94
            store_move($value, $to_cat_id, $part);
95
        }
96
97
        return get_lang('FilesMoved');
98
    }
99
100
    // STEP 3D: downloading
101
    if ($_POST['action'] == 'download_sent' || $_POST['action'] == 'download_received') {
102
        zip_download($checked_file_ids);
103
    }
104
}
105
106
/**
107
 * Get conf settings
108
 * @return array
109
 */
110
function getDropboxConf()
111
{
112
    return Session::read('dropbox_conf');
113
}
114
115
/**
116
* This function deletes a dropbox category
117
*
118
* @todo give the user the possibility what needs to be done with the files
119
 * in this category: move them to the root, download them as a zip, delete them
120
*
121
* @author Patrick Cool <[email protected]>, Ghent University
122
* @version march 2006
123
*/
124
function delete_category($action, $id, $user_id = null)
125
{
126
    $course_id = api_get_course_int_id();
127
    $is_courseAdmin = api_is_course_admin();
128
    $is_courseTutor = api_is_course_tutor();
129
    $dropbox_cnf = getDropboxConf();
130
131
    if (empty($user_id)) {
132
        $user_id = api_get_user_id();
133
    }
134
135
    $cat = get_dropbox_category($id);
136
    if (count($cat)==0) {
137
        return false;
138
    }
139
140
    if ($cat['user_id'] != $user_id && !api_is_platform_admin($user_id)) {
141
        return false;
142
    }
143
144
    // an additional check that might not be necessary
145
    if ($action == 'deletereceivedcategory') {
146
        $sentreceived = 'received';
147
        $entries_table = $dropbox_cnf['tbl_post'];
148
        $id_field = 'file_id';
149
        $return_message = get_lang('ReceivedCatgoryDeleted');
150
    } elseif ($action == 'deletesentcategory') {
151
        $sentreceived = 'sent';
152
        $entries_table = $dropbox_cnf['tbl_file'];
153
        $id_field = 'id';
154
        $return_message = get_lang('SentCatgoryDeleted');
155
    } else {
156
        return get_lang('Error');
157
    }
158
159
    // step 1: delete the category
160
    $sql = "DELETE FROM ".$dropbox_cnf['tbl_category']."
161
            WHERE c_id = $course_id AND cat_id='".intval($id)."' AND $sentreceived='1'";
162
    Database::query($sql);
163
164
    // step 2: delete all the documents in this category
165
    $sql = "SELECT * FROM ".$entries_table."
166
            WHERE c_id = $course_id AND cat_id='".intval($id)."'";
167
    $result = Database::query($sql);
168
169
    while($row = Database::fetch_array($result)) {
170
        $dropboxfile = new Dropbox_Person($user_id, $is_courseAdmin, $is_courseTutor);
171
        if ($action == 'deletereceivedcategory') {
172
            $dropboxfile->deleteReceivedWork($row[$id_field]);
173
        }
174
        if ($action == 'deletesentcategory') {
175
            $dropboxfile->deleteSentWork($row[$id_field]);
176
        }
177
    }
178
179
    return $return_message;
180
}
181
182
/**
183
* Displays the form to move one individual file to a category
184
*@ return html code of the form that appears in a message box.
185
* @author Julio Montoya - function rewritten
186
*/
187
function display_move_form($part, $id, $target = array(), $extra_params = array(), $viewReceivedCategory, $viewSentCategory, $view)
188
{
189
    $form = new FormValidator(
190
        'form1',
191
        'post',
192
        api_get_self().'?view_received_category='.$viewReceivedCategory.'&view_sent_category='.$viewSentCategory.'&view='.$view.'&'.$extra_params
193
    );
194
    $form->addElement('header', get_lang('MoveFileTo'));
195
    $form->addElement('hidden', 'id', intval($id));
196
    $form->addElement('hidden', 'part', Security::remove_XSS($part));
197
198
    $options = array('0' => get_lang('Root'));
199
    foreach ($target as $category) {
200
        $options[$category['cat_id']] = $category['cat_name'];
201
    }
202
    $form->addElement('select', 'move_target', get_lang('MoveFileTo'), $options);
203
    $form->addElement('button', 'do_move', get_lang('MoveFile'));
204
    $form->display();
205
}
206
207
/**
208
* This function moves a file to a different category
209
*
210
* @param $id the id of the file we are moving
211
* @param $target the id of the folder we are moving to
212
* @param $part are we moving a received file or a sent file?
213
*
214
* @return language string
215
*
216
* @author Patrick Cool <[email protected]>, Ghent University
217
* @version march 2006
218
*/
219
function store_move($id, $target, $part)
220
{
221
    $_user = api_get_user_info();
222
    $dropbox_cnf = getDropboxConf();
223
    $course_id = api_get_course_int_id();
224
225
    if ((isset($id) && $id != '') &&
226
        (isset($target) && $target != '') &&
227
        (isset($part) && $part != '')
228
    ) {
229
230 View Code Duplication
        if ($part == 'received') {
231
            $sql = "UPDATE ".$dropbox_cnf["tbl_post"]."
232
                    SET cat_id = ".intval($target)."
233
                    WHERE c_id = $course_id AND dest_user_id = ".intval($_user['user_id'])."
234
                    AND file_id = ".intval($id)."";
235
            Database::query($sql);
236
            $return_message = get_lang('ReceivedFileMoved');
237
        }
238 View Code Duplication
        if ($part == 'sent') {
239
            $sql = "UPDATE ".$dropbox_cnf["tbl_file"]."
240
                    SET cat_id = ".intval($target)."
241
                    WHERE
242
                        c_id = $course_id AND
243
                        uploader_id = ".intval($_user['user_id'])." AND
244
                        id = ".intval($id)."";
245
            Database::query($sql);
246
            $return_message = get_lang('SentFileMoved');
247
        }
248
    } else {
249
        $return_message = get_lang('NotMovedError');
250
    }
251
252
    return $return_message;
253
}
254
255
/**
256
* This functions displays all teh possible actions that can be
257
 * performed on multiple files. This is the dropdown list that
258
* appears below the sortable table of the sent / or received files.
259
*
260
* @return html value for the dropdown list
261
*
262
* @author Patrick Cool <[email protected]>, Ghent University
263
* @version march 2006
264
*/
265
function display_action_options($part, $categories, $current_category = 0)
266
{
267
    echo '<select name="actions">';
268
    echo '<option value="download">'.get_lang('Download').'</option>';
269
    echo '<option value="delete">'.get_lang('Delete').'</option>';
270
    if (is_array($categories)) {
271
        echo '<optgroup label="'.get_lang('MoveTo').'">';
272
        if ($current_category != 0) {
273
            echo '<option value="move_0">'.get_lang('Root').'</a>';
274
        }
275
        foreach ($categories as $value) {
276
            if ($current_category != $value['cat_id']) {
277
                echo '<option value="move_'.$value['cat_id'].'">'.$value['cat_name'].'</option>';
278
            }
279
        }
280
        echo '</optgroup>';
281
    }
282
    echo '</select>';
283
    echo '<input type="submit" name="do_actions_'.Security::remove_XSS($part).'" value="'.get_lang('Ok').'" />';
284
}
285
286
/**
287
* this function returns the html code that displays the checkboxes next to the files so that
288
* multiple actions on one file are possible.
289
*
290
* @param $id the unique id of the file
291
* @param $part are we dealing with a sent or with a received file?
292
*
293
* @return html code
294
*
295
* @author Patrick Cool <[email protected]>, Ghent University
296
* @version march 2006
297
*/
298
function display_file_checkbox($id, $part) {
299
    if (isset($_GET['selectall'])) {
300
        $checked = 'checked';
301
    }
302
    $return_value = '<input type="checkbox" name="'.Security::remove_XSS($part).'_'.Security::remove_XSS($id).'" value="'.Security::remove_XSS($id).'" '.$checked.' />';
303
304
    return $return_value;
305
}
306
307
/**
308
* This function retrieves all dropbox categories and returns them as an array
309
*
310
* @param $filter default '', when we need only the categories of the sent or the received part.
311
*
312
* @return array
313
*
314
* @author Patrick Cool <[email protected]>, Ghent University
315
* @version march 2006
316
*/
317
function get_dropbox_categories($filter = '')
318
{
319
    $course_id = api_get_course_int_id();
320
    $_user = api_get_user_info();
321
    $dropbox_cnf = getDropboxConf();
322
    $return_array = array();
323
324
    $session_id = api_get_session_id();
325
    $condition_session = api_get_session_condition($session_id);
326
327
    $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']."
328
            WHERE c_id = $course_id AND user_id='".$_user['user_id']."' $condition_session";
329
330
    $result = Database::query($sql);
331
    while ($row = Database::fetch_array($result)) {
332
        if (($filter == 'sent' && $row['sent'] == 1) || ($filter == 'received' && $row['received'] == 1) || $filter == '') {
333
            $return_array[$row['cat_id']] = $row;
334
        }
335
    }
336
337
    return $return_array;
338
}
339
340
/**
341
 * Get a dropbox category details
342
 * @param int The category ID
343
 * @return array The details of this category
344
 */
345
function get_dropbox_category($id)
346
{
347
    $dropbox_cnf = getDropboxConf();
348
    $course_id = api_get_course_int_id();
349
    if (empty($id) or $id != intval($id)) { return array(); }
350
    $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']."
351
            WHERE c_id = $course_id AND cat_id='".$id."'";
352
    $res = Database::query($sql);
353
    if ($res === false) {
354
        return array();
355
    }
356
    $row = Database::fetch_assoc($res);
357
    return $row;
358
}
359
360
/**
361
* This functions stores a new dropboxcategory
362
*
363
* @var  it might not seem very elegant if you create a category in sent
364
 * and in received with the same name that you get two entries in the
365
*       dropbox_category table but it is the easiest solution. You get
366
*       cat_name | received | sent | user_id
367
*       test     |    1     |   0  |    237
368
*       test     |    0     |   1  |    237
369
*       more elegant would be
370
*       test     |    1     |   1  |    237
371
*
372
* @author Patrick Cool <[email protected]>, Ghent University
373
* @version march 2006
374
*/
375
function store_addcategory()
376
{
377
    $course_id = api_get_course_int_id();
378
    $_user = api_get_user_info();
379
    $dropbox_cnf = getDropboxConf();
380
381
    // check if the target is valid
382
    if ($_POST['target'] == 'sent') {
383
        $sent = 1;
384
        $received = 0;
385
    } elseif ($_POST['target'] == 'received') {
386
        $sent = 0;
387
        $received = 1;
388
    } else {
389
        return get_lang('Error');
390
    }
391
392
    // check if the category name is valid
393
    if ($_POST['category_name'] == '') {
394
        return array('type' => 'error', 'message' => get_lang('ErrorPleaseGiveCategoryName'));
395
    }
396
397
    if (!$_POST['edit_id']) {
398
        $session_id = api_get_session_id();
399
        // step 3a, we check if the category doesn't already exist
400
        $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']."
401
                WHERE
402
                    c_id = $course_id AND
403
                    user_id='".$_user['user_id']."' AND
404
                    cat_name='".Database::escape_string($_POST['category_name'])."' AND
405
                    received='".$received."' AND
406
                    sent='$sent' AND
407
                    session_id='$session_id'";
408
        $result = Database::query($sql);
409
410
        // step 3b, we add the category if it does not exist yet.
411
        if (Database::num_rows($result) == 0) {
412
            $params = [
413
                'cat_id' => 0,
414
                'c_id' => $course_id,
415
                'cat_name' => $_POST['category_name'],
416
                'received' => $received,
417
                'sent' => $sent,
418
                'user_id' => $_user['user_id'],
419
                'session_id' => $session_id,
420
            ];
421
            $id = Database::insert($dropbox_cnf['tbl_category'], $params);
422
            if ($id) {
423
                $sql = "UPDATE ".$dropbox_cnf['tbl_category']." SET cat_id = iid WHERE iid = $id";
424
                Database::query($sql);
425
            }
426
427
            return array('type' => 'confirmation', 'message' => get_lang('CategoryStored'));
428
        } else {
429
            return array('type' => 'error', 'message' => get_lang('CategoryAlreadyExistsEditIt'));
430
        }
431
    } else {
432
433
        $params = [
434
            'cat_name' => $_POST['category_name'],
435
            'received' => $received,
436
            'sent' => $sent
437
        ];
438
439
        Database::update(
440
            $dropbox_cnf['tbl_category'],
441
            $params,
442
            [
443
                'c_id = ? AND user_id = ? AND cat_id = ?' => [
444
                    $course_id,
445
                    $_user['user_id'],
446
                    $_POST['edit_id'],
447
                ],
448
            ]
449
        );
450
451
        return array('type' => 'confirmation', 'message' => get_lang('CategoryModified'));
452
    }
453
}
454
455
/**
456
* This function displays the form to add a new category.
457
*
458
* @param $category_name this parameter is the name of the category (used when no section is selected)
459
* @param $id this is the id of the category we are editing.
460
*
461
* @author Patrick Cool <[email protected]>, Ghent University
462
  @author Julio Montoya UI changes
463
 *
464
* @version march 2006
465
*/
466
function display_addcategory_form($category_name = '', $id = '', $action)
467
{
468
    $dropbox_cnf = getDropboxConf();
469
    $course_id = api_get_course_int_id();
470
    $title = get_lang('AddNewCategory');
471
472
    if (isset($id) && $id != '') {
473
        // retrieve the category we are editing
474
        $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']."
475
                WHERE c_id = $course_id AND cat_id = ".intval($id)."";
476
        $result = Database::query($sql);
477
        $row = Database::fetch_array($result);
478
479
        if (empty($category_name)) {
480
            // after an edit with an error we do not want to return to the
481
            // original name but the name we already modified.
482
            // (happens when createinrecievedfiles AND createinsentfiles are not checked)
483
            $category_name = $row['cat_name'];
484
        }
485
        if ($row['received'] == '1') {
486
            $target = 'received';
487
        }
488
        if ($row['sent'] == '1') {
489
            $target = 'sent';
490
        }
491
        $title = get_lang('EditCategory');
492
    }
493
494
    if ($action == 'addreceivedcategory') {
495
        $target = 'received';
496
    }
497
    if ($action == 'addsentcategory') {
498
        $target = 'sent';
499
    }
500
501
    if ($action == 'editcategory') {
502
        $text = get_lang('ModifyCategory');
503
    } elseif ($action == 'addreceivedcategory' || $action == 'addsentcategory') {
504
        $text = get_lang('CreateCategory');
505
    }
506
507
    $form = new FormValidator('add_new_category', 'post', api_get_self().'?view='.Security::remove_XSS($_GET['view']));
508
    $form->addElement('header', $title);
509
510
    if (isset($id) && $id != '') {
511
        $form->addElement('hidden', 'edit_id', intval($id));
512
    }
513
    $form->addElement('hidden', 'action', Security::remove_XSS($action));
514
    $form->addElement('hidden', 'target', Security::remove_XSS($target));
515
516
    $form->addElement('text', 'category_name', get_lang('CategoryName'));
517
    $form->addRule('category_name', get_lang('ThisFieldIsRequired'), 'required');
518
    $form->addButtonSave($text, 'StoreCategory');
519
520
    $defaults = array();
521
    $defaults['category_name'] = $category_name;
522
    $form->setDefaults($defaults);
523
    $form->display();
524
}
525
526
/**
527
* this function displays the form to upload a new item to the dropbox.
528
*
529
* @author Patrick Cool <[email protected]>, Ghent University
530
* @version march 2006
531
*/
532
function display_add_form($dropbox_unid, $viewReceivedCategory, $viewSentCategory, $view)
533
{
534
    $course_info = api_get_course_info();
535
    $_user = api_get_user_info();
536
    $is_courseAdmin = api_is_course_admin();
537
    $is_courseTutor = api_is_course_tutor();
538
    $origin = isset($_GET['origin']) ? $_GET['origin'] : null;
539
540
    $token = Security::get_token();
541
    $dropbox_person = new Dropbox_Person(
542
        api_get_user_id(),
543
        $is_courseAdmin,
544
        $is_courseTutor
545
    );
546
547
    $form = new FormValidator(
548
        'sent_form',
549
        'post',
550
        api_get_self().'?view_received_category='.$viewReceivedCategory.'&view_sent_category='.$viewSentCategory.'&view='.$view.'&'.api_get_cidreq(),
551
        null,
552
        array('enctype' => 'multipart/form-data', 'onsubmit' => 'javascript: return checkForm(this);')
553
    );
554
555
    $form->addElement('header', get_lang('UploadNewFile'));
556
    $form->addElement('hidden', 'MAX_FILE_SIZE', dropbox_cnf('maxFilesize'));
557
    $form->addElement('hidden', 'dropbox_unid', $dropbox_unid);
558
    $form->addElement('hidden', 'sec_token', $token);
559
    $form->addElement('hidden', 'origin', $origin);
560
    $form->addElement('file', 'file', get_lang('UploadFile'), array('onChange' => 'javascript: checkfile(this.value);'));
561
562
    if (dropbox_cnf('allowOverwrite')) {
563
        $form->addElement('checkbox', 'cb_overwrite', null, get_lang('OverwriteFile'), array('id' => 'cb_overwrite'));
564
    }
565
566
    // List of all users in this course and all virtual courses combined with it
567
    if (api_get_session_id()) {
568
        $complete_user_list_for_dropbox = array();
569 View Code Duplication
        if (api_get_setting('dropbox_allow_student_to_student') == 'true' || $_user['status'] != STUDENT) {
570
            $complete_user_list_for_dropbox = CourseManager:: get_user_list_from_course_code(
571
                $course_info['code'],
572
                api_get_session_id(),
573
                null,
574
                null,
575
                0
576
            );
577
        }
578
579
        $complete_user_list2 = CourseManager::get_coach_list_from_course_code(
580
            $course_info['code'],
581
            api_get_session_id()
582
        );
583
584
        $generalCoachList = array();
585
        $courseCoachList = array();
586
        foreach ($complete_user_list2 as $coach) {
587
            if ($coach['type'] == 'general_coach') {
588
                $generalCoachList[] = $coach;
589
            } else {
590
                $courseCoachList[] = $coach;
591
            }
592
        }
593
594
        $hideCourseCoach = api_get_setting('dropbox_hide_course_coach');
595
        if ($hideCourseCoach == 'false') {
596
            $complete_user_list_for_dropbox = array_merge(
597
                $complete_user_list_for_dropbox,
598
                $courseCoachList
599
            );
600
        }
601
        $hideGeneralCoach = api_get_setting('dropbox_hide_general_coach');
602
603
        if ($hideGeneralCoach == 'false') {
604
            $complete_user_list_for_dropbox = array_merge(
605
                $complete_user_list_for_dropbox,
606
                $generalCoachList
607
            );
608
        }
609
    } else {
610 View Code Duplication
        if (api_get_setting('dropbox_allow_student_to_student') == 'true' || $_user['status'] != STUDENT) {
611
            $complete_user_list_for_dropbox = CourseManager::get_user_list_from_course_code(
612
                $course_info['code'],
613
                api_get_session_id()
614
            );
615
        } else {
616
            $complete_user_list_for_dropbox = CourseManager::get_teacher_list_from_course_code(
617
                $course_info['code'],
618
                false
619
            );
620
        }
621
    }
622
623
    if (!empty($complete_user_list_for_dropbox)) {
624
        foreach ($complete_user_list_for_dropbox as $k => $e) {
0 ignored issues
show
Bug introduced by
The expression $complete_user_list_for_dropbox of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
625
            $complete_user_list_for_dropbox[$k] = $e + array('lastcommafirst' => api_get_person_name($e['firstname'], $e['lastname']));
626
        }
627
        $complete_user_list_for_dropbox = TableSort::sort_table($complete_user_list_for_dropbox, 'lastcommafirst');
0 ignored issues
show
Bug introduced by
It seems like $complete_user_list_for_dropbox can also be of type integer; however, TableSort::sort_table() does only seem to accept array, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
628
    }
629
630
    /*
631
        Create the options inside the select box:
632
        List all selected users their user id as value and a name string as display
633
    */
634
635
    $current_user_id = '';
636
    $options = array();
637
    $userGroup = new UserGroup();
638
    foreach ($complete_user_list_for_dropbox as $current_user) {
0 ignored issues
show
Bug introduced by
The expression $complete_user_list_for_dropbox of type array|integer|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
639
        if (($dropbox_person -> isCourseTutor
640
                || $dropbox_person -> isCourseAdmin
641
                || dropbox_cnf('allowStudentToStudent')
642
                || $current_user['status'] != 5                         // Always allow teachers.
643
                || $current_user['is_tutor'] == 1                       // Always allow tutors.
644
                ) && $current_user['user_id'] != $_user['user_id']) {   // Don't include yourself.
645
            if ($current_user['user_id'] == $current_user_id) {
646
                continue;
647
            }
648
            $userId = $current_user['user_id'];
649
            $userInfo = api_get_user_info($userId);
650
            if ($userInfo['status'] != INVITEE) {
651
                $groupNameListToString = '';
652
                if (!empty($groups)) {
653
                    $groupNameList = array_column($groups, 'name');
654
                    $groupNameListToString = ' - ['.implode(', ', $groupNameList).']';
655
                }
656
                $groups = $userGroup->getUserGroupListByUser($userId);
657
658
                $full_name = $userInfo['complete_name'].$groupNameListToString;
659
                $current_user_id = $current_user['user_id'];
660
                $options['user_' . $current_user_id] = $full_name;
661
            }
662
        }
663
    }
664
665
    /*
666
    * Show groups
667
    */
668
    if (($dropbox_person->isCourseTutor || $dropbox_person->isCourseAdmin)
669
        && dropbox_cnf('allowGroup') || dropbox_cnf('allowStudentToStudent')
670
    ) {
671
        $complete_group_list_for_dropbox = GroupManager::get_group_list(null, dropbox_cnf('courseId'));
672
673
        if (count($complete_group_list_for_dropbox) > 0) {
674
            foreach ($complete_group_list_for_dropbox as $current_group) {
675
                if ($current_group['number_of_members'] > 0) {
676
                    $options['group_'.$current_group['id']] = 'G: '.$current_group['name'].' - '.$current_group['number_of_members'].' '.get_lang('Users');
677
                }
678
            }
679
        }
680
    }
681
682
    if (dropbox_cnf('allowJustUpload')) {
683
        $options['user_'.$_user['user_id']] = get_lang('JustUploadInSelect');
684
    }
685
686
    $form->addSelect(
687
        'recipients',
688
        get_lang('SendTo'),
689
        $options,
690
        array(
691
            'multiple' => 'multiple',
692
            'size' => '10'
693
        )
694
    );
695
    $form->addButtonUpload(get_lang('Upload'), 'submitWork');
696
697
698
    $headers = array(
699
        get_lang('Upload'),
700
        get_lang('Upload').' ('.get_lang('Simple').')',
701
    );
702
703
    $multipleForm = new FormValidator(
704
        'sent_multiple',
705
        'post',
706
        '#',
707
        null,
708
        array('enctype' => 'multipart/form-data', 'id' => 'fileupload')
709
    );
710
711
    $multipleForm->addSelect(
712
        'recipients',
713
        get_lang('SendTo'),
714
        $options,
715
        array(
716
            'multiple' => 'multiple',
717
            'size' => '10',
718
            'id' => 'recipient_form'
719
        )
720
    );
721
722
    $url = api_get_path(WEB_AJAX_PATH).'dropbox.ajax.php?'.api_get_cidreq().'&a=upload_file&id=';
723
    $multipleForm->addHtml('<div id="multiple_form" style="display:none">');
724
    $multipleForm->addMultipleUpload($url);
725
    $multipleForm->addHtml('</div>');
726
727
    echo Display::tabs($headers, array($multipleForm->returnForm(), $form->returnForm()), 'tabs');
728
}
729
730
/**
731
* returns username or false if user isn't registered anymore
732
* @todo check if this function is still necessary. There might be a library function for this.
733
*/
734
function getUserNameFromId($id)
735
{
736
    $dropbox_cnf = getDropboxConf();
737
738
    $mailingId = $id - dropbox_cnf('mailingIdBase');
739
    if ($mailingId > 0) {
740
        return get_lang('MailingAsUsername', '') . $mailingId;
741
    }
742
    $id = intval($id);
743
    $sql = "SELECT ".(api_is_western_name_order() ? "CONCAT(firstname,' ', lastname)" : "CONCAT(lastname,' ', firstname)")." AS name
744
            FROM " . $dropbox_cnf['tbl_user'] . "
745
            WHERE user_id='$id'";
746
    $result = Database::query($sql);
747
    $res = Database::fetch_array($result);
748
749
    if (!$res) {
750
        return false;
751
    }
752
753
    return stripslashes($res['name']);
754
}
755
756
/**
757
* returns loginname or false if user isn't registered anymore
758
* @todo check if this function is still necessary. There might be a library function for this.
759
*/
760
function getLoginFromId($id)
761
{
762
    $id = intval($id);
763
    $sql = "SELECT username
764
            FROM " . dropbox_cnf('tbl_user') . "
765
            WHERE user_id='$id'";
766
    $result = Database::query($sql);
767
    $res = Database::fetch_array($result);
768
    if (!$res) return false;
769
770
    return stripslashes($res['username']);
771
}
772
773
/**
774
* @return boolean indicating if user with user_id=$user_id is a course member
775
* @todo check if this function is still necessary. There might be a library function for this.
776
*/
777
function isCourseMember($user_id)
778
{
779
    $_course = api_get_course_info();
780
    $course_code = $_course['code'];
781
    $is_course_member = CourseManager::is_user_subscribed_in_course($user_id, $course_code, true);
782
783
    return $is_course_member;
784
}
785
786
/**
787
* Checks if there are files in the dropbox_file table that aren't used anymore in dropbox_person table.
788
* If there are, all entries concerning the file are deleted from the db + the file is deleted from the server
789
*/
790
function removeUnusedFiles()
791
{
792
    $course_id = api_get_course_int_id();
793
794
    // select all files that aren't referenced anymore
795
    $sql = "SELECT DISTINCT f.id, f.filename
796
            FROM " . dropbox_cnf('tbl_file') . " f
797
            LEFT JOIN " . dropbox_cnf('tbl_person') . " p
798
            ON (f.id = p.file_id)
799
            WHERE p.user_id IS NULL AND
800
                  f.c_id = $course_id
801
            ";
802
    $result = Database::query($sql);
803
    while ($res = Database::fetch_array($result)) {
804
        //delete the selected files from the post and file tables
805
        $sql = "DELETE FROM " . dropbox_cnf('tbl_post') . "
806
                WHERE c_id = $course_id AND file_id = '" . $res['id'] . "'";
807
        Database::query($sql);
808
        $sql = "DELETE FROM " . dropbox_cnf('tbl_file') . "
809
                WHERE c_id = $course_id AND id ='" . $res['id'] . "'";
810
        Database::query($sql);
811
        //delete file from server
812
        @unlink( dropbox_cnf('sysPath') . '/' . $res['filename']);
813
    }
814
}
815
816
/**
817
*
818
* Mailing zip-file is posted to (dest_user_id = ) mailing pseudo_id
819
* and is only visible to its uploader (user_id).
820
*
821
* Mailing content files have uploader_id == mailing pseudo_id, a normal recipient,
822
* and are visible initially to recipient and pseudo_id.
823
*
824
* @author René Haentjens, Ghent University
825
*
826
* @todo check if this function is still necessary.
827
*/
828
function getUserOwningThisMailing($mailingPseudoId, $owner = 0, $or_die = '')
829
{
830
    $course_id = api_get_course_int_id();
831
    $dropbox_cnf = getDropboxConf();
832
833
    $mailingPseudoId = intval($mailingPseudoId);
834
    $sql = "SELECT f.uploader_id
835
            FROM " . $dropbox_cnf['tbl_file'] . " f
836
            LEFT JOIN " . $dropbox_cnf['tbl_post'] . " p
837
            ON (f.id = p.file_id AND f.c_id = $course_id AND p.c_id = $course_id)
838
            WHERE
839
                p.dest_user_id = '" . $mailingPseudoId . "' AND
840
                p.c_id = $course_id
841
            ";
842
    $result = Database::query($sql);
843
844
    if (!($res = Database::fetch_array($result)))
845
        die(get_lang('GeneralError').' (code 901)');
846
    if ($owner == 0) return $res['uploader_id'];
847
    if ($res['uploader_id'] == $owner) return true;
848
    die(get_lang('GeneralError').' (code '.$or_die.')');
849
}
850
851
/**
852
* @author René Haentjens, Ghent University
853
* @todo check if this function is still necessary.
854
*/
855
function removeMoreIfMailing($file_id)
856
{
857
    $course_id = api_get_course_int_id();
858
    $dropbox_cnf = getDropboxConf();
859
    // when deleting a mailing zip-file (posted to mailingPseudoId):
860
    // 1. the detail window is no longer reachable, so
861
    //    for all content files, delete mailingPseudoId from person-table
862
    // 2. finding the owner (getUserOwningThisMailing) is no longer possible, so
863
    //    for all content files, replace mailingPseudoId by owner as uploader
864
    $file_id = intval($file_id);
865
    $sql = "SELECT p.dest_user_id
866
            FROM " . $dropbox_cnf['tbl_post'] . " p
867
            WHERE c_id = $course_id AND p.file_id = '" . $file_id . "'";
868
    $result = Database::query($sql);
869
870
    if ($res = Database::fetch_array($result)) {
871
        $mailingPseudoId = $res['dest_user_id'];
872
        if ($mailingPseudoId > dropbox_cnf('mailingIdBase')) {
873
            $sql = "DELETE FROM " . dropbox_cnf('tbl_person') . "
874
                    WHERE c_id = $course_id AND user_id='" . $mailingPseudoId . "'";
875
            Database::query($sql);
876
877
            $sql = "UPDATE " . dropbox_cnf('tbl_file') ."
878
                    SET uploader_id='" . api_get_user_id() . "'
879
                    WHERE c_id = $course_id AND uploader_id='" . $mailingPseudoId . "'";
880
            Database::query($sql);
881
        }
882
    }
883
}
884
885
/**
886
* Function that finds a given config setting
887
*
888
* @author René Haentjens, Ghent University
889
*/
890
function dropbox_cnf($variable)
891
{
892
    $dropbox_cnf = getDropboxConf();
893
    return $dropbox_cnf[$variable];
894
}
895
896
/**
897
 * @param array $file
898
 *
899
 * @return array|null|string
900
 */
901
function store_add_dropbox($file = [])
902
{
903
    $_course = api_get_course_info();
904
    $_user = api_get_user_info();
905
    $dropbox_cnf = getDropboxConf();
906
907
    if (empty($file)) {
908
        $file = isset($_FILES['file']) ? $_FILES['file'] : null;
909
    }
910
911
    // Validating the form data
912
913
    // there are no recipients selected
914
    if (!isset($_POST['recipients']) || count($_POST['recipients']) <= 0) {
915
        return get_lang('YouMustSelectAtLeastOneDestinee');
916
    } else {
917
        // Check if all the recipients are valid
918
        $thisIsAMailing = false;
919
        $thisIsJustUpload = false;
920
        foreach ($_POST['recipients'] as $rec) {
921
            if ($rec == 'mailing') {
922
                $thisIsAMailing = true;
923
            } elseif ($rec == 'upload') {
924
                $thisIsJustUpload = true;
925
            } elseif (strpos($rec, 'user_') === 0 && !isCourseMember(substr($rec, strlen('user_')))) {
926
                Display::addFlash(Display::return_message(get_lang('InvalideUserDetected'), 'warning'));
927
                return false;
928
            } elseif (strpos($rec, 'group_') !== 0 && strpos($rec, 'user_') !== 0) {
929
                Display::addFlash(Display::return_message(get_lang('InvalideGroupDetected'), 'warning'));
930
                return false;
931
            }
932
        }
933
    }
934
935
    // we are doing a mailing but an additional recipient is selected
936
    if ($thisIsAMailing && (count($_POST['recipients']) != 1)) {
937
        Display::addFlash(Display::return_message(get_lang('MailingSelectNoOther'), 'warning'));
938
939
        return false;
940
    }
941
942
    // we are doing a just upload but an additional recipient is selected.
943
    // note: why can't this be valid? It is like sending a document to
944
    // yourself AND to a different person (I do this quite often with my e-mails)
945
    if ($thisIsJustUpload && (count($_POST['recipients']) != 1)) {
946
947
        Display::addFlash(Display::return_message(get_lang('MailingJustUploadSelectNoOther'), 'warning'));
948
        return false;
949
    }
950
951 View Code Duplication
    if (empty($file['name'])) {
952
        Display::addFlash(Display::return_message(get_lang('NoFileSpecified'), 'warning'));
953
        return false;
954
    }
955
956
    // are we overwriting a previous file or sending a new one
957
958
    $dropbox_overwrite = false;
959
    if (isset($_POST['cb_overwrite']) && $_POST['cb_overwrite']) {
960
        $dropbox_overwrite = true;
961
    }
962
963
    // doing the upload
964
965
    $dropbox_filename = $file['name'];
966
    $dropbox_filesize = $file['size'];
967
    $dropbox_filetype = $file['type'];
968
    $dropbox_filetmpname = $file['tmp_name'];
969
970
    // check if the filesize does not exceed the allowed size.
971
    if ($dropbox_filesize <= 0 || $dropbox_filesize > $dropbox_cnf['maxFilesize']) {
972
        Display::addFlash(Display::return_message(get_lang('DropboxFileTooBig'), 'warning'));
973
974
        return false;
975
    }
976
977
    // check if the file is actually uploaded
978 View Code Duplication
    if (!is_uploaded_file($dropbox_filetmpname)) { // check user fraud : no clean error msg.
979
        Display::addFlash(Display::return_message(get_lang('TheFileIsNotUploaded'), 'warning'));
980
981
        return false;
982
    }
983
984
    $upload_ok = process_uploaded_file($file, true);
985
986
    if (!$upload_ok) {
987
        return null;
988
    }
989
990
    // Try to add an extension to the file if it hasn't got one
991
    $dropbox_filename = add_ext_on_mime($dropbox_filename, $dropbox_filetype);
992
    // Replace dangerous characters
993
    $dropbox_filename = api_replace_dangerous_char($dropbox_filename);
994
    // Transform any .php file in .phps fo security
995
    $dropbox_filename = php2phps($dropbox_filename);
996
997
    //filter extension
998 View Code Duplication
    if (!filter_extension($dropbox_filename)) {
999
        Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'warning'));
1000
        return false;
1001
    }
1002
1003
    // set title
1004
    $dropbox_title = $dropbox_filename;
1005
    // set author
1006
    if (!isset($_POST['authors'])) {
1007
        $_POST['authors'] = getUserNameFromId($_user['user_id']);
1008
    }
1009
1010
    // note: I think we could better migrate everything from here on to
1011
    // separate functions: store_new_dropbox, store_new_mailing, store_just_upload
1012
1013
    if ($dropbox_overwrite) {
1014
        $dropbox_person = new Dropbox_Person(
1015
            $_user['user_id'],
1016
            api_is_course_admin(),
1017
            api_is_course_tutor()
1018
        );
1019
1020
        foreach ($dropbox_person->sentWork as $w) {
1021
            if ($w->title == $dropbox_filename) {
1022
                if (($w->recipients[0]['id'] > dropbox_cnf('mailingIdBase')) xor $thisIsAMailing) {
1023
                    Display::addFlash(Display::return_message(get_lang('MailingNonMailingError'), 'warning'));
1024
                    return false;
1025
                }
1026
                if (($w->recipients[0]['id'] == $_user['user_id']) xor $thisIsJustUpload) {
1027
1028
                    Display::addFlash(Display::return_message(get_lang('MailingJustUploadSelectNoOther'), 'warning'));
1029
                    return false;
1030
                }
1031
                $dropbox_filename = $w->filename;
1032
                $found = true; // note: do we still need this?
1033
                break;
1034
            }
1035
        }
1036 View Code Duplication
    } else {  // rename file to login_filename_uniqueId format
1037
        $dropbox_filename = getLoginFromId($_user['user_id']) . "_" . $dropbox_filename . "_".uniqid('');
1038
    }
1039
1040
    // creating the array that contains all the users who will receive the file
1041
    $new_work_recipients = array();
1042 View Code Duplication
    foreach ($_POST['recipients'] as $rec) {
1043
        if (strpos($rec, 'user_') === 0) {
1044
            $new_work_recipients[] = substr($rec, strlen('user_'));
1045
        } elseif (strpos($rec, 'group_') === 0) {
1046
            $userList = GroupManager::get_subscribed_users(substr($rec, strlen('group_')));
1047
            foreach ($userList as $usr) {
1048
                if (!in_array($usr['user_id'], $new_work_recipients) && $usr['user_id'] != $_user['user_id']) {
1049
                    $new_work_recipients[] = $usr['user_id'];
1050
                }
1051
            }
1052
        }
1053
    }
1054
1055
    @move_uploaded_file($dropbox_filetmpname, dropbox_cnf('sysPath') . '/' . $dropbox_filename);
1056
1057
    $b_send_mail = api_get_course_setting('email_alert_on_new_doc_dropbox');
1058
1059
    if ($b_send_mail) {
1060
        foreach ($new_work_recipients as $recipient_id) {
1061
            $recipent_temp = api_get_user_info($recipient_id);
1062
            $additionalParameters = array(
1063
                'smsType' => SmsPlugin::NEW_FILE_SHARED_COURSE_BY,
1064
                'userId' => $recipient_id,
1065
                'courseTitle' => $_course['title'],
1066
                'userUsername' => $recipent_temp['username']
1067
            );
1068
            api_mail_html(
1069
                api_get_person_name(
1070
                    $recipent_temp['firstname'].' '.$recipent_temp['lastname'],
1071
                    null,
1072
                    PERSON_NAME_EMAIL_ADDRESS
1073
                ),
1074
                $recipent_temp['email'],
1075
                get_lang('NewDropboxFileUploaded'),
1076
                get_lang('NewDropboxFileUploadedContent').' <a href="'.api_get_path(WEB_CODE_PATH).'dropbox/index.php?' . api_get_cidreq() . '">'.get_lang('SeeFile').'</a>'.
1077
                "\n\n".
1078
                api_get_person_name(
1079
                    $_user['firstName'],
1080
                    $_user['lastName'],
1081
                    null,
1082
                    PERSON_NAME_EMAIL_ADDRESS
1083
                )."\n".  get_lang('Email') ." : ".$_user['mail'],
1084
                api_get_person_name(
1085
                    $_user['firstName'],
1086
                    $_user['lastName'],
1087
                    null,
1088
                    PERSON_NAME_EMAIL_ADDRESS
1089
                ),
1090
                $_user['mail'],
1091
                null,
1092
                null,
1093
                null,
1094
                $additionalParameters
1095
            );
1096
        }
1097
    }
1098
1099
    $result = new Dropbox_SentWork(
1100
        $_user['user_id'],
1101
        $dropbox_title,
1102
        isset($_POST['description']) ? $_POST['description'] : '',
1103
        strip_tags($_POST['authors']),
1104
        $dropbox_filename,
1105
        $dropbox_filesize,
1106
        $new_work_recipients
1107
    );
1108
1109
    Security::clear_token();
1110
    Display::addFlash(Display::return_message(get_lang('FileUploadSucces')));
1111
1112
    return $result;
1113
}
1114
1115
/**
1116
* Transforms the array containing all the feedback into something visually attractive.
1117
*
1118
* @param an array containing all the feedback about the given message.
1119
*
1120
* @author Patrick Cool <[email protected]>, Ghent University
1121
* @version march 2006
1122
*/
1123
function feedback($array) {
1124
    $output = null;
1125
    foreach ($array as $value) {
1126
        $output .= format_feedback($value);
1127
    }
1128
    $output .= feedback_form();
1129
    return $output;
1130
}
1131
1132
/**
1133
* This function returns the html code to display the feedback messages on a given dropbox file
1134
* @param $feedback_array an array that contains all the feedback messages about the given document.
1135
* @return html code
1136
* @todo add the form for adding new comment (if the other party has not deleted it yet).
1137
*
1138
* @author Patrick Cool <[email protected]>, Ghent University
1139
* @version march 2006
1140
*/
1141
function format_feedback($feedback)
1142
{
1143
    $userInfo = api_get_user_info($feedback['author_user_id']);
1144
    $output = UserManager::getUserProfileLink($userInfo);
0 ignored issues
show
Security Bug introduced by
It seems like $userInfo defined by api_get_user_info($feedback['author_user_id']) on line 1143 can also be of type false; however, UserManager::getUserProfileLink() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1145
    $output .= '&nbsp;&nbsp;'.api_convert_and_format_date($feedback['feedback_date'], DATE_TIME_FORMAT_LONG).'<br />';
1146
    $output .= '<div style="padding-top:6px">'.nl2br($feedback['feedback']).'</div><hr size="1" noshade/><br />';
1147
    return $output;
1148
}
1149
1150
/**
1151
* this function returns the code for the form for adding a new feedback message to a dropbox file.
1152
* @return html code
1153
*
1154
* @author Patrick Cool <[email protected]>, Ghent University
1155
* @version march 2006
1156
*/
1157
function feedback_form()
1158
{
1159
    $return = get_lang('AddNewFeedback').'<br />';
1160
    $number_users_who_see_file = check_if_file_exist($_GET['id']);
1161
    if ($number_users_who_see_file) {
1162
        $token = Security::get_token();
1163
        $return .= '<textarea name="feedback" style="width: 80%; height: 80px;"></textarea>';
1164
        $return .= '<input type="hidden" name="sec_token" value="'.$token.'"/>';
1165
        $return .= '<br /><button type="submit" class="add" name="store_feedback" value="'.get_lang('Ok').'"
1166
                    onclick="javascript: document.form_dropbox.attributes.action.value = document.location;">'.get_lang('AddComment').'</button>';
1167
    } else {
1168
        $return .= get_lang('AllUsersHaveDeletedTheFileAndWillNotSeeFeedback');
1169
    }
1170
    return $return;
1171
}
1172
1173
function user_can_download_file($id, $user_id)
1174
{
1175
    $dropbox_cnf = getDropboxConf();
1176
    $course_id = api_get_course_int_id();
1177
    $id = intval($id);
1178
    $user_id = intval($user_id);
1179
1180
    $sql = "SELECT file_id FROM ".$dropbox_cnf['tbl_person']."
1181
            WHERE c_id = $course_id AND user_id = $user_id AND file_id = ".$id;
1182
    $result = Database::query($sql);
1183
    $number_users_who_see_file = Database::num_rows($result);
1184
1185
    $sql = "SELECT file_id FROM ".$dropbox_cnf["tbl_post"]."
1186
            WHERE c_id = $course_id AND dest_user_id = $user_id AND file_id = ".$id;
1187
    $result = Database::query($sql);
1188
    $count = Database::num_rows($result);
1189
    return $number_users_who_see_file > 0 || $count > 0;
1190
}
1191
1192
// we now check if the other users have not delete this document yet.
1193
// If this is the case then it is useless to see the
1194
// add feedback since the other users will never get to see the feedback.
1195
function check_if_file_exist($id)
1196
{
1197
    $dropbox_cnf = getDropboxConf();
1198
    $id = intval($id);
1199
    $course_id = api_get_course_int_id();
1200
    $sql = "SELECT file_id FROM ".$dropbox_cnf['tbl_person']."
1201
            WHERE c_id = $course_id AND file_id = ".$id;
1202
    $result = Database::query($sql);
1203
    $number_users_who_see_file = Database::num_rows($result);
1204
1205
    $sql = "SELECT file_id FROM ".$dropbox_cnf["tbl_post"]."
1206
            WHERE c_id = $course_id AND file_id = ".$id;
1207
    $result = Database::query($sql);
1208
    $count = Database::num_rows($result);
1209
    return $number_users_who_see_file > 0 || $count > 0;
1210
}
1211
1212
/**
1213
* @return a language string (depending on the success or failure.
1214
*
1215
* @author Patrick Cool <[email protected]>, Ghent University
1216
* @version march 2006
1217
*/
1218
function store_feedback()
1219
{
1220
    $dropbox_cnf = getDropboxConf();
1221
    if (!is_numeric($_GET['id'])) {
1222
        return get_lang('FeedbackError');
1223
    }
1224
    $course_id = api_get_course_int_id();
1225
    if (empty($_POST['feedback'])) {
1226
        return get_lang('PleaseTypeText');
1227
    } else {
1228
        $params = [
1229
            'c_id' => $course_id,
1230
            'file_id' => $_GET['id'],
1231
            'author_user_id' => api_get_user_id(),
1232
            'feedback' => $_POST['feedback'],
1233
            'feedback_date' => api_get_utc_datetime(),
1234
        ];
1235
1236
        $id = Database::insert($dropbox_cnf['tbl_feedback'], $params);
1237
        if ($id) {
1238
            $sql = "UPDATE ".$dropbox_cnf['tbl_feedback']." SET feedback_id = iid WHERE iid = $id";
1239
            Database::query($sql);
1240
        }
1241
1242
        return get_lang('DropboxFeedbackStored');
1243
    }
1244
}
1245
1246
/**
1247
* This function downloads all the files of the input array into one zip
1248
* @param array $fileList containing all the ids of the files that have to be downloaded.
1249
* @author Patrick Cool <[email protected]>, Ghent University
1250
* @todo consider removing the check if the user has received or sent this file (zip download of a folder already sufficiently checks for this).
1251
* @todo integrate some cleanup function that removes zip files that are older than 2 days
1252
*
1253
* @author Patrick Cool <[email protected]>, Ghent University
1254
* @author Julio Montoya  Addin c_id support
1255
* @version march 2006
1256
*/
1257
function zip_download($fileList)
1258
{
1259
    $_course = api_get_course_info();
1260
    $dropbox_cnf = getDropboxConf();
1261
    $course_id = api_get_course_int_id();
1262
    $fileList = array_map('intval', $fileList);
1263
1264
    // note: we also have to add the check if the user has received or sent this file.
1265
    $sql = "SELECT DISTINCT file.filename, file.title, file.author, file.description
1266
            FROM ".$dropbox_cnf['tbl_file']." file
1267
            INNER JOIN ".$dropbox_cnf['tbl_person']." person
1268
            ON (person.file_id=file.id AND file.c_id = $course_id AND person.c_id = $course_id)
1269
            INNER JOIN ".$dropbox_cnf['tbl_post']." post
1270
            ON (post.file_id = file.id AND post.c_id = $course_id AND file.c_id = $course_id)
1271
            WHERE
1272
                file.id IN (".implode(', ', $fileList).") AND
1273
                file.id = person.file_id AND
1274
                (
1275
                    person.user_id = '".api_get_user_id()."' OR
1276
                    post.dest_user_id = '".api_get_user_id()."'
1277
                ) ";
1278
    $result = Database::query($sql);
1279
1280
    $files = array();
1281
    while ($row = Database::fetch_array($result)) {
1282
        $files[$row['filename']] = array(
1283
            'filename' => $row['filename'],
1284
            'title' => $row['title'],
1285
            'author' => $row['author'],
1286
            'description' => $row['description']
1287
        );
1288
    }
1289
1290
    // Step 3: create the zip file and add all the files to it
1291
    $temp_zip_file = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
1292
    Session::write('dropbox_files_to_download', $files);
1293
    $zip = new PclZip($temp_zip_file);
1294
    foreach ($files as $value) {
1295
        $zip->add(
1296
            api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'],
1297
            PCLZIP_OPT_REMOVE_ALL_PATH,
1298
            PCLZIP_CB_PRE_ADD,
1299
            'my_pre_add_callback'
1300
        );
1301
    }
1302
    Session::erase('dropbox_files_to_download');
1303
    $name = 'dropbox-'.api_get_utc_datetime().'.zip';
1304
    DocumentManager::file_send_for_download($temp_zip_file, true, $name);
1305
    @unlink($temp_zip_file);
1306
    exit;
1307
}
1308
1309
/**
1310
* This is a callback function to decrypt the files in the zip file to their normal filename (as stored in the database)
1311
* @param array $p_event a variable of PCLZip
1312
* @param array $p_header a variable of PCLZip
1313
*
1314
* @author Patrick Cool <[email protected]>, Ghent University
1315
* @version march 2006
1316
*/
1317
function my_pre_add_callback($p_event, &$p_header)
1318
{
1319
    $files = Session::read('dropbox_files_to_download');
1320
    $p_header['stored_filename'] = $files[$p_header['stored_filename']]['title'];
1321
    return 1;
1322
}
1323
1324
/**
1325
 * @desc Generates the contents of a html file that gives an overview of all the files in the zip file.
1326
 *       This is to know the information of the files that are inside the zip file (who send it, the comment, ...)
1327
 * @author Patrick Cool <[email protected]>, Ghent University, March 2006
1328
 * @author Ivan Tcholakov, 2010, code for html metadata has been added.
1329
 */
1330
function generate_html_overview($files, $dont_show_columns = array(), $make_link = array())
1331
{
1332
    $return = '<!DOCTYPE html'."\n";
1333
    $return .= "\t".'PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'."\n";
1334
    $return .= "\t".'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
1335
    $return .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.api_get_language_isocode().'" lang="'.api_get_language_isocode().'">'."\n";
1336
1337
    $return .= "<head>\n\t<title>".get_lang('OverviewOfFilesInThisZip')."</title>\n";
1338
    $return .= "\t".'<meta http-equiv="Content-Type" content="text/html; charset='.api_get_system_encoding().'" />'."\n";
1339
    $return .= "</head>\n\n";
1340
    $return .= '<body dir="'.api_get_text_direction().'">'."\n\n";
1341
    $return .= "<table border=\"1px\">\n";
1342
1343
    $counter = 0;
1344
    foreach ($files as $value) {
1345
1346
        // Adding the header.
1347
        if ($counter == 0) {
1348
            $columns_array = array_keys($value);
1349
            $return .= "\n<tr>";
1350
            foreach ($columns_array as $columns_array_key => $columns_array_value) {
1351
                if (!in_array($columns_array_value, $dont_show_columns)) {
1352
                    $return .= "\n\t<th>".$columns_array_value."</th>";
1353
                }
1354
                $column[] = $columns_array_value;
1355
            }
1356
            $return .= "\n</tr>\n";
1357
        }
1358
        $counter++;
1359
1360
        // Adding the content.
1361
        $return .= "\n<tr>";
1362
        foreach ($column as $column_key => $column_value) {
1363
            if (!in_array($column_value,$dont_show_columns)) {
1364
                $return .= "\n\t<td>";
1365
                if (in_array($column_value, $make_link)) {
1366
                    $return .= '<a href="'.$value[$column_value].'">'.$value[$column_value].'</a>';
1367
                } else {
1368
                    $return .= $value[$column_value];
1369
                }
1370
                $return .= "</td>";
1371
            }
1372
        }
1373
        $return .= "\n</tr>\n";
1374
    }
1375
    $return .= "\n</table>\n\n</body>";
1376
    $return .= "\n</html>";
1377
1378
    return $return;
1379
}
1380
1381
/**
1382
* @desc This function retrieves the number of feedback messages on every document. This function might become obsolete when
1383
*       the feedback becomes user individual.
1384
* @author Patrick Cool <[email protected]>, Ghent University
1385
* @version march 2006
1386
*/
1387
function get_total_number_feedback($file_id = '')
1388
{
1389
    $dropbox_cnf = getDropboxConf();
1390
    $course_id = api_get_course_int_id();
1391
    $sql = "SELECT COUNT(feedback_id) AS total, file_id
1392
            FROM ".$dropbox_cnf['tbl_feedback']."
1393
            WHERE c_id = $course_id GROUP BY file_id";
1394
    $result = Database::query($sql);
1395
    $return = array();
1396
    while ($row=Database::fetch_array($result)) {
1397
        $return[$row['file_id']] = $row['total'];
1398
    }
1399
    return $return;
1400
}
1401
1402
1403
/**
1404
* @desc this function checks if the key exists. If this is the case it returns the value, if not it returns 0
1405
* @author Patrick Cool <[email protected]>, Ghent University
1406
* @version march 2006
1407
*/
1408
function check_number_feedback($key, $array)
1409
{
1410
    if (is_array($array)) {
1411
        if (array_key_exists($key, $array)) {
1412
            return $array[$key];
1413
        } else {
1414
            return 0;
1415
        }
1416
    } else {
1417
        return 0;
1418
    }
1419
}
1420
1421
/**
1422
 * Get the last access to a given tool of a given user
1423
 * @param $tool string the tool constant
1424
 * @param $courseId the course_id
1425
 * @param $user_id the id of the user
1426
 * @return string last tool access date
1427
 *
1428
 * @author Patrick Cool <[email protected]>, Ghent University
1429
 * @version march 2006
1430
 *
1431
 * @todo consider moving this function to a more appropriate place.
1432
 */
1433
function get_last_tool_access($tool, $courseId = null, $user_id = null)
1434
{
1435
    // The default values of the parameters
1436
    if (empty($courseId)) {
1437
        $courseId = api_get_course_int_id();
1438
    }
1439
    if (empty($user_id)) {
1440
        $user_id = api_get_user_id();
1441
    }
1442
1443
    // the table where the last tool access is stored (=track_e_lastaccess)
1444
    $table_last_access = Database::get_main_table('track_e_lastaccess');
1445
1446
    $sql = "SELECT access_date FROM $table_last_access
1447
            WHERE
1448
                access_user_id = ".intval($user_id)." AND
1449
                c_id='".intval($courseId)."' AND
1450
                access_tool='".Database::escape_string($tool)."'
1451
                ORDER BY access_date DESC
1452
                LIMIT 1";
1453
    $result = Database::query($sql);
1454
    $row = Database::fetch_array($result);
1455
    return $row['access_date'];
1456
}
1457