Add possibility to restrict aggregated feeds to a set of feeds

This commit is contained in:
Nicolas Le Goff
2014-03-20 18:19:55 +01:00
parent 6d79e44c9a
commit 8638bfb3d4
12 changed files with 53 additions and 51 deletions

View File

@@ -38,7 +38,7 @@ class Publications implements ControllerProviderInterface
$controllers->get('/list/', function (PhraseaApplication $app) { $controllers->get('/list/', function (PhraseaApplication $app) {
$feeds = \Feed_Collection::load_all( $feeds = \Feed_Collection::load(
$app, $app['authentication']->getUser() $app, $app['authentication']->getUser()
); );

View File

@@ -529,7 +529,7 @@ class Root implements ControllerProviderInterface
private function getPublicationStartPage(Application $app) private function getPublicationStartPage(Application $app)
{ {
return $app['twig']->render('client/home_inter_pub_basket.html.twig', array( 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') 'image_size' => (int) $app['authentication']->getUser()->getPrefs('images_size')
)); ));
} }

View File

@@ -37,7 +37,7 @@ class Feed implements ControllerProviderInterface
* I got a selection of docs, which publications are available forthese docs ? * I got a selection of docs, which publications are available forthese docs ?
*/ */
$controllers->post('/requestavailable/', function (Application $app, Request $request) { $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')); $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)); 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(); 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)); $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 = (int) $request->query->get('page');
$page = $page > 0 ? $page : 1; $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' $datas = $app['twig']->render('prod/feeds/feeds.html.twig'
, array( , array(
@@ -223,7 +223,7 @@ class Feed implements ControllerProviderInterface
$page = $page > 0 ? $page : 1; $page = $page > 0 ? $page : 1;
$feed = \Feed_Adapter::load_with_user($app, $app['authentication']->getUser(), $id); $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)); $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) { $controllers->get('/subscribe/aggregated/', function (Application $app, Request $request) {
$renew = ($request->query->get('renew') === 'true'); $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( $output = array(
'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') 'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.')

View File

@@ -74,7 +74,7 @@ class Root implements ControllerProviderInterface
$cssfile = '000000'; $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()); $feeds = array_merge(array($user_feeds->get_aggregate()), $user_feeds->get_feeds());
$thjslist = ""; $thjslist = "";

View File

@@ -1480,14 +1480,14 @@ class API_V1_adapter extends API_V1_Abstract
{ {
$result = new API_V1_result($this->app, $request, $this); $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) { 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; return $result;
} }
@@ -1536,21 +1536,21 @@ class API_V1_adapter extends API_V1_Abstract
{ {
$result = new API_V1_result($this->app, $request, $this); $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); $offset_start = (int) ($request->get('offset_start') ? : 0);
$per_page = (int) ($request->get('per_page') ? : 5); $per_page = (int) ($request->get('per_page') ? : 5);
$per_page = (($per_page >= 1) && ($per_page <= 20)) ? $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(), 'total_entries' => $feed->get_count_total_entries(),
'offset_start' => $offset_start, 'offset_start' => $offset_start,
'per_page' => $per_page, 'per_page' => $per_page,
'entries' => $this->list_publications_entries($feed, $offset_start, $per_page), 'entries' => $this->list_publications_entries($feed, $offset_start, $per_page),
); ));
$result->set_datas($datas);
return $result; return $result;
} }

View File

@@ -212,11 +212,12 @@ class Feed_Aggregate extends Feed_Abstract implements Feed_Interface
* *
* @param Application $app * @param Application $app
* @param User_Adapter $user * @param User_Adapter $user
* @param array $reduce
* @return Feed_Aggregate * @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()); return new self($app, $feeds->get_feeds());
} }

View File

