Passed
Push — master ( 017cdc...ca97c4 )
by Yannick
08:28
created

CLink::toggleVisibility()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CourseBundle\Entity;
8
9
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
10
use ApiPlatform\Metadata\ApiFilter;
11
use ApiPlatform\Metadata\ApiProperty;
12
use ApiPlatform\Metadata\ApiResource;
13
use ApiPlatform\Metadata\Delete;
14
use ApiPlatform\Metadata\Get;
15
use ApiPlatform\Metadata\GetCollection;
16
use ApiPlatform\Metadata\Post;
17
use ApiPlatform\Metadata\Put;
18
use Chamilo\CoreBundle\Controller\Api\CheckCLinkAction;
19
use Chamilo\CoreBundle\Controller\Api\CLinkDetailsController;
20
use Chamilo\CoreBundle\Controller\Api\CLinkImageController;
21
use Chamilo\CoreBundle\Controller\Api\CreateCLinkAction;
22
use Chamilo\CoreBundle\Controller\Api\GetLinksCollectionController;
23
use Chamilo\CoreBundle\Controller\Api\UpdateCLinkAction;
24
use Chamilo\CoreBundle\Controller\Api\UpdatePositionLink;
25
use Chamilo\CoreBundle\Controller\Api\UpdateVisibilityLink;
26
use Chamilo\CoreBundle\Entity\AbstractResource;
27
use Chamilo\CoreBundle\Entity\Asset;
28
use Chamilo\CoreBundle\Entity\ResourceInterface;
29
use Chamilo\CoreBundle\Entity\ResourceShowCourseResourcesInSessionInterface;
30
use Chamilo\CourseBundle\Repository\CLinkRepository;
31
use Doctrine\ORM\Mapping as ORM;
32
use Stringable;
33
use Symfony\Component\Serializer\Annotation\Groups;
34
use Symfony\Component\Validator\Constraints as Assert;
35
36
#[ApiResource(
37
    shortName: 'Links',
