diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index 83a2a3072f..850183cb08 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -48,9 +48,17 @@ class Publications implements ControllerProviderInterface $controllers->post('/create/', function(PhraseaApplication $app, Request $request) { - $publisher = new FeedPublisher($app['authentication']->getUser(), true); + $publisher = new FeedPublisher(); - $feed = new Feed($publisher, $request->request->get('title'), $request->request->get('subtitle')); + $feed = new Feed(); + + $publisher->setFeed($feed); + $publisher->setUsrId($app['authentication']->getUser()->get_id()); + $publisher->setOwner(true); + + $feed->addPublisher($publisher); + $feed->setTitle($request->request->get('title')); + $feed->setSubtitle($request->request->get('subtitle')); if ($request->request->get('public') == '1') { $feed->setPublic(true); @@ -69,7 +77,7 @@ class Publications implements ControllerProviderInterface })->bind('admin_feeds_create'); $controllers->get('/feed/{id}/', function(PhraseaApplication $app, Request $request, $id) { - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); return $app['twig'] ->render('admin/publications/fiche.html.twig', array('feed' => $feed, 'error' => $app['request']->query->get('error'))); @@ -79,24 +87,27 @@ class Publications implements ControllerProviderInterface $controllers->post('/feed/{id}/update/', function(PhraseaApplication $app, Request $request, $id) { - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); try { $collection = \collection::get_from_base_id($app, $request->request->get('base_id')); } catch (\Exception $e) { $collection = null; } - $feed->setTitle($request->request->get('title')); - $feed->setDescription($request->request->get('subtitle')); + if (null !== $request->request->get('title')) { + $feed->setTitle($request->request->get('title')); + } + if (null !== $request->request->get('subtitle')) { + $feed->setSubtitle($request->request->get('subtitle')); + } $feed->setCollection($collection); - $feed->setPublic($request->request->get('public')); - + $feed->setPublic($request->request->get('public') === '1' ? true : false); $app["EM"]->persist($feed); $app["EM"]->flush(); return $app->redirectPath('admin_feeds_list'); })->before(function(Request $request) use ($app) { - $feed = $app["EM"]->getRepository("Entities\Feed")->find($request->attributes->get('id')); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $request->attributes->get('id'))); if (!$feed->getOwner($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'))); @@ -110,7 +121,7 @@ class Publications implements ControllerProviderInterface 'success' => false, 'message' => '', ); - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); $request = $app["request"]; @@ -156,8 +167,6 @@ class Publications implements ControllerProviderInterface throw new \Exception_InternalServerError('Error while resizing'); } - //$feed->set_icon($tmpname); - unset($media); $app['filesystem']->remove($tmpname); @@ -177,9 +186,11 @@ class Publications implements ControllerProviderInterface try { $request = $app['request']; $user = \User_Adapter::getInstance($request->request->get('usr_id'), $app); - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); - $publisher = new FeedPublisher($user, false); + $publisher = new FeedPublisher(); + $publisher->setUsrId($user->get_id()); + $publisher->setOwner(false); $publisher->setFeed($feed); $feed->addPublisher($publisher); @@ -201,9 +212,13 @@ class Publications implements ControllerProviderInterface try { $request = $app['request']; - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); + + $publisher = $app["EM"]->getRepository("Entities\FeedPublisher")->findOneBy(array("id" => $request->request->get('publisher_id'))); + if (null === $publisher) { + throw new \Exception_Feed_PublisherNotFound(); + } - $publisher = $app["EM"]->getRepository("Entities\FeedPublisher")->find($request->request->get('publisher_id')); $user = $publisher->getUser($app); if ($feed->isPublisher($user) === true && $feed->isOwner($user) === false) { $feed->removePublisher($publisher); @@ -221,7 +236,7 @@ class Publications implements ControllerProviderInterface ->assert('id', '\d+'); $controllers->post('/feed/{id}/delete/', function(PhraseaApplication $app, $id) { - $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $feed = $app["EM"]->getRepository("Entities\Feed")->findOneBy(array("id" => $id)); $publishers = $feed->getPublishers(); foreach ($publishers as $publisher) { $app["EM"]->remove($publisher); diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php index 7bfd23ffcc..6e90f40b93 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php @@ -539,7 +539,6 @@ class Root implements ControllerProviderInterface private function getPublicationStartPage(Application $app) { return $app['twig']->render('client/home_inter_pub_basket.html.twig', array( -// 'feeds' => \Feed_Collection::load_all($app, $app['authentication']->getUser()), 'feeds' => $app['EM']->getRepository('Entities\Feed')->getAllforUser($app['authentication']->getUser()), 'image_size' => (int) $app['authentication']->getUser()->getPrefs('images_size') )); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php index dc477fb40b..8ede6dfdd6 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -11,10 +11,10 @@ namespace Alchemy\Phrasea\Controller\Prod; -use Alchemy\Phrasea\Feed\Aggregate; -use Alchemy\Phrasea\Feed\AggregateLinkGenerator; use Alchemy\Phrasea\Controller\RecordsRequest; -use Alchemy\Phrasea\Feed\LinkGenerator; +use Alchemy\Phrasea\Feed\Aggregate; +use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator; +use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator; use Entities\FeedEntry; use Entities\FeedItem; use Silex\Application; @@ -60,7 +60,7 @@ class Feed implements ControllerProviderInterface $title = $request->request->get('title'); $subtitle = $request->request->get('subtitle'); $author_name = $request->request->get('author_name'); - $author_email = $request->request->get('author_email'); + $author_email = $request->request->get('author_mail'); $entry = new FeedEntry(); $entry->setFeed($feed); @@ -134,7 +134,7 @@ class Feed implements ControllerProviderInterface $title = $request->request->get('title'); $subtitle = $request->request->get('subtitle'); $author_name = $request->request->get('author_name'); - $author_mail = $request->request->get('author_email'); + $author_mail = $request->request->get('author_mail'); $entry->setAuthorEmail($author_mail) ->setAuthorName($author_name) @@ -237,7 +237,7 @@ class Feed implements ControllerProviderInterface $datas = $app['twig']->render('prod/feeds/feeds.html.twig' , array( 'feeds' => $feeds - , 'feed' => new Aggregate($app, $feeds) + , 'feed' => new Aggregate($app["EM"], $feeds) , 'page' => $page ) ); @@ -264,7 +264,7 @@ class Feed implements ControllerProviderInterface $feeds = $app["EM"]->getRepository("Entities\Feed")->findAll(); - $aggregate = new Aggregate($app, $feeds); + $aggregate = new Aggregate($app["EM"], $feeds); $link = $app['feed.aggregate-link-generator']->generate($aggregate, $app['authentication']->getUser(), AggregateLinkGenerator::FORMAT_RSS, null, $renew); @@ -283,7 +283,7 @@ class Feed implements ControllerProviderInterface $feed = $app["EM"]->getRepository("Entities\Feed")->loadWithUser($app, $app['authentication']->getUser(), $id); - $link = $app['feed.user-link-generator']->generate($feed, $app['authentication']->getUser(), LinkGenerator::FORMAT_RSS, null, $renew); + $link = $app['feed.user-link-generator']->generate($feed, $app['authentication']->getUser(), FeedLinkGenerator::FORMAT_RSS, null, $renew); $output = array( 'texte' => '

' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php index b448de9eef..02870affb5 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php +++ b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php @@ -11,6 +11,8 @@ namespace Alchemy\Phrasea\Controller\Root; +use Entities\Feed; +use Alchemy\Phrasea\Feed\Aggregate; use Symfony\Component\HttpFoundation\Response; use Silex\Application; use Silex\ControllerProviderInterface; @@ -27,59 +29,14 @@ class RSSFeeds implements ControllerProviderInterface { $controllers = $app['controllers_factory']; - $display_feed = function(Application $app, $feed, $format, $page, $user = null) { - $total = $feed->getCountTotalEntries(); - $perPage = 5; - $entries = $feed->getEntries((($page - 1) * $perPage), $perPage); - - if ($format == 'rss') { - $content = new \Feed_XML_RSS(); - } - - if ($format == 'atom') { - $content = new \Feed_XML_Atom(); - } - - if ($format == 'cooliris') { - $content = new \Feed_XML_Cooliris(); - } - - if ($user instanceof \User_Adapter) - $link = $feed->getUserLink($app['phraseanet.registry'], $user, $format, $page); - else - $link = $feed->get_homepage_link($app['phraseanet.registry'], $format, $page); - - $content->set_updated_on(new \DateTime()); - $content->set_title($feed->getTitle()); - $content->set_subtitle($feed->getSubtitle()); - $content->set_generator('Phraseanet'); - $content->set_link($link); - - if ($user instanceof \User_Adapter) { - if ($page > 1) - $content->set_previous_page($feed->getUserLink($app['phraseanet.registry'], $user, $format, ($page - 1))); - if ($total > ($page * $perPage)) - $content->set_next_page($feed->getUserLink($app['phraseanet.registry'], $user, $format, ($page + 1))); - } else { - if ($page > 1) - $content->set_previous_page($feed->get_homepage_link($app['phraseanet.registry'], $format, ($page - 1))); - if ($total > ($page * $perPage)) - $content->set_next_page($feed->get_homepage_link($app['phraseanet.registry'], $format, ($page + 1))); - } - foreach ($entries->getEntries() as $entry) - $content->set_item($entry); - - $render = $content->render(); - $response = new Response($render, 200, array('Content-Type' => $content->get_mimetype())); - $response->setCharset('UTF-8'); - - return $response; - }; - - $controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) use ($display_feed) { + $controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) { $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); - if (!$feed->isPublic()) { + if (!$feed) { + return new Response('Not Found', 404); + } + + if (!$feed->getPublic()) { return new Response('Forbidden', 403); } @@ -88,65 +45,92 @@ class RSSFeeds implements ControllerProviderInterface $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, $format, $page); + return $app[$this->getFormater($format)]->createResponse($feed, $page); }) ->bind('feed_public') ->assert('id', '\d+') ->assert('format', '(rss|atom)'); - $controllers->get('/userfeed/{token}/{id}/{format}/', function(Application $app, $token, $id, $format) use ($display_feed) { - $token = $app["EM"]->getRepository("Entities\FeedToken")->findBy(array("id" => $id)); + $controllers->get('/userfeed/{token}/{id}/{format}/', function(Application $app, $token, $id, $format) { + $token = $app["EM"]->getRepository("Entities\FeedToken")->findOneBy(array("id" => $id)); $feed = $token->getFeed(); + $usrId = $token->getUsrId(); + + $user = \User_Adapter::getInstance($usrId, $app); $request = $app['request']; $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, $format, $page, $token->get_user()); + return $app[$this->getFormater($format)]->createResponse($feed, $page, $user); }) ->bind('feed_user') ->assert('id', '\d+') ->assert('format', '(rss|atom)'); - $controllers->get('/userfeed/aggregated/{token}/{format}/', function(Application $app, $token, $format) use ($display_feed) { - $token = $app["EM"]->getRepository("Entities\AggregateToken")->findBy(array("id" => $id)); + $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); + + $feeds = $app["EM"]->getRepository('Entities\Feed')->getAllForUser($user); + + $aggregate = new Aggregate($app["EM"], $feeds, $token); $request = $app['request']; $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, $format, $page, $token->get_user()); + return $app[$this->getFormater($format)]->createResponse($aggregate, $page, $user); }) ->bind('feed_user_aggregated') ->assert('format', '(rss|atom)'); - $controllers->get('/aggregated/{format}/', function(Application $app, $format) use ($display_feed) { + $controllers->get('/aggregated/{format}/', function(Application $app, $format) { $feeds = $app["EM"]->getRepository("Entities\Feed")->findAllPublic(); - $feed = new Aggregate($app, $feeds); + $feed = new Aggregate($app["EM"], $feeds); $request = $app['request']; $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, $format, $page); + return $app[$this->getFormater($format)]->createResponse($feed, $page); }) ->bind('feed_public_aggregated') ->assert('format', '(rss|atom)'); - $controllers->get('/cooliris/', function(Application $app) use ($display_feed) { + $controllers->get('/cooliris/', function(Application $app) { $feeds = $app["EM"]->getRepository("Entities\Feed")->findAllPublic(); - $feed = new Aggregate($app, $feeds); + $feed = new Aggregate($app["EM"], $feeds); $request = $app['request']; $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, 'cooliris', $page); + return $app[$this->getFormater('cooliris')]->createResponse($feed, $page); }) ->bind('feed_public_cooliris'); return $controllers; } + + private function getFormater($type) + { + switch ($type) { + case 'rss': + return 'feed.rss-formatter'; + break; + case 'atom': + return 'feed.atom-formatter'; + break; + case 'cooliris': + return 'feed.cooliris-formatter'; + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } } diff --git a/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php index f16badbc1c..4009fdb552 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php @@ -11,8 +11,12 @@ namespace Alchemy\Phrasea\Core\Provider; -use Alchemy\Phrasea\Feed\LinkGenerator; -use Alchemy\Phrasea\Feed\AggregateLinkGenerator; +use Alchemy\Phrasea\Feed\Formatter\AtomFormatter; +use Alchemy\Phrasea\Feed\Formatter\CoolirisFormatter; +use Alchemy\Phrasea\Feed\Formatter\RssFormatter; +use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator; +use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator; +use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection; use Silex\Application; use Silex\ServiceProviderInterface; @@ -21,11 +25,26 @@ class FeedServiceProvider implements ServiceProviderInterface public function register(Application $app) { $app['feed.user-link-generator'] = $app->share(function($app) { - return new LinkGenerator($app['url_generator'], $app['EM'], $app['tokens']); + return new FeedLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']); }); $app['feed.aggregate-link-generator'] = $app->share(function($app) { return new AggregateLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']); }); + $app['feed.link-generator-collection'] = $app->share(function($app) { + $collection = new LinkGeneratorCollection(); + $collection->pushGenerator($app['feed.user-link-generator']); + $collection->pushGenerator($app['feed.aggregate-link-generator']); + return $collection; + }); + $app['feed.rss-formatter'] = $app->share(function($app) { + return new RssFormatter($app['feed.link-generator-collection']); + }); + $app['feed.atom-formatter'] = $app->share(function($app) { + return new AtomFormatter($app['feed.link-generator-collection']); + }); + $app['feed.cooliris-formatter'] = $app->share(function($app) { + return new CoolirisFormatter($app['feed.link-generator-collection']); + }); } public function boot(Application $app) diff --git a/lib/Alchemy/Phrasea/Feed/Aggregate.php b/lib/Alchemy/Phrasea/Feed/Aggregate.php index 3bfbdd6177..03d90e979a 100644 --- a/lib/Alchemy/Phrasea/Feed/Aggregate.php +++ b/lib/Alchemy/Phrasea/Feed/Aggregate.php @@ -4,6 +4,7 @@ namespace Alchemy\Phrasea\Feed; use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityManager; +use Entities\AggregateToken; class Aggregate implements FeedInterface { @@ -35,15 +36,15 @@ class Aggregate implements FeedInterface protected $token; - protected $app; + protected $em; - public function __construct(Application $app, array $feeds) + public function __construct(EntityManager $em, array $feeds, AggregateToken $token = null) { $this->title = 'AGGREGATE'; $this->subtitle = 'AGGREGATE SUBTITLE'; $this->created_on = new \DateTime(); $this->updated_on = new \DateTime(); - $this->app = $app; + $this->em = $em; $tmp_feeds = array(); @@ -52,20 +53,22 @@ class Aggregate implements FeedInterface } $this->feeds = $tmp_feeds; + $this->token = $token; return $this; } - public static function createFromUser(Application $app, \User_Adapter $user) + public static function createFromUser(EntityManager $em, \User_Adapter $user) { - $feeds = $app["EM"]->getRepository('Entities\Feed')->findByUser($user); + $feeds = $em->getRepository('Entities\Feed')->getAllForUser($user); + $token = $em->getRepository('Entities\AggregateToken')->findByUser($user); - return new static($app, $feeds); + return new static($em, $feeds, $token); } public static function create(Application $app, array $feed_ids) { - $feeds = $app["EM"]->getRepository('Entities\Feed')->findByIdArray($feed_ids); + $feeds = $this->em->getRepository('Entities\Feed')->findByIdArray($feed_ids); return new static($app, $feeds); } @@ -75,26 +78,26 @@ class Aggregate implements FeedInterface return true; } - public function getEntries($offset_start, $how_many) + public function getEntries($offset_start = 0, $how_many = null) { - $result = new \Feed_Entry_Collection(); + $count = 0; + $added = 0; - if (count($this->feeds) === 0) { - return $result; - } - - $offset_start = (int) $offset_start; - $how_many = $how_many > 20 ? 20 : (int) $how_many; - - $rs = $this->app["EM"]->getRepository("Entities\FeedEntry")->findByFeeds($this->feeds, $offset_start, $how_many); - - foreach ($rs as $entry) { - if ($entry) { - $result->add_entry($entry); + $collection = array(); + foreach ($this->feeds as $feed) { + foreach ($feed->getEntries() as $entry) { + if ($count >= $offset_start) { + $collection[] = $entry; + $added++; + } + $count++; + if (null !== $how_many && $added == $how_many) { + return $collection; + } } } - return $result; + return $collection; } public function getSubtitle() @@ -142,8 +145,16 @@ class Aggregate implements FeedInterface public function getCountTotalEntries() { if (count($this->feeds) > 0) { - return count($this->app["EM"]->getRepository("Entities\FeedEntry")->findByFeeds($this->feeds)); + return count($this->em->getRepository("Entities\FeedEntry")->findByFeeds($this->feeds)); } return 0; } + + public function hasPage($page, $pageSize) + { + $count = $this->getCountTotalEntries(); + if ($page >= $count / $pageSize) + return true; + return false; + } } diff --git a/lib/Alchemy/Phrasea/Feed/FeedInterface.php b/lib/Alchemy/Phrasea/Feed/FeedInterface.php index 504e9b6e37..976cc07d6b 100644 --- a/lib/Alchemy/Phrasea/Feed/FeedInterface.php +++ b/lib/Alchemy/Phrasea/Feed/FeedInterface.php @@ -1,15 +1,23 @@ linkGenerator = $generator; + } + + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet') + { + $content = $this->format($feed, $page, $user, $generator); + $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') + { + $title = $feed->getTitle(); + $subtitle = $feed->getSubtitle(); + $updated_on = $feed->getUpdatedOn(); + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = true; + $document->standalone = true; + + $root = $this->addTag($document, $document, 'feed'); + $root->setAttribute('xmlns', 'http://www.w3.org/2005/Atom'); + $root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/'); + + $this->addTag($document, $root, 'title', $title); + if ($updated_on instanceof \DateTime) { + $updated_on = $updated_on->format(DATE_ATOM); + $this->addTag($document, $root, 'updated', $updated_on); + } + + 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) { + $feedlink = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page); + } + else { + $feedlink = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page); + } + + if ($feedlink instanceof FeedLink) { + $link = $this->addTag($document, $root, 'link'); + $link->setAttribute('rel', 'self'); + $link->setAttribute('href', $feedlink->getURI()); + $this->addTag($document, $root, 'id', $feedlink->getURI()); + } + + if ($prev instanceof FeedLink) { + $prev_link = $this->addTag($document, $root, 'link'); + $prev_link->setAttribute('rel', 'previous'); + $prev_link->setAttribute('href', $prev->getURI()); + } + + if ($next instanceof FeedLink) { + $next_link = $this->addTag($document, $root, 'link'); + $next_link->setAttribute('rel', 'next'); + $next_link->setAttribute('href', $next->getURI()); + } + + if (isset($generator)) + $this->addTag($document, $root, 'generator', $generator); + if (isset($subtitle)) + $this->addTag($document, $root, 'subtitle', $subtitle); + 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)) + $this->addTag($document, $author, 'email', $this->author_email); + if (isset($this->author_name)) + $this->addTag($document, $author, 'name', $this->author_name); + if (isset($this->author_url)) + $this->addTag($document, $author, 'uri', $this->author_url); + } + + foreach ($feed->getEntries() as $item) { + $this->addItem($document, $root, $item, $feedlink); + } + + return $document->saveXML(); + } + + protected function addItem(DOMDocument $document, DOMNode $feed, FeedEntry $entry, FeedLink $link) + { + $entry_node = $this->addTag($document, $feed, 'entry'); + + $link = sprintf('%sentry/%d/', $link->getURI(), $entry->getId()); + + $this->addTag($document, $entry_node, 'id', $link); + $link_tag = $this->addTag($document, $entry_node, 'link'); + $link_tag->setAttribute('rel', 'self'); + $link_tag->setAttribute('href', $link); + + $updated_on = $entry->getUpdatedOn()->format(DATE_ATOM); + $created_on = $entry->getCreatedOn()->format(DATE_ATOM); + + $this->addTag($document, $entry_node, 'updated', $updated_on); + $this->addTag($document, $entry_node, 'published', $created_on); + $this->addTag($document, $entry_node, 'title', $entry->getTitle()); + $author = $this->addTag($document, $entry_node, 'author'); + + if ($entry->getAuthorEmail()) + $this->addTag($document, $author, 'email', $entry->getAuthorEmail()); + if ($entry->getAuthorName()) + $this->addTag($document, $author, 'name', $entry->getAuthorName()); + + $this->addTag($document, $entry_node, 'content', $entry->getSubtitle()); + + foreach ($entry->getItems() as $content) { + $this->addContent($document, $entry_node, $entry, $content); + } + + return $entry_node; + } +} + diff --git a/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php new file mode 100644 index 0000000000..74fbc4c734 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Formatter/CoolirisFormatter.php @@ -0,0 +1,266 @@ +linkGenerator = $generator; + } + + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet') + { + $content = $this->format($feed, $page, $user, $generator); + $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') + { + $title = $feed->getTitle(); + $subtitle = $feed->getSubtitle(); + $updated_on = $feed->getUpdatedOn(); + + $doc = new \DOMDocument('1.0', 'UTF-8'); + $doc->formatOutput = true; + $doc->standalone = true; + + $root = $this->addTag($doc, $doc, 'rss'); + + $root->setAttribute('version', self::VERSION); + $root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/'); + $root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom'); + $root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + + $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 (null !== $user) { + $link = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page); + } + else { + $link = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page); + } + + if ($link instanceof FeedLink) + $this->addTag($doc, $channel, 'link', $link->getURI()); + + if (isset($this->language)) + $this->addTag($doc, $channel, 'language', $this->language); + if (isset($this->copyright)) + $this->addTag($doc, $channel, 'copyright', $this->copyright); + if (isset($this->managingEditor)) + $this->addTag($doc, $channel, 'managingEditor', $this->managingEditor); + if (isset($this->webMaster)) + $this->addTag($doc, $channel, 'webMaster', $this->webMaster); + if ($updated_on instanceof DateTime) { + $updated_on = $updated_on->format(DATE_RFC2822); + $this->addTag($doc, $channel, 'pubDate', $updated_on); + } + if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) { + $last_build = $this->lastBuildDate->format(DATE_RFC2822); + $this->addTag($doc, $channel, 'lastBuildDate', $last_build); + } + if (isset($this->categories) && count($this->categories) > 0) { + foreach ($this->categories as $category) { + $this->addTag($doc, $channel, 'category', $category); + } + } + if (isset($this->linkgenerator)) + $this->addTag($doc, $channel, 'generator', $this->linkgenerator); + if (isset($this->docs)) + $this->addTag($doc, $channel, 'docs', $this->docs); + if (isset($this->ttl)) + $this->addTag($doc, $channel, 'ttl', $this->ttl); + if (isset($this->image) && $this->image instanceof Feed_XML_RSS_Image) { + $image = $this->addTag($doc, $channel, 'image'); + $this->addTag($doc, $image, 'url', $this->image->get_url()); + $this->addTag($doc, $image, 'title', $this->image->get_title()); + $this->addTag($doc, $image, 'link', $this->image->get_link()); + if ($this->image->get_width()) + $this->addTag($doc, $image, 'width', $this->image->get_width()); + if ($this->image->get_height()) + $this->addTag($doc, $image, 'height', $this->image->get_height()); + if ($this->image->get_description()) + $this->addTag($doc, $image, 'description', $this->image->get_description()); + } + if (isset($this->skipHours) && count($this->skipHours)) { + $skipHours = $this->addTag($doc, $channel, 'skipHours'); + foreach ($this->skipHours as $hour) { + $this->addTag($doc, $skipHours, 'hour', $hour); + } + } + if (isset($this->skipDays) && count($this->skipDays) > 0) { + $skipDays = $this->addTag($doc, $channel, 'skipDays'); + foreach ($this->skipDays as $day) { + $this->addTag($doc, $skipDays, 'day', $day); + } + } + if ($link instanceof FeedLink) { + $self_link = $this->addTag($doc, $channel, 'atom:link'); + $self_link->setAttribute('rel', 'self'); + $self_link->setAttribute('href', $link->getURI()); + } + + 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'; + + if ($prev instanceof FeedLink) { + $prev_link = $this->addTag($doc, $channel, $prefix . 'link'); + $prev_link->setAttribute('rel', 'previous'); + $prev_link->setAttribute('href', $prev->getURI()); + } + + if ($next instanceof FeedLink) { + $next_link = $this->addTag($doc, $channel, $prefix . 'link'); + $next_link->setAttribute('rel', 'next'); + $next_link->setAttribute('href', $next->getURI()); + } + + foreach ($feed->getEntries() as $item) { + $this->addItem($doc, $channel, $item); + } + + return $doc->saveXML(); + } + + protected function addItem(\DOMDocument $document, \DOMNode $feed, FeedEntry $entry) + { + foreach ($entry->get_content() as $content) { + $this->addContent($document, $feed, $entry, $content); + } + } + + protected function addContent(\DOMDocument $document, \DOMNode $node, FeedItem $content) + { + + $preview_sd = $content->getRecord()->get_subdef('preview'); + $preview_permalink = $preview_sd->get_permalink(); + $thumbnail_sd = $content->getRecord()->get_thumbnail(); + $thumbnail_permalink = $thumbnail_sd->get_permalink(); + + $medium = strtolower($content->getRecord()->get_type()); + + if ( ! in_array($medium, array('image', 'audio', 'video'))) { + return $this; + } + + if (! $preview_permalink || ! $thumbnail_permalink) { + return $this; + } + + //add item node to channel node + $item = $this->addTag($document, $node, 'item'); + + $caption = $content->getRecord()->get_caption(); + + $title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title); + if ($title_field) { + $str_title = $title_field->get_serialized_values(' '); + } else { + $str_title = $content->getRecord()->get_title(); + } + + //attach tile node to item node + $title = $this->addTag($document, $item, 'title', $str_title); + + $desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description); + if ($desc_field) { + $str_desc = $desc_field->get_serialized_values(' '); + } else { + $str_desc = ''; + } + + //attach desc node to item node + $desc = $this->addTag($document, $item, 'description', $str_desc); + + $duration = $content->getRecord()->get_duration(); + + if ($preview_permalink) { + $preview = $this->addTag($document, $item, 'media:content'); + + $preview->setAttribute('url', $preview_permalink->get_url()); + $preview->setAttribute('fileSize', $preview_sd->get_size()); + $preview->setAttribute('type', $preview_sd->get_mime()); + $preview->setAttribute('medium', $medium); + $preview->setAttribute('expression', 'full'); + $preview->setAttribute('isDefault', 'true'); + + if ($preview_sd->get_width()) + $preview->setAttribute('width', $preview_sd->get_width()); + if ($preview_sd->get_height()) + $preview->setAttribute('height', $preview_sd->get_height()); + if ($duration) + $preview->setAttribute('duration', $duration); + } + + if ($thumbnail_permalink) { + $thumbnail = $this->addTag($document, $item, 'media:thumbnail'); + + $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); + + if ($thumbnail_sd->get_width()) + $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); + if ($thumbnail_sd->get_height()) + $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + + $thumbnail = $this->addTag($document, $item, 'media:content'); + + $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); + $thumbnail->setAttribute('fileSize', $thumbnail_sd->get_size()); + $thumbnail->setAttribute('type', $thumbnail_sd->get_mime()); + $thumbnail->setAttribute('medium', $medium); + $thumbnail->setAttribute('isDefault', 'false'); + + if ($thumbnail_sd->get_width()) + $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); + if ($thumbnail_sd->get_height()) + $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + if ($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 new file mode 100644 index 0000000000..97974f2729 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterAbstract.php @@ -0,0 +1,164 @@ +createElement($tagname); + + if (trim($tagcontent) !== '') + $tag->appendChild($document->createTextNode($tagcontent)); + $node->appendChild($tag); + + return $tag; + } + + /** + * + * @param DOMDocument $document + * @param DOMNode $item + * @param FeedItem $content + * @return FeedFormaterInterface + */ + protected function addContent(\DOMDocument $document, \DOMNode $item, FeedItem $content) + { + $preview_sd = $content->getRecord()->get_subdef('preview'); + $preview_permalink = $preview_sd->get_permalink(); + $thumbnail_sd = $content->getRecord()->get_thumbnail(); + $thumbnail_permalink = $thumbnail_sd->get_permalink(); + + $medium = strtolower($content->getRecord()->get_type()); + + if ( ! in_array($medium, array('image', 'audio', 'video'))) { + return $this; + } + + if (! $preview_permalink || ! $thumbnail_permalink) { + return $this; + } + + $group = $this->addTag($document, $item, 'media:group'); + + $caption = $content->getRecord()->get_caption(); + + $title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title); + if ($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) { + $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) { + $str_contrib = $contrib_field->get_serialized_values(' '); + $contrib = $this->addTag($document, $group, 'media:credit', $str_contrib); + $contrib->setAttribute('role', 'contributor'); + $contrib->setAttribute('scheme', 'urn:ebu'); + } + + $director_field = $caption->get_dc_field(databox_Field_DCESAbstract::Creator); + if ($director_field) { + $str_director = $director_field->get_serialized_values(' '); + $director = $this->addTag($document, $group, 'media:credit', $str_director); + $director->setAttribute('role', 'director'); + $director->setAttribute('scheme', 'urn:ebu'); + } + + $publisher_field = $caption->get_dc_field(databox_Field_DCESAbstract::Publisher); + if ($publisher_field) { + $str_publisher = $publisher_field->get_serialized_values(' '); + $publisher = $this->addTag($document, $group, 'media:credit', $str_publisher); + $publisher->setAttribute('role', 'publisher'); + $publisher->setAttribute('scheme', 'urn:ebu'); + } + + $rights_field = $caption->get_dc_field(databox_Field_DCESAbstract::Rights); + if ($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) { + $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) { + $preview = $this->addTag($document, $group, 'media:content'); + + $preview->setAttribute('url', $preview_permalink->get_url()); + $preview->setAttribute('fileSize', $preview_sd->get_size()); + $preview->setAttribute('type', $preview_sd->get_mime()); + $preview->setAttribute('medium', $medium); + $preview->setAttribute('expression', 'full'); + $preview->setAttribute('isDefault', 'true'); + + if ($preview_sd->get_width()) + $preview->setAttribute('width', $preview_sd->get_width()); + if ($preview_sd->get_height()) + $preview->setAttribute('height', $preview_sd->get_height()); + if ($duration) + $preview->setAttribute('duration', $duration); + } + + if ($thumbnail_permalink) { + $thumbnail = $this->addTag($document, $group, 'media:thumbnail'); + + $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); + + if ($thumbnail_sd->get_width()) + $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); + if ($thumbnail_sd->get_height()) + $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + + $thumbnail = $this->addTag($document, $group, 'media:content'); + + $thumbnail->setAttribute('url', $thumbnail_permalink->get_url()); + $thumbnail->setAttribute('fileSize', $thumbnail_sd->get_size()); + $thumbnail->setAttribute('type', $thumbnail_sd->get_mime()); + $thumbnail->setAttribute('medium', $medium); + $thumbnail->setAttribute('isDefault', 'false'); + + if ($thumbnail_sd->get_width()) + $thumbnail->setAttribute('width', $thumbnail_sd->get_width()); + if ($thumbnail_sd->get_height()) + $thumbnail->setAttribute('height', $thumbnail_sd->get_height()); + if ($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 new file mode 100644 index 0000000000..7ac7185652 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Formatter/FeedFormatterInterface.php @@ -0,0 +1,20 @@ +linkGenerator = $generator; + } + + public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet') + { + $content = $this->format($feed, $page, $user, $generator); + $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') + { + $title = $feed->getTitle(); + $subtitle = $feed->getSubtitle(); + $updated_on = $feed->getUpdatedOn(); + + 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) { + $link = $this->linkGenerator->generate($feed, $user, static::FORMAT, $page); + } + else { + $link = $this->linkGenerator->generatePublic($feed, static::FORMAT, $page); + } + + $doc = new \DOMDocument('1.0', 'UTF-8'); + $doc->formatOutput = true; + $doc->standalone = true; + + $root = $this->addTag($doc, $doc, 'rss'); + + $root->setAttribute('version', static::VERSION); + $root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/'); + $root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom'); + $root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + + $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, 'link', $link->getURI()); + + if (isset($this->language)) + $this->addTag($doc, $channel, 'language', $this->language); + if (isset($this->copyright)) + $this->addTag($doc, $channel, 'copyright', $this->copyright); + if (isset($this->managingEditor)) + $this->addTag($doc, $channel, 'managingEditor', $this->managingEditor); + if (isset($this->webMaster)) + $this->addTag($doc, $channel, 'webMaster', $this->webMaster); + if ($updated_on instanceof \DateTime) { + $updated_on = $updated_on->format(DATE_RFC2822); + $this->addTag($doc, $channel, 'pubDate', $updated_on); + } + if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) { + $last_build = $this->lastBuildDate->format(DATE_RFC2822); + $this->addTag($doc, $channel, 'lastBuildDate', $last_build); + } + if (isset($this->categories) && count($this->categories) > 0) { + foreach ($this->categories as $category) { + $this->addTag($doc, $channel, 'category', $category); + } + } + if (isset($generator)) + $this->addTag($doc, $channel, 'generator', $generator); + if (isset($this->docs)) + $this->addTag($doc, $channel, 'docs', $this->docs); + if (isset($this->ttl)) + $this->addTag($doc, $channel, 'ttl', $this->ttl); + if (isset($this->image) && $this->image instanceof Feed_XML_RSS_Image) { + $image = $this->addTag($doc, $channel, 'image'); + $this->addTag($doc, $image, 'url', $this->image->get_url()); + $this->addTag($doc, $image, 'title', $this->image->get_title()); + $this->addTag($doc, $image, 'link', $this->image->get_link()); + if ($this->image->get_width()) + $this->addTag($doc, $image, 'width', $this->image->get_width()); + if ($this->image->get_height()) + $this->addTag($doc, $image, 'height', $this->image->get_height()); + if ($this->image->get_description()) + $this->addTag($doc, $image, 'description', $this->image->get_description()); + } + if (isset($this->skipHours) && count($this->skipHours)) { + $skipHours = $this->addTag($doc, $channel, 'skipHours'); + foreach ($this->skipHours as $hour) { + $this->addTag($doc, $skipHours, 'hour', $hour); + } + } + if (isset($this->skipDays) && count($this->skipDays) > 0) { + $skipDays = $this->addTag($doc, $channel, 'skipDays'); + foreach ($this->skipDays as $day) { + $this->addTag($doc, $skipDays, 'day', $day); + } + } + if ($link instanceof FeedLink) { + $self_link = $this->addTag($doc, $channel, 'atom:link'); + $self_link->setAttribute('rel', 'self'); + $self_link->setAttribute('href', $link->getURI()); + } + + $prefix = 'atom:'; + + if ($prev instanceof FeedLink) { + $prev_link = $this->addTag($doc, $channel, $prefix . 'link'); + $prev_link->setAttribute('rel', 'previous'); + $prev_link->setAttribute('href', $prev->getURI()); + } + + if ($next instanceof FeedLink) { + $next_link = $this->addTag($doc, $channel, $prefix . 'link'); + $next_link->setAttribute('rel', 'next'); + $next_link->setAttribute('href', $next->getURI()); + } + + foreach ($feed->getEntries() as $item) { + $this->addItem($doc, $channel, $item); + } + + return $doc->saveXML(); + } + + protected function addItem(\DOMDocument $document, \DOMNode $node, FeedEntry $entry) + { + $item = $this->addTag($document, $node, 'item'); + + $link = $entry->getLink(); + + $this->addTag($document, $item, 'title', $entry->getTitle()); + $this->addTag($document, $item, 'description', $entry->getSubtitle()); + + $author = sprintf( + '%s (%s)' + , $entry->getAuthorEmail() + , $entry->getAuthorName() + ); + $created_on = $entry->getCreatedOn()->format(DATE_RFC2822); + + $this->addTag($document, $item, 'author', $author); + $this->addTag($document, $item, 'pubDate', $created_on); + $this->addTag($document, $item, 'guid', $link->getURI()); + $this->addTag($document, $item, 'link', $link->getURI()); + + /** + * Missing : + * + * category Includes the item in one or more categories. More. + * comments URL of a page for comments relating to the item. More. + * enclosure Describes a media object that is attached to the item. More. + * source The RSS channel that the item came from. More. + * + */ + foreach ($entry->getItems() as $content) { + $this->addContent($document, $item, $entry, $content); + } + + return $item; + } +} + diff --git a/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php new file mode 100644 index 0000000000..22afd10a2e --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Link/AggregateLinkGenerator.php @@ -0,0 +1,122 @@ +generator = $generator; + $this->em = $em; + $this->random = $random; + } + + public function generate(FeedInterface $aggregate, \User_Adapter $user, $format, $page = null, $renew = false) + { + if (!$this->supports($aggregate)) { + throw new InvalidArgumentException('AggregateLinkGenerator only support aggregate feeds.'); + } + + switch ($format) { + case self::FORMAT_ATOM: + $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), + 'application/atom+xml' + ); + break; + case self::FORMAT_RSS: + $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + public function supports(FeedInterface $feed) + { + return $feed instanceof Aggregate; + } + + public function generatePublic(FeedInterface $aggregate, $format, $page = null) + { + if (!$this->supports($aggregate)) { + throw new InvalidArgumentException('AggregateLinkGenerator only support aggregate feeds.'); + } + + switch ($format) { + case self::FORMAT_ATOM: + $params = array('format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_public_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), + 'application/atom+xml' + ); + break; + case self::FORMAT_RSS: + $params = array('format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_public_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + private function getAggregateToken(\User_Adapter $user, $renew = false) + { + $token = $this->em + ->getRepository('Entities\AggregateToken') + ->findByUser($user); + + if (null === $token || true === $renew) { + if (null === $token) { + $token = new AggregateToken(); + $token->setUsrId($user->get_id()); + } + + $token->setValue($this->random->generatePassword(12, \random::LETTERS_AND_NUMBERS)); + $this->em->persist($token); + $this->em->flush(); + } + + return $token; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php new file mode 100644 index 0000000000..3d55b2c562 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLink.php @@ -0,0 +1,68 @@ +mimetype = $mimetype; + $this->uri = $uri; + $this->title = $title; + } + + /** + * {@inheritdoc} + */ + public function getMimetype() + { + return $this->mimetype; + } + + /** + * {@inheritdoc} + */ + public function getTitle() + { + return $this->title; + } + + /** + * {@inheritdoc} + */ + public function getURI() + { + return $this->uri; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php new file mode 100644 index 0000000000..aed7972f5d --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkGenerator.php @@ -0,0 +1,142 @@ +generator = $generator; + $this->em = $em; + $this->random = $random; + } + + public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false) + { + if (!$this->supports($feed)) { + throw new InvalidArgumentException('FeedLinkGenerator only support aggregate feeds.'); + } + + switch ($format) { + case self::FORMAT_ATOM: + $params = array('token' => $this->getFeedToken($feed, $user, $renew)->getValue(), + 'id' => $feed->getId(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + + return new FeedLink( + $this->generator->generate('feed_user', $params, UrlGenerator::ABSOLUTE_URL), + 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'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_user', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $feed->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + public function supports(FeedInterface $feed) + { + return $feed instanceof Feed; + } + + public function generatePublic(FeedInterface $feed, $format, $page = null) + { + if (!$this->supports($feed)) { + throw new InvalidArgumentException('FeedLinkGenerator only support aggregate feeds.'); + } + + switch ($format) { + case self::FORMAT_ATOM: + $params = array('id' => $feed->getId(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + + return new FeedLink( + $this->generator->generate('feed_public', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $feed->getTitle(), 'Atom'), + 'application/atom+xml' + ); + break; + case self::FORMAT_RSS: + $params = array('id' => $feed->getId(), + 'format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } + + return new FeedLink( + $this->generator->generate('feed_public', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $feed->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + private function getFeedToken(Feed $feed, \User_Adapter $user, $renew = false) + { + $token = $this->em + ->getRepository('Entities\FeedToken') + ->findByFeedAndUser($feed, $user); + + if (null === $token || true === $renew) { + if (null === $token) { + $token = new FeedToken(); + $token->setFeed($feed); + $token->setUsrId($user->get_id()); + $feed->addToken($token); + + $this->em->persist($feed); + } + + $token->setValue($this->random->generatePassword(12, \random::LETTERS_AND_NUMBERS)); + $this->em->persist($token); + $this->em->flush(); + } + + return $token; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php new file mode 100644 index 0000000000..6e158bdc23 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Link/FeedLinkInterface.php @@ -0,0 +1,30 @@ +generators[] = $generator; + } + + public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false) + { + if (null === $generator = $this->findGenerator($feed)) { + throw new InvalidArgumentException(sprintf('Unable to find a valid generator for %s', get_class($feed))); + } + + return $generator->generate($feed, $user, $format, $page); + } + + public function generatePublic(FeedInterface $feed, $format, $page = null) + { + if (null === $generator = $this->findGenerator($feed)) { + throw new InvalidArgumentException(sprintf('Unable to find a valid generator for %s', get_class($feed))); + } + + return $generator->generatePublic($feed, $format, $page); + } + + public function supports(FeedInterface $feed) + { + return null !== $this->findGenerator($feed); + } + + private function findGenerator(FeedInterface $feed) + { + foreach ($this->generators as $generator) { + if ($generator->supports($feed)) { + return $generator; + } + } + + return null; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php new file mode 100644 index 0000000000..017b49d035 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Link/LinkGeneratorInterface.php @@ -0,0 +1,32 @@ +entries; + } return $this->entries->slice($offset_start, $how_many); } @@ -434,7 +437,7 @@ class Feed implements FeedInterface public function addEntrie(\Entities\FeedEntry $entries) { $this->entries[] = $entries; - + return $this; } @@ -447,4 +450,12 @@ class Feed implements FeedInterface { $this->entries->removeElement($entries); } + + public function hasPage($page, $pageSize) + { + $count = $this->getCountTotalEntries(); + if ($page >= $count / $pageSize + $pageSize) + return true; + return false; + } } \ No newline at end of file diff --git a/templates/web/admin/publications/fiche.html.twig b/templates/web/admin/publications/fiche.html.twig index e83e21c902..ce47d325a9 100644 --- a/templates/web/admin/publications/fiche.html.twig +++ b/templates/web/admin/publications/fiche.html.twig @@ -89,7 +89,7 @@

- +
diff --git a/templates/web/client/home_inter_pub_basket.html.twig b/templates/web/client/home_inter_pub_basket.html.twig index 225a7e7a99..27e90e55d9 100644 --- a/templates/web/client/home_inter_pub_basket.html.twig +++ b/templates/web/client/home_inter_pub_basket.html.twig @@ -5,24 +5,24 @@
- {% for entry in feeds.get_aggregate().get_entries(0, 5).get_entries() %} + {% for entry in feeds.getEntries(0, 5) %}

- - {{ entry.get_title() }} + + {{ entry.getTitle() }}

- {{ app['date-formatter'].getPrettyString(entry.get_created_on()) }} - {% if entry.get_author_email() %} - - {{ entry.get_author_name() }} + {{ app['date-formatter'].getPrettyString(entry.getCreatedOn()) }} + {% if entry.getAuthorEmail() %} + + {{ entry.getAuthorName() }} - {% if entry.get_updated_on() > entry.get_created_on() %} + {% if entry.getUpdatedOn() > entry.getCreatedOn() %}
- {% trans "publications:: derniere mise a jour" %} {{ app['date-formatter'].getPrettyString(entry.get_updated_on()) }} + {% trans "publications:: derniere mise a jour" %} {{ app['date-formatter'].getPrettyString(entry.getUpdatedOn()) }}

@@ -37,9 +37,9 @@ {% endif %}
-
- {% for item in entry.get_content() %} - {% set record = item.get_record() %} +
+ {% for item in entry.getItems() %} + {% set record = item.getRecord() %} {% set thumbnail = record.get_thumbnail() %} {% set docType = record.get_type() %} {% set duration = "" %} diff --git a/templates/web/lightbox/feed_container.html.twig b/templates/web/lightbox/feed_container.html.twig index 8b86ac19e9..fee39c469f 100644 --- a/templates/web/lightbox/feed_container.html.twig +++ b/templates/web/lightbox/feed_container.html.twig @@ -1,7 +1,7 @@ {% block basket %}
- {% for element in feed_entry.get_content() %} + {% for element in feed_entry.getItems() %}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php index ab2ac13d68..2e47c8620c 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php @@ -13,73 +13,52 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic $crawler = self::$DI['client']->request('GET', '/admin/publications/list/'); $pageContent = self::$DI['client']->getResponse()->getContent(); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = self::$DI['app']['EM']->getRepository("Entities\Feed")->getAllForUser(self::$DI['user']); - foreach ($feeds->get_feeds() as $feed) { - $this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->get_id() . '/', $pageContent); - if ($feed->get_collection() != null) - $this->assertRegExp('/' . $feed->get_collection()->get_label(self::$DI['app']['locale.I18n']) . '/', $pageContent); - if ($feed->is_owner(self::$DI['user'])) - $this->assertEquals(1, $crawler->filterXPath("//form[@action='/admin/publications/feed/" . $feed->get_id() . "/delete/']")->count()); + foreach ($feeds as $feed) { + $this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->getId() . '/', $pageContent); + if ($feed->getCollection() != null) + $this->assertRegExp('/' . $feed->getCollection()->get_label(self::$DI['app']['locale.I18n']) . '/', $pageContent); + if ($feed->isOwner(self::$DI['user'])) + $this->assertEquals(1, $crawler->filterXPath("//form[@action='/admin/publications/feed/" . $feed->getId() . "/delete/']")->count()); } } public function testCreate() { - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); - $count = sizeof($feeds->get_feeds()); + $feeds = self::$DI['app']['EM']->getRepository("Entities\Feed")->getAllForUser(self::$DI['user']); + $count = sizeof($feeds); $crawler = self::$DI['client']->request('POST', '/admin/publications/create/', array("title" => "hello", "subtitle" => "coucou", "base_id" => self::$DI['collection']->get_base_id())); $this->assertTrue(self::$DI['client']->getResponse()->isRedirect('/admin/publications/list/')); - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); - $count_after = sizeof($feeds->get_feeds()); + $feeds = self::$DI['app']['EM']->getRepository("Entities\Feed")->getAllForUser(self::$DI['user']); + $count_after = sizeof($feeds); $this->assertGreaterThan($count, $count_after); - - $all_feeds = $feeds->get_feeds(); - $feed = array_pop($all_feeds); - - $feed->delete(); } public function testGetFeed() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); - $crawler = self::$DI['client']->request('GET', '/admin/publications/feed/' . $feed->get_id() . '/'); + $feed = $this->insertOneFeed(self::$DI['user'], "salut"); + $crawler = self::$DI['client']->request('GET', '/admin/publications/feed/' . $feed->getId() . '/'); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - $this->assertEquals(1, $crawler->filterXPath("//form[@action='/admin/publications/feed/" . $feed->get_id() . "/update/']")->count()); + $this->assertEquals(1, $crawler->filterXPath("//form[@action='/admin/publications/feed/" . $feed->getId() . "/update/']")->count()); $this->assertEquals(1, $crawler->filterXPath("//input[@value='salut']")->count()); - $this->assertEquals(1, $crawler->filterXPath("//input[@value='coucou']")->count()); - - $feed->delete(); - } - - public function testUpdateFeedNotOwner() - { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user_alt1'], "salut", 'coucou'); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/update/"); - $this->assertTrue(self::$DI['client']->getResponse()->isRedirect(), 'update fails, i\'m redirected'); - $this->assertTrue( - strpos( - self::$DI['client']->getResponse()->headers->get('Location') - , '/admin/publications/feed/' . $feed->get_id() . '/?' - ) === 0); - $feed->delete(); } public function testUpdatedFeedException() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/update/", array( + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/update/", array( 'title' => 'test' , 'subtitle' => 'test' , 'public' => '1' )); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); $this->assertTrue( strpos( @@ -87,19 +66,17 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic , '/admin/publications/list/' ) === 0); - $this->assertEquals('test', $feed->get_title()); - $this->assertEquals('test', $feed->get_subtitle()); - $this->assertTrue($feed->is_public()); - $this->assertNull($feed->get_collection()); - - $feed->delete(); + $this->assertEquals('test', $feed->getTitle()); + $this->assertEquals('test', $feed->getSubtitle()); + $this->assertTrue($feed->getPublic()); + $this->assertNull($feed->getCollection(self::$DI['app'])); } public function testUpdatedFeedOwner() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/update/", array( + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/update/", array( 'title' => 'test' , 'subtitle' => 'test' , 'public' => '1' @@ -112,13 +89,13 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic , '/admin/publications/list/' ) === 0); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); - $collection = $feed->get_collection(); + $collection = $feed->getCollection(self::$DI['app']); - $this->assertEquals('test', $feed->get_title()); - $this->assertEquals('test', $feed->get_subtitle()); - $this->assertFalse($feed->is_public()); + $this->assertEquals('test', $feed->getTitle()); + $this->assertEquals('test', $feed->getSubtitle()); + $this->assertTrue($feed->getPublic()); $this->assertEquals(self::$DI['collection']->get_base_id(), $collection->get_base_id()); $this->assertTrue( @@ -126,12 +103,12 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic self::$DI['client']->getResponse()->headers->get('Location') , '/admin/publications/list/' ) === 0); - - $feed->delete(); } public function testIconUploadErrorOwner() { + $this->markTestSkipped(); // icon upload being changed + $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user_alt1'], "salut", 'coucou'); self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/iconupload/", array(), array(), array('HTTP_ACCEPT' => 'application/json')); @@ -149,6 +126,8 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic public function testIconUploadErrorFileData() { + $this->markTestSkipped(); // icon upload being changed + $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); self::$DI['client']->request( @@ -169,6 +148,8 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic public function testIconUploadErrorFileType() { + $this->markTestSkipped(); // icon upload being changed + $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); self::$DI['client']->request( @@ -189,6 +170,8 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic public function testIconUpload() { + $this->markTestSkipped(); // icon upload being changed + $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); $files = array( @@ -221,105 +204,94 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic public function testAddPublisher() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/addpublisher/", array( + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/addpublisher/", array( 'usr_id' => self::$DI['user_alt1']->get_id() )); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isRedirect()); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); - $publishers = $feed->get_publishers(); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); + $publishers = $feed->getPublishers(); - $this->assertTrue(isset($publishers[self::$DI['user_alt1']->get_id()])); + $this->assertTrue($feed->isPublisher(self::$DI['user_alt1'])); $this->assertTrue( strpos( self::$DI['client']->getResponse()->headers->get('Location') - , '/admin/publications/feed/' . $feed->get_id() . '/' + , '/admin/publications/feed/' . $feed->getId() . '/' ) === 0); - - $feed->delete(); } public function testAddPublisherException() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/addpublisher/"); + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/addpublisher/"); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isRedirect()); $this->assertTrue( strpos( self::$DI['client']->getResponse()->headers->get('Location') - , '/admin/publications/feed/' . $feed->get_id() . '/?err' + , '/admin/publications/feed/' . $feed->getId() . '/?err' ) === 0); - - $feed->delete(); } public function testRemovePublisher() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/removepublisher/", array( + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/removepublisher/", array( 'usr_id' => self::$DI['user_alt1']->get_id() )); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isRedirect()); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); - $publishers = $feed->get_publishers(); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); + $publishers = $feed->getPublishers(); $this->assertFalse(isset($publishers[self::$DI['user_alt1']->get_id()])); $this->assertTrue( strpos( self::$DI['client']->getResponse()->headers->get('Location') - , '/admin/publications/feed/' . $feed->get_id() . '/' + , '/admin/publications/feed/' . $feed->getId() . '/' ) === 0); - - $feed->delete(); } public function testRemovePublisherException() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/removepublisher/"); + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/removepublisher/"); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isRedirect()); - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); $this->assertTrue( strpos( self::$DI['client']->getResponse()->headers->get('Location') - , '/admin/publications/feed/' . $feed->get_id() . '/?err' + , '/admin/publications/feed/' . $feed->getId() . '/?err' ) === 0); - - $feed->delete(); } public function testDeleteFeed() { - $feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], "salut", 'coucou'); + $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->get_id() . "/delete/"); + self::$DI['client']->request("POST", "/admin/publications/feed/" . $feed->getId() . "/delete/"); $response = self::$DI['client']->getResponse(); $this->assertTrue($response->isRedirect()); - try { - $feed = new \Feed_Adapter(self::$DI['app'], $feed->get_id()); - $feed->delete(); + $feed = self::$DI['app']['EM']->getRepository("Entities\Feed")->findOneBy(array('id' => $feed->getId())); + if (null !== $feed) { $this->fail("fail deleting feed"); - } catch (\Exception $e) { - } } } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php index 829b53c7e0..da8e27b91d 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php @@ -75,11 +75,11 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $feed = $this->insertOneFeed(self::$DI['user']); $params = array( - "feed_id" => $feed->getId() + "feed_id" => $feed->getId() , "title" => "salut" , "subtitle" => "coucou" , "author_name" => "robert" - , "author_email" => "robert@kikoo.mail" + , "author_mail" => "robert@kikoo.mail" , 'lst' => self::$DI['record_1']->get_serialize_key() ); @@ -95,11 +95,11 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract public function testEntryCreateError() { $params = array( - "feed_id" => 'unknow' + "feed_id" => 'unknow' , "title" => "salut" , "subtitle" => "coucou" , "author_name" => "robert" - , "author_email" => "robert@kikoo.mail" + , "author_mail" => "robert@kikoo.mail" , 'lst' => self::$DI['record_1']->get_serialize_key() ); $crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/create/', $params); @@ -145,7 +145,7 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract "title" => "dog", "subtitle" => "cat", "author_name" => "bird", - "author_email" => "mouse", + "author_mail" => "mouse", 'lst' => self::$DI['record_1']->get_serialize_key(), ); @@ -170,7 +170,7 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract "title" => "dog", "subtitle" => "cat", "author_name" => "bird", - "author_email" => "mouse", + "author_mail" => "mouse", 'lst' => self::$DI['record_1']->get_serialize_key(), ); $crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params); @@ -200,7 +200,7 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract "title" => "dog", "subtitle" => "cat", "author_name" => "bird", - "author_email" => "mouse", + "author_mail" => "mouse", 'lst' => self::$DI['record_1']->get_serialize_key(), ); @@ -222,7 +222,7 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract "title" => "dog", "subtitle" => "cat", "author_name" => "bird", - "author_email" => "mouse", + "author_mail" => "mouse", 'lst' => self::$DI['record_1']->get_serialize_key(), ); @@ -239,11 +239,11 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { $params = array( - "feed_id" => 9999999 + "feed_id" => 9999999 , "title" => "dog" , "subtitle" => "cat" , "author_name" => "bird" - , "author_email" => "mouse" + , "author_mail" => "mouse" , 'lst' => self::$DI['record_1']->get_serialize_key() ); @@ -265,11 +265,11 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $entry = $this->insertOneFeedEntry(self::$DI['user']); $params = array( - "feed_id" => 9999999 + "feed_id" => 9999999 , "title" => "dog" , "subtitle" => "cat" , "author_name" => "bird" - , "author_email" => "mouse" + , "author_mail" => "mouse" , 'sorted_lst' => self::$DI['record_1']->get_serialize_key() . ";" . self::$DI['record_2']->get_serialize_key() . ";12345;" . "unknow_unknow" ); @@ -299,7 +299,7 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract , "title" => "dog" , "subtitle" => "cat" , "author_name" => "bird" - , "author_email" => "mouse" + , "author_mail" => "mouse" , 'lst' => self::$DI['record_1']->get_serialize_key() ); @@ -425,10 +425,10 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['app']['feed.aggregate-link-generator'] = $this->getMockBuilder('Alchemy\Phrasea\Feed\AggregateLinkGenerator') + self::$DI['app']['feed.aggregate-link-generator'] = $this->getMockBuilder('Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator') ->disableOriginalConstructor() ->getMock(); - $link = $this->getMockBuilder('Alchemy\Phrasea\Feed\FeedLink') + $link = $this->getMockBuilder('Alchemy\Phrasea\Feed\Link\FeedLink') ->disableOriginalConstructor() ->getMock(); $link->expects($this->once()) @@ -459,10 +459,10 @@ class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { $feed = $this->insertOneFeed(self::$DI['user']); - self::$DI['app']['feed.user-link-generator'] = $this->getMockBuilder('Alchemy\Phrasea\Feed\LinkGenerator') + self::$DI['app']['feed.user-link-generator'] = $this->getMockBuilder('Alchemy\Phrasea\Feed\Link\FeedLinkGenerator') ->disableOriginalConstructor() ->getMock(); - $link = $this->getMockBuilder('Alchemy\Phrasea\Feed\FeedLink') + $link = $this->getMockBuilder('Alchemy\Phrasea\Feed\Link\FeedLink') ->disableOriginalConstructor() ->getMock(); $link->expects($this->once()) diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php index 255e59d30c..0ebbd57551 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php @@ -5,72 +5,15 @@ namespace Alchemy\Tests\Phrasea\Controller\Root; require_once __DIR__ . '/../../../../../classes/FeedValidator.inc'; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Feed\Aggregate; +use Entities\Feed; +use Entities\FeedEntry; +use Entities\FeedItem; +use Alchemy\Phrasea\Feed\FeedLink; use Symfony\Component\HttpFoundation\Response; class RssFeedTest extends \PhraseanetWebTestCaseAbstract { - /** - * - * @var \Feed_Adapter - */ - public static $feed; - - /** - * - * @var \Feed_Adapter_Entry - */ - public static $entry; - public static $publisher; - - /** - * - * @var \Feed_Collection - */ - protected static $public_feeds; - - /** - * - * @var \Feed_Collection - */ - protected static $private_feeds; - - /** - * - * @var \Feed_Adapter - */ - protected static $feed_1_private; - protected static $feed_1_private_title = 'Feed 1 title'; - protected static $feed_1_private_subtitle = 'Feed 1 subtitle'; - protected static $feed_1_entries = array(); - protected static $feed_2_entries = array(); - protected static $feed_3_entries = array(); - protected static $feed_4_entries = array(); - - /** - * - * @var \Feed_Adapter - */ - protected static $feed_2_private; - protected static $feed_2_private_title = 'Feed 2 title'; - protected static $feed_2_private_subtitle = 'Feed 2 subtitle'; - - /** - * - * @var \Feed_Adapter - */ - protected static $feed_3_public; - protected static $feed_3_public_title = 'Feed 3 title'; - protected static $feed_3_public_subtitle = 'Feed 3 subtitle'; - - /** - * - * @var \Feed_Adapter - */ - protected static $feed_4_public; - protected static $feed_4_public_title = 'Feed 4 title'; - protected static $feed_4_public_subtitle = 'Feed 4 subtitle'; - protected $client; - private static $initialized = false; public function setUp() @@ -81,92 +24,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract @unlink('/tmp/db.sqlite'); copy(__DIR__ . '/../../../../../db-ref.sqlite', '/tmp/db.sqlite'); - - self::$DI['app']['session']->clear(); - self::$DI['app']['session']->set('usr_id', self::$DI['user']->get_id()); - - self::$feed_1_private = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_1_private_title, self::$feed_1_private_subtitle); - self::$feed_1_private->set_public(false); - self::$feed_1_private->set_icon(__DIR__ . '/../../../../../files/logocoll.gif'); - - self::$feed_2_private = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_2_private_title, self::$feed_2_private_subtitle); - self::$feed_2_private->set_public(false); - - self::$feed_3_public = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_3_public_title, self::$feed_3_public_subtitle); - self::$feed_3_public->set_public(true); - self::$feed_3_public->set_icon(__DIR__ . '/../../../../../files/logocoll.gif'); - - self::$feed_4_public = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_4_public_title, self::$feed_4_public_subtitle); - self::$feed_4_public->set_public(true); - - $publishers = self::$feed_4_public->get_publishers(); - $publisher = array_shift($publishers); - - self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') - ->disableOriginalConstructor() - ->getMock(); - - self::$DI['app']['notification.deliverer']->expects($this->atLeastOnce()) - ->method('deliver') - ->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication'), $this->equalTo(null)); - - for ($i = 1; $i != 15; $i++) { - $entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed_4_public, $publisher, 'titre entry', 'soustitre entry', 'Jean-Marie Biggaro', 'author@example.com'); - - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_6']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_7']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_13']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_15']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_16']); - - $entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed_1_private, $publisher, 'titre entry', 'soustitre entry', 'Jean-Marie Biggaro', 'author@example.com'); - - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_6']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_7']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_13']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_15']); - $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_16']); - - self::$feed_4_entries[] = $entry; - } - - self::$public_feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); - self::$private_feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); - self::$DI['app']['session']->clear(); - - self::$initialized = true; } - - self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') - ->disableOriginalConstructor() - ->getMock(); - - self::$DI['app']['notification.deliverer']->expects($this->atLeastOnce()) - ->method('deliver') - ->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication'), $this->equalTo(null)); - - self::$feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], 'title', 'subtitle'); - self::$publisher = \Feed_Publisher_Adapter::getPublisher(self::$DI['app']['phraseanet.appbox'], self::$feed, self::$DI['user']); - self::$entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed, self::$publisher, 'title_entry', 'subtitle', 'hello', "test@mail.com"); - \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], self::$entry, self::$DI['record_1']); - \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], self::$entry, self::$DI['record_2']); - self::$feed->set_public(true); - } - - public function tearDown() - { - if (self::$publisher instanceof \Feed_Publisher_Adapter) { - self::$publisher->delete(); - } - if (self::$entry instanceof \Feed_Entry_Adapter) { - self::$entry->delete(); - } - if (self::$feed instanceof \Feed_Adapter) { - self::$feed->delete(); - } - parent::tearDown(); } public static function setUpBeforeClass() @@ -179,17 +37,13 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public static function tearDownAfterClass() { - self::$feed_1_private->delete(); - self::$feed_2_private->delete(); - self::$feed_3_public->delete(); - self::$feed_4_public->delete(); - parent::tearDownAfterClass(); } public function testPublicFeedAggregated() { - self::$public_feeds->get_aggregate(); + $this->insertOneFeed(self::$DI['user']); + self::$DI['client']->request('GET', '/feeds/aggregated/atom/'); $response = self::$DI['client']->getResponse(); @@ -234,12 +88,9 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract { $this->authenticate(self::$DI['app']); - $link = self::$feed_3_public->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); - $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); + $feed = $this->insertOneFeed(self::$DI['user'], "test1", true); - $this->logout(self::$DI['app']); - - self::$DI['client']->request('GET', "/feeds" . $link); + self::$DI['client']->request('GET', "/feeds/feed/" . $feed->getId() . "/atom/"); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); @@ -250,14 +101,15 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testUserFeedAggregated() { - $this->authenticate(self::$DI['app']); + $feed = $this->insertOneFeed(self::$DI['user']); - $link = self::$private_feeds->get_aggregate()->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); - $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); + $token = $this->insertOneAggregateToken(self::$DI['user']); + + $tokenValue = $token->getValue(); $this->logout(self::$DI['app']); - self::$DI['client']->request('GET', "/feeds" . $link); + self::$DI['client']->request('GET', "/feeds/userfeed/aggregated/$tokenValue/atom/"); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); @@ -270,12 +122,17 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract { $this->authenticate(self::$DI['app']); - $link = self::$feed_1_private->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); - $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); + $feed = $this->insertOneFeed(self::$DI['user']); + + $id = $feed->getId(); + + $token = $this->insertOneFeedToken($feed, self::$DI['user']); + + $tokenValue = $token->getValue(); $this->logout(self::$DI['app']); - self::$DI['client']->request('GET', "/feeds" . $link); + self::$DI['client']->request('GET', "/feeds/userfeed/$tokenValue/$id/atom/"); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); @@ -286,18 +143,16 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testGetFeedFormat() { - $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); - $all_feeds = $feeds->get_feeds(); - $feed = array_shift($all_feeds); + $feed = $this->insertOneFeed(self::$DI['user'], "test", true); - $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/rss/"); + $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->getId() . "/rss/"); $this->assertEquals("application/rss+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); $this->verifyRSS($feed, $xml); - $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/atom/"); + $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->getId() . "/atom/"); $this->assertEquals("application/atom+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); @@ -306,6 +161,8 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testCooliris() { + $feed = $this->insertOneFeed(self::$DI['user'], "test", true); + $crawler = self::$DI['client']->request("GET", "/feeds/cooliris/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertEquals("application/rss+xml", self::$DI['client']->getResponse()->headers->get("content-type")); @@ -315,10 +172,13 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testAggregatedRss() { - $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); - $all_feeds = $feeds->get_feeds(); + $this->insertOneFeed(self::$DI['user'], "test1", true); + $this->insertOneFeed(self::$DI['user'], "test2", true); + + $all_feeds = self::$DI['app']['EM']->getRepository("Entities\Feed")->findAllPublic(); + foreach ($all_feeds as $feed) { - $this->assertTrue($feed->is_public()); + $this->assertTrue($feed->getPublic()); } $crawler = self::$DI['client']->request("GET", "/feeds/aggregated/rss/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); @@ -329,10 +189,13 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testAggregatedAtom() { - $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); - $all_feeds = $feeds->get_feeds(); + $this->insertOneFeed(self::$DI['user'], "test1", true); + $this->insertOneFeed(self::$DI['user'], "test2", true); + + $all_feeds = self::$DI['app']['EM']->getRepository("Entities\Feed")->findAllPublic(); + foreach ($all_feeds as $feed) { - $this->assertTrue($feed->is_public()); + $this->assertTrue($feed->getPublic()); } $crawler = self::$DI['client']->request("GET", "/feeds/aggregated/atom/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); @@ -356,17 +219,15 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testGetFeedId() { - $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); - $all_feeds = $feeds->get_feeds(); - $feed = array_shift($all_feeds); + $feed = $this->insertOneFeed(self::$DI['user'], "test1", true); - $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/rss/"); + $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->getId() . "/rss/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); $this->verifyRSS($feed, $xml); - $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/atom/"); + $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->getId() . "/atom/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyATOM($feed, $xml); @@ -374,12 +235,11 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function testPrivateFeedAccess() { - $private_feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], 'title', 'subtitle'); - $private_feed->set_public(false); - self::$DI['client']->request("GET", "/feeds/feed/" . $private_feed->get_id() . "/rss/"); + $feed = $this->insertOneFeed(self::$DI['user'], "test1", false); + + self::$DI['client']->request("GET", "/feeds/feed/" . $feed->getId() . "/rss/"); $this->assertFalse(self::$DI['client']->getResponse()->isOk()); $this->assertEquals(403, self::$DI['client']->getResponse()->getStatusCode()); - $private_feed->delete(); } public function verifyXML($xml) @@ -400,7 +260,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract } } - public function verifyRSS(\Feed_Adapter $feed, $xml_string) + public function verifyRSS(Feed $feed, $xml_string) { $dom_doc = new \DOMDocument(); $dom_doc->loadXML($xml_string); @@ -413,23 +273,23 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract $this->checkRSSEntryNode($xpath, $feed); } - public function checkRSSRootNode(\DOMXPath $xpath, \Feed_Adapter $feed) + public function checkRSSRootNode(\DOMXPath $xpath, Feed $feed) { $channel = $xpath->query("/rss/channel"); foreach ($channel->item(0)->childNodes as $child) { if ($child->nodeType !== XML_TEXT_NODE) { switch ($child->nodeName) { case 'title': - $this->assertEquals($feed->get_title(), $child->nodeValue); + $this->assertEquals($feed->getTitle(), $child->nodeValue); break; case 'dc:title': - $this->assertEquals($feed->get_title(), $child->nodeValue); + $this->assertEquals($feed->getTitle(), $child->nodeValue); break; case 'description': - $this->assertEquals($feed->get_subtitle(), $child->nodeValue); + $this->assertEquals($feed->getSubtitle(), $child->nodeValue); break; case 'link': - $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_RSS, 1)->get_href(), $child->nodeValue); + $this->assertEquals(self::$DI['app']['feed.user-link-generator']->generatePublic($feed, 'rss', 1)->getURI(), $child->nodeValue); break; case 'pubDate': $this->assertTrue(new \DateTime() >= new \DateTime($child->nodeValue)); @@ -443,7 +303,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract case 'atom:link': foreach ($child->attributes as $attribute) { if ($attribute->name == "href") { - $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_RSS, 1)->get_href(), $attribute->value); + $this->assertEquals(self::$DI['app']['feed.user-link-generator']->generatePublic($feed, 'rss', 1)->getURI(), $attribute->value); break; } } @@ -453,58 +313,56 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract } } - public function checkRSSEntryNode(\DOMXPath $xpath, \Feed_Adapter $feed) + public function checkRSSEntryNode(\DOMXPath $xpath, Feed $feed) { $list_entries = $xpath->query("/rss/channel/item"); $count = 0; $offset_start = 0; $n_entries = 20; - $collection = $feed->get_entries($offset_start, $n_entries); - $entries = $collection->get_entries(); + $entries = $feed->getEntries($offset_start, $n_entries); foreach ($list_entries as $node) { if (sizeof($entries) == 0) { $offset_start = ($offset_start++) * $n_entries; - $collection = $feed->get_entries($offset_start, $n_entries); - $entries = $collection->get_entries(); + $entries = $feed->getEntries($offset_start, $n_entries); if (sizeof($entries) == 0) //no more break; } $feed_entry = array_shift($entries); switch ($node->nodeName) { case 'title': - $this->assertEquals($feed_entry->get_title(), $node->nodeValue); + $this->assertEquals($feed_entry->getTitle(), $node->nodeValue); break; case 'description': - $this->assertEquals($feed_entry->get_subtitle(), $node->nodeValue); + $this->assertEquals($feed_entry->getSubtitle(), $node->nodeValue); break; case 'author': $author = sprintf( '%s (%s)' - , $feed_entry->get_author_email() - , $feed_entry->get_author_name() + , $feed_entry->getAuthorEmail() + , $feed_entry->getAuthorName() ); $this->assertEquals($author, $node->nodeValue); break; case 'pubDate': - $this->assertEquals($feed_entry->get_created_on()->format(DATE_RFC2822), $node->nodeValue); + $this->assertEquals($feed_entry->getCreatedOn()->format(DATE_RFC2822), $node->nodeValue); break; case 'guid': - $this->assertEquals($feed_entry->get_link()->get_href(), $node->nodeValue); + $this->assertEquals($feed_entry->getLink()->getURI(), $node->nodeValue); break; case 'link': - $this->assertEquals($feed_entry->get_link()->get_href(), $node->nodeValue); + $this->assertEquals($feed_entry->getLink()->getURI(), $node->nodeValue); break; } $count++; $this->checkRSSEntryItemsNode($xpath, $feed_entry, $count); } - $this->assertEquals($feed->get_count_total_entries(), $count); + $this->assertEquals($feed->getCountTotalEntries(), $count); } - public function checkRSSEntryItemsNode(\DOMXPath $xpath, \Feed_Entry_Adapter $entry, $count) + public function checkRSSEntryItemsNode(\DOMXPath $xpath, FeedEntry $entry, $count) { - $content = $entry->get_content(); + $content = $entry->getItems(); $available_medium = array('image', 'audio', 'video'); array_walk($content, $this->removeBadItems($content, $available_medium)); $media_group = $xpath->query("/rss/channel/item[" . $count . "]/media:group"); @@ -516,7 +374,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract } } - public function verifyMediaItem(\Feed_Entry_Item $item, \DOMNode $node) + public function verifyMediaItem(FeedItem $item, \DOMNode $node) { foreach ($node->childNodes as $node) { if ($node->nodeType !== XML_TEXT_NODE) { @@ -543,11 +401,11 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract return $current_attributes; } - public function checkMediaContentAttributes(\Feed_Entry_Item $entry_item, \DOMNode $node) + public function checkMediaContentAttributes(FeedItem $entry_item, \DOMNode $node) { $current_attributes = $this->parseAttributes($node); $is_thumbnail = false; - $record = $entry_item->get_record(); + $record = $entry_item->getRecord(); if (false !== strpos($current_attributes["url"], 'preview')) { $ressource = $record->get_subdef('preview'); @@ -602,7 +460,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract } } - public function checkOptionnalMediaGroupNode(\DOMNode $node, \Feed_Entry_Item $entry_item) + public function checkOptionnalMediaGroupNode(\DOMNode $node, FeedItem $entry_item) { $fields = array( 'title' => array( @@ -690,7 +548,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract if ($field["media_field"]["name"] == $node->nodeName && $role != false) { - if ($p4field = $entry_item->get_record()->get_caption()->get_dc_field($field["dc_field"])) { + if ($p4field = $entry_item->getRecord()->get_caption()->get_dc_field($field["dc_field"])) { $this->assertEquals($p4field->get_serialized_values($field["separator"]), $node->nodeValue, sprintf('Asserting good value for DC %s', $field["dc_field"])); if (sizeof($field["media_field"]["attributes"]) > 0) { foreach ($node->attributes as $attribute) { @@ -709,12 +567,12 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract public function removeBadItems(Array &$item_entries, Array $available_medium) { $remove = function($entry_item, $key) use (&$item_entries, $available_medium) { - $preview_sd = $entry_item->get_record()->get_subdef('preview'); + $preview_sd = $entry_item->getRecord()->get_subdef('preview'); $url_preview = $preview_sd->get_permalink(); - $thumbnail_sd = $entry_item->get_record()->get_thumbnail(); + $thumbnail_sd = $entry_item->getRecord()->get_thumbnail(); $url_thumb = $thumbnail_sd->get_permalink(); - if (!in_array(strtolower($entry_item->get_record()->get_type()), $available_medium)) { + if (!in_array(strtolower($entry_item->getRecord()->get_type()), $available_medium)) { unset($item_entries[$key]); //remove } @@ -726,7 +584,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract return $remove; } - public function verifyATOM(\Feed_Adapter $feed, $xml_string) + public function verifyATOM(Feed $feed, $xml_string) { $this->verifyXML($xml_string); $dom_doc = new \DOMDocument(); @@ -739,17 +597,17 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract $this->checkATOMRootNode($dom_doc, $xpath, $feed); } - public function checkATOMRootNode(\DOMDocument $dom_doc, \DOMXPath $xpath, \Feed_Adapter $feed) + public function checkATOMRootNode(\DOMDocument $dom_doc, \DOMXPath $xpath, Feed $feed) { $ids = $xpath->query('/Atom:feed/Atom:id'); - $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $ids->item(0)->nodeValue); + $this->assertEquals(self::$DI['app']['feed.user-link-generator']->generatePublic($feed, 'atom', 1)->getURI(), $ids->item(0)->nodeValue); $titles = $xpath->query('/Atom:feed/Atom:title'); - $this->assertEquals($feed->get_title(), $titles->item(0)->nodeValue); + $this->assertEquals($feed->getTitle(), $titles->item(0)->nodeValue); $subtitles = $xpath->query('/Atom:feed/Atom:subtitle'); if ($subtitles->length > 0) - $this->assertEquals($feed->get_subtitle(), $subtitles->item(0)->nodeValue); + $this->assertEquals($feed->getSubtitle(), $subtitles->item(0)->nodeValue); $updateds = $xpath->query('/Atom:feed/Atom:updated'); $this->assertTrue(new \DateTime() >= new \DateTime($updateds->item(0)->nodeValue)); @@ -759,14 +617,12 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract $count = 0; $offset_start = 0; $n_entries = 20; - $collection = $feed->get_entries($offset_start, $n_entries); - $entries = $collection->get_entries(); + $entries = $feed->getEntries($offset_start, $n_entries); foreach ($entries_item as $entry) { if (sizeof($entries) == 0) { $offset_start = ($offset_start++) * $n_entries; - $collection = $feed->get_entries($offset_start, $n_entries); - $entries = $collection->get_entries(); + $entries = $feed->getEntries($offset_start, $n_entries); if (sizeof($entries) == 0) //no more break; } @@ -774,7 +630,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract $this->checkATOMEntryNode($entry, $xpath, $feed, $feed_entry); $count++; } - $this->assertEquals($feed->get_count_total_entries(), $count); + $this->assertEquals($feed->getCountTotalEntries(), $count); } public function checkATOMEntryNode(\DOMNode $node, \DOMXPath $xpath, \Feed_Adapter $feed, \Feed_Entry_Adapter $entry) @@ -783,12 +639,13 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract if ($child->nodeType !== XML_TEXT_NODE) { switch ($child->nodeName) { case 'id': - $this->assertEquals(sprintf('%sentry/%d/', $feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $entry->get_id()), $child->nodeValue); + + $this->assertEquals(sprintf('%sentry/%d/', self::$DI['app']['feed.user-link-generator']->generatePublic($feed, 'atom', 1)->getURI(), $entry->get_id()), $child->nodeValue); break; case 'link': foreach ($child->attributes as $attribute) { if ($attribute->name == "href") { - $this->assertEquals(sprintf('%sentry/%d/', $feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $entry->get_id()), $attribute->value); + $this->assertEquals(sprintf('%sentry/%d/', self::$DI['app']['feed.user-link-generator']->generatePublic($feed, 'atom', 1)->getURI(), $entry->get_id()), $attribute->value); break; } } diff --git a/tests/Alchemy/Tests/Phrasea/Feed/AggregateLinkGeneratorTest.php b/tests/Alchemy/Tests/Phrasea/Feed/AggregateLinkGeneratorTest.php index 17d21f31d2..e53f1e52cd 100644 --- a/tests/Alchemy/Tests/Phrasea/Feed/AggregateLinkGeneratorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Feed/AggregateLinkGeneratorTest.php @@ -3,7 +3,7 @@ namespace Alchemy\Tests\Phrasea\Feed; use Alchemy\Phrasea\Feed\Aggregate; -use Alchemy\Phrasea\Feed\AggregateLinkGenerator; +use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator; use Entities\Feed; use Symfony\Component\Routing\Generator\UrlGenerator; @@ -22,7 +22,7 @@ class AggregateLinkGeneratorTest extends \PhraseanetPHPUnitAbstract $feeds = array($feed, $another_feed); - $aggregate = new Aggregate(self::$DI['app'], $feeds); + $aggregate = new Aggregate(self::$DI['app']['EM'], $feeds); $generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator') ->disableOriginalConstructor() diff --git a/tests/Alchemy/Tests/Phrasea/Feed/FeedLinkGeneratorTest.php b/tests/Alchemy/Tests/Phrasea/Feed/FeedLinkGeneratorTest.php new file mode 100644 index 0000000000..37c25d4db6 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Feed/FeedLinkGeneratorTest.php @@ -0,0 +1,194 @@ +persist($feed); + self::$DI['app']['EM']->flush(); + + $generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator') + ->disableOriginalConstructor() + ->getMock(); + + if ($alreadyCreated) { + $token = $this->insertOneFeedToken($feed, $user); + $tokenValue = $token->getValue(); + } + + $capture = null; + $generator->expects($this->once()) + ->method('generate') + ->with('feed_user', $this->isType('array'), UrlGenerator::ABSOLUTE_URL) + ->will($this->returnCallback(function ($name, $data, $option) use (&$capture, $expected) { + $capture = $data; + + return $expected; + })); + + $random = self::$DI['app']['tokens']; + + $linkGenerator = new FeedLinkGenerator($generator, self::$DI['app']['EM'], $random); + + $link = $linkGenerator->generate($feed, $user, $format, $page, $renew); + + $this->assertSame($expected, $link->getUri()); + if ($format == "atom") { + $this->assertSame("application/atom+xml", $link->getMimetype()); + $this->assertSame("Title - Atom", $link->getTitle()); + } + elseif ($format == "rss") { + $this->assertSame("application/rss+xml", $link->getMimetype()); + $this->assertSame("Title - RSS", $link->getTitle()); + } + + if ($alreadyCreated) { + if ($renew) { + $this->assertEquals($feed->getId(), $capture['id']); + $this->assertEquals($format, $capture['format']); + $this->assertNotEquals($tokenValue, $capture['token']); + if (null !== $page) { + $this->assertEquals($page, $capture['page']); + } + + $this->assertCount(0, self::$DI['app']['EM'] + ->getRepository("Entities\FeedToken") + ->findBy(array('value' => $tokenValue))); + $this->assertCount(1, self::$DI['app']['EM'] + ->getRepository("Entities\FeedToken") + ->findBy(array('value' => $capture['token']))); + } else { + $expectedParams = array( + 'token' => $tokenValue, + 'id' => $feed->getId(), + 'format' => $format, + ); + + if ($page !== null) { + $expectedParams['page'] = $page; + } + + $this->assertEquals($expectedParams, $capture); + + $this->assertCount(1, self::$DI['app']['EM'] + ->getRepository("Entities\FeedToken") + ->findBy(array('value' => $tokenValue))); + } + } else { + if (null !== $page) { + $this->assertEquals($page, $capture['page']); + } + $this->assertEquals($feed->getId(), $capture['id']); + $this->assertEquals($format, $capture['format']); + $this->assertEquals(12, strlen($capture['token'])); + + $this->assertCount(1, self::$DI['app']['EM'] + ->getRepository("Entities\FeedToken") + ->findBy(array('value' => $capture['token']))); + } + $token = self::$DI['app']['EM'] + ->getRepository('Entities\FeedToken') + ->findByFeedAndUser($feed, $user); + self::$DI['app']['EM']->remove($token); + self::$DI['app']['EM']->flush(); + } + + /** + * @dataProvider provideGenerationDataPublic + */ + public function testGeneratePublic($expected, $format, $feed, $page) + { + self::$DI['app']['EM']->persist($feed); + self::$DI['app']['EM']->flush(); + + $generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator') + ->disableOriginalConstructor() + ->getMock(); + + $capture = null; + $generator->expects($this->once()) + ->method('generate') + ->with('feed_public', $this->isType('array'), UrlGenerator::ABSOLUTE_URL) + ->will($this->returnCallback(function ($name, $data, $option) use (&$capture, $expected) { + $capture = $data; + + return $expected; + })); + + $random = self::$DI['app']['tokens']; + + $linkGenerator = new FeedLinkGenerator($generator, self::$DI['app']['EM'], $random); + + $link = $linkGenerator->generatePublic($feed, $format, $page); + + $this->assertSame($expected, $link->getUri()); + if ($format == "atom") { + $this->assertSame("application/atom+xml", $link->getMimetype()); + $this->assertSame("Title - Atom", $link->getTitle()); + } + elseif ($format == "rss") { + $this->assertSame("application/rss+xml", $link->getMimetype()); + $this->assertSame("Title - RSS", $link->getTitle()); + } + + if (null !== $page) { + $this->assertEquals($page, $capture['page']); + } + $this->assertEquals($feed->getId(), $capture['id']); + $this->assertEquals($format, $capture['format']); + } + + public function provideGenerationData() + { + $user = $this->getMockBuilder('User_Adapter') + ->disableOriginalConstructor() + ->getMock(); + + $user->expects($this->any()) + ->method('get_id') + ->will($this->returnValue(42)); + + $feed = new \Entities\Feed(); + $feed->setTitle('Title'); + + return array( + array('doliprane', 'atom', $feed, $user, null, false, false), + array('doliprane', 'atom', $feed, $user, null, false, true), + array('doliprane', 'atom', $feed, $user, null, true, false), + array('doliprane', 'atom', $feed, $user, null, true, true), + array('doliprane', 'atom', $feed, $user, 1, false, false), + array('doliprane', 'atom', $feed, $user, 1, false, true), + array('doliprane', 'atom', $feed, $user, 1, true, false), + array('doliprane', 'atom', $feed, $user, 1, true, true), + array('doliprane', 'rss', $feed, $user, null, false, false), + array('doliprane', 'rss', $feed, $user, null, false, true), + array('doliprane', 'rss', $feed, $user, null, true, false), + array('doliprane', 'rss', $feed, $user, null, true, true), + array('doliprane', 'rss', $feed, $user, 1, false, false), + array('doliprane', 'rss', $feed, $user, 1, false, true), + array('doliprane', 'rss', $feed, $user, 1, true, false), + array('doliprane', 'rss', $feed, $user, 1, true, true), + ); + } + + public function provideGenerationDataPublic() + { + $feed = new \Entities\Feed(); + $feed->setTitle('Title'); + + return array( + array('doliprane', 'atom', $feed, null), + array('doliprane', 'atom', $feed, 1), + array('doliprane', 'rss', $feed, null), + array('doliprane', 'rss', $feed, 1) + ); + } +} diff --git a/tests/classes/PhraseanetPHPUnitAbstract.php b/tests/classes/PhraseanetPHPUnitAbstract.php index 6aa28dc264..8efcbc6b93 100644 --- a/tests/classes/PhraseanetPHPUnitAbstract.php +++ b/tests/classes/PhraseanetPHPUnitAbstract.php @@ -331,7 +331,7 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase * * @return \Entities\Feed */ - protected function insertOneFeed(\User_Adapter $user, $title = null) + protected function insertOneFeed(\User_Adapter $user, $title = null, $public = null) { try { $feedFixture = new PhraseaFixture\Feed\LoadOneFeed(); @@ -341,6 +341,10 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase $feedFixture->setTitle($title); } + if ($public !== null) { + $feedFixture->setPublic($public); + } + $loader = new Loader(); $loader->addFixture($feedFixture); @@ -397,7 +401,10 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase $token->setFeed($feed); $token->setUsrId($user->get_id()); + $feed->addToken($token); + self::$DI['app']['EM']->persist($token); + self::$DI['app']['EM']->persist($feed); self::$DI['app']['EM']->flush(); } catch (\Exception $e) { $this->fail('Fail to load one FeedToken : ' . $e->getMessage());