3 namespace Shaarli\Bookmark
;
7 use Shaarli\Bookmark\Exception\InvalidBookmarkException
;
12 * This class represent a single Bookmark with all its attributes.
13 * Every bookmark should manipulated using this, before being formatted.
15 * @package Shaarli\Bookmark
19 /** @var string Date format used in string (former ID format) */
20 const LINK_DATE_FORMAT
= 'Ymd_His';
22 /** @var int Bookmark ID */
25 /** @var string Permalink identifier */
28 /** @var string Bookmark's URL - $shortUrl prefixed with `?` for notes */
31 /** @var string Bookmark's title */
34 /** @var string Raw bookmark's description */
35 protected $description;
37 /** @var array List of bookmark's tags */
40 /** @var string|bool|null Thumbnail's URL - initialized at null, false if no thumbnail could be found */
43 /** @var bool Set to true if the bookmark is set as sticky */
46 /** @var DateTimeInterface Creation datetime */
49 /** @var DateTimeInterface datetime */
52 /** @var bool True if the bookmark can only be seen while logged in */
56 * Initialize a link from array data. Especially useful to create a Bookmark from former link storage format.
62 public function fromArray($data)
64 $this->id
= $data['id'];
65 $this->shortUrl
= $data['shorturl'];
66 $this->url
= $data['url'];
67 $this->title
= $data['title'];
68 $this->description
= $data['description'];
69 $this->thumbnail
= isset($data['thumbnail']) ? $data['thumbnail'] : null;
70 $this->sticky
= isset($data['sticky']) ? $data['sticky'] : false;
71 $this->created
= $data['created'];
72 if (is_array($data['tags'])) {
73 $this->tags
= $data['tags'];
75 $this->tags
= preg_split('/\s+/', $data['tags'], -1, PREG_SPLIT_NO_EMPTY
);
77 if (! empty($data['updated'])) {
78 $this->updated
= $data['updated'];
80 $this->private = $data['private'] ? true : false;
86 * Make sure that the current instance of Bookmark is valid and can be saved into the data store.
87 * A valid link requires:
89 * - a short URL (for permalinks)
92 * This function also initialize optional empty fields:
93 * - the URL with the permalink
94 * - the title with the URL
96 * @throws InvalidBookmarkException
98 public function validate()
100 if ($this->id
=== null
101 || ! is_int($this->id
)
102 || empty($this->shortUrl
)
103 || empty($this->created
)
104 || ! $this->created
instanceof DateTimeInterface
106 throw new InvalidBookmarkException($this);
108 if (empty($this->url
)) {
109 $this->url
= '/shaare/'. $this->shortUrl
;
111 if (empty($this->title
)) {
112 $this->title
= $this->url
;
118 * If they're not already initialized, this function also set:
119 * - created: with the current datetime
120 * - shortUrl: with a generated small hash from the date and the given ID
126 public function setId($id)
129 if (empty($this->created
)) {
130 $this->created
= new DateTime();
132 if (empty($this->shortUrl
)) {
133 $this->shortUrl
= link_small_hash($this->created
, $this->id
);
144 public function getId()
154 public function getShortUrl()
156 return $this->shortUrl
;
164 public function getUrl()
174 public function getTitle()
180 * Get the Description.
184 public function getDescription()
186 return ! empty($this->description
) ? $this->description
: '';
192 * @return DateTimeInterface
194 public function getCreated()
196 return $this->created
;
202 * @return DateTimeInterface
204 public function getUpdated()
206 return $this->updated
;
212 * @param string $shortUrl
216 public function setShortUrl($shortUrl)
218 $this->shortUrl
= $shortUrl;
227 * @param array $allowedProtocols
231 public function setUrl($url, $allowedProtocols = [])
235 $url = whitelist_protocols($url, $allowedProtocols);
245 * @param string $title
249 public function setTitle($title)
251 $this->title
= trim($title);
257 * Set the Description.
259 * @param string $description
263 public function setDescription($description)
265 $this->description
= $description;
272 * Note: you shouldn't set this manually except for special cases (like bookmark import)
274 * @param DateTimeInterface $created
278 public function setCreated($created)
280 $this->created
= $created;
288 * @param DateTimeInterface $updated
292 public function setUpdated($updated)
294 $this->updated
= $updated;
304 public function isPrivate()
306 return $this->private ? true : false;
312 * @param bool $private
316 public function setPrivate($private)
318 $this->private = $private ? true : false;
328 public function getTags()
330 return is_array($this->tags
) ? $this->tags
: [];
340 public function setTags($tags)
342 $this->setTagsString(implode(' ', $tags));
350 * @return string|bool|null Thumbnail's URL - initialized at null, false if no thumbnail could be found
352 public function getThumbnail()
354 return !$this->isNote() ? $this->thumbnail
: false;
360 * @param string|bool $thumbnail Thumbnail's URL - false if no thumbnail could be found
364 public function setThumbnail($thumbnail)
366 $this->thumbnail
= $thumbnail;
376 public function isSticky()
378 return $this->sticky
? true : false;
384 * @param bool $sticky
388 public function setSticky($sticky)
390 $this->sticky
= $sticky ? true : false;
396 * @return string Bookmark's tags as a string, separated by a space
398 public function getTagsString()
400 return implode(' ', $this->getTags());
406 public function isNote()
408 // We check empty value to get a valid result if the link has not been saved yet
409 return empty($this->url
) || startsWith($this->url
, '/shaare/') || $this->url
[0] === '?';
413 * Set tags from a string.
415 * - tags must be separated whether by a space or a comma
416 * - multiple spaces will be removed
417 * - trailing dash in tags will be removed
419 * @param string $tags
423 public function setTagsString($tags)
425 // Remove first '-' char in tags.
426 $tags = preg_replace('/(^| )\-/', '$1', $tags);
427 // Explode all tags separted by spaces or commas
428 $tags = preg_split('/[\s
,]+
/', $tags);
429 // Remove eventual empty values
430 $tags = array_values(array_filter($tags));
438 * Rename a tag in tags list.
440 * @param string $fromTag
441 * @param string $toTag
443 public function renameTag($fromTag, $toTag)
445 if (($pos = array_search($fromTag, $this->tags)) !== false) {
446 $this->tags[$pos] = trim($toTag);
451 * Delete a tag from tags list.
455 public function deleteTag($tag)
457 if (($pos = array_search($tag, $this->tags)) !== false) {
458 unset($this->tags[$pos]);
459 $this->tags = array_values($this->tags);