diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Controller/FeedController.php | 22 | ||||
-rw-r--r-- | lib/Controller/FolderController.php | 61 | ||||
-rw-r--r-- | lib/Cron/UpdaterJob.php | 2 | ||||
-rw-r--r-- | lib/Db/FolderMapper.php | 143 | ||||
-rw-r--r-- | lib/Db/FolderMapperV2.php | 14 | ||||
-rw-r--r-- | lib/Hooks/UserDeleteHook.php | 4 | ||||
-rw-r--r-- | lib/Service/FolderService.php | 227 | ||||
-rw-r--r-- | lib/Service/FolderServiceV2.php | 139 | ||||
-rw-r--r-- | lib/Service/Service.php | 4 | ||||
-rw-r--r-- | lib/Service/StatusService.php | 16 | ||||
-rw-r--r-- | lib/Service/UpdaterService.php | 4 |
11 files changed, 201 insertions, 435 deletions
diff --git a/lib/Controller/FeedController.php b/lib/Controller/FeedController.php index 5e2ba8a96..76f777a12 100644 --- a/lib/Controller/FeedController.php +++ b/lib/Controller/FeedController.php @@ -15,6 +15,7 @@ namespace OCA\News\Controller; use OCA\News\Service\Exceptions\ServiceConflictException; use OCA\News\Service\Exceptions\ServiceNotFoundException; +use OCA\News\Service\FolderServiceV2; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; use OCP\IConfig; @@ -23,8 +24,9 @@ use OCP\AppFramework\Http; use OCA\News\Service\ItemService; use OCA\News\Service\FeedService; -use OCA\News\Service\FolderService; use OCA\News\Db\FeedType; +use OCP\IUser; +use OCP\IUserSession; class FeedController extends Controller { @@ -33,27 +35,29 @@ class FeedController extends Controller //TODO: Remove private $feedService; //TODO: Remove - private $folderService; - //TODO: Remove private $itemService; + /** + * @var FolderServiceV2 + */ + private $folderService; private $userId; private $settings; public function __construct( string $appName, IRequest $request, - FolderService $folderService, + FolderServiceV2 $folderService, FeedService $feedService, ItemService $itemService, IConfig $settings, - string $UserId + IUser $user ) { parent::__construct($appName, $request); - $this->feedService = $feedService; $this->folderService = $folderService; - $this->itemService = $itemService; - $this->userId = $UserId; - $this->settings = $settings; + $this->feedService = $feedService; + $this->itemService = $itemService; + $this->settings = $settings; + $this->userId = $user->getUID(); } diff --git a/lib/Controller/FolderController.php b/lib/Controller/FolderController.php index e67299c6d..662d45029 100644 --- a/lib/Controller/FolderController.php +++ b/lib/Controller/FolderController.php @@ -19,18 +19,20 @@ use \OCP\IRequest; use \OCP\AppFramework\Controller; use \OCP\AppFramework\Http; -use \OCA\News\Service\FolderService; +use \OCA\News\Service\FolderServiceV2; use \OCA\News\Service\FeedService; use \OCA\News\Service\ItemService; use \OCA\News\Service\Exceptions\ServiceNotFoundException; use \OCA\News\Service\Exceptions\ServiceConflictException; -use \OCA\News\Service\Exceptions\ServiceValidationException; +use OCP\IUser; class FolderController extends Controller { - use JSONHttpErrorTrait; + use JSONHttpErrorTrait, ApiPayloadTrait; - //TODO: Remove + /** + * @var FolderServiceV2 + */ private $folderService; //TODO: Remove private $feedService; @@ -41,16 +43,16 @@ class FolderController extends Controller public function __construct( string $appName, IRequest $request, - FolderService $folderService, + FolderServiceV2 $folderService, FeedService $feedService, ItemService $itemService, - $UserId + IUser $user ) { parent::__construct($appName, $request); $this->folderService = $folderService; $this->feedService = $feedService; $this->itemService = $itemService; - $this->userId = $UserId; + $this->userId = $user->getUID(); } @@ -60,7 +62,7 @@ class FolderController extends Controller public function index() { $folders = $this->folderService->findAllForUser($this->userId); - return ['folders' => $folders]; + return ['folders' => $this->serialize($folders)]; } @@ -77,7 +79,7 @@ class FolderController extends Controller $folderId = $folderId === 0 ? null : $folderId; try { - $this->folderService->open($folderId, $open, $this->userId); + $this->folderService->open($this->userId, $folderId, $open); } catch (ServiceException $ex) { return $this->error($ex, Http::STATUS_NOT_FOUND); } @@ -89,24 +91,17 @@ class FolderController extends Controller /** * @NoAdminRequired * - * @param string $folderName + * @param string $folderName + * @param int|null $parent * * @return array|JSONResponse */ - public function create(string $folderName) + public function create(string $folderName, ?int $parent = null) { - try { - // we need to purge deleted folders if a folder is created to - // prevent already exists exceptions - $this->folderService->purgeDeleted($this->userId, false); - $folder = $this->folderService->create($folderName, $this->userId); + $this->folderService->purgeDeleted(); + $folder = $this->folderService->create($this->userId, $folderName, $parent); - return ['folders' => [$folder]]; - } catch (ServiceConflictException $ex) { - return $this->error($ex, Http::STATUS_CONFLICT); - } catch (ServiceValidationException $ex) { - return $this->error($ex, Http::STATUS_UNPROCESSABLE_ENTITY); - } + return ['folders' => $this->serialize($folder)]; } @@ -123,9 +118,11 @@ class FolderController extends Controller return new JSONResponse([], Http::STATUS_BAD_REQUEST); } try { - $this->folderService->markDeleted($folderId, $this->userId); + $this->folderService->markDelete($this->userId, $folderId, true); } catch (ServiceNotFoundException $ex) { return $this->error($ex, Http::STATUS_NOT_FOUND); + } catch (ServiceConflictException $ex) { + return $this->error($ex, Http::STATUS_CONFLICT); } return []; @@ -146,17 +143,11 @@ class FolderController extends Controller return new JSONResponse([], Http::STATUS_BAD_REQUEST); } try { - $folder = $this->folderService->rename( - $folderId, - $folderName, - $this->userId - ); + $folder = $this->folderService->rename($this->userId, $folderId, $folderName); - return ['folders' => [$folder]]; + return ['folders' => $this->serialize($folder)]; } catch (ServiceConflictException $ex) { return $this->error($ex, Http::STATUS_CONFLICT); - } catch (ServiceValidationException $ex) { - return $this->error($ex, Http::STATUS_UNPROCESSABLE_ENTITY); } catch (ServiceNotFoundException $ex) { return $this->error($ex, Http::STATUS_NOT_FOUND); } @@ -179,8 +170,8 @@ class FolderController extends Controller $highestItemId, $this->userId ); - - return ['feeds' => $this->feedService->findAllForUser($this->userId)]; + $feeds = $this->feedService->findAllForUser($this->userId); + return ['feeds' => $this->serialize($feeds)]; } @@ -196,9 +187,11 @@ class FolderController extends Controller $folderId = $folderId === 0 ? null : $folderId; try { - $this->folderService->unmarkDeleted($folderId, $this->userId); + $this->folderService->markDelete($this->userId, $folderId, false); } catch (ServiceNotFoundException $ex) { return $this->error($ex, Http::STATUS_NOT_FOUND); + } catch (ServiceConflictException $ex) { + return $this->error($ex, Http::STATUS_CONFLICT); } return []; diff --git a/lib/Cron/UpdaterJob.php b/lib/Cron/UpdaterJob.php index d2dbde149..bec1c3579 100644 --- a/lib/Cron/UpdaterJob.php +++ b/lib/Cron/UpdaterJob.php @@ -60,7 +60,7 @@ class UpdaterJob extends TimedJob Application::DEFAULT_SETTINGS['useCronUpdates'] ); - if (!$uses_cron || !$this->statusService->isProperlyConfigured()) { + if (!$uses_cron || !$this->statusService->isCronProperlyConfigured()) { return; } diff --git a/lib/Db/FolderMapper.php b/lib/Db/FolderMapper.php deleted file mode 100644 index 75b749974..000000000 --- a/lib/Db/FolderMapper.php +++ /dev/null @@ -1,143 +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\Db; - -use OCA\News\Utility\Time; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\MultipleObjectsReturnedException; -use OCP\IDBConnection; -use OCP\AppFramework\Db\Entity; - -/** - * Class LegacyFolderMapper - * - * @package OCA\News\Db - * @deprecated use FolderMapper - */ -class FolderMapper extends NewsMapper -{ - - const TABLE_NAME = 'news_folders'; - - public function __construct(IDBConnection $db, Time $time) - { - parent::__construct($db, $time, Folder::class); - } - - public function find(string $userId, int $id) - { - $sql = 'SELECT * FROM `*PREFIX*news_folders` ' . - 'WHERE `id` = ? ' . - 'AND `user_id` = ?'; - - return $this->findEntity($sql, [$id, $userId]); - } - - - public function findAllFromUser(string $userId): array - { - $sql = 'SELECT * FROM `*PREFIX*news_folders` ' . - 'WHERE `user_id` = ? ' . - 'AND `deleted_at` = 0'; - $params = [$userId]; - - return $this->findEntities($sql, $params); - } - - - public function findByName(string $folderName, string $userId) - { - $sql = 'SELECT * FROM `*PREFIX*news_folders` ' . - 'WHERE `name` = ? ' . - 'AND `user_id` = ?'; - $params = [$folderName, $userId]; - - return $this->findEntities($sql, $params); - } - - - public function delete(Entity $entity): Entity - { - parent::delete($entity); - - // someone please slap me for doing this manually :P - // we needz CASCADE + FKs please - $sql = 'DELETE FROM `*PREFIX*news_feeds` WHERE `folder_id` = ?'; - $params = [$entity->getId()]; - $stmt = $this->execute($sql, $params); - $stmt->closeCursor(); - - $sql = 'DELETE FROM `*PREFIX*news_items` WHERE `feed_id` NOT IN ' . - '(SELECT `feeds`.`id` FROM `*PREFIX*news_feeds` `feeds`)'; - - $stmt = $this->execute($sql); - $stmt->closeCursor(); - - return $entity; - } - - - /** - * @param int $deleteOlderThan if given gets all entries with a delete date - * older than that timestamp - * @param string $userId if given returns only entries from the given user - * @return array with the database rows - */ - public function getToDelete($deleteOlderThan = null, $userId = null) - { - $sql = 'SELECT * FROM `*PREFIX*news_folders` ' . - 'WHERE `deleted_at` > 0 '; - $params = []; - - // sometimes we want to delete all entries - if ($deleteOlderThan !== null) { - $sql .= 'AND `deleted_at` < ? '; - $params[] = $deleteOlderThan; - } - - // we need to sometimes only delete feeds of a user - if ($userId !== null) { - $sql .= 'AND `user_id` = ?'; - $params[] = $userId; - } - - return $this->findEntities($sql, $params); - } - - - /** - * Deletes all folders of a user - * - * @param string $userId the name of the user - */ - public function deleteUser(string $userId) - { - $sql = 'DELETE FROM `*PREFIX*news_folders` WHERE `user_id` = ?'; - $this->execute($sql, [$userId]); - } - - /** - * NO-OP - * @return array - */ - public function findAll(): array - { - return []; - } - - public function findFromUser(string $userId, int $id): Entity - { - return $this->find($id, $userId); - } -} diff --git a/lib/Db/FolderMapperV2.php b/lib/Db/FolderMapperV2.php index c2b172870..a69f8be45 100644 --- a/lib/Db/FolderMapperV2.php +++ b/lib/Db/FolderMapperV2.php @@ -43,7 +43,7 @@ class FolderMapperV2 extends NewsMapperV2 * @param string $userId The user identifier * @param array $params Filter parameters * - * @return Entity[] + * @return Folder[] */ public function findAllFromUser(string $userId, array $params = []): array { @@ -60,7 +60,7 @@ class FolderMapperV2 extends NewsMapperV2 /** * Find all items * - * @return Entity[] + * @return Folder[] */ public function findAll(): array { @@ -72,6 +72,16 @@ class FolderMapperV2 extends NewsMapperV2 return $this->findEntities($builder); } + /** + * Find a single feed for a user + * + * @param string $userId The user identifier + * @param int $id The feed ID + * + * @return Folder + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + */ public function findFromUser(string $userId, int $id): Entity { $builder = $this->db->getQueryBuilder(); diff --git a/lib/Hooks/UserDeleteHook.php b/lib/Hooks/UserDeleteHook.php index 491f84fcb..128e6fa79 100644 --- a/lib/Hooks/UserDeleteHook.php +++ b/lib/Hooks/UserDeleteHook.php @@ -16,7 +16,7 @@ namespace OCA\News\Hooks; use OCA\News\AppInfo\Application; use OCA\News\Service\ItemService; use OCA\News\Service\FeedService; -use OCA\News\Service\FolderService; +use OCA\News\Service\FolderServiceV2; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\User\Events\BeforeUserDeletedEvent; @@ -39,6 +39,6 @@ class UserDeleteHook implements IEventListener // order is important! $container->get(ItemService::class)->deleteUser($userId); $container->get(FeedService::class)->deleteUser($userId); - $container->get(FolderService::class)->deleteUser($userId); + $container->get(FolderServiceV2::class)->deleteUser($userId); } } diff --git a/lib/Service/FolderService.php b/lib/Service/FolderService.php deleted file mode 100644 index db060b050..000000000 --- a/lib/Service/FolderService.php +++ /dev/null @@ -1,227 +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 OCP\IConfig; -use OCA\News\Service\Exceptions\ServiceConflictException; -use OCA\News\Service\Exceptions\ServiceException; -use OCA\News\Service\Exceptions\ServiceNotFoundException; -use OCA\News\Service\Exceptions\ServiceValidationException; -use OCP\AppFramework\Db\Entity; -use OCP\IL10N; -use OCA\News\Db\Folder; -use OCA\News\Db\FolderMapper; -use OCA\News\Utility\Time; -use Psr\Log\LoggerInterface; - -/** - * Class LegacyFolderService - * - * @package OCA\News\Service - * @deprecated use FolderServiceV2 - */ -class FolderService extends Service -{ - - private $l10n; - private $timeFactory; - private $autoPurgeMinimumInterval; - private $folderMapper; - - public function __construct( - FolderMapper $folderMapper, - IL10N $l10n, - Time $timeFactory, - IConfig $config, - LoggerInterface $logger - ) { - parent::__construct($folderMapper, $logger); - $this->l10n = $l10n; - $this->timeFactory = $timeFactory; - $this->folderMapper = $folderMapper; - $this->autoPurgeMinimumInterval = $config->getAppValue( - Application::NAME, - 'autoPurgeMinimumInterval', - Application::DEFAULT_SETTINGS['autoPurgeMinimumInterval'] - ); - } - - /** - * Finds all folders of a user - * - * @param string $userId the name of the user - * - * @return Folder[] - */ - public function findAllForUser(string $userId, array $params = []): array - { - return $this->folderMapper->findAllFromUser($userId); - } - - - private function validateFolder(string $folderName, string $userId) - { - $existingFolders - = $this->folderMapper->findByName($folderName, $userId); - if (count($existingFolders) > 0) { - throw new ServiceConflictException( - $this->l10n->t('Can not add folder: Exists already') - ); - } - - if (mb_strlen($folderName) === 0) { - throw new ServiceValidationException( - 'Folder name can not be empty' - ); - } - } - - - /** - * Creates a new folder - * - * @param string $folderName the name of the folder - * @param string $userId the name of the user for whom it should be created - * @param int $parentId the parent folder id, deprecated we don't nest - * folders - * - * @return Folder|Entity the newly created folder - * @throws ServiceValidationException if the folder has invalid parameters - * @throws ServiceConflictException if name exists already - */ - public function create(string $folderName, string $userId, ?int $parentId = null) - { - $this->validateFolder($folderName, $userId); - - $folder = new Folder(); - $folder->setName($folderName) - ->setUserId($userId) - ->setParentId($parentId) - ->setOpened(true); - - return $this->folderMapper->insert($folder); - } - - - /** - * @param int|null $folderId - * @param bool $opened - * @param string $userId - * - * @throws ServiceNotFoundException - */ - public function open(?int $folderId, bool $opened, string $userId) - { - $folder = $this->find($userId, $folderId); - $folder->setOpened($opened); - $this->folderMapper->update($folder); - } - - - /** - * Renames a folder - * - * @param int $folderId the id of the folder that should be deleted - * @param string $folderName the new name of the folder - * @param string $userId the name of the user for security reasons - * - * @return Folder the updated folder - * @throws ServiceValidationException if the folder has invalid parameters - * @throws ServiceNotFoundException if the folder does not exist - * @throws ServiceConflictException if name exists already - */ - public function rename(int $folderId, string $folderName, string $userId) - { - $this->validateFolder($folderName, $userId); - - $folder = $this->find($userId, $folderId); - $folder->setName($folderName); - - return $this->folderMapper->update($folder); - } - - - /** - * Use this to mark a folder as deleted. That way it can be un-deleted - * - * @param int $folderId the id of the folder that should be deleted - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when folder does not exist - */ - public function markDeleted(int $folderId, string $userId) - { - $folder = $this->find($userId, $folderId); - $folder->setDeletedAt($this->timeFactory->getTime()); - $this->folderMapper->update($folder); - } - - - /** - * Use this to restore a folder - * - * @param int $folderId the id of the folder that should be restored - * @param string $userId the name of the user for security reasons - * - * @throws ServiceNotFoundException when folder does not exist - */ - public function unmarkDeleted(int $folderId, string $userId) - { - $folder = $this->find($userId, $folderId); - $folder->setDeletedAt(0); - $this->folderMapper->update($folder); - } - - - /** - * Deletes all deleted folders - * - * @param ?string $userId if given it purges only folders 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(?string $userId = null, bool $useInterval = true) - { - $deleteOlderThan = null; - - if ($useInterval) { - $now = $this->timeFactory->getTime(); - $deleteOlderThan = $now - $this->autoPurgeMinimumInterval; - } - - $toDelete = $this->folderMapper->getToDelete($deleteOlderThan, $userId); - - foreach ($toDelete as $folder) { - $this->folderMapper->delete($folder); - } - } - - - /** - * Deletes all folders of a user - * - * @param string $userId the name of the user - */ - public function deleteUser(string $userId) - { - $this->folderMapper->deleteUser($userId); - } - - public function findAll(): array - { - return $this->mapper->findAll(); - } -} diff --git a/lib/Service/FolderServiceV2.php b/lib/Service/FolderServiceV2.php index ee24addfd..95761b530 100644 --- a/lib/Service/FolderServiceV2.php +++ b/lib/Service/FolderServiceV2.php @@ -13,11 +13,14 @@ namespace OCA\News\Service; -use OCA\News\Db\Feed; -use OCA\News\Db\FeedMapperV2; +use OC\AppFramework\Utility\TimeFactory; use OCA\News\Db\Folder; use OCA\News\Db\FolderMapperV2; +use OCA\News\Service\Exceptions\ServiceConflictException; +use OCA\News\Service\Exceptions\ServiceNotFoundException; +use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; use Psr\Log\LoggerInterface; /** @@ -31,14 +34,20 @@ class FolderServiceV2 extends Service * @var FeedServiceV2 */ private $feedService; + /** + * @var FeedServiceV2 + */ + private $timeFactory; public function __construct( FolderMapperV2 $mapper, FeedServiceV2 $feedService, + TimeFactory $timeFactory, LoggerInterface $logger ) { parent::__construct($mapper, $logger); $this->feedService = $feedService; + $this->timeFactory = $timeFactory; } /** @@ -55,7 +64,31 @@ class FolderServiceV2 extends Service } /** - * @param string $userId + * 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. + * + * @param string $userId The name/ID of the owner * * @return Folder[] */ @@ -80,33 +113,117 @@ class FolderServiceV2 extends Service return $this->mapper->findAll(); } + /** + * Create a folder + * + * @param string $userId + * @param string $name + * @param int|null $parent + * + * @return Folder + */ public function create(string $userId, string $name, ?int $parent = null): Entity { $folder = new Folder(); $folder->setUserId($userId) ->setName($name) - ->setParentId($parent); + ->setParentId($parent) + ->setOpened(true); return $this->mapper->insert($folder); } - public function delete(string $user, int $id) + /** + * 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 { - $entity = $this->mapper->findFromUser($user, $id); + $folder = $this->findForUser($userId, $folderId); - $this->mapper->delete($entity); + return $this->mapper->delete($folder); } + /** + * Purge all deleted folders. + */ public function purgeDeleted() { $this->mapper->purgeDeleted(); } - public function rename(string $userId, int $folderId, string $newName) + /** + * Rename a folder + * + * @param string $userId Folder owner + * @param int $folderId Folder ID + * @param string $newName New name + * + * @return Folder + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function rename(string $userId, int $folderId, string $newName): Entity { - /** @var Folder $folder */ - $folder = $this->mapper->find($userId, $folderId); + $folder = $this->findForUser($userId, $folderId); $folder->setName($newName); - $this->mapper->update($folder); + return $this->mapper->update($folder); + } + + /** + * Mark a folder as deleted + * + * @param string $userId Folder owner + * @param int $folderId Folder ID + * @param bool $mark If the mark should be added or removed + * + * @return Folder + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function markDelete(string $userId, int $folderId, bool $mark): Entity + { + $folder = $this->findForUser($userId, $folderId); + $time = $mark ? $this->timeFactory->getTime() : 0; + $folder->setDeletedAt($time); + + return $this->mapper->update($folder); + } + + /** + * Mark a folder as opened + * + * @param string $userId Folder owner + * @param int|null $folderId Folder ID + * @param bool $open If the mark should be added or removed + * + * @return Folder + * @throws ServiceConflictException + * @throws ServiceNotFoundException + */ + public function open(string $userId, ?int $folderId, bool $open): Entity + { + |