Dropbox_SentWork::createExistingSentWork()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 20
nc 3
nop 1
dl 0
loc 27
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Dropbox module for Chamilo
7
 * Classes for the dropbox module.
8
 *
9
 * 3 classes have been defined:
10
 * - Dropbox_Work:
11
 *        . id
12
 *        . uploader_id    => who sent it
13
 *        . filename        => name of file stored on the server
14
 *        . filesize
15
 *        . title            => name of file returned to user. This is the original name of the file
16
 *                            except when the original name contained spaces. In that case the spaces
17
 *                            will be replaced by _
18
 *        . description
19
 *        . author
20
 *        . upload_date    => date when file was first sent
21
 *        . last_upload_date => date when file was last sent
22
 *    . isOldWork    => has the work already been uploaded before
23
 *
24
 *      . feedback_date  => date of most recent feedback
25
 *      . feedback      => feedback text (or HTML?)
26
 *
27
 * - Dropbox_SentWork extends Dropbox_Work
28
 *        . recipients    => array of ["id"]["name"] lists the recipients of the work
29
 *
30
 * - Dropbox_Person:
31
 *        . userId
32
 *        . receivedWork    => array of Dropbox_Work objects
33
 *        . sentWork        => array of Dropbox_SentWork objects
34
 *        . isCourseTutor
35
 *        . isCourseAdmin
36
 *        . _orderBy        => private property used for determining the field by which the works have to be ordered
37
 *
38
 * @version 1.30
39
 *
40
 * @copyright 2004
41
 * @author Jan Bols <[email protected]>
42
 * with contributions by René Haentjens <[email protected]>
43
 */
