OPML export command and fixes

Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
This commit is contained in:
Sean Molenaar 2020-09-29 13:54:17 +02:00 committed by Benjamin Brahmer
parent d6d169be15
commit 35b53ecd40
61 changed files with 506 additions and 492 deletions

View File

@ -104,9 +104,10 @@ jobs:
./occ news:generate-explore --votes 100 "https://nextcloud.com/blog/feed/"
./occ news:folder:add 'admin' 'Something'
./occ news:folder:list 'admin' | grep 'Something'
./occ news:folder:delete 'admin' $(./occ news:folder:list 'admin' | grep 'Something' -1 | head -1 | grep -oE '[0-9]*')
./occ news:feed:add 'admin' "https://nextcloud.com/blog/feed/"
./occ news:feed:list 'admin' | grep 'nextcloud\.com'
./occ news:opml:export 'admin' | grep 'nextcloud\.com'
./occ news:folder:delete 'admin' $(./occ news:folder:list 'admin' | grep 'Something' -1 | head -1 | grep -oE '[0-9]*')
./occ news:feed:delete 'admin' $(./occ news:feed:list 'admin' | grep 'nextcloud\.com' -1 | head -1 | grep -oE '[0-9]*')
- name: Prep PHP tests

View File

@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
## Unreleased
- Drop support before nextcloud 20
- Move to modern SQL syntax
- Add management commands
```shell script
./occ news:opml:export <userID>
./occ news:folder:add <userID> <name>
./occ news:folder:list <userID>
./occ news:folder:delete <userID>
./occ news:feed:add <userID> <URL>
./occ news:feed:list <userID>
./occ news:feed:delete <userID>
```
## 14.2.2
### Changed
@ -99,7 +114,7 @@ All notable changes to this project will be documented in this file.
## 14.1.2
## Changed
- Updated js packages
- Updated js packages
### Fixed
- Signature was missing
@ -163,7 +178,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Fixed some feeds with a empty body #474
- Restored full text by default for some feeds #479
- Some smaller adjustments for the design #463 #464
- Some smaller adjustments for the design #463 #464
## 13.1.4
@ -187,7 +202,7 @@ All notable changes to this project will be documented in this file.
- Highlight in compact mode #109
- Prevent raw angluar templates from flashing on page load #429
- HTML elements where not rendered #428
- Provide UserAgent to prevent HTTP 403 errors #428
- Provide UserAgent to prevent HTTP 403 errors #428
## 13.1.1

View File

