/** @var bool True if the bookmark can only be seen while logged in */
protected $private;
+ /** @var mixed[] Available to store any additional content for a bookmark. Currently used for search highlight. */
+ protected $additionalContent = [];
+
/**
* Initialize a link from array data. Especially useful to create a Bookmark from former link storage format.
*
- * @param array $data
+ * @param array $data
+ * @param string $tagsSeparator Tags separator loaded from the config file.
+ * This is a context data, and it should *never* be stored in the Bookmark object.
*
* @return $this
*/
- public function fromArray(array $data): Bookmark
+ public function fromArray(array $data, string $tagsSeparator = ' '): Bookmark
{
$this->id = $data['id'] ?? null;
$this->shortUrl = $data['shorturl'] ?? null;
if (is_array($data['tags'])) {
$this->tags = $data['tags'];
} else {
- $this->tags = preg_split('/\s+/', $data['tags'] ?? '', -1, PREG_SPLIT_NO_EMPTY);
+ $this->tags = tags_str2array($data['tags'] ?? '', $tagsSeparator);
}
if (! empty($data['updated'])) {
$this->updated = $data['updated'];
* - the URL with the permalink
* - the title with the URL
*
+ * Also make sure that we do not save search highlights in the datastore.
+ *
* @throws InvalidBookmarkException
*/
public function validate(): void
if (empty($this->title)) {
$this->title = $this->url;
}
+ if (array_key_exists('search_highlight', $this->additionalContent)) {
+ unset($this->additionalContent['search_highlight']);
+ }
}
/**
*/
public function setTags(?array $tags): Bookmark
{
- $this->setTagsString(implode(' ', $tags ?? []));
+ $this->tags = array_map(
+ function (string $tag): string {
+ return $tag[0] === '-' ? substr($tag, 1) : $tag;
+ },
+ tags_filter($tags, ' ')
+ );
return $this;
}
return $this;
}
+ /**
+ * Return true if:
+ * - the bookmark's thumbnail is not already set to false (= not found)
+ * - it's not a note
+ * - it's an HTTP(S) link
+ * - the thumbnail has not yet be retrieved (null) or its associated cache file doesn't exist anymore
+ *
+ * @return bool True if the bookmark's thumbnail needs to be retrieved.
+ */
+ public function shouldUpdateThumbnail(): bool
+ {
+ return $this->thumbnail !== false
+ && !$this->isNote()
+ && startsWith(strtolower($this->url), 'http')
+ && (null === $this->thumbnail || !is_file($this->thumbnail))
+ ;
+ }
+
/**
* Get the Sticky.
*
}
/**
- * @return string Bookmark's tags as a string, separated by a space
+ * @param string $separator Tags separator loaded from the config file.
+ *
+ * @return string Bookmark's tags as a string, separated by a separator
*/
- public function getTagsString(): string
+ public function getTagsString(string $separator = ' '): string
{
- return implode(' ', $this->getTags());
+ return tags_array2str($this->getTags(), $separator);
}
/**
* - trailing dash in tags will be removed
*
* @param string|null $tags
+ * @param string $separator Tags separator loaded from the config file.
*
* @return $this
*/
- public function setTagsString(?string $tags): Bookmark
+ public function setTagsString(?string $tags, string $separator = ' '): Bookmark
+ {
+ $this->setTags(tags_str2array($tags, $separator));
+
+ return $this;
+ }
+
+ /**
+ * Get entire additionalContent array.
+ *
+ * @return mixed[]
+ */
+ public function getAdditionalContent(): array
{
- // Remove first '-' char in tags.
- $tags = preg_replace('/(^| )\-/', '$1', $tags ?? '');
- // Explode all tags separted by spaces or commas
- $tags = preg_split('/[\s,]+/', $tags);
- // Remove eventual empty values
- $tags = array_values(array_filter($tags));
+ return $this->additionalContent;
+ }
- $this->tags = $tags;
+ /**
+ * Set a single entry in additionalContent, by key.
+ *
+ * @param string $key
+ * @param mixed|null $value Any type of value can be set.
+ *
+ * @return $this
+ */
+ public function addAdditionalContentEntry(string $key, $value): self
+ {
+ $this->additionalContent[$key] = $value;
return $this;
}
+ /**
+ * Get a single entry in additionalContent, by key.
+ *
+ * @param string $key
+ * @param mixed|null $default
+ *
+ * @return mixed|null can be any type or even null.
+ */
+ public function getAdditionalContentEntry(string $key, $default = null)
+ {
+ return array_key_exists($key, $this->additionalContent) ? $this->additionalContent[$key] : $default;
+ }
+
/**
* Rename a tag in tags list.
*
*/
public function renameTag(string $fromTag, string $toTag): void
{
- if (($pos = array_search($fromTag, $this->tags)) !== false) {
+ if (($pos = array_search($fromTag, $this->tags ?? [])) !== false) {
$this->tags[$pos] = trim($toTag);
}
}
*/
public function deleteTag(string $tag): void
{
- if (($pos = array_search($tag, $this->tags)) !== false) {
+ if (($pos = array_search($tag, $this->tags ?? [])) !== false) {
unset($this->tags[$pos]);
$this->tags = array_values($this->tags);
}