Passed
Push — master ( fa3144...e03985 )
by Julito
07:53
created

AbstractResource::getFirstResourceLink()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 0
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Entity;
6
7
use ApiPlatform\Core\Annotation\ApiProperty;
8
use ApiPlatform\Core\Annotation\ApiSubresource;
9
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
10
use Chamilo\CourseBundle\Entity\CGroup;
11
use Doctrine\Common\Collections\Criteria;
12
use Doctrine\ORM\Mapping as ORM;
13
use Symfony\Component\Serializer\Annotation\Groups;
14
use Symfony\Component\Validator\Constraints as Assert;
15
16
/**
17
 * @ORM\MappedSuperclass
18
 * @ORM\HasLifecycleCallbacks
19
 * @ORM\EntityListeners({"Chamilo\CoreBundle\Entity\Listener\ResourceListener"})
20
 */
21
abstract class AbstractResource
22
{
23
    /**
24
     * @var string|null
25
     *
26
     * @ApiProperty(iri="http://schema.org/contentUrl")
27
     * @Groups({"resource_file:read", "resource_node:read", "document:read", "media_object_read"})
28
     */
29
    public $contentUrl;
30
31
    /**
32
     * @var string|null
33
     *
34
     * @ApiProperty(iri="http://schema.org/contentUrl")
35
     * @Groups({"resource_file:read", "resource_node:read", "document:read", "media_object_read"})
36
     */
37
    public $downloadUrl;
38
39
    /**
40
     * @var string|null
41
     *
42
     * @Groups({"resource_file:read", "resource_node:read", "document:read", "document:write", "media_object_read"})
43
     */
44
    public $contentFile;
45
46
    /**
47
     * @Assert\Valid()
48
     * @ApiSubresource()
49
     * @Groups({"resource_node:read", "resource_node:write", "document:write" })
50
     * @ORM\OneToOne(
51
     *     targetEntity="Chamilo\CoreBundle\Entity\ResourceNode",
52
     *     cascade={"persist", "remove"},
53
     *     orphanRemoval=true
54
     * )
55
     * @ORM\JoinColumn(name="resource_node_id", referencedColumnName="id", onDelete="CASCADE")
56
     */
57
    public $resourceNode;
58
59
    /**
60
     * @Groups({"resource_node:read", "resource_node:write", "document:read", "document:write"})
61
     */
62
    public $parentResourceNode;
63
64
    /**
65
     * @ApiProperty(iri="http://schema.org/image")
66
     */
67
    public $uploadFile;
68
69
    /** @var AbstractResource */
70
    public $parentResource;
71
72
    /**
73
     * @Groups({"resource_node:read", "document:read"})
74
     */
75
    public $resourceLinkListFromEntity;
76
77
    /**
78
     * Use when sending a request to Api platform.
79
     * Temporal array that saves the resource link list that will be filled by CreateResourceNodeFileAction.php.
80
     *
81
     * @var array
82
     */
83
    public $resourceLinkList;
84
85
    /**
86
     * Use when sending request to Chamilo.
87
     * Temporal array of objects locates the resource link list that will be filled by CreateResourceNodeFileAction.php.
88
     *
89
     * @var ResourceLink[]
90
     */
91
    public $resourceLinkEntityList;
92
93
    abstract public function getResourceName(): string;
94
95
    abstract public function setResourceName(string $name);
96
97
    public function getResourceLinkEntityList()
98
    {
99
        return $this->resourceLinkEntityList;
100
    }
101
102
    public function addLink(ResourceLink $link)
103
    {
104
        $this->resourceLinkEntityList[] = $link;
105
106
        return $this;
107
    }
108
109
    public function addCourseLink(Course $course, Session $session = null, CGroup $group = null, int $visibility = ResourceLink::VISIBILITY_PUBLISHED)
110
    {
111
        if (null === $this->getParent()) {
112
            throw new \Exception('addCourseLink requires to set the parent first.');
113
        }
114
115
        $resourceLink = new ResourceLink();
116
        $resourceLink
117
            ->setVisibility($visibility)
118
            ->setCourse($course)
119
            ->setSession($session)
120
            ->setGroup($group)
121
        ;
122
123
        $rights = [];
124
        switch ($visibility) {
125
            case ResourceLink::VISIBILITY_PENDING:
126
            case ResourceLink::VISIBILITY_DRAFT:
127
                $editorMask = ResourceNodeVoter::getEditorMask();
128
                $resourceRight = new ResourceRight();
129
                $resourceRight
130
                    ->setMask($editorMask)
131
                    ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
132
                ;
133
                $rights[] = $resourceRight;
134
135
                break;
136
        }
137
138
        if (!empty($rights)) {
139
            foreach ($rights as $right) {
140
                $resourceLink->addResourceRight($right);
141
            }
142
        }
143
144
        if ($this->hasResourceNode()) {
145
            $resourceNode = $this->getResourceNode();
146
            $exists = $resourceNode->getResourceLinks()->exists(
147
                function ($key, $element) use ($course, $session, $group) {
148
                    return
149
                        $course === $element->getCourse() &&
150
                        $session === $element->getSession() &&
151
                        $group === $element->getGroup();
152
                }
153
            );
154
155
            if ($exists) {
156
                return $this;
157
            }
158
            $resourceNode->addResourceLink($resourceLink);
159
        } else {
160
            $this->addLink($resourceLink);
161
        }
162
163
        return $this;
164
    }
165
166
    public function addGroupLink(Course $course, Session $session = null, CGroup $group = null)
167
    {
168
        $resourceLink = new ResourceLink();
169
        $resourceLink
170
            ->setCourse($course)
171
            ->setSession($session)
172
            ->setGroup($group)
173
            ->setVisibility(ResourceLink::VISIBILITY_PUBLISHED)
174
        ;
175
176
        if ($this->hasResourceNode()) {
177
            $resourceNode = $this->getResourceNode();
178
            $exists = $resourceNode->getResourceLinks()->exists(
179
                function ($key, $element) use ($group) {
180
                    if ($element->getGroup()) {
181
                        return $group->getIid() === $element->getGroup()->getIid();
0 ignored issues
show
Bug introduced by
The method getIid() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

181
                        return $group->/** @scrutinizer ignore-call */ getIid() === $element->getGroup()->getIid();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
182
                    }
183
                }
184
            );
185
186
            if ($exists) {
187
                return $this;
188
            }
189
            $resourceNode->addResourceLink($resourceLink);
190
        } else {
191
            $this->addLink($resourceLink);
192
        }
193
194
        return $this;
195
    }
196
197
    public function addUserLink(User $user, Course $course = null, Session $session = null, CGroup $group = null)
198
    {
199
        $resourceLink = new ResourceLink();
200
        $resourceLink
201
            ->setVisibility(ResourceLink::VISIBILITY_PUBLISHED)
202
            ->setUser($user)
203
            ->setCourse($course)
204
            ->setSession($session)
205
            ->setGroup($group)
206
        ;
207
208
        if ($this->hasResourceNode()) {
209
            $resourceNode = $this->getResourceNode();
210
            $exists = $resourceNode->getResourceLinks()->exists(
211
                function ($key, $element) use ($user) {
212
                    if ($element->hasUser()) {
213
                        return $user->getId() === $element->getUser()->getId();
214
                    }
215
                }
216
            );
217
218
            if ($exists) {
219
                error_log('Link already exist for user: '.$user->getUsername().', skipping');
220
221
                return $this;
222
            }
223
224
            error_log('New link can be added for user: '.$user->getUsername());
225
            $resourceNode->addResourceLink($resourceLink);
226
        } else {
227
            $this->addLink($resourceLink);
228
        }
229
230
        return $this;
231
    }
232
233
    public function setParent(AbstractResource $parent)
234
    {
235
        $this->parentResource = $parent;
236
237
        return $this;
238
    }
239
240
    public function getParent()
241
    {
242
        return $this->parentResource;
243
    }
244
245
    /**
246
     * @param array $userList User id list
247
     */
248
    public function addResourceToUserList(
249
        array $userList,
250
        Course $course = null,
251
        Session $session = null,
252
        CGroup $group = null
253
    ) {
254
        if (!empty($userList)) {
255
            foreach ($userList as $user) {
256
                $this->addUserLink($user, $course, $session, $group);
257
            }
258
        }
259
260
        return $this;
261
    }
262
263
    public function setResourceLinkArray(array $links)
264
    {
265
        $this->resourceLinkList = $links;
266
267
        return $this;
268
    }
269
270
    public function getResourceLinkArray()
271
    {
272
        return $this->resourceLinkList;
273
    }
274
275
    public function getResourceLinkListFromEntity()
276
    {
277
        return $this->resourceLinkListFromEntity;
278
    }
279
280
    public function setResourceLinkListFromEntity()
281
    {
282
        $resourceNode = $this->getResourceNode();
283
        $links = $resourceNode->getResourceLinks();
284
        $resourceLinkList = [];
285
286
        foreach ($links as $link) {
287
            $resourceLinkList[] = [
288
                'id' => $link->getId(),
289
                'session' => $link->getSession(),
290
                'course' => $link->getCourse(),
291
                'visibility' => $link->getVisibility(),
292
                'visibilityName' => $link->getVisibilityName(),
293
                'group' => $link->getGroup(),
294
                'userGroup' => $link->getUserGroup(),
295
            ];
296
        }
297
        $this->resourceLinkListFromEntity = $resourceLinkList;
298
    }
299
300
    public function hasParentResourceNode(): bool
301
    {
302
        return null !== $this->parentResourceNode;
303
    }
304
305
    public function setParentResourceNode($resourceNode): self
306
    {
307
        $this->parentResourceNode = $resourceNode;
308
309
        return $this;
310
    }
311
312
    public function getParentResourceNode()
313
    {
314
        return $this->parentResourceNode;
315
    }
316
317
    public function hasUploadFile(): bool
318
    {
319
        return null !== $this->uploadFile;
320
    }
321
322
    public function getUploadFile()
323
    {
324
        return $this->uploadFile;
325
    }
326
327
    public function setUploadFile($file): self
328
    {
329
        $this->uploadFile = $file;
330
331
        return $this;
332
    }
333
334
    public function setResourceNode(ResourceNode $resourceNode): ResourceInterface
335
    {
336
        $this->resourceNode = $resourceNode;
337
338
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Chamilo\CoreBundle\Entity\AbstractResource which is incompatible with the type-hinted return Chamilo\CoreBundle\Entity\ResourceInterface.
Loading history...
339
    }
340
341
    public function hasResourceNode(): bool
342
    {
343
        return $this->resourceNode instanceof ResourceNode;
344
    }
345
346
    public function getResourceNode(): ResourceNode
347
    {
348
        return $this->resourceNode;
349
    }
350
351
    public function getFirstResourceLink(): ?ResourceLink
352
    {
353
        $resourceNode = $this->getResourceNode();
354
355
        if ($resourceNode && $resourceNode->getResourceLinks()->count()) {
356
            $result = $resourceNode->getResourceLinks()->first();
357
            if ($result) {
358
                return $result;
359
            }
360
        }
361
362
        return null;
363
    }
364
365
    /**
366
     * See ResourceLink to see the visibility constants. Example: ResourceLink::VISIBILITY_DELETED.
367
     */
368
    public function getLinkVisibility(Course $course, Session $session = null): ?ResourceLink
369
    {
370
        return $this->getFirstResourceLinkFromCourseSession($course, $session)->getVisibility();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getFirstResourceL...sion($course, $session) targeting Chamilo\CoreBundle\Entit...LinkFromCourseSession() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
371
    }
372
373
    public function isVisible(Course $course, Session $session = null): bool
374
    {
375
        $link = $this->getFirstResourceLinkFromCourseSession($course, $session);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $link is correct as $this->getFirstResourceL...sion($course, $session) targeting Chamilo\CoreBundle\Entit...LinkFromCourseSession() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
376
        if (null === $link) {
377
            return false;
378
        }
379
380
        return ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility();
381
    }
382
383
    public function getFirstResourceLinkFromCourseSession(Course $course, Session $session = null): ?ResourceLink
384
    {
385
        /*$criteria = Criteria::create();
386
        $criteria
387
            ->where(Criteria::expr()->eq('course', $course->getId()))
388
            ->andWhere(
389
                Criteria::expr()->eq('session', $session)
390
            )
391
            ->setFirstResult(0)
392
            ->setMaxResults(1)
393
        ;*/
394
        $resourceNode = $this->getResourceNode();
395
        $result = null;
396
        if ($resourceNode && $resourceNode->getResourceLinks()->count() > 0) {
397
            $links = $resourceNode->getResourceLinks();
398
            $found = false;
399
            foreach ($links as $link) {
400
                if ($link->getCourse() === $course && $link->getSession() === $session) {
401
                    $found = true;
402
                    break;
403
                }
404
            }
405
            //$result = $links->matching($criteria)->count();
406
            //var_dump($result);
407
            //var_dump($result);
408
            if ($found) {
409
                return $link;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $link seems to be defined by a foreach iteration on line 399. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
410
            }
411
        }
412
413
        return null;
414
    }
415
416
    public function getUsersAndGroupSubscribedToResource(): array
417
    {
418
        $users = [];
419
        $groups = [];
420
        $everyone = false;
421
        $links = $this->getResourceNode()->getResourceLinks();
422
        foreach ($links as $link) {
423
            if ($link->getUser()) {
424
                $users[] = $link->getUser()->getId();
425
            }
426
            if ($link->getGroup()) {
427
                $groups[] = $link->getGroup()->getIid();
428
            }
429
        }
430
431
        if (empty($users) && empty($groups)) {
432
            $everyone = true;
433
        }
434
435
        return [
436
            'everyone' => $everyone,
437
            'users' => $users,
438
            'groups' => $groups,
439
        ];
440
    }
441
}
442