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