From 1764d5f5c4de44e2d2f496edbfaf2dbd09fabaee Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 19 Jun 2013 16:09:31 +0200 Subject: [PATCH] Fixed order in entry/update, fixed a lot of codestyle --- .../Phrasea/Controller/Admin/Publications.php | 42 ++--- lib/Alchemy/Phrasea/Controller/Prod/Feed.php | 107 +++++++------ lib/Alchemy/Phrasea/Controller/Prod/Root.php | 3 + .../Phrasea/Controller/Root/RSSFeeds.php | 15 +- lib/Alchemy/Phrasea/Feed/Aggregate.php | 143 ++++++++++++++---- lib/Alchemy/Phrasea/Feed/AggregateToken.php | 41 ++--- lib/Alchemy/Phrasea/Feed/FeedInterface.php | 46 ++++++ .../Phrasea/Feed/Formatter/AtomFormatter.php | 46 +++--- .../Feed/Formatter/CoolirisFormatter.php | 67 ++++---- .../Feed/Formatter/FeedFormatterAbstract.php | 47 +++--- .../Feed/Formatter/FeedFormatterInterface.php | 28 +++- .../Phrasea/Feed/Formatter/RssFormatter.php | 33 ++-- .../Feed/Link/AggregateLinkGenerator.php | 31 +++- lib/Alchemy/Phrasea/Feed/Link/FeedLink.php | 14 +- .../Phrasea/Feed/Link/FeedLinkGenerator.php | 48 ++++-- .../Phrasea/Feed/Link/FeedLinkInterface.php | 6 + .../Feed/Link/LinkGeneratorCollection.php | 14 ++ .../Feed/Link/LinkGeneratorInterface.php | 29 +++- lib/Doctrine/Entities/Feed.php | 73 ++++++++- lib/Doctrine/Entities/FeedEntry.php | 17 ++- lib/Doctrine/Entities/FeedItem.php | 10 ++ lib/Doctrine/Entities/FeedPublisher.php | 2 +- .../Repositories/AggregateTokenRepository.php | 8 + .../Repositories/FeedTokenRepository.php | 9 ++ .../Repositories/OrderElementRepository.php | 23 ++- .../Repositories/SessionRepository.php | 2 +- .../Repositories/UserSettingRepository.php | 32 ++-- lib/classes/patch/320f.php | 9 +- templates/web/prod/index.html.twig | 6 +- .../Controller/Admin/PublicationTest.php | 6 +- .../Phrasea/Controller/Prod/FeedTest.php | 68 ++++++++- 31 files changed, 719 insertions(+), 306 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index e19bf9d6df..afc5520f9a 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -48,6 +48,10 @@ class Publications implements ControllerProviderInterface $controllers->post('/create/', function(PhraseaApplication $app, Request $request) { + if ('' === $title = trim($request->request->get('title', ''))) { + $app->abort(400, "Bad request"); + } + $publisher = new FeedPublisher(); $feed = new Feed(); @@ -57,9 +61,8 @@ class Publications implements ControllerProviderInterface $publisher->setIsOwner(true); $feed->addPublisher($publisher); - $feed->setTitle($request->request->get('title')); - $feed->setSubtitle($request->request->get('subtitle')); - $feed->setIconUrl(false); + $feed->setTitle($title); + $feed->setSubtitle($request->request->get('subtitle', '')); if ($request->request->get('public') == '1') { $feed->setIsPublic(true); @@ -88,6 +91,10 @@ class Publications implements ControllerProviderInterface $controllers->post('/feed/{id}/update/', function(PhraseaApplication $app, Request $request, $id) { + if ('' === $title = trim($request->request->get('title', ''))) { + $app->abort(400, "Bad request"); + } + $feed = $app["EM"]->find('Entities\Feed', $id); try { @@ -95,14 +102,10 @@ class Publications implements ControllerProviderInterface } catch (\Exception $e) { $collection = null; } - if (null !== $title = $request->request->get('title')) { - $feed->setTitle($title); - } - if (null !== $subtitle = $request->request->get('subtitle')) { - $feed->setSubtitle($subtitle); - } + $feed->setTitle($title); + $feed->setSubtitle($request->request->get('subtitle', '')); $feed->setCollection($collection); - $feed->setIsPublic($request->request->get('public') === '1' ? true : false); + $feed->setIsPublic('1' === $request->request->get('public')); $app['EM']->persist($feed); $app['EM']->flush(); @@ -110,7 +113,7 @@ class Publications implements ControllerProviderInterface })->before(function(Request $request) use ($app) { $feed = $app["EM"]->find('Entities\Feed', $request->attributes->get('id')); - if (!$feed->getOwner($app['authentication']->getUser())) { + if (!$feed->isOwner($app['authentication']->getUser())) { return $app->redirectPath('admin_feeds_feed', array('id' => $request->attributes->get('id'), 'error' => _('You are not the owner of this feed, you can not edit it'))); } }) @@ -176,16 +179,14 @@ class Publications implements ControllerProviderInterface $app['EM']->persist($feed); $app['EM']->flush(); - $baseDir = realpath(__DIR__ . '/../../../../../'); - - $app['filesystem']->copy($tmpname, $baseDir . '/config/feed_' . $feed->getId() . '.jpg'); + $app['filesystem']->copy($tmpname, $app['root.path'] . '/config/feed_' . $feed->getId() . '.jpg'); $app['filesystem']->copy($tmpname, 'custom/feed_' . $feed->getId() . '.jpg'); $app['filesystem']->remove($tmpname); $datas['success'] = true; } catch (\Exception $e) { - $datas['message'] = _('Unable to add file to Phraseanet') . $e->getMessage(); + $datas['message'] = _('Unable to add file to Phraseanet'); } return $app->json($datas); @@ -202,7 +203,6 @@ class Publications implements ControllerProviderInterface $publisher = new FeedPublisher(); $publisher->setUsrId($user->get_id()); - $publisher->setIsOwner(false); $publisher->setFeed($feed); $feed->addPublisher($publisher); @@ -232,7 +232,7 @@ class Publications implements ControllerProviderInterface } $user = $publisher->getUser($app); - if ($feed->isPublisher($user) === true && $feed->isOwner($user) === false) { + if ($feed->isPublisher($user) && false === $feed->isOwner($user)) { $feed->removePublisher($publisher); $app['EM']->remove($publisher); @@ -249,10 +249,12 @@ class Publications implements ControllerProviderInterface $controllers->post('/feed/{id}/delete/', function(PhraseaApplication $app, $id) { $feed = $app["EM"]->find('Entities\Feed', $id); - $publishers = $feed->getPublishers(); - foreach ($publishers as $publisher) { - $app['EM']->remove($publisher); + + if (true === $feed->getIconURL()) { + unlink($app['root.path'] . '/config/feed_' . $feed->getId() . '.jpg'); + unlink('custom/feed_' . $feed->getId() . '.jpg'); } + $app['EM']->remove($feed); $app['EM']->flush(); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php index 16eb2a3342..9929a05e00 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -53,46 +53,50 @@ class Feed implements ControllerProviderInterface * I've selected a publication for my docs, let's publish them */ $controllers->post('/entry/create/', function(Application $app, Request $request) { - try { - $feed = $app['EM']->getRepository('Entities\Feed')->find($request->request->get('feed_id')); - $publisher = $app['EM']->getRepository('Entities\FeedPublisher')->findByUser($feed, $app['authentication']->getUser()); - $title = $request->request->get('title'); - $subtitle = $request->request->get('subtitle'); - $author_name = $request->request->get('author_name'); - $author_email = $request->request->get('author_mail'); + $feed = $app['EM']->getRepository('Entities\Feed')->find($request->request->get('feed_id')); - $entry = new FeedEntry(); - $entry->setFeed($feed); - $entry->setPublisher($publisher); - $entry->setTitle($title); - $entry->setSubtitle($subtitle); - $entry->setAuthorName($author_name); - $entry->setAuthorEmail($author_email); - - $feed->addEntry($entry); - - $publishing = RecordsRequest::fromRequest($app, $request, true, array(), array('bas_chupub')); - foreach ($publishing as $record) { - $item = new FeedItem(); - $item->setEntry($entry); - $item->setRecordId($record->get_record_id()); - $item->setSbasId($record->get_sbas_id()); - $item->setLastInFeedItem(); - $entry->addItem($item); - $app['EM']->persist($item); - } - - $app['EM']->persist($entry); - $app['EM']->persist($feed); - $app['EM']->flush(); - - $app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId()), $entry); - - $datas = array('error' => false, 'message' => false); - } catch (\Exception $e) { - $datas = array('error' => true, 'message' => _('An error occured'), 'details' => $e->getMessage()); + if (null === $feed) { + $app->abort(404, "Feed not found"); } + $publisher = $app['EM']->getRepository('Entities\FeedPublisher')->findByUser($feed, $app['authentication']->getUser()); + + if ('' === $title = trim($request->request->get('title', ''))) { + $app->abort(400, "Bad request"); + } + + if (!$feed->isPublisher($app['authentication']->getUser())) { + $app->abort(403, 'Unathorized action'); + } + + $entry = new FeedEntry(); + $entry->setAuthorEmail($request->request->get('author_mail')) + ->setAuthorName($request->request->get('author_name')) + ->setTitle($title) + ->setFeed($feed) + ->setPublisher($publisher) + ->setSubtitle($request->request->get('subtitle', '')); + + $feed->addEntry($entry); + + $publishing = RecordsRequest::fromRequest($app, $request, true, array(), array('bas_chupub')); + foreach ($publishing as $record) { + $item = new FeedItem(); + $item->setEntry($entry) + ->setRecordId($record->get_record_id()) + ->setSbasId($record->get_sbas_id()); + $entry->addItem($item); + $app['EM']->persist($item); + } + + $app['EM']->persist($entry); + $app['EM']->persist($feed); + $app['EM']->flush(); + + $app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId()), $entry); + + $datas = array('error' => false, 'message' => false); + return $app->json($datas); }) ->bind('prod_feeds_entry_create') @@ -107,7 +111,7 @@ class Feed implements ControllerProviderInterface throw new AccessDeniedHttpException(); } - $feeds = $app['EM']->getRepository('Entities\Feed')->findAll(); + $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser()); $datas = $app['twig']->render('prod/actions/publish/publish_edit.html.twig', array('entry' => $entry, 'feeds' => $feeds)); @@ -129,20 +133,18 @@ class Feed implements ControllerProviderInterface if (!$entry->isPublisher($app['authentication']->getUser())) { $app->abort(403, 'Unathorized action'); } + if ('' === $title = trim($request->request->get('title', ''))) { + $app->abort(400, "Bad request"); + } - $title = $request->request->get('title'); - $subtitle = $request->request->get('subtitle'); - $author_name = $request->request->get('author_name'); - $author_mail = $request->request->get('author_mail'); - - $entry->setAuthorEmail($author_mail) - ->setAuthorName($author_name) + $entry->setAuthorEmail($request->request->get('author_mail')) + ->setAuthorName($request->request->get('author_name')) ->setTitle($title) - ->setSubtitle($subtitle); + ->setSubtitle($request->request->get('subtitle', '')); $current_feed_id = $entry->getFeed()->getId(); $new_feed_id = $request->request->get('feed_id', $current_feed_id); - if ($current_feed_id != $new_feed_id) { + if ($current_feed_id !== (int) $new_feed_id) { $new_feed = $app['EM']->getRepository('Entities\Feed')->find($new_feed_id); @@ -163,10 +165,7 @@ class Feed implements ControllerProviderInterface if (count($item_sort_datas) != 2) { continue; } - - $item = new FeedItem(); - $item->setEntry($entry); - $entry->addItem($item); + $item = $app['EM']->getRepository('Entities\FeedItem')->find($item_sort_datas[0]); $item->setOrd($item_sort_datas[1]); $app['EM']->persist($item); } @@ -214,7 +213,7 @@ class Feed implements ControllerProviderInterface $page = (int) $request->query->get('page'); $page = $page > 0 ? $page : 1; - $feeds = $app['EM']->getRepository('Entities\Feed')->findAll(); + $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser()); $datas = $app['twig']->render('prod/feeds/feeds.html.twig' , array( @@ -232,7 +231,7 @@ class Feed implements ControllerProviderInterface $page = $page > 0 ? $page : 1; $feed = $app['EM']->getRepository('Entities\Feed')->loadWithUser($app, $app['authentication']->getUser(), $id); - $feeds = $app['EM']->getRepository('Entities\Feed')->findAll(); + $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser()); $datas = $app['twig']->render('prod/feeds/feeds.html.twig', array('feed' => $feed, 'feeds' => $feeds, 'page' => $page)); @@ -244,7 +243,7 @@ class Feed implements ControllerProviderInterface $controllers->get('/subscribe/aggregated/', function(Application $app, Request $request) { $renew = ($request->query->get('renew') === 'true'); - $feeds = $app['EM']->getRepository('Entities\Feed')->findAll(); + $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser()); $aggregate = new Aggregate($app['EM'], $feeds); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php index 68ecbe102d..f457634755 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php @@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Controller\Prod; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Exception\SessionNotFound; +use Alchemy\Phrasea\Feed\Aggregate; use Silex\Application as SilexApplication; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; @@ -73,6 +74,7 @@ class Root implements ControllerProviderInterface } $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser()); + $aggregate = Aggregate::createFromUser($app['EM'], $app['authentication']->getUser()); $thjslist = ""; @@ -115,6 +117,7 @@ class Root implements ControllerProviderInterface 'cgus_agreement' => \databox_cgu::askAgreement($app), 'css' => $css, 'feeds' => $feeds, + 'aggregate' => $aggregate, 'GV_google_api' => $app['phraseanet.registry']->get('GV_google_api'), 'queries_topics' => $queries_topics, 'search_status' => \databox_status::getSearchStatus($app), diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php index ac282593c5..f2e34561eb 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php +++ b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php @@ -27,12 +27,11 @@ class RSSFeeds implements ControllerProviderInterface public function connect(Application $app) { $controllers = $app['controllers_factory']; - $that = $this; $controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) { $feed = $app['EM']->getRepository('Entities\Feed')->find($id); - if (!$feed) { + if (null === $feed) { $app->abort(404, 'Feed not found'); } @@ -54,9 +53,8 @@ class RSSFeeds implements ControllerProviderInterface $controllers->get('/userfeed/{token}/{id}/{format}/', function(Application $app, $token, $id, $format) { $token = $app["EM"]->find('Entities\FeedToken', $id); $feed = $token->getFeed(); - $usrId = $token->getUsrId(); - $user = \User_Adapter::getInstance($usrId, $app); + $user = \User_Adapter::getInstance($token->getUsrId(), $app); $request = $app['request']; @@ -71,9 +69,8 @@ class RSSFeeds implements ControllerProviderInterface $controllers->get('/userfeed/aggregated/{token}/{format}/', function(Application $app, $token, $format) { $token = $app['EM']->getRepository('Entities\AggregateToken')->findOneBy(array("value" => $token)); - $usrId = $token->getUsrId(); - $user = \User_Adapter::getInstance($usrId, $app); + $user = \User_Adapter::getInstance($token->getUsrId(), $app); $feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($user); @@ -90,8 +87,7 @@ class RSSFeeds implements ControllerProviderInterface ->assert('format', '(rss|atom)'); $controllers->get('/aggregated/{format}/', function(Application $app, $format) { - $feeds = $app['EM']->getRepository('Entities\Feed')->findAllPublic(); - $feed = new Aggregate($app['EM'], $feeds); + $feed = Aggregate::getPublic($app); $request = $app['request']; $page = (int) $request->query->get('page'); @@ -103,8 +99,7 @@ class RSSFeeds implements ControllerProviderInterface ->assert('format', '(rss|atom)'); $controllers->get('/cooliris/', function(Application $app) { - $feeds = $app['EM']->getRepository('Entities\Feed')->findAllPublic(); - $feed = new Aggregate($app['EM'], $feeds); + $feed = Aggregate::getPublic($app); $request = $app['request']; $page = (int) $request->query->get('page'); diff --git a/lib/Alchemy/Phrasea/Feed/Aggregate.php b/lib/Alchemy/Phrasea/Feed/Aggregate.php index 133e66e5c8..ca1a347d7b 100644 --- a/lib/Alchemy/Phrasea/Feed/Aggregate.php +++ b/lib/Alchemy/Phrasea/Feed/Aggregate.php @@ -1,43 +1,51 @@ title = 'AGGREGATE'; @@ -58,6 +66,14 @@ class Aggregate implements FeedInterface return $this; } + /** + * Creates an aggregate from all the feeds available to a given user. + * + * @param EntityManager $em + * @param \User_Adapter $user + * + * @return Aggregate + */ public static function createFromUser(EntityManager $em, \User_Adapter $user) { $feeds = $em->getRepository('Entities\Feed')->getAllForUser($user); @@ -66,6 +82,14 @@ class Aggregate implements FeedInterface return new static($em, $feeds, $token); } + /** + * Creates an aggregate from given Feed id array. + * + * @param EntityManager $em + * @param array $feed_ids + * + * @return Aggregate + */ public static function create(Application $app, array $feed_ids) { $feeds = $this->em->getRepository('Entities\Feed')->findByIdArray($feed_ids); @@ -73,60 +97,101 @@ class Aggregate implements FeedInterface return new static($app, $feeds); } + /** + * {@inheritdoc} + */ public function isAggregated() { return true; } + /** + * {@inheritdoc} + */ public function getEntries($offset_start = null, $how_many = null) { - if (count($this->feeds) == 0) { + if (0 === count($this->feeds)) { return null; } return $this->em->getRepository('Entities\FeedEntry')->findByFeeds($this->feeds, $offset_start, $how_many); } + /** + * {@inheritdoc} + */ public function getSubtitle() { return $this->subtitle; } + /** + * {@inheritdoc} + */ public function getTitle() { return $this->title; } + /** + * {@inheritdoc} + */ public function getIconUrl() { return false; } + /** + * {@inheritdoc} + */ public function getCreatedOn() { return $this->created_on; } + /** + * {@inheritdoc} + */ public function getUpdatedOn() { return $this->updated_on; } + /** + * Get AggregateToken + * + * @return AggregateToken + */ public function getToken() { return $this->token; } + /** + * Set AggregateToken + * + * @param AggregateToken $token + */ public function setToken($token) { $this->token = $token; } + /** + * Get Feeds + * + * @return array + */ public function getFeeds() { return $this->feeds; } + /** + * Returns the total number of entries from all the feeds. + * + * @return int + */ public function getCountTotalEntries() { if (count($this->feeds) > 0) { @@ -136,11 +201,31 @@ class Aggregate implements FeedInterface return 0; } + /** + * {@inheritdoc} + */ public function hasPage($page, $pageSize) { + if (0 >= $pageSize) { + throw new LogicException; + } + $count = $this->getCountTotalEntries(); - if ($page >= $count / $pageSize) + if (0 > $page && $page <= $count / $pageSize) { return true; + } return false; } + + /** + * Creates an Aggregate from all the public feeds. + * + * @param Application $app + * + * @return Aggregate + */ + public static function getPublic(Application $app) + { + return new static($app['EM'], $app['EM']->getRepository('Entities\Feed')->findAllPublic()); + } } diff --git a/lib/Alchemy/Phrasea/Feed/AggregateToken.php b/lib/Alchemy/Phrasea/Feed/AggregateToken.php index 3034d7017e..175c793154 100644 --- a/lib/Alchemy/Phrasea/Feed/AggregateToken.php +++ b/lib/Alchemy/Phrasea/Feed/AggregateToken.php @@ -1,26 +1,31 @@ feed = $feed; + $this->aggregatedFeed = $feed; return $this; } @@ -71,11 +76,11 @@ class AggregateToken /** * Get feed * - * @return \Entities\Feed + * @return Aggregate */ public function getFeed() { - return $this->feed; + return $this->aggregatedFeed; } /** * @var string @@ -86,7 +91,7 @@ class AggregateToken * Set value * * @param string $value - * @return FeedToken + * @return AggregateToken */ public function setValue($value) { diff --git a/lib/Alchemy/Phrasea/Feed/FeedInterface.php b/lib/Alchemy/Phrasea/Feed/FeedInterface.php index 976cc07d6b..3780f31a26 100644 --- a/lib/Alchemy/Phrasea/Feed/FeedInterface.php +++ b/lib/Alchemy/Phrasea/Feed/FeedInterface.php @@ -13,19 +13,65 @@ namespace Alchemy\Phrasea\Feed; interface FeedInterface { + /** + * Returns a boolean indicating whether the feed has a custom icon. + * + * @return boolean + */ public function getIconUrl(); + /** + * Returns an UTF-8 title for the feed. + * + * @return string + */ public function getTitle(); + /** + * Returns a collection of FeedEntry. + * + * @param integer $offset_start + * @param integer $how_many + * + * @return \Doctrine\Common\Collections\Collection + */ public function getEntries($offset_start = 0, $how_many = null); + /** + * Returns an UTF-8 subtitle for the feed. + * + * @return string + */ public function getSubtitle(); + /** + * Returns a boolean indicating whether the feed is aggregated or not. + * + * @return boolean + */ public function isAggregated(); + /** + * Returns the date of creation of the feed. + * + * @return \DateTime + */ public function getCreatedOn(); + /** + * Returns the date of last update of the feed. + * + * @return \DateTime + */ public function getUpdatedOn(); + /** + * Returns a boolean indicating whether the feed has a given page. + * + * @param integer $page + * @param integer $pageSize + * + * @return \DateTime + */ public function hasPage($page, $pageSize); } diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php index 6d6c834fc0..8b6a57acd3 100644 --- a/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php +++ b/lib/Alchemy/Phrasea/Feed/Formatter/AtomFormatter.php @@ -22,24 +22,30 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf const FORMAT = 'atom'; private $linkGenerator; + /** + * @param LinkGeneratorCollection $generator + */ public function __construct(LinkGeneratorCollection $generator) { $this->linkGenerator = $generator; } - public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet') + /** + * {@inheritdoc} + */ + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { - $content = $this->format($feed, $page, $user, $generator); + $content = $this->format($feed, $page, $user, $generator, $app); $response = new Response($content, 200, array('Content-Type' => 'application/atom+xml')); - $response->setCharset('UTF-8'); return $response; } - public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', $app = null) + /** + * {@inheritdoc} + */ + public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { - $title = $feed->getTitle(); - $subtitle = $feed->getSubtitle(); $updated_on = $feed->getUpdatedOn(); $document = new \DOMDocument('1.0', 'UTF-8'); @@ -50,29 +56,28 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf $root->setAttribute('xmlns', 'http://www.w3.org/2005/Atom'); $root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/'); - $this->addTag($document, $root, 'title', $title); + $this->addTag($document, $root, 'title', $feed->getTitle()); if ($updated_on instanceof \DateTime) { $updated_on = $updated_on->format(DATE_ATOM); $this->addTag($document, $root, 'updated', $updated_on); } + $next = $prev = null; + if ($feed->hasPage($page + 1, static::PAGE_SIZE)) { if (null === $user) { $next = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page + 1); } else { $next = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page + 1); } - } else { - $next = null; } + if ($feed->hasPage($page - 1, static::PAGE_SIZE)) { if (null === $user) { $prev = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page - 1); } else { $prev = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page - 1); } - } else { - $prev = null; } if (null !== $user) { @@ -100,12 +105,15 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf $next_link->setAttribute('href', $next->getURI()); } - if (isset($generator)) + if (null !== $generator) { $this->addTag($document, $root, 'generator', $generator); - if (isset($subtitle)) - $this->addTag($document, $root, 'subtitle', $subtitle); - if (isset($this->icon)) + } + if (null !== $feed->getSubtitle()) { + $this->addTag($document, $root, 'subtitle', $feed->getSubtitle()); + } + if (isset($this->icon)) { $this->addTag($document, $root, 'icon', $this->icon); + } if (isset($this->author)) { $author = $this->addTag($document, $root, 'author'); if (isset($this->author_email)) @@ -142,11 +150,13 @@ class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterf $this->addTag($document, $entry_node, 'title', $entry->getTitle()); $author = $this->addTag($document, $entry_node, 'author'); - if ($entry->getAuthorEmail()) + if ($entry->getAuthorEmail()) { $this->addTag($document, $author, 'email', $entry->getAuthorEmail()); - if ($entry->getAuthorName()) + } + if ($entry->getAuthorName()) { $this->addTag($document, $author, 'name', $entry->getAuthorName()); - + } + $this->addTag($document, $entry_node, 'content', $entry->getSubtitle()); foreach ($entry->getItems() as $content) { diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php index ef0a830c18..3caf35f83d 100644 --- a/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php +++ b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php @@ -23,24 +23,30 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn const VERSION = '2.0'; private $linkGenerator; + /** + * @param LinkGeneratorCollection $generator + */ public function __construct(LinkGeneratorCollection $generator) { $this->linkGenerator = $generator; } - public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', $app = null) + /** + * {@inheritdoc} + */ + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { $content = $this->format($feed, $page, $user, $generator, $app); $response = new Response($content, 200, array('Content-Type' => 'application/rss+xml')); - $response->setCharset('UTF-8'); return $response; } - public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', $app = null) + /** + * {@inheritdoc} + */ + public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { - $title = $feed->getTitle(); - $subtitle = $feed->getSubtitle(); $updated_on = $feed->getUpdatedOn(); $doc = new \DOMDocument('1.0', 'UTF-8'); @@ -56,9 +62,9 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $channel = $this->addTag($doc, $root, 'channel'); - $this->addTag($doc, $channel, 'title', $title); - $this->addTag($doc, $channel, 'dc:title', $title); - $this->addTag($doc, $channel, 'description', $subtitle); + $this->addTag($doc, $channel, 'title', $feed->getTitle()); + $this->addTag($doc, $channel, 'dc:title', $feed->getTitle()); + $this->addTag($doc, $channel, 'description', $feed->getSubtitle()); if (null !== $user) { $link = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page); @@ -66,8 +72,9 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $link = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page); } - if ($link instanceof FeedLink) + if ($link instanceof FeedLink) { $this->addTag($doc, $channel, 'link', $link->getURI()); + } if (isset($this->language)) $this->addTag($doc, $channel, 'language', $this->language); @@ -126,23 +133,22 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $self_link->setAttribute('href', $link->getURI()); } + $next = $prev = null; + if ($feed->hasPage($page + 1, static::PAGE_SIZE)) { if (null === $user) { $next = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page + 1); } else { $next = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page + 1); } - } else { - $next = null; } + if ($feed->hasPage($page - 1, static::PAGE_SIZE)) { if (null === $user) { $prev = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page - 1); } else { $prev = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page - 1); } - } else { - $prev = null; } $prefix = 'atom'; @@ -175,7 +181,6 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn protected function addContent(Application $app, \DOMDocument $document, \DOMNode $node, FeedItem $content) { - $preview_sd = $content->getRecord($app)->get_subdef('preview'); $preview_permalink = $preview_sd->get_permalink(); $thumbnail_sd = $content->getRecord($app)->get_thumbnail(); @@ -187,7 +192,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn return $this; } - if (! $preview_permalink || ! $thumbnail_permalink) { + if (null === $preview_permalink || null === $thumbnail_permalink) { return $this; } @@ -197,7 +202,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $caption = $content->getRecord($app)->get_caption(); $title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title); - if ($title_field) { + if (null !== $title_field) { $str_title = $title_field->get_serialized_values(' '); } else { $str_title = $content->getRecord($app)->get_title(); @@ -207,7 +212,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $title = $this->addTag($document, $item, 'title', $str_title); $desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description); - if ($desc_field) { + if (null !== $desc_field) { $str_desc = $desc_field->get_serialized_values(' '); } else { $str_desc = ''; @@ -218,7 +223,7 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $duration = $content->getRecord($app)->get_duration(); - if ($preview_permalink) { + if (null !== $preview_permalink) { $preview = $this->addTag($document, $item, 'media:content'); $preview->setAttribute('url', $preview_permalink->get_url()); @@ -228,23 +233,28 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $preview->setAttribute('expression', 'full'); $preview->setAttribute('isDefault', 'true'); - if ($preview_sd->get_width()) + if (null !== $preview_sd->get_width()) { $preview->setAttribute('width', $preview_sd->get_width()); - if ($preview_sd->get_height()) + } + if (null !== $preview_sd->get_height()) { $preview->setAttribute('height', $preview_sd->get_height()); - if ($duration) + } + if (null !== $duration) { $preview->setAttribute('duration', $duration); + } } - if ($thumbnail_permalink) { + if (null !== $thumbnail_permalink) { $thumbnail = $this->addTag($document, $item, 'media:thumbnail'); $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); - if ($thumbnail_sd->get_width()) + if (null !== $thumbnail_sd->get_width()) { $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); - if ($thumbnail_sd->get_height()) + } + if (null !== $thumbnail_sd->get_height()) { $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + } $thumbnail = $this->addTag($document, $item, 'media:content'); @@ -254,12 +264,15 @@ class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterIn $thumbnail->setAttribute('medium', $medium); $thumbnail->setAttribute('isDefault', 'false'); - if ($thumbnail_sd->get_width()) + if (null !== $thumbnail_sd->get_width()) { $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); - if ($thumbnail_sd->get_height()) + } + if (null !== $thumbnail_sd->get_height()) { $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); - if ($duration) + } + if (null !== $duration) { $thumbnail->setAttribute('duration', $duration); + } } return $this; diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php index a2a6b6ca2c..0a77fe9b51 100644 --- a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php +++ b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php @@ -29,8 +29,9 @@ abstract class FeedFormatterAbstract { $tag = $document->createElement($tagname); - if (trim($tagcontent) !== '') + if (trim($tagcontent) !== '') { $tag->appendChild($document->createTextNode($tagcontent)); + } $node->appendChild($tag); return $tag; @@ -56,7 +57,7 @@ abstract class FeedFormatterAbstract return $this; } - if (! $preview_permalink || ! $thumbnail_permalink) { + if (null === $preview_permalink || null === $thumbnail_permalink) { return $this; } @@ -65,21 +66,21 @@ abstract class FeedFormatterAbstract $caption = $content->getRecord($app)->get_caption(); $title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title); - if ($title_field) { + if (null !== $title_field) { $str_title = $title_field->get_serialized_values(' '); $title = $this->addTag($document, $group, 'media:title', $str_title); $title->setAttribute('type', 'plain'); } $desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description); - if ($desc_field) { + if (null !== $desc_field) { $str_desc = $desc_field->get_serialized_values(' '); $desc = $this->addTag($document, $group, 'media:description', $str_desc); $desc->setAttribute('type', 'plain'); } $contrib_field = $caption->get_dc_field(databox_Field_DCESAbstract::Contributor); - if ($contrib_field) { + if (null !== $contrib_field) { $str_contrib = $contrib_field->get_serialized_values(' '); $contrib = $this->addTag($document, $group, 'media:credit', $str_contrib); $contrib->setAttribute('role', 'contributor'); @@ -87,7 +88,7 @@ abstract class FeedFormatterAbstract } $director_field = $caption->get_dc_field(databox_Field_DCESAbstract::Creator); - if ($director_field) { + if (null !== $director_field) { $str_director = $director_field->get_serialized_values(' '); $director = $this->addTag($document, $group, 'media:credit', $str_director); $director->setAttribute('role', 'director'); @@ -95,7 +96,7 @@ abstract class FeedFormatterAbstract } $publisher_field = $caption->get_dc_field(databox_Field_DCESAbstract::Publisher); - if ($publisher_field) { + if (null !== $publisher_field) { $str_publisher = $publisher_field->get_serialized_values(' '); $publisher = $this->addTag($document, $group, 'media:credit', $str_publisher); $publisher->setAttribute('role', 'publisher'); @@ -103,20 +104,20 @@ abstract class FeedFormatterAbstract } $rights_field = $caption->get_dc_field(databox_Field_DCESAbstract::Rights); - if ($rights_field) { + if (null !== $rights_field) { $str_rights = $rights_field->get_serialized_values(' '); $rights = $this->addTag($document, $group, 'media:copyright', $str_rights); } $keyword_field = $caption->get_dc_field(databox_Field_DCESAbstract::Subject); - if ($keyword_field) { + if (null !== $keyword_field) { $str_keywords = $keyword_field->get_serialized_values(', '); $keywords = $this->addTag($document, $group, 'media:keywords', $str_keywords); } $duration = $content->get_record()->get_duration(); - if ($preview_permalink) { + if (null !== $preview_permalink) { $preview = $this->addTag($document, $group, 'media:content'); $preview->setAttribute('url', $preview_permalink->get_url()); @@ -126,23 +127,28 @@ abstract class FeedFormatterAbstract $preview->setAttribute('expression', 'full'); $preview->setAttribute('isDefault', 'true'); - if ($preview_sd->get_width()) + if (null !== $preview_sd->get_width()) { $preview->setAttribute('width', $preview_sd->get_width()); - if ($preview_sd->get_height()) + } + if (null !== $preview_sd->get_height()) { $preview->setAttribute('height', $preview_sd->get_height()); - if ($duration) + } + if (null !== $duration) { $preview->setAttribute('duration', $duration); + } } - if ($thumbnail_permalink) { + if (null !== $thumbnail_permalink) { $thumbnail = $this->addTag($document, $group, 'media:thumbnail'); $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); - if ($thumbnail_sd->get_width()) + if (null !== $thumbnail_sd->get_width()) { $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); - if ($thumbnail_sd->get_height()) + } + if (null !== $thumbnail_sd->get_height()) { $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + } $thumbnail = $this->addTag($document, $group, 'media:content'); @@ -152,12 +158,15 @@ abstract class FeedFormatterAbstract $thumbnail->setAttribute('medium', $medium); $thumbnail->setAttribute('isDefault', 'false'); - if ($thumbnail_sd->get_width()) + if (null !== $thumbnail_sd->get_width()) { $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); - if ($thumbnail_sd->get_height()) + } + if (null !== $thumbnail_sd->get_height()) { $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); - if ($duration) + } + if (null !== $duration) { $thumbnail->setAttribute('duration', $duration); + } } return $this; diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterInterface.php b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterInterface.php index 7b7c4daf33..75f810a43a 100644 --- a/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterInterface.php +++ b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterInterface.php @@ -1,20 +1,44 @@ linkGenerator = $generator; } - public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet') + /** + * {@inheritdoc} + */ + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { - $content = $this->format($feed, $page, $user, $generator); + $content = $this->format($feed, $page, $user, $generator, $app); $response = new Response($content, 200, array('Content-Type' => 'application/rss+xml')); - $response->setCharset('UTF-8'); return $response; } - public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', $app = null) + /** + * {@inheritdoc} + */ + public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null) { - $title = $feed->getTitle(); - $subtitle = $feed->getSubtitle(); $updated_on = $feed->getUpdatedOn(); + $next = $prev = null; + if ($feed->hasPage($page + 1, static::PAGE_SIZE)) { if (null === $user) { $next = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page + 1); } else { $next = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page + 1); } - } else { - $next = null; } if ($feed->hasPage($page - 1, static::PAGE_SIZE)) { if (null === $user) { @@ -59,8 +65,6 @@ class RssFormatter extends FeedFormatterAbstract implements FeedFormatterInterfa } else { $prev = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page - 1); } - } else { - $prev = null; } if (null !== $user) { @@ -82,11 +86,12 @@ class RssFormatter extends FeedFormatterAbstract implements FeedFormatterInterfa $channel = $this->addTag($doc, $root, 'channel'); - $this->addTag($doc, $channel, 'title', $title); - $this->addTag($doc, $channel, 'dc:title', $title); - $this->addTag($doc, $channel, 'description', $subtitle); - if ($link instanceof FeedLink) + $this->addTag($doc, $channel, 'title', $feed->getTitle()); + $this->addTag($doc, $channel, 'dc:title', $feed->getTitle()); + $this->addTag($doc, $channel, 'description', $feed->getSubtitle()); + if ($link instanceof FeedLink) { $this->addTag($doc, $channel, 'link', $link->getURI()); + } if (isset($this->language)) $this->addTag($doc, $channel, 'language', $this->language); diff --git a/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php index 93ff9ca774..8f5625b6d6 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php +++ b/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php @@ -5,6 +5,7 @@ namespace Alchemy\Phrasea\Feed\Link; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Feed\Aggregate; use Alchemy\Phrasea\Feed\FeedInterface; +use Alchemy\Phrasea\Feed\Link\FeedLink; use Entities\AggregateToken; use Doctrine\ORM\EntityManager; use Symfony\Component\Routing\Generator\UrlGenerator; @@ -18,6 +19,11 @@ class AggregateLinkGenerator implements LinkGeneratorInterface private $generator; private $random; + /** + * @param UrlGenerator $generator + * @param EntityManager $em + * @param \random $random + */ public function __construct(UrlGenerator $generator, EntityManager $em, \random $random) { $this->generator = $generator; @@ -25,6 +31,9 @@ class AggregateLinkGenerator implements LinkGeneratorInterface $this->random = $random; } + /** + * {@inheritdoc} + */ public function generate(FeedInterface $aggregate, \User_Adapter $user, $format, $page = null, $renew = false) { if (!$this->supports($aggregate)) { @@ -33,8 +42,10 @@ class AggregateLinkGenerator implements LinkGeneratorInterface switch ($format) { case self::FORMAT_ATOM: - $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), - 'format' => 'atom'); + $params = array( + 'token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'atom' + ); if (null !== $page) { $params['page'] = $page; } @@ -44,10 +55,11 @@ class AggregateLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), 'application/atom+xml' ); - break; case self::FORMAT_RSS: - $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), - 'format' => 'rss'); + $params = array( + 'token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'rss' + ); if (null !== $page) { $params['page'] = $page; } @@ -57,17 +69,22 @@ class AggregateLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), 'application/rss+xml' ); - break; default: throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); } } + /** + * {@inheritdoc} + */ public function supports(FeedInterface $feed) { return $feed instanceof Aggregate; } + /** + * {@inheritdoc} + */ public function generatePublic(FeedInterface $aggregate, $format, $page = null) { if (!$this->supports($aggregate)) { @@ -86,7 +103,6 @@ class AggregateLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), 'application/atom+xml' ); - break; case self::FORMAT_RSS: $params = array('format' => 'rss'); if (null !== $page) { @@ -98,7 +114,6 @@ class AggregateLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), 'application/rss+xml' ); - break; default: throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); } diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php index 9845e19c98..a82c8deef4 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php @@ -13,27 +13,19 @@ namespace Alchemy\Phrasea\Feed\Link; class FeedLink implements FeedLinkInterface { - /** - * @var string - */ + /** @var string */ protected $mimetype; - /** - * @var string - */ + /** @var string */ protected $title; - /** - * @var string - */ + /** @var string */ protected $uri; /** * @param string $uri * @param string $title * @param string $mimetype - * - * @return FeedLink */ public function __construct($uri, $title, $mimetype) { diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php index 9eb0267de6..d720969dd9 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php @@ -12,9 +12,9 @@ namespace Alchemy\Phrasea\Feed\Link; use Alchemy\Phrasea\Exception\InvalidArgumentException; +use Alchemy\Phrasea\Feed\FeedInterface; use Doctrine\ORM\EntityManager; use Entities\Feed; -use Alchemy\Phrasea\Feed\FeedInterface; use Entities\FeedToken; use Symfony\Component\Routing\Generator\UrlGenerator; @@ -27,6 +27,11 @@ class FeedLinkGenerator implements LinkGeneratorInterface private $generator; private $random; + /** + * @param UrlGenerator $generator + * @param EntityManager $em + * @param \random $random + */ public function __construct(UrlGenerator $generator, EntityManager $em, \random $random) { $this->generator = $generator; @@ -34,6 +39,9 @@ class FeedLinkGenerator implements LinkGeneratorInterface $this->random = $random; } + /** + * {@inheritdoc} + */ public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false) { if (!$this->supports($feed)) { @@ -42,9 +50,11 @@ class FeedLinkGenerator implements LinkGeneratorInterface switch ($format) { case self::FORMAT_ATOM: - $params = array('token' => $this->getFeedToken($feed, $user, $renew)->getValue(), - 'id' => $feed->getId(), - 'format' => 'atom'); + $params = array( + 'token' => $this->getFeedToken($feed, $user, $renew)->getValue(), + 'id' => $feed->getId(), + 'format' => 'atom' + ); if (null !== $page) { $params['page'] = $page; } @@ -54,11 +64,12 @@ class FeedLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $feed->getTitle(), 'Atom'), 'application/atom+xml' ); - break; case self::FORMAT_RSS: - $params = array('token' => $this->getFeedToken($feed, $user, $renew)->getValue(), - 'id' => $feed->getId(), - 'format' => 'rss'); + $params = array( + 'token' => $this->getFeedToken($feed, $user, $renew)->getValue(), + 'id' => $feed->getId(), + 'format' => 'rss' + ); if (null !== $page) { $params['page'] = $page; } @@ -68,17 +79,22 @@ class FeedLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $feed->getTitle(), 'RSS'), 'application/rss+xml' ); - break; default: throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); } } + /** + * {@inheritdoc} + */ public function supports(FeedInterface $feed) { return $feed instanceof Feed; } + /** + * {@inheritdoc} + */ public function generatePublic(FeedInterface $feed, $format, $page = null) { if (!$this->supports($feed)) { @@ -87,8 +103,10 @@ class FeedLinkGenerator implements LinkGeneratorInterface switch ($format) { case self::FORMAT_ATOM: - $params = array('id' => $feed->getId(), - 'format' => 'atom'); + $params = array( + 'id' => $feed->getId(), + 'format' => 'atom' + ); if (null !== $page) { $params['page'] = $page; } @@ -98,10 +116,11 @@ class FeedLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $feed->getTitle(), 'Atom'), 'application/atom+xml' ); - break; case self::FORMAT_RSS: - $params = array('id' => $feed->getId(), - 'format' => 'rss'); + $params = array( + 'id' => $feed->getId(), + 'format' => 'rss' + ); if (null !== $page) { $params['page'] = $page; } @@ -111,7 +130,6 @@ class FeedLinkGenerator implements LinkGeneratorInterface sprintf('%s - %s', $feed->getTitle(), 'RSS'), 'application/rss+xml' ); - break; default: throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); } diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php index 6e158bdc23..29f946b161 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php @@ -14,16 +14,22 @@ namespace Alchemy\Phrasea\Feed\Link; interface FeedLinkInterface { /** + * Returns the mimetype of the link. + * * @return string */ public function getMimetype(); /** + * Returns the title of the link. + * * @return string */ public function getTitle(); /** + * Returns the URI of the link. + * * @return string */ public function getURI(); diff --git a/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorCollection.php b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorCollection.php index 2fe35944fd..81a9089898 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorCollection.php +++ b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorCollection.php @@ -9,11 +9,19 @@ class LinkGeneratorCollection implements LinkGeneratorInterface { private $generators = array(); + /** + * Adds a LinkGeneratorInterface to the internal array. + * + * @param LinkGeneratorInterface $generator + */ public function pushGenerator(LinkGeneratorInterface $generator) { $this->generators[] = $generator; } + /** + * {@inheritdoc} + */ public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false) { if (null === $generator = $this->findGenerator($feed)) { @@ -23,6 +31,9 @@ class LinkGeneratorCollection implements LinkGeneratorInterface return $generator->generate($feed, $user, $format, $page); } + /** + * {@inheritdoc} + */ public function generatePublic(FeedInterface $feed, $format, $page = null) { if (null === $generator = $this->findGenerator($feed)) { @@ -32,6 +43,9 @@ class LinkGeneratorCollection implements LinkGeneratorInterface return $generator->generatePublic($feed, $format, $page); } + /** + * {@inheritdoc} + */ public function supports(FeedInterface $feed) { return null !== $this->findGenerator($feed); diff --git a/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php index 65d9be33ec..312e757039 100644 --- a/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php +++ b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php @@ -7,26 +7,39 @@ use Alchemy\Phrasea\Feed\FeedInterface; interface LinkGeneratorInterface { /** + * Generates a FeedLink based on given FeedInterface and User_Adapter. * - * @param \Alchemy\Phrasea\Feed\FeedInterface $feed - * @param \User_Adapter $user - * @param type $format - * @param type $page - * @param type $renew + * @param FeedInterface $feed + * @param \User_Adapter $user + * @param type $format + * @param type $page + * @param type $renew + * + * @return FeedLink * * @throws InvalidArgumentException */ public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false); /** + * Generates a public FeedLink based on given FeedInterface. * - * @param \Alchemy\Phrasea\Feed\FeedInterface $feed - * @param type $format - * @param type $page + * @param FeedInterface $feed + * @param type $format + * @param type $page + * + * @return FeedLink * * @throws InvalidArgumentException */ public function generatePublic(FeedInterface $feed, $format, $page = null); + /** + * Returns an instance of FeedInterface supported by the class. + * + * @param \Alchemy\Phrasea\Feed\FeedInterface $feed + * + * @return FeedInterface + */ public function supports(FeedInterface $feed); } diff --git a/lib/Doctrine/Entities/Feed.php b/lib/Doctrine/Entities/Feed.php index 09dcd16b37..b4d2eea8ad 100644 --- a/lib/Doctrine/Entities/Feed.php +++ b/lib/Doctrine/Entities/Feed.php @@ -246,6 +246,11 @@ class Feed implements FeedInterface return $this->entries->slice($offset_start, $how_many); } + /** + * Returns the owner of the feed. + * + * @return FeedPublisher + */ public function getOwner() { foreach ($this->getPublishers() as $publisher) { @@ -255,6 +260,13 @@ class Feed implements FeedInterface } } + /** + * Returns a boolean indicating whether the given User_Adapter is the owner of the feed. + * + * @param \User_Adapter $user + * + * @return boolean + */ public function isOwner(\User_Adapter $user) { $owner = $this->getOwner(); @@ -265,6 +277,13 @@ class Feed implements FeedInterface return false; } + /** + * Returns the collection to which the feed belongs. + * + * @param Application $app + * + * @return type + */ public function getCollection(Application $app) { if ($this->getBaseId() !== null) { @@ -272,6 +291,13 @@ class Feed implements FeedInterface } } + /** + * Sets the collection. + * + * @param \collection $collection + * + * @return type + */ public function setCollection(\collection $collection = null) { if ($collection === null) { @@ -328,6 +354,13 @@ class Feed implements FeedInterface return $this->updated_on; } + /** + * Returns a boolean indicating whether the given User_Adapter is a publisher of the feed. + * + * @param \User_Adapter $user + * + * @return boolean + */ public function isPublisher(\User_Adapter $user) { foreach ($this->getPublishers() as $publisher) { @@ -339,6 +372,13 @@ class Feed implements FeedInterface return false; } + /** + * Returns an instance of FeedPublisher matching to the given User_Adapter + * + * @param \User_Adapter $user + * + * @return FeedPublisher + */ public function getPublisher(\User_Adapter $user) { foreach ($this->getPublishers() as $publisher) { @@ -373,16 +413,34 @@ class Feed implements FeedInterface return $this->subtitle; } + /** + * Returns a boolean indicating whether the feed is aggregated. + * + * @return boolean + */ public function isAggregated() { return false; } + /** + * Returns the number of entries the feed contains + * + * @return integer + */ public function getCountTotalEntries() { return (count($this->entries)); } + /** + * Returns a boolean indicating whether the given User_Adapter has access to the feed + * + * @param \User_Adapter $user + * @param Application $app + * + * @return boolean + */ public function hasAccess(\User_Adapter $user, Application $app) { if ($this->getCollection($app) instanceof collection) { @@ -448,11 +506,24 @@ class Feed implements FeedInterface $this->entries->removeElement($entries); } + /** + * Returns a boolean indicating whether the feed contains a given page, assuming a given page size. + * + * @param integer $page + * @param integer $pageSize + * + * @return boolean + */ public function hasPage($page, $pageSize) { + if (0 >= $pageSize) { + throw new LogicException; + } + $count = $this->getCountTotalEntries(); - if ($page >= $count / $pageSize + $pageSize) + if (0 > $page && $page <= $count / $pageSize) { return true; + } return false; } } diff --git a/lib/Doctrine/Entities/FeedEntry.php b/lib/Doctrine/Entities/FeedEntry.php index 5592db4b1d..a0a6e17d2a 100644 --- a/lib/Doctrine/Entities/FeedEntry.php +++ b/lib/Doctrine/Entities/FeedEntry.php @@ -292,16 +292,31 @@ class FeedEntry return $this->feed; } + /** + * Returns a boolean indicating whether the given User_Adapter is the publisher of the entry. + * + * @param \User_Adapter $user + * + * @return boolean + */ public function isPublisher(\User_Adapter $user) { if ($this->publisher) { - if ($this->publisher->getUsrId() === $user->get_id()) + if ($this->publisher->getUsrId() === $user->get_id()) { return true; + } } return false; } + /** + * Returns the item from a given id. + * + * @param int $id + * + * @return null + */ public function getItem($id) { foreach ($this->items as $item) { diff --git a/lib/Doctrine/Entities/FeedItem.php b/lib/Doctrine/Entities/FeedItem.php index 6faa693113..985fc1357f 100644 --- a/lib/Doctrine/Entities/FeedItem.php +++ b/lib/Doctrine/Entities/FeedItem.php @@ -191,11 +191,21 @@ class FeedItem return $this->updated_on; } + /** + * Marks this item as the last added. + */ public function setLastInFeedItem() { $this->setOrd($this->getEntry()->getItems()->count() + 1); } + /** + * Returns the record_adapter associated to this FeedItem. + * + * @param Application $app + * + * @return \record_adapter + */ public function getRecord(Application $app) { return new \record_adapter($app, $this->getSbasId(), $this->getRecordId(), $this->getOrd()); diff --git a/lib/Doctrine/Entities/FeedPublisher.php b/lib/Doctrine/Entities/FeedPublisher.php index 2cd8d4bf89..9e8062ee94 100644 --- a/lib/Doctrine/Entities/FeedPublisher.php +++ b/lib/Doctrine/Entities/FeedPublisher.php @@ -22,7 +22,7 @@ class FeedPublisher /** * @var boolean */ - private $owner; + private $owner = false; /** * @var \DateTime diff --git a/lib/Doctrine/Repositories/AggregateTokenRepository.php b/lib/Doctrine/Repositories/AggregateTokenRepository.php index dd99abba02..a84ddd5b0a 100644 --- a/lib/Doctrine/Repositories/AggregateTokenRepository.php +++ b/lib/Doctrine/Repositories/AggregateTokenRepository.php @@ -3,6 +3,7 @@ namespace Repositories; use Doctrine\ORM\EntityRepository; +use Entities\AggregateToken; /** * AggregateTokenRepository @@ -12,6 +13,13 @@ use Doctrine\ORM\EntityRepository; */ class AggregateTokenRepository extends EntityRepository { + /** + * Finds an AggregateToken based on given User_Adapter. + * + * @param \User_Adapter $user + * + * @return AggregateToken + */ public function findByUser(\User_Adapter $user) { $dql = 'SELECT t diff --git a/lib/Doctrine/Repositories/FeedTokenRepository.php b/lib/Doctrine/Repositories/FeedTokenRepository.php index c592dd4611..ff01aa47b8 100644 --- a/lib/Doctrine/Repositories/FeedTokenRepository.php +++ b/lib/Doctrine/Repositories/FeedTokenRepository.php @@ -4,6 +4,7 @@ namespace Repositories; use Doctrine\ORM\EntityRepository; use Entities\Feed; +use Entities\FeedToken; /** * FeedTokenRepository @@ -13,6 +14,14 @@ use Entities\Feed; */ class FeedTokenRepository extends EntityRepository { + /** + * Finds a FeedToken based on given Feed and User_Adapter. + * + * @param Feed $feed + * @param \User_Adapter $user + * + * @return FeedToken + */ public function findByFeedAndUser(Feed $feed, \User_Adapter $user) { $dql = 'SELECT t diff --git a/lib/Doctrine/Repositories/OrderElementRepository.php b/lib/Doctrine/Repositories/OrderElementRepository.php index 916c536108..424cd60c2f 100644 --- a/lib/Doctrine/Repositories/OrderElementRepository.php +++ b/lib/Doctrine/Repositories/OrderElementRepository.php @@ -3,6 +3,8 @@ namespace Repositories; use Doctrine\ORM\EntityRepository; +use Entities\Feed; +use Entities\FeedPublisher; /** * OrderElementRepository @@ -12,18 +14,15 @@ use Doctrine\ORM\EntityRepository; */ class OrderElementRepository extends EntityRepository { - public function find($id) - { - $dql = 'SELECT f FROM Entities\FeedPublisher f - WHERE f.id = :id '; - - $query = $this->_em->createQuery($dql); - $query->setParameter('id', $id); - - return $query->getOneOrNullResult(); - } - - public function findByUser(\Entities\Feed $feed, \User_Adapter $user) + /** + * Finds a FeedPublisher based on a given Feed and a User_Adapter. + * + * @param Feed $feed + * @param \User_Adapter $user + * + * @return FeedPublisher + */ + public function findByUser(Feed $feed, \User_Adapter $user) { $dql = 'SELECT f FROM Entities\FeedPublisher f WHERE f.usr_id = :usrId AND f.feed = :feed'; diff --git a/lib/Doctrine/Repositories/SessionRepository.php b/lib/Doctrine/Repositories/SessionRepository.php index f0c44306d5..cd2ee6832c 100644 --- a/lib/Doctrine/Repositories/SessionRepository.php +++ b/lib/Doctrine/Repositories/SessionRepository.php @@ -13,10 +13,10 @@ use Doctrine\ORM\EntityRepository; */ class SessionRepository extends EntityRepository { - /** * * @param User_Adapter $user + * * @return \Doctrine\Common\Collections\Collection */ public function getAllForUser(\User_Adapter $user) diff --git a/lib/Doctrine/Repositories/UserSettingRepository.php b/lib/Doctrine/Repositories/UserSettingRepository.php index 193df37898..5ec02bb1e9 100644 --- a/lib/Doctrine/Repositories/UserSettingRepository.php +++ b/lib/Doctrine/Repositories/UserSettingRepository.php @@ -12,29 +12,15 @@ use Doctrine\ORM\EntityRepository; */ class UserSettingRepository extends EntityRepository { - public function find($id) - { - $dql = 'SELECT f FROM Entities\FeedEntry f - WHERE f.id = :id '; - - $query = $this->_em->createQuery($dql); - $query->setParameter('id', $id); - - return $query->getOneOrNullResult(); - } - - public function findByFeed($feed, $id) - { - $dql = 'SELECT f FROM Entities\FeedEntry f - WHERE f.id = :id AND f.feed = :feed'; - - $query = $this->_em->createQuery($dql); - $query->setParameter('id', $id); - $query->setParameter('feed', $feed); - - return $query->getOneOrNullResult(); - } - + /** + * Returns a collection of FeedEntry from given feeds, limited to $how_many results, starting with $offset_start + * + * @param array $feeds + * @param integer $offset_start + * @param integer $how_many + * + * @return \Doctrine\Common\Collections\Collection + */ public function findByFeeds($feeds, $offset_start = null, $how_many = null) { $dql = 'SELECT f FROM Entities\FeedEntry f diff --git a/lib/classes/patch/320f.php b/lib/classes/patch/320f.php index cf2ead259e..cb4d2f07b8 100644 --- a/lib/classes/patch/320f.php +++ b/lib/classes/patch/320f.php @@ -127,7 +127,6 @@ class patch_320f implements patchInterface $entry->addItem($item); $item->setRecordId($record->get_record_id()); $item->setSbasId($record->get_sbas_id()); - $item->setLastInFeedItem(); $app['EM']->persist($item); } catch (NotFoundHttpException $e) { @@ -164,12 +163,13 @@ class patch_320f implements patchInterface protected function get_feed(appbox $appbox, User_Adapter $user, $pub_restrict, $homelink, Application $app) { $user_key = 'user_' . $user->get_id(); - if ($homelink == '1') + if ($homelink == '1') { $feed_key = 'feed_homelink'; - elseif ($pub_restrict == '1') + } elseif ($pub_restrict == '1') { $feed_key = 'feed_restricted'; - else + } else { $feed_key = 'feed_public'; + } if ( ! array_key_exists($user_key, self::$feeds) || ! isset(self::$feeds[$user_key][$feed_key])) { if ($homelink == '1') @@ -183,7 +183,6 @@ class patch_320f implements patchInterface $publisher = new FeedPublisher(); $feed->setTitle('title'); $feed->setSubtitle(''); - $feed->setIconUrl(false); $feed->addPublisher($publisher); $publisher->setFeed($feed); $publisher->setOwner(true); diff --git a/templates/web/prod/index.html.twig b/templates/web/prod/index.html.twig index c8594d97d9..cce1d5a898 100644 --- a/templates/web/prod/index.html.twig +++ b/templates/web/prod/index.html.twig @@ -55,9 +55,13 @@ {% for feed in feeds %} {% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %} - {% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %} + {% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'atom') %} {% endfor %} + {% set link = app['feed.aggregate-link-generator'].generate(aggregate, app['authentication'].getUser(), 'rss') %} + + {% set link = app['feed.aggregate-link-generator'].generate(aggregate, app['authentication'].getUser(), 'atom') %} + {% endblock %} {% block stylesheet %} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php index ef2f01b15a..624966da44 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php @@ -17,10 +17,12 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic foreach ($feeds as $feed) { $this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->getId() . '/', $pageContent); - if ($feed->getCollection() != null) + if ($feed->getCollection() != null) { $this->assertRegExp('/' . $feed->getCollection()->get_label(self::$DI['app']['locale.I18n']) . '/', $pageContent); - if ($feed->isOwner(self::$DI['user'])) + } + if ($feed->isOwner(self::$DI['user'])) { $this->assertEquals(1, $crawler->filterXPath("//form[@action='/admin/publications/feed/" . $feed->getId() . "/delete/']")->count()); + } } } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php index 9caa3fa0d6..9011f44890 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php @@ -3,6 +3,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Prod; use Alchemy\Phrasea\Application; +use Entities\FeedItem; use Symfony\Component\CssSelector\CssSelector; class FeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract @@ -72,12 +73,32 @@ class FeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract , 'lst' => self::$DI['record_1']->get_serialize_key() ); $crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/create/', $params); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type")); - $pageContent = json_decode(self::$DI['client']->getResponse()->getContent()); - $this->assertTrue(is_object($pageContent)); - $this->assertTrue($pageContent->error); - $this->assertTrue(is_string($pageContent->message)); + $this->assertFalse(self::$DI['client']->getResponse()->isOk()); + $this->assertEquals(404, self::$DI['client']->getResponse()->getStatusCode()); + } + + public function testEntryCreateUnauthorized() + { + $feed = $this->insertOneFeed(self::$DI['user_alt1']); + + self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') + ->disableOriginalConstructor() + ->getMock(); + + self::$DI['app']['notification.deliverer']->expects($this->never()) + ->method('deliver'); + + $params = array( + "feed_id" => $feed->getId() + , "title" => "salut" + , "subtitle" => "coucou" + , "author_name" => "robert" + , "author_mail" => "robert@kikoo.mail" + , 'lst' => self::$DI['record_1']->get_serialize_key() + ); + + $crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/create/', $params); + $this->assertEquals(403, self::$DI['client']->getResponse()->getStatusCode()); } public function testEntryEdit() @@ -259,6 +280,41 @@ class FeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $this->assertEquals(403, self::$DI['client']->getResponse()->getStatusCode());; } + public function testEntryUpdateChangeOrder() + { + $item1 = $this->insertOneFeedItem(self::$DI['user']); + $entry = $item1->getEntry(); + $item2 = new FeedItem(); + $item2->setEntry($entry) + ->setRecordId(self::$DI['record_2']->get_record_id()) + ->setSbasId(self::$DI['record_2']->get_sbas_id()); + $entry->addItem($item2); + + self::$DI['app']['EM']->persist($entry); + self::$DI['app']['EM']->persist($item2); + self::$DI['app']['EM']->flush(); + + $ord1 = $item1->getOrd(); + $ord2 = $item2->getOrd(); + + $params = array( + "title" => $entry->getTitle(), + "author_name" => $entry->getAuthorName(), + "author_mail" => $entry->getAuthorEmail(), + 'sorted_lst' => $item1->getId() . '_' . $item2->getOrd() . ';' + . $item2->getId() . '_' . $item1->getOrd() + ); + + $crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params); + $this->assertTrue(self::$DI['client']->getResponse()->isOk()); + + $newItem1 = self::$DI['app']['EM']->getRepository('Entities\FeedItem')->find($item1->getId()); + $newItem2 = self::$DI['app']['EM']->getRepository('Entities\FeedItem')->find($item2->getId()); + + $this->assertEquals($ord1, (int) $newItem2->getOrd()); + $this->assertEquals($ord2, (int) $newItem1->getOrd()); + } + public function testDelete() { $entry = $this->insertOneFeedEntry(self::$DI['user']);