Passed
Push — master ( 93e8b6...d802b2 )
by Julito
11:32
created

BaseResourceFileAction   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 148
c 1
b 0
f 0
dl 0
loc 338
rs 8.8
wmc 45

3 Methods

Rating   Name   Duplication   Size   Complexity  
C setLinks() 0 65 17
B handleUpdateRequest() 0 133 11
D handleCreateRequest() 0 91 17

How to fix   Complexity   

Complex Class

Complex classes like BaseResourceFileAction often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BaseResourceFileAction, and based on these observations, apply Extract Interface, too.

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\AbstractResource;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\ResourceLink;
12
use Chamilo\CoreBundle\Entity\Session;
13
use Chamilo\CoreBundle\Entity\User;
14
use Chamilo\CoreBundle\Repository\ResourceRepository;
15
use Chamilo\CourseBundle\Entity\CGroup;
16
use DateTime;
17
use Doctrine\ORM\EntityManager;
18
use Exception;
19
use InvalidArgumentException;
20
use Symfony\Component\HttpFoundation\File\UploadedFile;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
23
24
class BaseResourceFileAction
25
{
26
    public function setLinks(AbstractResource $resource, $em): void
27
    {
28
        error_log('setLinks ResourceNode ');
29
        $resourceNode = $resource->getResourceNode();
30
        $links = $resource->getResourceLinkArray();
31
        if ($links) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $links 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...
32
            error_log('$resource->getResourceLinkArray()');
33
            $groupRepo = $em->getRepository(CGroup::class);
34
            $courseRepo = $em->getRepository(Course::class);
35
            $sessionRepo = $em->getRepository(Session::class);
36
            $userRepo = $em->getRepository(User::class);
37
38
            foreach ($links as $link) {
39
                $resourceLink = new ResourceLink();
40
                $linkSet = false;
41
                if (isset($link['cid']) && !empty($link['cid'])) {
42
                    $course = $courseRepo->find($link['cid']);
43
                    if (null !== $course) {
44
                        $linkSet = true;
45
                        $resourceLink->setCourse($course);
46
                    } else {
47
                        throw new InvalidArgumentException(sprintf('Course #%s does not exists', $link['cid']));
48
                    }
49
                }
50
51
                if (isset($link['sid']) && !empty($link['sid'])) {
52
                    $session = $sessionRepo->find($link['sid']);
53
                    if (null !== $session) {
54
                        $linkSet = true;
55
                        $resourceLink->setSession($session);
56
                    } else {
57
                        throw new InvalidArgumentException(sprintf('Session #%s does not exists', $link['sid']));
58
                    }
59
                }
60
61
                if (isset($link['gid']) && !empty($link['gid'])) {
62
                    $group = $groupRepo->find($link['gid']);
63
                    if (null !== $group) {
64
                        $linkSet = true;
65
                        $resourceLink->setGroup($group);
66
                    } else {
67
                        throw new InvalidArgumentException(sprintf('Group #%s does not exists', $link['gid']));
68
                    }
69
                }
70
71
                if (isset($link['uid']) && !empty($link['uid'])) {
72
                    $user = $userRepo->find($link['uid']);
73
                    if (null !== $user) {
74
                        $linkSet = true;
75
                        $resourceLink->setUser($user);
76
                    } else {
77
                        throw new InvalidArgumentException(sprintf('User #%s does not exists', $link['uid']));
78
                    }
79
                }
80
81
                if (isset($link['visibility'])) {
82
                    $resourceLink->setVisibility((int) $link['visibility']);
83
                } else {
84
                    throw new InvalidArgumentException('Link needs a visibility key');
85
                }
86
87
                if ($linkSet) {
88
                    error_log('add link');
89
                    $em->persist($resourceLink);
90
                    $resourceNode->addResourceLink($resourceLink);
91
                    //$em->persist($resourceNode);
92
                    //$em->persist($resource->getResourceNode());
93
                }
94
            }
95
        }
96
97
        //$em->persist($resource);
98
99
        // Use by Chamilo not api platform.
100
        /*$links = $resource->getResourceLinkEntityList();
101
        if ($links) {
102
            error_log('$resource->getResourceLinkEntityList()');
103
            foreach ($links as $link) {
104
                $rights = [];
105
                switch ($link->getVisibility()) {
106
                    case ResourceLink::VISIBILITY_PENDING:
107
                    case ResourceLink::VISIBILITY_DRAFT:
108
                        $editorMask = ResourceNodeVoter::getEditorMask();
109
                        $resourceRight = new ResourceRight();
110
                        $resourceRight
111
                            ->setMask($editorMask)
112
                            ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
113
                        ;
114
                        $rights[] = $resourceRight;
115
116
                        break;
117
                }
118
119
                if (!empty($rights)) {
120
                    foreach ($rights as $right) {
121
                        $link->addResourceRight($right);
122
                    }
123
                }
124
                //error_log('link adding to node: '.$resource->getResourceNode()->getId());
125
                //error_log('link with user : '.$link->getUser()->getUsername());
126
                $resource->getResourceNode()->addResourceLink($link);
127
128
                $em->persist($link);
129
            }
130
        }*/
131
    }