44
class Dropbox_Work
45
{
46
    public $id;
47
    public $uploader_id;
48
    public $filename;
49
    public $filesize;
50
    public $title;
51
    public $description;
52
    public $author;
53
    public $upload_date;
54
    public $last_upload_date;
55
    public $isOldWork;
56
    public $feedback_date;
57
    public $feedback;
58
59
    /**
60
     * Constructor calls private functions to create a new work or retrieve an existing work from DB
61
     * depending on the number of parameters.
62
     *
63
     * @param int    $arg1
64
     * @param string $arg2
65
     * @param string $arg3
66
     * @param string $arg4
67
     * @param string $arg5
68
     * @param int    $arg6
69
     */
70
    public function __construct($arg1, $arg2 = null, $arg3 = null, $arg4 = null, $arg5 = null, $arg6 = null)
71
    {
72
        if (func_num_args() > 1) {
73
            $this->createNewWork($arg1, $arg2, $arg3, $arg4, $arg5, $arg6);
74
        } else {
75
            $this->createExistingWork($arg1);
76
        }
77
    }
78
79
    /**
80
     * private function creating a new work object.
81
     *
82
     * @param int    $uploader_id
83
     * @param string $title
84
     * @param string $description
85
     * @param string $author
86
     * @param string $filename
87
     * @param int    $filesize
88
     *
89
     * @todo    $author was originally a field but this has now been replaced by the first and lastname of the uploader (to prevent anonymous uploads)
90
     *            As a consequence this parameter can be removed
91
     */
92
    public function createNewWork($uploader_id, $title, $description, $author, $filename, $filesize)
93
    {
94
        // Fill in the properties
95
        $this->uploader_id = (int) $uploader_id;
96
        $this->filename = $filename;
97
        $this->filesize = $filesize;
98
        $this->title = $title;
99
        $this->description = $description;
100
        $this->author = $author;
101
        $this->last_upload_date = api_get_utc_datetime();
102
        $course_id = api_get_course_int_id();
103
104
        // Check if object exists already. If it does, the old object is used
105
        // with updated information (authors, description, upload_date)
106
        $this->isOldWork = false;
107
        $sql = 'SELECT id, upload_date
108
                FROM '.Database::get_course_table(TABLE_DROPBOX_FILE)."
109
                WHERE
110
                    c_id = $course_id AND
111
                    filename = '".Database::escape_string($this->filename)."'";
112
        $result = Database::query($sql);
113
        $res = Database::fetch_array($result);
114
        if ($res) {
115
            $this->isOldWork = true;
116
        }
117
        // Insert or update the dropbox_file table and set the id property
118
        if ($this->isOldWork) {
119
            $this->id = $res['id'];
120
            $this->upload_date = $res['upload_date'];
121
122
            $params = [
123
                'filesize' => $this->filesize,
124
                'title' => $this->title,
125
                'description' => $this->description,
126
                'author' => $this->author,
127
                'last_upload_date' => $this->last_upload_date,
128
                'session_id' => api_get_session_id(),
129
            ];
130
131
            Database::update(
132
                Database::get_course_table(TABLE_DROPBOX_FILE),
133
                $params,
134
                ['c_id = ? AND id = ?' => [$course_id, $this->id]]
135
            );
136
        } else {
137
            $this->upload_date = $this->last_upload_date;
138
            $params = [
139
                'c_id' => $course_id,
140
                'uploader_id' => $this->uploader_id,
141
                'filename' => $this->filename,
142
                'filesize' => $this->filesize,
143
                'title' => $this->title,
144
                'description' => $this->description,
145
                'author' => $this->author,
146
                'upload_date' => $this->upload_date,
147
                'last_upload_date' => $this->last_upload_date,
148
                'session_id' => api_get_session_id(),
149
                'cat_id' => 0,
150
            ];
151
152
            $this->id = Database::insert(Database::get_course_table(TABLE_DROPBOX_FILE), $params);
153
            if ($this->id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
154
                $sql = 'UPDATE '.Database::get_course_table(TABLE_DROPBOX_FILE)." SET id = iid
155
                        WHERE iid = {$this->id}";
156
                Database::query($sql);
157
            }
158
        }
159
160
        $sql = 'SELECT count(file_id) as count
161
                FROM '.Database::get_course_table(TABLE_DROPBOX_PERSON)."
162
                WHERE c_id = $course_id AND file_id = ".intval($this->id).' AND user_id = '.$this->uploader_id;
163
        $result = Database::query($sql);
164
        $row = Database::fetch_array($result);
165
        if (0 == $row['count']) {
166
            // Insert entries into person table
167
            $sql = 'INSERT INTO '.Database::get_course_table(TABLE_DROPBOX_PERSON)." (c_id, file_id, user_id)
168
                    VALUES ($course_id, ".intval($this->id).' , '.intval($this->uploader_id).')';
169
            Database::query($sql);
170
        }
171
    }
172
173
    /**
174
     * private function creating existing object by retrieving info from db.
175
     *
176
     * @param int $id
177
     */
178
    public function createExistingWork($id)
179
    {
180
        $course_id = api_get_course_int_id();
181
        $action = isset($_GET['action']) ? $_GET['action'] : null;
182
183
        // Do some sanity checks
184
        $id = intval($id);
185
186
        // Get the data from DB
187
        $sql = 'SELECT uploader_id, filename, filesize, title, description, author, upload_date, last_upload_date, cat_id
188
                FROM '.Database::get_course_table(TABLE_DROPBOX_FILE)."
189
                WHERE c_id = $course_id AND id = ".$id.'';
190
        $result = Database::query($sql);
191
        $res = Database::fetch_array($result, 'ASSOC');
192
193
        // Check if uploader is still in Chamilo system
194
        $uploader_id = stripslashes($res['uploader_id']);
195
        $userInfo = api_get_user_info($uploader_id);
196
        if (!$userInfo) {
197
            //deleted user
198
            $this->uploader_id = -1;
199
        } else {
200
            $this->uploader_id = $uploader_id;
201
        }
202
203
        // Fill in properties
204
        $this->id = $id;
205
        $this->filename = stripslashes($res['filename']);
206
        $this->filesize = stripslashes($res['filesize']);
207
        $this->title = stripslashes($res['title']);
208
        $this->description = stripslashes($res['description']);
209
        $this->author = stripslashes($res['author']);
210
        $this->upload_date = stripslashes($res['upload_date']);
211
        $this->last_upload_date = stripslashes($res['last_upload_date']);
212
        $this->category = $res['cat_id'];
213
214
        // Getting the feedback on the work.
215
        if ('viewfeedback' == $action && $this->id == $_GET['id']) {
216
            $feedback2 = [];
217
            $sql = 'SELECT * FROM '.Database::get_course_table(TABLE_DROPBOX_FEEDBACK)."
218
                    WHERE c_id = $course_id AND file_id='".$id."'
219
                    ORDER BY feedback_id ASC";
220
            $result = Database::query($sql);
221
            while ($row_feedback = Database::fetch_array($result)) {
222
                $row_feedback['feedback'] = Security::remove_XSS($row_feedback['feedback']);
223
                $feedback2[] = $row_feedback;
224
            }
225
            $this->feedback2 = $feedback2;
226
        }
227
    }
228
229
    /**
230
     * @return bool
231
     */
232
    public function updateFile()
233
    {
234
        $course_id = api_get_course_int_id();
235
        if (empty($this->id) || empty($course_id)) {
236
            return false;
237
        }
238
239
        $params = [
240
            'uploader_id' => $this->uploader_id,
241
            'filename' => $this->filename,
242
            'filesize' => $this->filesize,
243
            'title' => $this->title,
244
            'description' => $this->description,
245
            'author' => $this->author,
246
            'upload_date' => $this->upload_date,
247
            'last_upload_date' => $this->last_upload_date,
248
            'session_id' => api_get_session_id(),
249
        ];
250
251
        Database::update(
252
            Database::get_course_table(TABLE_DROPBOX_FILE),
253
            $params,
254
            ['c_id = ? AND id = ?' => [$course_id, $this->id]]
255
        );
256
257
        return true;
258
    }
259
}
260
261
class Dropbox_SentWork extends Dropbox_Work
262
{
263
    public $recipients; //array of ['id']['name'] arrays
264
265
    /**
266
     * Constructor calls private functions to create a new work or retrieve an existing work from DB
267
     * depending on the number of parameters.
268
     *
269
     * @param int    $arg1
270
     * @param string $arg2
271
     * @param string $arg3
272
     * @param string $arg4
273
     * @param string $arg5
274
     * @param int    $arg6
275
     * @param array  $arg7
276
     */
277
    public function __construct($arg1, $arg2 = null, $arg3 = null, $arg4 = null, $arg5 = null, $arg6 = null, $arg7 = null)
278
    {
279
        if (func_num_args() > 1) {
280
            $this->createNewSentWork($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7);
281
        } else {
282
            $this->createExistingSentWork($arg1);
283
        }
284
    }
285
286
    /**
287
     * private function creating a new SentWork object.
288
     *
289
     * @param int    $uploader_id
290
     * @param string $title
291
     * @param string $description
292
     * @param string $author
293
     * @param string $filename
294
     * @param int    $filesize
295
     * @param array  $recipient_ids
296
     */
297
    public function createNewSentWork($uploader_id, $title, $description, $author, $filename, $filesize, $recipient_ids)
298
    {
299
        $_course = api_get_course_info();
300
301
        // Call constructor of Dropbox_Work object
302
        parent::__construct(
303
            $uploader_id,
304
            $title,
305
            $description,
306
            $author,
307
            $filename,
308
            $filesize
309
        );
310
311
        $course_id = api_get_course_int_id();
312
313
        // Do sanity checks on recipient_ids array & property filling
314
        // The sanity check for ex-course members is already done in base constructor
315
        $uploader_id = (int) $uploader_id;
316
317
        $justSubmit = false;
318
        if (is_int($recipient_ids)) {
319
            $justSubmit = true;
320
            $recipient_ids = [$recipient_ids + $this->id];
321
        } elseif (0 == count($recipient_ids)) {
322
            $justSubmit = true;
323
            $recipient_ids = [$uploader_id];
324
        }
325
326
        if (!is_array($recipient_ids) || 0 == count($recipient_ids)) {
327
            exit(get_lang('GeneralError').' (code 209)');
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...
328
        }
329
330
        foreach ($recipient_ids as $rec) {
331
            if (empty($rec)) {
332
                continue;
333
            }
334
335
            //this check is done when validating submitted data
336
            $this->recipients[] = ['id' => $rec];
337
        }
338
339
        $table_post = Database::get_course_table(TABLE_DROPBOX_POST);
340
        $table_person = Database::get_course_table(TABLE_DROPBOX_PERSON);
341
        $session_id = api_get_session_id();
342
        $user = api_get_user_id();
343
        $now = api_get_utc_datetime();
344
        $mailId = get_mail_id_base();
345
346
        // Insert data in dropbox_post and dropbox_person table for each recipient
347
        foreach ($this->recipients as $rec) {
348
            $file_id = (int) $this->id;
349
            $user_id = (int) $rec['id'];
350
            $sql = "INSERT INTO $table_post (c_id, file_id, dest_user_id, session_id, feedback_date, cat_id)
351
                    VALUES ($course_id, $file_id, $user_id, $session_id, '$now', 0)";
352
            Database::query($sql);
353
            // If work already exists no error is generated
354
355
            /*
356
             * Poster is already added when work is created - not so good to split logic.
357
             */
358
            if ($user_id != $user) {
359
                // Insert entries into person table
360
                $sql = "INSERT INTO $table_person (c_id, file_id, user_id)
361
                        VALUES ($course_id, $file_id, $user_id)";
362
363
                // Do not add recipient in person table if mailing zip or just upload.
364
                if (!$justSubmit) {
365
                    Database::query($sql); // If work already exists no error is generated
366
                }
367
            }
368
369
            // Update item_property table for each recipient
370
            if (($ownerid = $this->uploader_id) > $mailId) {
371
                $ownerid = getUserOwningThisMailing($ownerid);
372
            }
373
            if (($recipid = $rec['id']) > $mailId) {
374
                $recipid = $ownerid; // mailing file recipient = mailing id, not a person
375
            }
376
            api_item_property_update(
377
                $_course,
378
                TOOL_DROPBOX,
379
                $this->id,
380
                'DropboxFileAdded',
381
                $ownerid,
382
                null,
383
                $recipid
384
            );
385
        }
386
    }
387
388
    /**
389
     * private function creating existing object by retrieving info from db.
390
     *
391
     * @param int $id
392
     */
393
    public function createExistingSentWork($id)
394
    {
395
        $id = (int) $id;
396
        $course_id = api_get_course_int_id();
397
398
        // Call constructor of Dropbox_Work object
399
        parent::__construct($id);
400
401
        // Fill in recipients array
402
        $this->recipients = [];
403
        $sql = 'SELECT dest_user_id, feedback_date, feedback
404
                FROM '.Database::get_course_table(TABLE_DROPBOX_POST)."
405
                WHERE c_id = $course_id AND file_id = ".intval($id);
406
        $result = Database::query($sql);
407
        while ($res = Database::fetch_array($result, 'ASSOC')) {
408
            // Check for deleted users
409
            $dest_user_id = $res['dest_user_id'];
410
            $user_info = api_get_user_info($dest_user_id);
411
            if (!$user_info) {
412
                $this->recipients[] = ['id' => -1, 'name' => get_lang('Unknown', '')];
413
            } else {
414
                $this->recipients[] = [
415
                    'id' => $dest_user_id,
416
                    'name' => $user_info['complete_name'],
417
                    'user_id' => $dest_user_id,
418
                    'feedback_date' => $res['feedback_date'],
419
                    'feedback' => $res['feedback'],
420
                ];
421
            }
422
        }
423
    }
424
}
425
426
class Dropbox_Person
427
{
428
    // The receivedWork and the sentWork arrays are sorted.
429
    public $receivedWork; // an array of Dropbox_Work objects
430
    public $sentWork; // an array of Dropbox_SentWork objects
431
432
    public $userId = 0;
433
    public $isCourseAdmin = false;
434
    public $isCourseTutor = false;
435
    public $_orderBy = ''; // private property that determines by which field
436
437
    /**
438
     * Constructor for recreating the Dropbox_Person object.
439
     */
440
    public function __construct(
441
        int $userId,
442
        bool $isCourseAdmin,
443
        bool $isCourseTutor,
444
        int $courseId = 0,
445
        int $sessionId = 0
446
    ) {
447
        if (empty($courseId)) {
448
            $courseId = api_get_course_int_id();
449
        }
450
        if (empty($sessionId)) {
451
            $sessionId = api_get_session_id();
452
        }
453
454
        // Fill in properties
455
        $this->userId = $userId;
456
        $this->isCourseAdmin = $isCourseAdmin;
457
        $this->isCourseTutor = $isCourseTutor;
458
        $this->receivedWork = [];
459
        $this->sentWork = [];
460
461
        // Note: perhaps include an ex course member check to delete old files
462
463
        $condition_session = api_get_session_condition($sessionId);
464
465
        $post_tbl = Database::get_course_table(TABLE_DROPBOX_POST);
466
        $person_tbl = Database::get_course_table(TABLE_DROPBOX_PERSON);
467
        $file_tbl = Database::get_course_table(TABLE_DROPBOX_FILE);
468
469
        // Find all entries where this person is the recipient
470
        $sql = "SELECT DISTINCT r.file_id, r.cat_id
471
                FROM $post_tbl r
472
                INNER JOIN $person_tbl p
473
                ON (r.file_id = p.file_id AND r.c_id = p.c_id)
474
                WHERE
475
                     r.c_id = $courseId AND
476
                     p.user_id = ".intval($this->userId).' AND
477
                     r.dest_user_id = '.intval($this->userId)." $condition_session ";
478
479
        $result = Database::query($sql);
480
        while ($res = Database::fetch_array($result)) {
481
            $temp = new Dropbox_Work($res['file_id']);
482
            $temp->category = $res['cat_id'];
483
            $this->receivedWork[] = $temp;
484
        }
485
        // Find all entries where this person is the sender/uploader
486
        $sql = "SELECT DISTINCT f.id
487
                FROM $file_tbl f
488
                INNER JOIN $person_tbl p
489
                ON (f.id = p.file_id AND f.c_id = p.c_id)
490
                WHERE
491
                    f.c_id = $courseId AND
492
                    f.uploader_id   = ".intval($this->userId).' AND
493
                    p.user_id       = '.intval($this->userId)."
494
                    $condition_session
495
                ";
496
        $result = Database::query($sql);
497
        while ($res = Database::fetch_array($result)) {
498
            $this->sentWork[] = new Dropbox_SentWork($res['id']);
499
        }
500
    }
501
502
    /**
503
     * Deletes all the received categories and work of this person.
504
     */
505
    public function deleteReceivedWorkFolder(int $id, int $courseId = 0, int $sessionId = 0): bool
506
    {
507
        if (empty($courseId)) {
508
            $courseId = api_get_course_int_id();
509
        }
510
        if (empty($sessionId)) {
511
            $sessionId = api_get_session_id();
512
        }
513
514
        $condition_session = api_get_session_condition($sessionId);
515
516
        $sql = 'DELETE FROM '.Database::get_course_table(TABLE_DROPBOX_FILE)."
517
                WHERE c_id = $courseId $condition_session AND cat_id = $id";
518
        Database::query($sql);
519
520
        $sql = 'DELETE FROM '.Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
521
                WHERE c_id = $courseId $condition_session AND cat_id = $id";
522
        Database::query($sql);
523
524
        $sql = 'DELETE FROM '.Database::get_course_table(TABLE_DROPBOX_POST)."
525
                WHERE c_id = $courseId $condition_session AND cat_id = $id";
526
        Database::query($sql);
527
528
        return true;
529
    }
530
531
    /**
532
     * Deletes a received dropbox file of this person with id=$id.
533
     */
534
    public function deleteReceivedWork(int $id, int $courseId = 0, int $sessionId = 0): void
535
    {
536
        if (empty($courseId)) {
537
            $courseId = api_get_course_int_id();
538
        }
539
        if (empty($sessionId)) {
540
            $sessionId = api_get_session_id();
541
        }
542
543
        // index check
544
        $found = false;
545
        foreach ($this->receivedWork as $w) {
546
            if ($w->id == $id) {
547
                $found = true;
548
                break;
549
            }
550
        }
551
552
        if (!$found) {
553
            if (!$this->deleteReceivedWorkFolder($id, $courseId, $sessionId)) {
554
                exit(get_lang('GeneralError').' (code 216)');
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...
555
            }
556
        }
557
        // Delete entries in person table concerning received works
558
        $sql = 'DELETE FROM '.Database::get_course_table(TABLE_DROPBOX_PERSON)."
559
                WHERE c_id = $courseId AND user_id = ".$this->userId." AND file_id = $id";
560
        Database::query($sql);
561
        removeUnusedFiles(); // Check for unused files
562
    }
563
564
    /**
565
     * Deletes a sent dropbox file of this person with id=$id.
566
     */
567
    public function deleteSentWork(int $id, int $courseId = 0, int $sessionId = 0): void
568
    {
569
        if (empty($courseId)) {
570
            $courseId = api_get_course_int_id();
571
        }
572
        if (empty($sessionId)) {
573
            $sessionId = api_get_session_id();
574
        }
575
576
        // index check
577
        $found = false;
578
        foreach ($this->sentWork as $w) {
579
            if ($w->id == $id) {
580
                $found = true;
581
                break;
582
            }
583
        }
584
        if (!$found) {
585
            if (!$this->deleteReceivedWorkFolder($id, $courseId, $sessionId)) {
586
                exit(get_lang('GeneralError').' (code 219)');
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...
587
            }
588
        }
589
        //$file_id = $this->sentWork[$index]->id;
590
        // Delete entries in person table concerning sent works
591
        $sql = 'DELETE FROM '.Database::get_course_table(TABLE_DROPBOX_PERSON)."
592
                WHERE c_id = $courseId AND user_id = ".$this->userId." AND file_id = $id";
593
        Database::query($sql);
594
        removeMoreIfMailing($id);
595
        removeUnusedFiles(); // Check for unused files
596
    }
597
}
598