@@ -52,24 +52,33 @@ class Feed_Collection implements Feed_CollectionInterface, cache_cacheableInterf
* *
* @param Application $app * @param Application $app
* @param User_Adapter $user * @param User_Adapter $user
* @param array $reduce
*
* @return Feed_Collection * @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()); $base_ids = array_keys($user->ACL()->get_granted_base());
$sql = 'SELECT id FROM feeds $chunkSql = array('SELECT id FROM feeds WHERE');
WHERE base_id IS NULL '; // restrict to given feed ids
if (count($reduce) > 0) {
if (count($base_ids) > 0) { $chunkSql[] = sprintf('(id IN (%s)) AND', implode(', ', $reduce));
$sql .= ' OR base_id } else {
IN (' . implode(', ', $base_ids) . ') '; $chunkSql[] = '1 OR';
} }
$sql .= ' OR public = "1" // restrict to granted collection
ORDER BY created_on DESC'; 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(); $stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC); $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
@@ -77,7 +86,7 @@ class Feed_Collection implements Feed_CollectionInterface, cache_cacheableInterf
$feeds = array(); $feeds = array();
foreach ($rs as $row) { 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); return new self($app, $feeds);

View File

@@ -13,7 +13,7 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic
$crawler = self::$DI['client']->request('GET', '/admin/publications/list/'); $crawler = self::$DI['client']->request('GET', '/admin/publications/list/');
$pageContent = self::$DI['client']->getResponse()->getContent(); $pageContent = self::$DI['client']->getResponse()->getContent();
$this->assertTrue(self::$DI['client']->getResponse()->isOk()); $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) { foreach ($feeds->get_feeds() as $feed) {
$this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->get_id() . '/', $pageContent); $this->assertRegExp('/\/admin\/publications\/feed\/' . $feed->get_id() . '/', $pageContent);
@@ -26,14 +26,14 @@ class Module_Admin_Route_PublicationTest extends \PhraseanetWebTestCaseAuthentic
public function testCreate() 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()); $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())); $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/')); $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()); $count_after = sizeof($feeds->get_feeds());
$this->assertGreaterThan($count, $count_after); $this->assertGreaterThan($count, $count_after);

View File

@@ -100,7 +100,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
{ {
$crawler = self::$DI['client']->request('POST', '/prod/feeds/requestavailable/'); $crawler = self::$DI['client']->request('POST', '/prod/feeds/requestavailable/');
$this->assertTrue(self::$DI['client']->getResponse()->isOk()); $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) { foreach ($feeds->get_feeds() as $one_feed) {
if ($one_feed->is_publisher(self::$DI['user'])) { if ($one_feed->is_publisher(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $one_feed->get_id() . "']")->count()); $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()); $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) { foreach ($feeds->get_feeds() as $one_feed) {
@@ -457,7 +457,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
if ($one_feed->has_access(self::$DI['user'])) { if ($one_feed->has_access(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg); $this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg);
} else { } 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() 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() . "/"); $crawler = self::$DI['client']->request('GET', '/prod/feeds/feed/' . $this->feed->get_id() . "/");
$pageContent = self::$DI['client']->getResponse()->getContent(); $pageContent = self::$DI['client']->getResponse()->getContent();
@@ -477,14 +477,14 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
if ($one_feed->has_access(self::$DI['user'])) { if ($one_feed->has_access(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg); $this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg);
} else { } 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() 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/'); $crawler = self::$DI['client']->request('GET', '/prod/feeds/subscribe/aggregated/');
$this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type")); $this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));

View File

@@ -133,7 +133,7 @@ class RssFeedTest extends \PhraseanetWebTestCaseAbstract
} }
self::$public_feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); 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::$DI['app']['session']->clear();
self::$initialized = true; self::$initialized = true;

View File

@@ -23,9 +23,9 @@ class Feed_CollectionTest extends PhraseanetPHPUnitAuthenticatedAbstract
parent::tearDownAfterClass(); 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) { foreach ($coll->get_feeds() as $feed) {
$this->assertInstanceOf('Feed_Adapter', $feed); $this->assertInstanceOf('Feed_Adapter', $feed);

View File

@@ -659,14 +659,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$feed->delete(); $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() public function testGet_publication()
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') 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_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 = 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']); $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) { foreach ($coll->get_feeds() as $feed) {
$result = $this->object->get_publication($request, $feed->get_id(), self::$DI['user']); $result = $this->object->get_publication($request, $feed->get_id(), self::$DI['user']);
$this->checkResponseField($result, "feed", 'array'); $this->checkResponseField($result, "feed", 'array');