Completed
Push — master ( 2518c0...2a5f19 )
by Matt
05:55
created

Image::postLoad()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
namespace App\Entity;
4
5
use ApiPlatform\Core\Annotation\ApiFilter;
6
use ApiPlatform\Core\Annotation\ApiResource;
7
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\ExistsFilter;
8
use App\EventListener\ImageCalculatedFieldSetterListener;
9
use App\EventListener\WanderUploadListener;
10
use App\Repository\ImageRepository;
11
use Doctrine\Common\Collections\ArrayCollection;
12
use Doctrine\Common\Collections\Collection;
13
use Doctrine\ORM\Mapping as ORM;
14
use Symfony\Component\HttpFoundation\File\File;
15
use Vich\UploaderBundle\Mapping\Annotation as Vich;
16
use Symfony\Component\Validator\Constraints as Assert;
17
use Symfony\Component\Serializer\Annotation\Groups;
18
use Symfony\Component\Serializer\Annotation\Ignore;
19
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
20
use App\EventListener\SearchIndexer;
21
use Beelab\TagBundle\Tag\TaggableInterface;
22
use Beelab\TagBundle\Tag\TagInterface;
23
use Doctrine\ORM\Event\LifecycleEventArgs;
24
25
/**
26
 * @ApiResource(
27
 *  collectionOperations={"get"={"normalization_context"={"groups"="image:list"}}},
28
 *  itemOperations={"get"={"normalization_context"={"groups"="image:item"}}},
29
 *  order={"capturedAt"="ASC"},
30
 *  paginationEnabled=false
31
 * )
32
 *
33
 * @ApiFilter(SearchFilter::class, properties={"wanders": "exact"})
34
 * @ApiFilter(ExistsFilter::class, properties={"latlng"})
35
 *
36
 * @ORM\Entity(repositoryClass=ImageRepository::class)
37
 *
38
 * @ORM\EntityListeners({
39
 *     ImageCalculatedFieldSetterListener::class,
40
 *     SearchIndexer::class
41
 * })
42
 *
43
 * @ORM\HasLifecycleCallbacks()
44
 *
45
 * This is just to control the stuff that goes back from our one controller
46
 * action that returns a JSON response, ImageController::upload
47
 *
48
 * @Vich\Uploadable
49
 */
