Implementation of doctrine entities

This commit is contained in:
Andrey
2013-05-30 19:04:49 +02:00
parent fc9379ca63
commit f117817e87
25 changed files with 1374 additions and 302 deletions

View File

@@ -84,6 +84,7 @@ use Alchemy\Phrasea\Core\Provider\CacheServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider;
use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider;
use Alchemy\Phrasea\Core\Provider\FeedServiceProvider;
use Alchemy\Phrasea\Core\Provider\FtpServiceProvider;
use Alchemy\Geonames\GeonamesServiceProvider;
use Alchemy\Phrasea\Core\Provider\InstallerServiceProvider;
@@ -200,6 +201,7 @@ class Application extends SilexApplication
$this->register(new ImagineServiceProvider());
$this->register(new JMSSerializerServiceProvider());
$this->register(new FFMpegServiceProvider());
$this->register(new FeedServiceProvider());
$this->register(new FilesystemServiceProvider());
$this->register(new FtpServiceProvider());
$this->register(new GeonamesServiceProvider());

View File

@@ -11,7 +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 Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -39,10 +42,10 @@ 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 = $app["EM"]->getRepository("Entities\Feed")->getAllForUser($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));
return $app['twig']->render('prod/actions/publish/publish.html.twig', array('publishing' => $publishing, 'feeds' => $feeds));
});
/**
@@ -50,24 +53,42 @@ class Feed implements ControllerProviderInterface
*/
$controllers->post('/entry/create/', function(Application $app, Request $request) {
try {
$feed = new \Feed_Adapter($app, $request->request->get('feed_id'));
$publisher = \Feed_Publisher_Adapter::getPublisher($app['phraseanet.appbox'], $feed, $app['authentication']->getUser());
$feed = $app["EM"]->getRepository("Entities\Feed")->find($request->request->get('feed_id'));
$publisher = $app["EM"]->getRepository("Entities\FeedPublisher")->findByUser($feed, $app['authentication']->getUser());
$title = $request->request->get('title');
$subtitle = $request->request->get('subtitle');
$author_name = $request->request->get('author_name');
$author_mail = $request->request->get('author_mail');
$author_email = $request->request->get('author_email');
$entry = \Feed_Entry_Adapter::create($app, $feed, $publisher, $title, $subtitle, $author_name, $author_mail);
$entry = new \Entities\FeedEntry();
$entry->setFeed($feed);
$entry->setPublisher($publisher);
$entry->setTitle($title);
$entry->setSubtitle($subtitle);
$entry->setAuthorName($author_name);
$entry->setAuthorEmail($author_email);
$feed->addEntry($entry);
$publishing = RecordsRequest::fromRequest($app, $request, true, array(), array('bas_chupub'));
foreach ($publishing as $record) {
$item = \Feed_Entry_Item::create($app['phraseanet.appbox'], $entry, $record);
$item = new \Entities\FeedItem();
$item->setEntry($entry);
$item->setRecordId($record->get_record_id());
$item->setSbasId($record->get_sbas_id());
$entry->addItem($item);
$app["EM"]->persist($item);
}
$datas = array('error' => false, 'message' => false);
$app["EM"]->persist($entry);
$app["EM"]->persist($feed);
$app["EM"]->flush();
$app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId()), $entry);
$datas = array('error' => false, 'message' => false);
} catch (\Exception $e) {
$datas = array('error' => true, 'message' => _('An error occured'), 'details' => $e->getMessage());
$datas = array('error' => true, 'message' => _('An error occured'), 'details' => $e->getMessage());
}
return $app->json($datas);
@@ -78,13 +99,13 @@ class Feed implements ControllerProviderInterface
});
$controllers->get('/entry/{id}/edit/', function(Application $app, Request $request, $id) {
$entry = \Feed_Entry_Adapter::load_from_id($app, $id);
$entry = $app["EM"]->getRepository("Entities\FeedEntry")->find($id);
if (!$entry->is_publisher($app['authentication']->getUser())) {
if (!$entry->isPublisher($app['authentication']->getUser())) {
throw new AccessDeniedHttpException();
}
$feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser());
$feeds = $app["EM"]->getRepository("Entities\Feed")->findAll();
$datas = $app['twig']->render('prod/actions/publish/publish_edit.html.twig', array('entry' => $entry, 'feeds' => $feeds));
@@ -97,40 +118,44 @@ class Feed implements ControllerProviderInterface
});
$controllers->post('/entry/{id}/update/', function(Application $app, Request $request, $id) {
$datas = array('error' => true, 'message' => '', 'datas' => '');
$datas = array('error' => true, 'message' => '', 'datas' => '');
try {
$app['phraseanet.appbox']->get_connection()->beginTransaction();
$entry = $app["EM"]->getRepository("Entities\FeedEntry")->find($id);
$entry = \Feed_Entry_Adapter::load_from_id($app, $id);
if (!$entry->is_publisher($app['authentication']->getUser())) {
if (null === $entry) {
throw new NotFoundHttpException();
}
if (!$entry->isPublisher($app['authentication']->getUser())) {
throw new AccessDeniedHttpException();
}
$title = $request->request->get('title');
$subtitle = $request->request->get('subtitle');
$author_name = $request->request->get('author_name');
$author_mail = $request->request->get('author_mail');
$author_mail = $request->request->get('author_email');
$entry->set_author_email($author_mail)
->set_author_name($author_name)
->set_title($title)
->set_subtitle($subtitle);
$entry->setAuthorEmail($author_mail)
->setAuthorName($author_name)
->setTitle($title)
->setSubtitle($subtitle);
$current_feed_id = $entry->get_feed()->get_id();
$current_feed_id = $entry->getFeed()->getId();
$new_feed_id = $request->request->get('feed_id', $current_feed_id);
if ($current_feed_id != $new_feed_id) {
try {
$new_feed = \Feed_Adapter::load_with_user($app, $app['authentication']->getUser(), $new_feed_id);
$new_feed = $app["EM"]->getRepository("Entities\Feed")->loadWithUser($app, $app['authentication']->getUser(), $new_feed_id);
} catch (NotFoundHttpException $e) {
throw new AccessDeniedHttpException('You have no access to this feed');
}
if (!$new_feed->is_publisher($app['authentication']->getUser())) {
throw new AccessDeniedHttpException('You are not publisher of this feed');
if ($new_feed === null) {
throw new NotFoundHttpException();
}
$entry->set_feed($new_feed);
if (!$new_feed->isPublisher($app['authentication']->getUser())) {
throw new \Exception_Forbidden('You are not publisher of this feed');
}
$entry->setFeed($new_feed);
}
$items = explode(';', $request->request->get('sorted_lst'));
@@ -141,26 +166,26 @@ class Feed implements ControllerProviderInterface
continue;
}
$item = new \Feed_Entry_Item($app['phraseanet.appbox'], $entry, $item_sort_datas[0]);
$item->set_ord($item_sort_datas[1]);
$item = new \entities\FeedItem($entry, $item_sort_datas[0]);
$item->setEntry($entry);
$entry->addItem($item);
$item->setOrd($item_sort_datas[1]);
$app["EM"]->persist($item);
}
$app['phraseanet.appbox']->get_connection()->commit();
$app["EM"]->persist($entry);
$app["EM"]->flush();
$entry = $app['twig']->render('prod/feeds/entry.html.twig', array('entry' => $entry));
$datas = array('error' => false, 'message' => 'succes', 'datas' => $entry);
$datas = array('error' => false, 'message' => 'succes', 'datas' => $entry);
} catch (\Exception_Feed_EntryNotFound $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = _('Feed entry not found');
} catch (NotFoundHttpException $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = _('Feed not found');
} catch (AccessDeniedHttpException $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = _('You are not authorized to access this feed');
} catch (\Exception $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = $e->getMessage();
}
@@ -172,26 +197,24 @@ class Feed implements ControllerProviderInterface
});
$controllers->post('/entry/{id}/delete/', function(Application $app, Request $request, $id) {
$datas = array('error' => true, 'message' => '');
$datas = array('error' => true, 'message' => '');
try {
$app['phraseanet.appbox']->get_connection()->beginTransaction();
$entry = $app["EM"]->getRepository("Entities\FeedEntry")->find($id);
$entry = \Feed_Entry_Adapter::load_from_id($app, $id);
if (!$entry->is_publisher($app['authentication']->getUser())
&& $entry->get_feed()->is_owner($app['authentication']->getUser()) === false) {
if (null === $entry) {
throw new NotFoundHttpException();
}
if (!$entry->isPublisher($app['authentication']->getUser()) && $entry->getFeed()->isOwner($app['authentication']->getUser()) === false) {
throw new AccessDeniedHttpException(_('Action Forbidden : You are not the publisher'));
}
$entry->delete();
$app["EM"]->remove($entry);
$app["EM"]->flush();
$app['phraseanet.appbox']->get_connection()->commit();
$datas = array('error' => false, 'message' => 'succes');
} catch (\Exception_Feed_EntryNotFound $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas = array('error' => false, 'message' => 'succes');
} catch (NotFoundHttpException $e) {
$datas['message'] = _('Feed entry not found');
} catch (\Exception $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = $e->getMessage();
}
@@ -207,13 +230,13 @@ 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 = $app["EM"]->getRepository("Entities\Feed")->findAll();
$datas = $app['twig']->render('prod/feeds/feeds.html.twig'
, array(
'feeds' => $feeds
, 'feed' => $feeds->get_aggregate()
, 'page' => $page
, 'feed' => new Aggregate($app, $feeds)
, 'page' => $page
)
);
@@ -224,10 +247,10 @@ class Feed implements ControllerProviderInterface
$page = (int) $request->query->get('page');
$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());
$feed = $app["EM"]->getRepository("Entities\Feed")->loadWithUser($app, $app['authentication']->getUser(), $id);
$feeds = $app["EM"]->getRepository("Entities\Feed")->findAll();
$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));
return new Response($datas);
})
@@ -237,12 +260,18 @@ 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 = $app["EM"]->getRepository("Entities\Feed")->findAll();
$aggregateGenerator = new AggregateLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']);
$aggregate = new Aggregate($app, $feeds);
$link = $aggregateGenerator->generate($aggregate, $app['authentication']->getUser(), AggregateLinkGenerator::FORMAT_RSS, null, $renew);
$output = array(
'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.')
. '</p><p>' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '</p>
<div><input type="text" readonly="readonly" class="input_select_copy" value="' . $feeds->get_aggregate()->get_user_link($app['phraseanet.registry'], $app['authentication']->getUser(), \Feed_Adapter::FORMAT_RSS, null, $renew)->get_href() . '"/></div>',
<div><input type="text" readonly="readonly" class="input_select_copy" value="' . $link->getURI() . '"/></div>',
'titre' => _('publications::votre rss personnel')
);
@@ -251,12 +280,17 @@ class Feed implements ControllerProviderInterface
$controllers->get('/subscribe/{id}/', function(Application $app, Request $request, $id) {
$renew = ($request->query->get('renew') === 'true');
$feed = \Feed_Adapter::load_with_user($app, $app['authentication']->getUser(), $id);
$feed = $app["EM"]->getRepository("Entities\Feed")->loadWithUser($app, $app['authentication']->getUser(), $id);
$linkGenerator = new LinkGenerator($app['url_generator'], $app['EM'], $app['tokens']);
$link = $linkGenerator->generate($feed, $app['authentication']->getUser(), LinkGenerator::FORMAT_RSS, null, $renew);
$output = array(
'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.')
. '</p><p>' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '</p>
<div><input type="text" style="width:100%" value="' . $feed->get_user_link($app['phraseanet.registry'], $app['authentication']->getUser(), \Feed_Adapter::FORMAT_RSS, null, $renew)->get_href() . '"/></div>',
<div><input type="text" style="width:100%" value="' . $link->getURI() . '"/></div>',
'titre' => _('publications::votre rss personnel')
);

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Controller\Prod;
use \Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Exception\SessionNotFound;
use Silex\Application as SilexApplication;
@@ -72,8 +73,10 @@ class Root implements ControllerProviderInterface
$cssfile = '000000';
}
$user_feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser());
$feeds = array_merge(array($user_feeds->get_aggregate()), $user_feeds->get_feeds());
// $user_feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser());
// $feeds = array_merge(array($user_feeds->get_aggregate()), $user_feeds->get_feeds());
$user_feeds = $app["EM"]->getRepository("Entities\Feed")->getAllForUser($app['authentication']->getUser());
$aggregate = new Aggregate($app, $user_feeds);
$thjslist = "";
@@ -115,7 +118,7 @@ class Root implements ControllerProviderInterface
'GV_thesaurus' => $app['phraseanet.registry']->get('GV_thesaurus'),
'cgus_agreement' => \databox_cgu::askAgreement($app),
'css' => $css,
'feeds' => $feeds,
'aggregate' => $aggregate,
'GV_google_api' => $app['phraseanet.registry']->get('GV_google_api'),
'queries_topics' => $queries_topics,
'search_status' => \databox_status::getSearchStatus($app),