38
    operations: [
39
        new Put(
40
            controller: UpdateCLinkAction::class,
41
            denormalizationContext: [
42
                'groups' => ['link:write'],
43
            ],
44
            security: "is_granted('EDIT', object.resourceNode)",
45
            validationContext: [
46
                'groups' => ['media_object_create', 'link:write'],
47
            ],
48
            deserialize: false
49
        ),
50
        new Put(
51
            uriTemplate: '/links/{iid}/toggle_visibility',
52
            controller: UpdateVisibilityLink::class,
53
            security: "is_granted('EDIT', object.resourceNode)",
54
            deserialize: false
55
        ),
56
        new Put(
57
            uriTemplate: '/links/{iid}/move',
58
            controller: UpdatePositionLink::class,
59
            security: "is_granted('EDIT', object.resourceNode)",
60
            deserialize: false
61
        ),
62
        new Post(
63
            controller: CreateCLinkAction::class,
64
            openapiContext: [
65
                'summary' => 'Create a new link resource',
66
                'requestBody' => [
67
                    'content' => [
68
                        'application/json' => [
69
                            'schema' => [
70
                                'type' => 'object',
71
                                'properties' => [
72
                                    'url' => ['type' => 'string'],
73
                                    'title' => ['type' => 'string'],
74
                                    'description' => ['type' => 'string'],
75
                                    'category_id' => ['type' => 'integer'],
76
                                    'target' => ['type' => 'string'],
77
                                    'parentResourceNodeId' => ['type' => 'integer'],
78
                                    'resourceLinkList' => [
79
                                        'type' => 'array',
80
                                        'items' => [
81
                                            'type' => 'object',
82
                                            'properties' => [
83
                                                'visibility' => ['type' => 'integer'],
84
                                                'cid' => ['type' => 'integer'],
85
                                                'gid' => ['type' => 'integer'],
86
                                                'sid' => ['type' => 'integer'],
87
                                            ],
88
                                        ],
89
                                    ],
90
                                ],
91
                                'required' => ['url', 'title'],
92
                            ],
93
                        ],
94
                    ],
95
                ],
96
            ],
97
            security: "is_granted('ROLE_CURRENT_COURSE_TEACHER') or is_granted('ROLE_CURRENT_COURSE_SESSION_TEACHER') or is_granted('ROLE_TEACHER')",
98
            validationContext: ['groups' => ['Default', 'media_object_create', 'link:write']],
99
            deserialize: false
100
        ),
101
        new Post(
102
            uriTemplate: '/links/{iid}/upload-image',
103
            controller: CLinkImageController::class,
104
            openapiContext: [
105
                'summary' => 'Upload a custom image for a link',
106
                'requestBody' => [
107
                    'content' => [
108
                        'multipart/form-data' => [
109
                            'schema' => [
110
                                'type' => 'object',
111
                                'properties' => [
112
                                    'customImage' => [
113
                                        'type' => 'string',
114
                                        'format' => 'binary',
115
                                    ],
116
                                ],
117
                                'required' => ['customImage'],
118
                            ],
119
                        ],
120
                    ],
121
                ],
122
            ],
123
            security: "is_granted('EDIT', object.resourceNode)",
124
            deserialize: false
125
        ),
126
        new Get(security: "is_granted('VIEW', object.resourceNode)"),
127
        new Get(
128
            uriTemplate: '/links/{iid}/details',
129
            controller: CLinkDetailsController::class,
130
            openapiContext: [
131
                'summary' => 'Gets the details of a link, including whether it is on the homepage',
132
            ],
133
            security: "is_granted('VIEW', object.resourceNode)"
134
        ),
135
        new Get(
136
            uriTemplate: '/links/{iid}/check',
137
            controller: CheckCLinkAction::class,
138
            openapiContext: [
139
                'summary' => 'Check if a link URL is valid',
140
            ],
141
            security: "is_granted('VIEW', object.resourceNode)"
142
        ),
143
        new Delete(security: "is_granted('DELETE', object.resourceNode)"),
144
        new GetCollection(
145
            controller: GetLinksCollectionController::class,
146
            openapiContext: [
147
                'parameters' => [
148
                    [
149
                        'name' => 'resourceNode.parent',
150
                        'in' => 'query',
151
                        'required' => true,
152
                        'description' => 'Resource node Parent',
153
                        'schema' => ['type' => 'integer'],
154
                    ],
155
                    [
156
                        'name' => 'cid',
157
                        'in' => 'query',
158
                        'required' => true,
159
                        'description' => 'Course id',
160
                        'schema' => [
161
                            'type' => 'integer',
162
                        ],
163
                    ],
164
                    [
165
                        'name' => 'sid',
166
                        'in' => 'query',
167
                        'required' => false,
168
                        'description' => 'Session id',
169
                        'schema' => [
170
                            'type' => 'integer',
171
                        ],
172
                    ],
173
                ],
174
            ]
175
        ),
176
    ],
177
    normalizationContext: [
178
        'groups' => ['link:read', 'resource_node:read'],
179
    ],
180
    denormalizationContext: [
181
        'groups' => ['link:write'],
182
    ],
