diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index 8c70055d29..2f51e9fed7 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -38,7 +38,7 @@ class Publications implements ControllerProviderInterface $controllers->get('/list/', function (PhraseaApplication $app) { - $feeds = \Feed_Collection::load_all( + $feeds = \Feed_Collection::load( $app, $app['authentication']->getUser() ); diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php index 4bc7d76c22..7bf641770e 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php @@ -529,7 +529,7 @@ 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' => \Feed_Collection::load($app, $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 7bfd4098ca..209095223a 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -37,7 +37,7 @@ class Feed implements ControllerProviderInterface * I got a selection of docs, which publications are available forthese docs ? */ $controllers->post('/requestavailable/', function (Application $app, Request $request) { - $feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $publishing = RecordsRequest::fromRequest($app, $request, true, array(), array('bas_chupub')); return $app['twig']->render('prod/actions/publish/publish.html.twig', array('publishing' => $publishing, 'feeds' => $feeds)); @@ -82,7 +82,7 @@ class Feed implements ControllerProviderInterface throw new AccessDeniedHttpException(); } - $feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $datas = $app['twig']->render('prod/actions/publish/publish_edit.html.twig', array('entry' => $entry, 'feeds' => $feeds)); @@ -205,7 +205,7 @@ class Feed implements ControllerProviderInterface $page = (int) $request->query->get('page'); $page = $page > 0 ? $page : 1; - $feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $datas = $app['twig']->render('prod/feeds/feeds.html.twig' , array( @@ -223,7 +223,7 @@ class Feed implements ControllerProviderInterface $page = $page > 0 ? $page : 1; $feed = \Feed_Adapter::load_with_user($app, $app['authentication']->getUser(), $id); - $feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $datas = $app['twig']->render('prod/feeds/feeds.html.twig', array('feed' => $feed, 'feeds' => $feeds, 'page' => $page)); @@ -235,7 +235,7 @@ class Feed implements ControllerProviderInterface $controllers->get('/subscribe/aggregated/', function (Application $app, Request $request) { $renew = ($request->query->get('renew') === 'true'); - $feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $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/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php index d484f2a6d1..c24f9681da 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php @@ -74,7 +74,7 @@ class Root implements ControllerProviderInterface $cssfile = '000000'; } - $user_feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser()); + $user_feeds = \Feed_Collection::load($app, $app['authentication']->getUser()); $feeds = array_merge(array($user_feeds->get_aggregate()), $user_feeds->get_feeds()); $thjslist = ""; diff --git a/lib/classes/API/V1/adapter.php b/lib/classes/API/V1/adapter.php index 7b544bf88b..ec66644e02 100644 --- a/lib/classes/API/V1/adapter.php +++ b/lib/classes/API/V1/adapter.php @@ -1480,14 +1480,14 @@ class API_V1_adapter extends API_V1_Abstract { $result = new API_V1_result($this->app, $request, $this); - $coll = Feed_Collection::load_all($this->app, $user); + $coll = Feed_Collection::load($this->app, $user); - $datas = array(); + $data = array(); foreach ($coll->get_feeds() as $feed) { - $datas[] = $this->list_publication($feed, $user); + $data[] = $this->list_publication($feed, $user); } - $result->set_datas(array("feeds" => $datas)); + $result->set_datas(array("feeds" => $data)); return $result; } @@ -1536,21 +1536,21 @@ class API_V1_adapter extends API_V1_Abstract { $result = new API_V1_result($this->app, $request, $this); - $feed = Feed_Aggregate::load_with_user($this->app, $user); + $restrictions = (array) ($request->get('feeds') ? : array()); + + $feed = Feed_Aggregate::load_with_user($this->app, $user, $restrictions); $offset_start = (int) ($request->get('offset_start') ? : 0); $per_page = (int) ($request->get('per_page') ? : 5); $per_page = (($per_page >= 1) && ($per_page <= 20)) ? $per_page : 5; - $datas = array( + $result->set_datas(array( 'total_entries' => $feed->get_count_total_entries(), 'offset_start' => $offset_start, 'per_page' => $per_page, 'entries' => $this->list_publications_entries($feed, $offset_start, $per_page), - ); - - $result->set_datas($datas); + )); return $result; } @@ -1643,6 +1643,7 @@ class API_V1_adapter extends API_V1_Abstract 'subtitle' => $entry->get_subtitle(), 'items' => $items, 'feed_id' => $entry->get_feed()->get_id(), + 'feed_title' => $entry->get_feed()->get_title(), 'feed_url' => '/feeds/' . $entry->get_feed()->get_id() . '/content/', 'url' => '/feeds/entry/' . $entry->get_id() . '/', ); diff --git a/lib/classes/Feed/Aggregate.php b/lib/classes/Feed/Aggregate.php index 98ab573248..8219d2eb4b 100644 --- a/lib/classes/Feed/Aggregate.php +++ b/lib/classes/Feed/Aggregate.php @@ -212,11 +212,12 @@ class Feed_Aggregate extends Feed_Abstract implements Feed_Interface * * @param Application $app * @param User_Adapter $user + * @param array $reduce * @return Feed_Aggregate */ - public static function load_with_user(Application $app, User_Adapter $user) + public static function load_with_user(Application $app, User_Adapter $user, $reduce = array()) { - $feeds = Feed_Collection::load_all($app, $user); + $feeds = Feed_Collection::load($app, $user, $reduce); return new self($app, $feeds->get_feeds()); } diff --git a/lib/classes/Feed/Collection.php b/lib/classes/Feed/Collection.php index c54e9b000b..49d86c10d8 100644 --- a/lib/classes/Feed/Collection.php +++ b/lib/classes/Feed/Collection.php @@ -52,24 +52,33 @@ class Feed_Collection implements Feed_CollectionInterface, cache_cacheableInterf * * @param Application $app * @param User_Adapter $user + * @param array $reduce + * * @return Feed_Collection */ - public static function load_all(Application $app, User_Adapter $user) + public static function load(Application $app, User_Adapter $user, $reduce = array()) { $base_ids = array_keys($user->ACL()->get_granted_base()); - $sql = 'SELECT id FROM feeds - WHERE base_id IS NULL '; - - if (count($base_ids) > 0) { - $sql .= ' OR base_id - IN (' . implode(', ', $base_ids) . ') '; + $chunkSql = array('SELECT id FROM feeds WHERE'); + // restrict to given feed ids + if (count($reduce) > 0) { + $chunkSql[] = sprintf('(id IN (%s)) AND', implode(', ', $reduce)); + } else { + $chunkSql[] = '1 AND'; } - $sql .= ' OR public = "1" - ORDER BY created_on DESC'; + // restrict to granted collection + if (count($base_ids) > 0) { + $chunkSql[] = sprintf('((base_id IN (%s)) OR ', implode(', ', $base_ids)); + } else { + $chunkSql[] = '('; + } + $chunkSql[] = '(public = "1") OR (base_id IS NULL)'; + $chunkSql[] = ')'; + $chunkSql[] = 'ORDER BY created_on DESC'; - $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); + $stmt = $app['phraseanet.appbox']->get_connection()->prepare(implode(' ', $chunkSql)); $stmt->execute(); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); @@ -77,7 +86,7 @@ class Feed_Collection implements Feed_CollectionInterface, cache_cacheableInterf $feeds = array(); foreach ($rs as $row) { - $feeds[] = new Feed_Adapter($app, $row['id']); + $feeds[$row['id']] = new Feed_Adapter($app, $row['id']); } return new self($app, $feeds); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php index ab2ac13d68..509bb1f743 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/PublicationTest.php @@ -13,7 +13,7 @@ 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 = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); foreach ($feeds->get_feeds() as $feed) { $this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->get_id() . '/', $pageContent); @@ -26,14 +26,14 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic public function testCreate() { - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); $count = sizeof($feeds->get_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']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); $count_after = sizeof($feeds->get_feeds()); $this->assertGreaterThan($count, $count_after); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php index 0b6b9ef15c..ab18d8a17c 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php @@ -100,7 +100,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract { $crawler = self::$DI['client']->request('POST', '/prod/feeds/requestavailable/'); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); foreach ($feeds->get_feeds() as $one_feed) { if ($one_feed->is_publisher(self::$DI['user'])) { $this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $one_feed->get_id() . "']")->count()); @@ -447,7 +447,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); foreach ($feeds->get_feeds() as $one_feed) { @@ -457,7 +457,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract if ($one_feed->has_access(self::$DI['user'])) { $this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg); } else { - $this->fail('Feed_collection::load_all should return feed where I got access'); + $this->fail('Feed_collection::load should return feed where I got access'); } } } @@ -465,7 +465,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract public function testGetFeed() { - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); $crawler = self::$DI['client']->request('GET', '/prod/feeds/feed/' . $this->feed->get_id() . "/"); $pageContent = self::$DI['client']->getResponse()->getContent(); @@ -477,14 +477,14 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract if ($one_feed->has_access(self::$DI['user'])) { $this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg); } else { - $this->fail('Feed_collection::load_all should return feed where I got access'); + $this->fail('Feed_collection::load should return feed where I got access'); } } } public function testSuscribeAggregate() { - $feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); $crawler = self::$DI['client']->request('GET', '/prod/feeds/subscribe/aggregated/'); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type")); diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php index 6bfa68f6b8..32453efd2b 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Root/RSSFeedTest.php @@ -133,7 +133,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract } 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::$private_feeds = \Feed_Collection::load(self::$DI['app'], self::$DI['user']); self::$DI['app']['session']->clear(); self::$initialized = true; diff --git a/tests/classes/Feed/Feed_CollectionTest.php b/tests/classes/Feed/Feed_CollectionTest.php index e2cfe01985..1f25621a82 100644 --- a/tests/classes/Feed/Feed_CollectionTest.php +++ b/tests/classes/Feed/Feed_CollectionTest.php @@ -23,9 +23,9 @@ class Feed_CollectionTest extends PhraseanetPHPUnitAuthenticatedAbstract parent::tearDownAfterClass(); } - public function testLoad_all() + public function testload() { - $coll = Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $coll = Feed_Collection::load(self::$DI['app'], self::$DI['user']); foreach ($coll->get_feeds() as $feed) { $this->assertInstanceOf('Feed_Adapter', $feed); diff --git a/tests/classes/api/v1/api_v1_adapterTest.php b/tests/classes/api/v1/api_v1_adapterTest.php index 2818c154dc..c3697af9e2 100644 --- a/tests/classes/api/v1/api_v1_adapterTest.php +++ b/tests/classes/api/v1/api_v1_adapterTest.php @@ -659,14 +659,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract $feed->delete(); } - public function testRemove_publications() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - public function testGet_publication() { self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') @@ -683,7 +675,7 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract $feed_publisher = Feed_Publisher_Adapter::getPublisher(self::$DI['app']['phraseanet.appbox'], $feed, self::$DI['user']); $feed_entry = Feed_Entry_Adapter::create(self::$DI['app'], $feed, $feed_publisher, "coucou", "hello", "me", "my@email.com"); $feed_entry_item = Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $feed_entry, self::$DI['record_1']); - $coll = Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); + $coll = Feed_Collection::load(self::$DI['app'], self::$DI['user']); foreach ($coll->get_feeds() as $feed) { $result = $this->object->get_publication($request, $feed->get_id(), self::$DI['user']); $this->checkResponseField($result, "feed", 'array');