From ac423f6ca08a86d66544c50a0277e3ff00acb467 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Sat, 2 Feb 2013 00:20:26 +0100 Subject: added foldercontroller + test --- appinfo/bootstrap.php | 4 +- business/businesslayer.php | 96 ------- business/feedbusinesslayer.php | 78 ----- business/feeddoesnotexistexception.php | 39 --- business/feedexistsexception.php | 39 --- business/multiplefeedsreturnedexception.php | 39 --- business/objectexistsexception.php | 37 --- business/permissionexception.php | 37 --- controller/foldercontroller.php | 55 ++++ controller/news.ajax.controller.php | 428 ++++++++++++++++++++++++++++ controller/news.controller.php | 89 ++++++ controllers/news.ajax.controller.php | 428 ---------------------------- controllers/news.controller.php | 89 ------ tests/classloader.php | 35 +++ tests/controller/FolderControllerTest.php | 80 ++++++ tests/index.php | 13 - 16 files changed, 689 insertions(+), 897 deletions(-) delete mode 100644 business/businesslayer.php delete mode 100644 business/feedbusinesslayer.php delete mode 100644 business/feeddoesnotexistexception.php delete mode 100644 business/feedexistsexception.php delete mode 100644 business/multiplefeedsreturnedexception.php delete mode 100644 business/objectexistsexception.php delete mode 100644 business/permissionexception.php create mode 100644 controller/foldercontroller.php create mode 100644 controller/news.ajax.controller.php create mode 100644 controller/news.controller.php delete mode 100644 controllers/news.ajax.controller.php delete mode 100644 controllers/news.controller.php create mode 100644 tests/classloader.php create mode 100644 tests/controller/FolderControllerTest.php delete mode 100644 tests/index.php diff --git a/appinfo/bootstrap.php b/appinfo/bootstrap.php index 03a9a79fc..72423c399 100644 --- a/appinfo/bootstrap.php +++ b/appinfo/bootstrap.php @@ -43,8 +43,8 @@ namespace OCA\News; \OC::$CLASSPATH['OCA\News\FeedType'] = 'apps/news/db/feedtype.php'; \OC::$CLASSPATH['OCA\News\StatusFlag'] = 'apps/news/db/statusflag.php'; -\OC::$CLASSPATH['OCA\News\NewsController'] = 'apps/news/controllers/news.controller.php'; -\OC::$CLASSPATH['OCA\News\NewsAjaxController'] = 'apps/news/controllers/news.ajax.controller.php'; +\OC::$CLASSPATH['OCA\News\NewsController'] = 'apps/news/controller/news.controller.php'; +\OC::$CLASSPATH['OCA\News\NewsAjaxController'] = 'apps/news/controller/news.ajax.controller.php'; /** diff --git a/business/businesslayer.php b/business/businesslayer.php deleted file mode 100644 index d1e43de56..000000000 --- a/business/businesslayer.php +++ /dev/null @@ -1,96 +0,0 @@ -. -* -*/ - -namespace OCA\News\Business; - -use \OCA\AppFramework\Db\DoesNotExistException; -use \OCA\AppFramework\Db\MultipleObjectsReturnedException; - -// use \OCA\News\Db\Entity; - - -abstract class BusinessLayer { - - protected $mapper; - - public function __construct($mapper){ - $this->mapper = $mapper; - } - - - public function create($entity){ - $this->validate($entity); - $this->mapper->create($entity); - } - - - public function update($entity){ - try { - $this->validate($entity); - $this->mapper->update($entity); - } catch(DoesNotExistException $ex){ - $this->throwDoesNotExistException($ex); - } - } - - - public function delete($id){ - try { - $this->mapper->delete($id); - } catch(DoesNotExistException $ex){ - $this->throwDoesNotExistException($ex); - } - } - - - public function getAll(){ - return $this->mapper->getAllByUserId($this->api->getUserId()); - } - - - public function getById($id){ - try { - $entity = $this->mapper->getByIdAndUserId($id, $this->api->getUserId()); - if($feed->getUserId() !== $this->api->getUserId()){ - throw new PermissionException('Not allowed to change the ' + - 'feeds of a user other than the current one'); - } else { - return $entity; - } - } catch(DoesNotExistException $ex){ - $this->throwDoesNotExistException($ex); - } catch(MultipleObjectsReturnedException $ex){ - $this->throwMultipleObjectsReturnedException($ex); - } - } - - - protected abstract function validate($entity); - - protected abstract function throwDoesNotExistException(DoesNotExistException $ex); - protected abstract function throwMultipleObjectsReturnedException(MultipleObjectsReturnedException $ex); - protected abstract function throwObjectExistsException(ObjectExistsException $ex); - -} diff --git a/business/feedbusinesslayer.php b/business/feedbusinesslayer.php deleted file mode 100644 index 6905a9b4a..000000000 --- a/business/feedbusinesslayer.php +++ /dev/null @@ -1,78 +0,0 @@ -. -* -*/ - -namespace OCA\News\Business; - -use \OCA\AppFramework\Core\API; -use \OCA\AppFramework\Db\DoesNotExistException; -use \OCA\AppFramework\Db\MultipleObjectsReturnedException; - -use \OCA\News\Db\ObjectExistsException; - - -class FeedBusinessLayer extends BusinessLayer { - - private $updater; - - public function __construct(API $api, $feedMapper, $updater) { - parent::__construct($api, $feedMapper); - $this->updater = $updater; - } - - - /** - * Sets all items with id lower than $idLowerThan as read - * @param int $feedId the id of the feed - * @param int $idLowerThan all items lower than this id will be marked read - * @throws FeedDoesNotExistException if feed with id $id does not exist - * @throws MultipleFeedsReturnedException if more feeds than one exist with - * the same id - */ - public function setRead($feedId, $idLowerThan){ - $feed = $this->getById($feedId); - $mapper->setAllReadWithIdLowerThan($feed->getId(), $idLowerThan); - } - - - protected function validate($feed){ - // TODO: validate feed (length, required fields etc) - } - - - protected function throwDoesNotExistException(DoesNotExistException $ex){ - throw new FeedDoesNotExistException($ex->getMessage()); - } - - - protected function throwMultipleObjectsReturnedException(MultipleObjectsReturnedException $ex){ - throw new MultipleFeedsReturnedException($ex->getMessage()); - } - - - protected function throwObjectExistsException(ObjectExistsException $ex){ - throw new FeedExistsException($ex->getMessage()); - } - -} \ No newline at end of file diff --git a/business/feeddoesnotexistexception.php b/business/feeddoesnotexistexception.php deleted file mode 100644 index 27c812b01..000000000 --- a/business/feeddoesnotexistexception.php +++ /dev/null @@ -1,39 +0,0 @@ -. -* -*/ - -namespace OCA\News\Business; - -use \OCA\AppFramework\Db\DoesNotExistException; - - -class FeedDoesNotExistException extends DoesNotExistException { - - - public function __construct($message){ - parent::__construct($message); - } - - -} \ No newline at end of file diff --git a/business/feedexistsexception.php b/business/feedexistsexception.php deleted file mode 100644 index 7e1561c4c..000000000 --- a/business/feedexistsexception.php +++ /dev/null @@ -1,39 +0,0 @@ -. -* -*/ - -namespace OCA\News\Business; - -use \OCA\News\Db\ObjectExistsException; - - -class FeedExistsException extends ObjectExistsException { - - - public function __construct($message){ - parent::__construct($message); - } - - -} \ No newline at end of file diff --git a/business/multiplefeedsreturnedexception.php b/business/multiplefeedsreturnedexception.php deleted file mode 100644 index 556d02e33..000000000 --- a/business/multiplefeedsreturnedexception.php +++ /dev/null @@ -1,39 +0,0 @@ -. -* -*/ - -namespace OCA\News\Business; - -use \OCA\AppFramework\Db\MultipleObjectsReturnedException; - - -class MultipleFeedsReturnedException extends MultipleObjectsReturnedException { - - - public function __construct($message){ - parent::__construct($message); - } - - -} \ No newline at end of file diff --git a/business/objectexistsexception.php b/business/objectexistsexception.php deleted file mode 100644 index dd6cb1341..000000000 --- a/business/objectexistsexception.php +++ /dev/null @@ -1,37 +0,0 @@ -. -* -*/ - -namespace OCA\News\Db; - - -class ObjectExistsException extends \Excpetion { - - - public function __construct($message){ - parent::__construct($message); - } - - -} \ No newline at end of file diff --git a/business/permissionexception.php b/business/permissionexception.php deleted file mode 100644 index da99e236a..000000000 --- a/business/permissionexception.php +++ /dev/null @@ -1,37 +0,0 @@ -. -* -*/ - -namespace OCA\News\BusinessLayer; - - -class PermissionException extends \Excpetion { - - - public function __construct($message){ - parent::__construct($message); - } - - -} \ No newline at end of file diff --git a/controller/foldercontroller.php b/controller/foldercontroller.php new file mode 100644 index 000000000..48a0d1694 --- /dev/null +++ b/controller/foldercontroller.php @@ -0,0 +1,55 @@ +. +* +*/ + +namespace OCA\News\Controller; + +use \OCA\AppFramework\Controller\Controller; +use \OCA\AppFramework\Core\API; +use \OCA\AppFramework\Http\Request; + + +class FolderController extends Controller { + + + public function __construct(API $api, Request $request, $folderMapper){ + parent::__construct($api, $request); + $this->folderMapper = $folderMapper; + } + + + /** + * @IsAdminExemption + * @IsSubAdminExemption + * @Ajax + * + * Returns all folders + */ + public function getAll(){ + $folders = $this->folderMapper->getAll(); + return $this->renderJSON($folders); + } + + +} \ No newline at end of file diff --git a/controller/news.ajax.controller.php b/controller/news.ajax.controller.php new file mode 100644 index 000000000..7e96b2c2a --- /dev/null +++ b/controller/news.ajax.controller.php @@ -0,0 +1,428 @@ + +* +* This file is licensed under the Affero General Public License version 3 or later. +* See the COPYING-README file +* +*/ + +namespace OCA\News; + +/** + * Class which handles all ajax calls + */ +class NewsAjaxController extends Controller { + + private $feedMapper; + private $folderMapper; + private $itemMapper; + + /** + * @param Request $request: the object with the request instance + * @param string $api: an instance of the api wrapper + * @param FeedMapper $feedMapepr an instance of the feed mapper + * @param FolderMapper $folderMapper an instance of the folder mapper + * @param ItemMapper $itemMapper an instance of the item mapper + */ + public function __construct($request, $api, $feedMapper, $folderMapper, + $itemMapper){ + parent::__construct($request, $api); + $this->feedMapper = $feedMapper; + $this->folderMapper = $folderMapper; + $this->itemMapper = $itemMapper; + } + + + /** + * @brief turns a post parameter which got a boolean from javascript to + * a boolean in PHP + * @param string $param the post parameter that should be turned into a bool + * @return a PHP boolean + */ + public function postParamToBool($param){ + if($param === 'false') { + return false; + } else { + return true; + } + } + + + /** + * This turns a folder result into an array which can be sent to the client + * as JSON + * @param array $folders the database query result for folders + * @return an array ready for sending as JSON + */ + private function foldersToArray($folders){ + $foldersArray = array(); + foreach($folders as $folder){ + if($folder instanceof \OCA\News\Folder){ + array_push($foldersArray, array( + 'id' => (int)$folder->getId(), + 'name' => $folder->getName(), + 'open' => $folder->getOpened()==="1", + 'hasChildren' => count($folder->getChildren()) > 0, + 'show' => true + ) + ); + } + } + return $foldersArray; + } + + + /** + * This turns a feed result into an array which can be sent to the client + * as JSON + * @param array $feeds the database query result for feeds + * @return an array ready for sending as JSON + */ + private function feedsToArray($feeds){ + $feedsArray = array(); + foreach($feeds as $feed){ + array_push($feedsArray, array( + 'id' => (int)$feed->getId(), + 'name' => $feed->getTitle(), + 'unreadCount' => (int)$this->itemMapper->getUnreadCount(FeedType::FEED, + $feed->getId()), + 'folderId' => (int)$feed->getFolderId(), + 'show' => true, + 'icon' => 'url(' . $feed->getFavicon() .')', + 'url' => $feed->getUrl() + ) + ); + } + return $feedsArray; + } + + + /** + * This turns an items result into an array which can be sent to the client + * as JSON + * @param array $items the database query result for items + * @return an array ready for sending as JSON + */ + private function itemsToArray($items){ + $itemsArray = array(); + foreach($items as $item){ + + $enclosure = $item->getEnclosure(); + if($enclosure){ + $enclosure = array( + 'link' => $enclosure->getLink(), + 'type' => $enclosure->getMimeType() + ); + } + + array_push($itemsArray, array( + 'id' => (int)$item->getId(), + 'title' => $item->getTitle(), + 'isRead' => (bool)$item->isRead(), + 'isImportant' => (bool)$item->isImportant(), + 'feedId' => (int)$item->getFeedId(), + 'feedTitle' => $item->getFeedTitle(), + 'date' => (int)$item->getDate(), + 'body' => $item->getBody(), + 'author' => $item->getAuthor(), + 'url' => $item->getUrl(), + 'enclosure' => $enclosure + ) + ); + } + return $itemsArray; + } + + + /** + * This is being called when the app starts and all feeds + * and folders are requested + */ + public function init(){ + $folders = $this->folderMapper->childrenOfWithFeeds(0); + $foldersArray = $this->foldersToArray($folders); + + $feeds = $this->feedMapper->findAll(); + $feedsArray = $this->feedsToArray($feeds); + + $activeFeed = array(); + $activeFeed['id'] = (int)$this->api->getUserValue('lastViewedFeed'); + $activeFeed['type'] = (int)$this->api->getUserValue('lastViewedFeedType'); + + $showAll = $this->api->getUserValue('showAll') === "1"; + + $starredCount = $this->itemMapper->getUnreadCount(\OCA\News\FeedType::STARRED, 0); + + $result = array( + 'folders' => $foldersArray, + 'feeds' => $feedsArray, + 'activeFeed' => $activeFeed, + 'showAll' => $showAll, + 'userId' => $this->userId, + 'starredCount' => $starredCount + ); + + return $this->renderJSON($result); + } + + + /** + * loads the next X feeds from the server + */ + public function loadFeed(){ + $feedType = (int)$this->params('type'); + $feedId = (int)$this->params('id'); + $latestFeedId = (int)$this->params('latestFeedId'); + $latestTimestamp = (int)$this->params('latestTimestamp'); + $limit = (int)$this->params('limit'); + + // FIXME: integrate latestFeedId, latestTimestamp and limit + $this->api->setUserValue('lastViewedFeed', $feedId); + $this->api->setUserValue('lastViewedFeedType', $feedType); + + $showAll = $this->api->getUserValue('showAll'); + + $items = $this->itemMapper->getItems($feedType, $feedId, $showAll); + $itemsArray = $this->itemsToArray($items); + + // update unread count of all feeds + $feeds = $this->feedMapper->findAll(); + $feedsArray = array(); + + foreach($feeds as $feed){ + $unreadCount = $this->itemMapper->countAllStatus($feed->getId(), StatusFlag::UNREAD); + $unreadArray = array( + 'id' => (int)$feed->getId(), + 'unreadCount' => (int)$unreadCount + ); + array_push($feedsArray, $unreadArray); + } + + $result = array( + 'items' => $itemsArray, + 'feeds' => $feedsArray + ); + + return $this->renderJSON($result); + + } + + + /** + * Used for setting the showAll value from a post request + */ + public function setShowAll(){ + $showAll = $this->postParamToBool($this->params('showAll')); + $this->api->setUserValue('showAll', $showAll); + return $this->renderJSON(); + } + + + /** + * Used for setting the showAll value from a post request + */ + public function collapseFolder(){ + $folderId = (int)$this->params('folderId'); + $opened = $this->postParamToBool($this->params('opened')); + + $folder = $this->folderMapper->find($folderId); + $folder->setOpened($opened); + $this->folderMapper->update($folder); + return $this->renderJSON(); + } + + + /** + * Deletes a feed + */ + public function deleteFeed(){ + $feedId = (int)$this->params('feedId'); + $this->feedMapper->deleteById($feedId); + return $this->renderJSON(); + } + + + /** + * Deletes a folder + */ + public function deleteFolder(){ + $folderId = (int)$this->params('folderId'); + $this->folderMapper->deleteById($folderId); + return $this->renderJSON(); + } + + + /** + * Sets the status of an item + */ + public function setItemStatus(){ + $itemId = (int)$this->params('itemId'); + $status = $this->params('status'); + $item = $this->itemMapper->findById($itemId); + + switch ($status) { + case 'read': + $item->setRead(); + break; + case 'unread': + $item->setUnread(); + break; + case 'important': + $item->setImportant(); + break; + case 'unimportant': + $item->setUnimportant(); + break; + default: + exit(); + break; + } + + $this->itemMapper->update($item); + return $this->renderJSON(); + } + + + /** + * Changes the name of a folder + */ + public function changeFolderName(){ + $folderId = (int)$this->params('folderId'); + $folderName = $this->params('folderName'); + $folder = $this->folderMapper->find($folderId); + $folder->setName($folderName); + $this->folderMapper->update($folder); + return $this->renderJSON(); + } + + + /** + * Moves a feed to a new folder + */ + public function moveFeedToFolder(){ + $feedId = (int)$this->params('feedId'); + $folderId = (int)$this->params('folderId'); + $feed = $this->feedMapper->findById($feedId); + if($folderId === 0) { + $this->feedMapper->save($feed, $folderId); + } else { + $folder = $this->folderMapper->find($folderId); + if(!$folder){ + $msgString = 'Can not move feed %s to folder %s'; + $msg = $this->trans->t($msgString, array($feedId, $folderId)); + return $this->renderJSONError($msg, __FILE__); + } + $this->feedMapper->save($feed, $folder->getId()); + } + return $this->renderJSON(); + } + + + /** + * Pulls new feed items from its url + */ + public function updateFeed(){ + $feedId = (int)$this->params('feedId'); + $feed = $this->feedMapper->findById($feedId); + $newFeed = Utils::fetch($feed->getUrl()); + + $newFeedId = false; + if ($newFeed !== null) { + $newFeedId = $this->feedMapper->save($newFeed, $feed->getFolderId()); + } + + if($newFeedId){ + $feeds = array($this->feedMapper->findById($feedId)); + $feedsArray = array( + 'feeds' => $this->feedsToArray($feeds) + ); + return $this->renderJSON($feedsArray); + } else { + $msgString = 'Error updating feed %s'; + $msg = $this->trans->t($msgString, array($feed->getUrl())); + return $this->renderJSONError($msg, __FILE__); + } + + } + + + /** + * Creates a new folder + */ + public function createFolder(){ + $folderName = $this->params('folderName'); + $folder = new Folder($folderName); + $folderId = $this->folderMapper->save($folder); + $folders = array($this->folderMapper->findById($folderId)); + $foldersArray = array( + 'folders' => $this->foldersToArray($folders) + ); + return $this->renderJSON($foldersArray); + } + + + /** + * Creates a new feed + */ + public function createFeed(){ + $feedUrl = trim($this->params('feedUrl')); + $folderId = (int)$this->params('folderId'); + + $folder = $this->folderMapper->findById($folderId); + + if(!$folder && $folderId !== 0){ + $msgString = 'Folder with id %s does not exist'; + $msg = $this->trans->t($msgString, array($folderId)); + var_dump($folder); + return $this->renderJSONError($msg, __FILE__); + } + + if($this->feedMapper->findIdFromUrl($feedUrl)){ + $msgString = 'Feed %s does already exist'; + $msg = $this->trans->t($msgString, array($feedUrl)); + return $this->renderJSONError($msg, __FILE__); + } + + $feed = Utils::fetch($feedUrl); + if($feed){ + $feedId = $this->feedMapper->save($feed, $folderId); + $feeds = array($this->feedMapper->findById($feedId)); + $feedsArray = array( + 'feeds' => $this->feedsToArray($feeds) + ); + return $this->renderJSON($feedsArray); + } else { + $msgString = 'Could not create feed %s'; + $msg = $this->trans->t($msgString, array($feedUrl)); + return $this->renderJSONError($msg, __FILE__); + } + } + + + /** + * Sets all items read that are older than the current transmitted + * dates and ids + */ + public function setAllItemsRead($feedId, $mostRecentItemId){ + $feedId = (int)$this->params('feedId'); + $mostRecentItemId = (int)$this->params('mostRecentItemId'); + + $feed = $this->feedMapper->findById($feedId); + + if($feed){ + $this->itemMapper->markAllRead($feed->getId(), $mostRecentItemId); + + $feeds = array($this->feedMapper->findById($feed->getId())); + $feedsArray = array( + 'feeds' => $this->feedsToArray($feeds) + ); + return $this->renderJSON($feedsArray); + } + + } + +} diff --git a/controller/news.controller.php b/controller/news.controller.php new file mode 100644 index 000000000..e13cfe979 --- /dev/null +++ b/controller/news.controller.php @@ -0,0 +1,89 @@ + +* +* This file is licensed under the Affero General Public License version 3 or later. +* See the COPYING-README file +* +*/ + +namespace OCA\News; + + +class NewsController extends Controller { + + private $feedMapper; + private $folderMapper; + + /** + * @param Request $request: the object with the request instance + * @param string $api: an instance of the api wrapper object + * @param FolderMapper $folderMapper: an instance of the folder mapper + * @param FeedMapper $feedMapper: an instance of the feed mapper + */ + public function __construct($request, $api, $feedMapper, $folderMapper){ + parent::__construct($request, $api); + $this->feedMapper = $feedMapper; + $this->folderMapper = $folderMapper; + $this->api->activateNavigationEntry(); + } + + + /** + * OPML export download page + */ + public function exportOPML($urlParams=array()){ + $opmlExporter = new OPMLExporter($this->api); + + $allFeeds = $this->folderMapper->childrenOfWithFeeds(0); + $opml = $opmlExporter->buildOPML($allFeeds); + + $fileName = 'ownCloud ' . $this->trans->t('News') . ' ' . $this->userId . '.opml'; + $contentType = 'application/x.opml+xml'; + $response = new TextDownloadResponse($opml, $fileName, $contentType); + + return $response; + } + + + /** + * Decides wether to show the feedpage or the firstrun page + */ + public function index($urlParams=array()){ + $this->api->add3rdPartyScript('angular-1.0.2/angular.min'); + $this->api->add3rdPartyScript('moment.min'); + $this->api->addScript('app'); + $this->api->addStyle('news'); + + + if($urlParams['feedid']){ + $this->api->setUserValue('lastViewedFeed', $urlParams['feedid']); + $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); + } + + $lastViewedFeedId = $this->api->getUserValue('lastViewedFeed'); + $lastViewedFeedType = $this->api->getUserValue('lastViewedFeedType'); + + if( $lastViewedFeedId === null || $lastViewedFeedType === null) { + $this->api->setUserValue('lastViewedFeed', $this->feedMapper->mostRecent());; + $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); + + } else { + // check if the last selected feed or folder exists + if(($lastViewedFeedType === FeedType::FEED && + $this->feedMapper->findById($lastViewedFeedId) === null) || + ($lastViewedFeedType === FeedType::FOLDER && + $this->folderMapper->findById($lastViewedFeedId) === null)){ + $this->api->setUserValue('lastViewedFeed', $this->feedMapper->mostRecent());; + $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); + } + } + + return $this->render('main'); + } + + +} diff --git a/controllers/news.ajax.controller.php b/controllers/news.ajax.controller.php deleted file mode 100644 index 4defd8f9c..000000000 --- a/controllers/news.ajax.controller.php +++ /dev/null @@ -1,428 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -namespace OCA\News; - -/** - * Class which handles all ajax calls - */ -class NewsAjaxController extends Controller { - - private $feedMapper; - private $folderMapper; - private $itemMapper; - - /** - * @param Request $request: the object with the request instance - * @param string $api: an instance of the api wrapper - * @param FeedMapper $feedMapepr an instance of the feed mapper - * @param FolderMapper $folderMapper an instance of the folder mapper - * @param ItemMapper $itemMapper an instance of the item mapper - */ - public function __construct($request, $api, $feedMapper, $folderMapper, - $itemMapper){ - parent::__construct($request, $api); - $this->feedMapper = $feedMapper; - $this->folderMapper = $folderMapper; - $this->itemMapper = $itemMapper; - } - - - /** - * @brief turns a post parameter which got a boolean from javascript to - * a boolean in PHP - * @param string $param the post parameter that should be turned into a bool - * @return a PHP boolean - */ - public function postParamToBool($param){ - if($param === 'false') { - return false; - } else { - return true; - } - } - - - /** - * This turns a folder result into an array which can be sent to the client - * as JSON - * @param array $folders the database query result for folders - * @return an array ready for sending as JSON - */ - private function foldersToArray($folders){ - $foldersArray = array(); - foreach($folders as $folder){ - if($folder instanceof \OCA\News\Folder){ - array_push($foldersArray, array( - 'id' => (int)$folder->getId(), - 'name' => $folder->getName(), - 'open' => $folder->getOpened()==="1", - 'hasChildren' => count($folder->getChildren()) > 0, - 'show' => true - ) - ); - } - } - return $foldersArray; - } - - - /** - * This turns a feed result into an array which can be sent to the client - * as JSON - * @param array $feeds the database query result for feeds - * @return an array ready for sending as JSON - */ - private function feedsToArray($feeds){ - $feedsArray = array(); - foreach($feeds as $feed){ - array_push($feedsArray, array( - 'id' => (int)$feed->getId(), - 'name' => $feed->getTitle(), - 'unreadCount' => (int)$this->itemMapper->getUnreadCount(FeedType::FEED, - $feed->getId()), - 'folderId' => (int)$feed->getFolderId(), - 'show' => true, - 'icon' => 'url(' . $feed->getFavicon() .')', - 'url' => $feed->getUrl() - ) - ); - } - return $feedsArray; - } - - - /** - * This turns an items result into an array which can be sent to the client - * as JSON - * @param array $items the database query result for items - * @return an array ready for sending as JSON - */ - private function itemsToArray($items){ - $itemsArray = array(); - foreach($items as $item){ - - $enclosure = $item->getEnclosure(); - if($enclosure){ - $enclosure = array( - 'link' => $enclosure->getLink(), - 'type' => $enclosure->getMimeType() - ); - } - - array_push($itemsArray, array( - 'id' => (int)$item->getId(), - 'title' => $item->getTitle(), - 'isRead' => (bool)$item->isRead(), - 'isImportant' => (bool)$item->isImportant(), - 'feedId' => (int)$item->getFeedId(), - 'feedTitle' => $item->getFeedTitle(), - 'date' => (int)$item->getDate(), - 'body' => $item->getBody(), - 'author' => $item->getAuthor(), - 'url' => $item->getUrl(), - 'enclosure' => $enclosure - ) - ); - } - return $itemsArray; - } - - - /** - * This is being called when the app starts and all feeds - * and folders are requested - */ - public function init(){ - $folders = $this->folderMapper->childrenOfWithFeeds(0); - $foldersArray = $this->foldersToArray($folders); - - $feeds = $this->feedMapper->findAll(); - $feedsArray = $this->feedsToArray($feeds); - - $activeFeed = array(); - $activeFeed['id'] = (int)$this->api->getUserValue('lastViewedFeed'); - $activeFeed['type'] = (int)$this->api->getUserValue('lastViewedFeedType'); - - $showAll = $this->api->getUserValue('showAll') === "1"; - - $starredCount = $this->itemMapper->getUnreadCount(\OCA\News\FeedType::STARRED, 0); - - $result = array( - 'folders' => $foldersArray, - 'feeds' => $feedsArray, - 'activeFeed' => $activeFeed, - 'showAll' => $showAll, - 'userId' => $this->userId, - 'starredCount' => $starredCount - ); - - return $this->renderJSON($result); - } - - - /** - * loads the next X feeds from the server - */ - public function loadFeed(){ - $feedType = (int)$this->params('type'); - $feedId = (int)$this->params('id'); - $latestFeedId = (int)$this->params('latestFeedId'); - $latestTimestamp = (int)$this->params('latestTimestamp'); - $limit = (int)$this->params('limit'); - - // FIXME: integrate latestFeedId, latestTimestamp and limit - $this->api->setUserValue('lastViewedFeed', $feedId); - $this->api->setUserValue('lastViewedFeedType', $feedType); - - $showAll = $this->api->getUserValue('showAll'); - - $items = $this->itemMapper->getItems($feedType, $feedId, $showAll); - $itemsArray = $this->itemsToArray($items); - - // update unread count of all feeds - $feeds = $this->feedMapper->findAll(); - $feedsArray = array(); - - foreach($feeds as $feed){ - $unreadCount = $this->itemMapper->countAllStatus($feed->getId(), StatusFlag::UNREAD); - $unreadArray = array( - 'id' => (int)$feed->getId(), - 'unreadCount' => (int)$unreadCount - ); - array_push($feedsArray, $unreadArray); - } - - $result = array( - 'items' => $itemsArray, - 'feeds' => $feedsArray - ); - - return $this->renderJSON($result); - - } - - - /** - * Used for setting the showAll value from a post request - */ - public function setShowAll(){ - $showAll = $this->postParamToBool($this->params('showAll')); - $this->api->setUserValue('showAll', $showAll); - return $this->renderJSON(); - } - - - /** - * Used for setting the showAll value from a post request - */ - public function collapseFolder(){ - $folderId = (int)$this->params('folderId'); - $opened = $this->postParamToBool($this->params('opened')); - - $folder = $this->folderMapper->find($folderId); - $folder->setOpened($opened); - $this->folderMapper->update($folder); - return $this->renderJSON(); - } - - - /** - * Deletes a feed - */ - public function deleteFeed(){ - $feedId = (int)$this->params('feedId'); - $this->feedMapper->deleteById($feedId); - return $this->renderJSON(); - } - - - /** - * Deletes a folder - */ - public function deleteFolder(){ - $folderId = (int)$this->params('folderId'); - $this->folderMapper->deleteById($folderId); - return $this->renderJSON(); - } - - - /** - * Sets the status of an item - */ - public function setItemStatus(){ - $itemId = (int)$this->params('itemId'); - $status = $this->params('status'); - $item = $this->itemMapper->findById($itemId); - - switch ($status) { - case 'read': - $item->setRead(); - break; - case 'unread': - $item->setUnread(); - break; - case 'important': - $item->setImportant(); - break; - case 'unimportant': - $item->setUnimportant(); - break; - default: - exit(); - break; - } - - $this->itemMapper->update($item); - return $this->renderJSON(); - } - - - /** - * Changes the name of a folder - */ - public function changeFolderName(){ - $folderId = (int)$this->params('folderId'); - $folderName = $this->params('folderName'); - $folder = $this->folderMapper->find($folderId); - $folder->setName($folderName); - $this->folderMapper->update($folder); - return $this->renderJSON(); - } - - - /** - * Moves a feed to a new folder - */ - public function moveFeedToFolder(){ - $feedId = (int)$this->params('feedId'); - $folderId = (int)$this->params('folderId'); - $feed = $this->feedMapper->findById($feedId); - if($folderId === 0) { - $this->feedMapper->save($feed, $folderId); - } else { - $folder = $this->folderMapper->find($folderId); - if(!$folder){ - $msgString = 'Can not move feed %s to folder %s'; - $msg = $this->trans->t($msgString, array($feedId, $folderId)); - return $this->renderJSONError($msg, __FILE__); - } - $this->feedMapper->save($feed, $folder->getId()); - } - return $this->renderJSON(); - } - - - /** - * Pulls new feed items from its url - */ - public function updateFeed(){ - $feedId = (int)$this->params('feedId'); - $feed = $this->feedMapper->findById($feedId); - $newFeed = Utils::fetch($feed->getUrl()); - - $newFeedId = false; - if ($newFeed !== null) { - $newFeedId = $this->feedMapper->save($newFeed, $feed->getFolderId()); - } - - if($newFeedId){ - $feeds = array($this->feedMapper->findById($feedId)); - $feedsArray = array( - 'feeds' => $this->feedsToArray($feeds) - ); - return $this->renderJSON($feedsArray); - } else { - $msgString = 'Error updating feed %s'; - $msg = $this->trans->t($msgString, array($feed->getUrl())); - return $this->renderJSONError($msg, __FILE__); - } - - } - - - /** - * Creates a new folder - */ - public function createFolder(){ - $folderName = $this->params('folderName'); - $folder = new Folder($folderName); - $folderId = $this->folderMapper->save($folder); - $folders = array($this->folderMapper->findById($folderId)); - $foldersArray = array( - 'folders' => $this->foldersToArray($folders) - ); - return $this->renderJSON($foldersArray); - } - - - /** - * Creates a new feed - */ - public function createFeed(){ - $feedUrl = trim($this->params('feedUrl')); - $folderId = (int)$this->params('folderId'); - - $folder = $this->folderMapper->findById($folderId); - - if(!$folder && $folderId !== 0){ - $msgString = 'Folder with id %s does not exist'; - $msg = $this->trans->t($msgString, array($folderId)); - var_dump($folder); - return $this->renderJSONError($msg, __FILE__); - } - - if($this->feedMapper->findIdFromUrl($feedUrl)){ - $msgString = 'Feed %s does already exist'; - $msg = $this->trans->t($msgString, array($feedUrl)); - return $this->renderJSONError($msg, __FILE__); - } - - $feed = Utils::fetch($feedUrl); - if($feed){ - $feedId = $this->feedMapper->save($feed, $folderId); - $feeds = array($this->feedMapper->findById($feedId)); - $feedsArray = array( - 'feeds' => $this->feedsToArray($feeds) - ); - return $this->renderJSON($feedsArray); - } else { - $msgString = 'Could not create feed %s'; - $msg = $this->trans->t($msgString, array($feedUrl)); - return $this->renderJSONError($msg, __FILE__); - } - } - - - /** - * Sets all items read that are older than the current transmitted - * dates and ids - */ - public function setAllItemsRead($feedId, $mostRecentItemId){ - $feedId = (int)$this->params('feedId'); - $mostRecentItemId = (int)$this->params('mostRecentItemId'); - - $feed = $this->feedMapper->findById($feedId); - - if($feed){ - $this->itemMapper->markAllRead($feed->getId(), $mostRecentItemId); - - $feeds = array($this->feedMapper->findById($feed->getId())); - $feedsArray = array( - 'feeds' => $this->feedsToArray($feeds) - ); - return $this->renderJSON($feedsArray); - } - - } - -} diff --git a/controllers/news.controller.php b/controllers/news.controller.php deleted file mode 100644 index d12783205..000000000 --- a/controllers/news.controller.php +++ /dev/null @@ -1,89 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -namespace OCA\News; - - -class NewsController extends Controller { - - private $feedMapper; - private $folderMapper; - - /** - * @param Request $request: the object with the request instance - * @param string $api: an instance of the api wrapper object - * @param FolderMapper $folderMapper: an instance of the folder mapper - * @param FeedMapper $feedMapper: an instance of the feed mapper - */ - public function __construct($request, $api, $feedMapper, $folderMapper){ - parent::__construct($request, $api); - $this->feedMapper = $feedMapper; - $this->folderMapper = $folderMapper; - $this->api->activateNavigationEntry(); - } - - - /** - * OPML export download page - */ - public function exportOPML($urlParams=array()){ - $opmlExporter = new OPMLExporter($this->api); - - $allFeeds = $this->folderMapper->childrenOfWithFeeds(0); - $opml = $opmlExporter->buildOPML($allFeeds); - - $fileName = 'ownCloud ' . $this->trans->t('News') . ' ' . $this->userId . '.opml'; - $contentType = 'application/x.opml+xml'; - $response = new TextDownloadResponse($opml, $fileName, $contentType); - - return $response; - } - - - /** - * Decides wether to show the feedpage or the firstrun page - */ - public function index($urlParams=array()){ - $this->api->add3rdPartyScript('angular-1.0.2/angular.min'); - $this->api->add3rdPartyScript('moment.min'); - $this->api->addScript('app'); - $this->api->addStyle('news'); - - - if($urlParams['feedid']){ - $this->api->setUserValue('lastViewedFeed', $urlParams['feedid']); - $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); - } - - $lastViewedFeedId = $this->api->getUserValue('lastViewedFeed'); - $lastViewedFeedType = $this->api->getUserValue('lastViewedFeedType'); - - if( $lastViewedFeedId === null || $lastViewedFeedType === null) { - $this->api->setUserValue('lastViewedFeed', $this->feedMapper->mostRecent());; - $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); - - } else { - // check if the last selected feed or folder exists - if(($lastViewedFeedType === FeedType::FEED && - $this->feedMapper->findById($lastViewedFeedId) === null) || - ($lastViewedFeedType === FeedType::FOLDER && - $this->folderMapper->findById($lastViewedFeedId) === null)){ - $this->api->setUserValue('lastViewedFeed', $this->feedMapper->mostRecent());; - $this->api->setUserValue('lastViewedFeedType', FeedType::FEED); - } - } - - return $this->render('main'); - } - - -} diff --git a/tests/classloader.php b/tests/classloader.php new file mode 100644 index 000000000..310dbea07 --- /dev/null +++ b/tests/classloader.php @@ -0,0 +1,35 @@ +. + * + */ + +// to execute without owncloud, we need to create our own classloader +spl_autoload_register(function ($className){ + if (strpos($className, 'OCA\\') === 0) { + + $path = strtolower(str_replace('\\', '/', substr($className, 3)) . '.php'); + $relPath = __DIR__ . '/../..' . $path; + + if(file_exists($relPath)){ + require_once $relPath; + } + } +}); \ No newline at end of file diff --git a/tests/controller/FolderControllerTest.php b/tests/controller/FolderControllerTest.php new file mode 100644 index 000000000..dd31bc62e --- /dev/null +++ b/tests/controller/FolderControllerTest.php @@ -0,0 +1,80 @@ +. +* +*/ + +namespace OCA\News\Controller; + +use \OCA\AppFramework\Http\Request; + + +require_once(__DIR__ . "/../classloader.php"); + + +class FolderControllerTest extends \PHPUnit_Framework_TestCase { + + private $api; + private $folderMapper; + private $request; + private $controller; + + + /** + * Gets run before each test + */ + public function setUp(){ + $this->api = $this->getMock('\OCA\AppFramework\Core\API', + null, array('news')); + $this->folderMapper = $this->getMock('FolderMapper', + array('getAll')); + $this->request = new Request(); + $this->controller = new FolderController($this->api, $this->request, + $this->folderMapper); + + } + + + public function testGetAllCalled(){ + $this->folderMapper->expects($this->once()) + ->method('getAll') + ->will($this->returnValue( array() )); + + $this->controller->getAll(); + } + + + public function testGetAllReturnsFolders(){ + $return = array( + 'folder1' => 'name1', + 'folder2' => 'name2' + ); + $this->folderMapper->expects($this->once()) + ->method('getAll') + ->will($this->returnValue($return)); + + $response = $this->controller->getAll(); + $this->assertEquals($return, $response->getParams()); + } + + +} \ No newline at end of file diff --git a/tests/index.php b/tests/index.php deleted file mode 100644 index 6f3ff037d..000000000 --- a/tests/index.php +++ /dev/null @@ -1,13 +0,0 @@ -assertTrue(false); - } -} -*/ -- cgit v1.2.3