183
)]
184
#[ApiFilter(SearchFilter::class, properties: ['title' => 'partial', 'resourceNode.parent' => 'exact'])]
185
#[ORM\Table(name: 'c_link')]
186
#[ORM\Entity(repositoryClass: CLinkRepository::class)]
187
class CLink extends AbstractResource implements ResourceInterface, ResourceShowCourseResourcesInSessionInterface, Stringable
188
{
189
    #[ApiProperty(identifier: true)]
190
    #[Groups(['link:read'])]
191
    #[ORM\Column(name: 'iid', type: 'integer')]
192
    #[ORM\Id]
193
    #[ORM\GeneratedValue]
194
    protected ?int $iid = null;
195
196
    #[Groups(['link:read', 'link:write', 'link:browse'])]
197
    #[Assert\NotBlank]
198
    #[ORM\Column(name: 'url', type: 'text', nullable: false)]
199
    protected string $url;
200
201
    #[Groups(['link:read', 'link:write', 'link:browse'])]
202
    #[Assert\NotBlank]
203
    #[ORM\Column(name: 'title', type: 'string', length: 255, nullable: false)]
204
    protected string $title;
205
206
    #[Groups(['link:read', 'link:write', 'link:browse'])]
207
    #[ORM\Column(name: 'description', type: 'text', nullable: true)]
208
    protected ?string $description;
209
210
    #[Groups(['link:read', 'link:write', 'link:browse'])]
211
    #[ORM\ManyToOne(targetEntity: CLinkCategory::class, inversedBy: 'links')]
212
    #[ORM\JoinColumn(name: 'category_id', referencedColumnName: 'iid', onDelete: 'SET NULL')]
213
    protected ?CLinkCategory $category = null;
214
215
    #[Groups(['link:read', 'link:write', 'link:browse'])]
216
    #[ORM\Column(name: 'target', type: 'string', length: 10, nullable: true)]
217
    protected ?string $target = null;
218
219
    #[Groups(['link:read', 'link:browse'])]
220
    protected bool $linkVisible = true;
221
222
    #[Groups(['cshortcut:read'])]
223
    #[ORM\ManyToOne(targetEntity: Asset::class, cascade: ['remove'])]
224
    #[ORM\JoinColumn(name: 'custom_image_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
225
    private ?Asset $customImage = null;
226
227
    public function __construct()
228
    {
229
        $this->description = '';
230
    }
231
232
    public function __toString(): string
233
    {
234
        return $this->getTitle();
235
    }
236
237
    public function setUrl(string $url): self
238
    {
239
        $this->url = $url;
240
241
        return $this;
242
    }
243
244
    public function getUrl(): string
245
    {
246
        return $this->url;
247
    }
248
249
    public function setTitle(string $title): self
250
    {
251
        $this->title = $title;
252
253
        return $this;
254
    }
255
256
    public function getTitle(): string
257
    {
258
        return $this->title;
259
    }
260
261
    public function setDescription(string $description): self
262
    {
263
        $this->description = $description;
264
265
        return $this;
266
    }
267
268
    public function getDescription(): ?string
269
    {
270
        return $this->description;
271
    }
272
273
    public function setTarget(string $target): self
274
    {
275
        $this->target = $target;
276
277
        return $this;
278
    }
279
280
    /**
281
     * Get target.
282
     *
283
     * @return string
284
     */
285
    public function getTarget()
286
    {
287
        return $this->target;
288
    }
289
290
    public function getIid(): int
291
    {
292
        return $this->iid;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->iid could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
293
    }
294
295
    public function getCategory(): ?CLinkCategory
296
    {
297
        return $this->category;
298
    }
299
300
    public function setCategory(?CLinkCategory $category): self
301
    {
302
        $this->category = $category;
303
304
        return $this;
305
    }
306
307
    public function getCustomImage(): ?Asset
308
    {
309
        return $this->customImage;
310
    }
311
312
    public function setCustomImage(?Asset $customImage): self
313
    {
314
        $this->customImage = $customImage;
315
        return $this;
316
    }
317
318
    public function toggleVisibility(): void
319
    {
320
        $this->linkVisible = !$this->getFirstResourceLink()->getVisibility();
321
    }
322
323
    public function getLinkVisible(): bool
324
    {
325
        $this->linkVisible = (bool) $this->getFirstResourceLink()->getVisibility();
326
327
        return $this->linkVisible;
328
    }
329
330
    public function getResourceIdentifier(): int
331
    {
332
        return $this->iid;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->iid could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
333
    }
334
335
    public function getResourceName(): string
336
    {
337
        return $this->getTitle();
338
    }
339
340
    public function setResourceName(string $name): self
341
    {
342
        return $this->setTitle($name);
343
    }
344
}
345