]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/CoreBundle/Entity/Entry.php
b3cfdc4a4c26dd13f979cb0782ba8a96592d453c
[github/wallabag/wallabag.git] / src / Wallabag / CoreBundle / Entity / Entry.php
1 <?php
2
3 namespace Wallabag\CoreBundle\Entity;
4
5 use Doctrine\Common\Collections\ArrayCollection;
6 use Doctrine\ORM\Mapping as ORM;
7 use Hateoas\Configuration\Annotation as Hateoas;
8 use JMS\Serializer\Annotation\Exclude;
9 use JMS\Serializer\Annotation\Groups;
10 use JMS\Serializer\Annotation\SerializedName;
11 use JMS\Serializer\Annotation\VirtualProperty;
12 use JMS\Serializer\Annotation\XmlRoot;
13 use Symfony\Component\Validator\Constraints as Assert;
14 use Wallabag\AnnotationBundle\Entity\Annotation;
15 use Wallabag\CoreBundle\Helper\EntityTimestampsTrait;
16 use Wallabag\UserBundle\Entity\User;
17
18 /**
19 * Entry.
20 *
21 * @XmlRoot("entry")
22 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository")
23 * @ORM\Table(
24 * name="`entry`",
25 * options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"},
26 * indexes={
27 * @ORM\Index(name="created_at", columns={"created_at"}),
28 * @ORM\Index(name="uid", columns={"uid"})
29 * }
30 * )
31 * @ORM\HasLifecycleCallbacks()
32 * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())")
33 */
34 class Entry
35 {
36 use EntityTimestampsTrait;
37
38 /** @Serializer\XmlAttribute */
39 /**
40 * @var int
41 *
42 * @ORM\Column(name="id", type="integer")
43 * @ORM\Id
44 * @ORM\GeneratedValue(strategy="AUTO")
45 *
46 * @Groups({"entries_for_user", "export_all"})
47 */
48 private $id;
49
50 /**
51 * @var string
52 *
53 * @ORM\Column(name="uid", type="string", length=23, nullable=true)
54 *
55 * @Groups({"entries_for_user", "export_all"})
56 */
57 private $uid;
58
59 /**
60 * @var string
61 *
62 * @ORM\Column(name="title", type="text", nullable=true)
63 *
64 * @Groups({"entries_for_user", "export_all"})
65 */
66 private $title;
67
68 /**
69 * @var string
70 *
71 * @Assert\NotBlank()
72 * @ORM\Column(name="url", type="text", nullable=true)
73 *
74 * @Groups({"entries_for_user", "export_all"})
75 */
76 private $url;
77
78 /**
79 * @var bool
80 *
81 * @Exclude
82 *
83 * @ORM\Column(name="is_archived", type="boolean")
84 *
85 * @Groups({"entries_for_user", "export_all"})
86 */
87 private $isArchived = false;
88
89 /**
90 * @var \DateTime
91 *
92 * @ORM\Column(name="archived_at", type="datetime", nullable=true)
93 *
94 * @Groups({"entries_for_user", "export_all"})
95 */
96 private $archivedAt = null;
97
98 /**
99 * @var bool
100 *
101 * @Exclude
102 *
103 * @ORM\Column(name="is_starred", type="boolean")
104 *
105 * @Groups({"entries_for_user", "export_all"})
106 */
107 private $isStarred = false;
108
109 /**
110 * @var string
111 *
112 * @ORM\Column(name="content", type="text", nullable=true)
113 *
114 * @Groups({"entries_for_user", "export_all"})
115 */
116 private $content;
117
118 /**
119 * @var \DateTime
120 *
121 * @ORM\Column(name="created_at", type="datetime")
122 *
123 * @Groups({"entries_for_user", "export_all"})
124 */
125 private $createdAt;
126
127 /**
128 * @var \DateTime
129 *
130 * @ORM\Column(name="updated_at", type="datetime")
131 *
132 * @Groups({"entries_for_user", "export_all"})
133 */
134 private $updatedAt;
135
136 /**
137 * @var \DateTime
138 *
139 * @ORM\Column(name="published_at", type="datetime", nullable=true)
140 *
141 * @Groups({"entries_for_user", "export_all"})
142 */
143 private $publishedAt;
144
145 /**
146 * @var array
147 *
148 * @ORM\Column(name="published_by", type="array", nullable=true)
149 *
150 * @Groups({"entries_for_user", "export_all"})
151 */
152 private $publishedBy;
153
154 /**
155 * @var \DateTime
156 *
157 * @ORM\Column(name="starred_at", type="datetime", nullable=true)
158 *
159 * @Groups({"entries_for_user", "export_all"})
160 */
161 private $starredAt = null;
162
163 /**
164 * @ORM\OneToMany(targetEntity="Wallabag\AnnotationBundle\Entity\Annotation", mappedBy="entry", cascade={"persist", "remove"})
165 * @ORM\JoinTable
166 *
167 * @Groups({"entries_for_user", "export_all"})
168 */
169 private $annotations;
170
171 /**
172 * @var string
173 *
174 * @ORM\Column(name="mimetype", type="text", nullable=true)
175 *
176 * @Groups({"entries_for_user", "export_all"})
177 */
178 private $mimetype;
179
180 /**
181 * @var string
182 *
183 * @ORM\Column(name="language", type="text", nullable=true)
184 *
185 * @Groups({"entries_for_user", "export_all"})
186 */
187 private $language;
188
189 /**
190 * @var int
191 *
192 * @ORM\Column(name="reading_time", type="integer", nullable=false)
193 *
194 * @Groups({"entries_for_user", "export_all"})
195 */
196 private $readingTime = 0;
197
198 /**
199 * @var string
200 *
201 * @ORM\Column(name="domain_name", type="text", nullable=true)
202 *
203 * @Groups({"entries_for_user", "export_all"})
204 */
205 private $domainName;
206
207 /**
208 * @var string
209 *
210 * @ORM\Column(name="preview_picture", type="text", nullable=true)
211 *
212 * @Groups({"entries_for_user", "export_all"})
213 */
214 private $previewPicture;
215
216 /**
217 * @var string
218 *
219 * @ORM\Column(name="http_status", type="string", length=3, nullable=true)
220 *
221 * @Groups({"entries_for_user", "export_all"})
222 */
223 private $httpStatus;
224
225 /**
226 * @var array
227 *
228 * @ORM\Column(name="headers", type="array", nullable=true)
229 *
230 * @Groups({"entries_for_user", "export_all"})
231 */
232 private $headers;
233
234 /**
235 * @Exclude
236 *
237 * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="entries")
238 *
239 * @Groups({"export_all"})
240 */
241 private $user;
242
243 /**
244 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="entries", cascade={"persist"})
245 * @ORM\JoinTable(
246 * name="entry_tag",
247 * joinColumns={
248 * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade")
249 * },
250 * inverseJoinColumns={
251 * @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade")
252 * }
253 * )
254 */
255 private $tags;
256
257 /**
258 * @var string
259 *
260 * @ORM\Column(name="origin_url", type="text", nullable=true)
261 *
262 * @Groups({"entries_for_user", "export_all"})
263 */
264 private $originUrl;
265
266 /*
267 * @param User $user
268 */
269 public function __construct(User $user)
270 {
271 $this->user = $user;
272 $this->tags = new ArrayCollection();
273 }
274
275 /**
276 * Get id.
277 *
278 * @return int
279 */
280 public function getId()
281 {
282 return $this->id;
283 }
284
285 /**
286 * Set title.
287 *
288 * @param string $title
289 *
290 * @return Entry
291 */
292 public function setTitle($title)
293 {
294 $this->title = $title;
295
296 return $this;
297 }
298
299 /**
300 * Get title.
301 *
302 * @return string
303 */
304 public function getTitle()
305 {
306 return $this->title;
307 }
308
309 /**
310 * Set url.
311 *
312 * @param string $url
313 *
314 * @return Entry
315 */
316 public function setUrl($url)
317 {
318 $this->url = $url;
319
320 return $this;
321 }
322
323 /**
324 * Get url.
325 *
326 * @return string
327 */
328 public function getUrl()
329 {
330 return $this->url;
331 }
332
333 /**
334 * Set isArchived.
335 *
336 * @param bool $isArchived
337 *
338 * @return Entry
339 */
340 public function setArchived($isArchived)
341 {
342 $this->isArchived = $isArchived;
343
344 return $this;
345 }
346
347 /**
348 * update isArchived and archive_at fields.
349 *
350 * @param bool $isArchived
351 *
352 * @return Entry
353 */
354 public function updateArchived($isArchived = false)
355 {
356 $this->setArchived($isArchived);
357 $this->setArchivedAt(null);
358 if ($this->isArchived()) {
359 $this->setArchivedAt(new \DateTime());
360 }
361
362 return $this;
363 }
364
365 /**
366 * @return \DateTime|null
367 */
368 public function getArchivedAt()
369 {
370 return $this->archivedAt;
371 }
372
373 /**
374 * @param \DateTime|null $archivedAt
375 *
376 * @return Entry
377 */
378 public function setArchivedAt($archivedAt = null)
379 {
380 $this->archivedAt = $archivedAt;
381
382 return $this;
383 }
384
385 /**
386 * Get isArchived.
387 *
388 * @return bool
389 */
390 public function isArchived()
391 {
392 return $this->isArchived;
393 }
394
395 /**
396 * @VirtualProperty
397 * @SerializedName("is_archived")
398 * @Groups({"entries_for_user", "export_all"})
399 */
400 public function is_Archived()
401 {
402 return (int) $this->isArchived();
403 }
404
405 public function toggleArchive()
406 {
407 $this->updateArchived($this->isArchived() ^ 1);
408
409 return $this;
410 }
411
412 /**
413 * Set isStarred.
414 *
415 * @param bool $isStarred
416 *
417 * @return Entry
418 */
419 public function setStarred($isStarred)
420 {
421 $this->isStarred = $isStarred;
422
423 return $this;
424 }
425
426 /**
427 * Get isStarred.
428 *
429 * @return bool
430 */
431 public function isStarred()
432 {
433 return $this->isStarred;
434 }
435
436 /**
437 * @VirtualProperty
438 * @SerializedName("is_starred")
439 * @Groups({"entries_for_user", "export_all"})
440 */
441 public function is_Starred()
442 {
443 return (int) $this->isStarred();
444 }
445
446 public function toggleStar()
447 {
448 $this->isStarred = $this->isStarred() ^ 1;
449
450 return $this;
451 }
452
453 /**
454 * Set content.
455 *
456 * @param string $content
457 *
458 * @return Entry
459 */
460 public function setContent($content)
461 {
462 $this->content = $content;
463
464 return $this;
465 }
466
467 /**
468 * Get content.
469 *
470 * @return string
471 */
472 public function getContent()
473 {
474 return $this->content;
475 }
476
477 /**
478 * @return User
479 */
480 public function getUser()
481 {
482 return $this->user;
483 }
484
485 /**
486 * @VirtualProperty
487 * @SerializedName("user_name")
488 */
489 public function getUserName()
490 {
491 return $this->user->getUserName();
492 }
493
494 /**
495 * @VirtualProperty
496 * @SerializedName("user_email")
497 */
498 public function getUserEmail()
499 {
500 return $this->user->getEmail();
501 }
502
503 /**
504 * @VirtualProperty
505 * @SerializedName("user_id")
506 */
507 public function getUserId()
508 {
509 return $this->user->getId();
510 }
511
512 /**
513 * Set created_at.
514 * Only used when importing data from an other service.
515 *
516 * @param \DateTime $createdAt
517 *
518 * @return Entry
519 */
520 public function setCreatedAt(\DateTime $createdAt)
521 {
522 $this->createdAt = $createdAt;
523
524 return $this;
525 }
526
527 /**
528 * @return \DateTime
529 */
530 public function getCreatedAt()
531 {
532 return $this->createdAt;
533 }
534
535 /**
536 * @return \DateTime
537 */
538 public function getUpdatedAt()
539 {
540 return $this->updatedAt;
541 }
542
543 /**
544 * @return \DateTime|null
545 */
546 public function getStarredAt()
547 {
548 return $this->starredAt;
549 }
550
551 /**
552 * @param \DateTime|null $starredAt
553 *
554 * @return Entry
555 */
556 public function setStarredAt($starredAt = null)
557 {
558 $this->starredAt = $starredAt;
559
560 return $this;
561 }
562
563 /**
564 * update isStarred and starred_at fields.
565 *
566 * @param bool $isStarred
567 *
568 * @return Entry
569 */
570 public function updateStar($isStarred = false)
571 {
572 $this->setStarred($isStarred);
573 $this->setStarredAt(null);
574 if ($this->isStarred()) {
575 $this->setStarredAt(new \DateTime());
576 }
577
578 return $this;
579 }
580
581 /**
582 * @return ArrayCollection<Annotation>
583 */
584 public function getAnnotations()
585 {
586 return $this->annotations;
587 }
588
589 /**
590 * @param Annotation $annotation
591 */
592 public function setAnnotation(Annotation $annotation)
593 {
594 $this->annotations[] = $annotation;
595 }
596
597 /**
598 * @return string
599 */
600 public function getMimetype()
601 {
602 return $this->mimetype;
603 }
604
605 /**
606 * @param string $mimetype
607 */
608 public function setMimetype($mimetype)
609 {
610 $this->mimetype = $mimetype;
611 }
612
613 /**
614 * @return int
615 */
616 public function getReadingTime()
617 {
618 return $this->readingTime;
619 }
620
621 /**
622 * @param int $readingTime
623 */
624 public function setReadingTime($readingTime)
625 {
626 $this->readingTime = $readingTime;
627 }
628
629 /**
630 * @return string
631 */
632 public function getDomainName()
633 {
634 return $this->domainName;
635 }
636
637 /**
638 * @param string $domainName
639 */
640 public function setDomainName($domainName)
641 {
642 $this->domainName = $domainName;
643 }
644
645 /**
646 * @return ArrayCollection
647 */
648 public function getTags()
649 {
650 return $this->tags;
651 }
652
653 /**
654 * @VirtualProperty
655 * @SerializedName("tags")
656 * @Groups({"entries_for_user", "export_all"})
657 */
658 public function getSerializedTags()
659 {
660 $data = [];
661 foreach ($this->tags as $tag) {
662 $data[] = $tag->getLabel();
663 }
664
665 return $data;
666 }
667
668 /**
669 * @param Tag $tag
670 */
671 public function addTag(Tag $tag)
672 {
673 if ($this->tags->contains($tag)) {
674 return;
675 }
676
677 // check if tag already exist but has not yet be persisted
678 // it seems that the previous condition with `contains()` doesn't check that case
679 foreach ($this->tags as $existingTag) {
680 if ($existingTag->getLabel() === $tag->getLabel()) {
681 return;
682 }
683 }
684
685 $this->tags->add($tag);
686 $tag->addEntry($this);
687 }
688
689 /**
690 * Remove the given tag from the entry (if the tag is associated).
691 *
692 * @param Tag $tag
693 */
694 public function removeTag(Tag $tag)
695 {
696 if (!$this->tags->contains($tag)) {
697 return;
698 }
699
700 $this->tags->removeElement($tag);
701 $tag->removeEntry($this);
702 }
703
704 /**
705 * Remove all assigned tags from the entry.
706 */
707 public function removeAllTags()
708 {
709 foreach ($this->tags as $tag) {
710 $this->tags->removeElement($tag);
711 $tag->removeEntry($this);
712 }
713 }
714
715 /**
716 * Set previewPicture.
717 *
718 * @param string $previewPicture
719 *
720 * @return Entry
721 */
722 public function setPreviewPicture($previewPicture)
723 {
724 $this->previewPicture = $previewPicture;
725
726 return $this;
727 }
728
729 /**
730 * Get previewPicture.
731 *
732 * @return string
733 */
734 public function getPreviewPicture()
735 {
736 return $this->previewPicture;
737 }
738
739 /**
740 * Set language.
741 *
742 * @param string $language
743 *
744 * @return Entry
745 */
746 public function setLanguage($language)
747 {
748 $this->language = $language;
749
750 return $this;
751 }
752
753 /**
754 * Get language.
755 *
756 * @return string
757 */
758 public function getLanguage()
759 {
760 return $this->language;
761 }
762
763 /**
764 * @return string
765 */
766 public function getUid()
767 {
768 return $this->uid;
769 }
770
771 /**
772 * @param string $uid
773 *
774 * @return Entry
775 */
776 public function setUid($uid)
777 {
778 $this->uid = $uid;
779
780 return $this;
781 }
782
783 public function generateUid()
784 {
785 if (null === $this->uid) {
786 // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter
787 $this->uid = uniqid('', true);
788 }
789 }
790
791 public function cleanUid()
792 {
793 $this->uid = null;
794 }
795
796 /**
797 * Used in the entries filter so it's more explicit for the end user than the uid.
798 * Also used in the API.
799 *
800 * @VirtualProperty
801 * @SerializedName("is_public")
802 * @Groups({"entries_for_user"})
803 *
804 * @return bool
805 */
806 public function isPublic()
807 {
808 return null !== $this->uid;
809 }
810
811 /**
812 * @return string
813 */
814 public function getHttpStatus()
815 {
816 return $this->httpStatus;
817 }
818
819 /**
820 * @param string $httpStatus
821 *
822 * @return Entry
823 */
824 public function setHttpStatus($httpStatus)
825 {
826 $this->httpStatus = $httpStatus;
827
828 return $this;
829 }
830
831 /**
832 * @return \Datetime
833 */
834 public function getPublishedAt()
835 {
836 return $this->publishedAt;
837 }
838
839 /**
840 * @param \Datetime $publishedAt
841 *
842 * @return Entry
843 */
844 public function setPublishedAt(\Datetime $publishedAt)
845 {
846 $this->publishedAt = $publishedAt;
847
848 return $this;
849 }
850
851 /**
852 * @return array
853 */
854 public function getPublishedBy()
855 {
856 return $this->publishedBy;
857 }
858
859 /**
860 * @param array $publishedBy
861 *
862 * @return Entry
863 */
864 public function setPublishedBy($publishedBy)
865 {
866 $this->publishedBy = $publishedBy;
867
868 return $this;
869 }
870
871 /**
872 * @return array
873 */
874 public function getHeaders()
875 {
876 return $this->headers;
877 }
878
879 /**
880 * @param array $headers
881 *
882 * @return Entry
883 */
884 public function setHeaders($headers)
885 {
886 $this->headers = $headers;
887
888 return $this;
889 }
890
891 /**
892 * Set origin url.
893 *
894 * @param string $originUrl
895 *
896 * @return Entry
897 */
898 public function setOriginUrl($originUrl)
899 {
900 $this->originUrl = $originUrl;
901
902 return $this;
903 }
904
905 /**
906 * Get origin url.
907 *
908 * @return string
909 */
910 public function getOriginUrl()
911 {
912 return $this->originUrl;
913 }
914 }