Passed
Pull Request — master (#6795)
by
unknown
12:13 queued 03:39
created

CreateDropboxFileAction   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 123
c 2
b 0
f 0
dl 0
loc 182
rs 9.44
wmc 37

3 Methods

Rating   Name   Duplication   Size   Complexity  
A extractUserIdsFromTokens() 0 14 5
D __invoke() 0 124 16
C buildLinks() 0 36 16
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Controller\Api;
8
9
use Chamilo\CoreBundle\Entity\ResourceLink;
10
use Chamilo\CoreBundle\Helpers\UserHelper;
11
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
12
use Chamilo\CoreBundle\Repository\SessionRepository;
13
use Chamilo\CourseBundle\Entity\CDropboxFile;
14
use Chamilo\CourseBundle\Entity\CDropboxPerson;
15
use Chamilo\CourseBundle\Entity\CDropboxPost;
16
use Chamilo\CourseBundle\Repository\CDropboxFileRepository;
17
use DateTime;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Symfony\Component\HttpFoundation\File\UploadedFile;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpKernel\Attribute\AsController;
23
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
24
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
25
26
#[AsController]
27
final class CreateDropboxFileAction
28
{
29
    public function __invoke(
30
        Request $request,
31
        CDropboxFileRepository $repo,
32
        CourseRepository $courseRepo,
33
        SessionRepository $sessionRepo,
34
        EntityManagerInterface $em,
35
        UserHelper $userHelper
36
    ): JsonResponse {
37
38
        $cid = (int) $request->query->get('cid', 0);
39
        $sid = (int) $request->query->get('sid', 0);
40
        $gid = (int) $request->query->get('gid', 0);
41
        if ($cid <= 0) {
42
            throw new BadRequestHttpException('Missing or invalid "cid".');
43
        }
44
        $user = $userHelper->getCurrent();
45
        if (!$user) {
46
            throw new UnauthorizedHttpException('', 'Unauthorized.');
47
        }
48
49
        /** @var UploadedFile|null $file */
50
        $file = $request->files->get('uploadFile');
51
        if (!$file) {
52
            foreach ($request->files as $val) {
53
                if ($val instanceof UploadedFile) {
54
                    $file = $val;
55
                    $request->files->set('uploadFile', $val);
56
                    break;
57
                }
58
            }
59
        }
60
        if (!$file) {
61
            throw new BadRequestHttpException('"uploadFile" is required');
62
        }
63
64
        $parentId = (int) $request->request->get('parentResourceNodeId', 0);
65
        if ($parentId === 0) {
66
            $course = $courseRepo->find($cid);
67
            $parentId = $course?->getResourceNode()?->getId() ?? 0;
68
            if ($parentId === 0) {
69
                throw new BadRequestHttpException('parentResourceNodeId (categoryId) is required');
70
            }
71
        }
72
73
        $description = (string) $request->request->get('description', '');
74
        $categoryId  = (int) $request->request->get('categoryId', 0);
75
        /** @var string[] $tokens */
76
        $tokens      = (array) ($request->request->all('recipients') ?? []);
77
78
        $original  = $file->getClientOriginalName() ?: 'upload.bin';
79
        $candidate = $original;
80
        $i = 1;
81
        while ($repo->findOneBy(['filename' => $candidate])) {
82
            $pi   = pathinfo($original);
83
            $name = $pi['filename'] ?? 'file';
84
            $ext  = isset($pi['extension']) ? '.'.$pi['extension'] : '';
85
            $candidate = $name.'_'.$i.$ext;
86
            $i++;
87
        }
88
89
        $now = new DateTime();
90
        $e = new CDropboxFile();
91
        $e->setFiletype('file');
92
        $e->setParentResourceNode($parentId);
93
        $e->setUploadFile($file);
94
95
        $e->setCId($cid);
96
        $e->setSessionId($sid);
97
        $e->setUploaderId($user->getId());
98
        $e->setTitle($candidate);
99
        $e->setFilename($candidate);
100
        $e->setFilesize((int) ($file->getSize() ?: 0));
101
        $e->setDescription($description);
102
        $e->setAuthor((string) $user->getFullName());
103
        $e->setUploadDate($now);
104
        $e->setLastUploadDate($now);
105
        $e->setCatId($categoryId);
106
107
        $e->setResourceLinkArray($this->buildLinks($tokens, $cid, $sid, $gid));
108
109
        $em->persist($e);
110
        $em->flush();
111
112
        $up = new CDropboxPerson();
113
        $up->setCId($cid);
114
        $up->setUserId($user->getId());
115
        $up->setFileId($e->getIid());
116
        $em->persist($up);
117
118
        $destUserIds = $this->extractUserIdsFromTokens($tokens, $user->getId());
119
        if (!$destUserIds) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $destUserIds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
120
            $destUserIds = [$user->getId()];
121
        }
122
123
        foreach ($destUserIds as $destUid) {
124
            $post = new CDropboxPost();
125
            $post->setCId($cid);
126
            $post->setSessionId($sid ?? 0);
127
            $post->setFileId($e->getIid());
128
            $post->setDestUserId($destUid);
129
            $post->setCatId($categoryId);
130
            $post->setFeedbackDate(new DateTime());
131
            $em->persist($post);
132
133
            if ($destUid !== $user->getId()) {
134
                $p = new CDropboxPerson();
135
                $p->setCId($cid);
136
                $p->setUserId($destUid);
137
                $p->setFileId($e->getIid());
138
                $em->persist($p);
139
            }
140
        }
141
142
        $em->flush();
143
144
        return new JsonResponse([
145
            'ok'         => true,
146
            'iid'        => (int) $e->getIid(),
147
            'title'      => $e->getTitle(),
148
            'filename'   => $e->getFilename(),
149
            'filesize'   => $e->getFilesize(),
150
            'categoryId' => $e->getCatId(),
151
            'message'    => 'File uploaded successfully',
152
        ], 201);
153
    }
154
155
    private function buildLinks(array $tokens, int $cid, int $sid, int $gid): array
156
    {
157
        $tokens = array_values(array_filter(array_map('strval', $tokens)));
158
159
        if (empty($tokens) || (count($tokens) === 1 && strtolower($tokens[0]) === 'self')) {
160
            return [[
161
                'visibility' => ResourceLink::VISIBILITY_PUBLISHED,
162
                'cid' => $cid,
163
                'sid' => $sid ?: null,
164
                'gid' => $gid ?: null,
165
            ]];
166
        }
167
168
        $out = [];
169
        foreach ($tokens as $t) {
170
            if (preg_match('/^USER:(\d+)$/i', $t, $m)) {
171
                $out[] = [
172
                    'visibility' => ResourceLink::VISIBILITY_PUBLISHED,
173
                    'cid' => $cid, 'sid' => $sid ?: null, 'uid' => (int) $m[1],
174
                ];
175
            } elseif (preg_match('/^GROUP:(\d+)$/i', $t, $m)) {
176
                $out[] = [
177
                    'visibility' => ResourceLink::VISIBILITY_PUBLISHED,
178
                    'cid' => $cid, 'sid' => $sid ?: null, 'gid' => (int) $m[1],
179
                ];
180
            } elseif (preg_match('/^user_(\d+)$/i', $t, $m)) {
181
                $out[] = [
182
                    'visibility' => ResourceLink::VISIBILITY_PUBLISHED,
183
                    'cid' => $cid, 'sid' => $sid ?: null, 'uid' => (int) $m[1],
184
                ];
185
            }
186
        }
187
188
        return $out ?: [[
189
            'visibility' => ResourceLink::VISIBILITY_PUBLISHED,
190
            'cid' => $cid, 'sid' => $sid ?: null, 'gid' => $gid ?: null,
191
        ]];
192
    }
193
194
    private function extractUserIdsFromTokens(array $tokens, int $uploaderId): array
195
    {
196
        $ids = [];
197
        foreach ($tokens as $t) {
198
            $s = (string) $t;
199
            if (strtolower($s) === 'self') {
200
                $ids[] = $uploaderId;
201
            } elseif (preg_match('/^USER:(\d+)$/i', $s, $m)) {
202
                $ids[] = (int) $m[1];
203
            } elseif (preg_match('/^user_(\d+)$/i', $s, $m)) {
204
                $ids[] = (int) $m[1];
205
            }
206
        }
207
        return array_values(array_unique(array_filter($ids, fn($v) => (int)$v > 0)));
208
    }
209
}
210