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