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