132
    /**
133
     * Function loaded when creating a resource using the api, then the ResourceListener is executed.
134
     */
135
    protected function handleCreateRequest(AbstractResource $resource, Request $request, EntityManager $em): array
136
    {
137
        error_log('handleCreateRequest');
138
        $contentData = $request->getContent();
139
        if (!empty($contentData)) {
140
            $contentData = json_decode($contentData, true);
141
            $title = $contentData['title'] ?? '';
142
            $comment = $contentData['comment'] ?? '';
143
            $parentResourceNodeId = $contentData['parentResourceNodeId'] ?? 0;
144
            $fileType = $contentData['filetype'] ?? '';
145
            $resourceLinkList = $contentData['resourceLinkList'] ?? [];
146
        } else {
147
            $title = $request->get('title');
148
            $comment = $request->get('comment');
149
            $parentResourceNodeId = (int) $request->get('parentResourceNodeId');
150
            $fileType = $request->get('filetype');
151
            $resourceLinkList = $request->get('resourceLinkList', []);
152
            if (!empty($resourceLinkList)) {
153
                $resourceLinkList = false === strpos($resourceLinkList, '[') ? json_decode('['.$resourceLinkList.']', true) : json_decode($resourceLinkList, true);
154
                if (empty($resourceLinkList)) {
155
                    $message = 'resourceLinkList is not a valid json. Use for example: [{"cid":1, "visibility":1}]';
156
157
                    throw new InvalidArgumentException($message);
158
                }
159
            }
160
        }
161
162
        if (empty($fileType)) {
163
            throw new Exception('filetype needed: folder or file');
164
        }
165
166
        if (0 === $parentResourceNodeId) {
167
            throw new Exception('parentResourceNodeId int value needed');
168
        }
169
170
        $resource->setParentResourceNode($parentResourceNodeId);
171
172
        switch ($fileType) {
173
            case 'file':
174
                $content = '';
175
                if ($request->request->has('contentFile')) {
176
                    $content = $request->request->get('contentFile');
177
                }
178
                $fileParsed = false;
179
                // File upload.
180
                if ($request->files->count() > 0) {
181
                    if (!$request->files->has('uploadFile')) {
182
                        throw new BadRequestHttpException('"uploadFile" is required');
183
                    }
184
185
                    /** @var UploadedFile $uploadedFile */
186
                    $uploadedFile = $request->files->get('uploadFile');
187
                    $title = $uploadedFile->getClientOriginalName();
188
                    $resource->setUploadFile($uploadedFile);
189
                    $fileParsed = true;
190
                }
191
192
                // Get data in content and create a HTML file.
193
                if (!$fileParsed && $content) {
194
                    $handle = tmpfile();
195
                    fwrite($handle, $content);
196
                    $meta = stream_get_meta_data($handle);
197
                    $file = new UploadedFile($meta['uri'], $title.'.html', 'text/html', null, true);
198
                    $resource->setUploadFile($file);
199
                    $fileParsed = true;
200
                }
201
202
                if (!$fileParsed) {
203
                    throw new InvalidArgumentException('filetype was set to "file" but not upload file found');
204
                }
205
206
                break;
207
            case 'folder':
208
                break;
209
        }
210
211
        if (empty($title)) {
212
            throw new InvalidArgumentException('title is required');
213
        }
214
215
        $resource->setResourceName($title);
216
217
        // Set resource link list if exists.
218
        if (!empty($resourceLinkList)) {
219
            $resource->setResourceLinkArray($resourceLinkList);
220
            $this->setLinks($resource, $em);
221
        }
222
223
        return [
224
            'filetype' => $fileType,
225
            'comment' => $comment,
226
        ];
227
    }
228
229
    protected function handleUpdateRequest(AbstractResource $resource, ResourceRepository $repo, Request $request, EntityManager $em)
