From b7f4f209fc7bc7ce775b7ff1baadc9cc57a7bb78 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 7 May 2013 15:44:28 +0200 Subject: [PATCH 01/67] Implement Doctrine feeds instead of Phrasea ones in the /list/ route --- .../Phrasea/Controller/Admin/Publications.php | 4 +- lib/Doctrine/Entities/Feed.php | 333 ++++++++++++++++++ .../Repositories/SessionRepository.php | 28 ++ .../web/admin/publications/list.html.twig | 22 +- 4 files changed, 374 insertions(+), 13 deletions(-) create mode 100644 lib/Doctrine/Entities/Feed.php diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index 5ad1cfdead..9acec00f3d 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -36,8 +36,8 @@ class Publications implements ControllerProviderInterface $controllers->get('/list/', function(PhraseaApplication $app) { - $feeds = \Feed_Collection::load_all( - $app, $app['authentication']->getUser() + $feeds = $app["EM"]->getRepository("Entities\Feed")->getAllForUser( + $app['authentication']->getUser() ); return $app['twig'] diff --git a/lib/Doctrine/Entities/Feed.php b/lib/Doctrine/Entities/Feed.php new file mode 100644 index 0000000000..4caf597836 --- /dev/null +++ b/lib/Doctrine/Entities/Feed.php @@ -0,0 +1,333 @@ +publishers = new \Doctrine\Common\Collections\ArrayCollection(); + $this->entries = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set public + * + * @param boolean $public + * @return Feed + */ + public function setPublic($public) + { + $this->public = $public; + + return $this; + } + + /** + * Get public + * + * @return boolean + */ + public function getPublic() + { + return $this->public; + } + + /** + * Set icon_url + * + * @param string $iconUrl + * @return Feed + */ + public function setIconUrl($iconUrl) + { + $this->icon_url = $iconUrl; + + return $this; + } + + /** + * Get icon_url + * + * @return string + */ + public function getIconUrl() + { + return $this->icon_url; + } + + /** + * Set base_id + * + * @param integer $baseId + * @return Feed + */ + public function setBaseId($baseId) + { + $this->base_id = $baseId; + + return $this; + } + + /** + * Get base_id + * + * @return integer + */ + public function getBaseId() + { + return $this->base_id; + } + + /** + * Set title + * + * @param string $title + * @return Feed + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set description + * + * @param string $description + * @return Feed + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * Get description + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set created + * + * @param \DateTime $created + * @return Feed + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * @return Feed + */ + public function setUpdated($updated) + { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Add publishers + * + * @param \Entities\FeedPublisher $publishers + * @return Feed + */ + public function addPublisher(\Entities\FeedPublisher $publishers) + { + $this->publishers[] = $publishers; + + return $this; + } + + /** + * Remove publishers + * + * @param \Entities\FeedPublisher $publishers + */ + public function removePublisher(\Entities\FeedPublisher $publishers) + { + $this->publishers->removeElement($publishers); + } + + /** + * Get publishers + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getPublishers() + { + return $this->publishers; + } + + /** + * Add entries + * + * @param \Entities\FeedEntry $entries + * @return Feed + */ + public function addEntrie(\Entities\FeedEntry $entries) + { + $this->entries[] = $entries; + + return $this; + } + + /** + * Remove entries + * + * @param \Entities\FeedEntry $entries + */ + public function removeEntrie(\Entities\FeedEntry $entries) + { + $this->entries->removeElement($entries); + } + + /** + * Get entries + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getEntries() + { + return $this->entries; + } + + public function getOwner() + { + foreach ($this->getPublishers() as $publisher) { + if ($publisher->isOwner()) { + return $publisher; + } + } + } + + public function isOwner(\User_Adapter $user) + { + $owner = $this->getOwner(); + if ($owner !== null && $user->get_id() === $owner->getId()) { + return true; + } + + return false; + } + + public function getCollection(Application $app) + { + if ($this->getBaseId() !== null) + return \collection::get_from_base_id($app, $this->getBaseId()); + } +} \ No newline at end of file diff --git a/lib/Doctrine/Repositories/SessionRepository.php b/lib/Doctrine/Repositories/SessionRepository.php index 747d99d7f3..b78db0574a 100644 --- a/lib/Doctrine/Repositories/SessionRepository.php +++ b/lib/Doctrine/Repositories/SessionRepository.php @@ -2,6 +2,7 @@ namespace Repositories; +use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityRepository; /** @@ -12,4 +13,31 @@ use Doctrine\ORM\EntityRepository; */ class SessionRepository extends EntityRepository { + + /** + * + * @param Application $app + * @param User_Adapter $user + * @return \Doctrine\Common\Collections\Collection + */ + public function getAllForUser(\User_Adapter $user) + { + $base_ids = array_keys($user->ACL()->get_granted_base()); + + + $dql = 'SELECT f FROM Entities\Feed f + WHERE f.base_id IS NULL '; + + if (count($base_ids) > 0) { + $dql .= ' OR f.base_id + IN (' . implode(', ', $base_ids) . ') '; + } + + $dql .= ' OR f.public = true + ORDER BY f.created DESC'; + + $query = $this->_em->createQuery($dql); + $feeds = $query->getResult(); + return $feeds; + } } diff --git a/templates/web/admin/publications/list.html.twig b/templates/web/admin/publications/list.html.twig index 875c289cb1..19c89f0b6d 100644 --- a/templates/web/admin/publications/list.html.twig +++ b/templates/web/admin/publications/list.html.twig @@ -59,35 +59,35 @@ - {% for feed in feeds.get_feeds %} + {% for feed in feeds %}
- - + +
- {{ feed.get_title() }} + {{ feed.getTitle() }} - {{ app['date-formatter'].getDate(feed.get_created_on()) }} + {{ app['date-formatter'].getDate(feed.getCreated()) }} - {% if feed.get_collection() != null %} - {{ feed.get_collection().get_databox().get_label(app['locale.I18n']) }} / - {{ feed.get_collection().get_name() }} + {% if feed.getCollection() != null %} + {{ feed.getCollection().get_databox().get_label(app['locale.I18n']) }} / + {{ feed.getCollection().get_name() }} {% endif %} - {% if feed.is_public() %} + {% if feed.getPublic() %} {% endif %} - {% if feed.is_owner(app['authentication'].getUser()) %} -
+ {% if feed.isOwner(app['authentication'].getUser()) %} +
{% endif %} From 9c49589d9c1e87026801e25af2804f07ccb7c069 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 14 May 2013 16:28:08 +0200 Subject: [PATCH 02/67] Implement admin controllers --- .../Phrasea/Controller/Admin/Publications.php | 80 +++-- lib/Doctrine/Entities/Feed.php | 206 +++++++----- lib/Doctrine/Entities/FeedEntry.php | 306 ++++++++++++++++++ lib/Doctrine/Entities/FeedItem.php | 198 ++++++++++++ lib/Doctrine/Entities/FeedPublisher.php | 147 +++++++++ .../Repositories/OrderElementRepository.php | 11 + .../Repositories/SessionRepository.php | 18 +- .../web/admin/publications/fiche.html.twig | 34 +- .../web/admin/publications/list.html.twig | 2 +- 9 files changed, 873 insertions(+), 129 deletions(-) create mode 100644 lib/Doctrine/Entities/FeedEntry.php create mode 100644 lib/Doctrine/Entities/FeedItem.php create mode 100644 lib/Doctrine/Entities/FeedPublisher.php diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index 9acec00f3d..b0d8bec98e 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application as PhraseaApplication; +use Repositories; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; @@ -46,21 +47,28 @@ class Publications implements ControllerProviderInterface $controllers->post('/create/', function(PhraseaApplication $app, Request $request) { - $feed = \Feed_Adapter::create( - $app, $app['authentication']->getUser(), $request->request->get('title'), $request->request->get('subtitle') - ); + $publisher = new \Entities\FeedPublisher($app['authentication']->getUser(), true); + + $feed = new \Entities\Feed($publisher, $request->request->get('title'), $request->request->get('subtitle')); if ($request->request->get('public') == '1') { - $feed->set_public(true); + $feed->setPublic(true); } elseif ($request->request->get('base_id')) { - $feed->set_collection(\collection::get_from_base_id($app, $request->request->get('base_id'))); + $feed->setCollection(\collection::get_from_base_id($app, $request->request->get('base_id'))); } + $publisher->setFeed($feed); + + $app["EM"]->persist($feed); + $app["EM"]->persist($publisher); + + $app["EM"]->flush(); + return $app->redirectPath('admin_feeds_list'); })->bind('admin_feeds_create'); $controllers->get('/feed/{id}/', function(PhraseaApplication $app, Request $request, $id) { - $feed = new \Feed_Adapter($app, $id); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); return $app['twig'] ->render('admin/publications/fiche.html.twig', array('feed' => $feed, 'error' => $app['request']->query->get('error'))); @@ -70,24 +78,26 @@ class Publications implements ControllerProviderInterface $controllers->post('/feed/{id}/update/', function(PhraseaApplication $app, Request $request, $id) { - $feed = new \Feed_Adapter($app, $id); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); try { $collection = \collection::get_from_base_id($app, $request->request->get('base_id')); } catch (\Exception $e) { $collection = null; } + $feed->setTitle($request->request->get('title')); + $feed->setDescription($request->request->get('subtitle')); + $feed->setCollection($collection); + $feed->setPublic($request->request->get('public')); - $feed->set_title($request->request->get('title')); - $feed->set_subtitle($request->request->get('subtitle')); - $feed->set_collection($collection); - $feed->set_public($request->request->get('public')); + $app["EM"]->persist($feed); + $app["EM"]->flush(); return $app->redirectPath('admin_feeds_list'); })->before(function(Request $request) use ($app) { - $feed = new \Feed_Adapter($app, $request->attributes->get('id')); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($request->attributes->get('id')); - if (!$feed->is_owner($app['authentication']->getUser())) { + if (!$feed->getOwner($app['authentication']->getUser())) { return $app->redirectPath('admin_feeds_feed', array('id' => $request->attributes->get('id'), 'error' => _('You are not the owner of this feed, you can not edit it'))); } }) @@ -99,12 +109,11 @@ class Publications implements ControllerProviderInterface 'success' => false, 'message' => '', ); - - $feed = new \Feed_Adapter($app, $id); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); $request = $app["request"]; - if (!$feed->is_owner($app['authentication']->getUser())) { + if (!$feed->getOwner($app['authentication']->getUser())) { $datas['message'] = 'You are not allowed to do that'; return $app->json($datas); @@ -146,7 +155,7 @@ class Publications implements ControllerProviderInterface throw new \Exception_InternalServerError('Error while resizing'); } - $feed->set_icon($tmpname); + //$feed->set_icon($tmpname); unset($media); @@ -167,8 +176,17 @@ class Publications implements ControllerProviderInterface try { $request = $app['request']; $user = \User_Adapter::getInstance($request->request->get('usr_id'), $app); - $feed = new \Feed_Adapter($app, $id); - $feed->add_publisher($user); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + + $publisher = new \Entities\FeedPublisher($user, false); + $publisher->setFeed($feed); + + $feed->addPublisher($publisher); + + $app["EM"]->persist($feed); + $app["EM"]->persist($publisher); + + $app["EM"]->flush(); } catch (\Exception $e) { $error = $e->getMessage(); } @@ -182,11 +200,16 @@ class Publications implements ControllerProviderInterface try { $request = $app['request']; - $feed = new \Feed_Adapter($app, $id); - $publisher = new \Feed_Publisher_Adapter($app, $request->request->get('publisher_id')); - $user = $publisher->get_user(); - if ($feed->is_publisher($user) === true && $feed->is_owner($user) === false) - $publisher->delete(); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + + $publisher = $app["EM"]->getRepository("Entities\FeedPublisher")->find($request->request->get('publisher_id')); + $user = $publisher->getUser($app); + if ($feed->isPublisher($user) === true && $feed->isOwner($user) === false) { + $feed->removePublisher($publisher); + + $app["EM"]->remove($publisher); + $app["EM"]->flush(); + } } catch (\Exception $e) { $error = $e->getMessage(); } @@ -197,8 +220,13 @@ class Publications implements ControllerProviderInterface ->assert('id', '\d+'); $controllers->post('/feed/{id}/delete/', function(PhraseaApplication $app, $id) { - $feed = new \Feed_Adapter($app, $id); - $feed->delete(); + $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); + $publishers = $feed->getPublishers(); + foreach ($publishers as $publisher) { + $app["EM"]->remove($publisher); + } + $app["EM"]->remove($feed); + $app["EM"]->flush(); return $app->redirectPath('admin_feeds_list'); }) diff --git a/lib/Doctrine/Entities/Feed.php b/lib/Doctrine/Entities/Feed.php index 4caf597836..f44aaf0b24 100644 --- a/lib/Doctrine/Entities/Feed.php +++ b/lib/Doctrine/Entities/Feed.php @@ -18,12 +18,12 @@ class Feed /** * @var boolean */ - private $public; + private $public = false; /** * @var string */ - private $icon_url; + private $icon_url = false; /** * @var integer @@ -38,17 +38,17 @@ class Feed /** * @var string */ - private $description; + private $subtitle; /** * @var \DateTime */ - private $created; + private $created_on; /** * @var \DateTime */ - private $updated; + private $updated_on; /** * @var \Doctrine\Common\Collections\Collection @@ -122,7 +122,11 @@ class Feed */ public function getIconUrl() { - return $this->icon_url; + if (!$this->icon_url) { + return '/skins/icons/rss32.gif'; + } + + return '/www/custom/feed_' . $this->getId() . '.jpg'; } /** @@ -171,75 +175,6 @@ class Feed return $this->title; } - /** - * Set description - * - * @param string $description - * @return Feed - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set created - * - * @param \DateTime $created - * @return Feed - */ - public function setCreated($created) - { - $this->created = $created; - - return $this; - } - - /** - * Get created - * - * @return \DateTime - */ - public function getCreated() - { - return $this->created; - } - - /** - * Set updated - * - * @param \DateTime $updated - * @return Feed - */ - public function setUpdated($updated) - { - $this->updated = $updated; - - return $this; - } - - /** - * Get updated - * - * @return \DateTime - */ - public function getUpdated() - { - return $this->updated; - } - /** * Add publishers * @@ -279,7 +214,7 @@ class Feed * @param \Entities\FeedEntry $entries * @return Feed */ - public function addEntrie(\Entities\FeedEntry $entries) + public function addEntry(\Entities\FeedEntry $entries) { $this->entries[] = $entries; @@ -291,7 +226,7 @@ class Feed * * @param \Entities\FeedEntry $entries */ - public function removeEntrie(\Entities\FeedEntry $entries) + public function removeEntry(\Entities\FeedEntry $entries) { $this->entries->removeElement($entries); } @@ -309,7 +244,7 @@ class Feed public function getOwner() { foreach ($this->getPublishers() as $publisher) { - if ($publisher->isOwner()) { + if ($publisher->getOwner()) { return $publisher; } } @@ -318,7 +253,7 @@ class Feed public function isOwner(\User_Adapter $user) { $owner = $this->getOwner(); - if ($owner !== null && $user->get_id() === $owner->getId()) { + if ($owner !== null && $user->get_id() === $owner->getUsrId()) { return true; } @@ -327,7 +262,116 @@ class Feed public function getCollection(Application $app) { - if ($this->getBaseId() !== null) + if ($this->getBaseId() !== null) { return \collection::get_from_base_id($app, $this->getBaseId()); + } } -} \ No newline at end of file + + public function setCollection(\collection $collection = null) + { + if ($collection === null) { + $this->base_id = null; + return; + } + $this->base_id = $collection->get_base_id(); + } + + /** + * Set created_on + * + * @param \DateTime $createdOn + * @return Feed + */ + public function setCreatedOn($createdOn) + { + $this->created_on = $createdOn; + + return $this; + } + + /** + * Get created_on + * + * @return \DateTime + */ + public function getCreatedOn() + { + return $this->created_on; + } + + /** + * Set updated_on + * + * @param \DateTime $updatedOn + * @return Feed + */ + public function setUpdatedOn($updatedOn) + { + $this->updated_on = $updatedOn; + + return $this; + } + + /** + * Get updated_on + * + * @return \DateTime + */ + public function getUpdatedOn() + { + return $this->updated_on; + } + + public function isPublisher(\User_Adapter $user) + { + foreach ($this->getPublishers() as $publisher) { + if ($publisher->getUsrId() == $user->get_id()) { + return true; + } + } + + return false; + } + + /** + * Set subtitle + * + * @param string $subtitle + * @return Feed + */ + public function setSubtitle($subtitle) + { + $this->subtitle = $subtitle; + + return $this; + } + + /** + * Get subtitle + * + * @return string + */ + public function getSubtitle() + { + return $this->subtitle; + } + + public function isAggregated() + { + return false; + } + + public function getCountTotalEntries() + { + return (count($this->entries)); + } + + public function hasAccess(User_Adapter $user) + { + if ($this->get_collection() instanceof collection) { + return $user->ACL()->has_access_to_base($this->collection->get_base_id()); + } + + return true; + } +} diff --git a/lib/Doctrine/Entities/FeedEntry.php b/lib/Doctrine/Entities/FeedEntry.php new file mode 100644 index 0000000000..f5f4e9288f --- /dev/null +++ b/lib/Doctrine/Entities/FeedEntry.php @@ -0,0 +1,306 @@ +items = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set title + * + * @param string $title + * @return FeedEntry + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set subtitle + * + * @param string $subtitle + * @return FeedEntry + */ + public function setSubtitle($subtitle) + { + $this->subtitle = $subtitle; + + return $this; + } + + /** + * Get subtitle + * + * @return string + */ + public function getSubtitle() + { + return $this->subtitle; + } + + /** + * Set author_name + * + * @param string $authorName + * @return FeedEntry + */ + public function setAuthorName($authorName) + { + $this->author_name = $authorName; + + return $this; + } + + /** + * Get author_name + * + * @return string + */ + public function getAuthorName() + { + return $this->author_name; + } + + /** + * Set author_email + * + * @param string $authorEmail + * @return FeedEntry + */ + public function setAuthorEmail($authorEmail) + { + $this->author_email = $authorEmail; + + return $this; + } + + /** + * Get author_email + * + * @return string + */ + public function getAuthorEmail() + { + return $this->author_email; + } + + /** + * Set created + * + * @param \DateTime $created + * @return FeedEntry + */ + public function setCreatedOn($createdOn) + { + $this->created_on = $createdOn; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreatedOn() + { + return $this->createdOn; + } + + /** + * Set updated + * + * @param \DateTime $updated + * @return FeedEntry + */ + public function setUpdatedOn($updatedOn) + { + $this->updated_on = $updatedOn; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdatedOn() + { + return $this->updatedOn; + } + + /** + * Add items + * + * @param \Entities\FeedItem $items + * @return FeedEntry + */ + public function addItem(\Entities\FeedItem $items) + { + $this->items[] = $items; + + return $this; + } + + /** + * Remove items + * + * @param \Entities\FeedItem $items + */ + public function removeItem(\Entities\FeedItem $items) + { + $this->items->removeElement($items); + } + + /** + * Get items + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getItems() + { + return $this->items; + } + + /** + * Set publisher + * + * @param \Entities\FeedPublisher $publisher + * @return FeedEntry + */ + public function setPublisher(\Entities\FeedPublisher $publisher = null) + { + $this->publisher = $publisher; + + return $this; + } + + /** + * Get publisher + * + * @return \Entities\FeedPublisher + */ + public function getPublisher() + { + return $this->publisher; + } + + /** + * Set feed + * + * @param \Entities\Feed $feed + * @return FeedEntry + */ + public function setFeed(\Entities\Feed $feed = null) + { + $this->feed = $feed; + + return $this; + } + + /** + * Get feed + * + * @return \Entities\Feed + */ + public function getFeed() + { + return $this->feed; + } + + public function isPublisher(\User_Adapter $user) + { + if ($this->publisher) { + if ($this->publisher->getUsrId() === $user->get_id()) + return true; + } + + return false; + } +} diff --git a/lib/Doctrine/Entities/FeedItem.php b/lib/Doctrine/Entities/FeedItem.php new file mode 100644 index 0000000000..4d33318551 --- /dev/null +++ b/lib/Doctrine/Entities/FeedItem.php @@ -0,0 +1,198 @@ +id; + } + + /** + * Set record_id + * + * @param integer $recordId + * @return FeedItem + */ + public function setRecordId($recordId) + { + $this->record_id = $recordId; + + return $this; + } + + /** + * Get record_id + * + * @return integer + */ + public function getRecordId() + { + return $this->record_id; + } + + /** + * Set sbas_id + * + * @param integer $sbasId + * @return FeedItem + */ + public function setSbasId($sbasId) + { + $this->sbas_id = $sbasId; + + return $this; + } + + /** + * Get sbas_id + * + * @return integer + */ + public function getSbasId() + { + return $this->sbas_id; + } + + /** + * Set entry + * + * @param \Entities\FeedEntry $entry + * @return FeedItem + */ + public function setEntry(\Entities\FeedEntry $entry = null) + { + $this->entry = $entry; + + return $this; + } + + /** + * Get entry + * + * @return \Entities\FeedEntry + */ + public function getEntry() + { + return $this->entry; + } + /** + * @var int + */ + private $ord; + + + /** + * Set ord + * + * @param \int $ord + * @return FeedItem + */ + public function setOrd(\int $ord) + { + $this->ord = $ord; + + return $this; + } + + /** + * Get ord + * + * @return \int + */ + public function getOrd() + { + return $this->ord; + } + + /** + * Set created_on + * + * @param \DateTime $createdOn + * @return FeedItem + */ + public function setCreatedOn($createdOn) + { + $this->created_on = $createdOn; + + return $this; + } + + /** + * Get created_on + * + * @return \DateTime + */ + public function getCreatedOn() + { + return $this->created_on; + } + + /** + * Set updated_on + * + * @param \DateTime $updatedOn + * @return FeedItem + */ + public function setUpdatedOn($updatedOn) + { + $this->updated_on = $updatedOn; + + return $this; + } + + /** + * Get updated_on + * + * @return \DateTime + */ + public function getUpdatedOn() + { + return $this->updated_on; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedPublisher.php b/lib/Doctrine/Entities/FeedPublisher.php new file mode 100644 index 0000000000..0bb630813a --- /dev/null +++ b/lib/Doctrine/Entities/FeedPublisher.php @@ -0,0 +1,147 @@ +id; + } + + /** + * Set usr_id + * + * @param integer $usrId + * @return FeedPublisher + */ + public function setUsrId($usrId) + { + $this->usr_id = $usrId; + + return $this; + } + + /** + * Get usr_id + * + * @return integer + */ + public function getUsrId() + { + return $this->usr_id; + } + + /** + * Set owner + * + * @param boolean $owner + * @return FeedPublisher + */ + public function setOwner($owner) + { + $this->owner = $owner; + + return $this; + } + + /** + * Get owner + * + * @return boolean + */ + public function getOwner() + { + return $this->owner; + } + + /** + * Set feed + * + * @param \Entities\Feed $feed + * @return FeedPublisher + */ + public function setFeed(\Entities\Feed $feed = null) + { + $this->feed = $feed; + + return $this; + } + + /** + * Get feed + * + * @return \Entities\Feed + */ + public function getFeed() + { + return $this->feed; + } + + public function getUser(Application $app) + { + $user = \User_Adapter::getInstance($this->getUsrId(), $app); + + return $user; + } + + /** + * Set created_on + * + * @param \DateTime $createdOn + * @return FeedPublisher + */ + public function setCreatedOn($createdOn) + { + $this->created_on = $createdOn; + + return $this; + } + + /** + * Get created_on + * + * @return \DateTime + */ + public function getCreatedOn() + { + return $this->created_on; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Repositories/OrderElementRepository.php b/lib/Doctrine/Repositories/OrderElementRepository.php index 26b72d24c5..88c305fbea 100644 --- a/lib/Doctrine/Repositories/OrderElementRepository.php +++ b/lib/Doctrine/Repositories/OrderElementRepository.php @@ -12,4 +12,15 @@ use Doctrine\ORM\EntityRepository; */ class OrderElementRepository extends EntityRepository { + public function find($id) + { + $dql = 'SELECT f FROM Entities\FeedPublisher f + WHERE f.id = :id '; + + $query = $this->_em->createQuery($dql); + $query->setParameter('id', $id); + $feed = $query->getResult(); + + return $feed[0]; + } } diff --git a/lib/Doctrine/Repositories/SessionRepository.php b/lib/Doctrine/Repositories/SessionRepository.php index b78db0574a..3a927bb8e9 100644 --- a/lib/Doctrine/Repositories/SessionRepository.php +++ b/lib/Doctrine/Repositories/SessionRepository.php @@ -2,7 +2,6 @@ namespace Repositories; -use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityRepository; /** @@ -16,7 +15,6 @@ class SessionRepository extends EntityRepository /** * - * @param Application $app * @param User_Adapter $user * @return \Doctrine\Common\Collections\Collection */ @@ -24,7 +22,6 @@ class SessionRepository extends EntityRepository { $base_ids = array_keys($user->ACL()->get_granted_base()); - $dql = 'SELECT f FROM Entities\Feed f WHERE f.base_id IS NULL '; @@ -34,10 +31,23 @@ class SessionRepository extends EntityRepository } $dql .= ' OR f.public = true - ORDER BY f.created DESC'; + ORDER BY f.created_on DESC'; $query = $this->_em->createQuery($dql); $feeds = $query->getResult(); + return $feeds; } + + public function find($id) + { + $dql = 'SELECT f FROM Entities\Feed f + WHERE f.id = :id '; + + $query = $this->_em->createQuery($dql); + $query->setParameter('id', $id); + $feed = $query->getResult(); + + return $feed[0]; + } } diff --git a/templates/web/admin/publications/fiche.html.twig b/templates/web/admin/publications/fiche.html.twig index 7a3862c980..e83e21c902 100644 --- a/templates/web/admin/publications/fiche.html.twig +++ b/templates/web/admin/publications/fiche.html.twig @@ -6,16 +6,16 @@ {% if error %}
{{ error }}
{% endif %} - {% if feed.is_owner(app['authentication'].getUser()) %} + {% if feed.isOwner(app['authentication'].getUser()) %}

{% trans 'Edition' %}

- +
- +
@@ -79,28 +79,28 @@ }); -
+
- +
- +
- {% for databox in app['authentication'].getUser().ACL().get_granted_sbas('bas_chupub') %} {% for collection in databox.get_collections() %} - + {% endfor %} {% endfor %} @@ -110,7 +110,7 @@
@@ -133,23 +133,23 @@ - {% for publisher in feed.get_publishers() %} + {% for publisher in feed.getPublishers() %} - {{ publisher.get_user().get_id() }} + {{ publisher.getUsrId() }} - {{ publisher.get_user().get_display_name() }} + {{ publisher.getUser(app).get_display_name() }} - {{ publisher.get_user().get_email() }} + {{ publisher.getUser(app).get_email() }} - {% if publisher.is_owner() == true %} + {% if publisher.getOwner() == true %} X {% else %} - - + + {% endif %} @@ -159,7 +159,7 @@
-
+
diff --git a/templates/web/admin/publications/list.html.twig b/templates/web/admin/publications/list.html.twig index 19c89f0b6d..f5cfde8d94 100644 --- a/templates/web/admin/publications/list.html.twig +++ b/templates/web/admin/publications/list.html.twig @@ -72,7 +72,7 @@ {{ feed.getTitle() }} - {{ app['date-formatter'].getDate(feed.getCreated()) }} + {{ app['date-formatter'].getDate(feed.getCreatedOn()) }} {% if feed.getCollection() != null %} From c2f7a5685e806b83803c5ebf6d9565728cedef4c Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 30 May 2013 18:55:53 +0200 Subject: [PATCH 03/67] Add token entities and repositories --- lib/Doctrine/Entities/AggregateToken.php | 83 ++++++++++++++ lib/Doctrine/Entities/FeedToken.php | 108 ++++++++++++++++++ .../Repositories/AggregateTokenRepository.php | 29 +++++ .../Repositories/FeedTokenRepository.php | 31 +++++ 4 files changed, 251 insertions(+) create mode 100644 lib/Doctrine/Entities/AggregateToken.php create mode 100644 lib/Doctrine/Entities/FeedToken.php create mode 100644 lib/Doctrine/Repositories/AggregateTokenRepository.php create mode 100644 lib/Doctrine/Repositories/FeedTokenRepository.php diff --git a/lib/Doctrine/Entities/AggregateToken.php b/lib/Doctrine/Entities/AggregateToken.php new file mode 100644 index 0000000000..85f9493da0 --- /dev/null +++ b/lib/Doctrine/Entities/AggregateToken.php @@ -0,0 +1,83 @@ +id; + } + + /** + * Set usr_id + * + * @param integer $usrId + * @return AggregateToken + */ + public function setUsrId($usrId) + { + $this->usr_id = $usrId; + + return $this; + } + + /** + * Get usr_id + * + * @return integer + */ + public function getUsrId() + { + return $this->usr_id; + } + + /** + * Set value + * + * @param string $value + * @return AggregateToken + */ + public function setValue($value) + { + $this->value = $value; + + return $this; + } + + /** + * Get value + * + * @return string + */ + public function getValue() + { + return $this->value; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedToken.php b/lib/Doctrine/Entities/FeedToken.php new file mode 100644 index 0000000000..9b1f35c72e --- /dev/null +++ b/lib/Doctrine/Entities/FeedToken.php @@ -0,0 +1,108 @@ +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; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Repositories/AggregateTokenRepository.php b/lib/Doctrine/Repositories/AggregateTokenRepository.php new file mode 100644 index 0000000000..a12579fabc --- /dev/null +++ b/lib/Doctrine/Repositories/AggregateTokenRepository.php @@ -0,0 +1,29 @@ +_em->createQuery($dql); + $query->setParameters(array( + ':usr_id' => $user->get_id()) + ); + + return $query->getOneOrNullResult(); + } +} diff --git a/lib/Doctrine/Repositories/FeedTokenRepository.php b/lib/Doctrine/Repositories/FeedTokenRepository.php new file mode 100644 index 0000000000..c592dd4611 --- /dev/null +++ b/lib/Doctrine/Repositories/FeedTokenRepository.php @@ -0,0 +1,31 @@ +_em->createQuery($dql); + $query->setParameters(array( + ':feed' => $feed, + ':usr_id' => $user->get_id()) + ); + + return $query->getOneOrNullResult(); + } +} From fc9379ca6309033bcc09107c2d3e77093cde604c Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 30 May 2013 18:58:05 +0200 Subject: [PATCH 04/67] Add more search methods to repositories --- .../Repositories/OrderElementRepository.php | 19 ++++++-- .../Repositories/SessionRepository.php | 48 +++++++++++++++---- .../Repositories/UserSettingRepository.php | 40 ++++++++++++++++ 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/lib/Doctrine/Repositories/OrderElementRepository.php b/lib/Doctrine/Repositories/OrderElementRepository.php index 88c305fbea..916c536108 100644 --- a/lib/Doctrine/Repositories/OrderElementRepository.php +++ b/lib/Doctrine/Repositories/OrderElementRepository.php @@ -16,11 +16,22 @@ class OrderElementRepository extends EntityRepository { $dql = 'SELECT f FROM Entities\FeedPublisher f WHERE f.id = :id '; - + $query = $this->_em->createQuery($dql); $query->setParameter('id', $id); - $feed = $query->getResult(); - - return $feed[0]; + + return $query->getOneOrNullResult(); + } + + public function findByUser(\Entities\Feed $feed, \User_Adapter $user) + { + $dql = 'SELECT f FROM Entities\FeedPublisher f + WHERE f.usr_id = :usrId AND f.feed = :feed'; + + $query = $this->_em->createQuery($dql); + $query->setParameter('usrId', $user->get_id()); + $query->setParameter('feed', $feed); + + return $query->getOneOrNullResult(); } } diff --git a/lib/Doctrine/Repositories/SessionRepository.php b/lib/Doctrine/Repositories/SessionRepository.php index 3a927bb8e9..a3ca1b71e0 100644 --- a/lib/Doctrine/Repositories/SessionRepository.php +++ b/lib/Doctrine/Repositories/SessionRepository.php @@ -2,6 +2,7 @@ namespace Repositories; +use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityRepository; /** @@ -12,7 +13,7 @@ use Doctrine\ORM\EntityRepository; */ class SessionRepository extends EntityRepository { - + /** * * @param User_Adapter $user @@ -35,19 +36,46 @@ class SessionRepository extends EntityRepository $query = $this->_em->createQuery($dql); $feeds = $query->getResult(); - + return $feeds; } - - public function find($id) + + public function findAllPublic() { $dql = 'SELECT f FROM Entities\Feed f - WHERE f.id = :id '; - + WHERE f.public = true + ORDER BY f.created_on DESC'; + $query = $this->_em->createQuery($dql); - $query->setParameter('id', $id); - $feed = $query->getResult(); - - return $feed[0]; + $feeds = $query->getResult(); + + return $feeds; + } + + public function loadWithUser(Application $app, \User_Adapter $user, $id) + { + $feed = $this->find($id); + if ($feed) { + $coll = $feed->getCollection($app); + if ($feed->getPublic() + || $coll === null + || in_array($coll->get_base_id(), array_keys($user->ACL()->get_granted_base()))) { + return $feed; + } + } + + return null; + } + + public function findByIdArray(array $feed_id) + { + $dql = 'SELECT f FROM Entities\Feed f + ORDER BY f.created_on DESC + WHERE f.id IN (' . implode(",", $feed_id) . ')'; + + $query = $this->_em->createQuery($dql); + $feeds = $query->getResult(); + + return $feeds; } } diff --git a/lib/Doctrine/Repositories/UserSettingRepository.php b/lib/Doctrine/Repositories/UserSettingRepository.php index 872f603c7f..3537ecd8b5 100644 --- a/lib/Doctrine/Repositories/UserSettingRepository.php +++ b/lib/Doctrine/Repositories/UserSettingRepository.php @@ -12,4 +12,44 @@ use Doctrine\ORM\EntityRepository; */ class UserSettingRepository extends EntityRepository { + public function find($id) + { + $dql = 'SELECT f FROM Entities\FeedEntry f + WHERE f.id = :id '; + + $query = $this->_em->createQuery($dql); + $query->setParameter('id', $id); + + return $query->getOneOrNullResult(); + } + + public function findByFeed($feed, $id) + { + $dql = 'SELECT f FROM Entities\FeedEntry f + WHERE f.id = :id AND f.feed = :feed'; + + $query = $this->_em->createQuery($dql); + $query->setParameter('id', $id); + $query->setParameter('feed', $feed); + + return $query->getOneOrNullResult(); + } + + public function findByFeeds($feeds, $offset_start = null, $how_many = null) + { + $dql = 'SELECT f FROM Entities\FeedEntry f + WHERE f.feed IN (:feeds)'; + + $query = $this->_em->createQuery($dql); + $query->setParameter('feeds', $feeds); + + if (null !== $offset_start) { + $query->setFirstResult($offset_start); + } + if (null !== $how_many) { + $query->setMaxResults($how_many); + } + + return $query->getResult(); + } } From f117817e8705d76a362d2605c133822aa8c0292e Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 30 May 2013 19:04:49 +0200 Subject: [PATCH 05/67] Implementation of doctrine entities --- lib/Alchemy/Phrasea/Application.php | 2 + lib/Alchemy/Phrasea/Controller/Prod/Feed.php | 154 ++++++---- lib/Alchemy/Phrasea/Controller/Prod/Root.php | 9 +- .../Phrasea/Controller/Root/RSSFeeds.php | 47 ++-- .../Core/Provider/FeedServiceProvider.php | 34 +++ lib/Alchemy/Phrasea/Feed/Aggregate.php | 149 ++++++++++ .../Phrasea/Feed/AggregateLinkGenerator.php | 74 +++++ lib/Alchemy/Phrasea/Feed/AggregateToken.php | 111 ++++++++ lib/Alchemy/Phrasea/Feed/FeedInterface.php | 21 ++ lib/Alchemy/Phrasea/Feed/Link.php | 68 +++++ lib/Alchemy/Phrasea/Feed/LinkGenerator.php | 80 ++++++ lib/Alchemy/Phrasea/Feed/LinkInterface.php | 30 ++ lib/Doctrine/Entities/Feed.php | 124 +++++--- lib/Doctrine/Entities/FeedEntry.php | 8 +- lib/Doctrine/Entities/FeedItem.php | 4 - .../prod/actions/publish/publish.html.twig | 10 +- templates/web/prod/feeds/entry.html.twig | 2 +- .../web/prod/feeds/entry_macro.html.twig | 40 +-- templates/web/prod/feeds/feeds.html.twig | 29 +- templates/web/prod/index.html.twig | 10 +- .../Phrasea/Controller/Prod/FeedTest.php | 264 +++++++++--------- .../Core/Provider/FeedServiceProviderTest.php | 25 ++ .../Feed/AggregateLinkGeneratorTest.php | 129 +++++++++ .../Tests/Phrasea/Feed/LinkGeneratorTest.php | 126 +++++++++ tests/classes/PhraseanetPHPUnitAbstract.php | 126 +++++++++ 25 files changed, 1374 insertions(+), 302 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php create mode 100644 lib/Alchemy/Phrasea/Feed/Aggregate.php create mode 100644 lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php create mode 100644 lib/Alchemy/Phrasea/Feed/AggregateToken.php create mode 100644 lib/Alchemy/Phrasea/Feed/FeedInterface.php create mode 100644 lib/Alchemy/Phrasea/Feed/Link.php create mode 100644 lib/Alchemy/Phrasea/Feed/LinkGenerator.php create mode 100644 lib/Alchemy/Phrasea/Feed/LinkInterface.php create mode 100644 tests/Alchemy/Tests/Phrasea/Core/Provider/FeedServiceProviderTest.php create mode 100644 tests/Alchemy/Tests/Phrasea/Feed/AggregateLinkGeneratorTest.php create mode 100644 tests/Alchemy/Tests/Phrasea/Feed/LinkGeneratorTest.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 5c400af903..ae485b1af3 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -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()); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php index b85df97637..0290f8ce91 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -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' => '

' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') . '

' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '

-
', +
', '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' => '

' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') . '

' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '

-
', +
', 'titre' => _('publications::votre rss personnel') ); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php index 75d889bc39..3d85e8f16d 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php @@ -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), diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php index 7855fbf691..fb00b5304c 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php +++ b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php @@ -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'); diff --git a/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php new file mode 100644 index 0000000000..dc4ceef38f --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php @@ -0,0 +1,34 @@ +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) + { + } +} diff --git a/lib/Alchemy/Phrasea/Feed/Aggregate.php b/lib/Alchemy/Phrasea/Feed/Aggregate.php new file mode 100644 index 0000000000..3bfbdd6177 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/Aggregate.php @@ -0,0 +1,149 @@ +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; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php new file mode 100644 index 0000000000..6f9477c6f8 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php @@ -0,0 +1,74 @@ +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; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/AggregateToken.php b/lib/Alchemy/Phrasea/Feed/AggregateToken.php new file mode 100644 index 0000000000..6ef2a26227 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/AggregateToken.php @@ -0,0 +1,111 @@ +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; + } +} \ No newline at end of file diff --git a/lib/Alchemy/Phrasea/Feed/FeedInterface.php b/lib/Alchemy/Phrasea/Feed/FeedInterface.php new file mode 100644 index 0000000000..504e9b6e37 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/FeedInterface.php @@ -0,0 +1,21 @@ +mimetype = $mimetype; + $this->uri = $uri; + $this->title = $title; + } + + /** + * {@inheritdoc} + */ + public function getMimetype() + { + return $this->mimetype; + } + + /** + * {@inheritdoc} + */ + public function getTitle() + { + return $this->title; + } + + /** + * {@inheritdoc} + */ + public function getURI() + { + return $this->uri; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/LinkGenerator.php b/lib/Alchemy/Phrasea/Feed/LinkGenerator.php new file mode 100644 index 0000000000..dbe105e0d6 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/LinkGenerator.php @@ -0,0 +1,80 @@ +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; + } +} diff --git a/lib/Alchemy/Phrasea/Feed/LinkInterface.php b/lib/Alchemy/Phrasea/Feed/LinkInterface.php new file mode 100644 index 0000000000..4d45c2d4d8 --- /dev/null +++ b/lib/Alchemy/Phrasea/Feed/LinkInterface.php @@ -0,0 +1,30 @@ +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; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedEntry.php b/lib/Doctrine/Entities/FeedEntry.php index f5f4e9288f..ae72ac8ecd 100644 --- a/lib/Doctrine/Entities/FeedEntry.php +++ b/lib/Doctrine/Entities/FeedEntry.php @@ -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; } -} +} \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedItem.php b/lib/Doctrine/Entities/FeedItem.php index 4d33318551..9c2682775f 100644 --- a/lib/Doctrine/Entities/FeedItem.php +++ b/lib/Doctrine/Entities/FeedItem.php @@ -39,10 +39,6 @@ class FeedItem */ private $entry; - public function __construct(\Entities\FeedEntry $entry, \record_adapter $record) - { - } - /** * Get id * diff --git a/templates/web/prod/actions/publish/publish.html.twig b/templates/web/prod/actions/publish/publish.html.twig index 3bd4fcebfb..f9df778eac 100644 --- a/templates/web/prod/actions/publish/publish.html.twig +++ b/templates/web/prod/actions/publish/publish.html.twig @@ -53,14 +53,14 @@

{% trans 'Fils disponibles' %}

- {% for feed in feeds.get_feeds() %} - {% if feed.is_publisher(app['authentication'].getUser()) %} + {% for feed in feeds %} + {% if feed.isPublisher(app['authentication'].getUser()) %}
- {{ feed.get_title() }} - {% if feed.is_public() %} + {{ feed.getTitle() }} + {% if feed.getPublic() %} {% endif %} - +
{% endif %} {% endfor %} diff --git a/templates/web/prod/feeds/entry.html.twig b/templates/web/prod/feeds/entry.html.twig index 7618484f4a..699d111ebd 100644 --- a/templates/web/prod/feeds/entry.html.twig +++ b/templates/web/prod/feeds/entry.html.twig @@ -1,2 +1,2 @@ {% import 'prod/feeds/entry_macro.html.twig' as _entry %} -{{ _entry.format(entry.get_feed(), entry) }} \ No newline at end of file +{{ _entry.format(entry.getFeed(), entry) }} \ No newline at end of file diff --git a/templates/web/prod/feeds/entry_macro.html.twig b/templates/web/prod/feeds/entry_macro.html.twig index 976d81275a..3954bde598 100644 --- a/templates/web/prod/feeds/entry_macro.html.twig +++ b/templates/web/prod/feeds/entry_macro.html.twig @@ -1,25 +1,25 @@ {% macro format(feed, entry)%} {% import 'prod/results/record.html.twig' as record_format %} -
+

- {% if feed.is_aggregated() %} - + {% if feed.isAggregated() %} + {% endif %} - {{ entry.get_title() }} - {% set author = entry.get_author_name() %} + {{ entry.getTitle() }} + {% set author = entry.getAuthorName() %} {% trans %}Par {{ author }}{% endtrans %}

- {% if entry.get_feed().is_owner(app['authentication'].getUser()) or entry.is_publisher(app['authentication'].getUser()) %} - + {% if entry.getFeed().isOwner(app['authentication'].getUser()) or entry.isPublisher(app['authentication'].getUser()) %} + - + {% endif %} @@ -27,8 +27,8 @@
-

{{ entry.get_subtitle()|nl2br|raw }}

+

{{ entry.getSubtitle()|nl2br|raw }}

- {% 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 %}
-{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/templates/web/prod/feeds/feeds.html.twig b/templates/web/prod/feeds/feeds.html.twig index 893e5d2669..182ff7b81a 100644 --- a/templates/web/prod/feeds/feeds.html.twig +++ b/templates/web/prod/feeds/feeds.html.twig @@ -6,23 +6,22 @@

- - {% if feed.is_aggregated %} + + {% if feed.isAggregated %} {% trans 'Toutes les publications' %} {% else %} - {{ feed.get_title() }} - + {{ feed.getTitle() }} + {% endif %} - - {% if feed.is_aggregated %} + {% if feed.isAggregated %} {% else %} - + {% endif %}

@@ -34,10 +33,10 @@
\ No newline at end of file +
diff --git a/templates/web/prod/index.html.twig b/templates/web/prod/index.html.twig index bea73022e5..e2cd7ac8ef 100644 --- a/templates/web/prod/index.html.twig +++ b/templates/web/prod/index.html.twig @@ -52,11 +52,11 @@ {% endblock %} {% block rss %} - {% for feed in feeds %} - {% set link = feed.get_user_link(app['phraseanet.registry'], app['authentication'].getUser(), 'rss') %} - - {% set link = feed.get_user_link(app['phraseanet.registry'], app['authentication'].getUser(), 'atom') %} - + {% for feed in aggregate.getFeeds() %} + {% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %} + + {% set link = app['feed.user-link-generator'].generate(feed, app['authentication'].getUser(), 'rss') %} + {% endfor %} {% endblock %} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php index 0b6b9ef15c..843df1659c 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/FeedTest.php @@ -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); } } diff --git a/tests/Alchemy/Tests/Phrasea/Core/Provider/FeedServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/Provider/FeedServiceProviderTest.php new file mode 100644 index 0000000000..0f160ae1c4 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Core/Provider/FeedServiceProviderTest.php @@ -0,0 +1,25 @@ +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), + ); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Feed/LinkGeneratorTest.php b/tests/Alchemy/Tests/Phrasea/Feed/LinkGeneratorTest.php new file mode 100644 index 0000000000..7121e4c3dc --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Feed/LinkGeneratorTest.php @@ -0,0 +1,126 @@ +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), + ); + } +} diff --git a/tests/classes/PhraseanetPHPUnitAbstract.php b/tests/classes/PhraseanetPHPUnitAbstract.php index ac3ab4e698..6aa28dc264 100644 --- a/tests/classes/PhraseanetPHPUnitAbstract.php +++ b/tests/classes/PhraseanetPHPUnitAbstract.php @@ -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 * From 1d7c60ac418abf0967cf104cb870a9ee431e777e Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 30 May 2013 19:06:14 +0200 Subject: [PATCH 06/67] Add token entities dcm files --- .../Doctrine/Entities.AggregateToken.dcm.yml | 20 ++++++++++++++++ .../Doctrine/Entities.FeedToken.dcm.yml | 24 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 lib/conf.d/Doctrine/Entities.AggregateToken.dcm.yml create mode 100644 lib/conf.d/Doctrine/Entities.FeedToken.dcm.yml diff --git a/lib/conf.d/Doctrine/Entities.AggregateToken.dcm.yml b/lib/conf.d/Doctrine/Entities.AggregateToken.dcm.yml new file mode 100644 index 0000000000..43eb71ae75 --- /dev/null +++ b/lib/conf.d/Doctrine/Entities.AggregateToken.dcm.yml @@ -0,0 +1,20 @@ +Entities\AggregateToken: + type: entity + repositoryClass: Repositories\AggregateTokenRepository + table: AggregateTokens + uniqueConstraints: + unique_aggregate_token_index: + columns: usr_id + id: + id: + type: integer + generator: + strategy: AUTO + fields: + usr_id: + type: integer + value: + type: string + length: 12 + nullable: true + \ No newline at end of file diff --git a/lib/conf.d/Doctrine/Entities.FeedToken.dcm.yml b/lib/conf.d/Doctrine/Entities.FeedToken.dcm.yml new file mode 100644 index 0000000000..c4efc5b43e --- /dev/null +++ b/lib/conf.d/Doctrine/Entities.FeedToken.dcm.yml @@ -0,0 +1,24 @@ +Entities\FeedToken: + type: entity + repositoryClass: Repositories\FeedTokenRepository + table: FeedTokens + id: + id: + type: integer + generator: + strategy: AUTO + fields: + usr_id: + type: integer + value: + type: string + length: 12 + nullable: true + manyToOne: + feed: + targetEntity: Feed + inversedBy: tokens + joinColumn: + name: feed_id + referencedColumnName: id + cascade: ["persist"] From affdfe7a0a59540ed3156b651d28036bd9411b26 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 4 Jun 2013 19:12:59 +0200 Subject: [PATCH 07/67] Implement RSSFeeds, fixed controllers implementation, fixed tests --- .../Phrasea/Controller/Admin/Publications.php | 9 +- .../Phrasea/Controller/Client/Root.php | 3 +- lib/Alchemy/Phrasea/Controller/Lightbox.php | 15 ++- lib/Alchemy/Phrasea/Controller/Prod/Feed.php | 16 +-- lib/Alchemy/Phrasea/Controller/Prod/Root.php | 8 +- lib/Alchemy/Phrasea/Controller/Root/Login.php | 5 +- .../Phrasea/Controller/Root/RSSFeeds.php | 14 +- .../Core/Provider/FeedServiceProvider.php | 2 +- .../Phrasea/Feed/AggregateLinkGenerator.php | 50 +++++-- lib/Alchemy/Phrasea/Feed/LinkGenerator.php | 56 ++++++-- lib/Doctrine/Entities/Feed.php | 23 ++++ lib/Doctrine/Entities/FeedEntry.php | 55 ++++---- lib/Doctrine/Entities/FeedItem.php | 37 +++--- lib/classes/eventsmanager/notify/feed.php | 28 ++-- templates/web/lightbox/feed.html.twig | 14 +- .../web/lightbox/feed_container.html.twig | 12 +- .../web/lightbox/feed_options_box.html.twig | 2 +- templates/web/login/index.html.twig | 6 +- .../actions/publish/publish_edit.html.twig | 30 ++--- templates/web/prod/index.html.twig | 2 +- .../Phrasea/Controller/Prod/FeedTest.php | 122 +++++++----------- .../Feed/AggregateLinkGeneratorTest.php | 29 ++++- .../Tests/Phrasea/Feed/LinkGeneratorTest.php | 76 ++++++++++- 23 files changed, 393 insertions(+), 221 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index b0d8bec98e..83a2a3072f 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -12,7 +12,8 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application as PhraseaApplication; -use Repositories; +use Entities\Feed; +use Entities\FeedPublisher; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; @@ -47,9 +48,9 @@ class Publications implements ControllerProviderInterface $controllers->post('/create/', function(PhraseaApplication $app, Request $request) { - $publisher = new \Entities\FeedPublisher($app['authentication']->getUser(), true); + $publisher = new FeedPublisher($app['authentication']->getUser(), true); - $feed = new \Entities\Feed($publisher, $request->request->get('title'), $request->request->get('subtitle')); + $feed = new Feed($publisher, $request->request->get('title'), $request->request->get('subtitle')); if ($request->request->get('public') == '1') { $feed->setPublic(true); @@ -178,7 +179,7 @@ class Publications implements ControllerProviderInterface $user = \User_Adapter::getInstance($request->request->get('usr_id'), $app); $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); - $publisher = new \Entities\FeedPublisher($user, false); + $publisher = new FeedPublisher($user, false); $publisher->setFeed($feed); $feed->addPublisher($publisher); diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php index 656c9b9a56..7bfd23ffcc 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php @@ -539,7 +539,8 @@ class Root implements ControllerProviderInterface private function getPublicationStartPage(Application $app) { return $app['twig']->render('client/home_inter_pub_basket.html.twig', array( - 'feeds' => \Feed_Collection::load_all($app, $app['authentication']->getUser()), +// 'feeds' => \Feed_Collection::load_all($app, $app['authentication']->getUser()), + 'feeds' => $app['EM']->getRepository('Entities\Feed')->getAllforUser($app['authentication']->getUser()), 'image_size' => (int) $app['authentication']->getUser()->getPrefs('images_size') )); } diff --git a/lib/Alchemy/Phrasea/Controller/Lightbox.php b/lib/Alchemy/Phrasea/Controller/Lightbox.php index 15395ea667..5fcbf35441 100644 --- a/lib/Alchemy/Phrasea/Controller/Lightbox.php +++ b/lib/Alchemy/Phrasea/Controller/Lightbox.php @@ -160,13 +160,15 @@ class Lightbox implements ControllerProviderInterface $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function(SilexApplication $app, $entry_id, $item_id) { - $entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id); - $item = new \Feed_Entry_Item($app['phraseanet.appbox'], $entry, $item_id); +// $entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id); + $entry = $app['EM']->getRepository("Entities\FeedEntry")->find($entry_id); +// $item = new \Feed_Entry_Item($app['phraseanet.appbox'], $entry, $item_id); + $item = $entry->getItems()->getItem($item_id); if ($app['browser']->isMobile()) { $output = $app['twig']->render('lightbox/feed_element.html.twig', array( 'feed_element' => $item, - 'module_name' => $item->get_record()->get_title() + 'module_name' => $item->getRecord()->get_title() ) ); @@ -313,7 +315,8 @@ class Lightbox implements ControllerProviderInterface return $app->redirectPath('logout'); } - $feed_entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id); +// $feed_entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id); + $feed_entry = $app['EM']->getEntity("Entities\FeedEntry")->find($entry_id); $template = 'lightbox/feed.html.twig'; @@ -321,12 +324,12 @@ class Lightbox implements ControllerProviderInterface $template = 'lightbox/IE6/feed.html.twig'; } - $content = $feed_entry->get_content(); + $content = $feed_entry->getItems(); $output = $app['twig']->render($template, array( 'feed_entry' => $feed_entry, 'first_item' => array_shift($content), - 'local_title' => $feed_entry->get_title(), + 'local_title' => $feed_entry->getTitle(), 'module' => 'lightbox', 'module_name' => _('admin::monitor: module validation') ) diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php index 0290f8ce91..dc477fb40b 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -15,6 +15,8 @@ use Alchemy\Phrasea\Feed\Aggregate; use Alchemy\Phrasea\Feed\AggregateLinkGenerator; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Feed\LinkGenerator; +use Entities\FeedEntry; +use Entities\FeedItem; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; @@ -60,7 +62,7 @@ class Feed implements ControllerProviderInterface $author_name = $request->request->get('author_name'); $author_email = $request->request->get('author_email'); - $entry = new \Entities\FeedEntry(); + $entry = new FeedEntry(); $entry->setFeed($feed); $entry->setPublisher($publisher); $entry->setTitle($title); @@ -72,7 +74,7 @@ class Feed implements ControllerProviderInterface $publishing = RecordsRequest::fromRequest($app, $request, true, array(), array('bas_chupub')); foreach ($publishing as $record) { - $item = new \Entities\FeedItem(); + $item = new FeedItem(); $item->setEntry($entry); $item->setRecordId($record->get_record_id()); $item->setSbasId($record->get_sbas_id()); @@ -166,7 +168,7 @@ class Feed implements ControllerProviderInterface continue; } - $item = new \entities\FeedItem($entry, $item_sort_datas[0]); + $item = new FeedItem($entry, $item_sort_datas[0]); $item->setEntry($entry); $entry->addItem($item); $item->setOrd($item_sort_datas[1]); @@ -262,11 +264,9 @@ class Feed implements ControllerProviderInterface $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); + $link = $app['feed.aggregate-link-generator']->generate($aggregate, $app['authentication']->getUser(), AggregateLinkGenerator::FORMAT_RSS, null, $renew); $output = array( 'texte' => '

' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') @@ -283,9 +283,7 @@ class Feed implements ControllerProviderInterface $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); + $link = $app['feed.user-link-generator']->generate($feed, $app['authentication']->getUser(), LinkGenerator::FORMAT_RSS, null, $renew); $output = array( 'texte' => '

' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.') diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php index 3d85e8f16d..dee619260b 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php @@ -11,7 +11,7 @@ namespace Alchemy\Phrasea\Controller\Prod; -use \Alchemy\Phrasea\Feed\Aggregate; +use Alchemy\Phrasea\Feed\Aggregate; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Exception\SessionNotFound; use Silex\Application as SilexApplication; @@ -75,8 +75,8 @@ class Root implements ControllerProviderInterface // $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); + $feeds = $app["EM"]->getRepository("Entities\Feed")->getAllForUser($app['authentication']->getUser()); +// $aggregate = new Aggregate($app, $user_feeds); $thjslist = ""; @@ -118,7 +118,7 @@ class Root implements ControllerProviderInterface 'GV_thesaurus' => $app['phraseanet.registry']->get('GV_thesaurus'), 'cgus_agreement' => \databox_cgu::askAgreement($app), 'css' => $css, - 'aggregate' => $aggregate, + 'feeds' => $feeds, 'GV_google_api' => $app['phraseanet.registry']->get('GV_google_api'), 'queries_topics' => $queries_topics, 'search_status' => \databox_status::getSearchStatus($app), diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index 11e385702e..af346af770 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -725,10 +725,7 @@ class Login implements ControllerProviderInterface $app->addFlash('error', _('login::erreur: No available connection - Please contact sys-admin')); } - $public_feeds = \Feed_Collection::load_public_feeds($app); - - $feeds = $public_feeds->get_feeds(); - array_unshift($feeds, $public_feeds->get_aggregate()); + $feeds = $app['EM']->getRepository('Entities\Feed')->findAllPublic(); $form = $app->form(new PhraseaAuthenticationForm()); $form->setData(array( diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php index fb00b5304c..b448de9eef 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php +++ b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php @@ -32,15 +32,15 @@ class RSSFeeds implements ControllerProviderInterface $perPage = 5; $entries = $feed->getEntries((($page - 1) * $perPage), $perPage); - if ($format == \Entities\Feed::FORMAT_RSS) { + if ($format == 'rss') { $content = new \Feed_XML_RSS(); } - if ($format == \Entities\Feed::FORMAT_ATOM) { + if ($format == 'atom') { $content = new \Feed_XML_Atom(); } - if ($format == \Entities\Feed::FORMAT_COOLIRIS) { + if ($format == 'cooliris') { $content = new \Feed_XML_Cooliris(); } @@ -77,7 +77,6 @@ class RSSFeeds implements ControllerProviderInterface }; $controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) use ($display_feed) { - // $feed = new \Feed_Adapter($app, $id); $feed = $app["EM"]->getRepository("Entities\Feed")->find($id); if (!$feed->isPublic()) { @@ -112,7 +111,6 @@ class RSSFeeds implements ControllerProviderInterface $controllers->get('/userfeed/aggregated/{token}/{format}/', function(Application $app, $token, $format) use ($display_feed) { $token = $app["EM"]->getRepository("Entities\AggregateToken")->findBy(array("id" => $id)); - //$feed = $token->getFeed(); $request = $app['request']; @@ -125,8 +123,6 @@ 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 = $app["EM"]->getRepository("Entities\Feed")->findAllPublic(); $feed = new Aggregate($app, $feeds); @@ -140,8 +136,6 @@ 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 = $app["EM"]->getRepository("Entities\Feed")->findAllPublic(); $feed = new Aggregate($app, $feeds); @@ -149,7 +143,7 @@ class RSSFeeds implements ControllerProviderInterface $page = (int) $request->query->get('page'); $page = $page < 1 ? 1 : $page; - return $display_feed($app, $feed, \Feed_Adapter::FORMAT_COOLIRIS, $page); + return $display_feed($app, $feed, 'cooliris', $page); }) ->bind('feed_public_cooliris'); diff --git a/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php index dc4ceef38f..f16badbc1c 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/FeedServiceProvider.php @@ -23,7 +23,7 @@ class FeedServiceProvider implements ServiceProviderInterface $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) { + $app['feed.aggregate-link-generator'] = $app->share(function($app) { return new AggregateLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']); }); } diff --git a/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php b/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php index 6f9477c6f8..9579fc2090 100644 --- a/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php +++ b/lib/Alchemy/Phrasea/Feed/AggregateLinkGenerator.php @@ -28,21 +28,55 @@ class AggregateLinkGenerator { switch ($format) { case self::FORMAT_ATOM: + $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } return new FeedLink( - $this->generator->generate('feed_user_aggregated', array( - 'token' => $this->getAggregateToken($user, $renew)->getValue(), - 'format' => 'atom', - ), UrlGenerator::ABSOLUTE_URL), + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), 'application/atom+xml' ); break; case self::FORMAT_RSS: + $params = array('token' => $this->getAggregateToken($user, $renew)->getValue(), + 'format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } return new FeedLink( - $this->generator->generate('feed_user_aggregated', array( - 'token' => $this->getAggregateToken($user, $renew)->getValue(), - 'format' => 'rss', - ), UrlGenerator::ABSOLUTE_URL), + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + public function generatePublic(Aggregate $aggregate, $format, $page = null) + { + switch ($format) { + case self::FORMAT_ATOM: + $params = array('format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $aggregate->getTitle(), 'Atom'), + 'application/atom+xml' + ); + break; + case self::FORMAT_RSS: + $params = array('format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_user_aggregated', $params, UrlGenerator::ABSOLUTE_URL), sprintf('%s - %s', $aggregate->getTitle(), 'RSS'), 'application/rss+xml' ); diff --git a/lib/Alchemy/Phrasea/Feed/LinkGenerator.php b/lib/Alchemy/Phrasea/Feed/LinkGenerator.php index dbe105e0d6..b63347697d 100644 --- a/lib/Alchemy/Phrasea/Feed/LinkGenerator.php +++ b/lib/Alchemy/Phrasea/Feed/LinkGenerator.php @@ -28,23 +28,59 @@ class LinkGenerator { switch ($format) { case self::FORMAT_ATOM: + $params = array('token' => $this->getFeedToken($feed, $user, $renew)->getValue(), + 'id' => $feed->getId(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } return new FeedLink( - $this->generator->generate('feed_user', array( - 'token' => $this->getFeedToken($feed, $user, $renew)->getValue(), - 'id' => $feed->getId(), - 'format' => 'atom', - ), UrlGenerator::ABSOLUTE_URL), + $this->generator->generate('feed_user', $params, UrlGenerator::ABSOLUTE_URL), sprintf('%s - %s', $feed->getTitle(), 'Atom'), 'application/atom+xml' ); break; case self::FORMAT_RSS: + $params = array('token' => $this->getFeedToken($feed, $user, $renew)->getValue(), + 'id' => $feed->getId(), + 'format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } return new FeedLink( - $this->generator->generate('feed_user', array( - 'token' => $this->getFeedToken($feed, $user, $renew)->getValue(), - 'id' => $feed->getId(), - 'format' => 'rss', - ), UrlGenerator::ABSOLUTE_URL), + $this->generator->generate('feed_user', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $feed->getTitle(), 'RSS'), + 'application/rss+xml' + ); + break; + default: + throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format)); + } + } + + public function generatePublic(Feed $feed, $format, $page = null) + { + switch ($format) { + case self::FORMAT_ATOM: + $params = array('id' => $feed->getId(), + 'format' => 'atom'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_public', $params, UrlGenerator::ABSOLUTE_URL), + sprintf('%s - %s', $feed->getTitle(), 'Atom'), + 'application/atom+xml' + ); + break; + case self::FORMAT_RSS: + $params = array('id' => $feed->getId(), + 'format' => 'rss'); + if (null !== $page) { + $params['page'] = $page; + } + return new FeedLink( + $this->generator->generate('feed_public', $params, UrlGenerator::ABSOLUTE_URL), sprintf('%s - %s', $feed->getTitle(), 'RSS'), 'application/rss+xml' ); diff --git a/lib/Doctrine/Entities/Feed.php b/lib/Doctrine/Entities/Feed.php index 8d44126200..2ba83f8cbc 100644 --- a/lib/Doctrine/Entities/Feed.php +++ b/lib/Doctrine/Entities/Feed.php @@ -424,4 +424,27 @@ class Feed implements FeedInterface { return $this->tokens; } + + /** + * Add entries + * + * @param \Entities\FeedEntry $entries + * @return Feed + */ + public function addEntrie(\Entities\FeedEntry $entries) + { + $this->entries[] = $entries; + + return $this; + } + + /** + * Remove entries + * + * @param \Entities\FeedEntry $entries + */ + public function removeEntrie(\Entities\FeedEntry $entries) + { + $this->entries->removeElement($entries); + } } \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedEntry.php b/lib/Doctrine/Entities/FeedEntry.php index ae72ac8ecd..62c1ce0a2c 100644 --- a/lib/Doctrine/Entities/FeedEntry.php +++ b/lib/Doctrine/Entities/FeedEntry.php @@ -66,11 +66,11 @@ class FeedEntry { $this->items = new \Doctrine\Common\Collections\ArrayCollection(); } - + /** * Get id * - * @return integer + * @return integer */ public function getId() { @@ -86,14 +86,14 @@ class FeedEntry public function setTitle($title) { $this->title = $title; - + return $this; } /** * Get title * - * @return string + * @return string */ public function getTitle() { @@ -109,14 +109,14 @@ class FeedEntry public function setSubtitle($subtitle) { $this->subtitle = $subtitle; - + return $this; } /** * Get subtitle * - * @return string + * @return string */ public function getSubtitle() { @@ -132,14 +132,14 @@ class FeedEntry public function setAuthorName($authorName) { $this->author_name = $authorName; - + return $this; } /** * Get author_name * - * @return string + * @return string */ public function getAuthorName() { @@ -155,14 +155,14 @@ class FeedEntry public function setAuthorEmail($authorEmail) { $this->author_email = $authorEmail; - + return $this; } /** * Get author_email * - * @return string + * @return string */ public function getAuthorEmail() { @@ -178,14 +178,14 @@ class FeedEntry public function setCreatedOn($createdOn) { $this->created_on = $createdOn; - + return $this; } /** * Get created * - * @return \DateTime + * @return \DateTime */ public function getCreatedOn() { @@ -201,14 +201,14 @@ class FeedEntry public function setUpdatedOn($updatedOn) { $this->updated_on = $updatedOn; - + return $this; } /** * Get updated * - * @return \DateTime + * @return \DateTime */ public function getUpdatedOn() { @@ -224,7 +224,7 @@ class FeedEntry public function addItem(\Entities\FeedItem $items) { $this->items[] = $items; - + return $this; } @@ -241,7 +241,7 @@ class FeedEntry /** * Get items * - * @return \Doctrine\Common\Collections\Collection + * @return \Doctrine\Common\Collections\Collection */ public function getItems() { @@ -257,14 +257,14 @@ class FeedEntry public function setPublisher(\Entities\FeedPublisher $publisher = null) { $this->publisher = $publisher; - + return $this; } /** * Get publisher * - * @return \Entities\FeedPublisher + * @return \Entities\FeedPublisher */ public function getPublisher() { @@ -280,27 +280,38 @@ class FeedEntry public function setFeed(\Entities\Feed $feed = null) { $this->feed = $feed; - + return $this; } /** * Get feed * - * @return \Entities\Feed + * @return \Entities\Feed */ public function getFeed() { return $this->feed; } - + public function isPublisher(\User_Adapter $user) { if ($this->publisher) { if ($this->publisher->getUsrId() === $user->get_id()) return true; } - + return false; } + + public function getItem($id) + { + foreach ($this->items as $item) { + if ($item->getId() == $id) { + return ($item); + } + } + + return null; + } } \ No newline at end of file diff --git a/lib/Doctrine/Entities/FeedItem.php b/lib/Doctrine/Entities/FeedItem.php index 9c2682775f..1ec74e792d 100644 --- a/lib/Doctrine/Entities/FeedItem.php +++ b/lib/Doctrine/Entities/FeedItem.php @@ -42,7 +42,7 @@ class FeedItem /** * Get id * - * @return integer + * @return integer */ public function getId() { @@ -58,14 +58,14 @@ class FeedItem public function setRecordId($recordId) { $this->record_id = $recordId; - + return $this; } /** * Get record_id * - * @return integer + * @return integer */ public function getRecordId() { @@ -81,14 +81,14 @@ class FeedItem public function setSbasId($sbasId) { $this->sbas_id = $sbasId; - + return $this; } /** * Get sbas_id * - * @return integer + * @return integer */ public function getSbasId() { @@ -104,21 +104,21 @@ class FeedItem public function setEntry(\Entities\FeedEntry $entry = null) { $this->entry = $entry; - + return $this; } /** * Get entry * - * @return \Entities\FeedEntry + * @return \Entities\FeedEntry */ public function getEntry() { return $this->entry; } /** - * @var int + * @var integer */ private $ord; @@ -126,20 +126,20 @@ class FeedItem /** * Set ord * - * @param \int $ord + * @param integer $ord * @return FeedItem */ - public function setOrd(\int $ord) + public function setOrd($ord) { $this->ord = $ord; - + return $this; } /** * Get ord * - * @return \int + * @return integer */ public function getOrd() { @@ -155,14 +155,14 @@ class FeedItem public function setCreatedOn($createdOn) { $this->created_on = $createdOn; - + return $this; } /** * Get created_on * - * @return \DateTime + * @return \DateTime */ public function getCreatedOn() { @@ -178,17 +178,22 @@ class FeedItem 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 setLastInFeedItem() + { + $this->setOrd($this->getEntry()->getItems()->count() + 1); + } } \ No newline at end of file diff --git a/lib/classes/eventsmanager/notify/feed.php b/lib/classes/eventsmanager/notify/feed.php index 7d4eb3ee44..55783d5bb8 100644 --- a/lib/classes/eventsmanager/notify/feed.php +++ b/lib/classes/eventsmanager/notify/feed.php @@ -45,7 +45,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract public function fire($event, $params, &$entry) { $params = array( - 'entry_id' => $entry->get_id() + 'entry_id' => $entry->getId() ); $dom_xml = new DOMDocument('1.0', 'UTF-8'); @@ -72,13 +72,18 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract ->include_templates(false) ->email_not_null(true); - if ($entry->get_feed()->get_collection()) { - $Query->on_base_ids(array($entry->get_feed()->get_collection()->get_base_id())); + if ($entry->getFeed()->getCollection($this->app)) { + $Query->on_base_ids(array($entry->getFeed()->getCollection($this->app)->get_base_id())); } $start = 0; $perLoop = 100; + $from = array( + 'email' => $entry->getAuthorEmail(), + 'name' => $entry->getAuthorName() + ); + do { $results = $Query->limit($start, $perLoop)->execute()->get_results(); @@ -93,7 +98,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract \random::TYPE_FEED_ENTRY , $user_to_notif->get_id() , null - , $entry->get_id() + , $entry->getId() ); $url = $this->app->url('lightbox', array('LOG' => $token)); @@ -107,8 +112,8 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract if ($readyToSend) { $mail = MailInfoNewPublication::create($this->app, $receiver); $mail->setButtonUrl($url); - $mail->setAuthor($entry->get_author_name()); - $mail->setTitle($entry->get_title()); + $mail->setAuthor($entry->getAuthorName()); + $mail->setTitle($entry->getTitle()); $this->app['notification.deliverer']->deliver($mail); $mailed = true; @@ -116,6 +121,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract } $this->broker->notify($user_to_notif->get_id(), __CLASS__, $datas, $mailed); + } $start += $perLoop; } while (count($results) > 0); @@ -134,16 +140,20 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract $sx = simplexml_load_string($datas); try { - $entry = \Feed_Entry_Adapter::load_from_id($this->app, (int) $sx->entry_id); + $entry = $this->app['EM']->getRepository("Entities\FeedEntry")->find((int) $sx->entry_id); } catch (\Exception $e) { return array(); } + if (null === $entry) { + return array(); + } + $ret = array( 'text' => sprintf( _('%1$s has published %2$s') - , $entry->get_author_name() - , '' . $entry->get_title() . '' + , $entry->getAuthorName() + , '' . $entry->getTitle() . '' ) , 'class' => ($unread == 1 ? 'reload_baskets' : '') ); diff --git a/templates/web/lightbox/feed.html.twig b/templates/web/lightbox/feed.html.twig index b5ea76a30d..42afbaa452 100644 --- a/templates/web/lightbox/feed.html.twig +++ b/templates/web/lightbox/feed.html.twig @@ -27,8 +27,8 @@

{% if first_item %}{{first_item.get_ord()}}{% endif %}
-
- {% if first_item %}{{first_item.get_record().get_title|raw}}{% endif %} +
+ {% if first_item %}{{first_item.get_record().getTitle|raw}}{% endif %}
@@ -43,9 +43,9 @@