50
51
class Image implements TaggableInterface
52
{
53
    /**
54
     * @ORM\Id
55
     * @ORM\GeneratedValue
56
     * @ORM\Column(type="integer")
57
     *
58
     * @Groups({"image:list", "image:item"})
59
     */
60
    private $id;
61
62
    // TODO: We probably don't want this massive field being returned
63
    // as part of any API response, etc.
64
    /**
65
     * @Vich\UploadableField(mapping="image", fileNameProperty="name", size="sizeInBytes",
66
     *  mimeType="mimeType", originalName="originalName", dimensions="dimensions")
67
     *
68
     * @Ignore()
69
     */
70
    private $imageFile;
71
72
    /**
73
     * @ORM\Column(type="string", length=255, nullable=true)
74
     *
75
     * @Groups({"image:list", "image:item"})
76
     */
77
    private $name; // For Vich, not for us. We use Title.
78
79
    /**
80
     * @ORM\Column(type="string", length=255, nullable=true)
81
     *
82
     * @Groups({"image:list", "image:item"})
83
     */
84
    private $title;
85
86
    /**
87
     * @ORM\Column(type="text", nullable=true)
88
     *
89
     * @Groups({"image:list", "image:item"})
90
     */
91
    private $description;
92
93
    /**
94
     * @ORM\Column(type="integer", nullable=true)
95
     *
96
     * @Groups({"image:list", "image:item"})
97
     */
98
    private $sizeInBytes;
99
100
    /**
101
     * @ORM\Column(type="string", length=255, nullable=true)
102
     *
103
     * @Groups({"image:list", "image:item"})
104
     */
105
    private $mimeType;
106
107
    /**
108
     * @ORM\Column(type="string", length=255, nullable=true)
109
     *
110
     * @Groups({"image:list", "image:item"})
111
     */
112
    private $originalName;
113
114
    /**
115
     * @ORM\Column(type="simple_array", nullable=true)
116
     *
117
     * @Groups({"image:list", "image:item"})
118
     */
119
    private $dimensions = [];
120
121
    /**
122
     * @ORM\Column(type="datetime")
123
     *
124
     * @Groups({"image:list", "image:item"})
125
     *
126
     * @var \DateTimeInterface|null
127
     */
128
    private $updatedAt;
129
130
    /**
131
     * @ORM\Column(type="simple_array", nullable=true)
132
     * @Assert\Count(
133
     *      min = 2,
134
     *      max = 2,
135
     *      minMessage = "There must be exactly two numbers in a latitude/longitude pair",
136
     *      maxMessage = "There must be exactly two numbers in a latitude/longitude pair",
137
     *      exactMessage = "Co-ordinates must consist of a latitude, longitude pair."
138
     * )
139
     *
140
     * @Groups({"image:list", "image:item"})
141
     *
142
     */
143
    private $latlng = [];
144
145
    /**
146
     * @var Collection
147
     * @ORM\ManyToMany(targetEntity="Tag")
148
     */
149
    private $tags;
150
151
    /**
152
     * @ORM\Column(type="datetime", nullable=true)
153
     *
154
     * @Groups({"image:list", "image:item"})
155
     */
156
    private $capturedAt;
157
158
    /**
159
     * @ORM\Column(type="integer", nullable=true)
160
     * @Groups({"image:list", "image:item"})
161
     */
162
    private $rating;
163
164
165
    // TODO: This @Ignore was here from when this was a many-to-many. Do we still
166
    // need it?
167
    /**
168
     * @ORM\ManyToOne(targetEntity=Wander::class, inversedBy="images")
169
     *
170
     * @Ignore()
171
     */
172
    private $wander;
173
174
    public function __construct()
175
    {
176
        $this->tags = new ArrayCollection();
177
    }
178
179
    /**
180
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
181
     * of 'UploadedFile' is injected into this setter to trigger the update. If this
182
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
183
     * must be able to accept an instance of 'File' as the bundle will inject one here
184
     * during Doctrine hydration.
185
     *
186
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $imageFile
187
     */
188
    public function setImageFile(?File $imageFile = null): void
189
    {
190
        $this->imageFile = $imageFile;
191
192
        if (null !== $imageFile) {
193
            // It is required that at least one field changes if you are using doctrine
194
            // otherwise the event listeners won't be called and the file is lost
195
            $this->updatedAt = new \DateTimeImmutable();
196
        }
197
    }
198
199
    /**
200
     * @Ignore()
201
     */
202
    public function getImageFile(): ?File
203
    {
204
        return $this->imageFile;
205
    }
206
207
    public function getId(): ?int
208
    {
209
        return $this->id;
210
    }
211
212
    public function getName(): ?string
213
    {
214
        return $this->name;
215
    }
216
217
    public function setName(?string $name): self
218
    {
219
        $this->name = $name;
220
221
        return $this;
222
    }
223
224
    public function getTitle(): ?string
225
    {
226
        return $this->title;
227
    }
228
229
    public function setTitle(?string $title): self
230
    {
231
        $this->title = $title;
232
233
        return $this;
234
    }
235
236
    public function getDescription(): ?string
237
    {
238
        return $this->description;
239
    }
240
241
    public function setDescription(?string $description): self
242
    {
243
        $this->description = $description;
244
245
        return $this;
246
    }
247
248
    public function getSizeInBytes(): ?int
249
    {
250
        return $this->sizeInBytes;
251
    }
252
253
    public function setSizeInBytes(?int $sizeInBytes): self
254
    {
255
        $this->sizeInBytes = $sizeInBytes;
256
257
        return $this;
258
    }
259
260
    public function getMimeType(): ?string
261
    {
262
        return $this->mimeType;
263
    }
264
265
    public function setMimeType(?string $mimeType): self
266
    {
267
        $this->mimeType = $mimeType;
268
269
        return $this;
270
    }
271
272
    public function getOriginalName(): ?string
273
    {
274
        return $this->originalName;
275
    }
276
277
    public function setOriginalName(?string $originalName): self
278
    {
279
        $this->originalName = $originalName;
280
281
        return $this;
282
    }
283
284
    public function getDimensions(): ?array
285
    {
286
        return $this->dimensions;
287
    }
288
289
    public function setDimensions(?array $dimensions): self
290
    {
291
        $this->dimensions = $dimensions;
292
293
        return $this;
294
    }
295
296
    public function getUpdatedAt(): ?\DateTimeInterface
297
    {
298
        return $this->updatedAt;
299
    }
300
301
    public function setUpdatedAt(\DateTimeInterface $updatedAt): self
302
    {
303
        $this->updatedAt = $updatedAt;
304
        return $this;
305
    }
306
307
    public function getLatitude(): ?float
308
    {
309
        if ($this->latlng === null ||
310
            !is_array($this->latlng) ||
311
            empty($this->latlng)) {
312
            return null;
313
        }
314
        return $this->latlng[0];
315
    }
316
317
    public function getLongitude(): ?float
318
    {
319
        if ($this->latlng === null ||
320
            !is_array($this->latlng) ||
321
            empty($this->latlng)) {
322
            return null;
323
        }
324
        return $this->latlng[1];
325
    }
326
327
    public function getLatlng(): ?array
328
    {
329
        return $this->latlng;
330
    }
331
332
    public function hasLatlng(): bool
333
    {
334
        return is_array($this->latlng) && count($this->latlng) == 2;
335
    }
336
337
    public function setLatlng(?array $latlng): self
338
    {
339
        $this->latlng = $latlng;
340
341
        return $this;
342
    }
343
344
    public function addTag(TagInterface $tag): void
345
    {
346
        if (!$this->tags->contains($tag)) {
347
            $this->tags->add($tag);
348
        }
349
    }
350
351
    public function clearTags(): void
352
    {
353
        $this->tags->clear();
354
    }
355
356
    public function removeTag(TagInterface $tag): void
357
    {
358
        $this->tags->removeElement($tag);
359
    }
360
361
    public function hasTag(TagInterface $tag): bool
362
    {
363
        return $this->tags->contains($tag);
364
    }
365
366
    /**
367
     * @return iterable<TagInterface>
368
     */
369
    public function getTags(): iterable
370
    {
371
        return $this->tags;
372
    }
373
374
    /**
375
     * @param Collection<TagInterface> $tags
376
     */
377
    public function setTags($tags): self
378
    {
379
        $this->clearTags();
380
        foreach ($tags as $tag) {
381
            $this->addTag($tag);
382
        }
383
        return $this;
384
    }
385
386
    /** @var string|null */
387
    private $tagsText;
388
389
    public function setTagsText(?string $tagsText): void
390
    {
391
        $this->tagsText = $tagsText;
392
        $this->updatedAt = new \DateTimeImmutable();
393
    }
394
395
    public function getTagsText(): ?string
396
    {
397
        $this->tagsText = \implode(', ', $this->tags->toArray());
398
        return $this->tagsText;
399
    }
400
401
    /**
402
     * @ORM\PostLoad
403
     */
404
    public function postLoad(): void {
405
        // Bodge to workaround behaviour of BeelabTagBundle, which updates
406
        // tags on persist, but only from the text tags. So if you don't
407
        // get/set the tags text, when you persist your entity all its
408
        // tags disappear. Sigh.
409
        $this->getTagsText();
410
    }
411
412
    /**
413
     * @return array<string>
414
     */
415
    public function getTagNames(): array
416
    {
417
        return empty($this->tagsText) ? [] : \array_map('trim', explode(',', $this->tagsText));
418
    }
419
420
    public function getCapturedAt(): ?\DateTimeInterface
421
    {
422
        return $this->capturedAt;
423
    }
424
425
    public function setCapturedAt(\DateTimeInterface $capturedAt): self
426
    {
427
        $this->capturedAt = $capturedAt;
428
429
        return $this;
430
    }
431
432
433
    public function getWander(): ?Wander
434
    {
435
        return $this->wander;
436
    }
437
438
    public function setWander(?Wander $wander): self
439
    {
440
        $this->wander = $wander;
441
        return $this;
442
    }
443
444
    public function getRating(): ?int
445
    {
446
        return $this->rating;
447
    }
448
449
    public function setRating(?int $rating): self
450
    {
451
        $this->rating = $rating;
452
453
        return $this;
454
    }
455
456
457
    /* Computed (set up by Doctrine postLoad listener) */
458
459
    /**
460
     * @Groups({"image:list", "image:item"})
461
     */
462
    private $imageUri;
463
464
    /**
465
     * @Groups({"image:list", "image:item"})
466
     */
467
    private $markerImageUri;
468
469
    /**
470
     * @Groups({"image:list", "image:item"})
471
     */
472
    private $mediumImageUri;
473
474
    /**
475
     * @Groups({"image:list", "image:item"})
476
     */
477
    private $imageShowUri;
478
479
    /**
480
     * @ORM\Column(type="array", nullable=true)
481
     */
482
    private $auto_tags = [];
483
484
    /**
485
     * @ORM\Column(type="string", length=255, nullable=true)
486
     */
487
    private $location;
488
489
490
    public function setImageUri($imageUri) {
491
        $this->imageUri = $imageUri;
492
    }
493
494
    public function getImageUri(): ?string {
495
        return $this->imageUri;
496
    }
497
498
    public function setMarkerImageUri($markerImageUri) {
499
        $this->markerImageUri = $markerImageUri;
500
    }
501
    public function getMarkerImageUri(): ?string {
502
        return $this->markerImageUri;
503
    }
504
505
    public function setMediumImageUri($mediumImageUri) {
506
        $this->mediumImageUri = $mediumImageUri;
507
    }
508
    public function getMediumImageUri(): ?string {
509
        return $this->mediumImageUri;
510
    }
511
512
    public function setImageShowUri($imageShowUri) {
513
        $this->imageShowUri = $imageShowUri;
514
    }
515
    public function getImageShowUri(): ?string {
516
        return $this->imageShowUri;
517
    }
518
519
    public function getAutoTags(): ?array
520
    {
521
        return $this->auto_tags;
522
    }
523
524
    public function setAutoTags(?array $auto_tags): self
525
    {
526
        $this->auto_tags = $auto_tags;
527
528
        return $this;
529
    }
530
    public function getAutoTagsCount(): int {
531
        if (is_array($this->auto_tags)) {
0 ignored issues
show
introduced by
The condition is_array($this->auto_tags) is always true.
Loading history...
532
            return count($this->auto_tags);
533
        }
534
        return 0;
535
    }
536
537
    public function getLocation(): ?string
538
    {
539
        return $this->location;
540
    }
541
542
    public function hasLocation(): bool
543
    {
544
        return $this->location !== null && $this->location <> '';
545
    }
546
547
    public function setLocation(?string $location): self
548
    {
549
        $this->location = $location;
550
551
        return $this;
552
    }
553
}
554
555