3 namespace Wallabag\CoreBundle\Entity
;
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
;
23 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository")
26 * options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"},
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"})
38 * @ORM\HasLifecycleCallbacks()
39 * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())")
43 use EntityTimestampsTrait
;
45 /** @Serializer\XmlAttribute */
49 * @ORM\Column(name="id", type="integer")
51 * @ORM\GeneratedValue(strategy="AUTO")
53 * @Groups({"entries_for_user", "export_all"})
60 * @ORM\Column(name="uid", type="string", length=23, nullable=true)
62 * @Groups({"entries_for_user", "export_all"})
69 * @ORM\Column(name="title", type="text", nullable=true)
71 * @Groups({"entries_for_user", "export_all"})
76 * Define the url fetched by wallabag (the final url after potential redirections).
81 * @ORM\Column(name="url", type="text", nullable=true)
83 * @Groups({"entries_for_user", "export_all"})
90 * @ORM\Column(name="hashed_url", type="string", length=40, nullable=true)
95 * From where user retrieved/found the url (an other article, a twitter, or the given_url if non are provided).
99 * @ORM\Column(name="origin_url", type="text", nullable=true)
101 * @Groups({"entries_for_user", "export_all"})
106 * Define the url entered by the user (without redirections).
110 * @ORM\Column(name="given_url", type="text", nullable=true)
112 * @Groups({"entries_for_user", "export_all"})
119 * @ORM\Column(name="hashed_given_url", type="string", length=40, nullable=true)
121 private $hashedGivenUrl;
128 * @ORM\Column(name="is_archived", type="boolean")
130 * @Groups({"entries_for_user", "export_all"})
132 private $isArchived = false;
137 * @ORM\Column(name="archived_at", type="datetime", nullable=true)
139 * @Groups({"entries_for_user", "export_all"})
141 private $archivedAt = null;
148 * @ORM\Column(name="is_starred", type="boolean")
150 * @Groups({"entries_for_user", "export_all"})
152 private $isStarred = false;
157 * @ORM\Column(name="content", type="text", nullable=true)
159 * @Groups({"entries_for_user", "export_all"})
166 * @ORM\Column(name="created_at", type="datetime")
168 * @Groups({"entries_for_user", "export_all"})
175 * @ORM\Column(name="updated_at", type="datetime")
177 * @Groups({"entries_for_user", "export_all"})
184 * @ORM\Column(name="published_at", type="datetime", nullable=true)
186 * @Groups({"entries_for_user", "export_all"})
188 private $publishedAt;
193 * @ORM\Column(name="published_by", type="array", nullable=true)
195 * @Groups({"entries_for_user", "export_all"})
197 private $publishedBy;
202 * @ORM\Column(name="starred_at", type="datetime", nullable=true)
204 * @Groups({"entries_for_user", "export_all"})
206 private $starredAt = null;
209 * @ORM\OneToMany(targetEntity="Wallabag\AnnotationBundle\Entity\Annotation", mappedBy="entry", cascade={"persist", "remove"})
212 * @Groups({"entries_for_user", "export_all"})
214 private $annotations;
219 * @ORM\Column(name="mimetype", type="text", nullable=true)
221 * @Groups({"entries_for_user", "export_all"})
228 * @ORM\Column(name="language", type="string", length=20, nullable=true)
230 * @Groups({"entries_for_user", "export_all"})
237 * @ORM\Column(name="reading_time", type="integer", nullable=false)
239 * @Groups({"entries_for_user", "export_all"})
241 private $readingTime = 0;
246 * @ORM\Column(name="domain_name", type="text", nullable=true)
248 * @Groups({"entries_for_user", "export_all"})
255 * @ORM\Column(name="preview_picture", type="text", nullable=true)
257 * @Groups({"entries_for_user", "export_all"})
259 private $previewPicture;
264 * @ORM\Column(name="http_status", type="string", length=3, nullable=true)
266 * @Groups({"entries_for_user", "export_all"})
273 * @ORM\Column(name="headers", type="array", nullable=true)
275 * @Groups({"entries_for_user", "export_all"})
282 * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="entries")
284 * @Groups({"export_all"})
289 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="entries", cascade={"persist"})
293 * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade")
295 * inverseJoinColumns={
296 * @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade")
305 public function __construct(User
$user)
308 $this->tags
= new ArrayCollection();
316 public function getId()
324 * @param string $title
328 public function setTitle($title)
330 $this->title
= $title;
340 public function getTitle()
352 public function setUrl($url)
355 $this->hashedUrl
= UrlHasher
::hashUrl($url);
365 public function getUrl()
373 * @param bool $isArchived
377 public function setArchived($isArchived)
379 $this->isArchived
= $isArchived;
385 * update isArchived and archive_at fields.
387 * @param bool $isArchived
391 public function updateArchived($isArchived = false)
393 $this->setArchived($isArchived);
394 $this->setArchivedAt(null);
395 if ($this->isArchived()) {
396 $this->setArchivedAt(new \
DateTime());
403 * @return \DateTime|null
405 public function getArchivedAt()
407 return $this->archivedAt
;
411 * @param \DateTime|null $archivedAt
415 public function setArchivedAt($archivedAt = null)
417 $this->archivedAt
= $archivedAt;
427 public function isArchived()
429 return $this->isArchived
;
434 * @SerializedName("is_archived")
435 * @Groups({"entries_for_user", "export_all"})
437 public function is_Archived()
439 return (int) $this->isArchived();
442 public function toggleArchive()
444 $this->updateArchived($this->isArchived() ^
1);
452 * @param bool $isStarred
456 public function setStarred($isStarred)
458 $this->isStarred
= $isStarred;
468 public function isStarred()
470 return $this->isStarred
;
475 * @SerializedName("is_starred")
476 * @Groups({"entries_for_user", "export_all"})
478 public function is_Starred()
480 return (int) $this->isStarred();
483 public function toggleStar()
485 $this->isStarred
= $this->isStarred() ^
1;
493 * @param string $content
497 public function setContent($content)
499 $this->content
= $content;
509 public function getContent()
511 return $this->content
;
517 public function getUser()
524 * @SerializedName("user_name")
526 public function getUserName()
528 return $this->user
->getUserName();
533 * @SerializedName("user_email")
535 public function getUserEmail()
537 return $this->user
->getEmail();
542 * @SerializedName("user_id")
544 public function getUserId()
546 return $this->user
->getId();
551 * Only used when importing data from an other service.
555 public function setCreatedAt(\DateTimeInterface
$createdAt)
557 $this->createdAt
= $createdAt;
565 public function getCreatedAt()
567 return $this->createdAt
;
573 public function getUpdatedAt()
575 return $this->updatedAt
;
579 * @return \DateTime|null
581 public function getStarredAt()
583 return $this->starredAt
;
587 * @param \DateTime|null $starredAt
591 public function setStarredAt($starredAt = null)
593 $this->starredAt
= $starredAt;
599 * update isStarred and starred_at fields.
601 * @param bool $isStarred
605 public function updateStar($isStarred = false)
607 $this->setStarred($isStarred);
608 $this->setStarredAt(null);
609 if ($this->isStarred()) {
610 $this->setStarredAt(new \
DateTime());
617 * @return ArrayCollection<Annotation>
619 public function getAnnotations()
621 return $this->annotations
;
624 public function setAnnotation(Annotation
$annotation)
626 $this->annotations
[] = $annotation;
632 public function getMimetype()
634 return $this->mimetype
;
638 * @param string $mimetype
640 public function setMimetype($mimetype)
642 $this->mimetype
= $mimetype;
648 public function getReadingTime()
650 return $this->readingTime
;
654 * @param int $readingTime
656 public function setReadingTime($readingTime)
658 $this->readingTime
= $readingTime;
664 public function getDomainName()
666 return $this->domainName
;
670 * @param string $domainName
672 public function setDomainName($domainName)
674 $this->domainName
= $domainName;
678 * @return ArrayCollection
680 public function getTags()
687 * @SerializedName("tags")
688 * @Groups({"entries_for_user", "export_all"})
690 public function getSerializedTags()
693 foreach ($this->tags
as $tag) {
694 $data[] = $tag->getLabel();
700 public function addTag(Tag
$tag)
702 if ($this->tags
->contains($tag)) {
706 // check if tag already exist but has not yet be persisted
707 // it seems that the previous condition with `contains()` doesn't check that case
708 foreach ($this->tags
as $existingTag) {
709 if ($existingTag->getLabel() === $tag->getLabel()) {
714 $this->tags
->add($tag);
715 $tag->addEntry($this);
719 * Remove the given tag from the entry (if the tag is associated).
721 public function removeTag(Tag
$tag)
723 if (!$this->tags
->contains($tag)) {
727 $this->tags
->removeElement($tag);
728 $tag->removeEntry($this);
732 * Remove all assigned tags from the entry.
734 public function removeAllTags()
736 foreach ($this->tags
as $tag) {
737 $this->tags
->removeElement($tag);
738 $tag->removeEntry($this);
743 * Set previewPicture.
745 * @param string $previewPicture
749 public function setPreviewPicture($previewPicture)
751 $this->previewPicture
= $previewPicture;
757 * Get previewPicture.
761 public function getPreviewPicture()
763 return $this->previewPicture
;
769 * @param string $language
773 public function setLanguage($language)
775 $this->language
= $language;
785 public function getLanguage()
787 return $this->language
;
791 * Format the entry language to a valid html lang attribute.
793 public function getHTMLLanguage()
795 $parsedLocale = \Locale
::parseLocale($this->getLanguage());
797 $lang .= $parsedLocale['language'] ?? '';
798 $lang .= isset($parsedLocale['region']) ? '-' . $parsedLocale['region'] : '';
804 * @return string|null
806 public function getUid()
816 public function setUid($uid)
823 public function generateUid()
825 if (null === $this->uid
) {
826 // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter
827 $this->uid
= uniqid('', true);
831 public function cleanUid()
837 * Used in the entries filter so it's more explicit for the end user than the uid.
838 * Also used in the API.
841 * @SerializedName("is_public")
842 * @Groups({"entries_for_user"})
846 public function isPublic()
848 return null !== $this->uid
;
854 public function getHttpStatus()
856 return $this->httpStatus
;
860 * @param string $httpStatus
864 public function setHttpStatus($httpStatus)
866 $this->httpStatus
= $httpStatus;
874 public function getPublishedAt()
876 return $this->publishedAt
;
882 public function setPublishedAt(\Datetime
$publishedAt)
884 $this->publishedAt
= $publishedAt;
892 public function getPublishedBy()
894 return $this->publishedBy
;
898 * @param array $publishedBy
902 public function setPublishedBy($publishedBy)
904 $this->publishedBy
= $publishedBy;
912 public function getHeaders()
914 return $this->headers
;
918 * @param array $headers
922 public function setHeaders($headers)
924 $this->headers
= $headers;
932 * @param string $originUrl
936 public function setOriginUrl($originUrl)
938 $this->originUrl
= $originUrl;
948 public function getOriginUrl()
950 return $this->originUrl
;
956 * @param string $givenUrl
960 public function setGivenUrl($givenUrl)
962 $this->givenUrl
= $givenUrl;
963 $this->hashedGivenUrl
= UrlHasher
::hashUrl($givenUrl);
973 public function getGivenUrl()
975 return $this->givenUrl
;
981 public function getHashedUrl()
983 return $this->hashedUrl
;
987 * @param mixed $hashedUrl
991 public function setHashedUrl($hashedUrl)
993 $this->hashedUrl
= $hashedUrl;