diff options
author | Sean Molenaar <sean@seanmolenaar.eu> | 2021-01-02 17:57:17 +0100 |
---|---|---|
committer | Sean Molenaar <SMillerDev@users.noreply.github.com> | 2021-02-13 13:22:57 +0100 |
commit | b4fa772bc5f23f84fc292f5d6bf884543d2bfe51 (patch) | |
tree | 8576ad3ea145f3644804e2fd93de462cfc2c2578 /lib/Service | |
parent | ceba81060303e49b2617397397f2804516052ec9 (diff) |
Remove V1 item API
Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
Diffstat (limited to 'lib/Service')
-rw-r--r-- | lib/Service/Exceptions/ServiceConflictException.php | 16 | ||||
-rw-r--r-- | lib/Service/Exceptions/ServiceException.php | 25 | ||||
-rw-r--r-- | lib/Service/Exceptions/ServiceNotFoundException.php | 17 | ||||
-rw-r--r-- | lib/Service/Exceptions/ServiceValidationException.php | 16 | ||||
-rw-r--r-- | lib/Service/FeedServiceV2.php | 20 | ||||
-rw-r--r-- | lib/Service/FolderServiceV2.php | 17 | ||||
-rw-r--r-- | lib/Service/ItemService.php | 352 | ||||
-rw-r--r-- | lib/Service/ItemServiceV2.php | 267 | ||||
-rw-r--r-- | lib/Service/Service.php | 12 |
9 files changed, 355 insertions, 387 deletions
diff --git a/lib/Service/Exceptions/ServiceConflictException.php b/lib/Service/Exceptions/ServiceConflictException.php index dd6ba03c9..ed3d3a54c 100644 --- a/lib/Service/Exceptions/ServiceConflictException.php +++ b/lib/Service/Exceptions/ServiceConflictException.php @@ -13,16 +13,22 @@ namespace OCA\News\Service\Exceptions; +use Exception; +use OCP\AppFramework\Db\IMapperException; + +/** + * Class ServiceConflictException + * + * @package OCA\News\Service\Exceptions + */ class ServiceConflictException extends ServiceException { /** - * Constructor - * - * @param string $msg the error message + * @inheritDoc */ - public function __construct(string $msg) + public static function from(IMapperException $exception): ServiceException { - parent::__construct($msg); + return new self($exception->getMessage(), $exception->getCode(), $exception); } } diff --git a/lib/Service/Exceptions/ServiceException.php b/lib/Service/Exceptions/ServiceException.php index c5ddddbd9..69b963ab6 100644 --- a/lib/Service/Exceptions/ServiceException.php +++ b/lib/Service/Exceptions/ServiceException.php @@ -13,16 +13,35 @@ namespace OCA\News\Service\Exceptions; -class ServiceException extends \Exception +use Exception; +use OCP\AppFramework\Db\IMapperException; + +/** + * Class ServiceException + * + * @package OCA\News\Service\Exceptions + */ +abstract class ServiceException extends Exception { /** * Constructor * * @param string $msg the error message + * @param int $code + * @param Exception|null $previous */ - public function __construct(string $msg) + final public function __construct(string $msg, int $code = 0, ?Exception $previous = null) { - parent::__construct($msg); + parent::__construct($msg, $code, $previous); } + + /** + * Create exception from Mapper exception. + * + * @param IMapperException|Exception $exception Existing exception + * + * @return static + */ + abstract public static function from(IMapperException $exception): ServiceException; } diff --git a/lib/Service/Exceptions/ServiceNotFoundException.php b/lib/Service/Exceptions/ServiceNotFoundException.php index 6c68ea6b2..f70706506 100644 --- a/lib/Service/Exceptions/ServiceNotFoundException.php +++ b/lib/Service/Exceptions/ServiceNotFoundException.php @@ -13,16 +13,21 @@ namespace OCA\News\Service\Exceptions; +use Exception; +use OCP\AppFramework\Db\IMapperException; + +/** + * Class ServiceNotFoundException + * + * @package OCA\News\Service\Exceptions + */ class ServiceNotFoundException extends ServiceException { - /** - * Constructor - * - * @param string $msg the error message + * @inheritDoc */ - public function __construct(string $msg) + public static function from(IMapperException $exception): ServiceException { - parent::__construct($msg); + return new self($exception->getMessage(), $exception->getCode(), $exception); } } diff --git a/lib/Service/Exceptions/ServiceValidationException.php b/lib/Service/Exceptions/ServiceValidationException.php index 8e9dc9fee..c41ce4aac 100644 --- a/lib/Service/Exceptions/ServiceValidationException.php +++ b/lib/Service/Exceptions/ServiceValidationException.php @@ -13,16 +13,22 @@ namespace OCA\News\Service\Exceptions; +use Exception; +use OCP\AppFramework\Db\IMapperException; + +/** + * Class ServiceValidationException + * + * @package OCA\News\Service\Exceptions + */ class ServiceValidationException extends ServiceException { /** - * Constructor - * - * @param string $msg the error message + * @inheritDoc */ - public function __construct(string $msg) + public static function from(IMapperException $exception): ServiceException { - parent::__construct($msg); + return new self($exception->getMessage(), $exception->getCode(), $exception); } } diff --git a/lib/Service/FeedServiceV2.php b/lib/Service/FeedServiceV2.php index 078941752..ccb7c047a 100644 --- a/lib/Service/FeedServiceV2.php +++ b/lib/Service/FeedServiceV2.php @@ -18,6 +18,7 @@ use FeedIo\Reader\ReadErrorException; use HTMLPurifier; use OCA\News\Db\FeedMapperV2; +use OCA\News\Db\Folder; use OCA\News\Fetcher\FeedFetcher; use OCA\News\Service\Exceptions\ServiceConflictException; use OCA\News\Service\Exceptions\ServiceNotFoundException; @@ -119,7 +120,7 @@ class FeedServiceV2 extends Service $feeds = $this->mapper->findAllFromUser($userId); foreach ($feeds as &$feed) { - $items = $this->itemService->findAllForFeed($feed->getId()); + $items = $this->itemService->findAllInFeed($userId, $feed->getId()); $feed->items = $items; } return $feeds; @@ -341,4 +342,21 @@ class FeedServiceV2 extends Service $this->fetch($feed); } } + + /** + * Mark a feed as read + * + * @param string $userId Feed owner + * @param int $id Feed ID + * @param int|null $maxItemID Highest item ID to mark as read + * + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function read(string $userId, int $id, ?int $maxItemID = null): void + { + $feed = $this->find($userId, $id); + + $this->mapper->read($userId, $feed->getId(), $maxItemID); + } } diff --git a/lib/Service/FolderServiceV2.php b/lib/Service/FolderServiceV2.php index ae8d37816..d13b4afc0 100644 --- a/lib/Service/FolderServiceV2.php +++ b/lib/Service/FolderServiceV2.php @@ -178,4 +178,21 @@ class FolderServiceV2 extends Service $folder->setOpened($open); return $this->mapper->update($folder); } + + /** + * Mark a folder as read + * + * @param string $userId Folder owner + * @param int $id Folder ID + * @param int|null $maxItemID Highest item ID to mark as read + * + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function read(string $userId, int $id, ?int $maxItemID = null): void + { + $folder = $this->find($userId, $id); + + $this->mapper->read($userId, $folder->getId(), $maxItemID); + } } diff --git a/lib/Service/ItemService.php b/lib/Service/ItemService.php deleted file mode 100644 index 8ba0a4b73..000000000 --- a/lib/Service/ItemService.php +++ /dev/null @@ -1,352 +0,0 @@ -<?php -/** - * Nextcloud - News - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Alessandro Cosentino <cosenal@gmail.com> - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @copyright 2012 Alessandro Cosentino - * @copyright 2012-2014 Bernhard Posselt - */ - -namespace OCA\News\Service; - -use OCA\News\AppInfo\Application; -use OCA\News\Db\ItemMapperV2; -use OCA\News\Service\Exceptions\ServiceNotFoundException; -use OCP\IConfig; -use OCP\AppFramework\Db\DoesNotExistException; - -use OCA\News\Db\ItemMapper; -use OCA\News\Db\FeedType; -use OCA\News\Utility\Time; -use Psr\Log\LoggerInterface; - -/** - * Class LegacyItemService - * - * @package OCA\News\Service - * @deprecated use ItemServiceV2 - */ -class ItemService extends Service -{ - - /** - * @var IConfig - */ - private $config; - /** - * @var Time - */ - private $timeFactory; - /** - * @var ItemMapper - */ - private $oldItemMapper; - - public function __construct( - ItemMapperV2 $itemMapper, - ItemMapper $oldItemMapper, - Time $timeFactory, - IConfig $config, - LoggerInterface $logger - ) { - parent::__construct($itemMapper, $logger); - $this->config = $config; - $this->timeFactory = $timeFactory; - $this->oldItemMapper = $oldItemMapper; - } - - - /** - * Returns all new items - * - * @param int|null $id the id of the feed, 0 for starred or all items - * @param int $type the type of the feed - * @param int $updatedSince a timestamp with the last modification date - * returns only items with a >= modified - * timestamp - * @param boolean $showAll if unread items should also be returned - * @param string $userId the name of the user - * - * @return array of items - */ - public function findAllNew(?int $id, $type, int $updatedSince, bool $showAll, string $userId) - { - switch ($type) { - case FeedType::FEED: - return $this->oldItemMapper->findAllNewFeed( - $id, - $updatedSince, - $showAll, - $userId - ); - case FeedType::FOLDER: - return $this->oldItemMapper->findAllNewFolder( - $id, - $updatedSince, - $showAll, - $userId - ); - default: - return $this->oldItemMapper->findAllNew( - $updatedSince, - $type, - $showAll, - $userId - ); - } - } - - - /** - * Returns all items - * - * @param int|null $id the id of the feed, 0 for starred or all items - * @param int $type the type of the feed - * @param int $limit how many items should be returned - * @param int $offset the offset - * @param boolean $showAll if unread items should also be returned - * @param boolean $oldestFirst if it should be ordered by oldest first - * @param string $userId the name of the user - * @param string[] $search an array of keywords that the result should - * contain in either the author, title, link - * or body - * - * @return array of items - */ - public function findAllItems( - ?int $id, - $type, - $limit, - $offset, - $showAll, - $oldestFirst, - $userId, - $search = [] - ) { - switch ($type) { - case FeedType::FEED: - return $this->oldItemMapper->findAllFeed( - $id, - $limit, - $offset, - $showAll, - $oldestFirst, - $userId, - $search - ); - case FeedType::FOLDER: - return $this->oldItemMapper->findAllFolder( - $id, - $limit, - $offset, - $showAll, - $oldestFirst, - $userId, - $search - ); - default: - return $this->oldItemMapper->findAllItems( - $limit, - $offset, - $type, - $showAll, - $oldestFirst, - $userId, - $search - ); - } - } - - public function findAllForUser(string $userId, array $params = []): array - { - return $this->mapper->findAllFromUser($userId, $params); - } - - - /** - * Star or unstar an item - * - * @param int $feedId the id of the item's feed that should be starred - * @param string $guidHash the guidHash of the item that should be starred - * @param boolean $isStarred if true the item will be marked as starred, - * if false unstar - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException if the item does not exist - * - * @return void - */ - public function star($feedId, $guidHash, $isStarred, $userId): void - { - try { - $item = $this->mapper->findByGuidHash($feedId, $guidHash); - - $item->setStarred($isStarred); - - $this->mapper->update($item); - } catch (DoesNotExistException $ex) { - throw new ServiceNotFoundException($ex->getMessage()); - } - } - - - /** - * Read or unread an item - * - * @param int $itemId the id of the item that should be read - * @param boolean $isRead if true the item will be marked as read, - * if false unread - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException if the item does not exist - * - * @return void - */ - public function read($itemId, $isRead, $userId): void - { - try { - $lastModified = $this->timeFactory->getMicroTime(); - $this->oldItemMapper->readItem($itemId, $isRead, $lastModified, $userId); - } catch (DoesNotExistException $ex) { - throw new ServiceNotFoundException($ex->getMessage()); - } - } - - - /** - * Set all items read - * - * @param int $highestItemId all items below that are marked read. This is - * used to prevent marking items as read that - * the users hasn't seen yet - * @param string $userId the name of the user - * - * @return void - */ - public function readAll($highestItemId, $userId): void - { - $time = $this->timeFactory->getMicroTime(); - $this->oldItemMapper->readAll($highestItemId, $time, $userId); - } - - - /** - * Set a folder read - * - * @param int|null $folderId the id of the folder that should be marked read - * @param int $highestItemId all items below that are marked read. This is - * used to prevent marking items as read that - * the users hasn't seen yet - * @param string $userId the name of the user - * - * @return void - */ - public function readFolder(?int $folderId, $highestItemId, $userId): void - { - $time = $this->timeFactory->getMicroTime(); - $this->oldItemMapper->readFolder( - $folderId, - $highestItemId, - $time, - $userId - ); - } - - - /** - * Set a feed read - * - * @param int $feedId the id of the feed that should be marked read - * @param int $highestItemId all items below that are marked read. This is - * used to prevent marking items as read that - * the users hasn't seen yet - * @param string $userId the name of the user - * - * @return void - */ - public function readFeed($feedId, $highestItemId, $userId): void - { - $time = $this->timeFactory->getMicroTime(); - $this->oldItemMapper->readFeed($feedId, $highestItemId, $time, $userId); - } - - - /** - * This method deletes all unread feeds that are not starred and over the - * count of $this->autoPurgeCount starting by the oldest. This is to clean - * up the database so that old entries don't spam your db. As criteria for - * old, the id is taken - * - * @return void - */ - public function autoPurgeOld(): void - { - $count = $this->config->getAppValue( - Application::NAME, - 'autoPurgeCount', - Application::DEFAULT_SETTINGS['autoPurgeCount'] - ); - if ($count >= 0) { - $this->oldItemMapper->deleteReadOlderThanThreshold($count); - } - } - - - /** - * Returns the newest item id, use this for marking feeds read - * - * @param string $userId the name of the user - * @throws ServiceNotFoundException if there is no newest item - * @return int - */ - public function getNewestItemId($userId) - { - try { - return $this->oldItemMapper->getNewestItemId($userId); - } catch (DoesNotExistException $ex) { - throw new ServiceNotFoundException($ex->getMessage()); - } - } - - - /** - * Returns the starred count - * - * @param string $userId the name of the user - * @return int the count - */ - public function starredCount($userId) - { - return $this->oldItemMapper->starredCount($userId); - } - - - /** - * @param string $userId from which user the items should be taken - * @return array of items which are starred or unread - */ - public function getUnreadOrStarred($userId): array - { - return $this->oldItemMapper->findAllUnreadOrStarred($userId); - } - - - /** - * Regenerates the search index for all items - * - * @return void - */ - public function generateSearchIndices(): void - { - $this->oldItemMapper->updateSearchIndices(); - } - - public function findAll(): array - { - return $this->mapper->findAll(); - } -} diff --git a/lib/Service/ItemServiceV2.php b/lib/Service/ItemServiceV2.php index f13b249b8..8a518b5bd 100644 --- a/lib/Service/ItemServiceV2.php +++ b/lib/Service/ItemServiceV2.php @@ -13,10 +13,16 @@ namespace OCA\News\Service; use OCA\News\AppInfo\Application; +use OCA\News\Db\Feed; +use OCA\News\Db\FeedType; use OCA\News\Db\Item; use OCA\News\Db\ItemMapperV2; +use OCA\News\Service\Exceptions\ServiceConflictException; +use OCA\News\Service\Exceptions\ServiceNotFoundException; +use OCA\News\Service\Exceptions\ServiceValidationException; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\IConfig; use Psr\Log\LoggerInterface; @@ -37,7 +43,7 @@ class ItemServiceV2 extends Service * ItemService constructor. * * @param ItemMapperV2 $mapper - * @param IConfig $config + * @param IConfig $config * @param LoggerInterface $logger */ public function __construct( @@ -53,7 +59,7 @@ class ItemServiceV2 extends Service * Finds all items of a user * * @param string $userId The ID/name of the user - * @param array $params Filter parameters + * @param array $params Filter parameters * * * @return Item[] @@ -83,14 +89,15 @@ class ItemServiceV2 extends Service public function insertOrUpdate(Item $item): Entity { try { - $db_item = $this->mapper->findByGuidHash($item->getFeedId(), $item->getGuidHash()); + $db_item = $this->findByGuidHash($item->getFeedId(), $item->getGuidHash()); // Transfer user modifications $item->setUnread($db_item->isUnread()) ->setStarred($db_item->isStarred()) ->setId($db_item->getId()); - $item->generateSearchIndex(); + $item->generateSearchIndex();//generates fingerprint + // We don't want to update the database record if there is no // change in the fetched item if ($db_item->getFingerprint() === $item->getFingerprint()) { @@ -104,13 +111,36 @@ class ItemServiceV2 extends Service } /** - * @param int $feedId + * Return all starred items * - * @return array + * @param string $userId + * + * @return Item[] */ - public function findAllForFeed(int $feedId): array + public function starred(string $userId): array { - return $this->mapper->findAllForFeed($feedId); + return $this->findAllForUser($userId, ['starred' => 1]); + } + + /** + * Mark an item as read + * + * @param string $userId Item owner + * @param int $id Item ID + * @param bool $read + * + * @return Item + * @throws ServiceNotFoundException + * @throws ServiceConflictException + */ + public function read(string $userId, int $id, bool $read): Entity + { + /** @var Item $item */ + $item = $this->find($userId, $id); + + $item->setUnread(!$read); + + return $this->mapper->update($item); } /** @@ -133,13 +163,232 @@ class ItemServiceV2 extends Service return $this->mapper->deleteOverThreshold($threshold, $removeUnread); } + /** + * Mark an item as starred + * + * @param string $userId Item owner + * @param int $id Item ID + * @param bool $starred + * + * @return Item + * @throws ServiceNotFoundException|ServiceConflictException + */ + public function star(string $userId, int $id, bool $starred): Entity + { + /** @var Item $item */ + $item = $this->find($userId, $id); + + $item->setStarred($starred); + + return $this->mapper->update($item); + } + + /** + * Mark an item as starred by GUID hash + * + * @param string $userId Item owner + * @param int $feedId Item ID + * @param string $guidHash + * @param bool $starred + * + * @return Item + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function starByGuid(string $userId, int $feedId, string $guidHash, bool $starred): Entity + { + try { + $item = $this->mapper->findForUserByGuidHash($userId, $feedId, $guidHash); + } catch (DoesNotExistException $ex) { + throw ServiceNotFoundException::from($ex); + } catch (MultipleObjectsReturnedException $ex) { + throw ServiceConflictException::from($ex); + } + + $item->setStarred($starred); + + return $this->mapper->update($item); + } + + /** + * Mark all items as read + * + * @param string $userId Item owner + * @param int $maxItemId + * + * @return void + */ + public function readAll(string $userId, int $maxItemId): void + { + $this->mapper->readAll($userId, $maxItemId); + } + + /** + * @param string $userId + * + * @return Item + */ + public function newest(string $userId): Entity + { + try { + return $this->mapper->newest($userId); + } catch (DoesNotExistException $e) { + throw ServiceNotFoundException::from($e); + } catch (MultipleObjectsReturnedException $e) { + throw ServiceConflictException::from($e); + } + } /** * @param int $feedId * @param string $guidHash + * + * @return Item|Entity + * + * @throws DoesNotExistException + * @throws MultipleObjectsReturnedException */ - public function findForGuidHash(int $feedId, string $guidHash) + public function findByGuidHash(int $feedId, string $guidHash): Entity { return $this->mapper->findByGuidHash($feedId, $guidHash); } + + /** + * Convenience method to find all items in a feed. + * + * @param string $userId + * @param int $feedId + * + * @return array + */ + public function findAllInFeed(string $userId, int $feedId): array + { + return $this->findAllInFeedAfter($userId, $feedId, PHP_INT_MIN, false); + } + + /** + * Returns all new items in a feed + * @param string $userId the name of the user + * @param int $feedId the id of the feed + * @param int $updatedSince a timestamp with the minimal modification date + * @param boolean $hideRead if unread items should also be returned + * + * @return array of items + */ + public function findAllInFeedAfter(string $userId, int $feedId, int $updatedSince, bool $hideRead): array + { + return $this->mapper->findAllInFeedAfter($userId, $feedId, $updatedSince, $hideRead); + } + + /** + * Returns all new items in a folder + * @param string $userId the name of the user + * @param int|null $folderId the id of the folder + * @param int $updatedSince a timestamp with the minimal modification date + * @param boolean $hideRead if unread items should also be returned + * + * @return array of items + */ + public function findAllInFolderAfter(string $userId, ?int $folderId, int $updatedSince, bool $hideRead): array + { + return $this->mapper->findAllInFolderAfter($userId, $folderId, $updatedSince, $hideRead); + } + + /** + * Returns all new items of a type + * + * @param string $userId the name of the user + * @param int $feedType the type of feed items to fetch. (starred || unread) + * @param int $updatedSince a timestamp with the minimal modification date + * + * @return array of items + * + * @throws ServiceValidationException + */ + public function findAllAfter(string $userId, int $feedType, int $updatedSince): array + { + if (!in_array($feedType, [FeedType::STARRED, FeedType::UNREAD])) { + throw new ServiceValidationException('Trying to find in unknown type'); + } + + return $this->mapper->findAllAfter($userId, $feedType, $updatedSince); + } + + + /** + * Returns all items + * + * @param int $feedId the id of the feed + * @param int $limit how many items should be returned + * @param int $offset the offset + * @param boolean $hideRead if unread items should also be returned + * @param boolean $oldestFirst if it should be ordered by oldest first + * @param string $userId the name of the user + * @param string[] $search an array of keywords that the result should + * contain in either the author, title, link + * or body + * + * @return array of items + */ + public function findAllInFeedWithFilters( + string $userId, + int $feedId, + int $limit, + int $offset, + bool $hideRead, + bool $oldestFirst, + array $search = [] + ): array { + return $this->mapper->findAllFeed($userId, $feedId, $limit, $offset, $hideRead, $oldestFirst, $search); + } + /** + * Returns all items + * + * @param int|null $folderId the id of the folder + * @param int $limit how many items should be returned + * @param int $offset the offset + * @param boolean $hideRead if unread items should also be returned + * @param boolean $oldestFirst if it should be ordered by oldest first + * @param string $userId the name of the user + * @param string[] $search an array of keywords that the result should + * contain in either the author, title, link + * or body + * + * @return array of items + */ + public function findAllInFolderWithFilters( + string $userId, + ?int $folderId, + int $limit, + int $offset, + bool $hideRead, + bool $oldestFirst, + array $search = [] + ): array { + return $this->mapper->findAllFolder($userId, $folderId, $limit, $offset, $hideRead, $oldestFirst, $search); + } + /** + * Returns all items + * + * @param int $type the type of the feed + * @param int $limit how many items should be returned + * @param int $offset the offset + * @param boolean $oldestFirst if it should be ordered by oldest first + * @param string $userId the name of the user + * @param string[] $search an array of keywords that the result should + * contain in either the author, title, link + * or body + * + * @return array of items + */ + public function findAllWithFilters( + string $userId, + int $type, + int $limit, + int $offset, + bool $oldestFirst, + array $search = [] + ): array { + return $this->mapper->findAllItems($userId, $type, $limit, $offset, $oldestFirst, $search); + } |