diff --git a/bower.json b/bower.json index af8d62cb85..160b1c6703 100644 --- a/bower.json +++ b/bower.json @@ -22,7 +22,8 @@ "zxcvbn": "https://github.com/lowe/zxcvbn.git", "geonames-server-jquery-plugin": "~0.2", "swfobject": "latest", - "tinymce": "~4.0" + "tinymce": "~4.0", + "jquery-galleria": "1.2.9" }, "devDependencies": { "mocha": "latest", diff --git a/lib/Alchemy/Phrasea/Controller/Permalink.php b/lib/Alchemy/Phrasea/Controller/Permalink.php index 5c57aafde9..5464d7a154 100644 --- a/lib/Alchemy/Phrasea/Controller/Permalink.php +++ b/lib/Alchemy/Phrasea/Controller/Permalink.php @@ -31,14 +31,24 @@ class Permalink extends AbstractDelivery $that = $this; - $deliverPermaview = function($sbas_id, $record_id, $token, $subdef, PhraseaApplication $app) { + $retrieveRecord = function ($app, $databox, $token, $record_id, $subdef) { + if (in_array($subdef, array(\databox_subdef::CLASS_PREVIEW, \databox_subdef::CLASS_THUMBNAIL)) && $app['EM']->getRepository('Entities\FeedItem')->isRecordInPublicFeed($app, $databox->get_sbas_id(), $record_id)) { + $record = $databox->get_record($record_id); + } else { + $record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef); + + if (!($record instanceof \record_adapter)) { + throw new NotFoundHttpException('Wrong token.'); + } + } + + return $record; + }; + + $deliverPermaview = function($sbas_id, $record_id, $token, $subdef, PhraseaApplication $app) use ($retrieveRecord) { $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef); - - if (!$record instanceof \record_adapter) { - throw new NotFoundHttpException('bad luck'); - } + $record = $retrieveRecord($app, $databox, $token, $record_id, $subdef); $params = array( 'subdef_name' => $subdef @@ -51,13 +61,10 @@ class Permalink extends AbstractDelivery return $app['twig']->render('overview.html.twig', $params); }; - $deliverPermalink = function(PhraseaApplication $app, $sbas_id, $record_id, $token, $subdef) use ($that) { + $deliverPermalink = function(PhraseaApplication $app, $sbas_id, $record_id, $token, $subdef) use ($that, $retrieveRecord) { $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef); - if (!($record instanceof \record_adapter)) { - throw new NotFoundHttpException('bad luck'); - } + $record = $retrieveRecord($app, $databox, $token, $record_id, $subdef); $watermark = $stamp = false; @@ -106,15 +113,11 @@ class Permalink extends AbstractDelivery return $response; }; - $controllers->get('/v1/{sbas_id}/{record_id}/caption/', function(PhraseaApplication $app, Request $request, $sbas_id, $record_id) { + $controllers->get('/v1/{sbas_id}/{record_id}/caption/', function(PhraseaApplication $app, Request $request, $sbas_id, $record_id) use ($retrieveRecord) { $token = $request->query->get('token'); $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - $record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, 'thumbnail'); - if (null === $record) { - throw new NotFoundHttpException("Caption not found"); - } + $record = $retrieveRecord($app, $databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL); $caption = $record->get_caption(); return new Response($caption->serialize(\caption_record::SERIALIZE_JSON), 200, array("Content-Type" => 'application/json')); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php index 730f42a697..84f68e14e9 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php @@ -93,7 +93,7 @@ class Feed implements ControllerProviderInterface $app['EM']->persist($feed); $app['EM']->flush(); - $app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId()), $entry); + $app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry->getId(), 'notify_email' => (Boolean) $request->request->get('notify')), $entry); $datas = array('error' => false, 'message' => false); diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index e70af6d6e9..2266c4ef76 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -49,7 +49,22 @@ class Login implements ControllerProviderInterface { public static function getDefaultTemplateVariables(Application $app) { + $items = array(); + + foreach($app['EM']->getRepository('Entities\FeedItem')->loadLatest($app, 20) as $item) { + $record = $item->getRecord($app); + $preview = $record->get_subdef('preview'); + $permalink = $preview->get_permalink(); + + $items[] = array( + 'record' => $record, + 'preview' => $preview, + 'permalink' => $permalink + ); + } + return array( + 'last_publication_items' => $items, 'instance_title' => $app['phraseanet.registry']->get('GV_homeTitle'), 'has_terms_of_use' => $app->hasTermsOfUse(), 'meta_description' => $app['phraseanet.registry']->get('GV_metaDescription'), diff --git a/lib/Doctrine/Repositories/FeedItemRepository.php b/lib/Doctrine/Repositories/FeedItemRepository.php index 3bcb8e9d9a..7203bd3582 100644 --- a/lib/Doctrine/Repositories/FeedItemRepository.php +++ b/lib/Doctrine/Repositories/FeedItemRepository.php @@ -2,6 +2,7 @@ namespace Repositories; +use Alchemy\Phrasea\Application; use Doctrine\ORM\EntityRepository; /** @@ -12,4 +13,73 @@ use Doctrine\ORM\EntityRepository; */ class FeedItemRepository extends EntityRepository { + /** + * Checks if a record is published in a public feed. + * + * @param Application $app + * @param integer $sbas_id + * @param integer $record_id + * + * @return Boolean + */ + public function isRecordInPublicFeed(Application $app, $sbas_id, $record_id) + { + $dql = 'SELECT i + FROM Entities\FeedItem i + JOIN i.entry e + JOIN e.feed f + WHERE i.sbasId = :sbas_id + AND i.recordId = :record_id + AND f.public = true'; + + $query = $this->_em->createQuery($dql); + $query->setParameters(array('sbas_id' => $sbas_id, 'record_id' => $record_id)); + + return count($query->getResult()) > 0; + } + + /** + * Gets latest items from public feeds. + * + * @param Application $app + * @param integer $nbItems + * + * @return FeedItem[] An array of FeedItem + */ + public function loadLatest(Application $app, $nbItems = 20) + { + $execution = 0; + $items = array(); + + do { + $dql = 'SELECT i + FROM Entities\FeedItem i + JOIN i.entry e + JOIN e.feed f + WHERE f.public = true ORDER BY i.createdOn DESC'; + + $query = $this->_em->createQuery($dql); + $query + ->setFirstResult((integer) $nbItems * $execution) + ->setMaxResults((integer) $nbItems); + + $result = $query->getResult(); + + foreach($result as $item) { + if (null !== $preview = $item->getRecord($app)->get_subdef('preview')) { + if (null !== $permalink = $preview->get_permalink()) { + $items[] = $item; + + if (count($items) >= $nbItems) { + break; + } + } + } + } + + $execution++; + } while (count($items) < $nbItems && count($result) !== 0); + + return $items; + } } diff --git a/lib/classes/ACL.php b/lib/classes/ACL.php index a88d474787..ab3bffcae6 100644 --- a/lib/classes/ACL.php +++ b/lib/classes/ACL.php @@ -119,6 +119,11 @@ class ACL implements cache_cacheableInterface return $this; } + public function set_app(Application $app) + { + $this->app = $app; + } + /** * Check if a hd grant has been received for a record * @@ -253,6 +258,10 @@ class ACL implements cache_cacheableInterface $granted = true; } + if (false === $granted && $this->app['EM']->getRepository('Entities\FeedItem')->isRecordInPublicFeed($this->app, $record->get_sbas_id(), $record->get_record_id())) { + $granted = true; + } + return $granted; } diff --git a/lib/classes/User/Adapter.php b/lib/classes/User/Adapter.php index a874a0bfff..ad8c760978 100644 --- a/lib/classes/User/Adapter.php +++ b/lib/classes/User/Adapter.php @@ -327,6 +327,8 @@ class User_Adapter implements User_Interface, cache_cacheableInterface self::$_instance[$id] = new self($id, $app); $app['phraseanet.appbox']->set_data_to_cache(self::$_instance[$id], '_user_' . $id); } + } else { + self::$_instance[$id]->set_app($app); } return array_key_exists($id, self::$_instance) ? self::$_instance[$id] : false; @@ -349,6 +351,9 @@ class User_Adapter implements User_Interface, cache_cacheableInterface protected function set_app(Application $app) { $this->app = $app; + if (null !== $this->ACL) { + $this->ACL->set_app($app); + } } /** @@ -1074,6 +1079,8 @@ class User_Adapter implements User_Interface, cache_cacheableInterface } } + $this->load_notifications_preferences($this->app); + return $this; } @@ -1090,22 +1097,18 @@ class User_Adapter implements User_Interface, cache_cacheableInterface } } } - $this->notification_preferences_loaded = true; } - protected $notifications_preferences_loaded = false; public function get_notifications_preference(Application $app, $notification_id) { - if (!$this->notifications_preferences_loaded) - $this->load_notifications_preferences($app); + $this->load_preferences($app); - return $this->_prefs['notification_' . $notification_id]; + return isset($this->_prefs['notification_' . $notification_id]) ? $this->_prefs['notification_' . $notification_id] : null; } public function set_notification_preference(Application $app, $notification_id, $value) { - if (!$this->notifications_preferences_loaded) - $this->load_notifications_preferences($app); + $this->load_preferences($app); return $this->_prefs['notification_' . $notification_id] = $value ? '1' : '0'; } diff --git a/lib/classes/databox/field.php b/lib/classes/databox/field.php index 4790ba138d..6774be8752 100644 --- a/lib/classes/databox/field.php +++ b/lib/classes/databox/field.php @@ -285,6 +285,7 @@ class databox_field implements cache_cacheableInterface $databox->set_data_to_cache(self::$_instance[$instance_id], $cache_key); } } + self::$_instance[$instance_id]->app = $app; return self::$_instance[$instance_id]; } diff --git a/lib/classes/eventsmanager/notify/feed.php b/lib/classes/eventsmanager/notify/feed.php index 6caf6ce81b..50140861bf 100644 --- a/lib/classes/eventsmanager/notify/feed.php +++ b/lib/classes/eventsmanager/notify/feed.php @@ -45,7 +45,8 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract public function fire($event, $params, &$entry) { $params = array( - 'entry_id' => $entry->getId() + 'entry_id' => $entry->getId(), + 'notify_email' => $params['notify_email'], ); $dom_xml = new DOMDocument('1.0', 'UTF-8'); @@ -91,7 +92,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract /* @var $user_to_notif \User_Adapter */ $mailed = false; - if ($this->shouldSendNotificationFor($user_to_notif->get_id())) { + if ($params['notify_email'] && $this->shouldSendNotificationFor($user_to_notif->get_id())) { $readyToSend = false; try { $token = $this->app['tokens']->getUrlToken( diff --git a/lib/classes/eventsmanager/notifyAbstract.php b/lib/classes/eventsmanager/notifyAbstract.php index df9a1ef5d9..272a7f82a3 100644 --- a/lib/classes/eventsmanager/notifyAbstract.php +++ b/lib/classes/eventsmanager/notifyAbstract.php @@ -26,7 +26,7 @@ abstract class eventsmanager_notifyAbstract extends eventsmanager_eventAbstract protected function get_prefs($class, $usr_id) { $user = User_Adapter::getInstance($usr_id, $this->app); - $pref = $user->getPrefs('notification_' . $class); + $pref = $user->get_notifications_preference($this->app, $class); return null !== $pref ? $pref : 1; } diff --git a/lib/conf.d/PhraseaFixture/Feed/LoadOneFeed.php b/lib/conf.d/PhraseaFixture/Feed/LoadOneFeed.php index c45fd6615e..61e9e8aec9 100644 --- a/lib/conf.d/PhraseaFixture/Feed/LoadOneFeed.php +++ b/lib/conf.d/PhraseaFixture/Feed/LoadOneFeed.php @@ -47,9 +47,7 @@ class LoadOneFeed extends AbstractFixture implements FixtureInterface $feed->setTitle("test"); } - if (isset($this->public) && $this->public !== null) { - $feed->setIsPublic($this->public); - } + $feed->setIsPublic((Boolean) $this->public); $feed->setSubtitle("description"); diff --git a/lib/conf.d/_GV_template.inc b/lib/conf.d/_GV_template.inc index 2bf9d89cc9..62c401375a 100644 --- a/lib/conf.d/_GV_template.inc +++ b/lib/conf.d/_GV_template.inc @@ -348,7 +348,9 @@ return call_user_func_array(function(Application $app) { 'available' => array( 'DISPLAYx1' => _('Single image'), 'SCROLL' => _('Slide show'), - 'COOLIRIS' => 'Cooliris' + 'COOLIRIS' => 'Cooliris', + 'CAROUSEL' => _('Carousel'), + 'GALLERIA' => _('Gallery') ), 'required' => true ) diff --git a/templates/web/login/include/carousel.html.twig b/templates/web/login/include/carousel.html.twig new file mode 100644 index 0000000000..1fdb8aa05d --- /dev/null +++ b/templates/web/login/include/carousel.html.twig @@ -0,0 +1,16 @@ +
+ + diff --git a/templates/web/login/include/galleria.html.twig b/templates/web/login/include/galleria.html.twig new file mode 100644 index 0000000000..b4752d36fb --- /dev/null +++ b/templates/web/login/include/galleria.html.twig @@ -0,0 +1,25 @@ +