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