Passed
Pull Request — master (#7158)
by
unknown
11:01
created

ResourceFile   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 352
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 174
dl 0
loc 352
rs 9.52
c 1
b 0
f 0
wmc 36

33 Methods

Rating   Name   Duplication   Size   Complexity  
A getLanguage() 0 3 1
A getDimensions() 0 3 1
A setTitle() 0 5 1
A setOriginalName() 0 5 1
A getTitle() 0 3 1
A setCrop() 0 5 1
A getOriginalName() 0 3 1
A getId() 0 3 1
A setDescription() 0 5 1
A __toString() 0 3 1
A getResourceNode() 0 3 1
A setSize() 0 5 1
A getDescription() 0 3 1
A getAccessUrl() 0 3 1
A isVideo() 0 5 1
A isText() 0 5 1
A getMimeType() 0 3 1
A isAudio() 0 5 1
A setAccessUrl() 0 5 1
A setResourceNode() 0 5 1
A isImage() 0 5 1
A setDimensions() 0 5 1
A setLanguage() 0 5 1
A __construct() 0 5 1
A setMetadata() 0 5 1
A getWidth() 0 8 2
A getMetadata() 0 3 1
A getCrop() 0 3 1
A setMimeType() 0 5 1
A getHeight() 0 8 2
A getFile() 0 3 1
A setFile() 0 10 2
A getSize() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Entity;
8
9
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
10
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
11
use ApiPlatform\Metadata\ApiFilter;
12
use ApiPlatform\Metadata\ApiResource;
13
use ApiPlatform\Metadata\Get;
14
use ApiPlatform\Metadata\GetCollection;
15
use ApiPlatform\Metadata\Post;
16
use ApiPlatform\OpenApi\Model\Operation;
17
use ApiPlatform\OpenApi\Model\RequestBody;
18
use ApiPlatform\Serializer\Filter\PropertyFilter;
19
use ArrayObject;
20
use Chamilo\CoreBundle\Controller\AddVariantResourceFileAction;
21
use Chamilo\CoreBundle\Controller\CreateResourceFileAction;
22
use Chamilo\CoreBundle\Repository\ResourceFileRepository;
23
use DateTime;
24
use DateTimeImmutable;
25
use Doctrine\ORM\Mapping as ORM;
26
use Gedmo\Mapping\Annotation as Gedmo;
27
use Gedmo\Timestampable\Traits\TimestampableEntity;
28
use Stringable;
29
use Symfony\Component\HttpFoundation\File\File;
30
use Symfony\Component\HttpFoundation\File\UploadedFile;
31
use Symfony\Component\Serializer\Annotation\Groups;
32
use Symfony\Component\Validator\Constraints as Assert;
33
use Vich\UploaderBundle\Mapping\Annotation as Vich;
34
35
//
36
// *     attributes={"security"="is_granted('ROLE_ADMIN')"},
37
#[Vich\Uploadable]
38
#[ApiResource(
39
    types: ['http://schema.org/MediaObject'],
40
    operations: [
41
        new Get(),
42
        new Post(
43
            controller: CreateResourceFileAction::class,
44
            openapi: new Operation(
45
                summary: 'Create a new resource file',
46
                requestBody: new RequestBody(
47
                    content: new ArrayObject([
48
                        'multipart/form-data' => [
49
                            'schema' => [
50
                                'type' => 'object',
51
                                'properties' => [
52
                                    'file' => [
53
                                        'type' => 'string',
54
                                        'format' => 'binary',
55
                                    ],
56
                                ],
57
                            ],
58
                        ],
59
                    ]),
60
                ),
61
            ),
62
            security: 'is_granted(\'ROLE_USER\')',
63
            validationContext: [
64
                'groups' => ['Default', 'media_object_create', 'document:write'],
65
            ],
66
            deserialize: false
67
        ),
68
        new Post(
69
            uriTemplate: '/resource_files/add_variant',
70
            controller: AddVariantResourceFileAction::class,
71
            openapi: new Operation(
72
                summary: 'Add a variant to an existing resource file',
73
                requestBody: new RequestBody(
74
                    content: new ArrayObject([
75
                        'multipart/form-data' => [
76
                            'schema' => [
77
                                'type' => 'object',
78
                                'properties' => [
79
                                    'file' => [
80
                                        'type' => 'string',
81
                                        'format' => 'binary',
82
                                    ],
83
                                    'resourceNodeId' => [
84
                                        'type' => 'integer',
85
                                    ],
86
                                    'accessUrlId' => [
87
                                        'type' => 'integer',
88
                                    ],
89
                                ],
90
                            ],
91
                        ],
92
                    ]),
93
                ),
94
            ),
95
            security: 'is_granted(\'ROLE_USER\')',
96
            deserialize: false,
97
            name: 'add_variant'
98
        ),
99
        new GetCollection(),
100
    ],
101
    normalizationContext: [
102
        'groups' => [
103
            'resource_file:read',
104
            'resource_node:read',
105
            'document:read',
106
            'media_object_read',
107
            'message:read',
108
            'personal_file:read',
109
        ],
110
    ]
111
)]
112
#[ORM\Table(name: 'resource_file')]
113
#[ORM\Entity(repositoryClass: ResourceFileRepository::class)]
114
#[ApiFilter(filterClass: PropertyFilter::class)]
115
#[ApiFilter(filterClass: SearchFilter::class, properties: ['name' => 'partial'])]
116
#[ApiFilter(filterClass: OrderFilter::class, properties: ['id', 'name', 'size', 'updatedAt'])]
117
class ResourceFile implements Stringable
118
{
119
    use TimestampableEntity;
120
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
121
    #[ORM\Id]
122
    #[ORM\Column(type: 'integer')]
123
    #[ORM\GeneratedValue]
124
    protected ?int $id = null;
125
    #[Assert\NotBlank]
126
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read'])]
127
    #[ORM\Column(type: 'string', length: 255)]
128
    protected ?string $title = null;
129
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
130
    #[ORM\Column(type: 'text', nullable: true)]
131
    protected ?string $mimeType = null;
132
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
133
    #[ORM\Column(type: 'text', nullable: true)]
134
    protected ?string $originalName = null;
135
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read'])]
136
    #[ORM\Column(type: 'simple_array', nullable: true)]
137
    protected ?array $dimensions;
138
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read', 'personal_file:read'])]
139
    #[ORM\Column(type: 'integer')]
140
    protected ?int $size = 0;
141
    /**
142
     * Optional language for the file variant.
143
     * This is used for indexing and future-proof resource variations.
144
     */
145
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'personal_file:read'])]
146
    #[ORM\ManyToOne(targetEntity: Language::class)]
