* If no URL is provided, it will generate a local note URL.
* If no title is provided, it will use the URL as title.
*
- * @param array $input Request Link.
- * @param bool $defaultPrivate Request Link.
+ * @param array|null $input Request Link.
+ * @param bool $defaultPrivate Setting defined if a bookmark is private by default.
*
* @return Bookmark instance.
*/
- public static function buildBookmarkFromRequest($input, $defaultPrivate): Bookmark
+ public static function buildBookmarkFromRequest(?array $input, bool $defaultPrivate): Bookmark
{
$bookmark = new Bookmark();
$url = ! empty($input['url']) ? cleanup_url($input['url']) : '';
*/
public function getLink($request, $response, $args)
{
- if (!$this->bookmarkService->exists($args['id'])) {
+ $id = is_integer_mixed($args['id']) ? (int) $args['id'] : null;
+ if ($id === null || ! $this->bookmarkService->exists($id)) {
throw new ApiLinkNotFoundException();
}
$index = index_url($this->ci['environment']);
- $out = ApiUtils::formatLink($this->bookmarkService->get($args['id']), $index);
+ $out = ApiUtils::formatLink($this->bookmarkService->get($id), $index);
return $response->withJson($out, 200, $this->jsonStyle);
}
*/
public function postLink($request, $response)
{
- $data = $request->getParsedBody();
+ $data = (array) ($request->getParsedBody() ?? []);
$bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
// duplicate by URL, return 409 Conflict
if (! empty($bookmark->getUrl())
*/
public function putLink($request, $response, $args)
{
- if (! $this->bookmarkService->exists($args['id'])) {
+ $id = is_integer_mixed($args['id']) ? (int) $args['id'] : null;
+ if ($id === null || !$this->bookmarkService->exists($id)) {
throw new ApiLinkNotFoundException();
}
// duplicate URL on a different link, return 409 Conflict
if (! empty($requestBookmark->getUrl())
&& ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl()))
- && $dup->getId() != $args['id']
+ && $dup->getId() != $id
) {
return $response->withJson(
ApiUtils::formatLink($dup, $index),
);
}
- $responseBookmark = $this->bookmarkService->get($args['id']);
+ $responseBookmark = $this->bookmarkService->get($id);
$responseBookmark = ApiUtils::updateLink($responseBookmark, $requestBookmark);
$this->bookmarkService->set($responseBookmark);
*/
public function deleteLink($request, $response, $args)
{
- if (! $this->bookmarkService->exists($args['id'])) {
+ $id = is_integer_mixed($args['id']) ? (int) $args['id'] : null;
+ if ($id === null || !$this->bookmarkService->exists($id)) {
throw new ApiLinkNotFoundException();
}
- $bookmark = $this->bookmarkService->get($args['id']);
+ $bookmark = $this->bookmarkService->get($id);
$this->bookmarkService->remove($bookmark);
return $response->withStatus(204);
<?php
+declare(strict_types=1);
+
namespace Shaarli\Bookmark;
use DateTime;
*
* @return $this
*/
- public function fromArray($data)
+ public function fromArray(array $data): Bookmark
{
- $this->id = $data['id'];
- $this->shortUrl = $data['shorturl'];
- $this->url = $data['url'];
- $this->title = $data['title'];
- $this->description = $data['description'];
- $this->thumbnail = isset($data['thumbnail']) ? $data['thumbnail'] : null;
- $this->sticky = isset($data['sticky']) ? $data['sticky'] : false;
- $this->created = $data['created'];
+ $this->id = $data['id'] ?? null;
+ $this->shortUrl = $data['shorturl'] ?? null;
+ $this->url = $data['url'] ?? null;
+ $this->title = $data['title'] ?? null;
+ $this->description = $data['description'] ?? null;
+ $this->thumbnail = $data['thumbnail'] ?? null;
+ $this->sticky = $data['sticky'] ?? false;
+ $this->created = $data['created'] ?? 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 = preg_split('/\s+/', $data['tags'] ?? '', -1, PREG_SPLIT_NO_EMPTY);
}
if (! empty($data['updated'])) {
$this->updated = $data['updated'];
}
- $this->private = $data['private'] ? true : false;
+ $this->private = ($data['private'] ?? false) ? true : false;
return $this;
}
*
* @throws InvalidBookmarkException
*/
- public function validate()
+ public function validate(): void
{
if ($this->id === null
|| ! is_int($this->id)
|| empty($this->shortUrl)
|| empty($this->created)
- || ! $this->created instanceof DateTimeInterface
) {
throw new InvalidBookmarkException($this);
}
* - created: with the current datetime
* - shortUrl: with a generated small hash from the date and the given ID
*
- * @param int $id
+ * @param int|null $id
*
* @return Bookmark
*/
- public function setId($id)
+ public function setId(?int $id): Bookmark
{
$this->id = $id;
if (empty($this->created)) {
/**
* Get the Id.
*
- * @return int
+ * @return int|null
*/
- public function getId()
+ public function getId(): ?int
{
return $this->id;
}
/**
* Get the ShortUrl.
*
- * @return string
+ * @return string|null
*/
- public function getShortUrl()
+ public function getShortUrl(): ?string
{
return $this->shortUrl;
}
/**
* Get the Url.
*
- * @return string
+ * @return string|null
*/
- public function getUrl()
+ public function getUrl(): ?string
{
return $this->url;
}
*
* @return string
*/
- public function getTitle()
+ public function getTitle(): ?string
{
return $this->title;
}
*
* @return string
*/
- public function getDescription()
+ public function getDescription(): string
{
return ! empty($this->description) ? $this->description : '';
}
*
* @return DateTimeInterface
*/
- public function getCreated()
+ public function getCreated(): ?DateTimeInterface
{
return $this->created;
}
*
* @return DateTimeInterface
*/
- public function getUpdated()
+ public function getUpdated(): ?DateTimeInterface
{
return $this->updated;
}
/**
* Set the ShortUrl.
*
- * @param string $shortUrl
+ * @param string|null $shortUrl
*
* @return Bookmark
*/
- public function setShortUrl($shortUrl)
+ public function setShortUrl(?string $shortUrl): Bookmark
{
$this->shortUrl = $shortUrl;
/**
* Set the Url.
*
- * @param string $url
- * @param array $allowedProtocols
+ * @param string|null $url
+ * @param string[] $allowedProtocols
*
* @return Bookmark
*/
- public function setUrl($url, $allowedProtocols = [])
+ public function setUrl(?string $url, array $allowedProtocols = []): Bookmark
{
- $url = trim($url);
+ $url = $url !== null ? trim($url) : '';
if (! empty($url)) {
$url = whitelist_protocols($url, $allowedProtocols);
}
/**
* Set the Title.
*
- * @param string $title
+ * @param string|null $title
*
* @return Bookmark
*/
- public function setTitle($title)
+ public function setTitle(?string $title): Bookmark
{
- $this->title = trim($title);
+ $this->title = $title !== null ? trim($title) : '';
return $this;
}
/**
* Set the Description.
*
- * @param string $description
+ * @param string|null $description
*
* @return Bookmark
*/
- public function setDescription($description)
+ public function setDescription(?string $description): Bookmark
{
$this->description = $description;
* Set the Created.
* Note: you shouldn't set this manually except for special cases (like bookmark import)
*
- * @param DateTimeInterface $created
+ * @param DateTimeInterface|null $created
*
* @return Bookmark
*/
- public function setCreated($created)
+ public function setCreated(?DateTimeInterface $created): Bookmark
{
$this->created = $created;
/**
* Set the Updated.
*
- * @param DateTimeInterface $updated
+ * @param DateTimeInterface|null $updated
*
* @return Bookmark
*/
- public function setUpdated($updated)
+ public function setUpdated(?DateTimeInterface $updated): Bookmark
{
$this->updated = $updated;
*
* @return bool
*/
- public function isPrivate()
+ public function isPrivate(): bool
{
return $this->private ? true : false;
}
/**
* Set the Private.
*
- * @param bool $private
+ * @param bool|null $private
*
* @return Bookmark
*/
- public function setPrivate($private)
+ public function setPrivate(?bool $private): Bookmark
{
$this->private = $private ? true : false;
/**
* Get the Tags.
*
- * @return array
+ * @return string[]
*/
- public function getTags()
+ public function getTags(): array
{
return is_array($this->tags) ? $this->tags : [];
}
/**
* Set the Tags.
*
- * @param array $tags
+ * @param string[]|null $tags
*
* @return Bookmark
*/
- public function setTags($tags)
+ public function setTags(?array $tags): Bookmark
{
- $this->setTagsString(implode(' ', $tags));
+ $this->setTagsString(implode(' ', $tags ?? []));
return $this;
}
/**
* Set the Thumbnail.
*
- * @param string|bool $thumbnail Thumbnail's URL - false if no thumbnail could be found
+ * @param string|bool|null $thumbnail Thumbnail's URL - false if no thumbnail could be found
*
* @return Bookmark
*/
- public function setThumbnail($thumbnail)
+ public function setThumbnail($thumbnail): Bookmark
{
$this->thumbnail = $thumbnail;
*
* @return bool
*/
- public function isSticky()
+ public function isSticky(): bool
{
return $this->sticky ? true : false;
}
/**
* Set the Sticky.
*
- * @param bool $sticky
+ * @param bool|null $sticky
*
* @return Bookmark
*/
- public function setSticky($sticky)
+ public function setSticky(?bool $sticky): Bookmark
{
$this->sticky = $sticky ? true : false;
/**
* @return string Bookmark's tags as a string, separated by a space
*/
- public function getTagsString()
+ public function getTagsString(): string
{
return implode(' ', $this->getTags());
}
/**
* @return bool
*/
- public function isNote()
+ public function isNote(): bool
{
// We check empty value to get a valid result if the link has not been saved yet
return empty($this->url) || startsWith($this->url, '/shaare/') || $this->url[0] === '?';
* - multiple spaces will be removed
* - trailing dash in tags will be removed
*
- * @param string $tags
+ * @param string|null $tags
*
* @return $this
*/
- public function setTagsString($tags)
+ public function setTagsString(?string $tags): Bookmark
{
// Remove first '-' char in tags.
- $tags = preg_replace('/(^| )\-/', '$1', $tags);
+ $tags = preg_replace('/(^| )\-/', '$1', $tags ?? '');
// Explode all tags separted by spaces or commas
$tags = preg_split('/[\s,]+/', $tags);
// Remove eventual empty values
* @param string $fromTag
* @param string $toTag
*/
- public function renameTag($fromTag, $toTag)
+ public function renameTag(string $fromTag, string $toTag): void
{
if (($pos = array_search($fromTag, $this->tags)) !== false) {
$this->tags[$pos] = trim($toTag);
*
* @param string $tag
*/
- public function deleteTag($tag)
+ public function deleteTag(string $tag): void
{
if (($pos = array_search($tag, $this->tags)) !== false) {
unset($this->tags[$pos]);
<?php
+declare(strict_types=1);
+
namespace Shaarli\Bookmark;
use Shaarli\Bookmark\Exception\InvalidBookmarkException;
/**
* Returns a bookmark offset in bookmarks array from its unique ID.
*
- * @param int $id Persistent ID of a bookmark.
+ * @param int|null $id Persistent ID of a bookmark.
*
* @return int Real offset in local array, or null if doesn't exist.
*/
- protected function getBookmarkOffset($id)
+ protected function getBookmarkOffset(?int $id): ?int
{
- if (isset($this->ids[$id])) {
+ if ($id !== null && isset($this->ids[$id])) {
return $this->ids[$id];
}
return null;
*
* @return int next ID.
*/
- public function getNextId()
+ public function getNextId(): int
{
if (!empty($this->ids)) {
return max(array_keys($this->ids)) + 1;
}
/**
- * @param $url
+ * @param string $url
*
* @return Bookmark|null
*/
- public function getByUrl($url)
+ public function getByUrl(string $url): ?Bookmark
{
if (! empty($url)
&& isset($this->urls[$url])
<?php
+declare(strict_types=1);
namespace Shaarli\Bookmark;
-
+use DateTime;
use Exception;
use malkusch\lock\mutex\Mutex;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
/**
* @inheritDoc
*/
- public function __construct(ConfigManager $conf, History $history, Mutex $mutex, $isLoggedIn)
+ public function __construct(ConfigManager $conf, History $history, Mutex $mutex, bool $isLoggedIn)
{
$this->conf = $conf;
$this->history = $history;
/**
* @inheritDoc
*/
- public function findByHash($hash)
+ public function findByHash(string $hash): Bookmark
{
$bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash);
// PHP 7.3 introduced array_key_first() to avoid this hack
/**
* @inheritDoc
*/
- public function findByUrl($url)
+ public function findByUrl(string $url): ?Bookmark
{
return $this->bookmarks->getByUrl($url);
}
* @inheritDoc
*/
public function search(
- $request = [],
- $visibility = null,
- $caseSensitive = false,
- $untaggedOnly = false,
+ array $request = [],
+ string $visibility = null,
+ bool $caseSensitive = false,
+ bool $untaggedOnly = false,
bool $ignoreSticky = false
) {
if ($visibility === null) {
}
// Filter bookmark database according to parameters.
- $searchtags = isset($request['searchtags']) ? $request['searchtags'] : '';
- $searchterm = isset($request['searchterm']) ? $request['searchterm'] : '';
+ $searchTags = isset($request['searchtags']) ? $request['searchtags'] : '';
+ $searchTerm = isset($request['searchterm']) ? $request['searchterm'] : '';
if ($ignoreSticky) {
$this->bookmarks->reorder('DESC', true);
return $this->bookmarkFilter->filter(
BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
- [$searchtags, $searchterm],
+ [$searchTags, $searchTerm],
$caseSensitive,
$visibility,
$untaggedOnly
/**
* @inheritDoc
*/
- public function get($id, $visibility = null)
+ public function get(int $id, string $visibility = null): Bookmark
{
if (! isset($this->bookmarks[$id])) {
throw new BookmarkNotFoundException();
/**
* @inheritDoc
*/
- public function set($bookmark, $save = true)
+ public function set(Bookmark $bookmark, bool $save = true): Bookmark
{
if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore'));
}
- if (! $bookmark instanceof Bookmark) {
- throw new Exception(t('Provided data is invalid'));
- }
if (! isset($this->bookmarks[$bookmark->getId()])) {
throw new BookmarkNotFoundException();
}
$bookmark->validate();
- $bookmark->setUpdated(new \DateTime());
+ $bookmark->setUpdated(new DateTime());
$this->bookmarks[$bookmark->getId()] = $bookmark;
if ($save === true) {
$this->save();
/**
* @inheritDoc
*/
- public function add($bookmark, $save = true)
+ public function add(Bookmark $bookmark, bool $save = true): Bookmark
{
if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore'));
}
- if (! $bookmark instanceof Bookmark) {
- throw new Exception(t('Provided data is invalid'));
- }
- if (! empty($bookmark->getId())) {
+ if (!empty($bookmark->getId())) {
throw new Exception(t('This bookmarks already exists'));
}
$bookmark->setId($this->bookmarks->getNextId());
/**
* @inheritDoc
*/
- public function addOrSet($bookmark, $save = true)
+ public function addOrSet(Bookmark $bookmark, bool $save = true): Bookmark
{
if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore'));
}
- if (! $bookmark instanceof Bookmark) {
- throw new Exception('Provided data is invalid');
- }
if ($bookmark->getId() === null) {
return $this->add($bookmark, $save);
}
/**
* @inheritDoc
*/
- public function remove($bookmark, $save = true)
+ public function remove(Bookmark $bookmark, bool $save = true): void
{
if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore'));
}
- if (! $bookmark instanceof Bookmark) {
- throw new Exception(t('Provided data is invalid'));
- }
if (! isset($this->bookmarks[$bookmark->getId()])) {
throw new BookmarkNotFoundException();
}
/**
* @inheritDoc
*/
- public function exists($id, $visibility = null)
+ public function exists(int $id, string $visibility = null): bool
{
if (! isset($this->bookmarks[$id])) {
return false;
/**
* @inheritDoc
*/
- public function count($visibility = null)
+ public function count(string $visibility = null): int
{
return count($this->search([], $visibility));
}
/**
* @inheritDoc
*/
- public function save()
+ public function save(): void
{
if (true !== $this->isLoggedIn) {
// TODO: raise an Exception instead
/**
* @inheritDoc
*/
- public function bookmarksCountPerTag($filteringTags = [], $visibility = null)
+ public function bookmarksCountPerTag(array $filteringTags = [], string $visibility = null): array
{
$bookmarks = $this->search(['searchtags' => $filteringTags], $visibility);
$tags = [];
$keys = array_keys($tags);
$tmpTags = array_combine($keys, $keys);
array_multisort($tags, SORT_DESC, $tmpTags, SORT_ASC, $tags);
+
return $tags;
}
/**
* @inheritDoc
*/
- public function days()
+ public function days(): array
{
$bookmarkDays = [];
foreach ($this->search() as $bookmark) {
/**
* @inheritDoc
*/
- public function filterDay($request)
+ public function filterDay(string $request)
{
$visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC;
/**
* @inheritDoc
*/
- public function initialize()
+ public function initialize(): void
{
$initializer = new BookmarkInitializer($this);
$initializer->initialize();
/**
* Handles migration to the new database format (BookmarksArray).
*/
- protected function migrate()
+ protected function migrate(): void
{
$bookmarkDb = new LegacyLinkDB(
$this->conf->get('resource.datastore'),
<?php
+declare(strict_types=1);
+
namespace Shaarli\Bookmark;
use Exception;
*
* @throws BookmarkNotFoundException
*/
- public function filter($type, $request, $casesensitive = false, $visibility = 'all', $untaggedonly = false)
- {
+ public function filter(
+ string $type,
+ $request,
+ bool $casesensitive = false,
+ string $visibility = 'all',
+ bool $untaggedonly = false
+ ) {
if (!in_array($visibility, ['all', 'public', 'private'])) {
$visibility = 'all';
}
*
* @return Bookmark[] filtered bookmarks.
*/
- private function noFilter($visibility = 'all')
+ private function noFilter(string $visibility = 'all')
{
if ($visibility === 'all') {
return $this->bookmarks;
*
* @param string $smallHash permalink hash.
*
- * @return array $filtered array containing permalink data.
+ * @return Bookmark[] $filtered array containing permalink data.
*
- * @throws \Shaarli\Bookmark\Exception\BookmarkNotFoundException if the smallhash doesn't match any link.
+ * @throws BookmarkNotFoundException if the smallhash doesn't match any link.
*/
- private function filterSmallHash($smallHash)
+ private function filterSmallHash(string $smallHash)
{
foreach ($this->bookmarks as $key => $l) {
if ($smallHash == $l->getShortUrl()) {
* @param string $searchterms search query.
* @param string $visibility Optional: return only all/private/public bookmarks.
*
- * @return array search results.
+ * @return Bookmark[] search results.
*/
- private function filterFulltext($searchterms, $visibility = 'all')
+ private function filterFulltext(string $searchterms, string $visibility = 'all')
{
if (empty($searchterms)) {
return $this->noFilter($visibility);
*
* @return string generated regex fragment
*/
- private static function tag2regex($tag)
+ private static function tag2regex(string $tag): string
{
$len = strlen($tag);
if (!$len || $tag === "-" || $tag === "*") {
* You can specify one or more tags, separated by space or a comma, e.g.
* print_r($mydb->filterTags('linux programming'));
*
- * @param string $tags list of tags separated by commas or blank spaces.
- * @param bool $casesensitive ignore case if false.
- * @param string $visibility Optional: return only all/private/public bookmarks.
+ * @param string|array $tags list of tags, separated by commas or blank spaces if passed as string.
+ * @param bool $casesensitive ignore case if false.
+ * @param string $visibility Optional: return only all/private/public bookmarks.
*
- * @return array filtered bookmarks.
+ * @return Bookmark[] filtered bookmarks.
*/
- public function filterTags($tags, $casesensitive = false, $visibility = 'all')
+ public function filterTags($tags, bool $casesensitive = false, string $visibility = 'all')
{
// get single tags (we may get passed an array, even though the docs say different)
$inputTags = $tags;
*
* @param string $visibility return only all/private/public bookmarks.
*
- * @return array filtered bookmarks.
+ * @return Bookmark[] filtered bookmarks.
*/
- public function filterUntagged($visibility)
+ public function filterUntagged(string $visibility)
{
$filtered = [];
foreach ($this->bookmarks as $key => $link) {
* @param string $day day to filter.
* @param string $visibility return only all/private/public bookmarks.
- * @return array all link matching given day.
+ * @return Bookmark[] all link matching given day.
*
* @throws Exception if date format is invalid.
*/
- public function filterDay($day, $visibility)
+ public function filterDay(string $day, string $visibility)
{
if (!checkDateFormat('Ymd', $day)) {
throw new Exception('Invalid date format');
* @param string $tags string containing a list of tags.
* @param bool $casesensitive will convert everything to lowercase if false.
*
- * @return array filtered tags string.
+ * @return string[] filtered tags string.
*/
- public static function tagsStrToArray($tags, $casesensitive)
+ public static function tagsStrToArray(string $tags, bool $casesensitive): array
{
// We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
$tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8');
<?php
+declare(strict_types=1);
+
namespace Shaarli\Bookmark;
use malkusch\lock\mutex\Mutex;
/**
* Reads database from disk to memory
*
- * @return BookmarkArray instance
+ * @return Bookmark[]
*
* @throws NotWritableDataStoreException Data couldn't be loaded
* @throws EmptyDataStoreException Datastore file exists but does not contain any bookmark
/**
* Saves the database from memory to disk
*
- * @param BookmarkArray $links instance.
+ * @param Bookmark[] $links
*
* @throws NotWritableDataStoreException the datastore is not writable
*/
<?php
+declare(strict_types=1);
+
namespace Shaarli\Bookmark;
/**
*
* @param BookmarkServiceInterface $bookmarkService
*/
- public function __construct($bookmarkService)
+ public function __construct(BookmarkServiceInterface $bookmarkService)
{
$this->bookmarkService = $bookmarkService;
}
/**
* Initialize the data store with default bookmarks
*/
- public function initialize()
+ public function initialize(): void
{
$bookmark = new Bookmark();
$bookmark->setTitle('quicksilver (loop) on Vimeo ' . t('(private bookmark with thumbnail demo)'));
<?php
-namespace Shaarli\Bookmark;
+declare(strict_types=1);
+namespace Shaarli\Bookmark;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
* Class BookmarksService
*
* This is the entry point to manipulate the bookmark DB.
+ *
+ * Regarding return types of a list of bookmarks, it can either be an array or an ArrayAccess implementation,
+ * so until PHP 8.0 is the minimal supported version with union return types it cannot be explicitly added.
*/
interface BookmarkServiceInterface
{
*
* @param string $hash
*
- * @return mixed
+ * @return Bookmark
*
* @throws \Exception
*/
- public function findByHash($hash);
+ public function findByHash(string $hash): Bookmark;
/**
* @param $url
*
* @return Bookmark|null
*/
- public function findByUrl($url);
+ public function findByUrl(string $url): ?Bookmark;
/**
* Search bookmarks
*
- * @param mixed $request
- * @param string $visibility
- * @param bool $caseSensitive
- * @param bool $untaggedOnly
- * @param bool $ignoreSticky
+ * @param array $request
+ * @param ?string $visibility
+ * @param bool $caseSensitive
+ * @param bool $untaggedOnly
+ * @param bool $ignoreSticky
*
* @return Bookmark[]
*/
public function search(
- $request = [],
- $visibility = null,
- $caseSensitive = false,
- $untaggedOnly = false,
+ array $request = [],
+ string $visibility = null,
+ bool $caseSensitive = false,
+ bool $untaggedOnly = false,
bool $ignoreSticky = false
);
/**
* Get a single bookmark by its ID.
*
- * @param int $id Bookmark ID
- * @param string $visibility all|public|private e.g. with public, accessing a private bookmark will throw an
- * exception
+ * @param int $id Bookmark ID
+ * @param ?string $visibility all|public|private e.g. with public, accessing a private bookmark will throw an
+ * exception
*
* @return Bookmark
*
* @throws BookmarkNotFoundException
* @throws \Exception
*/
- public function get($id, $visibility = null);
+ public function get(int $id, string $visibility = null);
/**
* Updates an existing bookmark (depending on its ID).
* @throws BookmarkNotFoundException
* @throws \Exception
*/
- public function set($bookmark, $save = true);
+ public function set(Bookmark $bookmark, bool $save = true): Bookmark;
/**
* Adds a new bookmark (the ID must be empty).
*
* @throws \Exception
*/
- public function add($bookmark, $save = true);
+ public function add(Bookmark $bookmark, bool $save = true): Bookmark;
/**
* Adds or updates a bookmark depending on its ID:
*
* @throws \Exception
*/
- public function addOrSet($bookmark, $save = true);
+ public function addOrSet(Bookmark $bookmark, bool $save = true): Bookmark;
/**
* Deletes a bookmark.
*
* @throws \Exception
*/
- public function remove($bookmark, $save = true);
+ public function remove(Bookmark $bookmark, bool $save = true): void;
/**
* Get a single bookmark by its ID.
*
- * @param int $id Bookmark ID
- * @param string $visibility all|public|private e.g. with public, accessing a private bookmark will throw an
- * exception
+ * @param int $id Bookmark ID
+ * @param ?string $visibility all|public|private e.g. with public, accessing a private bookmark will throw an
+ * exception
*
* @return bool
*/
- public function exists($id, $visibility = null);
+ public function exists(int $id, string $visibility = null): bool;
/**
* Return the number of available bookmarks for given visibility.
*
- * @param string $visibility public|private|all
+ * @param ?string $visibility public|private|all
*
* @return int Number of bookmarks
*/
- public function count($visibility = null);
+ public function count(string $visibility = null): int;
/**
* Write the datastore.
*
* @throws NotWritableDataStoreException
*/
- public function save();
+ public function save(): void;
/**
* Returns the list tags appearing in the bookmarks with the given tags
*
- * @param array $filteringTags tags selecting the bookmarks to consider
- * @param string $visibility process only all/private/public bookmarks
+ * @param array|null $filteringTags tags selecting the bookmarks to consider
+ * @param string|null $visibility process only all/private/public bookmarks
*
* @return array tag => bookmarksCount
*/
- public function bookmarksCountPerTag($filteringTags = [], $visibility = 'all');
+ public function bookmarksCountPerTag(array $filteringTags = [], ?string $visibility = null): array;
/**
* Returns the list of days containing articles (oldest first)
*
* @return array containing days (in format YYYYMMDD).
*/
- public function days();
+ public function days(): array;
/**
* Returns the list of articles for a given day.
*
* @throws BookmarkNotFoundException
*/
- public function filterDay($request);
+ public function filterDay(string $request);
/**
* Creates the default database after a fresh install.
*/
- public function initialize();
+ public function initialize(): void;
}
}
// Optionally filter the results:
- $linksToDisplay = $this->linkDB->search($userInput, null, false, false, true);
+ $linksToDisplay = $this->linkDB->search($userInput ?? [], null, false, false, true);
$nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
}
try {
- $bookmark = $this->container->bookmarkService->get($id);
+ $bookmark = $this->container->bookmarkService->get((int) $id);
} catch (BookmarkNotFoundException $e) {
return $response->withStatus(404);
}
*
* @return true when the user is logged in, false otherwise
*/
- public function isLoggedIn()
+ public function isLoggedIn(): bool
{
if ($this->openShaarli) {
return true;
$this->assertEquals(History::CREATED, $actual['event']);
$this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
$this->assertEquals(1, $actual['id']);
-
- $history = new History(self::$historyFilePath);
- $bookmark = (new Bookmark())->setId('str');
- $history->addLink($bookmark);
- $actual = $history->getHistory()[0];
- $this->assertEquals(History::CREATED, $actual['event']);
- $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
- $this->assertEquals('str', $actual['id']);
}
// /**
$array['nope'] = $bookmark;
}
- /**
- * Test adding a bad entry: invalid ID type
- */
- public function testArrayAccessAddBadEntryIdType()
- {
- $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
-
- $array = new BookmarkArray();
- $bookmark = (new Bookmark())->setId('nope');
- $bookmark->validate();
- $array[] = $bookmark;
- }
-
/**
* Test adding a bad entry: ID/offset not consistent
*/
$this->publicLinkDB->add(new Bookmark());
}
- /**
- * Test add() method with an entry which is not a bookmark instance
- */
- public function testAddNotABookmark()
- {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('Provided data is invalid');
-
- $this->privateLinkDB->add(['title' => 'hi!']);
- }
-
/**
* Test add() method with a Bookmark already containing an ID
*/
$this->publicLinkDB->set(new Bookmark());
}
- /**
- * Test set() method with an entry which is not a bookmark instance
- */
- public function testSetNotABookmark()
- {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('Provided data is invalid');
-
- $this->privateLinkDB->set(['title' => 'hi!']);
- }
-
/**
* Test set() method with a Bookmark without an ID defined.
*/
$this->publicLinkDB->addOrSet(new Bookmark());
}
- /**
- * Test addOrSet() method with an entry which is not a bookmark instance
- */
- public function testAddOrSetNotABookmark()
- {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('Provided data is invalid');
-
- $this->privateLinkDB->addOrSet(['title' => 'hi!']);
- }
-
/**
* Test addOrSet() method for a bookmark without any field set and without writing the data store
*/
$this->publicLinkDB->remove($bookmark);
}
- /**
- * Test remove() method with an entry which is not a bookmark instance
- */
- public function testRemoveNotABookmark()
- {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('Provided data is invalid');
-
- $this->privateLinkDB->remove(['title' => 'hi!']);
- }
-
/**
* Test remove() method with a Bookmark with an unknown ID
*/
$this->assertContainsPolyfill('- ID: '. PHP_EOL, $exception->getMessage());
}
- /**
- * Test validate() with a a bookmark with a non integer ID.
- */
- public function testValidateNotValidStringId()
- {
- $bookmark = new Bookmark();
- $bookmark->setId('str');
- $bookmark->setShortUrl('abc');
- $bookmark->setCreated(\DateTime::createFromFormat('Ymd_His', '20190514_200102'));
- $exception = null;
- try {
- $bookmark->validate();
- } catch (InvalidBookmarkException $e) {
- $exception = $e;
- }
- $this->assertNotNull($exception);
- $this->assertContainsPolyfill('- ID: str'. PHP_EOL, $exception->getMessage());
- }
-
/**
* Test validate() with a a bookmark without short url.
*/
$this->assertContainsPolyfill('- Created: '. PHP_EOL, $exception->getMessage());
}
- /**
- * Test validate() with a a bookmark with a bad created datetime.
- */
- public function testValidateNotValidBadCreated()
- {
- $bookmark = new Bookmark();
- $bookmark->setId(1);
- $bookmark->setShortUrl('abc');
- $bookmark->setCreated('hi!');
- $exception = null;
- try {
- $bookmark->validate();
- } catch (InvalidBookmarkException $e) {
- $exception = $e;
- }
- $this->assertNotNull($exception);
- $this->assertContainsPolyfill('- Created: Not a DateTime object'. PHP_EOL, $exception->getMessage());
- }
-
/**
* Test setId() and make sure that default fields are generated.
*/
;
$response = new Response();
+ $this->container->bookmarkService->method('get')->with('123')->willReturn(
+ (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')
+ );
+
$this->container->formatterFactory = $this->createMock(FormatterFactory::class);
$this->container->formatterFactory
->expects(static::once())
$this->container->bookmarkService
->expects(static::once())
->method('addOrSet')
- ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void {
+ ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark {
static::assertFalse($save);
$checkBookmark($bookmark);
$bookmark->setId($id);
+
+ return $bookmark;
})
;
$this->container->bookmarkService
->expects(static::once())
->method('set')
- ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void {
+ ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark {
static::assertTrue($save);
$checkBookmark($bookmark);
static::assertSame($id, $bookmark->getId());
+
+ return $bookmark;
})
;
$this->container->bookmarkService
->expects(static::once())
->method('addOrSet')
- ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void {
+ ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark {
static::assertFalse($save);
$checkBookmark($bookmark);
+
+ return $bookmark;
})
;
$this->container->bookmarkService
->expects(static::once())
->method('set')
- ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void {
+ ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark {
static::assertTrue($save);
$checkBookmark($bookmark);
static::assertSame($id, $bookmark->getId());
+
+ return $bookmark;
})
;
$this->container->bookmarkService
->expects(static::once())
->method('addOrSet')
- ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): void {
+ ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): Bookmark {
static::assertSame($thumb, $bookmark->getThumbnail());
+
+ return $bookmark;
})
;
$this->container->bookmarkService
->expects(static::once())
->method('set')
- ->willReturnCallback(function (Bookmark $bookmark) use ($thumb) {
+ ->willReturnCallback(function (Bookmark $bookmark) use ($thumb): Bookmark {
static::assertSame($thumb, $bookmark->getThumbnail());
+
+ return $bookmark;
})
;