@ -65,11 +65,12 @@ Before you update to a new version, [check the changelog](https://github.com/nex
<command>OCA\News\Command\Config\FeedAdd</command>
<command>OCA\News\Command\Config\FeedDelete</command>
<command>OCA\News\Command\Config\FeedDelete</command>
<command>OCA\News\Command\Config\OpmlExport</command>
</commands>
<settings>
<admin>OCA\News\Settings\Admin</admin>
<admin-section>OCA\News\Settings\Section</admin-section>
<admin>OCA\News\Settings\AdminSettings</admin>
<admin-section>OCA\News\Settings\AdminSection</admin-section>
</settings>
<navigations>

View File

@ -51,7 +51,8 @@
"ext-json": "*",
"ext-simplexml": "*",
"ext-libxml": "*",
"ext-dom": "*"
"ext-dom": "*",
"ext-curl": "*"
},
"require-dev": {
"phpunit/phpunit": "9.2.*",

5
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "e553641d7a0ca7ff73af7bdbc2c47617",
"content-hash": "63f7665291caac91a887b6eb20a03db7",
"packages": [
{
"name": "andreskrey/readability.php",
@ -2298,7 +2298,8 @@
"ext-json": "*",
"ext-simplexml": "*",
"ext-libxml": "*",
"ext-dom": "*"
"ext-dom": "*",
"ext-curl": "*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"

View File

@ -0,0 +1,50 @@
<?php
namespace OCA\News\Command\Config;
use OCA\News\Service\OpmlService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class OpmlExport extends Command
{
/**
* @var OpmlService service for the data.
*/
protected $opmlService;
public function __construct(OpmlService $opmlService)
{
parent::__construct(null);
$this->opmlService = $opmlService;
}
/**
* Configure command
*/
protected function configure()
{
$this->setName('news:opml:export')
->setDescription('Print OPML file')
->addArgument('userID', InputArgument::REQUIRED, 'User data to export');
}
/**
* Execute command
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int|void
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$user = $input->getArgument('userID');
$output->write($this->opmlService->export($user));
return 0;
}
}

View File

@ -50,6 +50,9 @@ class ShowFeed extends Command
$this->feedFetcher = $feedFetcher;
}
/**
* Configure the command
*/
protected function configure()
{
$this->setName('news:show-feed')
@ -60,6 +63,14 @@ class ShowFeed extends Command
->addOption('full-text', 'f', InputOption::VALUE_NONE, 'Usa a scraper to get full text');
}
/**
* Execute the command
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$url = $input->getArgument('feed');

View File

@ -98,9 +98,9 @@ class FetcherConfig
/**
* Configure a guzzle client
*
* @return ClientInterface Legacy client to guzzle.
* @return ClientInterface Client to guzzle.
*/
public function getClient()
public function getClient(): ClientInterface
{
$config = [
'timeout' => $this->client_timeout,

View File

@ -67,12 +67,17 @@ class AdminController extends Controller
*
* @return TemplateResponse
*/
public function index()
public function index(): TemplateResponse
{
return new TemplateResponse($this->appName, 'admin', $this->getData(), 'blank');
}
private function getData()
/**
* Get admin data.
*
* @return array
*/
private function getData(): array
{
$data = [];
@ -108,7 +113,7 @@ class AdminController extends Controller
bool $useCronUpdates,
string $exploreUrl,
int $updateInterval
) {
): array {
$this->config->setAppValue($this->appName, 'autoPurgeMinimumInterval', $autoPurgeMinimumInterval);
$this->config->setAppValue($this->appName, 'autoPurgeCount', $autoPurgeCount);
$this->config->setAppValue($this->appName, 'maxRedirects', $maxRedirects);

View File

@ -16,6 +16,7 @@
namespace OCA\News\Controller;
use \OCP\IRequest;
use OCP\IUser;
use \OCP\IUserSession;
use \OCP\AppFramework\ApiController as BaseApiController;

View File

@ -57,7 +57,7 @@ class EntityApiSerializer
}
private function convert($entities)
private function convert(array $entities)
{
$converted = [];

View File

@ -13,39 +13,37 @@
namespace OCA\News\Controller;
use OCA\News\Service\FeedServiceV2;
use OCA\News\Service\FolderServiceV2;
use OCA\News\Service\ItemServiceV2;
use OCA\News\Service\OpmlService;
use OCP\AppFramework\Http\DataDownloadResponse;
use \OCP\IRequest;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http;
use \OCP\AppFramework\Http\JSONResponse;
use \OCA\News\Http\TextDownloadResponse;
use \OCA\News\Service\FolderService;
use \OCA\News\Service\FeedService;
use \OCA\News\Service\ItemService;
use \OCA\News\Utility\OPMLExporter;
class ExportController extends Controller
{
private $opmlExporter;
private $opmlService;
private $folderService;
private $feedService;
private $itemService;
private $userId;
public function __construct(
$appName,
string $appName,
IRequest $request,
FolderService $folderService,
FeedService $feedService,
ItemService $itemService,
OPMLExporter $opmlExporter,
$UserId
FolderServiceV2 $folderService,
FeedServiceV2 $feedService,
ItemServiceV2 $itemService,
OpmlService $opmlService,
string $UserId
) {
parent::__construct($appName, $request);
$this->feedService = $feedService;
$this->folderService = $folderService;
$this->opmlExporter = $opmlExporter;
$this->opmlService = $opmlService;
$this->itemService = $itemService;
$this->userId = $UserId;
}
@ -55,15 +53,15 @@ class ExportController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function opml()
public function opml(): DataDownloadResponse
{
$feeds = $this->feedService->findAll($this->userId);
$folders = $this->folderService->findAll($this->userId);
$opml = $this->opmlExporter->build($folders, $feeds)->saveXML();
$date = date('Y-m-d');
$name = "subscriptions-" . $date . ".opml";
$mimeType = 'text/xml';
return new TextDownloadResponse($opml, $name, $mimeType);
return new DataDownloadResponse(
$this->opmlService->export($this->userId),
"subscriptions-${date}.opml",
'text/xml'
);
}
@ -71,10 +69,10 @@ class ExportController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function articles()
public function articles(): JSONResponse
{
$feeds = $this->feedService->findAll($this->userId);
$items = $this->itemService->getUnreadOrStarred($this->userId);
$feeds = $this->feedService->findAllForUser($this->userId);
$items = $this->itemService->findAllForUser($this->userId, ['unread' => true, 'starred' => true]);
// build assoc array for fast access
$feedsDict = [];

View File

@ -18,6 +18,7 @@ namespace OCA\News\Controller;
use OCA\News\Service\Exceptions\ServiceConflictException;
use OCA\News\Service\Exceptions\ServiceNotFoundException;
use OCA\News\Utility\PsrLogger;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\ILogger;
use \OCP\IUserSession;
@ -52,7 +53,7 @@ class FeedApiController extends ApiController
private $serializer;
public function __construct(
$appName,
string $appName,
IRequest $request,
IUserSession $userSession,
FeedService $feedService,
@ -72,7 +73,7 @@ class FeedApiController extends ApiController
* @NoCSRFRequired
* @CORS
*/
public function index()
public function index(): array
{
$result = [
@ -100,9 +101,10 @@ class FeedApiController extends ApiController
*
* @param string $url
* @param int $folderId
* @return array|mixed|\OCP\AppFramework\Http\JSONResponse
*
* @return array|mixed|JSONResponse
*/
public function create($url, $folderId = 0)
public function create(string $url, int $folderId = 0)
{
try {
$this->feedService->purgeDeleted($this->getUserId(), false);
@ -133,9 +135,10 @@ class FeedApiController extends ApiController
* @CORS
*
* @param int $feedId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function delete($feedId)
public function delete(int $feedId)
{
try {
$this->feedService->delete($feedId, $this->getUserId());
@ -155,7 +158,7 @@ class FeedApiController extends ApiController
* @param int $feedId
* @param int $newestItemId
*/
public function read($feedId, $newestItemId)
public function read(int $feedId, int $newestItemId): void
{
$this->itemService->readFeed($feedId, $newestItemId, $this->getUserId());
}
@ -168,9 +171,10 @@ class FeedApiController extends ApiController
*
* @param int $feedId
* @param int $folderId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function move($feedId, $folderId)
public function move(int $feedId, int $folderId)
{
try {
$this->feedService->patch(
@ -193,9 +197,10 @@ class FeedApiController extends ApiController
*
* @param int $feedId
* @param string $feedTitle
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function rename($feedId, $feedTitle)
public function rename(int $feedId, string $feedTitle)
{
try {
$this->feedService->patch(
@ -215,7 +220,7 @@ class FeedApiController extends ApiController
* @NoCSRFRequired
* @CORS
*/
public function fromAllUsers()
public function fromAllUsers(): array
{
$feeds = $this->feedService->findAllFromAllUsers();
$result = ['feeds' => []];
@ -237,7 +242,7 @@ class FeedApiController extends ApiController
* @param string $userId
* @param int $feedId
*/
public function update($userId, $feedId)
public function update(string $userId, int $feedId): void
{
try {
$this->feedService->update($userId, $feedId);

View File

@ -15,6 +15,7 @@ namespace OCA\News\Controller;
use OCA\News\Service\Exceptions\ServiceConflictException;
use OCA\News\Service\Exceptions\ServiceNotFoundException;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IConfig;
use OCP\AppFramework\Controller;
@ -36,13 +37,13 @@ class FeedController extends Controller
private $settings;
public function __construct(
$appName,
string $appName,
IRequest $request,
FolderService $folderService,
FeedService $feedService,
ItemService $itemService,
IConfig $settings,
$UserId
string $UserId
) {
parent::__construct($appName, $request);
$this->feedService = $feedService;
@ -56,7 +57,7 @@ class FeedController extends Controller
/**
* @NoAdminRequired
*/
public function index()
public function index(): array
{
// this method is also used to update the interface
@ -83,7 +84,7 @@ class FeedController extends Controller
/**
* @NoAdminRequired
*/
public function active()
public function active(): array
{
$feedId = (int) $this->settings->getUserValue(
$this->userId,
@ -134,14 +135,15 @@ class FeedController extends Controller
* @param string $title
* @param string $user
* @param string $password
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function create(
$url,
$parentFolderId,
$title = null,
$user = null,
$password = null
string $url,
int $parentFolderId,
?string $title = null,
?string $user = null,
?string $password = null
) {
try {
// we need to purge deleted feeds if a feed is created to
@ -180,9 +182,10 @@ class FeedController extends Controller
* @NoAdminRequired
*
* @param int $feedId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function delete($feedId)
public function delete(int $feedId)
{
try {
$this->feedService->markDeleted($feedId, $this->userId);
@ -198,9 +201,10 @@ class FeedController extends Controller
* @NoAdminRequired
*
* @param int $feedId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function update($feedId)
public function update(int $feedId)
{
try {
$feed = $this->feedService->update($this->userId, $feedId);
@ -227,7 +231,7 @@ class FeedController extends Controller
* @param array $json
* @return array
*/
public function import($json)
public function import(array $json): array
{
$feed = $this->feedService->importArticles($json, $this->userId);
@ -250,7 +254,7 @@ class FeedController extends Controller
* @param int $highestItemId
* @return array
*/
public function read($feedId, $highestItemId)
public function read(int $feedId, int $highestItemId): array
{
$this->itemService->readFeed($feedId, $highestItemId, $this->userId);
@ -269,9 +273,10 @@ class FeedController extends Controller
* @NoAdminRequired
*
* @param int $feedId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function restore($feedId)
public function restore(int $feedId)
{
try {
$this->feedService->unmarkDeleted($feedId, $this->userId);
@ -292,15 +297,17 @@ class FeedController extends Controller
* @param int $ordering
* @param int $folderId
* @param string $title
*
* @return array|JSONResponse
*/
public function patch(
$feedId,
$pinned = null,
$fullTextEnabled = null,
$updateMode = null,
$ordering = null,
$title = null,
$folderId = null
int $feedId,
?bool $pinned = null,
?bool $fullTextEnabled = null,
?int $updateMode = null,
?int $ordering = null,
?int $folderId = null,
?string $title = null
) {
$attributes = [
'pinned' => $pinned,

View File

@ -15,6 +15,7 @@
namespace OCA\News\Controller;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\IUserSession;
use \OCP\AppFramework\Http;
@ -34,7 +35,7 @@ class FolderApiController extends ApiController
private $serializer;
public function __construct(
$appName,
string $appName,
IRequest $request,
IUserSession $userSession,
FolderService $folderService,
@ -55,7 +56,7 @@ class FolderApiController extends ApiController
public function index()
{
return $this->serializer->serialize(
$this->folderService->findAll($this->getUserId())
$this->folderService->findAllForUser($this->getUserId())
);
}
@ -66,9 +67,10 @@ class FolderApiController extends ApiController
* @CORS
*
* @param string $name
* @return array|mixed|\OCP\AppFramework\Http\JSONResponse
*
* @return array|mixed|JSONResponse
*/
public function create($name)
public function create(string $name)
{
try {
$this->folderService->purgeDeleted($this->getUserId(), false);
@ -89,9 +91,10 @@ class FolderApiController extends ApiController
* @CORS
*
* @param int $folderId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function delete($folderId)
public function delete(int $folderId)
{
try {
$this->folderService->delete($folderId, $this->getUserId());
@ -107,11 +110,13 @@ class FolderApiController extends ApiController
* @NoAdminRequired
* @NoCSRFRequired
* @CORS
*
* @param int $folderId
* @param string $name
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function update($folderId, $name)
public function update(int $folderId, string $name)
{
try {
$this->folderService->rename($folderId, $name, $this->getUserId());
@ -135,7 +140,7 @@ class FolderApiController extends ApiController
* @param int $folderId
* @param int $newestItemId
*/
public function read($folderId, $newestItemId)
public function read(int $folderId, int $newestItemId): void
{
$this->itemService->readFolder($folderId, $newestItemId, $this->getUserId());
}

View File

@ -13,6 +13,8 @@
namespace OCA\News\Controller;
use OCA\News\Service\Exceptions\ServiceException;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http;
@ -34,7 +36,7 @@ class FolderController extends Controller
private $userId;
public function __construct(
$appName,
string $appName,
IRequest $request,
FolderService $folderService,
FeedService $feedService,
@ -54,7 +56,7 @@ class FolderController extends Controller
*/
public function index()
{
$folders = $this->folderService->findAll($this->userId);
$folders = $this->folderService->findAllForUser($this->userId);
return ['folders' => $folders];
}
@ -64,13 +66,14 @@ class FolderController extends Controller
*
* @param int $folderId
* @param bool $open
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function open($folderId, $open)
public function open(int $folderId, bool $open)
{
try {
$this->folderService->open($folderId, $open, $this->userId);
} catch (ServiceNotFoundException $ex) {
} catch (ServiceException $ex) {
return $this->error($ex, Http::STATUS_NOT_FOUND);
}
@ -82,9 +85,10 @@ class FolderController extends Controller
* @NoAdminRequired
*
* @param string $folderName
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function create($folderName)
public function create(string $folderName)
{
try {
// we need to purge deleted folders if a folder is created to
@ -105,9 +109,10 @@ class FolderController extends Controller
* @NoAdminRequired
*
* @param int $folderId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function delete($folderId)
public function delete(int $folderId)
{
try {
$this->folderService->markDeleted($folderId, $this->userId);
@ -124,9 +129,10 @@ class FolderController extends Controller
*
* @param string $folderName
* @param int $folderId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function rename($folderName, $folderId)
public function rename(string $folderName, int $folderId)
{
try {
$folder = $this->folderService->rename(
@ -152,7 +158,7 @@ class FolderController extends Controller
* @param int $highestItemId
* @return array
*/
public function read($folderId, $highestItemId)
public function read(int $folderId, int $highestItemId): array
{
$this->itemService->readFolder(
$folderId,
@ -160,7 +166,7 @@ class FolderController extends Controller
$this->userId
);
return ['feeds' => $this->feedService->findAll($this->userId)];
return ['feeds' => $this->feedService->findAllForUser($this->userId)];
}
@ -168,9 +174,10 @@ class FolderController extends Controller
* @NoAdminRequired
*
* @param int $folderId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function restore($folderId)
public function restore(int $folderId)
{
try {
$this->folderService->unmarkDeleted($folderId, $this->userId);

View File

@ -15,6 +15,7 @@
namespace OCA\News\Controller;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\IUserSession;
use \OCP\AppFramework\Http;
@ -30,7 +31,7 @@ class ItemApiController extends ApiController
private $serializer;
public function __construct(
$appName,
string $appName,
IRequest $request,
IUserSession $userSession,
ItemService $itemService
@ -55,15 +56,15 @@ class ItemApiController extends ApiController
* @return array|mixed
*/
public function index(
$type = 3,
$id = 0,
$getRead = true,
$batchSize = -1,
$offset = 0,
$oldestFirst = false
int $type = 3,
int $id = 0,
bool $getRead = true,
int $batchSize = -1,
int $offset = 0,
bool $oldestFirst = false
) {
return $this->serializer->serialize(
$this->itemService->findAll(
$this->itemService->findAllItems(
$id,
$type,
$batchSize,
@ -124,9 +125,10 @@ class ItemApiController extends ApiController
* @CORS
*
* @param int $itemId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function read($itemId)
public function read(int $itemId)
{
return $this->setRead(true, $itemId);
}
@ -138,9 +140,10 @@ class ItemApiController extends ApiController
* @CORS
*
* @param int $itemId
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function unread($itemId)
public function unread(int $itemId)
{
return $this->setRead(false, $itemId);
}
@ -170,9 +173,10 @@ class ItemApiController extends ApiController
*
* @param int $feedId
* @param string $guidHash
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function star($feedId, $guidHash)
public function star(int $feedId, string $guidHash)
{
return $this->setStarred(true, $feedId, $guidHash);
}
@ -185,9 +189,10 @@ class ItemApiController extends ApiController
*
* @param int $feedId
* @param string $guidHash
* @return array|\OCP\AppFramework\Http\JSONResponse
*
* @return array|JSONResponse
*/
public function unstar($feedId, $guidHash)
public function unstar(int $feedId, string $guidHash)
{
return $this->setStarred(false, $feedId, $guidHash);
}
@ -200,7 +205,7 @@ class ItemApiController extends ApiController
*
* @param int $newestItemId
*/
public function readAll($newestItemId)
public function readAll(int $newestItemId)
{
$this->itemService->readAll($newestItemId, $this->getUserId());
}
@ -225,7 +230,7 @@ class ItemApiController extends ApiController
*
* @param int[] $items item ids
*/
public function readMultiple($items)
public function readMultiple(array $items)
{
$this->setMultipleRead(true, $items);
}
@ -238,7 +243,7 @@ class ItemApiController extends ApiController
*
* @param int[] $items item ids
*/
public function unreadMultiple($items)
public function unreadMultiple(array $items)
{
$this->setMultipleRead(false, $items);
}
@ -268,7 +273,7 @@ class ItemApiController extends ApiController
*
* @param int[] $items item ids
*/
public function starMultiple($items)
public function starMultiple(array $items)
{
$this->setMultipleStarred(true, $items);
}
@ -281,7 +286,7 @@ class ItemApiController extends ApiController
*
* @param int[] $items item ids
*/
public function unstarMultiple($items)
public function unstarMultiple(array $items)
{
$this->setMultipleStarred(false, $items);
}

View File

@ -61,13 +61,13 @@ class ItemController extends Controller
* @return array
*/
public function index(
$type = 3,
$id = 0,
$limit = 50,
$offset = 0,
$showAll = null,
$oldestFirst = null,
$search = ''
int $type = 3,
int $id = 0,
int $limit = 50,
int $offset = 0,
?bool $showAll = null,
?bool $oldestFirst = null,
string $search = ''
) {
// in case this is called directly and not from the website use the
@ -119,12 +119,12 @@ class ItemController extends Controller
if ($offset === 0) {
$params['newestItemId'] =
$this->itemService->getNewestItemId($this->userId);
$params['feeds'] = $this->feedService->findAll($this->userId);
$params['feeds'] = $this->feedService->findAllForUser($this->userId);
$params['starred'] =
$this->itemService->starredCount($this->userId);
}
$params['items'] = $this->itemService->findAll(
$params['items'] = $this->itemService->findAllItems(
$id,
$type,
$limit,
@ -165,7 +165,7 @@ class ItemController extends Controller
try {
$params['newestItemId'] =
$this->itemService->getNewestItemId($this->userId);
$params['feeds'] = $this->feedService->findAll($this->userId);
$params['feeds'] = $this->feedService->findAllForUser($this->userId);
$params['starred'] =
$this->itemService->starredCount($this->userId);
$params['items'] = $this->itemService->findAllNew(
@ -238,7 +238,7 @@ class ItemController extends Controller
public function readAll($highestItemId)
{
$this->itemService->readAll($highestItemId, $this->userId);
return ['feeds' => $this->feedService->findAll($this->userId)];
return ['feeds' => $this->feedService->findAllForUser($this->userId)];
}

View File

@ -20,7 +20,7 @@ trait JSONHttpErrorTrait
* @param int $code The http error code
* @return JSONResponse
*/
public function error(\Exception $exception, $code)
public function error(\Exception $exception, int $code)
{
return new JSONResponse(['message' => $exception->getMessage()], $code);
}

View File

@ -87,7 +87,7 @@ class PageController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index()
public function index(): TemplateResponse
{
$status = $this->statusService->getStatus();
$response = new TemplateResponse(
@ -118,7 +118,7 @@ class PageController extends Controller
/**
* @NoAdminRequired
*/
public function settings()
public function settings(): array
{
$settings = [
'showAll',
@ -173,7 +173,7 @@ class PageController extends Controller
bool $preventReadOnScroll,
bool $oldestFirst,
bool $compactExpand
) {
): void {
$settings = [
'showAll' => $showAll,
'compact' => $compact,

View File

@ -24,11 +24,10 @@ use \OCP\AppFramework\Http;
class UserApiController extends ApiController
{
private $userSession;
private $rootFolder;
public function __construct(
$appName,
string $appName,
IRequest $request,
IUserSession $userSession,
IRootFolder $rootFolder
@ -42,7 +41,7 @@ class UserApiController extends ApiController
* @NoCSRFRequired
* @CORS
*/
public function index()
public function index(): array
{
$user = $this->getUser();

View File

@ -30,7 +30,7 @@ class UtilityApiController extends ApiController
private $statusService;
public function __construct(
$appName,
string $appName,
IRequest $request,
IUserSession $userSession,
UpdaterService $updater,

View File

@ -16,8 +16,14 @@ namespace OCA\News\Db;
trait EntityJSONSerializer
{
public function serializeFields($properties)
/**
* Serialize object properties.
*
* @param array $properties Serializable properties
*
* @return array
*/
public function serializeFields(array $properties): array
{
$result = [];
foreach ($properties as $property) {

View File

@ -95,7 +95,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getBasicAuthPassword()
public function getBasicAuthPassword(): ?string
{
return $this->basicAuthPassword;
}
@ -103,7 +103,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getBasicAuthUser()
public function getBasicAuthUser(): ?string
{
return $this->basicAuthUser;
}
@ -111,7 +111,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return int|null
*/
public function getDeletedAt()
public function getDeletedAt(): ?int
{
return $this->deletedAt;
}
@ -119,7 +119,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getFaviconLink()
public function getFaviconLink(): ?string
{
return $this->faviconLink;
}
@ -167,7 +167,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLastModified()
public function getLastModified(): ?string
{
return $this->lastModified;
}
@ -175,7 +175,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLastUpdateError()
public function getLastUpdateError(): ?string
{
return $this->lastUpdateError;
}
@ -183,7 +183,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLink()
public function getLink(): ?string
{
return $this->link;
}
@ -191,7 +191,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLocation()
public function getLocation(): ?string
{
return $this->location;
}
@ -321,7 +321,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param int|null $added
*/
public function setAdded(int $added = null): Feed
public function setAdded(?int $added = null): Feed
{
if ($this->added !== $added) {
$this->added = $added;
@ -347,7 +347,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $basicAuthPassword
*/
public function setBasicAuthPassword(string $basicAuthPassword = null): Feed
public function setBasicAuthPassword(?string $basicAuthPassword = null): Feed
{
if ($this->basicAuthPassword !== $basicAuthPassword) {
$this->basicAuthPassword = $basicAuthPassword;
@ -360,7 +360,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $basicAuthUser
*/
public function setBasicAuthUser(string $basicAuthUser = null): Feed
public function setBasicAuthUser(?string $basicAuthUser = null): Feed
{
if ($this->basicAuthUser !== $basicAuthUser) {
$this->basicAuthUser = $basicAuthUser;
@ -373,7 +373,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param int|null $deletedAt
*/
public function setDeletedAt(int $deletedAt = null): Feed
public function setDeletedAt(?int $deletedAt = null): Feed
{
if ($this->deletedAt !== $deletedAt) {
$this->deletedAt = $deletedAt;
@ -386,7 +386,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $faviconLink
*/
public function setFaviconLink(string $faviconLink = null): Feed
public function setFaviconLink(?string $faviconLink = null): Feed
{
if ($this->faviconLink !== $faviconLink) {
$this->faviconLink = $faviconLink;
@ -425,7 +425,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $httpEtag
*/
public function setHttpEtag(string $httpEtag = null): Feed
public function setHttpEtag(?string $httpEtag = null): Feed
{
if ($this->httpEtag !== $httpEtag) {
$this->httpEtag = $httpEtag;
@ -438,7 +438,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $httpLastModified
*/
public function setHttpLastModified(string $httpLastModified = null): Feed
public function setHttpLastModified(?string $httpLastModified = null): Feed
{
if ($this->httpLastModified !== $httpLastModified) {
$this->httpLastModified = $httpLastModified;
@ -464,7 +464,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $lastModified
*/
public function setLastModified(string $lastModified = null): Feed
public function setLastModified(?string $lastModified = null): Feed
{
if ($this->lastModified !== $lastModified) {
$this->lastModified = $lastModified;
@ -477,7 +477,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $lastUpdateError
*/
public function setLastUpdateError(string $lastUpdateError = null): Feed
public function setLastUpdateError(?string $lastUpdateError = null): Feed
{
if ($this->lastUpdateError !== $lastUpdateError) {
$this->lastUpdateError = $lastUpdateError;
@ -490,7 +490,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $link
*/
public function setLink(string $link = null): Feed
public function setLink(?string $link = null): Feed
{
$link = trim($link);
if (strpos($link, 'http') === 0 && $this->link !== $link) {
@ -504,7 +504,7 @@ class Feed extends Entity implements IAPI, \JsonSerializable
/**
* @param string|null $location
*/
public function setLocation(string $location = null): Feed
public function setLocation(?string $location = null): Feed
{
if ($this->location !== $location) {
$this->location = $location;

View File

@ -46,7 +46,7 @@ class FeedMapperV2 extends NewsMapperV2
*
* @return Entity[]
*/
public function findAllFromUser(string $userId): array
public function findAllFromUser(string $userId, array $params = []): array
{
$builder = $this->db->getQueryBuilder();
$builder->addSelect('*')

View File

@ -37,7 +37,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
/**
* @return int|null
*/
public function getDeletedAt()
public function getDeletedAt(): ?int
{
return $this->deletedAt;
}
@ -50,7 +50,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLastModified()
public function getLastModified(): ?string
{
return $this->lastModified;
}
@ -68,7 +68,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
/**
* @return int|null
*/
public function getParentId()
public function getParentId(): ?int
{
return $this->parentId;
}
@ -95,7 +95,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
);
}
public function setDeletedAt(int $deletedAt = null)
public function setDeletedAt(?int $deletedAt = null): void
{
if ($this->deletedAt !== $deletedAt) {
$this->deletedAt = $deletedAt;
@ -103,7 +103,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setId(int $id)
public function setId(int $id): void
{
if ($this->id !== $id) {
$this->id = $id;
@ -111,7 +111,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setLastModified(string $lastModified = null)
public function setLastModified(?string $lastModified = null): void
{
if ($this->lastModified !== $lastModified) {
@ -120,7 +120,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setName(string $name)
public function setName(string $name): void
{
if ($this->name !== $name) {
$this->name = $name;
@ -128,7 +128,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setOpened(bool $opened)
public function setOpened(bool $opened): void
{
if ($this->opened !== $opened) {
$this->opened = $opened;
@ -136,7 +136,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setParentId(int $parentId = 0)
public function setParentId(int $parentId = 0): void
{
if ($this->parentId !== $parentId) {
$this->parentId = $parentId;
@ -144,7 +144,7 @@ class Folder extends Entity implements IAPI, \JsonSerializable
}
}
public function setUserId(string $userId)
public function setUserId(string $userId): void
{
if ($this->userId !== $userId) {
$this->userId = $userId;

View File

@ -44,7 +44,7 @@ class FolderMapperV2 extends NewsMapperV2
*
* @return Entity[]
*/
public function findAllFromUser($userId): array
public function findAllFromUser(string $userId, array $params = []): array
{
$builder = $this->db->getQueryBuilder();
$builder->select('*')

View File

@ -103,7 +103,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
return $item;
}
public function generateSearchIndex()
public function generateSearchIndex(): void
{
$this->setSearchIndex(
mb_strtolower(
@ -121,7 +121,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getAuthor()
public function getAuthor(): ?string
{
return $this->author;
}
@ -129,7 +129,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getBody()
public function getBody(): ?string
{
return $this->body;
}
@ -137,7 +137,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getContentHash()
public function getContentHash(): ?string
{
return $this->contentHash;
}
@ -145,7 +145,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getEnclosureLink()
public function getEnclosureLink(): ?string
{
return $this->enclosureLink;
}
@ -153,7 +153,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getMediaThumbnail()
public function getMediaThumbnail(): ?string
{
return $this->mediaThumbnail;
}
@ -161,7 +161,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getMediaDescription()
public function getMediaDescription(): ?string
{
return $this->mediaDescription;
}
@ -169,12 +169,12 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getEnclosureMime()
public function getEnclosureMime(): ?string
{
return $this->enclosureMime;
}
public function getFeedId()
public function getFeedId(): string
{
return $this->feedId;
}
@ -182,7 +182,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getFingerprint()
public function getFingerprint(): ?string
{
return $this->fingerprint;
}
@ -197,12 +197,12 @@ class Item extends Entity implements IAPI, \JsonSerializable
return $this->guidHash;
}
public function getId()
public function getId(): string
{
return $this->id;
}
public function getIntro()
public function getIntro(): string
{
return strip_tags($this->getBody());
}
@ -210,7 +210,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return string|null
*/
public function getLastModified()
public function getLastModified(): ?string
{
return $this->lastModified;
}
@ -218,7 +218,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return int|null
*/
public function getPubDate()
public function getPubDate(): ?int
{
return $this->pubDate;
}
@ -231,7 +231,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getSearchIndex()
public function getSearchIndex(): ?string
{
return $this->searchIndex;
}
@ -239,7 +239,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getTitle()
public function getTitle(): ?string
{
return $this->title;
}
@ -247,7 +247,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return int|null
*/
public function getUpdatedDate()
public function getUpdatedDate(): ?int
{
return $this->updatedDate;
}
@ -255,17 +255,17 @@ class Item extends Entity implements IAPI, \JsonSerializable
/**
* @return null|string
*/
public function getUrl()
public function getUrl(): ?string
{
return $this->url;
}
public function isStarred()
public function isStarred(): bool
{
return $this->starred;
}
public function isUnread()
public function isUnread(): bool
{
return $this->unread;
}
@ -299,7 +299,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
];
}
public function setAuthor(string $author = null)
public function setAuthor(string $author = null): void
{
$author = strip_tags($author);
@ -309,7 +309,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setBody(string $body = null)
public function setBody(string $body = null): void
{
// FIXME: this should not happen if the target="_blank" is already
// on the link
@ -321,7 +321,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setContentHash(string $contentHash = null)
public function setContentHash(string $contentHash = null): void
{
if ($this->contentHash !== $contentHash) {
$this->contentHash = $contentHash;
@ -329,7 +329,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setEnclosureLink(string $enclosureLink = null)
public function setEnclosureLink(string $enclosureLink = null): void
{
if ($this->enclosureLink !== $enclosureLink) {
$this->enclosureLink = $enclosureLink;
@ -337,7 +337,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setEnclosureMime(string $enclosureMime = null)
public function setEnclosureMime(string $enclosureMime = null): void
{
if ($this->enclosureMime !== $enclosureMime) {
$this->enclosureMime = $enclosureMime;
@ -345,7 +345,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setMediaThumbnail(string $mediaThumbnail = null)
public function setMediaThumbnail(string $mediaThumbnail = null): void
{
if ($this->mediaThumbnail !== $mediaThumbnail) {
$this->mediaThumbnail = $mediaThumbnail;
@ -353,7 +353,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setMediaDescription(string $mediaDescription = null)
public function setMediaDescription(string $mediaDescription = null): void
{
if ($this->mediaDescription !== $mediaDescription) {
$this->mediaDescription = $mediaDescription;
@ -361,7 +361,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setFeedId(int $feedId)
public function setFeedId(int $feedId): void
{
if ($this->feedId !== $feedId) {
$this->feedId = $feedId;
@ -369,7 +369,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setFingerprint(string $fingerprint = null)
public function setFingerprint(string $fingerprint = null): void
{
if ($this->fingerprint !== $fingerprint) {
$this->fingerprint = $fingerprint;
@ -377,7 +377,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setGuid(string $guid)
public function setGuid(string $guid): void
{
if ($this->guid !== $guid) {
$this->guid = $guid;
@ -385,7 +385,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setGuidHash(string $guidHash)
public function setGuidHash(string $guidHash): void
{
if ($this->guidHash !== $guidHash) {
$this->guidHash = $guidHash;
@ -393,7 +393,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setId(int $id)
public function setId(int $id): void
{
if ($this->id !== $id) {
$this->id = $id;
@ -401,7 +401,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setLastModified(string $lastModified = null)
public function setLastModified(string $lastModified = null): void
{
if ($this->lastModified !== $lastModified) {
$this->lastModified = $lastModified;
@ -409,7 +409,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setPubDate(int $pubDate = null)
public function setPubDate(int $pubDate = null): void
{
if ($this->pubDate !== $pubDate) {
$this->pubDate = $pubDate;
@ -417,7 +417,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setRtl(bool $rtl)
public function setRtl(bool $rtl): void
{
if ($this->rtl !== $rtl) {
$this->rtl = $rtl;
@ -425,7 +425,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setSearchIndex(string $searchIndex = null)
public function setSearchIndex(string $searchIndex = null): void
{
if ($this->searchIndex !== $searchIndex) {
$this->searchIndex = $searchIndex;
@ -433,7 +433,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setStarred(bool $starred)
public function setStarred(bool $starred): void
{
if ($this->starred !== $starred) {
$this->starred = $starred;
@ -441,7 +441,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setTitle(string $title = null)
public function setTitle(string $title = null): void
{
$title = strip_tags($title);
@ -451,7 +451,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setUnread(bool $unread)
public function setUnread(bool $unread): void
{
if ($this->unread !== $unread) {
$this->unread = $unread;
@ -459,7 +459,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setUpdatedDate(int $updatedDate = null)
public function setUpdatedDate(int $updatedDate = null): void
{
if ($this->updatedDate !== $updatedDate) {
$this->updatedDate = $updatedDate;
@ -467,7 +467,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
}
}
public function setUrl(string $url = null)
public function setUrl(string $url = null): void
{
$url = trim($url);
if ((strpos($url, 'http') === 0 || strpos($url, 'magnet') === 0)
@ -549,7 +549,7 @@ class Item extends Entity implements IAPI, \JsonSerializable
*
* @return boolean
*/
public function isSupportedMime($mime)
public function isSupportedMime(string $mime): bool
{
return (
stripos($mime, 'audio/') !== false ||

View File

@ -43,10 +43,11 @@ class ItemMapperV2 extends NewsMapperV2
* Find all feeds for a user.
*
* @param string $userId The user identifier
* @param array $params Filter parameters
*
* @return Entity[]
*/
public function findAllFromUser($userId): array
public function findAllFromUser(string $userId, array $params = []): array
{
$builder = $this->db->getQueryBuilder();
$builder->select('items.*')
@ -56,6 +57,11 @@ class ItemMapperV2 extends NewsMapperV2
->andWhere('deleted_at = 0')
->setParameter(':user_id', $userId, IQueryBuilder::PARAM_STR);
foreach ($params as $key => $value) {
$builder->andWhere("${key} = :${key}")
->setParameter(":${key}", $value);
}
return $this->findEntities($builder);
}
@ -110,7 +116,7 @@ class ItemMapperV2 extends NewsMapperV2
*
* @param int $threshold Deletion threshold
*/
public function deleteOverThreshold($threshold)
public function deleteOverThreshold(int $threshold)
{
$builder = $this->db->getQueryBuilder();

View File

@ -88,10 +88,11 @@ abstract class NewsMapperV2 extends QBMapper
* Find all items for a user.
*
* @param string $userId ID of the user
* @param array $params Filter parameters
*
* @return Entity[]
*/
abstract public function findAllFromUser(string $userId): array;
abstract public function findAllFromUser(string $userId, array $params = []): array;
/**
* Find item for a user.

View File

@ -35,7 +35,7 @@ class RecommendedSites
*
* @throws RecommendedSiteNotFoundException
*/
public function forLanguage(string $languageCode)
public function forLanguage(string $languageCode): array
{
$file = $this->directory . '/feeds.' . $languageCode . '.json';

View File

@ -35,7 +35,7 @@ class Fetcher
*
* @param IFeedFetcher $fetcher the fetcher
*/
public function registerFetcher(IFeedFetcher $fetcher)
public function registerFetcher(IFeedFetcher $fetcher): void
{
$this->fetchers[] = $fetcher;
}
@ -62,7 +62,7 @@ class Fetcher
bool $fullTextEnabled = false,
?string $user = null,
?string $password = null
) {
): array {
foreach ($this->fetchers as $fetcher) {
if (!$fetcher->canHandle($url)) {
continue;

View File

@ -21,7 +21,7 @@ class FetcherException extends \Exception
*
* @param string $msg the error message
*/
public function __construct($msg)
public function __construct(string $msg)
{
parent::__construct($msg);
}

View File

@ -29,7 +29,7 @@ class YoutubeFetcher implements IFeedFetcher
*
* @return string
*/
private function buildUrl(string $url)
private function buildUrl(string $url): string
{
$baseRegex = '%(?:https?://|//)?(?:www.)?youtube.com';
$playRegex = $baseRegex . '.*?list=([^&]*)%';

View File

@ -1,51 +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\Http;
use \OCP\AppFramework\Http\DownloadResponse;
/**
* Prompts the user to download the a text file
*/
class TextDownloadResponse extends DownloadResponse
{
private $content;
/**
* Creates a response that prompts the user to download a file which
* contains the passed string
*
* @param string $content the content that should be written into the file
* @param string $filename the name that the downloaded file should have
* @param string $contentType the mimetype that the downloaded file should
* have
*/
public function __construct($content, $filename, $contentType)
{
parent::__construct($filename, $contentType);
$this->content = $content;
}
/**
* Simply sets the headers and returns the file contents
*
* @return string the file contents
*/
public function render()
{
return $this->content;
}
}

View File

@ -1,49 +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\Http;
use \OCP\AppFramework\Http\Response;
/**
* Just outputs text to the browser
*/
class TextResponse extends Response
{
private $content;
/**
* Creates a response that just outputs text
*
* @param string $content the content that should be written into the file
* @param string $contentType the mimetype. text/ is added automatically so
* only plain or html can be added to get text/plain or text/html
*/
public function __construct($content, $contentType = 'plain')
{
$this->content = $content;
$this->addHeader('Content-type', 'text/' . $contentType);
}
/**
* Simply sets the headers and returns the file contents
*
* @return string the file contents
*/
public function render()
{
return $this->content;
}
}

View File

@ -21,7 +21,7 @@ class ServiceConflictException extends ServiceException
*
* @param string $msg the error message
*/
public function __construct($msg)
public function __construct(string $msg)
{
parent::__construct($msg);
}

View File

@ -21,7 +21,7 @@ class ServiceException extends \Exception
*
* @param string $msg the error message
*/
public function __construct($msg)
public function __construct(string $msg)
{
parent::__construct($msg);
}

View File

@ -21,7 +21,7 @@ class ServiceNotFoundException extends ServiceException
*
* @param string $msg the error message
*/
public function __construct($msg)
public function __construct(string $msg)
{
parent::__construct($msg);
}

View File

@ -21,7 +21,7 @@ class ServiceValidationException extends ServiceException
*
* @param string $msg the error message
*/
public function __construct($msg)
public function __construct(string $msg)
{
parent::__construct($msg);
}

View File

@ -83,7 +83,7 @@ class FeedService extends Service
*
* @return Feed[]
*/
public function findAllForUser($userId): array
public function findAllForUser($userId, array $params = []): array
{
return $this->feedMapper->findAllFromUser($userId);
}

View File

@ -89,7 +89,7 @@ class FeedServiceV2 extends Service
*
* @return Feed[]
*/
public function findAllForUser(string $userId): array
public function findAllForUser(string $userId, array $params = []): array
{
return $this->mapper->findAllFromUser($userId);
}

View File

@ -65,7 +65,7 @@ class FolderService extends Service
*
* @return Folder[]
*/
public function findAllForUser(string $userId): array
public function findAllForUser(string $userId, array $params = []): array
{
return $this->folderMapper->findAllFromUser($userId);
}

View File

@ -47,7 +47,7 @@ class FolderServiceV2 extends Service
*
* @return Folder[]
*/
public function findAllForUser(string $userId): array
public function findAllForUser(string $userId, array $params = []): array
{
return $this->mapper->findAllFromUser($userId);
}

View File

@ -150,7 +150,7 @@ class ItemService extends Service
}
}
public function findAllForUser(string $userId): array
public function findAllForUser(string $userId, array $params = []): array
{
return $this->itemMapper->findAllFromUser($userId);
}

View File

@ -51,13 +51,15 @@ class ItemServiceV2 extends Service
/**
* Finds all items of a user
*
* @param string $userId the name of the user
* @param string $userId The ID/name of the user
* @param array $params Filter parameters
*
*
* @return Item[]
*/
public function findAllForUser($userId): array
public function findAllForUser(string $userId, array $params = []): array
{
return $this->mapper->findAllFromUser($userId);
return $this->mapper->findAllFromUser($userId, $params);
}
/**
@ -86,7 +88,7 @@ class ItemServiceV2 extends Service
return $this->mapper->findAllForFeed($feedId);
}
public function purgeOverThreshold($threshold = null)
public function purgeOverThreshold(int $threshold = null)
{
$threshold = (int) $threshold ?? $this->config->getAppValue(

View File

@ -0,0 +1,69 @@
<?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\Utility\OPMLExporter;
class OpmlService
{
/**
* @var FolderService
*/
private $folderService;
/**
* @var FeedService
*/
private $feedService;
/**
* @var ItemService
*/
private $itemService;
/**
* @var OPMLExporter
*/
private $exporter;
public function __construct(
FolderServiceV2 $folderService,
FeedServiceV2 $feedService,
ItemServiceV2 $itemService,
OPMLExporter $exporter
) {
$this->folderService = $folderService;
$this->feedService = $feedService;
$this->itemService = $itemService;
$this->exporter = $exporter;
}
/**
* Export all feeds for a user.
*
* @param string $userId User ID
*
* @return string Exported OPML data
*/
public function export(string $userId): string
{
$feeds = $this->feedService->findAllForUser($userId);
$folders = $this->folderService->findAllForUser($userId);
return $this->exporter->build($folders, $feeds)
->saveXML();
}
}

View File

@ -52,11 +52,12 @@ abstract class Service
/**
* Finds all items of a user
*
* @param string $userId the name of the user
* @param string $userId The ID/name of the user
* @param array $params Filter parameters
*
* @return Entity[]
*/
abstract public function findAllForUser(string $userId): array;
abstract public function findAllForUser(string $userId, array $params = []): array;
/**
* Finds all items
@ -89,7 +90,7 @@ abstract class Service
* @param int $id the id of the entity
* @param string $userId the name of the user for security reasons
*
* @return \OCP\AppFramework\Db\Entity the entity
* @return Entity the entity
* @throws ServiceNotFoundException if the entity does not exist, or there
* are more than one of it
*/

View File

@ -14,14 +14,6 @@
namespace OCA\News\Service;
use OCA\News\Db\ItemMapperV2;
use OCA\News\Service\FeedServiceV2;
use OCA\News\Service\FolderServiceV2;
use OCA\News\Service\ItemServiceV2;
use \OCA\News\Service\LegacyFolderService;
use \OCA\News\Service\FeedService;
use \OCA\News\Service\ItemService;
class UpdaterService
{

View File

@ -6,7 +6,7 @@ use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Settings\IIconSection;
class Section implements IIconSection
class AdminSection implements IIconSection
{
private $l;
private $url;

View File

@ -16,6 +16,7 @@ namespace OCA\News\Utility;
use \DOMDocument;
use \DOMElement;
use OCA\News\Db\Feed;
use OCA\News\Db\Folder;
/**
* Exports the OPML
@ -26,8 +27,8 @@ class OPMLExporter
/**
* Generates the OPML for the active user
*
* @param \OCA\News\Db\Folder[] $folders
* @param \OCA\News\Db\Feed[] $feeds
* @param Folder[] $folders
* @param Feed[] $feeds
* @return DOMDocument the document
*/
public function build(array $folders, array $feeds)

View File

@ -14,14 +14,15 @@
namespace OCA\News\Tests\Unit\Controller;
use OCA\News\Controller\ExportController;
use OCA\News\Service\FeedService;
use OCA\News\Service\FolderService;
use OCA\News\Service\ItemService;
use OCA\News\Service\FeedServiceV2;
use OCA\News\Service\FolderServiceV2;
use \OCA\News\Http\TextDownloadResponse;
use OCA\News\Service\ItemServiceV2;
use OCA\News\Service\OpmlService;
use \OCA\News\Utility\OPMLExporter;
use \OCA\News\Db\Item;
use \OCA\News\Db\Feed;
use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\IRequest;
use PHPUnit\Framework\TestCase;
@ -29,39 +30,55 @@ use PHPUnit\Framework\TestCase;
class ExportControllerTest extends TestCase
{
private $appName;
private $request;
private $controller;
private $user;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|FeedServiceV2
*/
private $feedService;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|FolderServiceV2
*/
private $folderService;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|ItemServiceV2
*/
private $itemService;
private $opmlExporter;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|OpmlService
*/
private $opmlService;
/**
* Gets run before each test
*/
public function setUp(): void
{
$this->appName = 'news';
$appName = 'news';
$this->user = 'john';
$this->itemService = $this->getMockBuilder(ItemService::class)
$this->itemService = $this->getMockBuilder(ItemServiceV2::class)
->disableOriginalConstructor()
->getMock();
$this->feedService = $this->getMockBuilder(FeedService::class)
$this->feedService = $this->getMockBuilder(FeedServiceV2::class)
->disableOriginalConstructor()
->getMock();
$this->folderService = $this->getMockBuilder(FolderService::class)
$this->folderService = $this->getMockBuilder(FolderServiceV2::class)
->disableOriginalConstructor()
->getMock();
$this->request = $this->getMockBuilder(IRequest::class)
$this->opmlService = $this->getMockBuilder(OpmlService::class)
->disableOriginalConstructor()
->getMock();
$request = $this->getMockBuilder(IRequest::class)
->disableOriginalConstructor()
->getMock();
$this->opmlExporter = new OPMLExporter();
$this->controller = new ExportController(
$this->appName, $this->request,
$this->folderService, $this->feedService,
$this->itemService, $this->opmlExporter, $this->user
$appName,
$request,
$this->folderService,
$this->feedService,
$this->itemService,
$this->opmlService,
$this->user
);
}
@ -77,17 +94,13 @@ class ExportControllerTest extends TestCase
" <body/>\n" .
"</opml>\n";
$this->feedService->expects($this->once())
->method('findAll')
->with($this->equalTo($this->user))
->will($this->returnValue([]));
$this->folderService->expects($this->once())
->method('findAll')
->with($this->equalTo($this->user))
->will($this->returnValue([]));
$this->opmlService->expects($this->once())
->method('export')
->with($this->user)
->will($this->returnValue($opml));
$return = $this->controller->opml();
$this->assertTrue($return instanceof TextDownloadResponse);
$this->assertTrue($return instanceof DataDownloadResponse);
$this->assertEquals($opml, $return->render());
}
@ -112,12 +125,12 @@ class ExportControllerTest extends TestCase
$articles = [$item1, $item2];
$this->feedService->expects($this->once())
->method('findAll')
->with($this->equalTo($this->user))
->method('findAllForUser')
->with($this->user)
->will($this->returnValue($feeds));
$this->itemService->expects($this->once())
->method('getUnreadOrStarred')
->with($this->equalTo($this->user))
->method('findAllForUser')
->with($this->user, ['unread' => true, 'starred' => true])
->will($this->returnValue($articles));

View File

@ -81,7 +81,7 @@ class FolderApiControllerTest extends TestCase
$folders = [new Folder()];
$this->folderService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user->getUID()))
->will($this->returnValue($folders));

View File

@ -72,7 +72,7 @@ class FolderControllerTest extends TestCase
{
$return = [new Folder(), new Folder()];
$this->folderService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->will($this->returnValue($return));
$response = $this->controller->index();
@ -303,7 +303,7 @@ class FolderControllerTest extends TestCase
$this->equalTo($this->user)
);
$this->feedService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user))
->will($this->returnValue([$feed]));

View File

@ -80,7 +80,7 @@ class ItemApiControllerTest extends TestCase
$item->setFeedId(123);
$this->itemService->expects($this->once())
->method('findAll')
->method('findAllItems')
->with(
$this->equalTo(2),
$this->equalTo(1),
@ -111,7 +111,7 @@ class ItemApiControllerTest extends TestCase
$item->setFeedId(123);
$this->itemService->expects($this->once())
->method('findAll')
->method('findAllItems')
->with(
$this->equalTo(2),
$this->equalTo(1),

View File

@ -181,7 +181,7 @@ class ItemControllerTest extends TestCase
$this->equalTo($this->user)
);
$this->feedService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user))
->will($this->returnValue([$feed]));
@ -240,7 +240,7 @@ class ItemControllerTest extends TestCase
$this->itemsApiExpects(2, FeedType::FEED, '0');
$this->feedService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user))
->will($this->returnValue($feeds));
@ -255,7 +255,7 @@ class ItemControllerTest extends TestCase
->will($this->returnValue(3111));
$this->itemService->expects($this->once())
->method('findAll')
->method('findAllItems')
->with(
$this->equalTo(2),
$this->equalTo(FeedType::FEED),
@ -286,7 +286,7 @@ class ItemControllerTest extends TestCase
$this->itemsApiExpects(2, FeedType::FEED, '0');
$this->feedService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user))
->will($this->returnValue($feeds));
@ -301,7 +301,7 @@ class ItemControllerTest extends TestCase
->will($this->returnValue(3111));
$this->itemService->expects($this->once())
->method('findAll')
->method('findAllItems')
->with(
$this->equalTo(2),
$this->equalTo(FeedType::FEED),
@ -329,7 +329,7 @@ class ItemControllerTest extends TestCase
$this->itemsApiExpects(2, FeedType::FEED);
$this->itemService->expects($this->once())
->method('findAll')
->method('findAllItems')
->with(
$this->equalTo(2),
$this->equalTo(FeedType::FEED),
@ -342,7 +342,7 @@ class ItemControllerTest extends TestCase
->will($this->returnValue($result['items']));
$this->feedService->expects($this->never())
->method('findAll');
->method('findAllForUser');
$response = $this->controller->index(FeedType::FEED, 2, 3, 10);
$this->assertEquals($result, $response);
@ -383,7 +383,7 @@ class ItemControllerTest extends TestCase
->will($this->returnValue('1'));
$this->feedService->expects($this->once())
->method('findAll')
->method('findAllForUser')
->with($this->equalTo($this->user))
->will($this->returnValue($feeds));

View File

@ -14,14 +14,8 @@
namespace OCA\News\Tests\Unit\Controller;
use OCA\News\Controller\JSONHttpErrorTrait;
use PHPUnit\Framework\TestCase;
class Test
{
use JSONHttpErrorTrait;
}
class JSONHttpErrorTest extends TestCase
{
@ -29,7 +23,7 @@ class JSONHttpErrorTest extends TestCase
public function testError()
{
$ex = new \Exception('hi');
$test = new Test();
$test = new DummyTraitingClass();
$result = $test->error($ex, 3);
$this->assertEquals(['message' => 'hi'], $result->getData());
@ -37,4 +31,10 @@ class JSONHttpErrorTest extends TestCase
}
}
class DummyTraitingClass
{
use JSONHttpErrorTrait;
}

View File

@ -255,7 +255,7 @@ class PageControllerTest extends TestCase
public function testExplore()
{
$in = 'test';
$in = ['test'];
$this->settings->expects($this->at(0))
->method('setUserValue')
->with('becka', 'news', 'lastViewedFeedId', 0);

View File

@ -1,38 +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\Tests\Unit\Http;
use OCA\News\Http\TextDownloadResponse;
use PHPUnit\Framework\TestCase;
class TextDownloadResponseTest extends TestCase
{
protected function setUp(): void
{
$this->response = new TextDownloadResponse(
'sometext', 'file', 'content'
);
}
public function testRender()
{
$this->assertEquals('sometext', $this->response->render());
}
}

View File

@ -1,51 +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\Tests\Unit\Http;
use PHPUnit\Framework\TestCase;
use OCA\News\Http\TextResponse;
class TextResponseTest extends TestCase
{
protected function setUp(): void
{
$this->response = new TextResponse('sometext');
}
public function testRender()
{
$this->assertEquals('sometext', $this->response->render());
}
public function testContentTypeDefaultsToText()
{
$headers = $this->response->getHeaders();
$this->assertEquals('text/plain', $headers['Content-type']);
}
public function testContentTypeIsSetableViaConstructor()
{
$response = new TextResponse('sometext', 'html');
$headers = $response->getHeaders();
$this->assertEquals('text/html', $headers['Content-type']);
}
}

View File

@ -32,7 +32,7 @@ class TestLegacyService extends Service
parent::__construct($mapper, $logger);
}
public function findAllForUser(string $userId): array
public function findAllForUser(string $userId, array $params = []): array
{
// TODO: Implement findAllForUser() method.
}