147
    #[ORM\JoinColumn(name: 'language_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
148
    protected ?Language $language = null;
149
    #[Vich\UploadableField(
150
        mapping: 'resources',
151
        fileNameProperty: 'title',
152
        size: 'size',
153
        mimeType: 'mimeType',
154
        originalName: 'originalName',
155
        dimensions: 'dimensions'
156
    )]
157
    protected ?File $file = null;
158
    #[ORM\Column(name: 'crop', type: 'string', length: 255, nullable: true)]
159
    protected ?string $crop = null;
160
161
    /**
162
     * @var string[]
163
     */
164
    #[ORM\Column(type: 'array', nullable: true)]
165
    protected ?array $metadata = [];
166
    #[Groups(['message:read'])]
167
    protected ?bool $audio = null;
168
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
169
    protected ?bool $image = null;
170
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
171
    protected ?bool $video = null;
172
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read', 'message:read'])]
173
    protected ?bool $text = null;
174
    #[ORM\Column(name: 'description', type: 'text', nullable: true)]
175
    protected ?string $description = null;
176
177
    /**
178
     * @var DateTime|DateTimeImmutable
179
     */
180
    #[Gedmo\Timestampable(on: 'update')]
181
    #[ORM\Column(type: 'datetime')]
182
    protected $updatedAt;
183
184
    #[ORM\ManyToOne(targetEntity: AccessUrl::class)]
185
    #[ORM\JoinColumn(name: 'access_url_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
186
    protected ?AccessUrl $accessUrl = null;
187
188
    #[Groups(['resource_file:read', 'resource_node:read', 'document:read'])]
189
    #[ORM\ManyToOne(inversedBy: 'resourceFiles')]
190
    private ?ResourceNode $resourceNode = null;
191
192
    public function __construct()
193
    {
194
        $this->size = 0;
195
        $this->metadata = [];
196
        $this->dimensions = [];
197
    }
198
    public function __toString(): string
199
    {
200
        return $this->getOriginalName();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getOriginalName() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
201
    }
202
    /**
203
     * Get the file language (can be null if unknown/multilingual).
204
     */
205
    public function getLanguage(): ?Language
