From 05377d023ef4d43818a4b42039c8143cb0f907e4 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sat, 26 Dec 2020 13:09:41 +0100 Subject: Remove PHPunit integration tests Signed-off-by: Sean Molenaar --- lib/Service/FeedService.php | 521 ---------------------------------------- lib/Service/FeedServiceV2.php | 122 +++++----- lib/Service/FolderServiceV2.php | 59 +---- lib/Service/ImportService.php | 125 ++++++++++ lib/Service/ItemService.php | 71 +++--- lib/Service/ItemServiceV2.php | 25 +- lib/Service/OpmlService.php | 7 - lib/Service/Service.php | 48 +++- lib/Service/StatusService.php | 5 +- 9 files changed, 292 insertions(+), 691 deletions(-) delete mode 100644 lib/Service/FeedService.php create mode 100644 lib/Service/ImportService.php (limited to 'lib/Service') diff --git a/lib/Service/FeedService.php b/lib/Service/FeedService.php deleted file mode 100644 index c671a035c..000000000 --- a/lib/Service/FeedService.php +++ /dev/null @@ -1,521 +0,0 @@ - - * @author Bernhard Posselt - * @copyright 2012 Alessandro Cosentino - * @copyright 2012-2014 Bernhard Posselt - */ - -namespace OCA\News\Service; - -use FeedIo\Reader\ReadErrorException; -use HTMLPurifier; - -use OCA\News\AppInfo\Application; -use OCP\IConfig; -use OCA\News\Service\Exceptions\ServiceConflictException; -use OCA\News\Service\Exceptions\ServiceNotFoundException; -use OCP\AppFramework\Db\Entity; -use OCP\IL10N; -use OCP\AppFramework\Db\DoesNotExistException; - -use OCA\News\Db\Feed; -use OCA\News\Db\Item; -use OCA\News\Db\FeedMapper; -use OCA\News\Db\ItemMapper; -use OCA\News\Fetcher\Fetcher; -use OCA\News\Utility\Time; -use Psr\Log\LoggerInterface; - -/** - * Class LegacyFeedService - * - * @package OCA\News\Service - * @deprecated use FeedServiceV2 - */ -class FeedService extends Service -{ - - private $feedFetcher; - private $itemMapper; - private $feedMapper; - private $l10n; - private $timeFactory; - private $autoPurgeMinimumInterval; - private $purifier; - private $loggerParams; - - public function __construct( - FeedMapper $legacyFeedMapper, - Fetcher $feedFetcher, - ItemMapper $legacyItemMapper, - LoggerInterface $logger, - IL10N $l10n, - Time $timeFactory, - IConfig $config, - HTMLPurifier $purifier - ) { - parent::__construct($legacyFeedMapper, $logger); - $this->feedFetcher = $feedFetcher; - $this->feedMapper = $legacyFeedMapper; - $this->itemMapper = $legacyItemMapper; - $this->logger = $logger; - $this->l10n = $l10n; - $this->timeFactory = $timeFactory; - $this->autoPurgeMinimumInterval = $config->getAppValue( - Application::NAME, - 'autoPurgeMinimumInterval', - Application::DEFAULT_SETTINGS['autoPurgeMinimumInterval'] - ); - $this->purifier = $purifier; - $this->loggerParams = ['app' => Application::NAME]; - } - - /** - * Finds all feeds of a user - * - * @param string $userId the name of the user - * - * @return Feed[] - */ - public function findAllForUser($userId, array $params = []): array - { - return $this->feedMapper->findAllFromUser($userId); - } - - - /** - * Finds all feeds from all users - * - * @return array of feeds - */ - public function findAllFromAllUsers() - { - return $this->findAll(); - } - - - /** - * Creates a new feed - * - * @param string $feedUrl the url to the feed - * @param int|null $folderId the folder where it should be put into, null for root - * folder - * @param string $userId for which user the feed should be created - * @param string|null $title if given, this is used for the opml feed title - * @param string|null $user if given, basic auth is set for this feed - * @param string|null $password if given, basic auth is set for this - * feed. Ignored if user is null or an empty string - * - * @return Feed the newly created feed - * @throws ServiceConflictException if the feed exists already - * @throws ServiceNotFoundException if the url points to an invalid feed - */ - public function create( - string $feedUrl, - ?int $folderId, - string $userId, - string $title = null, - string $user = null, - string $password = null - ) { - // first try if the feed exists already - try { - /** - * @var Feed $feed - * @var Item[] $items - */ - list($feed, $items) = $this->feedFetcher->fetch($feedUrl, true, null, false, $user, $password); - // try again if feed exists depending on the reported link - if ($feed === null) { - throw new ServiceNotFoundException($this->l10n->t('Can not add feed: Unable to parse feed')); - } - try { - $hash = $feed->getUrlHash(); - $this->feedMapper->findByUrlHash($hash, $userId); - throw new ServiceConflictException( - $this->l10n->t('Can not add feed: Exists already') - ); - } catch (DoesNotExistException $ex) { - // If no matching feed was found everything was ok - } - - // insert feed - $itemCount = count($items); - $feed->setBasicAuthUser($user); - $feed->setBasicAuthPassword($password); - $feed->setFolderId($folderId); - $feed->setUserId($userId); - $feed->setArticlesPerUpdate($itemCount); - - if (!empty($title)) { - $feed->setTitle($title); - } - - $feed = $this->feedMapper->insert($feed); - - // insert items in reverse order because the first one is usually - // the newest item - $unreadCount = 0; - foreach (array_reverse($items) as $item) { - $item->setFeedId($feed->getId()); - - // check if item exists (guidhash is the same) - // and ignore it if it does - try { - $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $item->getFeedId(), - $userId - ); - continue; - } catch (DoesNotExistException $ex) { - $unreadCount += 1; - $item->setBody($this->purifier->purify($item->getBody())); - $this->itemMapper->insert($item); - } - } - - // set unread count - $feed->setUnreadCount($unreadCount); - - return $feed; - } catch (ReadErrorException $ex) { - $this->logger->debug($ex->getMessage(), $this->loggerParams); - throw new ServiceNotFoundException($ex->getMessage()); - } - } - - - /** - * Runs all the feed updates - */ - public function updateAll() - { - // TODO: this method is not covered by any tests - $feeds = $this->feedMapper->findAll(); - foreach ($feeds as $feed) { - try { - $this->update($feed->getId(), $feed->getUserId()); - } catch (\Exception $ex) { - // something is really wrong here, log it - $this->logger->error( - 'Unexpected error when updating feed ' . $ex->getMessage(), - $this->loggerParams - ); - } - } - } - - - /** - * Updates a single feed - * - * @param string $userId the id of the user - * @param int $feedId the id of the feed that should be updated - * @param bool $forceUpdate update even if the article exists already - * - * @throws ServiceNotFoundException if the feed does not exist - * @return Feed the updated feed entity - */ - public function update(string $userId, int $feedId, $forceUpdate = false) - { - /** @var Feed $existingFeed */ - $existingFeed = $this->find($userId, $feedId); - - if ($existingFeed->getPreventUpdate() === true) { - return $existingFeed; - } - - // for backwards compability it can be that the location is not set - // yet, if so use the url - $location = $existingFeed->getLocation(); - if (!$location) { - $location = $existingFeed->getUrl(); - } - - try { - list($fetchedFeed, $items) = $this->feedFetcher->fetch( - $location, - false, - $existingFeed->getHttpLastModified(), - $existingFeed->getFullTextEnabled(), - $existingFeed->getBasicAuthUser(), - $existingFeed->getBasicAuthPassword() - ); - - // if there is no feed it means that no update took place - if (!$fetchedFeed) { - return $existingFeed; - } - - // update number of articles on every feed update - $itemCount = count($items); - - // this is needed to adjust to updates that add more items - // than when the feed was created. You can't update the count - // if it's lower because it may be due to the caching headers - // that were sent as the request and it might cause unwanted - // deletion and reappearing of feeds - if ($itemCount > $existingFeed->getArticlesPerUpdate()) { - $existingFeed->setArticlesPerUpdate($itemCount); - } - - $existingFeed->setHttpLastModified( - $fetchedFeed->getHttpLastModified() - ); - $existingFeed->setHttpEtag($fetchedFeed->getHttpEtag()); - $existingFeed->setLocation($fetchedFeed->getLocation()); - - // insert items in reverse order because the first one is - // usually the newest item - for ($i = $itemCount - 1; $i >= 0; $i--) { - $item = $items[$i]; - $item->setFeedId($existingFeed->getId()); - - try { - $dbItem = $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $feedId, - $userId - ); - - // in case of update - if ($forceUpdate - || $item->getUpdatedDate() > $dbItem->getUpdatedDate() - ) { - $dbItem->setTitle($item->getTitle()); - $dbItem->setUrl($item->getUrl()); - $dbItem->setAuthor($item->getAuthor()); - $dbItem->setSearchIndex($item->getSearchIndex()); - $dbItem->setRtl($item->getRtl()); - $dbItem->setLastModified($item->getLastModified()); - $dbItem->setPubDate($item->getPubDate()); - $dbItem->setUpdatedDate($item->getUpdatedDate()); - $dbItem->setEnclosureMime($item->getEnclosureMime()); - $dbItem->setEnclosureLink($item->getEnclosureLink()); - $dbItem->setBody( - $this->purifier->purify($item->getBody()) - ); - - // update modes: 0 nothing, 1 set unread - if ($existingFeed->getUpdateMode() === 1) { - $dbItem->setUnread(true); - } - - $this->itemMapper->update($dbItem); - } - } catch (DoesNotExistException $ex) { - $item->setBody( - $this->purifier->purify($item->getBody()) - ); - $this->itemMapper->insert($item); - } - } - - // mark feed as successfully updated - $existingFeed->setUpdateErrorCount(0); - $existingFeed->setLastUpdateError(''); - } catch (ReadErrorException $ex) { - $existingFeed->setUpdateErrorCount( - $existingFeed->getUpdateErrorCount() + 1 - ); - $existingFeed->setLastUpdateError($ex->getMessage()); - } - - $this->feedMapper->update($existingFeed); - - return $this->find($userId, $feedId); - } - - /** - * Import articles - * - * @param array $json the array with json - * @param string $userId the username - * - * @return Feed if one had to be created for nonexistent feeds - */ - public function importArticles($json, $userId) - { - $url = 'http://nextcloud/nofeed'; - $urlHash = md5($url); - - // build assoc array for fast access - $feeds = $this->findAllForUser($userId); - $feedsDict = []; - foreach ($feeds as $feed) { - $feedsDict[$feed->getLink()] = $feed; - } - - $createdFeed = false; - - // loop over all items and get the corresponding feed - // if the feed does not exist, create a separate feed for them - foreach ($json as $entry) { - $item = Item::fromImport($entry); - $feedLink = $entry['feedLink']; // this is not set on the item yet - - if (array_key_exists($feedLink, $feedsDict)) { - $feed = $feedsDict[$feedLink]; - $item->setFeedId($feed->getId()); - } elseif (array_key_exists($url, $feedsDict)) { - $feed = $feedsDict[$url]; - $item->setFeedId($feed->getId()); - } else { - $createdFeed = true; - $feed = new Feed(); - $feed->setUserId($userId); - $feed->setLink($url); - $feed->setUrl($url); - $feed->setTitle($this->l10n->t('Articles without feed')); - $feed->setAdded($this->timeFactory->getTime()); - $feed->setFolderId(null); - $feed->setPreventUpdate(true); - /** @var Feed $feed */ - $feed = $this->feedMapper->insert($feed); - - $item->setFeedId($feed->getId()); - $feedsDict[$feed->getLink()] = $feed; - } - - try { - // if item exists, copy the status - $existingItem = $this->itemMapper->findByGuidHash( - $item->getGuidHash(), - $feed->getId(), - $userId - ); - $existingItem->setStatus($item->getStatus()); - $this->itemMapper->update($existingItem); - } catch (DoesNotExistException $ex) { - $item->setBody($this->purifier->purify($item->getBody())); - $item->generateSearchIndex(); - $this->itemMapper->insert($item); - } - } - - if ($createdFeed) { - return $this->feedMapper->findByUrlHash($urlHash, $userId); - } - - return null; - } - - - /** - * Use this to mark a feed as deleted. That way it can be un-deleted - * - * @param int $feedId the id of the feed that should be deleted - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when feed does not exist - */ - public function markDeleted(int $feedId, string $userId) - { - $feed = $this->find($userId, $feedId); - $feed->setDeletedAt($this->timeFactory->getTime()); - $this->feedMapper->update($feed); - } - - - /** - * Use this to undo a feed deletion - * - * @param int $feedId the id of the feed that should be restored - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when feed does not exist - */ - public function unmarkDeleted(int $feedId, string $userId) - { - $feed = $this->find($userId, $feedId); - $feed->setDeletedAt(0); - $this->feedMapper->update($feed); - } - - - /** - * Deletes all deleted feeds - * - * @param string $userId if given it purges only feeds of that user - * @param boolean $useInterval defaults to true, if true it only purges - * entries in a given interval to give the user a chance to undo the - * deletion - */ - public function purgeDeleted($userId = null, $useInterval = true) - { - $deleteOlderThan = null; - - if ($useInterval) { - $now = $this->timeFactory->getTime(); - $deleteOlderThan = $now - $this->autoPurgeMinimumInterval; - } - - $toDelete = $this->feedMapper->getToDelete($deleteOlderThan, $userId); - - foreach ($toDelete as $feed) { - $this->feedMapper->delete($feed); - } - } - - - /** - * Deletes all feeds of a user, delete items first since the user_id - * is not defined in there - * - * @param string $userId the name of the user - */ - public function deleteUser($userId) - { - $this->feedMapper->deleteUser($userId); - } - - /** - * @param int $feedId ID of the feed. - * @param string $userId ID of the user. - * @param array $diff An array containing the fields to update, e.g.: - * - * [ - * 'ordering' => 1, - * 'fullTextEnabled' => true, - * 'pinned' => true, - * 'updateMode' => 0, - * 'title' => 'title' - * ] - * - * - * @throws ServiceNotFoundException if feed does not exist - * @return Feed The patched feed - */ - public function patch(int $feedId, string $userId, array $diff = []) - { - $feed = $this->find($userId, $feedId); - - foreach ($diff as $attribute => $value) { - $method = 'set' . ucfirst($attribute); - $feed->$method($value); - } - - // special feed updates - if (array_key_exists('fullTextEnabled', $diff)) { - // disable caching for the next update - $feed->setHttpEtag(''); - $feed->setHttpLastModified(0); - $this->feedMapper->update($feed); - return $this->update($userId, $feedId, true); - } - - return $this->feedMapper->update($feed); - } - - public function findAll(): array - { - return $this->feedMapper->findAll(); - } -} diff --git a/lib/Service/FeedServiceV2.php b/lib/Service/FeedServiceV2.php index 16402d0da..88f18a3bf 100644 --- a/lib/Service/FeedServiceV2.php +++ b/lib/Service/FeedServiceV2.php @@ -29,7 +29,6 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCA\News\Db\Feed; use OCA\News\Db\Item; -use OCA\News\Db\FeedMapper; use OCA\News\Db\ItemMapper; use OCA\News\Fetcher\Fetcher; use OCA\News\Config\Config; @@ -104,22 +103,6 @@ class FeedServiceV2 extends Service return $this->mapper->findAllFromUser($userId, $params); } - /** - * Finds a feed of a user - * - * @param string $userId the name of the user - * @param string $id the id of the feed - * - * @return Feed - * - * @throws DoesNotExistException - * @throws MultipleObjectsReturnedException - */ - public function findForUser(string $userId, string $id): Feed - { - return $this->mapper->findFromUser($userId, $id); - } - /** * @param int|null $id * @@ -139,6 +122,7 @@ class FeedServiceV2 extends Service */ public function findAllForUserRecursive(string $userId): array { + /** @var Feed[] $feeds */ $feeds = $this->mapper->findAllFromUser($userId); foreach ($feeds as &$feed) { @@ -167,12 +151,24 @@ class FeedServiceV2 extends Service * @return bool */ public function existsForUser(string $userID, string $url): bool + { + return $this->findByURL($userID, $url) !== null; + } + + /** + * Check if a feed exists for a user + * + * @param string $userID the name of the user + * @param string $url the feed URL + * + * @return Entity|Feed|null + */ + public function findByURL(string $userID, string $url): ?Entity { try { - $this->mapper->findByURL($userID, $url); - return true; + return $this->mapper->findByURL($userID, $url); } catch (DoesNotExistException $e) { - return false; + return null; } } @@ -274,58 +270,59 @@ class FeedServiceV2 extends Service $feed->getBasicAuthUser(), $feed->getBasicAuthPassword() ); + } catch (ReadErrorException $ex) { + $feed->setUpdateErrorCount($feed->getUpdateErrorCount() + 1); + $feed->setLastUpdateError($ex->getMessage()); - // if there is no feed it means that no update took place - if (!$fetchedFeed) { - return $feed; - } + return $this->mapper->update($feed); + } - // update number of articles on every feed update - $itemCount = count($items); + // if there is no feed it means that no update took place + if (!$fetchedFeed) { + return $feed; + } - // this is needed to adjust to updates that add more items - // than when the feed was created. You can't update the count - // if it's lower because it may be due to the caching headers - // that were sent as the request and it might cause unwanted - // deletion and reappearing of feeds - if ($itemCount > $feed->getArticlesPerUpdate()) { - $feed->setArticlesPerUpdate($itemCount); - } + // update number of articles on every feed update + $itemCount = count($items); - $feed->setHttpLastModified($fetchedFeed->getHttpLastModified()) - ->setHttpEtag($fetchedFeed->getHttpEtag()) - ->setLocation($fetchedFeed->getLocation()); + // this is needed to adjust to updates that add more items + // than when the feed was created. You can't update the count + // if it's lower because it may be due to the caching headers + // that were sent as the request and it might cause unwanted + // deletion and reappearing of feeds + if ($itemCount > $feed->getArticlesPerUpdate()) { + $feed->setArticlesPerUpdate($itemCount); + } - // insert items in reverse order because the first one is - // usually the newest item - for ($i = $itemCount - 1; $i >= 0; $i--) { - $item = $items[$i]; - $item->setFeedId($feed->getId()) - ->setBody($this->purifier->purify($item->getBody())); + $feed->setHttpLastModified($fetchedFeed->getHttpLastModified()) + ->setHttpEtag($fetchedFeed->getHttpEtag()) + ->setLocation($fetchedFeed->getLocation()); - // update modes: 0 nothing, 1 set unread - if ($feed->getUpdateMode() === 1) { - $item->setUnread(true); - } + foreach (array_reverse($items) as &$item) { + $item->setFeedId($feed->getId()) + ->setBody($this->purifier->purify($item->getBody())); - $this->itemService->insertOrUpdate($item); + // update modes: 0 nothing, 1 set unread + if ($feed->getUpdateMode() === Feed::UPDATE_MODE_NORMAL) { + $item->setUnread(true); } - // mark feed as successfully updated - $feed->setUpdateErrorCount(0); - $feed->setLastUpdateError(null); - } catch (ReadErrorException $ex) { - $feed->setUpdateErrorCount($feed->getUpdateErrorCount() + 1); - $feed->setLastUpdateError($ex->getMessage()); + $item = $this->itemService->insertOrUpdate($item); } - return $this->mapper->update($feed); - } - public function delete(string $user, int $id): void - { - $feed = $this->mapper->findFromUser($user, $id); - $this->mapper->delete($feed); + // mark feed as successfully updated + $feed->setUpdateErrorCount(0); + $feed->setLastUpdateError(null); + + $unreadCount = 0; + array_map(function (Item $item) use (&$unreadCount) { + if ($item->isUnread()) { + $unreadCount++; + } + }, $items); + + return $this->mapper->update($feed)->setUnreadCount($unreadCount); } /** @@ -341,6 +338,11 @@ class FeedServiceV2 extends Service $this->mapper->purgeDeleted($userID, $minTimestamp); } + /** + * Fetch all feeds. + * + * @see FeedServiceV2::fetch() + */ public function fetchAll(): void { foreach ($this->findAll() as $feed) { diff --git a/lib/Service/FolderServiceV2.php b/lib/Service/FolderServiceV2.php index ae04c8089..25903c17b 100644 --- a/lib/Service/FolderServiceV2.php +++ b/lib/Service/FolderServiceV2.php @@ -63,28 +63,6 @@ class FolderServiceV2 extends Service return $this->mapper->findAllFromUser($userId, $params); } - /** - * Finds a folder of a user - * - * @param string $userId The name/ID of the user - * @param int|null $folderId ID of the folder - * - * @return Folder - * - * @throws ServiceConflictException - * @throws ServiceNotFoundException - */ - public function findForUser(string $userId, ?int $folderId): Entity - { - try { - return $this->mapper->findFromUser($userId, $folderId); - } catch (DoesNotExistException $e) { - throw new ServiceNotFoundException('Folder not found'); - } catch (MultipleObjectsReturnedException $e) { - throw new ServiceConflictException('Multiple folders found'); - } - } - /** * Find all folders and it's feeds. * @@ -133,23 +111,6 @@ class FolderServiceV2 extends Service return $this->mapper->insert($folder); } - /** - * Delete a feed. - * - * @param string $userId Folder owner - * @param int $folderId Folder ID - * - * @return Folder - * @throws ServiceConflictException - * @throws ServiceNotFoundException - */ - public function delete(string $userId, int $folderId): Entity - { - $folder = $this->findForUser($userId, $folderId); - - return $this->mapper->delete($folder); - } - /** * Purge all deleted folders. * @@ -174,8 +135,9 @@ class FolderServiceV2 extends Service */ public function rename(string $userId, int $folderId, string $newName): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $folder->setName($newName); + return $this->mapper->update($folder); } @@ -192,7 +154,7 @@ class FolderServiceV2 extends Service */ public function markDelete(string $userId, int $folderId, bool $mark): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $time = $mark ? $this->timeFactory->getTime() : 0; $folder->setDeletedAt($time); @@ -212,21 +174,8 @@ class FolderServiceV2 extends Service */ public function open(string $userId, ?int $folderId, bool $open): Entity { - $folder = $this->findForUser($userId, $folderId); + $folder = $this->find($userId, $folderId); $folder->setOpened($open); return $this->mapper->update($folder); } - - /** - * Delete all folders of a user - * - * @param string $userId User ID/name - */ - public function deleteUser(string $userId): void - { - $folders = $this->findAllForUser($userId); - foreach ($folders as $folder) { - $this->mapper->delete($folder); - } - } } diff --git a/lib/Service/ImportService.php b/lib/Service/ImportService.php new file mode 100644 index 000000000..c3334fad2 --- /dev/null +++ b/lib/Service/ImportService.php @@ -0,0 +1,125 @@ + + * @author Bernhard Posselt + * @copyright 2012 Alessandro Cosentino + * @copyright 2012-2014 Bernhard Posselt + */ + +namespace OCA\News\Service; + +use \OCA\News\Db\Item; +use \OCA\News\Db\Feed; + +use \Psr\Log\LoggerInterface; +use \HTMLPurifier; + +/** + * Class ImportService + * + * @package OCA\News\Service + */ +class ImportService +{ + /** + * Items service. + * + * @var ItemServiceV2 + */ + protected $itemService; + /** + * Feeds service. + * + * @var FeedServiceV2 + */ + protected $feedService; + /** + * @var LoggerInterface + */ + protected $logger; + /** + * @var HTMLPurifier + */ + protected $purifier; + + /** + * FeedService constructor. + * + * @param FeedServiceV2 $feedService Service for feeds + * @param ItemServiceV2 $itemService Service to manage items + * @param HTMLPurifier $purifier HTML Purifier + * @param LoggerInterface $logger Logger + */ + public function __construct( + FeedServiceV2 $feedService, + ItemServiceV2 $itemService, + HTMLPurifier $purifier, + LoggerInterface $logger + ) { + $this->itemService = $itemService; + $this->feedService = $feedService; + $this->purifier = $purifier; + $this->logger = $logger; + } + + /** + * @param string $userId + * @param array $json + * + * @return array|null + */ + public function importArticles(string $userId, array $json) + { + $url = 'http://nextcloud/nofeed'; + + // build assoc array for fast access + $feeds = $this->feedService->findAllForUser($userId); + $feedsDict = []; + foreach ($feeds as $feed) { + $feedsDict[$feed->getLink()] = $feed; + } + + $createdFeed = false; + + // loop over all items and get the corresponding feed + // if the feed does not exist, create a separate feed for them + foreach ($json as $entry) { + $item = Item::fromImport($entry); + $feedLink = $entry['feedLink']; // this is not set on the item yet + + if (array_key_exists($feedLink, $feedsDict)) { + $feed = $feedsDict[$feedLink]; + } else { + $createdFeed = true; + $feed = new Feed(); + $feed->setUserId($userId) + ->setUrlHash(md5($url)) + ->setLink($url) + ->setUrl($url) + ->setTitle('Articles without feed') + ->setAdded(time()) + ->setFolderId(null) + ->setPreventUpdate(true); + + $feed = $this->feedService->insert($feed); + $feedsDict[$feed->getLink()] = $feed; + } + + $item->setFeedId($feed->getId()) + ->setBody($this->purifier->purify($item->getBody())) + ->generateSearchIndex(); + $this->itemService->insertOrUpdate($item); + } + + if (!$createdFeed) { + return null; + } + + return $this->feedService->findByURL($userId, $url); + } +} diff --git a/lib/Service/ItemService.php b/lib/Service/ItemService.php index ab5536137..1b459d49c 100644 --- a/lib/Service/ItemService.php +++ b/lib/Service/ItemService.php @@ -15,6 +15,7 @@ namespace OCA\News\Service; use OCA\News\AppInfo\Application; use OCA\News\Db\Item; +use OCA\News\Db\ItemMapperV2; use OCA\News\Service\Exceptions\ServiceNotFoundException; use OCP\AppFramework\Db\Entity; use OCP\IConfig; @@ -34,12 +35,22 @@ use Psr\Log\LoggerInterface; class ItemService extends Service { + /** + * @var IConfig + */ private $config; + /** + * @var Time + */ private $timeFactory; - private $itemMapper; + /** + * @var ItemMapper + */ + private $oldItemMapper; public function __construct( - ItemMapper $itemMapper, + ItemMapperV2 $itemMapper, + ItemMapper $oldItemMapper, Time $timeFactory, IConfig $config, LoggerInterface $logger @@ -47,7 +58,7 @@ class ItemService extends Service parent::__construct($itemMapper, $logger); $this->config = $config; $this->timeFactory = $timeFactory; - $this->itemMapper = $itemMapper; + $this->oldItemMapper = $oldItemMapper; } @@ -68,21 +79,21 @@ class ItemService extends Service { switch ($type) { case FeedType::FEED: - return $this->itemMapper->findAllNewFeed( + return $this->oldItemMapper->findAllNewFeed( $id, $updatedSince, $showAll, $userId ); case FeedType::FOLDER: - return $this->itemMapper->findAllNewFolder( + return $this->oldItemMapper->findAllNewFolder( $id, $updatedSince, $showAll, $userId ); default: - return $this->itemMapper->findAllNew( + return $this->oldItemMapper->findAllNew( $updatedSince, $type, $showAll, @@ -120,7 +131,7 @@ class ItemService extends Service ) { switch ($type) { case FeedType::FEED: - return $this->itemMapper->findAllFeed( + return $this->oldItemMapper->findAllFeed( $id, $limit, $offset, @@ -130,7 +141,7 @@ class ItemService extends Service $search ); case FeedType::FOLDER: - return $this->itemMapper->findAllFolder( + return $this->oldItemMapper->findAllFolder( $id, $limit, $offset, @@ -140,7 +151,7 @@ class ItemService extends Service $search ); default: - return $this->itemMapper->findAllItems( + return $this->oldItemMapper->findAllItems( $limit, $offset, $type, @@ -154,7 +165,7 @@ class ItemService extends Service public function findAllForUser(string $userId, array $params = []): array { - return $this->itemMapper->findAllFromUser($userId); + return $this->mapper->findAllFromUser($userId, $params); } @@ -171,18 +182,11 @@ class ItemService extends Service public function star($feedId, $guidHash, $isStarred, $userId) { try { - /** - * @var Item $item -*/ - $item = $this->itemMapper->findByGuidHash( - $guidHash, - $feedId, - $userId - ); + $item = $this->mapper->findByGuidHash($feedId, $guidHash); $item->setStarred($isStarred); - $this->itemMapper->update($item); + $this->mapper->update($item); } catch (DoesNotExistException $ex) { throw new ServiceNotFoundException($ex->getMessage()); } @@ -202,7 +206,7 @@ class ItemService extends Service { try { $lastModified = $this->timeFactory->getMicroTime(); - $this->itemMapper->readItem($itemId, $isRead, $lastModified, $userId); + $this->oldItemMapper->readItem($itemId, $isRead, $lastModified, $userId); } catch (DoesNotExistException $ex) { throw new ServiceNotFoundException($ex->getMessage()); } @@ -220,7 +224,7 @@ class ItemService extends Service public function readAll($highestItemId, $userId) { $time = $this->timeFactory->getMicroTime(); - $this->itemMapper->readAll($highestItemId, $time, $userId); + $this->oldItemMapper->readAll($highestItemId, $time, $userId); } @@ -236,7 +240,7 @@ class ItemService extends Service public function readFolder(?int $folderId, $highestItemId, $userId) { $time = $this->timeFactory->getMicroTime(); - $this->itemMapper->readFolder( + $this->oldItemMapper->readFolder( $folderId, $highestItemId, $time, @@ -257,7 +261,7 @@ class ItemService extends Service public function readFeed($feedId, $highestItemId, $userId) { $time = $this->timeFactory->getMicroTime(); - $this->itemMapper->readFeed($feedId, $highestItemId, $time, $userId); + $this->oldItemMapper->readFeed($feedId, $highestItemId, $time, $userId); } @@ -275,7 +279,7 @@ class ItemService extends Service Application::DEFAULT_SETTINGS['autoPurgeCount'] ); if ($count >= 0) { - $this->itemMapper->deleteReadOlderThanThreshold($count); + $this->oldItemMapper->deleteReadOlderThanThreshold($count); } } @@ -290,7 +294,7 @@ class ItemService extends Service public function getNewestItemId($userId) { try { - return $this->itemMapper->getNewestItemId($userId); + return $this->oldItemMapper->getNewestItemId($userId); } catch (DoesNotExistException $ex) { throw new ServiceNotFoundException($ex->getMessage()); } @@ -305,7 +309,7 @@ class ItemService extends Service */ public function starredCount($userId) { - return $this->itemMapper->starredCount($userId); + return $this->oldItemMapper->starredCount($userId); } @@ -315,18 +319,7 @@ class ItemService extends Service */ public function getUnreadOrStarred($userId) { - return $this->itemMapper->findAllUnreadOrStarred($userId); - } - - - /** - * Deletes all items of a user - * - * @param string $userId the name of the user - */ - public function deleteUser($userId) - { - $this->itemMapper->deleteUser($userId); + return $this->oldItemMapper->findAllUnreadOrStarred($userId); } @@ -335,7 +328,7 @@ class ItemService extends Service */ public function generateSearchIndices() { - $this->itemMapper->updateSearchIndices(); + $this->oldItemMapper->updateSearchIndices(); } public function findAll(): array diff --git a/lib/Service/ItemServiceV2.php b/lib/Service/ItemServiceV2.php index 0a04fd8ad..54cefa197 100644 --- a/lib/Service/ItemServiceV2.php +++ b/lib/Service/ItemServiceV2.php @@ -16,6 +16,7 @@ use OCA\News\AppInfo\Application; use OCA\News\Db\Item; use OCA\News\Db\ItemMapperV2; use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\Entity; use OCP\IConfig; use Psr\Log\LoggerInterface; @@ -76,8 +77,10 @@ class ItemServiceV2 extends Service * Insert an item or update. * * @param Item $item + * + * @return Entity|Item The updated/inserted item */ - public function insertOrUpdate(Item $item) + public function insertOrUpdate(Item $item): Entity { try { $db_item = $this->mapper->findByGuidHash($item->getFeedId(), $item->getGuidHash()); @@ -94,17 +97,24 @@ class ItemServiceV2 extends Service $item->resetUpdatedFields(); } - $this->mapper->update($item); + return $this->mapper->update($item); } catch (DoesNotExistException $exception) { - $this->mapper->insert($item); + return $this->mapper->insert($item); } } + /** + * @param int $feedId + * + * @return array + */ public function findAllForFeed(int $feedId): array { return $this->mapper->findAllForFeed($feedId); } + + public function purgeOverThreshold(int $threshold = null) { @@ -120,4 +130,13 @@ class ItemServiceV2 extends Service return $this->mapper->deleteOverThreshold($threshold); } + + /** + * @param int $feedId + * @param string $guidHash + */ + public function findForGuidHash(int $feedId, string $guidHash) + { + return $this->mapper->findByGuidHash($feedId, $guidHash); + } } diff --git a/lib/Service/OpmlService.php b/lib/Service/OpmlService.php index ea570cf68..932b5c9a5 100644 --- a/lib/Service/OpmlService.php +++ b/lib/Service/OpmlService.php @@ -29,11 +29,6 @@ class OpmlService */ private $feedService; - /** - * @var ItemService - */ - private $itemService; - /** * @var OPMLExporter */ @@ -42,12 +37,10 @@ class OpmlService public function __construct( FolderServiceV2 $folderService, FeedServiceV2 $feedService, - ItemServiceV2 $itemService, OPMLExporter $exporter ) { $this->folderService = $folderService; $this->feedService = $feedService; - $this->itemService = $itemService; $this->exporter = $exporter; } diff --git a/lib/Service/Service.php b/lib/Service/Service.php index 597a99647..ea7c3995d 100644 --- a/lib/Service/Service.php +++ b/lib/Service/Service.php @@ -43,7 +43,7 @@ abstract class Service * @param NewsMapperV2 $mapper * @param LoggerInterface $logger */ - public function __construct($mapper, LoggerInterface $logger) + public function __construct(NewsMapperV2 $mapper, LoggerInterface $logger) { $this->mapper = $mapper; $this->logger = $logger; @@ -76,11 +76,40 @@ abstract class Service * @throws ServiceNotFoundException if the entity does not exist, or there * are more than one of it */ - public function delete(string $userId, int $id) + public function delete(string $userId, int $id): Entity { $entity = $this->find($userId, $id); - $this->mapper->delete($entity); + return $this->mapper->delete($entity); + } + + + /** + * Insert an entity + * + * @param Entity $entity The entity to insert + * + * @return Entity The inserted entity + */ + public function insert(Entity $entity): Entity + { + return $this->mapper->insert($entity); + } + + + /** + * Update an entity + * + * @param string $userId the name of the user for security reasons + * @param Entity $entity the entity + * + * @throws ServiceNotFoundException if the entity does not exist, or there + * are more than one of it + */ + public function update(string $userId, Entity $entity): Entity + { + $this->find($userId, $entity->getId()); + return $this->mapper->update($entity); } @@ -104,4 +133,17 @@ abstract class Service throw new ServiceNotFoundException($ex->getMessage()); } } + + /** + * Delete all items of a user + * + * @param string $userId User ID/name + */ + public function deleteUser(string $userId): void + { + $items = $this->findAllForUser($userId); + foreach ($items as $item) { + $this->mapper->delete($item); + } + } } diff --git a/lib/Service/StatusService.php b/lib/Service/StatusService.php index f46624cd0..d33d99bad 100644 --- a/lib/Service/StatusService.php +++ b/lib/Service/StatusService.php @@ -28,12 +28,11 @@ class StatusService public function __construct( IConfig $settings, - IDBConnection $connection, - string $AppName + IDBConnection $connection ) { $this->settings = $settings; - $this->appName = $AppName; $this->connection = $connection; + $this->appName = Application::NAME; } /** -- cgit v1.2.3