View File

@@ -28,45 +28,45 @@ class RSSFeeds implements ControllerProviderInterface
$controllers = $app['controllers_factory'];
$display_feed = function(Application $app, $feed, $format, $page, $user = null) {
$total = $feed->get_count_total_entries();
$total = $feed->getCountTotalEntries();
$perPage = 5;
$entries = $feed->get_entries((($page - 1) * $perPage), $perPage);
$entries = $feed->getEntries((($page - 1) * $perPage), $perPage);
if ($format == \Feed_Adapter::FORMAT_RSS) {
if ($format == \Entities\Feed::FORMAT_RSS) {
$content = new \Feed_XML_RSS();
}
if ($format == \Feed_Adapter::FORMAT_ATOM) {
if ($format == \Entities\Feed::FORMAT_ATOM) {
$content = new \Feed_XML_Atom();
}
if ($format == \Feed_Adapter::FORMAT_COOLIRIS) {
if ($format == \Entities\Feed::FORMAT_COOLIRIS) {
$content = new \Feed_XML_Cooliris();
}
if ($user instanceof \User_Adapter)
$link = $feed->get_user_link($app['phraseanet.registry'], $user, $format, $page);
$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->get_title());
$content->set_subtitle($feed->get_subtitle());
$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->get_user_link($app['phraseanet.registry'], $user, $format, ($page - 1)));
$content->set_previous_page($feed->getUserLink($app['phraseanet.registry'], $user, $format, ($page - 1)));
if ($total > ($page * $perPage))
$content->set_next_page($feed->get_user_link($app['phraseanet.registry'], $user, $format, ($page + 1)));
$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->get_entries() as $entry)
foreach ($entries->getEntries() as $entry)
$content->set_item($entry);
$render = $content->render();
@@ -77,9 +77,10 @@ class RSSFeeds implements ControllerProviderInterface
};
$controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) use ($display_feed) {
$feed = new \Feed_Adapter($app, $id);
// $feed = new \Feed_Adapter($app, $id);
$feed = $app["EM"]->getRepository("Entities\Feed")->find($id);
if (!$feed->is_public()) {
if (!$feed->isPublic()) {
return new Response('Forbidden', 403);
}
@@ -95,8 +96,8 @@ class RSSFeeds implements ControllerProviderInterface
->assert('format', '(rss|atom)');
$controllers->get('/userfeed/{token}/{id}/{format}/', function(Application $app, $token, $id, $format) use ($display_feed) {
$token = new \Feed_Token($app, $token, $id);
$feed = $token->get_feed();
$token = $app["EM"]->getRepository("Entities\FeedToken")->findBy(array("id" => $id));
$feed = $token->getFeed();
$request = $app['request'];
@@ -110,8 +111,8 @@ class RSSFeeds implements ControllerProviderInterface
->assert('format', '(rss|atom)');
$controllers->get('/userfeed/aggregated/{token}/{format}/', function(Application $app, $token, $format) use ($display_feed) {
$token = new \Feed_TokenAggregate($app, $token);
$feed = $token->get_feed();
$token = $app["EM"]->getRepository("Entities\AggregateToken")->findBy(array("id" => $id));
//$feed = $token->getFeed();
$request = $app['request'];
@@ -124,8 +125,10 @@ class RSSFeeds implements ControllerProviderInterface
->assert('format', '(rss|atom)');
$controllers->get('/aggregated/{format}/', function(Application $app, $format) use ($display_feed) {
$feeds = \Feed_Collection::load_public_feeds($app);
$feed = $feeds->get_aggregate();
//$feeds = \Feed_Collection::load_public_feeds($app);
//$feed = $feeds->get_aggregate();
$feeds = $app["EM"]->getRepository("Entities\Feed")->findAllPublic();
$feed = new Aggregate($app, $feeds);
$request = $app['request'];
$page = (int) $request->query->get('page');
@@ -137,8 +140,10 @@ class RSSFeeds implements ControllerProviderInterface
->assert('format', '(rss|atom)');
$controllers->get('/cooliris/', function(Application $app) use ($display_feed) {
$feeds = \Feed_Collection::load_public_feeds($app);
$feed = $feeds->get_aggregate();
// $feeds = \Feed_Collection::load_public_feeds($app);
// $feed = $feeds->get_aggregate();
$feeds = $app["EM"]->getRepository("Entities\Feed")->findAllPublic();
$feed = new Aggregate($app, $feeds);
$request = $app['request'];
$page = (int) $request->query->get('page');

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Feed\LinkGenerator;
use Alchemy\Phrasea\Feed\AggregateLinkGenerator;
use Silex\Application;
use Silex\ServiceProviderInterface;
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']);
});
$app['feed.aggreagate-link-generator'] = $app->share(function($app) {
return new AggregateLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']);
});
}
public function boot(Application $app)
{
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace Alchemy\Phrasea\Feed;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityManager;
class Aggregate implements FeedInterface
{
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $subtitle;
/**
* @var DateTime
*/
protected $created_on;
/**
* @var DateTime
*/
protected $updated_on;
/**
* @var array
*/
protected $feeds;
protected $token;
protected $app;
public function __construct(Application $app, array $feeds)
{
$this->title = 'AGGREGATE';
$this->subtitle = 'AGGREGATE SUBTITLE';
$this->created_on = new \DateTime();
$this->updated_on = new \DateTime();
$this->app = $app;
$tmp_feeds = array();
foreach ($feeds as $feed) {
$tmp_feeds[$feed->getId()] = $feed;
}
$this->feeds = $tmp_feeds;
return $this;
}
public static function createFromUser(Application $app, \User_Adapter $user)
{
$feeds = $app["EM"]->getRepository('Entities\Feed')->findByUser($user);
return new static($app, $feeds);
}
public static function create(Application $app, array $feed_ids)
{
$feeds = $app["EM"]->getRepository('Entities\Feed')->findByIdArray($feed_ids);
return new static($app, $feeds);
}
public function isAggregated()
{
return true;
}
public function getEntries($offset_start, $how_many)
{
$result = new \Feed_Entry_Collection();
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);
}
}
return $result;
}
public function getSubtitle()
{
return $this->subtitle;
}
public function getTitle()
{
return $this->title;
}
public function getIconUrl()
{
$url = '/skins/icons/rss32.gif';
return $url;
}
public function getCreatedOn()
{
return $this->created_on;
}
public function getUpdatedOn()
{
return $this->updated_on;
}
public function getToken()
{
return $this->token;
}
public function setToken($token)
{
$this->token = $token;
}
public function getFeeds()
{
return $this->feeds;
}
public function getCountTotalEntries()
{
if (count($this->feeds) > 0) {
return count($this->app["EM"]->getRepository("Entities\FeedEntry")->findByFeeds($this->feeds));
}
return 0;
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Alchemy\Phrasea\Feed;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Feed\Aggregate;
use Entities\AggregateToken;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Routing\Generator\UrlGenerator;
class AggregateLinkGenerator
{
const FORMAT_ATOM = 'atom';
const FORMAT_RSS = 'rss';
private $em;
private $generator;
private $random;
public function __construct(UrlGenerator $generator, EntityManager $em, \random $random)
{
$this->generator = $generator;
$this->em = $em;
$this->random = $random;
}
public function generate(Aggregate $aggregate, \User_Adapter $user, $format, $page = null, $renew = false)
{
switch ($format) {
case self::FORMAT_ATOM:
return new FeedLink(
$this->generator->generate('feed_user_aggregated', array(
'token' => $this->getAggregateToken($user, $renew)->getValue(),
'format' => 'atom',
), UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $aggregate->getTitle(), 'Atom'),
'application/atom+xml'
);
break;
case self::FORMAT_RSS:
return new FeedLink(
$this->generator->generate('feed_user_aggregated', array(
'token' => $this->getAggregateToken($user, $renew)->getValue(),
'format' => 'rss',
), 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;
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace Alchemy\Phrasea\Feed;
use Doctrine\ORM\Mapping as ORM;
/**
* FeedToken
*/
class AggregateToken
{
/**
* @var integer
*/
private $id;
/**
* @var integer
*/
private $usr_id;
/**
* @var \Entities\Feed
*/
private $feed;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set usr_id
*
* @param integer $usrId
* @return FeedToken
*/
public function setUsrId($usrId)
{
$this->usr_id = $usrId;
return $this;
}
/**
* Get usr_id
*
* @return integer
*/
public function getUsrId()
{
return $this->usr_id;
}
/**
* Set feed
*
* @param \Entities\Feed $feed
* @return FeedToken
*/
public function setFeed(\Entities\Feed $feed = null)
{
$this->feed = $feed;
return $this;
}
/**
* Get feed
*
* @return \Entities\Feed
*/
public function getFeed()
{
return $this->feed;
}
/**
* @var string
*/
private $value;
/**
* Set value
*
* @param string $value
* @return FeedToken
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Alchemy\Phrasea\Feed;
interface FeedInterface
{
public function getIconUrl();
public function getTitle();
public function getEntries($offset_start, $how_many);
public function getSubtitle();
public function isAggregated();
public function getCreatedOn();
public function getUpdatedOn();
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed;
class FeedLink implements FeedLinkInterface
{
/**
* @var string
*/
protected $mimetype;
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $uri;
/**
* @param string $uri
* @param string $title
* @param string $mimetype
*
* @return FeedLink
*/
public function __construct($uri, $title, $mimetype)
{
$this->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;
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Alchemy\Phrasea\Feed;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Doctrine\ORM\EntityManager;
use Entities\Feed;
use Entities\FeedToken;
use Symfony\Component\Routing\Generator\UrlGenerator;
class LinkGenerator
{
const FORMAT_ATOM = 'atom';
const FORMAT_RSS = 'rss';
private $em;
private $generator;
private $random;
public function __construct(UrlGenerator $generator, EntityManager $em, \random $random)
{
$this->generator = $generator;
$this->em = $em;
$this->random = $random;
}
public function generate(Feed $feed, \User_Adapter $user, $format, $page = null, $renew = false)
{
switch ($format) {
case self::FORMAT_ATOM:
return new FeedLink(
$this->generator->generate('feed_user', array(
'token' => $this->getFeedToken($feed, $user, $renew)->getValue(),
'id' => $feed->getId(),
'format' => 'atom',
), UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $feed->getTitle(), 'Atom'),
'application/atom+xml'
);
break;
case self::FORMAT_RSS:
return new FeedLink(
$this->generator->generate('feed_user', array(
'token' => $this->getFeedToken($feed, $user, $renew)->getValue(),
'id' => $feed->getId(),
'format' => 'rss',
), 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;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed;
interface FeedLinkInterface
{
/**
* @return string
*/
public function getMimetype();
/**
* @return string
*/
public function getTitle();
/**
* @return string
*/
public function getURI();
}

View File

@@ -3,12 +3,13 @@
namespace Entities;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Feed
*/
class Feed
class Feed implements FeedInterface
{
/**
* @var integer
@@ -60,6 +61,11 @@ class Feed
*/
private $entries;
/**
* @var \Doctrine\Common\Collections\Collection
*/
private $tokens;
/**
* Constructor
*/
@@ -68,11 +74,11 @@ class Feed
$this->publishers = new \Doctrine\Common\Collections\ArrayCollection();
$this->entries = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
* @return integer
*/
public function getId()
{
@@ -88,14 +94,14 @@ class Feed
public function setPublic($public)
{
$this->public = $public;
return $this;
}
/**
* Get public
*
* @return boolean
* @return boolean
*/
public function getPublic()
{
@@ -111,21 +117,21 @@ class Feed
public function setIconUrl($iconUrl)
{
$this->icon_url = $iconUrl;
return $this;
}
/**
* Get icon_url
*
* @return string
* @return string
*/
public function getIconUrl()
{
if (!$this->icon_url) {
return '/skins/icons/rss32.gif';
}
return '/www/custom/feed_' . $this->getId() . '.jpg';
}
@@ -138,14 +144,14 @@ class Feed
public function setBaseId($baseId)
{
$this->base_id = $baseId;
return $this;
}
/**
* Get base_id
*
* @return integer
* @return integer
*/
public function getBaseId()
{
@@ -161,14 +167,14 @@ class Feed
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
* @return string
*/
public function getTitle()
{
@@ -184,7 +190,7 @@ class Feed
public function addPublisher(\Entities\FeedPublisher $publishers)
{
$this->publishers[] = $publishers;
return $this;
}
@@ -201,7 +207,7 @@ class Feed
/**
* Get publishers
*
* @return \Doctrine\Common\Collections\Collection
* @return \Doctrine\Common\Collections\Collection
*/
public function getPublishers()
{
@@ -217,7 +223,7 @@ class Feed
public function addEntry(\Entities\FeedEntry $entries)
{
$this->entries[] = $entries;
return $this;
}
@@ -234,39 +240,39 @@ class Feed
/**
* Get entries
*
* @return \Doctrine\Common\Collections\Collection
* @return \Doctrine\Common\Collections\Collection
*/
public function getEntries()
public function getEntries($offset_start, $how_many)
{
return $this->entries;
return $this->entries->slice($offset_start, $how_many);
}
public function getOwner()
{
{
foreach ($this->getPublishers() as $publisher) {
if ($publisher->getOwner()) {
return $publisher;
}
}
}
public function isOwner(\User_Adapter $user)
{
$owner = $this->getOwner();
if ($owner !== null && $user->get_id() === $owner->getUsrId()) {
return true;
}
return false;
}
public function getCollection(Application $app)
{
if ($this->getBaseId() !== null) {
return \collection::get_from_base_id($app, $this->getBaseId());
}
}
public function setCollection(\collection $collection = null)
{
if ($collection === null) {
@@ -285,14 +291,14 @@ class Feed
public function setCreatedOn($createdOn)
{
$this->created_on = $createdOn;
return $this;
}
/**
* Get created_on
*
* @return \DateTime
* @return \DateTime
*/
public function getCreatedOn()
{
@@ -308,20 +314,20 @@ class Feed
public function setUpdatedOn($updatedOn)
{
$this->updated_on = $updatedOn;
return $this;
}
/**
* Get updated_on
*
* @return \DateTime
* @return \DateTime
*/
public function getUpdatedOn()
{
return $this->updated_on;
}
public function isPublisher(\User_Adapter $user)
{
foreach ($this->getPublishers() as $publisher) {
@@ -329,10 +335,21 @@ class Feed
return true;
}
}
return false;
}
public function getPublisher(\User_Adapter $user)
{
foreach ($this->getPublishers() as $publisher) {
if ($publisher->getUsrId() == $user->get_id()) {
return $publisher;
}
}
return null;
}
/**
* Set subtitle
*
@@ -342,14 +359,14 @@ class Feed
public function setSubtitle($subtitle)
{
$this->subtitle = $subtitle;
return $this;
}
/**
* Get subtitle
*
* @return string
* @return string
*/
public function getSubtitle()
{
@@ -360,18 +377,51 @@ class Feed
{
return false;
}
public function getCountTotalEntries()
{
return (count($this->entries));
}
public function hasAccess(User_Adapter $user)
public function hasAccess(\User_Adapter $user, Application $app)
{
if ($this->get_collection() instanceof collection) {
if ($this->getCollection($app) instanceof collection) {
return $user->ACL()->has_access_to_base($this->collection->get_base_id());
}
return true;
}
}
/**
* Add tokens
*
* @param \Entities\FeedToken $tokens
* @return Feed
*/
public function addToken(\Entities\FeedToken $tokens)
{
$this->tokens[] = $tokens;
return $this;
}
/**
* Remove tokens
*
* @param \Entities\FeedToken $tokens
*/
public function removeToken(\Entities\FeedToken $tokens)
{
$this->tokens->removeElement($tokens);
}
/**
* Get tokens
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getTokens()
{
return $this->tokens;
}
}

View File

@@ -172,7 +172,7 @@ class FeedEntry
/**
* Set created
*
* @param \DateTime $created
* @param \DateTime $createdOn
* @return FeedEntry
*/
public function setCreatedOn($createdOn)
@@ -189,7 +189,7 @@ class FeedEntry
*/
public function getCreatedOn()
{
return $this->createdOn;
return $this->created_on;
}
/**
@@ -212,7 +212,7 @@ class FeedEntry
*/
public function getUpdatedOn()
{
return $this->updatedOn;
return $this->updated_on;
}
/**
@@ -303,4 +303,4 @@ class FeedEntry
return false;
}
}
}

View File

@@ -39,10 +39,6 @@ class FeedItem
*/
private $entry;
public function __construct(\Entities\FeedEntry $entry, \record_adapter $record)
{
}
/**
* Get id
*

View File

@@ -53,14 +53,14 @@
<div class="PNB10 feeds">
<h1>{% trans 'Fils disponibles' %}</h1>
<div class="list">
{% for feed in feeds.get_feeds() %}
{% if feed.is_publisher(app['authentication'].getUser()) %}
{% for feed in feeds %}
{% if feed.isPublisher(app['authentication'].getUser()) %}
<div class="feed {% if loop.index is odd%}odd{% endif %}">
<span>{{ feed.get_title() }}</span>
{% if feed.is_public() %}
<span>{{ feed.getTitle() }}</span>
{% if feed.getPublic() %}
<img src="/skins/icons/ligth-on.png" title="{% trans 'This feed is public' %}"/>
{% endif %}
<input type="hidden" value="{{ feed.get_id() }}"/>
<input type="hidden" value="{{ feed.getId() }}"/>
</div>
{% endif %}
{% endfor %}

View File

@@ -1,2 +1,2 @@
{% import 'prod/feeds/entry_macro.html.twig' as _entry %}
{{ _entry.format(entry.get_feed(), entry) }}
{{ _entry.format(entry.getFeed(), entry) }}

View File

@@ -1,25 +1,25 @@
{% macro format(feed, entry)%}
{% import 'prod/results/record.html.twig' as record_format %}
<div class="entry ui-corner-all" id="entry_{{ entry.get_id() }}">
<div class="entry ui-corner-all" id="entry_{{ entry.getId() }}">
<table class="head">
<tr>
<td>
<h1 class="title">
{% if feed.is_aggregated() %}
<img style="height:16px;" src="{{ entry.get_feed().get_icon_url() }}" />
{% if feed.isAggregated() %}
<img style="height:16px;" src="{{ entry.getFeed().getIconUrl() }}" />
{% endif %}
{{ entry.get_title() }}
{% set author = entry.get_author_name() %}
{{ entry.getTitle() }}
{% set author = entry.getAuthorName() %}
<span class="author">{% trans %}Par {{ author }}{% endtrans %}</span>
</h1>
</td>
<td style="width:60px;text-align:right;">
{% if entry.get_feed().is_owner(app['authentication'].getUser()) or entry.is_publisher(app['authentication'].getUser()) %}
<a class="tools options feed_edit" href="{{ path('feed_entry_edit', { 'id' : entry.get_id() }) }}">
{% if entry.getFeed().isOwner(app['authentication'].getUser()) or entry.isPublisher(app['authentication'].getUser()) %}
<a class="tools options feed_edit" href="{{ path('prod_feeds_feed_edit', { 'id' : entry.getId() }) }}">
<img src="/skins/icons/file-edit.png" title="{% trans 'boutton::editer' %}"/>
</a>
<a class="tools feed_delete" href="{{ path('feed_entry_delete', { 'id' : entry.get_id() }) }}">
<a class="tools feed_delete" href="{{ path('prod_feeds_feed_delete', { 'id' : entry.getId() }) }}">
<img src="/skins/icons/delete.png" title="{% trans 'boutton::supprimer' %}"/>
</a>
{% endif %}
@@ -27,8 +27,8 @@
</tr>
</table>
<div class="post_date">
{% set updated_on = app['date-formatter'].getPrettyString(entry.get_updated_on()) %}
{% set created_on = app['date-formatter'].getPrettyString(entry.get_created_on()) %}
{% set updated_on = app['date-formatter'].getPrettyString(entry.getUpdatedOn()) %}
{% set created_on = app['date-formatter'].getPrettyString(entry.getCreatedOn()) %}
<span class="created_on">
{{ created_on }}
</span>
@@ -41,23 +41,23 @@
)
</span>
{% endif %}
{% if feed.is_aggregated() %}
<a class="ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : entry.get_feed().get_id() }) }}">
{% set feed_name = entry.get_feed().get_title() %}
{% if feed.isAggregated() %}
<a class="ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : entry.getFeed().getId() }) }}">
{% set feed_name = entry.getFeed().getTitle() %}
{% trans %}
dans {{feed_name}}
{% endtrans %}
<img style="height:16px;" src="{{ entry.get_feed().get_icon_url() }}" />
<img style="height:16px;" src="{{ entry.getFeed().getIconUrl() }}" />
</a>
{% endif %}
</div>
<p>{{ entry.get_subtitle()|nl2br|raw }}</p>
<p>{{ entry.getSubtitle()|nl2br|raw }}</p>
<div class="contents selectable">
{% for item in entry.get_content() %}
{% set record = item.get_record() %}
{% set prefix = 'PUBLI_' ~ item.get_id() %}
{{record_format.block(record, false, null, prefix, entry.get_id())}}
{% for item in entry.getItems() %}
{% set record = item.getRecord() %}
{% set prefix = 'PUBLI_' ~ item.getId() %}
{{record_format.block(record, false, null, prefix, entry.getId())}}
{% endfor %}
</div>
</div>
{% endmacro %}
{% endmacro %}

View File

@@ -6,23 +6,22 @@
<tr>
<td style="width:600px;">
<h1>
<img src="{{feed.get_icon_url()}}" style="height:32px;"/>
{% if feed.is_aggregated %}
<img src="{{feed.getIconUrl()}}" style="height:32px;"/>
{% if feed.isAggregated %}
{% trans 'Toutes les publications' %}
<a class="feed_reload ajax_answers no_scroll" href="{{ path('prod_feeds') }}" >
<img src="/skins/icons/reload.png" title="{% trans 'rafraichir' %}" />
</a>
{% else %}
{{ feed.get_title() }}
<a class="feed_reload ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : feed.get_id() }) }}" >
{{ feed.getTitle() }}
<a class="feed_reload ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : feed.getId() }) }}" >
<img src="/skins/icons/reload.png" title="{% trans 'rafraichir' %}" />
</a>
{% endif %}
{% if feed.is_aggregated %}
{% if feed.isAggregated %}
<a class="subscribe_rss" href="{{ path('prod_feeds_subscribe_aggregated') }}">{% trans 'publications:: s\'abonner aux publications' %}</a>
{% else %}
<a class="subscribe_rss" href="{{ path('prod_feeds_subscribe_feed', { 'id' : feed.get_id() }) }}">{% trans 'publications:: s\'abonner aux publications' %}</a>
<a class="subscribe_rss" href="{{ path('prod_feeds_subscribe_feed', { 'id' : feed.getId() }) }}">{% trans 'publications:: s\'abonner aux publications' %}</a>
{% endif %}
</h1>
</td>
@@ -34,10 +33,10 @@
<span class="caret"></span>
</button>
<ul class="submenu dropdown-menu">
{% for aval_feed in feeds.get_feeds() %}
{% for aval_feed in feeds %}
<li>
<a class="ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : aval_feed.get_id() }) }}">
<img src="{{aval_feed.get_icon_url()}}" style="height:16px;"/> {{ aval_feed.get_title() }}
<a class="ajax_answers" href="{{ path('prod_feeds_feed', { 'id' : aval_feed.getId() }) }}">
<img src="{{aval_feed.getIconUrl()}}" style="height:16px;"/> {{ aval_feed.getTitle() }}
</a>
</li>
{% endfor %}
@@ -51,7 +50,7 @@
{% endif %}
{% set offset_start = ((page - 1) * 5 )%}
{% set entries = feed.get_entries(offset_start,5).get_entries() %}
{% set entries = feed.getEntries(offset_start,5) %}
{% for entry in entries %}
{{ _entry.format(feed, entry) }}
@@ -60,18 +59,18 @@
<p>{% trans 'Aucune entree pour le moment' %}</p>
{% endif %}
{% if feed.get_count_total_entries() > (page*5) %}
{% if feed.getCountTotalEntries() > (page*5) %}
{% set next_page = page + 1 %}
<div class="see_more">
{% if feed.is_aggregated() %}
{% if feed.isAggregated() %}
<a href="{{ path('prod_feeds', { page : next_page }) }}" class="ajax_answers append">
{% trans 'charger d\'avantage de publications' %}
</a>
{% else %}
<a href="{{ path('prod_feeds_feed', { 'id' : feed.get_id(), 'page' : next_page }) }}" class="ajax_answers append">
<a href="{{ path('prod_feeds_feed', { 'id' : feed.getId(), 'page' : next_page }) }}" class="ajax_answers append">
{% trans 'charger d\'avantage de publications' %}
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>

View File

@@ -52,11 +52,11 @@
{% endblock %}
{% block rss %}
{% for feed in feeds %}
{% set link = feed.get_user_link(app['phraseanet.registry'], app['authentication'].getUser(), 'rss') %}
<link rel="alternate" type="{{ link.get_mimetype() }}" title="{{ link.get_title() }}" href="{{ link.get_href() }}" />
{% set link = feed.get_user_link(app['phraseanet.registry'], app['authentication'].getUser(), 'atom') %}
<link rel="alternate" type="{{ link.get_mimetype() }}" title="{{ link.get_title() }}" href="{{ link.get_href() }}" />
{% for feed in aggregate.getFeeds() %}
{% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %}
<link rel="alternate" type="{{ link.getMimetype() }}" title="{{ link.getTitle() }}" href="{{ link.getURI() }}" />
{% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %}
<link rel="alternate" type="{{ link.getMimetype() }}" title="{{ link.getTitle() }}" href="{{ link.getURI() }}" />
{% endfor %}
{% endblock %}

View File

@@ -3,9 +3,12 @@
namespace Alchemy\Tests\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\AggregateLinkGenerator;
use Alchemy\Phrasea\Feed\LinkGenerator;
use Symfony\Component\CssSelector\CssSelector;
class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
class ControllerFeedTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
/**
*
@@ -42,33 +45,28 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
parent::setUp();
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));
$this->feed = \Feed_Adapter::create(
self::$DI['app'], self::$DI['user'], $this->feed_title, $this->feed_subtitle
);
$this->publisher = \Feed_Publisher_Adapter::getPublisher(
self::$DI['app']['phraseanet.appbox'], $this->feed, self::$DI['user']
);
$this->entry = \Feed_Entry_Adapter::create(
self::$DI['app']
, $this->feed
, $this->publisher
, $this->entry_title
, $this->entry_subtitle
, $this->entry_authorname
, $this->entry_authormail
);
$this->item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $this->entry, self::$DI['record_1']);
// $this->publisher = new \Entities\FeedPublisher(self::$DI['user']);
//
// $this->feed = new \Entities\Feed($this->publisher, $this->feed_title, $this->feed_subtitle);
//
// $this->entry = new \Entities\FeedEntry(
// $this->feed
// , $this->publisher
// , $this->entry_title
// , $this->entry_subtitle
// , $this->entry_authorname
// , $this->entry_authormail
// );
//
// $this->item = new \Entities\FeedItem($this->entry, self::$DI['record_1']);
//
// $this->publisher->setFeed($this->feed);
//
// self::$DI['app']["EM"]->persist($this->feed);
// self::$DI['app']["EM"]->persist($this->publisher);
// self::$DI['app']["EM"]->persist($this->entry);
// self::$DI['app']["EM"]->persist($this->item);
// self::$DI['app']["EM"]->flush();
}
public static function setUpBeforeClass()
@@ -84,34 +82,46 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function tearDown()
{
if ($this->feed instanceof \Feed_Adapter) {
$this->feed->delete();
} elseif ($this->entry instanceof \Feed_Entry_Adapter) {
$this->entry->delete();
if ($this->publisher instanceof \Feed_Publisher_Adapter) {
$this->publisher->delete();
}
}
// if ($this->feed instanceof \Entities\Feed) {
// self::$DI['app']["EM"]->remove($this->feed);
// } else if ($this->entry instanceof \Entities\FeedEntry) {
// self::$DI['app']["EM"]->remove($this->entry);
// if ($this->publisher instanceof \Entities\FeedPublisher) {
// self::$DI['app']["EM"]->remove($this->publisher);
// }
// }
// self::$DI['app']["EM"]->flush();
parent::tearDown();
}
public function testRequestAvailable()
{
$feed = $this->insertOneFeed(self::$DI['user']);
$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']);
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());
$feeds = self::$DI['app']["EM"]->getRepository("\Entities\Feed")->getAllForUser(self::$DI['user']);
foreach ($feeds as $one_feed) {
if ($one_feed->isPublisher(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $one_feed->getId() . "']")->count());
}
}
}
public function testEntryCreate()
{
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));
$feed = $this->insertOneFeed(self::$DI['user']);
$params = array(
"feed_id" => $this->feed->get_id()
"feed_id" => $feed->getId()
, "title" => "salut"
, "subtitle" => "coucou"
, "author_name" => "robert"
@@ -149,49 +159,36 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testEntryEdit()
{
$crawler = self::$DI['client']->request('GET', '/prod/feeds/entry/' . $this->entry->get_id() . '/edit/');
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$crawler = self::$DI['client']->request('GET', '/prod/feeds/entry/' . $entry->getId() . '/edit/');
$pageContent = self::$DI['client']->getResponse()->getContent();
foreach ($this->entry->get_content() as $content) {
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $content->get_id() . "' and @name='item_id']")->count());
foreach ($entry->getItems() as $content) {
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $content->getId() . "' and @name='item_id']")->count());
}
$this->assertEquals(1, $crawler->filterXPath("//form[@action='/prod/feeds/entry/" . $this->entry->get_id() . "/update/']")->count());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $this->entry_title . "']")->count());
$this->assertEquals($this->entry_subtitle, $crawler->filterXPath("//textarea[@id='feed_add_subtitle']")->text());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $this->entry_authorname . "']")->count());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $this->entry_authormail . "']")->count());
$this->assertEquals(1, $crawler->filterXPath("//form[@action='/prod/feeds/entry/" . $entry->getId() . "/update/']")->count());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $entry->getTitle() . "']")->count());
$this->assertEquals($entry->getSubtitle(), $crawler->filterXPath("//textarea[@id='feed_add_subtitle']")->text());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $entry->getAuthorName() . "']")->count());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='" . $entry->getAuthorEmail() . "']")->count());
}
public function testEntryEditUnauthorized()
{
$feed = \Feed_Adapter::create(
self::$DI['app'], self::$DI['user_alt1'], $this->feed_title, $this->feed_subtitle
);
$entry = $this->insertOneFeedEntry(self::$DI['user_alt1']);
$publisher = \Feed_Publisher_Adapter::getPublisher(
self::$DI['app']['phraseanet.appbox'], $feed, self::$DI['user_alt1']
);
try {
$crawler = self::$DI['client']->request('GET', '/prod/feeds/entry/' . $entry->getId() . '/edit/');
$this->fail('Should raise an exception');
} catch (\Exception_UnauthorizedAction $e) {
$entry = \Feed_Entry_Adapter::create(
self::$DI['app']
, $feed
, $publisher
, $this->entry_title
, $this->entry_subtitle
, $this->entry_authorname
, $this->entry_authormail
);
self::$DI['client']->request('GET', '/prod/feeds/entry/' . $entry->get_id() . '/edit/');
$this->assertEquals(403, self::$DI['client']->getResponse()->getStatusCode());
$feed->delete();
}
}
public function testEntryUpdate()
{
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$params = array(
"title" => "dog",
@@ -201,7 +198,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
'lst' => self::$DI['record_1']->get_serialize_key(),
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
@@ -209,25 +206,23 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertFalse($pageContent->error);
$this->assertTrue(is_string($pageContent->message));
$this->assertTrue(is_string($pageContent->datas));
$this->assertRegExp("/entry_" . $this->entry->get_id() . "/", $pageContent->datas);
$this->assertRegExp("/entry_" . $entry->getId() . "/", $pageContent->datas);
}
public function testEntryUpdateChangeFeed()
{
$newfeed = \Feed_Adapter::create(
self::$DI['app'], self::$DI['user'], $this->feed_title, $this->feed_subtitle
);
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$newfeed = $this->insertOneFeed(self::$DI['user'], "test2");
$params = array(
"feed_id" => $newfeed->get_id(),
"feed_id" => $newfeed->getId(),
"title" => "dog",
"subtitle" => "cat",
"author_name" => "bird",
"author_email" => "mouse",
'lst' => self::$DI['record_1']->get_serialize_key(),
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
@@ -235,23 +230,22 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertFalse($pageContent->error);
$this->assertTrue(is_string($pageContent->message));
$this->assertTrue(is_string($pageContent->datas));
$this->assertRegExp("/entry_" . $this->entry->get_id() . "/", $pageContent->datas);
$this->assertRegExp("/entry_" . $entry->getId() . "/", $pageContent->datas);
$retrievedentry = \Feed_Entry_Adapter::load_from_id(self::$DI['app'], $this->entry->get_id());
$this->assertEquals($newfeed->get_id(), $retrievedentry->get_feed()->get_id());
$newfeed->delete();
$retrievedentry = self::$DI['app']["EM"]->getRepository("\Entities\FeedEntry")->find($entry->getId());
$this->assertEquals($newfeed->getId(), $retrievedentry->getFeed()->getId());
}
public function testEntryUpdateChangeFeedNoAccess()
{
$newfeed = \Feed_Adapter::create(
self::$DI['app'], self::$DI['user'], $this->feed_title, $this->feed_subtitle
);
$newfeed->set_collection(self::$DI['collection_no_access']);
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$newfeed = $this->insertOneFeed(self::$DI['user'], "test2");
$newfeed->setCollection(self::$DI['collection_no_access']);
self::$DI['app']["EM"]->persist($newfeed);
self::$DI['app']["EM"]->flush();
$params = array(
"feed_id" => $newfeed->get_id(),
"feed_id" => $newfeed->getId(),
"title" => "dog",
"subtitle" => "cat",
"author_name" => "bird",
@@ -259,19 +253,19 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
'lst' => self::$DI['record_1']->get_serialize_key(),
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
$this->assertTrue(is_object($pageContent));
$this->assertTrue($pageContent->error);
$this->assertTrue(is_string($pageContent->message));
$newfeed->delete();
}
public function testEntryUpdateChangeFeedInvalidFeed()
{
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$params = array(
"feed_id" => 0,
"title" => "dog",
@@ -281,7 +275,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
'lst' => self::$DI['record_1']->get_serialize_key(),
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
@@ -317,6 +311,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testEntryUpdateFailed()
{
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$params = array(
"feed_id" => 9999999
@@ -327,7 +322,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
, 'sorted_lst' => self::$DI['record_1']->get_serialize_key() . ";" . self::$DI['record_2']->get_serialize_key() . ";12345;" . "unknow_unknow"
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$response = self::$DI['client']->getResponse();
@@ -345,13 +340,11 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
/**
* I CREATE A FEED THAT IS NOT MINE
* */
$feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user_alt1'], "salut", 'coucou');
$publisher = \Feed_Publisher_Adapter::getPublisher(self::$DI['app']['phraseanet.appbox'], $feed, self::$DI['user_alt1']);
$entry = \Feed_Entry_Adapter::create(self::$DI['app'], $feed, $publisher, "hello", "coucou", "salut", "bonjour@phraseanet.com");
$item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']);
$entry = $this->insertOneFeedEntry(self::$DI['user_alt1']);
$params = array(
"feed_id" => $feed->get_id()
"feed_id" => $entry->getFeed()->getId()
, "title" => "dog"
, "subtitle" => "cat"
, "author_name" => "bird"
@@ -359,7 +352,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
, 'lst' => self::$DI['record_1']->get_serialize_key()
);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->get_id() . '/update/', $params);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/update/', $params);
$response = self::$DI['client']->getResponse();
@@ -370,14 +363,13 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue(is_object($pageContent));
$this->assertTrue($pageContent->error);
$this->assertTrue(is_string($pageContent->message));
$feed->delete();
}
public function testDelete()
{
$entry = $this->insertOneFeedEntry(self::$DI['user']);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $this->entry->get_id() . '/delete/');
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/delete/');
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
@@ -389,7 +381,7 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue(is_string($pageContent->message));
try {
\Feed_Entry_Adapter::load_from_id(self::$DI['app'], $this->entry->get_id());
self::$DI["app"]["EM"]->getRepository("\Entities\FeedEntry")->find($entry->getId());
$this->fail("Failed to delete entry");
} catch (\Exception $e) {
@@ -417,13 +409,9 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
/**
* I CREATE A FEED
* */
$feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user_alt1'], "salut", 'coucou');
$entry = $this->insertOneFeedEntry(self::$DI['user_alt1']);
$publisher = \Feed_Publisher_Adapter::getPublisher(self::$DI['app']['phraseanet.appbox'], $feed, self::$DI['user_alt1']);
$entry = \Feed_Entry_Adapter::create(self::$DI['app'], $feed, $publisher, "hello", "coucou", "salut", "bonjour@phraseanet.com");
$item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']);
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->get_id() . '/delete/');
$crawler = self::$DI['client']->request('POST', '/prod/feeds/entry/' . $entry->getId() . '/delete/');
$response = self::$DI['client']->getResponse();
@@ -434,8 +422,6 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue(is_object($pageContent));
$this->assertTrue($pageContent->error);
$this->assertTrue(is_string($pageContent->message));
$feed->delete();
}
public function testRoot()
@@ -447,12 +433,12 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
$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 $one_feed) {
foreach ($feeds as $one_feed) {
$path = CssSelector::toXPath("ul.submenu a[href='/prod/feeds/feed/" . $one_feed->get_id() . "/']");
$msg = sprintf("user %s has access to feed %s", self::$DI['user']->get_id(), $one_feed->get_id());
$path = CssSelector::toXPath("ul.submenu a[href='/prod/feeds/feed/" . $one_feed->getId() . "/']");
$msg = sprintf("user %s has access to feed %s", self::$DI['user']->getId(), $one_feed->getId());
if ($one_feed->has_access(self::$DI['user'])) {
$this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg);
@@ -465,16 +451,18 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testGetFeed()
{
$feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']);
$feed = $this->insertOneFeed(self::$DI['user']);
$crawler = self::$DI['client']->request('GET', '/prod/feeds/feed/' . $this->feed->get_id() . "/");
$feeds = self::$DI['app']["EM"]->getRepository("\Entities\Feed")->getAllForUser(self::$DI['user']);
$crawler = self::$DI['client']->request('GET', '/prod/feeds/feed/' . $feed->getId() . "/");
$pageContent = self::$DI['client']->getResponse()->getContent();
foreach ($feeds->get_feeds() as $one_feed) {
$path = CssSelector::toXPath("ul.submenu a[href='/prod/feeds/feed/" . $one_feed->get_id() . "/']");
$msg = sprintf("user %s has access to feed %s", self::$DI['user']->get_id(), $one_feed->get_id());
foreach ($feeds as $one_feed) {
$path = CssSelector::toXPath("ul.submenu a[href='/prod/feeds/feed/" . $one_feed->getId() . "/']");
$msg = sprintf("user %s has access to feed %s", self::$DI['user']->get_id(), $one_feed->getId());
if ($one_feed->has_access(self::$DI['user'])) {
if ($one_feed->hasAccess(self::$DI['user'], self::$DI['app'])) {
$this->assertEquals(1, $crawler->filterXPath($path)->count(), $msg);
} else {
$this->fail('Feed_collection::load_all should return feed where I got access');
@@ -484,26 +472,48 @@ class ControllerFeedApp extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testSuscribeAggregate()
{
$feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']);
$feed = $this->insertOneFeed(self::$DI['user']);
$generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator')
->disableOriginalConstructor()
->getMock();
$random = self::$DI['app']['tokens'];
$aggregateGenerator = new AggregateLinkGenerator($generator, self::$DI['app']['EM'], $random);
$feeds = self::$DI['app']["EM"]->getRepository("\Entities\Feed")->getAllForUser(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"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
$this->assertTrue(is_object($pageContent));
$this->assertTrue(is_string($pageContent->texte));
$suscribe_link = $feeds->get_aggregate()->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_RSS, null, false)->get_href();
$this->assertContains($suscribe_link, $pageContent->texte);
$aggregate = new Aggregate(self::$DI['app'], $feeds);
$suscribe_link = $aggregateGenerator->generate($aggregate, self::$DI['user'], AggregateLinkGenerator::FORMAT_RSS);
$this->assertContains($suscribe_link->getURI(), $pageContent->texte);
}
public function testSuscribe()
{
$crawler = self::$DI['client']->request('GET', '/prod/feeds/subscribe/' . $this->feed->get_id() . '/');
$feed = $this->insertOneFeed(self::$DI['user']);
$generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator')
->disableOriginalConstructor()
->getMock();
$random = self::$DI['app']['tokens'];
$linkGenerator = new LinkGenerator($generator, self::$DI['app']['EM'], $random);
$crawler = self::$DI['client']->request('GET', '/prod/feeds/subscribe/' . $feed->getId() . '/');
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->assertEquals("application/json", self::$DI['client']->getResponse()->headers->get("content-type"));
$pageContent = json_decode(self::$DI['client']->getResponse()->getContent());
$this->assertTrue(is_object($pageContent));
$this->assertTrue(is_string($pageContent->texte));
$suscribe_link = $this->feed->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_RSS, null, false)->get_href();
$this->assertContains($suscribe_link, $pageContent->texte);
$suscribe_link = $linkGenerator->generate($feed, self::$DI['user'], LinkGenerator::FORMAT_RSS);
var_dump($suscribe_link);
$this->assertContains($suscribe_link->getURI(), $pageContent->texte);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Provider;
/**
* @covers Alchemy\Phrasea\Core\Provider\GeonamesServiceProvider
*/
class GeonamesServiceProvidertest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return array(
array(
'Alchemy\Phrasea\Core\Provider\FeedServiceProvider',
'feed.user-link-generator',
'Alchemy\Phrasea\Feed\LinkGenerator'
),
array(
'Alchemy\Phrasea\Core\Provider\FeedServiceProvider',
'feed.aggregate-link-generator',
'Alchemy\Phrasea\Feed\AggregateLinkGenerator'
),
);
}
}

View File

@@ -0,0 +1,129 @@
<?php
namespace Alchemy\Tests\Phrasea\Feed;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\AggregateLinkGenerator;
use Entities\Feed;
use Symfony\Component\Routing\Generator\UrlGenerator;
class AggregateLinkGeneratorTest extends \PhraseanetPHPUnitAbstract
{
/**
* @dataProvider provideGenerationData
*/
public function testGenerate($expected, $format, $user, $page, $renew, $alreadyCreated)
{
$feed = new Feed();
$feed->setTitle("title");
$another_feed = new Feed($user);
$another_feed->setTitle("another_title");
$feeds = array($feed, $another_feed);
$aggregate = new Aggregate(self::$DI['app'], $feeds);
$generator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGenerator')
->disableOriginalConstructor()
->getMock();
if ($alreadyCreated) {
$token = $this->insertOneAggregateToken($user);
$tokenValue = $token->getValue();
}
$capture = null;
$generator->expects($this->once())
->method('generate')
->with('feed_user_aggregated', $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 AggregateLinkGenerator($generator, self::$DI['app']['EM'], $random);
$link = $linkGenerator->generate($aggregate, $user, $format, $page, $renew);
$this->assertSame($expected, $link->getUri());
if ($format == "atom") {
$this->assertSame("application/atom+xml", $link->getMimetype());
$this->assertSame("AGGREGATE - Atom", $link->getTitle());
}
elseif ($format == "rss") {
$this->assertSame("application/rss+xml", $link->getMimetype());
$this->assertSame("AGGREGATE - RSS", $link->getTitle());
}
if ($alreadyCreated) {
if ($renew) {
$this->assertCount(2, $capture);
$this->assertEquals($format, $capture['format']);
$this->assertNotEquals($tokenValue, $capture['token']);
$this->assertCount(0, self::$DI['app']['EM']
->getRepository("Entities\AggregateToken")
->findBy(array('value' => $tokenValue)));
$this->assertCount(1, self::$DI['app']['EM']
->getRepository("Entities\AggregateToken")
->findBy(array('value' => $capture['token'])));
} else {
$this->assertEquals(array(
'token' => $tokenValue,
'format' => $format,
), $capture);
$this->assertCount(1, self::$DI['app']['EM']
->getRepository("Entities\AggregateToken")
->findBy(array('value' => $tokenValue)));
}
} else {
$this->assertCount(2, $capture);
$this->assertEquals($format, $capture['format']);
$this->assertEquals(12, strlen($capture['token']));
$this->assertCount(1, self::$DI['app']['EM']
->getRepository("Entities\AggregateToken")
->findBy(array('value' => $capture['token'])));
}
$token = self::$DI['app']['EM']
->getRepository('Entities\AggregateToken')
->findByUser($user);
self::$DI['app']['EM']->remove($token);
self::$DI['app']['EM']->flush();
}
public function provideGenerationData()
{
$user = $this->getMockBuilder('User_Adapter')
->disableOriginalConstructor()
->getMock();
$user->expects($this->any())
->method('get_id')
->will($this->returnValue(42));
return array(
array('doliprane', 'atom', $user, null, false, false),
array('doliprane', 'atom', $user, null, false, true),
array('doliprane', 'atom', $user, null, true, false),
array('doliprane', 'atom', $user, null, true, true),
array('doliprane', 'atom', $user, 1, false, false),
array('doliprane', 'atom', $user, 1, false, true),
array('doliprane', 'atom', $user, 1, true, false),
array('doliprane', 'atom', $user, 1, true, true),
array('doliprane', 'rss', $user, null, false, false),
array('doliprane', 'rss', $user, null, false, true),
array('doliprane', 'rss', $user, null, true, false),
array('doliprane', 'rss', $user, null, true, true),
array('doliprane', 'rss', $user, 1, false, false),
array('doliprane', 'rss', $user, 1, false, true),
array('doliprane', 'rss', $user, 1, true, false),
array('doliprane', 'rss', $user, 1, true, true),
);
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace Alchemy\Tests\Phrasea\Feed;
use Alchemy\Phrasea\Feed\LinkGenerator;
use Symfony\Component\Routing\Generator\UrlGenerator;
class LinkGeneratorTest extends \PhraseanetPHPUnitAbstract
{
/**
* @dataProvider provideGenerationData
*/
public function testGenerate($expected, $format, $feed, $user, $page, $renew, $alreadyCreated)
{
self::$DI['app']['EM']->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 LinkGenerator($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->assertCount(3, $capture);
$this->assertEquals($feed->getId(), $capture['id']);
$this->assertEquals($format, $capture['format']);
$this->assertNotEquals($tokenValue, $capture['token']);
$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 {
$this->assertEquals(array(
'token' => $tokenValue,
'id' => $feed->getId(),
'format' => $format,
), $capture);
$this->assertCount(1, self::$DI['app']['EM']
->getRepository("Entities\FeedToken")
->findBy(array('value' => $tokenValue)));
}
} else {
$this->assertCount(3, $capture);
$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();
}
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),
);
}
}

View File

@@ -4,6 +4,9 @@ use Alchemy\Phrasea\CLI;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border\File;
use Doctrine\Common\DataFixtures\Loader;
use Entities\AggregateToken;
use Entities\Feed;
use Entities\FeedToken;
use Entities\User;
use Silex\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
@@ -323,6 +326,129 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
}
}
/**
* Insert one feed
*
* @return \Entities\Feed
*/
protected function insertOneFeed(\User_Adapter $user, $title = null)
{
try {
$feedFixture = new PhraseaFixture\Feed\LoadOneFeed();
$feedFixture->setUser($user);
if ($title !== null) {
$feedFixture->setTitle($title);
}
$loader = new Loader();
$loader->addFixture($feedFixture);
$this->insertFixtureInDatabase($loader);
return $feedFixture->feed;
} catch (\Exception $e) {
$this->fail('Fail to load one Feed : ' . $e->getMessage());
}
}
/**
*
* @return \Entities\FeedEntry
*/
protected function insertOneFeedEntry(\User_Adapter $user)
{
try {
$feed = $this->insertOneFeed($user);
$em = self::$DI['app']['EM'];
$entry = new \Entities\FeedEntry();
$entry->setFeed($feed);
$entry->setTitle("test");
$entry->setSubtitle("description");
$entry->setAuthorName('user');
$entry->setAuthorEmail('user@email.com');
$publisher = $feed->getPublisher($user);
if ($publisher !== null) {
$entry->setPublisher($publisher);
}
$feed->addEntry($entry);
$em->persist($entry);
$em->persist($feed);
$em->flush();
return $entry;
} catch (\Exception $e) {
$this->fail('Fail to load one FeedEntry : ' . $e->getMessage());
}
}
protected function insertOneFeedToken(Feed $feed, \User_Adapter $user)
{
try {
$token = new FeedToken();
$token->setValue(self::$DI['app']['tokens']->generatePassword(12));
$token->setFeed($feed);
$token->setUsrId($user->get_id());
self::$DI['app']['EM']->persist($token);
self::$DI['app']['EM']->flush();
} catch (\Exception $e) {
$this->fail('Fail to load one FeedToken : ' . $e->getMessage());
}
return $token;
}
protected function insertOneAggregateToken(\User_Adapter $user)
{
try {
$token = new AggregateToken();
$token->setValue(self::$DI['app']['tokens']->generatePassword(12));
$token->setUsrId($user->get_id());
self::$DI['app']['EM']->persist($token);
self::$DI['app']['EM']->flush();
} catch (\Exception $e) {
$this->fail('Fail to load one AggregateToken : ' . $e->getMessage());
}
return $token;
}
/**
*
* @return \Entities\FeedEntry
*/
protected function insertOneFeedItem(\User_Adapter $user)
{
try {
$entry = $this->insertOneFeedEntry($user);
$item = new \Entities\FeedItem();
$item->setEntry($entry);
$entry->addItem($item);
$em = self::$DI['app']['EM'];
$em->persist($entry);
$em->persist($item);
$em->flush();
return $entry;
} catch (\Exception $e) {
$this->fail('Fail to load one FeedEntry : ' . $e->getMessage());
}
}
/**
* Insert one basket entry ans set current authenticated user as owner
*