206
    {
207
        return $this->language;
208
    }
209
    /**
210
     * Set the file language (nullable by design).
211
     */
212
    public function setLanguage(?Language $language): self
213
    {
214
        $this->language = $language;
215
216
        return $this;
217
    }
218
    public function isText(): bool
219
    {
220
        $mimeType = $this->getMimeType();
221
222
        return str_contains($mimeType, 'text');
223
    }
224
    public function isImage(): bool
225
    {
226
        $mimeType = $this->getMimeType();
227
228
        return str_contains($mimeType, 'image');
229
    }
230
    public function isVideo(): bool
231
    {
232
        $mimeType = $this->getMimeType();
233
234
        return str_contains($mimeType, 'video');
235
    }
236
    public function isAudio(): bool
237
    {
238
        $mimeType = $this->getMimeType();
239
240
        return str_contains($mimeType, 'audio');
241
    }
242
    public function getTitle(): ?string
243
    {
244
        return $this->title;
245
    }
246
    public function setTitle(?string $title): self
247
    {
248
        $this->title = $title;
249
250
        return $this;
251
    }
252
    public function getCrop(): ?string
253
    {
254
        return $this->crop;
255
    }
256
257
    /**
258
     * $crop example: 100,100,100,100 = width,height,x,y.
259
     */
260
    public function setCrop(string $crop): self
261
    {
262
        $this->crop = $crop;
263
264
        return $this;
265
    }
266
    public function getSize(): ?int
267
    {
268
        return $this->size;
269
    }
270
    public function setSize(?int $size): self
271
    {
272
        $this->size = $size;
273
274
        return $this;
275
    }
276
277
    public function getId(): ?int
278
    {
279
        return $this->id;
280
    }
281
282
    public function getMimeType(): ?string
283
    {
284
        return $this->mimeType;
285
    }
286
    public function setMimeType(?string $mimeType): self
287
    {
288
        $this->mimeType = $mimeType;
289
290
        return $this;
291
    }
292
    public function getOriginalName(): ?string
293
    {
294
        return $this->originalName;
295
    }
296
    public function setOriginalName(?string $originalName): self
297
    {
298
        $this->originalName = $originalName;
299
300
        return $this;
301
    }
302
    public function getDimensions(): array
303
    {
304
        return $this->dimensions;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->dimensions could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
305
    }
306
    public function setDimensions(?array $dimensions): self
307
    {
308
        $this->dimensions = $dimensions;
309
310
        return $this;
311
    }
312
    public function getWidth(): int
313
    {
314
        $data = $this->getDimensions();
315
        if ([] !== $data) {
316
            return (int) $data[0];
317
        }
318
319
        return 0;
320
    }
321
    public function getHeight(): int
322
    {
323
        $data = $this->getDimensions();
324
        if ([] !== $data) {
325
            return (int) $data[1];
326
        }
327
328
        return 0;
329
    }
330
    public function getMetadata(): array
331
    {
332
        return $this->metadata;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->metadata could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
333
    }
334
    public function setMetadata(array $metadata): self
335
    {
336
        $this->metadata = $metadata;
337
338
        return $this;
339
    }
340
    public function getDescription(): string
341
    {
342
        return $this->description;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->description could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
343
    }
344
    public function setDescription(string $description): self
345
    {
346
        $this->description = $description;
347
348
        return $this;
349
    }
350
    public function getFile(): ?File
351
    {
352
        return $this->file;
353
    }
354
355
    public function setFile(File|UploadedFile|null $file = null): self
356
    {
357
        $this->file = $file;
358
        if (null !== $file) {
359
            // It is required that at least one field changes if you are using doctrine
360
            // otherwise the event listeners won't be called and the file is lost
361
            $this->updatedAt = new DateTimeImmutable();
362
        }
363
364
        return $this;
365
    }
366
367
    public function getAccessUrl(): ?AccessUrl
368
    {
369
        return $this->accessUrl;
370
    }
371
372
    public function setAccessUrl(?AccessUrl $accessUrl): self
373
    {
374
        $this->accessUrl = $accessUrl;
375
376
        return $this;
377
    }
378
379
    public function getResourceNode(): ?ResourceNode
380
    {
381
        return $this->resourceNode;
382
    }
383
384
    public function setResourceNode(?ResourceNode $resourceNode): static
385
    {
386
        $this->resourceNode = $resourceNode;
387
388
        return $this;
389
    }
390
}
391