230
    {
231
        error_log('handleUpdateRequest');
232
        $contentData = $request->getContent();
233
        $resourceLinkList = [];
234
        if (!empty($contentData)) {
235
            error_log('contentData');
236
            $contentData = json_decode($contentData, true);
237
            $title = $contentData['title'] ?? '';
238
            $content = $contentData['contentFile'] ?? '';
239
            $resourceLinkList = $contentData['resourceLinkListFromEntity'] ?? [];
240
        } else {
241
            error_log('else');
242
            $title = $request->get('title');
243
            $content = $request->request->get('contentFile');
244
            //$comment = $request->request->get('comment');
245
        }
246
247
        $repo->setResourceName($resource, $title);
248
249
        $hasFile = $resource->getResourceNode()->hasResourceFile();
250
251
        $resourceNode = $resource->getResourceNode();
252
253
        if ($hasFile && !empty($content)) {
254
            if ($resourceNode->hasResourceFile()) {
255
                // The content is updated by the ResourceNodeListener.php
256
                $resourceNode->setContent($content);
257
                $resourceNode->getResourceFile()->setSize(\strlen($content));
258
            }
259
            $resourceNode->getResourceFile()->setUpdatedAt(new DateTime());
260
            $resource->setResourceNode($resourceNode);
261
        }
262
263
        $link = null;
264
        if (!empty($resourceLinkList)) {
265
            foreach ($resourceLinkList as $linkArray) {
266
                // Find the exact link.
267
                $linkId = $linkArray['id'] ?? 0;
268
                if (!empty($linkId)) {
269
                    /** @var ResourceLink $link */
270
                    $link = $resourceNode->getResourceLinks()->filter(fn ($link) => $link->getId() === $linkId)->first();
271
272
                    if (null !== $link) {
273
                        $link->setVisibility((int) $linkArray['visibility']);
274
275
                        break;
276
                    }
277
                }
278
            }
279
280
            error_log(print_r($resourceLinkList, true));
281
            $resource->setResourceLinkArray($resourceLinkList);
282
            $this->setLinks($resource, $em);
283
            /*
284
285
            $groupRepo = $em->getRepository(CGroup::class);
286
            $courseRepo = $em->getRepository(Course::class);
287
            $sessionRepo = $em->getRepository(Session::class);
288
            $userRepo = $em->getRepository(User::class);
289
290
            foreach ($resourceLinkList as $link) {
291
                $resourceLink = new ResourceLink();
292
                $linkSet = false;
293
                if (isset($link['cid']) && !empty($link['cid'])) {
294
                    $course = $courseRepo->find($link['cid']);
295
                    if (null !== $course) {
296
                        $linkSet = true;
297
                        $resourceLink->setCourse($course);
298
                    } else {
299
                        throw new InvalidArgumentException(sprintf('Course #%s does not exists', $link['cid']));
300
                    }
301
                }
302
303
                if (isset($link['sid']) && !empty($link['sid'])) {
304
                    $session = $sessionRepo->find($link['sid']);
305
                    if (null !== $session) {
306
                        $linkSet = true;
307
                        $resourceLink->setSession($session);
308
                    } else {
309
                        throw new InvalidArgumentException(sprintf('Session #%s does not exists', $link['sid']));
310
                    }
311
                }
312
313
                if (isset($link['gid']) && !empty($link['gid'])) {
314
                    $group = $groupRepo->find($link['gid']);
315
                    if (null !== $group) {
316
                        $linkSet = true;
317
                        $resourceLink->setGroup($group);
318
                    } else {
319
                        throw new InvalidArgumentException(sprintf('Group #%s does not exists', $link['gid']));
320
                    }
321
                }
322
323
                if (isset($link['uid']) && !empty($link['uid'])) {
324
                    $user = $userRepo->find($link['uid']);
325
                    if (null !== $user) {
326
                        $linkSet = true;
327
                        $resourceLink->setUser($user);
328
                    } else {
329
                        throw new InvalidArgumentException(sprintf('User #%s does not exists', $link['uid']));
330
                    }
331
                }
332
333
                if (isset($link['visibility'])) {
334
                    $resourceLink->setVisibility((int) $link['visibility']);
335
                } else {
336
                    throw new InvalidArgumentException('Link needs a visibility key');
337
                }
338
339
                if ($linkSet) {
340
                    error_log('link added');
341
                    $em->persist($resourceLink);
342
                    //$resourceLink->setResourceNode($resource->getResourceNode());
343
                    $resource->getResourceNode()->addResourceLink($resourceLink);
344
                    $em->persist($resource->getResourceNode());
345
                }
346
            }
347
348
            */
349
        }
350
351
        $isRecursive = !$hasFile;
352
        // If it's a folder then change the visibility to the children (That have the same link).
353
        if ($isRecursive && null !== $link) {
354
            $repo->copyVisibilityToChildren($resource->getResourceNode(), $link);
355
        }
356
357
        $resourceNode->setUpdatedAt(new DateTime());
358
359
        error_log('Finish update resource node file action');
360
361
        return $resource;
362
    }
363
}
364