Merge branch 'feeds-entities' of https://github.com/csaoh/Phraseanet

This commit is contained in:
Romain Neutron
2013-09-12 13:53:56 +02:00
133 changed files with 6726 additions and 7091 deletions

View File

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

View File

@@ -12,6 +12,8 @@
namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Entities\Feed;
use Entities\FeedPublisher;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -35,9 +37,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']
@@ -45,22 +46,40 @@ class Publications implements ControllerProviderInterface
})->bind('admin_feeds_list');
$controllers->post('/create/', function(PhraseaApplication $app, Request $request) {
if ('' === $title = trim($request->request->get('title', ''))) {
$app->abort(400, "Bad request");
}
$feed = \Feed_Adapter::create(
$app, $app['authentication']->getUser(), $request->request->get('title'), $request->request->get('subtitle')
);
$publisher = new FeedPublisher();
$feed = new Feed();
$publisher->setFeed($feed);
$publisher->setUsrId($app['authentication']->getUser()->get_id());
$publisher->setIsOwner(true);
$feed->addPublisher($publisher);
$feed->setTitle($title);
$feed->setSubtitle($request->request->get('subtitle', ''));
if ($request->request->get('public') == '1') {
$feed->set_public(true);
$feed->setIsPublic(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"]->find('Entities\Feed', $id);
return $app['twig']
->render('admin/publications/fiche.html.twig', array('feed' => $feed, 'error' => $app['request']->query->get('error')));
@@ -70,24 +89,29 @@ class Publications implements ControllerProviderInterface
$controllers->post('/feed/{id}/update/', function(PhraseaApplication $app, Request $request, $id) {
$feed = new \Feed_Adapter($app, $id);
if ('' === $title = trim($request->request->get('title', ''))) {
$app->abort(400, "Bad request");
}
$feed = $app["EM"]->find('Entities\Feed', $id);
try {
$collection = \collection::get_from_base_id($app, $request->request->get('base_id'));
} catch (\Exception $e) {
$collection = null;
}
$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'));
$feed->setTitle($title);
$feed->setSubtitle($request->request->get('subtitle', ''));
$feed->setCollection($collection);
$feed->setIsPublic('1' === $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"]->find('Entities\Feed', $request->attributes->get('id'));
if (!$feed->is_owner($app['authentication']->getUser())) {
if (!$feed->isOwner($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,15 +123,16 @@ class Publications implements ControllerProviderInterface
'success' => false,
'message' => '',
);
$feed = $app["EM"]->find('Entities\Feed', $id);
$feed = new \Feed_Adapter($app, $id);
if (null === $feed) {
$app->abort(404, "Feed not found");
}
$request = $app["request"];
if (!$feed->is_owner($app['authentication']->getUser())) {
$datas['message'] = 'You are not allowed to do that';
return $app->json($datas);
if (!$feed->isOwner($app['authentication']->getUser())) {
$app->abort(403, "Access Forbidden");
}
try {
@@ -146,10 +171,15 @@ class Publications implements ControllerProviderInterface
throw new \Exception_InternalServerError('Error while resizing');
}
$feed->set_icon($tmpname);
unset($media);
$feed->setIconUrl(true);
$app['EM']->persist($feed);
$app['EM']->flush();
$app['filesystem']->copy($tmpname, $app['root.path'] . '/config/feed_' . $feed->getId() . '.jpg');
$app['filesystem']->copy($tmpname, sprintf('%s/www/custom/feed_%d.jpg', $app['root.path'], $feed->getId()));
$app['filesystem']->remove($tmpname);
$datas['success'] = true;
@@ -167,10 +197,20 @@ 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"]->find('Entities\Feed', $id);
$publisher = new FeedPublisher();
$publisher->setUsrId($user->get_id());
$publisher->setFeed($feed);
$feed->addPublisher($publisher);
$app['EM']->persist($feed);
$app['EM']->persist($publisher);
$app['EM']->flush();
} catch (\Exception $e) {
$error = $e->getMessage();
$error = "An error occured";
}
return $app->redirectPath('admin_feeds_feed', array('id' => $id, 'error' => $error));
@@ -182,13 +222,22 @@ 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"]->find('Entities\Feed', $id);
$publisher = $app["EM"]->find('Entities\FeedPublisher', $request->request->get('publisher_id'));
if (null === $publisher) {
$app->abort(404, "Feed Publisher not found");
}
$user = $publisher->getUser($app);
if ($feed->isPublisher($user) && !$feed->isOwner($user)) {
$feed->removePublisher($publisher);
$app['EM']->remove($publisher);
$app['EM']->flush();
}
} catch (\Exception $e) {
$error = $e->getMessage();
$error = "An error occured";
}
return $app->redirectPath('admin_feeds_feed', array('id' => $id, 'error' => $error));
@@ -197,8 +246,19 @@ 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"]->find('Entities\Feed', $id);
if (null === $feed) {
$app->abort(404);
}
if (true === $feed->getIconURL()) {
unlink($app['root.path'] . '/config/feed_' . $feed->getId() . '.jpg');
unlink('custom/feed_' . $feed->getId() . '.jpg');
}
$app['EM']->remove($feed);
$app['EM']->flush();
return $app->redirectPath('admin_feeds_list');
})

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Controller\Client;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\Exception\SessionNotFound;
use Entities\UserQuery;
@@ -539,7 +540,7 @@ class Root implements ControllerProviderInterface
private function getPublicationStartPage(Application $app)
{
return $app['twig']->render('client/home_inter_pub_basket.html.twig', array(
'feeds' => \Feed_Collection::load_all($app, $app['authentication']->getUser()),
'feeds' => Aggregate::createFromUser($app['EM'], $app['authentication']->getUser()),
'image_size' => (int) $app['authentication']->getUser()->getPrefs('images_size')
));
}

View File

@@ -160,13 +160,13 @@ 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 = $app['EM']->getRepository('Entities\FeedEntry')->find($entry_id);
$item = $entry->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($app)->get_title()
)
);
@@ -181,12 +181,12 @@ class Lightbox implements ControllerProviderInterface
}
$ret = array();
$ret['number'] = $item->get_record()->get_number();
$ret['title'] = $item->get_record()->get_title();
$ret['number'] = $item->getRecord($app)->get_number();
$ret['title'] = $item->getRecord($app)->get_title();
$ret['preview'] = $app['twig']->render($template_preview, array('record' => $item->get_record(), 'not_wrapped' => true));
$ret['preview'] = $app['twig']->render($template_preview, array('record' => $item->getRecord($app), 'not_wrapped' => true));
$ret['options_html'] = $app['twig']->render($template_options, array('feed_element' => $item));
$ret['caption'] = $app['twig']->render($template_caption, array('view' => 'preview', 'record' => $item->get_record()));
$ret['caption'] = $app['twig']->render($template_caption, array('view' => 'preview', 'record' => $item->getRecord($app)));
$ret['agreement_html'] = $ret['selector_html'] = $ret['note_html'] = '';
@@ -313,7 +313,7 @@ class Lightbox implements ControllerProviderInterface
return $app->redirectPath('logout');
}
$feed_entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id);
$feed_entry = $app['EM']->getRepository('Entities\FeedEntry')->find($entry_id);
$template = 'lightbox/feed.html.twig';
@@ -321,12 +321,13 @@ class Lightbox implements ControllerProviderInterface
$template = 'lightbox/IE6/feed.html.twig';
}
$content = $feed_entry->get_content();
$content = $feed_entry->getItems();
$first = $content->first();
$output = $app['twig']->render($template, array(
'feed_entry' => $feed_entry,
'first_item' => array_shift($content),
'local_title' => $feed_entry->get_title(),
'first_item' => $first,
'local_title' => $feed_entry->getTitle(),
'module' => 'lightbox',
'module_name' => _('admin::monitor: module validation')
)

View File

@@ -12,12 +12,16 @@
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Controller\RecordsRequest;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator;
use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator;
use Entities\FeedEntry;
use Entities\FeedItem;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
@@ -39,7 +43,7 @@ class Feed implements ControllerProviderInterface
* I got a selection of docs, which publications are available forthese docs ?
*/
$controllers->post('/requestavailable/', function(Application $app, Request $request) {
$feeds = \Feed_Collection::load_all($app, $app['authentication']->getUser());
$feeds = $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));
@@ -49,26 +53,49 @@ class Feed implements ControllerProviderInterface
* I've selected a publication for my docs, let's publish them
*/
$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'));
$title = $request->request->get('title');
$subtitle = $request->request->get('subtitle');
$author_name = $request->request->get('author_name');
$author_mail = $request->request->get('author_mail');
if (null === $feed) {
$app->abort(404, "Feed not found");
}
$entry = \Feed_Entry_Adapter::create($app, $feed, $publisher, $title, $subtitle, $author_name, $author_mail);
$publisher = $app['EM']->getRepository('Entities\FeedPublisher')->findOneBy(array('feed' => $feed, 'usrId' => $app['authentication']->getUser()->get_id()));
if ('' === $title = trim($request->request->get('title', ''))) {
$app->abort(400, "Bad request");
}
if (!$feed->isPublisher($app['authentication']->getUser())) {
$app->abort(403, 'Unathorized action');
}
$entry = new FeedEntry();
$entry->setAuthorEmail($request->request->get('author_mail'))
->setAuthorName($request->request->get('author_name'))
->setTitle($title)
->setFeed($feed)
->setPublisher($publisher)
->setSubtitle($request->request->get('subtitle', ''));
$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 FeedItem();
$item->setEntry($entry)
->setRecordId($record->get_record_id())
->setSbasId($record->get_sbas_id());
$entry->addItem($item);
$app['EM']->persist($item);
}
$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());
}
return $app->json($datas);
})
@@ -78,13 +105,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')->getAllForUser($app['authentication']->getUser());
$datas = $app['twig']->render('prod/actions/publish/publish_edit.html.twig', array('entry' => $entry, 'feeds' => $feeds));
@@ -98,39 +125,37 @@ class Feed implements ControllerProviderInterface
$controllers->post('/entry/{id}/update/', function(Application $app, Request $request, $id) {
$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())) {
throw new AccessDeniedHttpException();
if (null === $entry) {
$app->abort(404, 'Entry not found');
}
if (!$entry->isPublisher($app['authentication']->getUser())) {
$app->abort(403, 'Unathorized action');
}
if ('' === $title = trim($request->request->get('title', ''))) {
$app->abort(400, "Bad request");
}
$title = $request->request->get('title');
$subtitle = $request->request->get('subtitle');
$author_name = $request->request->get('author_name');
$author_mail = $request->request->get('author_mail');
$entry->setAuthorEmail($request->request->get('author_mail'))
->setAuthorName($request->request->get('author_name'))
->setTitle($title)
->setSubtitle($request->request->get('subtitle', ''));
$entry->set_author_email($author_mail)
->set_author_name($author_name)
->set_title($title)
->set_subtitle($subtitle);
$currentFeedId = $entry->getFeed()->getId();
$new_feed_id = $request->request->get('feed_id', $currentFeedId);
if ($currentFeedId !== (int) $new_feed_id) {
$current_feed_id = $entry->get_feed()->get_id();
$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);
} catch (NotFoundHttpException $e) {
throw new AccessDeniedHttpException('You have no access to this feed');
$new_feed = $app['EM']->getRepository('Entities\Feed')->find($new_feed_id);
if ($new_feed === null) {
$app->abort(404, 'Feed not found');
}
if (!$new_feed->is_publisher($app['authentication']->getUser())) {
throw new AccessDeniedHttpException('You are not publisher of this feed');
if (!$new_feed->isPublisher($app['authentication']->getUser())) {
$app->abort(403, 'You are not publisher of this feed');
}
$entry->set_feed($new_feed);
$entry->setFeed($new_feed);
}
$items = explode(';', $request->request->get('sorted_lst'));
@@ -140,31 +165,21 @@ class Feed implements ControllerProviderInterface
if (count($item_sort_datas) != 2) {
continue;
}
$item = new \Feed_Entry_Item($app['phraseanet.appbox'], $entry, $item_sort_datas[0]);
$item->set_ord($item_sort_datas[1]);
}
$app['phraseanet.appbox']->get_connection()->commit();
$entry = $app['twig']->render('prod/feeds/entry.html.twig', array('entry' => $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();
$item = $app['EM']->getRepository('Entities\FeedItem')->find($item_sort_datas[0]);
$item->setOrd($item_sort_datas[1]);
$app['EM']->persist($item);
}
return $app->json($datas);
$app['EM']->persist($entry);
$app['EM']->flush();
return $app->json(array(
'error' => false,
'message' => 'succes',
'datas' => $app['twig']->render('prod/feeds/entry.html.twig', array(
'entry' => $entry
))
));
})
->bind('prod_feeds_entry_update')
->assert('id', '\d+')->before(function(Request $request) use ($app) {
@@ -173,31 +188,22 @@ class Feed implements ControllerProviderInterface
$controllers->post('/entry/{id}/delete/', function(Application $app, Request $request, $id) {
$datas = array('error' => true, 'message' => '');
try {
$app['phraseanet.appbox']->get_connection()->beginTransaction();
$entry = \Feed_Entry_Adapter::load_from_id($app, $id);
$entry = $app['EM']->getRepository('Entities\FeedEntry')->find($id);
if (!$entry->is_publisher($app['authentication']->getUser())
&& $entry->get_feed()->is_owner($app['authentication']->getUser()) === false) {
throw new AccessDeniedHttpException(_('Action Forbidden : You are not the publisher'));
if (null === $entry) {
$app->abort(404, 'Entry not found');
}
if (!$entry->isPublisher($app['authentication']->getUser()) && $entry->getFeed()->isOwner($app['authentication']->getUser()) === false) {
$app->abort(403, _('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['message'] = _('Feed entry not found');
} catch (\Exception $e) {
$app['phraseanet.appbox']->get_connection()->rollBack();
$datas['message'] = $e->getMessage();
}
return $app->json($datas);
return $app->json(array('error' => false, 'message' => 'succes'));
})
->bind('feed_entry_delete')
->bind('prod_feeds_entry_delete')
->assert('id', '\d+')->before(function(Request $request) use ($app) {
$app['firewall']->requireRight('bas_chupub');
});
@@ -207,15 +213,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')->getAllForUser($app['authentication']->getUser());
$datas = $app['twig']->render('prod/feeds/feeds.html.twig'
, array(
'feeds' => $feeds
, 'feed' => $feeds->get_aggregate()
, 'page' => $page
)
);
$datas = $app['twig']->render('prod/feeds/feeds.html.twig', array(
'feeds' => $feeds,
'feed' => new Aggregate($app['EM'], $feeds),
'page' => $page
));
return new Response($datas);
})->bind('prod_feeds');
@@ -224,8 +228,11 @@ 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')->find($id);
if (!$feed->isAccessible($app['authentication']->getUser(), $app)) {
$app->abort(404, 'Feed not found');
}
$feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser());
$datas = $app['twig']->render('prod/feeds/feeds.html.twig', array('feed' => $feed, 'feeds' => $feeds, 'page' => $page));
@@ -237,12 +244,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')->getAllForUser($app['authentication']->getUser());
$link = $app['feed.aggregate-link-generator']->generate(new Aggregate($app['EM'], $feeds),
$app['authentication']->getUser(),
AggregateLinkGenerator::FORMAT_RSS,
null, $renew
);
$output = array(
'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.')
. '</p><p>' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '</p>
<div><input type="text" readonly="readonly" class="input_select_copy" value="' . $feeds->get_aggregate()->get_user_link($app['phraseanet.registry'], $app['authentication']->getUser(), \Feed_Adapter::FORMAT_RSS, null, $renew)->get_href() . '"/></div>',
<div><input type="text" readonly="readonly" class="input_select_copy" value="' . $link->getURI() . '"/></div>',
'titre' => _('publications::votre rss personnel')
);
@@ -251,12 +264,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')->find($id);
if (!$feed->isAccessible($app['authentication']->getUser(), $app)) {
$app->abort(404, 'Feed not found');
}
$link = $app['feed.user-link-generator']->generate($feed, $app['authentication']->getUser(), FeedLinkGenerator::FORMAT_RSS, null, $renew);
$output = array(
'texte' => '<p>' . _('publication::Voici votre fil RSS personnel. Il vous permettra d\'etre tenu au courrant des publications.')
. '</p><p>' . _('publications::Ne le partagez pas, il est strictement confidentiel') . '</p>
<div><input type="text" style="width:100%" value="' . $feed->get_user_link($app['phraseanet.registry'], $app['authentication']->getUser(), \Feed_Adapter::FORMAT_RSS, null, $renew)->get_href() . '"/></div>',
<div><input type="text" style="width:100%" value="' . $link->getURI() . '"/></div>',
'titre' => _('publications::votre rss personnel')
);

View File

@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Exception\SessionNotFound;
use Alchemy\Phrasea\Feed\Aggregate;
use Silex\Application as SilexApplication;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -72,8 +73,8 @@ 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());
$feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($app['authentication']->getUser());
$aggregate = Aggregate::createFromUser($app['EM'], $app['authentication']->getUser());
$thjslist = "";
@@ -116,6 +117,7 @@ class Root implements ControllerProviderInterface
'cgus_agreement' => \databox_cgu::askAgreement($app),
'css' => $css,
'feeds' => $feeds,
'aggregate' => $aggregate,
'GV_google_api' => $app['phraseanet.registry']->get('GV_google_api'),
'queries_topics' => $queries_topics,
'search_status' => \databox_status::getSearchStatus($app),

View File

@@ -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')->findBy(array('public' => true), array('updatedOn' => 'DESC'));
$form = $app->form(new PhraseaAuthenticationForm());
$form->setData(array(

View File

@@ -11,7 +11,8 @@
namespace Alchemy\Phrasea\Controller\Root;
use Symfony\Component\HttpFoundation\Response;
use Entities\Feed;
use Alchemy\Phrasea\Feed\Aggregate;
use Silex\Application;
use Silex\ControllerProviderInterface;
@@ -27,60 +28,15 @@ class RSSFeeds implements ControllerProviderInterface
{
$controllers = $app['controllers_factory'];
$display_feed = function(Application $app, $feed, $format, $page, $user = null) {
$total = $feed->get_count_total_entries();
$perPage = 5;
$entries = $feed->get_entries((($page - 1) * $perPage), $perPage);
$controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) {
$feed = $app['EM']->getRepository('Entities\Feed')->find($id);
if ($format == \Feed_Adapter::FORMAT_RSS) {
$content = new \Feed_XML_RSS();
if (null === $feed) {
$app->abort(404, 'Feed not found');
}
if ($format == \Feed_Adapter::FORMAT_ATOM) {
$content = new \Feed_XML_Atom();
}
if ($format == \Feed_Adapter::FORMAT_COOLIRIS) {
$content = new \Feed_XML_Cooliris();
}
if ($user instanceof \User_Adapter)
$link = $feed->get_user_link($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_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)));
if ($total > ($page * $perPage))
$content->set_next_page($feed->get_user_link($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)
$content->set_item($entry);
$render = $content->render();
$response = new Response($render, 200, array('Content-Type' => $content->get_mimetype()));
$response->setCharset('UTF-8');
return $response;
};
$controllers->get('/feed/{id}/{format}/', function(Application $app, $id, $format) use ($display_feed) {
$feed = new \Feed_Adapter($app, $id);
if (!$feed->is_public()) {
return new Response('Forbidden', 403);
if (!$feed->isPublic()) {
$app->abort(403, 'Forbidden');
}
$request = $app['request'];
@@ -88,63 +44,66 @@ class RSSFeeds implements ControllerProviderInterface
$page = (int) $request->query->get('page');
$page = $page < 1 ? 1 : $page;
return $display_feed($app, $feed, $format, $page);
return $app['feed.formatter-strategy']($format)->createResponse($feed, $page);
})
->bind('feed_public')
->assert('id', '\d+')
->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();
$controllers->get('/userfeed/{token}/{id}/{format}/', function(Application $app, $token, $id, $format) {
$token = $app["EM"]->find('Entities\FeedToken', $id);
$request = $app['request'];
$page = (int) $request->query->get('page');
$page = $page < 1 ? 1 : $page;
return $display_feed($app, $feed, $format, $page, $token->get_user());
return $app['feed.formatter-strategy']($format)
->createResponse($token->getFeed(), $page, \User_Adapter::getInstance($token->getUsrId(), $app));
})
->bind('feed_user')
->assert('id', '\d+')
->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();
$controllers->get('/userfeed/aggregated/{token}/{format}/', function(Application $app, $token, $format) {
$token = $app['EM']->getRepository('Entities\AggregateToken')->findOneBy(array("value" => $token));
$user = \User_Adapter::getInstance($token->getUsrId(), $app);
$feeds = $app['EM']->getRepository('Entities\Feed')->getAllForUser($user);
$aggregate = new Aggregate($app['EM'], $feeds, $token);
$request = $app['request'];
$page = (int) $request->query->get('page');
$page = $page < 1 ? 1 : $page;
return $display_feed($app, $feed, $format, $page, $token->get_user());
return $app['feed.formatter-strategy']($format)->createResponse($aggregate, $page, $user);
})
->bind('feed_user_aggregated')
->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();
$controllers->get('/aggregated/{format}/', function(Application $app, $format) {
$feed = Aggregate::getPublic($app);
$request = $app['request'];
$page = (int) $request->query->get('page');
$page = $page < 1 ? 1 : $page;
return $display_feed($app, $feed, $format, $page);
return $app['feed.formatter-strategy']($format)->createResponse($feed, $page);
})
->bind('feed_public_aggregated')
->assert('format', '(rss|atom)');
$controllers->get('/cooliris/', function(Application $app) use ($display_feed) {
$feeds = \Feed_Collection::load_public_feeds($app);
$feed = $feeds->get_aggregate();
$controllers->get('/cooliris/', function(Application $app) {
$feed = Aggregate::getPublic($app);
$request = $app['request'];
$page = (int) $request->query->get('page');
$page = $page < 1 ? 1 : $page;
return $display_feed($app, $feed, \Feed_Adapter::FORMAT_COOLIRIS, $page);
return $app['feed.formatter-strategy']('cooliris')->createResponse($feed, $page, null, 'Phraseanet', $app);
})
->bind('feed_public_cooliris');

View File

@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Setup\ConfigurationTester;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\PreSchemaUpgradeCollection;
use Silex\Application as SilexApplication;
use Silex\ServiceProviderInterface;
@@ -24,6 +25,10 @@ class ConfigurationTesterServiceProvider implements ServiceProviderInterface
$app['phraseanet.configuration-tester'] = $app->share(function(Application $app) {
return new ConfigurationTester($app);
});
$app['phraseanet.pre-schema-upgrader'] = $app->share(function () {
return new PreSchemaUpgradeCollection();
});
}
public function boot(SilexApplication $app)

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Feed\Formatter\AtomFormatter;
use Alchemy\Phrasea\Feed\Formatter\CoolirisFormatter;
use Alchemy\Phrasea\Feed\Formatter\RssFormatter;
use Alchemy\Phrasea\Feed\Link\AggregateLinkGenerator;
use Alchemy\Phrasea\Feed\Link\FeedLinkGenerator;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Silex\Application;
use Silex\ServiceProviderInterface;
class FeedServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['feed.user-link-generator'] = $app->share(function($app) {
return new FeedLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']);
});
$app['feed.aggregate-link-generator'] = $app->share(function($app) {
return new AggregateLinkGenerator($app['url_generator'], $app['EM'], $app['tokens']);
});
$app['feed.link-generator-collection'] = $app->share(function($app) {
$collection = new LinkGeneratorCollection();
$collection->pushGenerator($app['feed.user-link-generator']);
$collection->pushGenerator($app['feed.aggregate-link-generator']);
return $collection;
});
$app['feed.rss-formatter'] = $app->share(function($app) {
return new RssFormatter($app['feed.link-generator-collection']);
});
$app['feed.atom-formatter'] = $app->share(function($app) {
return new AtomFormatter($app['feed.link-generator-collection']);
});
$app['feed.cooliris-formatter'] = $app->share(function($app) {
return new CoolirisFormatter($app['feed.link-generator-collection']);
});
$app['feed.formatter-strategy'] = $app->protect(function($type) use ($app) {
switch ($type) {
case 'rss':
return $app['feed.rss-formatter'];
break;
case 'atom':
return $app['feed.atom-formatter'];
break;
case 'cooliris':
return $app['feed.cooliris-formatter'];
break;
default:
throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $type));
}
});
}
public function boot(Application $app)
{
}
}

View File

@@ -18,7 +18,7 @@ namespace Alchemy\Phrasea\Core;
*/
class Version
{
protected static $number = '3.9.0.a6';
protected static $number = '3.9.0.a7';
protected static $name = 'Diplodocus';
public static function getNumber()

View File

@@ -0,0 +1,240 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Exception\LogicException;
use Doctrine\ORM\EntityManager;
use Entities\AggregateToken;
class Aggregate implements FeedInterface
{
/** @var string */
private $title;
/** @var string */
private $subtitle;
/** @var DateTime */
private $createdOn;
/** @var DateTime */
private $updatedOn;
/** @var array */
private $feeds;
/** @var AggregateToken */
private $token;
/** @var EntityManager */
private $em;
/**
* @param EntityManager $em
* @param array $feeds
* @param AggregateToken $token
*
* @return Aggregate
*/
public function __construct(EntityManager $em, array $feeds, AggregateToken $token = null)
{
$this->title = 'AGGREGATE';
$this->subtitle = 'AGGREGATE SUBTITLE';
$this->createdOn = new \DateTime();
$this->updatedOn = new \DateTime();
$this->em = $em;
$tmp_feeds = array();
foreach ($feeds as $feed) {
$tmp_feeds[$feed->getId()] = $feed;
}
$this->feeds = $tmp_feeds;
$this->token = $token;
return $this;
}
/**
* Creates an aggregate from all the feeds available to a given user.
*
* @param EntityManager $em
* @param \User_Adapter $user
*
* @return Aggregate
*/
public static function createFromUser(EntityManager $em, \User_Adapter $user)
{
$feeds = $em->getRepository('Entities\Feed')->getAllForUser($user);
$token = $em->getRepository('Entities\AggregateToken')->findOneBy(array('usrId' => $user->get_id()));
return new static($em, $feeds, $token);
}
/**
* Creates an aggregate from given Feed id array.
*
* @param EntityManager $em
* @param array $feed_ids
*
* @return Aggregate
*/
public static function create(Application $app, array $feed_ids)
{
$feeds = $this->em->getRepository('Entities\Feed')->findByIds($feed_ids);
return new static($app, $feeds);
}
/**
* {@inheritdoc}
*/
public function isAggregated()
{
return true;
}
/**
* {@inheritdoc}
*/
public function getEntries($offset_start = null, $how_many = null)
{
if (0 === count($this->feeds)) {
return null;
}
$feedIds = array();
foreach ($this->feeds as $feed) {
$feedIds[] = $feed->getId();
}
return $this->em->getRepository('Entities\FeedEntry')->findByFeeds($feedIds, $offset_start, $how_many);
}
/**
* {@inheritdoc}
*/
public function getSubtitle()
{
return $this->subtitle;
}
/**
* {@inheritdoc}
*/
public function getTitle()
{
return $this->title;
}
/**
* {@inheritdoc}
*/
public function getIconUrl()
{
return false;
}
/**
* {@inheritdoc}
*/
public function getCreatedOn()
{
return $this->createdOn;
}
/**
* {@inheritdoc}
*/
public function getUpdatedOn()
{
return $this->updatedOn;
}
/**
* Get AggregateToken
*
* @return AggregateToken
*/
public function getToken()
{
return $this->token;
}
/**
* Set AggregateToken
*
* @param AggregateToken $token
*/
public function setToken($token)
{
$this->token = $token;
}
/**
* Get Feeds
*
* @return array
*/
public function getFeeds()
{
return $this->feeds;
}
/**
* Returns the total number of entries from all the feeds.
*
* @return int
*/
public function getCountTotalEntries()
{
if (count($this->feeds) > 0) {
$feedIds = array();
foreach ($this->feeds as $feed) {
$feedIds[] = $feed->getId();
}
return count($this->em->getRepository('Entities\FeedEntry')->findByFeeds($feedIds));
}
return 0;
}
/**
* {@inheritdoc}
*/
public function hasPage($pageNumber, $nbEntriesByPage)
{
if (0 >= $nbEntriesByPage) {
throw new LogicException;
}
$count = $this->getCountTotalEntries();
if (0 > $pageNumber && $pageNumber <= $count / $nbEntriesByPage) {
return true;
}
return false;
}
/**
* Creates an Aggregate from all the public feeds.
*
* @param Application $app
*
* @return Aggregate
*/
public static function getPublic(Application $app)
{
return new static($app['EM'], $app['EM']->getRepository('Entities\Feed')->findBy(array('public' => true), array('updatedOn' => 'DESC')));
}
}

View File

@@ -0,0 +1,112 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed;
use Alchemy\Phrasea\Feed\Aggregate;
/**
* AggregateToken
*/
class AggregateToken
{
/** @var integer */
private $id;
/** @var string */
private $usrId;
/** @var Aggregate */
private $aggregatedFeed;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set usr_id
*
* @param integer $usrId
* @return AggregateToken
*/
public function setUsrId($usrId)
{
$this->usrId = $usrId;
return $this;
}
/**
* Get usr_id
*
* @return integer
*/
public function getUsrId()
{
return $this->usrId;
}
/**
* Set feed
*
* @param Aggregate $feed
* @return AggregateToken
*/
public function setFeed(\Entities\Feed $feed = null)
{
$this->aggregatedFeed = $feed;
return $this;
}
/**
* Get feed
*
* @return Aggregate
*/
public function getFeed()
{
return $this->aggregatedFeed;
}
/**
* @var string
*/
private $value;
/**
* 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;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed;
interface FeedInterface
{
/**
* Returns a boolean indicating whether the feed has a custom icon.
*
* @return boolean
*/
public function getIconUrl();
/**
* Returns an UTF-8 title for the feed.
*
* @return string
*/
public function getTitle();
/**
* Returns a collection of FeedEntry.
*
* @param integer $offset_start
* @param integer $how_many
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getEntries($offset_start = 0, $how_many = null);
/**
* Returns an UTF-8 subtitle for the feed.
*
* @return string
*/
public function getSubtitle();
/**
* Returns a boolean indicating whether the feed is aggregated or not.
*
* @return boolean
*/
public function isAggregated();
/**
* Returns the date of creation of the feed.
*
* @return \DateTime
*/
public function getCreatedOn();
/**
* Returns the date of last update of the feed.
*
* @return \DateTime
*/
public function getUpdatedOn();
/**
* Returns a boolean indicating whether the feed has a given page.
*
* @param integer $pageNumber
* @param integer $nbEntriesByPage
*
* @return \DateTime
*/
public function hasPage($pageNumber, $nbEntriesByPage);
}

View File

@@ -0,0 +1,168 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\Formatter;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Feed\Link\FeedLink;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Symfony\Component\HttpFoundation\Response;
class AtomFormatter extends FeedFormatterAbstract implements FeedFormatterInterface
{
const FORMAT = 'atom';
private $linkGenerator;
/**
* @param LinkGeneratorCollection $generator
*/
public function __construct(LinkGeneratorCollection $generator)
{
$this->linkGenerator = $generator;
}
/**
* {@inheritdoc}
*/
public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$content = $this->format($feed, $page, $user, $generator, $app);
$response = new Response($content, 200, array('Content-Type' => 'application/atom+xml'));
return $response;
}
/**
* {@inheritdoc}
*/
public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$updated_on = $feed->getUpdatedOn();
$document = new \DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$document->standalone = true;
$root = $this->addTag($document, $document, 'feed');
$root->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$this->addTag($document, $root, 'title', $feed->getTitle());
if ($updated_on instanceof \DateTime) {
$updated_on = $updated_on->format(DATE_ATOM);
$this->addTag($document, $root, 'updated', $updated_on);
}
$next = $prev = null;
if ($feed->hasPage($page + 1, self::PAGE_SIZE)) {
if (null === $user) {
$next = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page + 1);
} else {
$next = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page + 1);
}
}
if ($feed->hasPage($page - 1, self::PAGE_SIZE)) {
if (null === $user) {
$prev = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page - 1);
} else {
$prev = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page - 1);
}
}
if (null !== $user) {
$feedlink = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page);
} else {
$feedlink = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page);
}
if ($feedlink instanceof FeedLink) {
$link = $this->addTag($document, $root, 'link');
$link->setAttribute('rel', 'self');
$link->setAttribute('href', $feedlink->getURI());
$this->addTag($document, $root, 'id', $feedlink->getURI());
}
if ($prev instanceof FeedLink) {
$prev_link = $this->addTag($document, $root, 'link');
$prev_link->setAttribute('rel', 'previous');
$prev_link->setAttribute('href', $prev->getURI());
}
if ($next instanceof FeedLink) {
$next_link = $this->addTag($document, $root, 'link');
$next_link->setAttribute('rel', 'next');
$next_link->setAttribute('href', $next->getURI());
}
if (null !== $generator) {
$this->addTag($document, $root, 'generator', $generator);
}
if (null !== $feed->getSubtitle()) {
$this->addTag($document, $root, 'subtitle', $feed->getSubtitle());
}
if (null !== $feed->getIconUrl()) {
$this->addTag($document, $root, 'icon', $feed->getIconUrl());
}
if (isset($this->author)) {
$author = $this->addTag($document, $root, 'author');
if (isset($this->author_email))
$this->addTag($document, $author, 'email', $this->author_email);
if (isset($this->author_name))
$this->addTag($document, $author, 'name', $this->author_name);
if (isset($this->author_url))
$this->addTag($document, $author, 'uri', $this->author_url);
}
foreach ($feed->getEntries() as $item) {
$this->addItem($document, $root, $item, $feedlink);
}
return $document->saveXML();
}
protected function addItem(DOMDocument $document, DOMNode $feed, FeedEntry $entry, FeedLink $link)
{
$entry_node = $this->addTag($document, $feed, 'entry');
$link = sprintf('%sentry/%d/', $link->getURI(), $entry->getId());
$this->addTag($document, $entry_node, 'id', $link);
$link_tag = $this->addTag($document, $entry_node, 'link');
$link_tag->setAttribute('rel', 'self');
$link_tag->setAttribute('href', $link);
$updated_on = $entry->getUpdatedOn()->format(DATE_ATOM);
$created_on = $entry->getCreatedOn()->format(DATE_ATOM);
$this->addTag($document, $entry_node, 'updated', $updated_on);
$this->addTag($document, $entry_node, 'published', $created_on);
$this->addTag($document, $entry_node, 'title', $entry->getTitle());
$author = $this->addTag($document, $entry_node, 'author');
if ($entry->getAuthorEmail()) {
$this->addTag($document, $author, 'email', $entry->getAuthorEmail());
}
if ($entry->getAuthorName()) {
$this->addTag($document, $author, 'name', $entry->getAuthorName());
}
$this->addTag($document, $entry_node, 'content', $entry->getSubtitle());
foreach ($entry->getItems() as $content) {
$this->addContent($document, $entry_node, $entry, $content);
}
return $entry_node;
}
}

View File

@@ -0,0 +1,280 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\Formatter;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Alchemy\Phrasea\Feed\RSS\FeedRSSImage;
use Symfony\Component\HttpFoundation\Response;
class CoolirisFormatter extends FeedFormatterAbstract implements FeedFormatterInterface
{
const FORMAT = 'atom';
const VERSION = '2.0';
private $linkGenerator;
/**
* @param LinkGeneratorCollection $generator
*/
public function __construct(LinkGeneratorCollection $generator)
{
$this->linkGenerator = $generator;
}
/**
* {@inheritdoc}
*/
public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$content = $this->format($feed, $page, $user, $generator, $app);
$response = new Response($content, 200, array('Content-Type' => 'application/rss+xml'));
return $response;
}
/**
* {@inheritdoc}
*/
public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$updated_on = $feed->getUpdatedOn();
$doc = new \DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$doc->standalone = true;
$root = $this->addTag($doc, $doc, 'rss');
$root->setAttribute('version', self::VERSION);
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$channel = $this->addTag($doc, $root, 'channel');
$this->addTag($doc, $channel, 'title', $feed->getTitle());
$this->addTag($doc, $channel, 'dc:title', $feed->getTitle());
$this->addTag($doc, $channel, 'description', $feed->getSubtitle());
if (null !== $user) {
$link = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page);
} else {
$link = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page);
}
if ($link instanceof FeedLink) {
$this->addTag($doc, $channel, 'link', $link->getURI());
}
if (isset($this->language))
$this->addTag($doc, $channel, 'language', $this->language);
if (isset($this->copyright))
$this->addTag($doc, $channel, 'copyright', $this->copyright);
if (isset($this->managingEditor))
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if (isset($this->webMaster))
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
if ($updated_on instanceof DateTime) {
$updated_on = $updated_on->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) {
$last_build = $this->lastBuildDate->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'lastBuildDate', $last_build);
}
if (isset($this->categories) && count($this->categories) > 0) {
foreach ($this->categories as $category) {
$this->addTag($doc, $channel, 'category', $category);
}
}
if (isset($this->linkgenerator))
$this->addTag($doc, $channel, 'generator', $this->linkgenerator);
if (isset($this->docs))
$this->addTag($doc, $channel, 'docs', $this->docs);
if (isset($this->ttl))
$this->addTag($doc, $channel, 'ttl', $this->ttl);
if (isset($this->image) && $this->image instanceof FeedRSSImage) {
$image = $this->addTag($doc, $channel, 'image');
$this->addTag($doc, $image, 'url', $this->image->getUrl());
$this->addTag($doc, $image, 'title', $this->image->getTitle());
$this->addTag($doc, $image, 'link', $this->image->getLink());
if ($this->image->getWidth())
$this->addTag($doc, $image, 'width', $this->image->getWidth());
if ($this->image->getHeight())
$this->addTag($doc, $image, 'height', $this->image->getHeight());
if ($this->image->getDescription())
$this->addTag($doc, $image, 'description', $this->image->getDescription());
}
if (isset($this->skipHours) && count($this->skipHours)) {
$skipHours = $this->addTag($doc, $channel, 'skipHours');
foreach ($this->skipHours as $hour) {
$this->addTag($doc, $skipHours, 'hour', $hour);
}
}
if (isset($this->skipDays) && count($this->skipDays) > 0) {
$skipDays = $this->addTag($doc, $channel, 'skipDays');
foreach ($this->skipDays as $day) {
$this->addTag($doc, $skipDays, 'day', $day);
}
}
if ($link instanceof FeedLink) {
$self_link = $this->addTag($doc, $channel, 'atom:link');
$self_link->setAttribute('rel', 'self');
$self_link->setAttribute('href', $link->getURI());
}
$next = $prev = null;
if ($feed->hasPage($page + 1, self::PAGE_SIZE)) {
if (null === $user) {
$next = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page + 1);
} else {
$next = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page + 1);
}
}
if ($feed->hasPage($page - 1, self::PAGE_SIZE)) {
if (null === $user) {
$prev = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page - 1);
} else {
$prev = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page - 1);
}
}
$prefix = 'atom';
if ($prev instanceof FeedLink) {
$prev_link = $this->addTag($doc, $channel, $prefix . 'link');
$prev_link->setAttribute('rel', 'previous');
$prev_link->setAttribute('href', $prev->getURI());
}
if ($next instanceof FeedLink) {
$next_link = $this->addTag($doc, $channel, $prefix . 'link');
$next_link->setAttribute('rel', 'next');
$next_link->setAttribute('href', $next->getURI());
}
foreach ($feed->getEntries() as $item) {
$this->addItem($app, $doc, $channel, $item);
}
return $doc->saveXML();
}
protected function addItem(Application $app, \DOMDocument $document, \DOMNode $feed, FeedEntry $entry)
{
foreach ($entry->get_content() as $content) {
$this->addContent($app, $document, $feed, $entry, $content);
}
}
protected function addContent(Application $app, \DOMDocument $document, \DOMNode $node, FeedItem $content)
{
$preview_sd = $content->getRecord($app)->get_subdef('preview');
$preview_permalink = $preview_sd->get_permalink();
$thumbnail_sd = $content->getRecord($app)->get_thumbnail();
$thumbnail_permalink = $thumbnail_sd->get_permalink();
$medium = strtolower($content->getRecord($app)->get_type());
if ( ! in_array($medium, array('image', 'audio', 'video'))) {
return $this;
}
if (null === $preview_permalink || null === $thumbnail_permalink) {
return $this;
}
//add item node to channel node
$item = $this->addTag($document, $node, 'item');
$caption = $content->getRecord($app)->get_caption();
$title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title);
if (null !== $title_field) {
$str_title = $title_field->get_serialized_values(' ');
} else {
$str_title = $content->getRecord($app)->get_title();
}
//attach tile node to item node
$title = $this->addTag($document, $item, 'title', $str_title);
$desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description);
if (null !== $desc_field) {
$str_desc = $desc_field->get_serialized_values(' ');
} else {
$str_desc = '';
}
//attach desc node to item node
$desc = $this->addTag($document, $item, 'description', $str_desc);
$duration = $content->getRecord($app)->get_duration();
if (null !== $preview_permalink) {
$preview = $this->addTag($document, $item, 'media:content');
$preview->setAttribute('url', $preview_permalink->get_url());
$preview->setAttribute('fileSize', $preview_sd->get_size());
$preview->setAttribute('type', $preview_sd->get_mime());
$preview->setAttribute('medium', $medium);
$preview->setAttribute('expression', 'full');
$preview->setAttribute('isDefault', 'true');
if (null !== $preview_sd->get_width()) {
$preview->setAttribute('width', $preview_sd->get_width());
}
if (null !== $preview_sd->get_height()) {
$preview->setAttribute('height', $preview_sd->get_height());
}
if (null !== $duration) {
$preview->setAttribute('duration', $duration);
}
}
if (null !== $thumbnail_permalink) {
$thumbnail = $this->addTag($document, $item, 'media:thumbnail');
$thumbnail->setAttribute('url', $thumbnail_permalink->get_url());
if (null !== $thumbnail_sd->get_width()) {
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
}
if (null !== $thumbnail_sd->get_height()) {
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
}
$thumbnail = $this->addTag($document, $item, 'media:content');
$thumbnail->setAttribute('url', $thumbnail_permalink->get_url());
$thumbnail->setAttribute('fileSize', $thumbnail_sd->get_size());
$thumbnail->setAttribute('type', $thumbnail_sd->get_mime());
$thumbnail->setAttribute('medium', $medium);
$thumbnail->setAttribute('isDefault', 'false');
if (null !== $thumbnail_sd->get_width()) {
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
}
if (null !== $thumbnail_sd->get_height()) {
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
}
if (null !== $duration) {
$thumbnail->setAttribute('duration', $duration);
}
}
return $this;
}
}

View File

@@ -9,188 +9,13 @@
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
abstract class Feed_XML_Abstract
namespace Alchemy\Phrasea\Feed\Formatter;
use Alchemy\Phrasea\Application;
abstract class FeedFormatterAbstract
{
/**
*
* @var DateTime
*/
protected $updated_on;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $subtitle;
/**
*
* @var Array
*/
protected $items = array();
/**
*
* @var Feed_Link
*/
protected $next_page;
/**
*
* @var Feed_Link
*/
protected $previous_page;
/**
*
* @var Feed_Link
*/
protected $link;
/**
*
* @var string
*/
protected $generator;
/**
*
* @var string
*/
protected $mimetype;
/**
*
* @param string $title
*/
public function set_title($title)
{
$this->title = $title;
return $this;
}
/**
*
* @param DateTime $datetime
* @return Feed_XML_Interface
*/
public function set_updated_on(DateTime $datetime)
{
$this->updated_on = $datetime;
return $this;
}
/**
*
* @param string $subtitle
* @return Feed_XML_Interface
*/
public function set_subtitle($subtitle)
{
$this->subtitle = $subtitle;
return $this;
}
/**
*
* @param Feed_Link $link
* @return Feed_XML_Interface
*/
public function set_link(Feed_Link $link)
{
$this->link = $link;
return $this;
}
/**
*
* @param Feed_Link $next_page
* @return Feed_XML_Interface
*/
public function set_next_page(Feed_Link $next_page)
{
$this->next_page = $next_page;
return $this;
}
/**
*
* @param Feed_Link $previous_page
* @return Feed_XML_Interface
*/
public function set_previous_page(Feed_Link $previous_page)
{
$this->previous_page = $previous_page;
return $this;
}
/**
*
* @param Feed_Entry_Adapter $entry
* @return Feed_XML_Interface
*/
public function set_item(Feed_Entry_Adapter $entry)
{
$this->items[] = $entry;
return $this;
}
/**
*
* @param string $generator
* @return Feed_XML_Interface
*/
public function set_generator($generator)
{
$this->generator = $generator;
return $this;
}
/**
*
* @param DOMDocument $document
* @param DOMNode $node
* @param boolean $namespaced
* @return Feed_XML_Interface
*/
public function add_navigation(DOMDocument $document, DOMNode $node, $namespaced)
{
$prefix = $namespaced ? 'atom:' : '';
if ($this->previous_page instanceof Feed_Link) {
$prev_link = $this->addTag($document, $node, $prefix . 'link');
$prev_link->setAttribute('rel', 'previous');
$prev_link->setAttribute('href', $this->previous_page->get_href());
}
if ($this->next_page instanceof Feed_Link) {
$next_link = $this->addTag($document, $node, $prefix . 'link');
$next_link->setAttribute('rel', 'next');
$next_link->setAttribute('href', $this->next_page->get_href());
}
return $this;
}
const PAGE_SIZE = 20;
/**
*
@@ -200,12 +25,13 @@ abstract class Feed_XML_Abstract
* @param string $tagcontent
* @return DOMElement
*/
protected function addTag(DOMDocument $document, DOMNode $node, $tagname, $tagcontent = null)
protected function addTag(\DOMDocument $document, \DOMNode $node, $tagname, $tagcontent = null)
{
$tag = $document->createElement($tagname);
if (trim($tagcontent) !== '')
if (trim($tagcontent) !== '') {
$tag->appendChild($document->createTextNode($tagcontent));
}
$node->appendChild($tag);
return $tag;
@@ -215,46 +41,46 @@ abstract class Feed_XML_Abstract
*
* @param DOMDocument $document
* @param DOMNode $item
* @param Feed_Entry_Item $content
* @return Feed_XML_Interface
* @param FeedItem $content
* @return FeedFormaterInterface
*/
protected function addContent(DOMDocument $document, DOMNode $item, Feed_Entry_Adapter $entry, Feed_Entry_Item $content)
protected function addContent(Application $app, \DOMDocument $document, \DOMNode $item, FeedItem $content)
{
$preview_sd = $content->get_record()->get_subdef('preview');
$preview_sd = $content->getRecord($app)->get_subdef('preview');
$preview_permalink = $preview_sd->get_permalink();
$thumbnail_sd = $content->get_record()->get_thumbnail();
$thumbnail_sd = $content->getRecord($app)->get_thumbnail();
$thumbnail_permalink = $thumbnail_sd->get_permalink();
$medium = strtolower($content->get_record()->get_type());
$medium = strtolower($content->getRecord($app)->get_type());
if ( ! in_array($medium, array('image', 'audio', 'video'))) {
return $this;
}
if (! $preview_permalink || ! $thumbnail_permalink) {
if (null === $preview_permalink || null === $thumbnail_permalink) {
return $this;
}
$group = $this->addTag($document, $item, 'media:group');
$caption = $content->get_record()->get_caption();
$caption = $content->getRecord($app)->get_caption();
$title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title);
if ($title_field) {
if (null !== $title_field) {
$str_title = $title_field->get_serialized_values(' ');
$title = $this->addTag($document, $group, 'media:title', $str_title);
$title->setAttribute('type', 'plain');
}
$desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description);
if ($desc_field) {
if (null !== $desc_field) {
$str_desc = $desc_field->get_serialized_values(' ');
$desc = $this->addTag($document, $group, 'media:description', $str_desc);
$desc->setAttribute('type', 'plain');
}
$contrib_field = $caption->get_dc_field(databox_Field_DCESAbstract::Contributor);
if ($contrib_field) {
if (null !== $contrib_field) {
$str_contrib = $contrib_field->get_serialized_values(' ');
$contrib = $this->addTag($document, $group, 'media:credit', $str_contrib);
$contrib->setAttribute('role', 'contributor');
@@ -262,7 +88,7 @@ abstract class Feed_XML_Abstract
}
$director_field = $caption->get_dc_field(databox_Field_DCESAbstract::Creator);
if ($director_field) {
if (null !== $director_field) {
$str_director = $director_field->get_serialized_values(' ');
$director = $this->addTag($document, $group, 'media:credit', $str_director);
$director->setAttribute('role', 'director');
@@ -270,7 +96,7 @@ abstract class Feed_XML_Abstract
}
$publisher_field = $caption->get_dc_field(databox_Field_DCESAbstract::Publisher);
if ($publisher_field) {
if (null !== $publisher_field) {
$str_publisher = $publisher_field->get_serialized_values(' ');
$publisher = $this->addTag($document, $group, 'media:credit', $str_publisher);
$publisher->setAttribute('role', 'publisher');
@@ -278,20 +104,20 @@ abstract class Feed_XML_Abstract
}
$rights_field = $caption->get_dc_field(databox_Field_DCESAbstract::Rights);
if ($rights_field) {
if (null !== $rights_field) {
$str_rights = $rights_field->get_serialized_values(' ');
$rights = $this->addTag($document, $group, 'media:copyright', $str_rights);
}
$keyword_field = $caption->get_dc_field(databox_Field_DCESAbstract::Subject);
if ($keyword_field) {
if (null !== $keyword_field) {
$str_keywords = $keyword_field->get_serialized_values(', ');
$keywords = $this->addTag($document, $group, 'media:keywords', $str_keywords);
}
$duration = $content->get_record()->get_duration();
if ($preview_permalink) {
if (null !== $preview_permalink) {
$preview = $this->addTag($document, $group, 'media:content');
$preview->setAttribute('url', $preview_permalink->get_url());
@@ -301,23 +127,28 @@ abstract class Feed_XML_Abstract
$preview->setAttribute('expression', 'full');
$preview->setAttribute('isDefault', 'true');
if ($preview_sd->get_width())
if (null !== $preview_sd->get_width()) {
$preview->setAttribute('width', $preview_sd->get_width());
if ($preview_sd->get_height())
}
if (null !== $preview_sd->get_height()) {
$preview->setAttribute('height', $preview_sd->get_height());
if ($duration)
}
if (null !== $duration) {
$preview->setAttribute('duration', $duration);
}
}
if ($thumbnail_permalink) {
if (null !== $thumbnail_permalink) {
$thumbnail = $this->addTag($document, $group, 'media:thumbnail');
$thumbnail->setAttribute('url', $thumbnail_permalink->get_url());
if ($thumbnail_sd->get_width())
if (null !== $thumbnail_sd->get_width()) {
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
if ($thumbnail_sd->get_height())
}
if (null !== $thumbnail_sd->get_height()) {
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
}
$thumbnail = $this->addTag($document, $group, 'media:content');
@@ -327,25 +158,18 @@ abstract class Feed_XML_Abstract
$thumbnail->setAttribute('medium', $medium);
$thumbnail->setAttribute('isDefault', 'false');
if ($thumbnail_sd->get_width())
if (null !== $thumbnail_sd->get_width()) {
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
if ($thumbnail_sd->get_height())
}
if (null !== $thumbnail_sd->get_height()) {
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
if ($duration)
}
if (null !== $duration) {
$thumbnail->setAttribute('duration', $duration);
}
}
return $this;
}
/**
*
* @return string
*/
public function get_mimetype()
{
return $this->mimetype;
}
abstract public function render();
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\Formatter;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
interface FeedFormatterInterface
{
/**
* Returns a string representation of the feed.
*
* @param FeedInterface $feed
* @param type $page
* @param \User_Adapter $user
* @param type $generator
* @param Application $app
*
* @return string
*/
public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null);
/**
* Returns an HTTP Response containing a string representation of the feed.
*
* @param FeedInterface $feed
* @param type $page
* @param \User_Adapter $user
* @param type $generator
* @param Application $app
*
* @return string
*/
public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null);
}

View File

@@ -0,0 +1,210 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\Formatter;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Feed\Link\FeedLink;
use Alchemy\Phrasea\Feed\Link\LinkGeneratorCollection;
use Alchemy\Phrasea\Feed\RSS\FeedRSSImage;
use Symfony\Component\HttpFoundation\Response;
class RssFormatter extends FeedFormatterAbstract implements FeedFormatterInterface
{
const FORMAT = 'rss';
const VERSION = '2.0';
private $linkGenerator;
/**
* @param LinkGeneratorCollection $generator
*/
public function __construct(LinkGeneratorCollection $generator)
{
$this->linkGenerator = $generator;
}
/**
* {@inheritdoc}
*/
public function createResponse(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$content = $this->format($feed, $page, $user, $generator, $app);
$response = new Response($content, 200, array('Content-Type' => 'application/rss+xml'));
return $response;
}
/**
* {@inheritdoc}
*/
public function format(FeedInterface $feed, $page, \User_Adapter $user = null, $generator = 'Phraseanet', Application $app = null)
{
$updated_on = $feed->getUpdatedOn();
$next = $prev = null;
if ($feed->hasPage($page + 1, self::PAGE_SIZE)) {
if (null === $user) {
$next = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page + 1);
} else {
$next = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page + 1);
}
}
if ($feed->hasPage($page - 1, self::PAGE_SIZE)) {
if (null === $user) {
$prev = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page - 1);
} else {
$prev = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page - 1);
}
}
if (null !== $user) {
$link = $this->linkGenerator->generate($feed, $user, self::FORMAT, $page);
} else {
$link = $this->linkGenerator->generatePublic($feed, self::FORMAT, $page);
}
$doc = new \DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$doc->standalone = true;
$root = $this->addTag($doc, $doc, 'rss');
$root->setAttribute('version', self::VERSION);
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$channel = $this->addTag($doc, $root, 'channel');
$this->addTag($doc, $channel, 'title', $feed->getTitle());
$this->addTag($doc, $channel, 'dc:title', $feed->getTitle());
$this->addTag($doc, $channel, 'description', $feed->getSubtitle());
if ($link instanceof FeedLink) {
$this->addTag($doc, $channel, 'link', $link->getURI());
}
if (isset($this->language))
$this->addTag($doc, $channel, 'language', $this->language);
if (isset($this->copyright))
$this->addTag($doc, $channel, 'copyright', $this->copyright);
if (isset($this->managingEditor))
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if (isset($this->webMaster))
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
if ($updated_on instanceof \DateTime) {
$updated_on = $updated_on->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
if (isset($this->lastBuildDate) && $this->lastBuildDate instanceof DateTime) {
$last_build = $this->lastBuildDate->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'lastBuildDate', $last_build);
}
if (isset($this->categories) && count($this->categories) > 0) {
foreach ($this->categories as $category) {
$this->addTag($doc, $channel, 'category', $category);
}
}
if (isset($generator))
$this->addTag($doc, $channel, 'generator', $generator);
if (isset($this->docs))
$this->addTag($doc, $channel, 'docs', $this->docs);
if (isset($this->ttl))
$this->addTag($doc, $channel, 'ttl', $this->ttl);
if (isset($this->image) && $this->image instanceof FeedRSSImage) {
$image = $this->addTag($doc, $channel, 'image');
$this->addTag($doc, $image, 'url', $this->image->getUrl());
$this->addTag($doc, $image, 'title', $this->image->getTitle());
$this->addTag($doc, $image, 'link', $this->image->getLink());
if ($this->image->getWidth())
$this->addTag($doc, $image, 'width', $this->image->getWidth());
if ($this->image->getHeight())
$this->addTag($doc, $image, 'height', $this->image->getHeight());
if ($this->image->getDescription())
$this->addTag($doc, $image, 'description', $this->image->getDescription());
}
if (isset($this->skipHours) && count($this->skipHours)) {
$skipHours = $this->addTag($doc, $channel, 'skipHours');
foreach ($this->skipHours as $hour) {
$this->addTag($doc, $skipHours, 'hour', $hour);
}
}
if (isset($this->skipDays) && count($this->skipDays) > 0) {
$skipDays = $this->addTag($doc, $channel, 'skipDays');
foreach ($this->skipDays as $day) {
$this->addTag($doc, $skipDays, 'day', $day);
}
}
if ($link instanceof FeedLink) {
$self_link = $this->addTag($doc, $channel, 'atom:link');
$self_link->setAttribute('rel', 'self');
$self_link->setAttribute('href', $link->getURI());
}
$prefix = 'atom:';
if ($prev instanceof FeedLink) {
$prev_link = $this->addTag($doc, $channel, $prefix . 'link');
$prev_link->setAttribute('rel', 'previous');
$prev_link->setAttribute('href', $prev->getURI());
}
if ($next instanceof FeedLink) {
$next_link = $this->addTag($doc, $channel, $prefix . 'link');
$next_link->setAttribute('rel', 'next');
$next_link->setAttribute('href', $next->getURI());
}
foreach ($feed->getEntries() as $item) {
$this->addItem($doc, $channel, $item);
}
return $doc->saveXML();
}
protected function addItem(\DOMDocument $document, \DOMNode $node, FeedEntry $entry)
{
$item = $this->addTag($document, $node, 'item');
$link = $entry->getLink();
$this->addTag($document, $item, 'title', $entry->getTitle());
$this->addTag($document, $item, 'description', $entry->getSubtitle());
$author = sprintf(
'%s (%s)'
, $entry->getAuthorEmail()
, $entry->getAuthorName()
);
$created_on = $entry->getCreatedOn()->format(DATE_RFC2822);
$this->addTag($document, $item, 'author', $author);
$this->addTag($document, $item, 'pubDate', $created_on);
$this->addTag($document, $item, 'guid', $link->getURI());
$this->addTag($document, $item, 'link', $link->getURI());
/**
* Missing :
*
* category Includes the item in one or more categories. More.
* comments URL of a page for comments relating to the item. More.
* enclosure Describes a media object that is attached to the item. More.
* source The RSS channel that the item came from. More.
*
*/
foreach ($entry->getItems() as $content) {
$this->addContent($document, $item, $entry, $content);
}
return $item;
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace Alchemy\Phrasea\Feed\Link;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Feed\Link\FeedLink;
use Entities\AggregateToken;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Routing\Generator\UrlGenerator;
class AggregateLinkGenerator implements LinkGeneratorInterface
{
const FORMAT_ATOM = 'atom';
const FORMAT_RSS = 'rss';
private $em;
private $generator;
private $random;
/**
* @param UrlGenerator $generator
* @param EntityManager $em
* @param \random $random
*/
public function __construct(UrlGenerator $generator, EntityManager $em, \random $random)
{
$this->generator = $generator;
$this->em = $em;
$this->random = $random;
}
/**
* {@inheritdoc}
*/
public function generate(FeedInterface $aggregate, \User_Adapter $user, $format, $page = null, $renew = false)
{
if (!$this->supports($aggregate)) {
throw new InvalidArgumentException('AggregateLinkGenerator only support aggregate feeds.');
}
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', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $aggregate->getTitle(), 'Atom'),
'application/atom+xml'
);
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', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $aggregate->getTitle(), 'RSS'),
'application/rss+xml'
);
default:
throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format));
}
}
/**
* {@inheritdoc}
*/
public function supports(FeedInterface $feed)
{
return $feed instanceof Aggregate;
}
/**
* {@inheritdoc}
*/
public function generatePublic(FeedInterface $aggregate, $format, $page = null)
{
if (!$this->supports($aggregate)) {
throw new InvalidArgumentException('AggregateLinkGenerator only support aggregate feeds.');
}
switch ($format) {
case self::FORMAT_ATOM:
$params = array('format' => 'atom');
if (null !== $page) {
$params['page'] = $page;
}
return new FeedLink(
$this->generator->generate('feed_public_aggregated', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $aggregate->getTitle(), 'Atom'),
'application/atom+xml'
);
case self::FORMAT_RSS:
$params = array('format' => 'rss');
if (null !== $page) {
$params['page'] = $page;
}
return new FeedLink(
$this->generator->generate('feed_public_aggregated', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $aggregate->getTitle(), 'RSS'),
'application/rss+xml'
);
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')
->findOneBy(array('usrId' => $user->get_id()));
if (null === $token || true === $renew) {
if (null === $token) {
$token = new AggregateToken();
$token->setUsrId($user->get_id());
}
$token->setValue($this->random->generatePassword(12, \random::LETTERS_AND_NUMBERS));
$this->em->persist($token);
$this->em->flush();
}
return $token;
}
}

View File

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

View File

@@ -0,0 +1,161 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\Link;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Feed\FeedInterface;
use Doctrine\ORM\EntityManager;
use Entities\Feed;
use Entities\FeedToken;
use Symfony\Component\Routing\Generator\UrlGenerator;
class FeedLinkGenerator implements LinkGeneratorInterface
{
const FORMAT_ATOM = 'atom';
const FORMAT_RSS = 'rss';
private $em;
private $generator;
private $random;
/**
* @param UrlGenerator $generator
* @param EntityManager $em
* @param \random $random
*/
public function __construct(UrlGenerator $generator, EntityManager $em, \random $random)
{
$this->generator = $generator;
$this->em = $em;
$this->random = $random;
}
/**
* {@inheritdoc}
*/
public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false)
{
if (!$this->supports($feed)) {
throw new InvalidArgumentException('FeedLinkGenerator only support aggregate feeds.');
}
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', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $feed->getTitle(), 'Atom'),
'application/atom+xml'
);
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', $params, UrlGenerator::ABSOLUTE_URL),
sprintf('%s - %s', $feed->getTitle(), 'RSS'),
'application/rss+xml'
);
default:
throw new InvalidArgumentException(sprintf('Format %s is not recognized.', $format));
}
}
/**
* {@inheritdoc}
*/
public function supports(FeedInterface $feed)
{
return $feed instanceof Feed;
}
/**
* {@inheritdoc}
*/
public function generatePublic(FeedInterface $feed, $format, $page = null)
{
if (!$this->supports($feed)) {
throw new InvalidArgumentException('FeedLinkGenerator only support aggregate feeds.');
}
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'
);
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'
);
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')
->findOneBy(array('usrId' => $user->get_id(), 'feed' => $feed->getId()));
if (null === $token || true === $renew) {
if (null === $token) {
$token = new FeedToken();
$token->setFeed($feed);
$token->setUsrId($user->get_id());
$feed->addToken($token);
$this->em->persist($feed);
}
$token->setValue($this->random->generatePassword(12, \random::LETTERS_AND_NUMBERS));
$this->em->persist($token);
$this->em->flush();
}
return $token;
}
}

View File

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

View File

@@ -0,0 +1,64 @@
<?php
namespace Alchemy\Phrasea\Feed\Link;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
class LinkGeneratorCollection implements LinkGeneratorInterface
{
private $generators = array();
/**
* Adds a LinkGeneratorInterface to the internal array.
*
* @param LinkGeneratorInterface $generator
*/
public function pushGenerator(LinkGeneratorInterface $generator)
{
$this->generators[] = $generator;
}
/**
* {@inheritdoc}
*/
public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false)
{
if (null === $generator = $this->findGenerator($feed)) {
throw new InvalidArgumentException(sprintf('Unable to find a valid generator for %s', get_class($feed)));
}
return $generator->generate($feed, $user, $format, $page);
}
/**
* {@inheritdoc}
*/
public function generatePublic(FeedInterface $feed, $format, $page = null)
{
if (null === $generator = $this->findGenerator($feed)) {
throw new InvalidArgumentException(sprintf('Unable to find a valid generator for %s', get_class($feed)));
}
return $generator->generatePublic($feed, $format, $page);
}
/**
* {@inheritdoc}
*/
public function supports(FeedInterface $feed)
{
return null !== $this->findGenerator($feed);
}
private function findGenerator(FeedInterface $feed)
{
foreach ($this->generators as $generator) {
if ($generator->supports($feed)) {
return $generator;
}
}
return null;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Alchemy\Phrasea\Feed\Link;
use Alchemy\Phrasea\Feed\FeedInterface;
interface LinkGeneratorInterface
{
/**
* Generates a FeedLink based on given FeedInterface and User_Adapter.
*
* @param FeedInterface $feed
* @param \User_Adapter $user
* @param type $format
* @param type $page
* @param type $renew
*
* @return FeedLink
*
* @throws InvalidArgumentException
*/
public function generate(FeedInterface $feed, \User_Adapter $user, $format, $page = null, $renew = false);
/**
* Generates a public FeedLink based on given FeedInterface.
*
* @param FeedInterface $feed
* @param type $format
* @param type $page
*
* @return FeedLink
*
* @throws InvalidArgumentException
*/
public function generatePublic(FeedInterface $feed, $format, $page = null);
/**
* Returns an instance of FeedInterface supported by the class.
*
* @param \Alchemy\Phrasea\Feed\FeedInterface $feed
*
* @return FeedInterface
*/
public function supports(FeedInterface $feed);
}

View File

@@ -9,13 +9,15 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\RSS;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
class Image implements FeedRSSImageInterface
{
/**
*
@@ -58,7 +60,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
* @param string $url
* @param string $title
* @param string $link
* @return Feed_XML_RSS_Image
* @return FeedRSSImage
*/
public function __construct($url, $title, $link)
{
@@ -72,9 +74,9 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
/**
*
* @param type $description
* @return Feed_XML_RSS_Image
* @return FeedRSSImage
*/
public function set_description($description)
public function setDescription($description)
{
$this->description = $description;
@@ -84,9 +86,9 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
/**
*
* @param int $width
* @return Feed_XML_RSS_Image
* @return FeedRSSImage
*/
public function set_width($width)
public function setWidth($width)
{
$this->width = (int) $width;
@@ -96,9 +98,9 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
/**
*
* @param int $height
* @return Feed_XML_RSS_Image
* @return FeedRSSImage
*/
public function set_height($height)
public function setHeight($height)
{
$this->height = (int) $height;
@@ -109,7 +111,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return string
*/
public function get_url()
public function getUrl()
{
return $this->url;
}
@@ -118,7 +120,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return string
*/
public function get_title()
public function getTitle()
{
return $this->title;
}
@@ -127,7 +129,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return string
*/
public function get_link()
public function getLink()
{
return $this->link;
}
@@ -136,7 +138,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return string
*/
public function get_description()
public function getDescription()
{
return $this->description;
}
@@ -145,7 +147,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return int
*/
public function get_width()
public function getWidth()
{
return $this->width;
}
@@ -154,7 +156,7 @@ class Feed_XML_RSS_Image implements Feed_XML_RSS_ImageInterface
*
* @return int
*/
public function get_height()
public function getHeight()
{
return $this->height;
}

View File

@@ -9,26 +9,28 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Feed\RSS;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_XML_RSS_ImageInterface
interface ImageInterface
{
public function __construct($url, $title, $link);
public function get_url();
public function getUrl();
public function get_title();
public function getTitle();
public function get_link();
public function getLink();
public function get_description();
public function getDescription();
public function get_height();
public function getHeight();
public function get_width();
public function getWidth();
}

View File

@@ -18,6 +18,7 @@ use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion;
use Alchemy\Phrasea\Exception\RuntimeException;
use Doctrine\Common\Collections\ArrayCollection;
use Entities\FeedEntry;
class PhraseaEngine implements SearchEngineInterface
{
@@ -303,7 +304,7 @@ class PhraseaEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function addFeedEntry(\Feed_Entry_Adapter $entry)
public function addFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Phrasea Engine');
}
@@ -311,7 +312,7 @@ class PhraseaEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function removeFeedEntry(\Feed_Entry_Adapter $entry)
public function removeFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Phrasea Engine');
}
@@ -319,7 +320,7 @@ class PhraseaEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function updateFeedEntry(\Feed_Entry_Adapter $entry)
public function updateFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Phrasea Engine');
}

View File

@@ -16,6 +16,7 @@ use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
use Alchemy\Phrasea\Exception\RuntimeException;
use Doctrine\Common\Collections\ArrayCollection;
use Entities\FeedEntry;
interface SearchEngineInterface
{
@@ -131,29 +132,29 @@ interface SearchEngineInterface
/**
* Add an entry to index
*
* @param \Feed_Entry_Adapter $entry
* @param FeedEntry $entry
* @return SearchEngineInterface
* @throws RuntimeException
*/
public function addFeedEntry(\Feed_Entry_Adapter $entry);
public function addFeedEntry(FeedEntry $entry);
/**
* Remove an entry to index
*
* @param \Feed_Entry_Adapter $entry
* @param FeedEntry $entry
* @return SearchEngineInterface
* @throws RuntimeException
*/
public function removeFeedEntry(\Feed_Entry_Adapter $entry);
public function removeFeedEntry(FeedEntry $entry);
/**
* Update an entry in the index
*
* @param \Feed_Entry_Adapter $entry
* @param FeedEntry $entry
* @return SearchEngineInterface
* @throws RuntimeException
*/
public function updateFeedEntry(\Feed_Entry_Adapter $entry);
public function updateFeedEntry(FeedEntry $entry);
/**
* Set options to search-engine

View File

@@ -18,6 +18,7 @@ use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion;
use Alchemy\Phrasea\Exception\RuntimeException;
use Doctrine\Common\Collections\ArrayCollection;
use Entities\FeedEntry;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\Process;
@@ -387,7 +388,7 @@ class SphinxSearchEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function addFeedEntry(\Feed_Entry_Adapter $entry)
public function addFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Sphinx Search Engine');
}
@@ -395,7 +396,7 @@ class SphinxSearchEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function removeFeedEntry(\Feed_Entry_Adapter $entry)
public function removeFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Sphinx Search Engine');
}
@@ -403,7 +404,7 @@ class SphinxSearchEngine implements SearchEngineInterface
/**
* {@inheritdoc}
*/
public function updateFeedEntry(\Feed_Entry_Adapter $entry)
public function updateFeedEntry(FeedEntry $entry)
{
throw new RuntimeException('Feed Entry indexing not supported by Sphinx Search Engine');
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade;
use Alchemy\Phrasea\Application;
/**
* Collection of Doctrine schema pre-upgrades
*/
class PreSchemaUpgradeCollection
{
/** @var PreSchemaUpgradeInterface[] */
private $upgrades = array();
public function __construct()
{
$this->upgrades[] = new Upgrade39();
}
/**
* Applies all applyable upgrades
*
* @param Application $app
*/
public function apply(Application $app)
{
foreach ($this->upgrades as $upgrade) {
if ($upgrade->isApplyable($app)) {
$upgrade->apply($app['EM']);
}
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade;
use Doctrine\ORM\EntityManager;
use Alchemy\Phrasea\Application;
/**
* Interface for DB schema upgrade that have to be done before Doctrine schema
* upgrade
*/
interface PreSchemaUpgradeInterface
{
/**
* Applies the pre-upgrade/
*
* @param EntityManager $em
*/
public function apply(EntityManager $em);
/**
* Returns true if the Upgrade is applyable
*
* @param Application $app
*
* @return Boolean
*/
public function isApplyable(Application $app);
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityManager;
class Upgrade39 implements PreSchemaUpgradeInterface
{
/**
* {@inheritdoc}
*/
public function apply(EntityManager $em)
{
$em->getConnection()->executeQuery('RENAME TABLE `feeds` TO `feeds_backup`');
}
/**
* {@inheritdoc}
*/
public function isApplyable(Application $app)
{
$rs = $app['phraseanet.appbox']->get_connection()->query('SHOW TABLE STATUS');
$found = false;
foreach ($rs as $row) {
if ('feeds' === $row['Name']) {
$found = true;
break;
}
}
return $found;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="AggregateTokens")
* @ORM\Entity(repositoryClass="Repositories\AggregateTokenRepository")
*/
class AggregateToken
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="integer", name="usr_id")
*/
private $usrId;
/**
* @ORM\Column(type="string", length=12, nullable=true)
*/
private $value;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set usr_id
*
* @param integer $usrId
* @return AggregateToken
*/
public function setUsrId($usrId)
{
$this->usrId = $usrId;
return $this;
}
/**
* Get usr_id
*
* @return integer
*/
public function getUsrId()
{
return $this->usrId;
}
/**
* 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;
}
}

View File

@@ -0,0 +1,566 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Feed\FeedInterface;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="Feeds")
* @ORM\Entity(repositoryClass="Repositories\FeedRepository")
*/
class Feed implements FeedInterface
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="boolean")
*/
private $public = false;
/**
* @ORM\Column(type="boolean", name="icon_url")
*/
private $iconUrl = false;
/**
* @ORM\Column(type="integer", nullable=true, name="base_id")
*/
private $baseId;
/**
* @ORM\Column(type="string", length=128)
*/
private $title;
/**
* @ORM\Column(type="string", length=1024, nullable=true)
*/
private $subtitle;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime", name="created_on")
*/
private $createdOn;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime", name="updated_on")
*/
private $updatedOn;
/**
* @ORM\OneToMany(targetEntity="FeedPublisher", mappedBy="feed", cascade={"ALL"})
*/
private $publishers;
/**
* @ORM\OneToMany(targetEntity="FeedEntry", mappedBy="feed", cascade={"ALL"})
* @ORM\OrderBy({"createdOn" = "ASC"})
*/
private $entries;
/**
* @ORM\OneToMany(targetEntity="FeedToken", mappedBy="feed", cascade={"ALL"})
*/
private $tokens;
/**
* Constructor
*/
public function __construct()
{
$this->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 setIsPublic($public)
{
$this->public = $public;
return $this;
}
/**
* Get public
*
* @return boolean
*/
public function isPublic()
{
return $this->public;
}
/**
* Set icon_url
*
* @param boolean $iconUrl
* @return Feed
*/
public function setIconUrl($iconUrl)
{
$this->iconUrl = $iconUrl;
return $this;
}
/**
* Get icon_url
*
* @return boolean
*/
public function getIconUrl()
{
return $this->iconUrl;
}
/**
* Set base_id
*
* @param integer $baseId
* @return Feed
*/
public function setBaseId($baseId)
{
$this->baseId = $baseId;
return $this;
}
/**
* Get base_id
*
* @return integer
*/
public function getBaseId()
{
return $this->baseId;
}
/**
* 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;
}
/**
* 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 addEntry(\Entities\FeedEntry $entries)
{
$this->entries[] = $entries;
return $this;
}
/**
* Remove entries
*
* @param \Entities\FeedEntry $entries
*/
public function removeEntry(\Entities\FeedEntry $entries)
{
$this->entries->removeElement($entries);
}
/**
* Get entries
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getEntries($offset_start = 0, $how_many = null)
{
if (null === $how_many) {
return $this->entries;
}
return $this->entries->slice($offset_start, $how_many);
}
/**
* Returns the owner of the feed.
*
* @return FeedPublisher
*/
public function getOwner()
{
foreach ($this->getPublishers() as $publisher) {
if ($publisher->isOwner()) {
return $publisher;
}
}
}
/**
* Returns a boolean indicating whether the given User_Adapter is the owner of the feed.
*
* @param \User_Adapter $user
*
* @return boolean
*/
public function isOwner(\User_Adapter $user)
{
$owner = $this->getOwner();
if ($owner !== null && $user->get_id() === $owner->getUsrId()) {
return true;
}
return false;
}
/**
* Returns the collection to which the feed belongs.
*
* @param Application $app
*
* @return type
*/
public function getCollection(Application $app)
{
if ($this->getBaseId() !== null) {
return \collection::get_from_base_id($app, $this->getBaseId());
}
}
/**
* Sets the collection.
*
* @param \collection $collection
*
* @return type
*/
public function setCollection(\collection $collection = null)
{
if ($collection === null) {
$this->baseId = null;
return;
}
$this->baseId = $collection->get_base_id();
}
/**
* Set created_on
*
* @param \DateTime $createdOn
* @return Feed
*/
public function setCreatedOn($createdOn)
{
$this->createdOn = $createdOn;
return $this;
}
/**
* Get created_on
*
* @return \DateTime
*/
public function getCreatedOn()
{
return $this->createdOn;
}
/**
* Set updated_on
*
* @param \DateTime $updatedOn
* @return Feed
*/
public function setUpdatedOn($updatedOn)
{
$this->updatedOn = $updatedOn;
return $this;
}
/**
* Get updated_on
*
* @return \DateTime
*/
public function getUpdatedOn()
{
return $this->updatedOn;
}
/**
* Returns a boolean indicating whether the given User_Adapter is a publisher of the feed.
*
* @param \User_Adapter $user
*
* @return boolean
*/
public function isPublisher(\User_Adapter $user)
{
foreach ($this->getPublishers() as $publisher) {
if ($publisher->getUsrId() == $user->get_id()) {
return true;
}
}
return false;
}
/**
* Returns an instance of FeedPublisher matching to the given User_Adapter
*
* @param \User_Adapter $user
*
* @return FeedPublisher
*/
public function getPublisher(\User_Adapter $user)
{
foreach ($this->getPublishers() as $publisher) {
if ($publisher->getUsrId() == $user->get_id()) {
return $publisher;
}
}
return null;
}
/**
* 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;
}
/**
* Returns a boolean indicating whether the feed is aggregated.
*
* @return boolean
*/
public function isAggregated()
{
return false;
}
/**
* Returns the number of entries the feed contains
*
* @return integer
*/
public function getCountTotalEntries()
{
return (count($this->entries));
}
/**
* Returns a boolean indicating whether the given User_Adapter has access to the feed
*
* @param \User_Adapter $user
* @param Application $app
*
* @return boolean
*/
public function hasAccess(\User_Adapter $user, Application $app)
{
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;
}
/**
* 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);
}
/**
* Returns a boolean indicating whether the feed contains a given page, assuming a given page size.
*
* @param integer $page
* @param integer $pageSize
*
* @return boolean
*/
public function hasPage($pageNumber, $nbEntriesByPage)
{
if (0 >= $nbEntriesByPage) {
throw new LogicException;
}
$count = $this->getCountTotalEntries();
if (0 > $pageNumber && $pageNumber <= $count / $nbEntriesByPage) {
return true;
}
return false;
}
/**
*
* Returns a boolean indicating whether a given user has access to the feed
*
* @param \User_Adapter $user
* @param \Alchemy\Phrasea\Application $app
*
* @return boolean
*/
public function isAccessible(\User_Adapter $user, Application $app)
{
$coll = $this->getCollection($app);
if ($this->isPublic()
|| $coll === null
|| in_array($coll->get_base_id(), array_keys($user->ACL()->get_granted_base()))) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,350 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="FeedEntries")
* @ORM\Entity(repositoryClass="Repositories\FeedEntryRepository")
*/
class FeedEntry
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="string", length=128)
*/
private $title;
/**
* @ORM\Column(type="string", length=128)
*/
private $subtitle;
/**
* @ORM\Column(type="string", length=128, name="author_name")
*/
private $authorName;
/**
* @ORM\Column(type="string", length=128, name="author_email")
*/
private $authorEmail;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime", name="created_on")
*/
private $createdOn;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime", name="updated_on")
*/
private $updatedOn;
/**
* @ORM\OneToMany(targetEntity="FeedItem", mappedBy="entry", cascade={"ALL"})
* @ORM\OrderBy({"ord" = "ASC"})
*/
private $items;
/**
* @ORM\ManyToOne(targetEntity="FeedPublisher", cascade={"persist"})
* @ORM\JoinColumn(name="publisher_id", referencedColumnName="id")
*/
private $publisher;
/**
* @ORM\ManyToOne(targetEntity="Feed", inversedBy="entries", cascade={"persist"})
* @ORM\JoinColumn(name="feed_id", referencedColumnName="id")
*/
private $feed;
/**
* Constructor
*/
public function __construct()
{
$this->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->authorName = $authorName;
return $this;
}
/**
* Get author_name
*
* @return string
*/
public function getAuthorName()
{
return $this->authorName;
}
/**
* Set author_email
*
* @param string $authorEmail
* @return FeedEntry
*/
public function setAuthorEmail($authorEmail)
{
$this->authorEmail = $authorEmail;
return $this;
}
/**
* Get author_email
*
* @return string
*/
public function getAuthorEmail()
{
return $this->authorEmail;
}
/**
* Set created
*
* @param \DateTime $createdOn
* @return FeedEntry
*/
public function setCreatedOn($createdOn)
{
$this->createdOn = $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->updatedOn = $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;
}
/**
* Returns a boolean indicating whether the given User_Adapter is the publisher of the entry.
*
* @param \User_Adapter $user
*
* @return boolean
*/
public function isPublisher(\User_Adapter $user)
{
if ($this->publisher) {
if ($this->publisher->getUsrId() === $user->get_id()) {
return true;
}
}
return false;
}
/**
* Returns the item from a given id.
*
* @param int $id
*
* @return null
*/
public function getItem($id)
{
foreach ($this->items as $item) {
if ($item->getId() == $id) {
return ($item);
}
}
return null;
}
}

View File

@@ -0,0 +1,233 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="FeedItems", uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={"entry_id","sbas_id","record_id"})})
* @ORM\Entity(repositoryClass="Repositories\FeedItemRepository")
* @ORM\HasLifecycleCallbacks
*/
class FeedItem
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="integer", name="record_id")
*/
private $recordId;
/**
* @ORM\Column(type="integer", name="sbas_id")
*/
private $sbasId;
/**
* @ORM\Column(type="integer")
*/
private $ord;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime", name="created_on")
*/
private $createdOn;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime", name="updated_on")
*/
private $updatedOn;
/**
* @ORM\ManyToOne(targetEntity="FeedEntry", inversedBy="items", cascade={"persist"})
* @ORM\JoinColumn(name="entry_id", referencedColumnName="id")
*/
private $entry;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set record_id
*
* @param integer $recordId
* @return FeedItem
*/
public function setRecordId($recordId)
{
$this->recordId = $recordId;
return $this;
}
/**
* Get record_id
*
* @return integer
*/
public function getRecordId()
{
return $this->recordId;
}
/**
* Set sbas_id
*
* @param integer $sbasId
* @return FeedItem
*/
public function setSbasId($sbasId)
{
$this->sbasId = $sbasId;
return $this;
}
/**
* Get sbas_id
*
* @return integer
*/
public function getSbasId()
{
return $this->sbasId;
}
/**
* 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;
}
/**
* Set ord
*
* @param integer $ord
* @return FeedItem
*/
public function setOrd($ord)
{
$this->ord = $ord;
return $this;
}
/**
* Get ord
*
* @return integer
*/
public function getOrd()
{
return $this->ord;
}
/**
* Set created_on
*
* @param \DateTime $createdOn
* @return FeedItem
*/
public function setCreatedOn($createdOn)
{
$this->createdOn = $createdOn;
return $this;
}
/**
* Get created_on
*
* @return \DateTime
*/
public function getCreatedOn()
{
return $this->createdOn;
}
/**
* Set updated_on
*
* @param \DateTime $updatedOn
* @return FeedItem
*/
public function setUpdatedOn($updatedOn)
{
$this->updatedOn = $updatedOn;
return $this;
}
/**
* Get updated_on
*
* @return \DateTime
*/
public function getUpdatedOn()
{
return $this->updatedOn;
}
/**
* @ORM\PrePersist
*/
public function setLastInFeedItem()
{
$this->setOrd($this->getEntry()->getItems()->count() + 1);
}
/**
* Returns the record_adapter associated to this FeedItem.
*
* @param Application $app
*
* @return \record_adapter
*/
public function getRecord(Application $app)
{
return new \record_adapter($app, $this->getSbasId(), $this->getRecordId(), $this->getOrd());
}
}

View File

@@ -0,0 +1,166 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="FeedPublishers")
* @ORM\Entity(repositoryClass="Repositories\FeedPublisherRepository")
*/
class FeedPublisher
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="integer", name="usr_id")
*/
private $usrId;
/**
* @ORM\Column(type="boolean")
*/
private $owner = false;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime", name="created_on")
*/
private $createdOn;
/**
* @ORM\ManyToOne(targetEntity="Feed", inversedBy="publishers", cascade={"persist"})
* @ORM\JoinColumn(name="feed_id", referencedColumnName="id")
*/
private $feed;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set usr_id
*
* @param integer $usrId
* @return FeedPublisher
*/
public function setUsrId($usrId)
{
$this->usrId = $usrId;
return $this;
}
/**
* Get usr_id
*
* @return integer
*/
public function getUsrId()
{
return $this->usrId;
}
/**
* Set owner
*
* @param boolean $owner
* @return FeedPublisher
*/
public function setIsOwner($owner)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* @return boolean
*/
public function isOwner()
{
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;
}
/**
* Get user
*
* @return \User_Adapter
*/
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->createdOn = $createdOn;
return $this;
}
/**
* Get created_on
*
* @return \DateTime
*/
public function getCreatedOn()
{
return $this->createdOn;
}
}

View File

@@ -0,0 +1,124 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="FeedTokens")
* @ORM\Entity(repositoryClass="Repositories\FeedTokenRepository")
*/
class FeedToken
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="integer", name="usr_id")
*/
private $usrId;
/**
* @ORM\Column(type="string", length=12, nullable=true)
*/
private $value;
/**
* @ORM\ManyToOne(targetEntity="Feed", inversedBy="tokens", cascade={"persist"})
* @ORM\JoinColumn(name="feed_id", referencedColumnName="id")
*/
private $feed;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set usr_id
*
* @param integer $usrId
* @return FeedToken
*/
public function setUsrId($usrId)
{
$this->usrId = $usrId;
return $this;
}
/**
* Get usr_id
*
* @return integer
*/
public function getUsrId()
{
return $this->usrId;
}
/**
* 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;
}
/**
* Set value
*
* @param string $value
* @return FeedToken
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class AggregateToken extends \Entities\AggregateToken implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setUsrId($usrId)
{
$this->__load();
return parent::setUsrId($usrId);
}
public function getUsrId()
{
$this->__load();
return parent::getUsrId();
}
public function setValue($value)
{
$this->__load();
return parent::setValue($value);
}
public function getValue()
{
$this->__load();
return parent::getValue();
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'usrId', 'value');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,202 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class Category extends \Entities\Category implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getTranslations()
{
$this->__load();
return parent::getTranslations();
}
public function getTranslation($locale)
{
$this->__load();
return parent::getTranslation($locale);
}
public function addTranslation(\Entities\CategoryTranslation $t)
{
$this->__load();
return parent::addTranslation($t);
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setTitle($title)
{
$this->__load();
return parent::setTitle($title);
}
public function getTitle()
{
$this->__load();
return parent::getTitle();
}
public function setSubtitle($subtitle)
{
$this->__load();
return parent::setSubtitle($subtitle);
}
public function getSubtitle()
{
$this->__load();
return parent::getSubtitle();
}
public function setParent($parent)
{
$this->__load();
return parent::setParent($parent);
}
public function getParent()
{
$this->__load();
return parent::getParent();
}
public function getRoot()
{
$this->__load();
return parent::getRoot();
}
public function getLevel()
{
$this->__load();
return parent::getLevel();
}
public function getChildren()
{
$this->__load();
return parent::getChildren();
}
public function getLeft()
{
$this->__load();
return parent::getLeft();
}
public function getRight()
{
$this->__load();
return parent::getRight();
}
public function getCreated()
{
$this->__load();
return parent::getCreated();
}
public function getUpdated()
{
$this->__load();
return parent::getUpdated();
}
public function getCreatedBy()
{
$this->__load();
return parent::getCreatedBy();
}
public function getUpdatedBy()
{
$this->__load();
return parent::getUpdatedBy();
}
public function __toString()
{
$this->__load();
return parent::__toString();
}
public function addElement(\Entities\CategoryElement $elements)
{
$this->__load();
return parent::addElement($elements);
}
public function removeElement(\Entities\CategoryElement $elements)
{
$this->__load();
return parent::removeElement($elements);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'title', 'subtitle', 'lft', 'rgt', 'root', 'level', 'parent', 'children', 'translations', 'elements');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,292 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class Feed extends \Entities\Feed implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setIsPublic($public)
{
$this->__load();
return parent::setIsPublic($public);
}
public function isPublic()
{
$this->__load();
return parent::isPublic();
}
public function setIconUrl($iconUrl)
{
$this->__load();
return parent::setIconUrl($iconUrl);
}
public function getIconUrl()
{
$this->__load();
return parent::getIconUrl();
}
public function setBaseId($baseId)
{
$this->__load();
return parent::setBaseId($baseId);
}
public function getBaseId()
{
$this->__load();
return parent::getBaseId();
}
public function setTitle($title)
{
$this->__load();
return parent::setTitle($title);
}
public function getTitle()
{
$this->__load();
return parent::getTitle();
}
public function addPublisher(\Entities\FeedPublisher $publishers)
{
$this->__load();
return parent::addPublisher($publishers);
}
public function removePublisher(\Entities\FeedPublisher $publishers)
{
$this->__load();
return parent::removePublisher($publishers);
}
public function getPublishers()
{
$this->__load();
return parent::getPublishers();
}
public function addEntry(\Entities\FeedEntry $entries)
{
$this->__load();
return parent::addEntry($entries);
}
public function removeEntry(\Entities\FeedEntry $entries)
{
$this->__load();
return parent::removeEntry($entries);
}
public function getEntries($offset_start = 0, $how_many = NULL)
{
$this->__load();
return parent::getEntries($offset_start, $how_many);
}
public function getOwner()
{
$this->__load();
return parent::getOwner();
}
public function isOwner(\User_Adapter $user)
{
$this->__load();
return parent::isOwner($user);
}
public function getCollection(\Alchemy\Phrasea\Application $app)
{
$this->__load();
return parent::getCollection($app);
}
public function setCollection(\collection $collection = NULL)
{
$this->__load();
return parent::setCollection($collection);
}
public function setCreatedOn($createdOn)
{
$this->__load();
return parent::setCreatedOn($createdOn);
}
public function getCreatedOn()
{
$this->__load();
return parent::getCreatedOn();
}
public function setUpdatedOn($updatedOn)
{
$this->__load();
return parent::setUpdatedOn($updatedOn);
}
public function getUpdatedOn()
{
$this->__load();
return parent::getUpdatedOn();
}
public function isPublisher(\User_Adapter $user)
{
$this->__load();
return parent::isPublisher($user);
}
public function getPublisher(\User_Adapter $user)
{
$this->__load();
return parent::getPublisher($user);
}
public function setSubtitle($subtitle)
{
$this->__load();
return parent::setSubtitle($subtitle);
}
public function getSubtitle()
{
$this->__load();
return parent::getSubtitle();
}
public function isAggregated()
{
$this->__load();
return parent::isAggregated();
}
public function getCountTotalEntries()
{
$this->__load();
return parent::getCountTotalEntries();
}
public function hasAccess(\User_Adapter $user, \Alchemy\Phrasea\Application $app)
{
$this->__load();
return parent::hasAccess($user, $app);
}
public function addToken(\Entities\FeedToken $tokens)
{
$this->__load();
return parent::addToken($tokens);
}
public function removeToken(\Entities\FeedToken $tokens)
{
$this->__load();
return parent::removeToken($tokens);
}
public function getTokens()
{
$this->__load();
return parent::getTokens();
}
public function addEntrie(\Entities\FeedEntry $entries)
{
$this->__load();
return parent::addEntrie($entries);
}
public function removeEntrie(\Entities\FeedEntry $entries)
{
$this->__load();
return parent::removeEntrie($entries);
}
public function hasPage($pageNumber, $nbEntriesByPage)
{
$this->__load();
return parent::hasPage($pageNumber, $nbEntriesByPage);
}
public function isAccessible(\User_Adapter $user, \Alchemy\Phrasea\Application $app)
{
$this->__load();
return parent::isAccessible($user, $app);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'public', 'iconUrl', 'baseId', 'title', 'subtitle', 'createdOn', 'updatedOn', 'publishers', 'entries', 'tokens');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,202 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class FeedEntry extends \Entities\FeedEntry implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setTitle($title)
{
$this->__load();
return parent::setTitle($title);
}
public function getTitle()
{
$this->__load();
return parent::getTitle();
}
public function setSubtitle($subtitle)
{
$this->__load();
return parent::setSubtitle($subtitle);
}
public function getSubtitle()
{
$this->__load();
return parent::getSubtitle();
}
public function setAuthorName($authorName)
{
$this->__load();
return parent::setAuthorName($authorName);
}
public function getAuthorName()
{
$this->__load();
return parent::getAuthorName();
}
public function setAuthorEmail($authorEmail)
{
$this->__load();
return parent::setAuthorEmail($authorEmail);
}
public function getAuthorEmail()
{
$this->__load();
return parent::getAuthorEmail();
}
public function setCreatedOn($createdOn)
{
$this->__load();
return parent::setCreatedOn($createdOn);
}
public function getCreatedOn()
{
$this->__load();
return parent::getCreatedOn();
}
public function setUpdatedOn($updatedOn)
{
$this->__load();
return parent::setUpdatedOn($updatedOn);
}
public function getUpdatedOn()
{
$this->__load();
return parent::getUpdatedOn();
}
public function addItem(\Entities\FeedItem $items)
{
$this->__load();
return parent::addItem($items);
}
public function removeItem(\Entities\FeedItem $items)
{
$this->__load();
return parent::removeItem($items);
}
public function getItems()
{
$this->__load();
return parent::getItems();
}
public function setPublisher(\Entities\FeedPublisher $publisher = NULL)
{
$this->__load();
return parent::setPublisher($publisher);
}
public function getPublisher()
{
$this->__load();
return parent::getPublisher();
}
public function setFeed(\Entities\Feed $feed = NULL)
{
$this->__load();
return parent::setFeed($feed);
}
public function getFeed()
{
$this->__load();
return parent::getFeed();
}
public function isPublisher(\User_Adapter $user)
{
$this->__load();
return parent::isPublisher($user);
}
public function getItem($id)
{
$this->__load();
return parent::getItem($id);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'title', 'subtitle', 'authorName', 'authorEmail', 'createdOn', 'updatedOn', 'items', 'publisher', 'feed');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,160 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class FeedItem extends \Entities\FeedItem implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setRecordId($recordId)
{
$this->__load();
return parent::setRecordId($recordId);
}
public function getRecordId()
{
$this->__load();
return parent::getRecordId();
}
public function setSbasId($sbasId)
{
$this->__load();
return parent::setSbasId($sbasId);
}
public function getSbasId()
{
$this->__load();
return parent::getSbasId();
}
public function setEntry(\Entities\FeedEntry $entry = NULL)
{
$this->__load();
return parent::setEntry($entry);
}
public function getEntry()
{
$this->__load();
return parent::getEntry();
}
public function setOrd($ord)
{
$this->__load();
return parent::setOrd($ord);
}
public function getOrd()
{
$this->__load();
return parent::getOrd();
}
public function setCreatedOn($createdOn)
{
$this->__load();
return parent::setCreatedOn($createdOn);
}
public function getCreatedOn()
{
$this->__load();
return parent::getCreatedOn();
}
public function setUpdatedOn($updatedOn)
{
$this->__load();
return parent::setUpdatedOn($updatedOn);
}
public function getUpdatedOn()
{
$this->__load();
return parent::getUpdatedOn();
}
public function setLastInFeedItem()
{
$this->__load();
return parent::setLastInFeedItem();
}
public function getRecord(\Alchemy\Phrasea\Application $app)
{
$this->__load();
return parent::getRecord($app);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'recordId', 'sbasId', 'ord', 'createdOn', 'updatedOn', 'entry');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class FeedPublisher extends \Entities\FeedPublisher implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setUsrId($usrId)
{
$this->__load();
return parent::setUsrId($usrId);
}
public function getUsrId()
{
$this->__load();
return parent::getUsrId();
}
public function setIsOwner($owner)
{
$this->__load();
return parent::setIsOwner($owner);
}
public function isOwner()
{
$this->__load();
return parent::isOwner();
}
public function setFeed(\Entities\Feed $feed = NULL)
{
$this->__load();
return parent::setFeed($feed);
}
public function getFeed()
{
$this->__load();
return parent::getFeed();
}
public function getUser(\Alchemy\Phrasea\Application $app)
{
$this->__load();
return parent::getUser($app);
}
public function setCreatedOn($createdOn)
{
$this->__load();
return parent::setCreatedOn($createdOn);
}
public function getCreatedOn()
{
$this->__load();
return parent::getCreatedOn();
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'usrId', 'owner', 'createdOn', 'feed');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace Proxies\__CG__\Entities;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class FeedToken extends \Entities\FeedToken implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
public $__isInitialized__ = false;
public function __construct($entityPersister, $identifier)
{
$this->_entityPersister = $entityPersister;
$this->_identifier = $identifier;
}
/** @private */
public function __load()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
if (method_exists($this, "__wakeup")) {
// call this after __isInitialized__to avoid infinite recursion
// but before loading to emulate what ClassMetadata::newInstance()
// provides.
$this->__wakeup();
}
if ($this->_entityPersister->load($this->_identifier, $this) === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
unset($this->_entityPersister, $this->_identifier);
}
}
/** @private */
public function __isInitialized()
{
return $this->__isInitialized__;
}
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) $this->_identifier["id"];
}
$this->__load();
return parent::getId();
}
public function setUsrId($usrId)
{
$this->__load();
return parent::setUsrId($usrId);
}
public function getUsrId()
{
$this->__load();
return parent::getUsrId();
}
public function setFeed(\Entities\Feed $feed = NULL)
{
$this->__load();
return parent::setFeed($feed);
}
public function getFeed()
{
$this->__load();
return parent::getFeed();
}
public function setValue($value)
{
$this->__load();
return parent::setValue($value);
}
public function getValue()
{
$this->__load();
return parent::getValue();
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'usrId', 'value', 'feed');
}
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields as $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
}
}

View File

@@ -0,0 +1,24 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Doctrine\ORM\EntityRepository;
/**
* AggregateTokenRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class AggregateTokenRepository extends EntityRepository
{
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Repositories;
use Doctrine\ORM\EntityRepository;
/**
* FeedEntryRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FeedEntryRepository extends EntityRepository
{
/**
* Returns a collection of FeedEntry from given feeds, limited to $how_many results, starting with $offset_start
*
* @param array $feeds
* @param integer $offset_start
* @param integer $how_many
*
* @return \Doctrine\Common\Collections\Collection
*/
public function findByFeeds($feeds, $offset_start = null, $how_many = null)
{
$dql = 'SELECT f FROM Entities\FeedEntry f
WHERE f.feed IN (:feeds) order by f.updatedOn DESC';
$query = $this->_em->createQuery($dql);
$query->setParameter('feeds', $feeds);
if (null !== $offset_start && 0 !== $offset_start) {
$query->setFirstResult($offset_start);
}
if (null !== $how_many) {
$query->setMaxResults($how_many);
}
return $query->getResult();
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Repositories;
use Doctrine\ORM\EntityRepository;
/**
* FeedItemRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FeedItemRepository extends EntityRepository
{
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Repositories;
use Doctrine\ORM\EntityRepository;
use Entities\Feed;
use Entities\FeedPublisher;
/**
* FeedPublisherRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FeedPublisherRepository extends EntityRepository
{
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Repositories;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityRepository;
use Entities\Feed;
/**
* FeedRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FeedRepository extends EntityRepository
{
/**
* Returns all the feeds a user can access.
*
* @param User_Adapter $user
* @return \Doctrine\Common\Collections\Collection
*/
public function getAllForUser(\User_Adapter $user)
{
$base_ids = array_keys($user->ACL()->get_granted_base());
$qb = $this
->createQueryBuilder('f');
$qb->where($qb->expr()->isNull('f.baseId'))
->orWhere('f.public = true');
if (count($base_ids) > 0) {
$qb->orWhere($qb->expr()->in('f.baseId', $base_ids));
}
$qb->orderBy('f.updatedOn', 'DESC');
return $qb->getQuery()->getResult();
}
/**
* Returns all the feeds from a given array containing their id.
*
* @param array $feedIds
* @return Collection
*/
public function findByIds(array $feedIds)
{
$qb = $this->createQueryBuilder('f');
if (!empty($feedIds)) {
$qb->Where($qb->expr()->in('f.id', $feedIds));
}
$qb->orderBy('f.updatedOn', 'DESC');
return $qb->getQuery()->getResult();
}
}

View File

@@ -0,0 +1,24 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Doctrine\ORM\EntityRepository;
/**
* FeedTokenRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FeedTokenRepository extends EntityRepository
{
}

View File

@@ -1,5 +1,14 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Doctrine\ORM\EntityRepository;

View File

@@ -1,5 +1,14 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Doctrine\ORM\EntityRepository;

View File

@@ -1,7 +1,17 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Alchemy\Phrasea\Application;
use Doctrine\ORM\EntityRepository;
/**

View File

@@ -1,5 +1,14 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Repositories;
use Doctrine\ORM\EntityRepository;
@@ -12,4 +21,33 @@ use Doctrine\ORM\EntityRepository;
*/
class UserSettingRepository extends EntityRepository
{
/**
* Returns a collection of FeedEntry from given feeds, limited to $how_many results, starting with $offset_start
*
* @param array $feeds
* @param integer $offsetStart
* @param integer $howMany
*
* @return \Doctrine\Common\Collections\Collection
*/
public function findByFeeds($feeds, $offsetStart = null, $perPage = null)
{
$qb = $this->createQueryBuilder('f');
if (!empty($feeds)) {
$qb->Where($qb->expr()->in('f.feed', $feeds));
}
$qb->orderBy('f.updatedOn', 'DESC');
if ($offsetStart) {
$qb->setFirstResult(max(0, (int) $offsetStart));
}
if ($perPage) {
$qb->setMaxResults(max(5, (int) $perPage));
}
return $qb->getQuery()->getResult();
}
}

View File

@@ -9,11 +9,16 @@
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Feed\FeedInterface;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border\File;
use Alchemy\Phrasea\Border\Attribute\Status;
use Alchemy\Phrasea\Border\Manager as BorderManager;
use Entities\Feed;
use Entities\FeedEntry;
use Entities\FeedItem;
use Entities\UserQuery;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -1479,10 +1484,10 @@ class API_V1_adapter extends API_V1_Abstract
{
$result = new API_V1_result($this->app, $request, $this);
$coll = Feed_Collection::load_all($this->app, $user);
$coll = $this->app['EM']->getRepository('Entities\Feed')->getAllForUser($user);
$datas = array();
foreach ($coll->get_feeds() as $feed) {
foreach ($coll as $feed) {
$datas[] = $this->list_publication($feed, $user);
}
@@ -1512,8 +1517,10 @@ class API_V1_adapter extends API_V1_Abstract
{
$result = new API_V1_result($this->app, $request, $this);
$feed = Feed_Adapter::load_with_user($this->app, $user, $publication_id);
$feed = $this->app['EM']->getRepository('Entities\Feed')->find($publication_id);
if (!$feed->isAccessible($user, $this->app)) {
return $result->set_datas(array());
}
$offset_start = (int) ($request->get('offset_start') ? : 0);
$per_page = (int) ($request->get('per_page') ? : 5);
@@ -1535,7 +1542,7 @@ class API_V1_adapter extends API_V1_Abstract
{
$result = new API_V1_result($this->app, $request, $this);
$feed = Feed_Aggregate::load_with_user($this->app, $user);
$feed = Aggregate::createFromUser($this->app['EM'], $user);
$offset_start = (int) ($request->get('offset_start') ? : 0);
$per_page = (int) ($request->get('per_page') ? : 5);
@@ -1543,7 +1550,7 @@ class API_V1_adapter extends API_V1_Abstract
$per_page = (($per_page >= 1) && ($per_page <= 20)) ? $per_page : 5;
$datas = array(
'total_entries' => $feed->get_count_total_entries(),
'total_entries' => $feed->getCountTotalEntries(),
'offset_start' => $offset_start,
'per_page' => $per_page,
'entries' => $this->list_publications_entries($feed, $offset_start, $per_page),
@@ -1558,9 +1565,9 @@ class API_V1_adapter extends API_V1_Abstract
{
$result = new API_V1_result($this->app, $request, $this);
$entry = Feed_Entry_Adapter::load_from_id($this->app, $entry_id);
$entry = $this->app['EM']->getRepository('Entities\FeedEntry')->find($entry_id);
$collection = $entry->get_feed()->get_collection();
$collection = $entry->getFeed()->getCollection($this->app);
if (null !== $collection && !$user->ACL()->has_access_to_base($collection->get_base_id())) {
throw new \API_V1_exception_forbidden('You have not access to the parent feed');
@@ -1578,38 +1585,38 @@ class API_V1_adapter extends API_V1_Abstract
/**
* Retrieve detailled informations about one feed
*
* @param Feed_Adapter $feed
* @param Feed $feed
* @param type $user
* @return array
*/
protected function list_publication(Feed_Adapter $feed, $user)
protected function list_publication(Feed $feed, $user)
{
return array(
'id' => $feed->get_id(),
'title' => $feed->get_title(),
'subtitle' => $feed->get_subtitle(),
'total_entries' => $feed->get_count_total_entries(),
'icon' => $feed->get_icon_url(),
'public' => $feed->is_public(),
'readonly' => !$feed->is_publisher($user),
'deletable' => $feed->is_owner($user),
'created_on' => $feed->get_created_on()->format(DATE_ATOM),
'updated_on' => $feed->get_updated_on()->format(DATE_ATOM),
'id' => $feed->getId(),
'title' => $feed->getTitle(),
'subtitle' => $feed->getSubtitle(),
'total_entries' => $feed->getCountTotalEntries(),
'icon' => $feed->getIconUrl(),
'public' => $feed->isPublic(),
'readonly' => !$feed->isPublisher($user),
'deletable' => $feed->isOwner($user),
'created_on' => $feed->getCreatedOn()->format(DATE_ATOM),
'updated_on' => $feed->getUpdatedOn()->format(DATE_ATOM),
);
}
/**
* Retrieve all entries of one feed
*
* @param Feed_Adapter $feed
* @param FeedInterface $feed
* @param int $offset_start
* @param int $how_many
* @return array
*/
protected function list_publications_entries(Feed_Abstract $feed, $offset_start = 0, $how_many = 5)
protected function list_publications_entries(FeedInterface $feed, $offset_start = 0, $how_many = 5)
{
$entries = $feed->get_entries($offset_start, $how_many)->get_entries();
$entries = $feed->getEntries($offset_start, $how_many);
$out = array();
foreach ($entries as $entry) {
@@ -1622,42 +1629,42 @@ class API_V1_adapter extends API_V1_Abstract
/**
* Retrieve detailled information about one feed entry
*
* @param Feed_Entry_Adapter $entry
* @param FeedEntry $entry
* @return array
*/
protected function list_publication_entry(Feed_Entry_Adapter $entry)
protected function list_publication_entry(FeedEntry $entry)
{
$items = array();
foreach ($entry->get_content() as $item) {
foreach ($entry->getItems() as $item) {
$items[] = $this->list_publication_entry_item($item);
}
return array(
'id' => $entry->get_id(),
'author_email' => $entry->get_author_email(),
'author_name' => $entry->get_author_name(),
'created_on' => $entry->get_created_on()->format(DATE_ATOM),
'updated_on' => $entry->get_updated_on()->format(DATE_ATOM),
'title' => $entry->get_title(),
'subtitle' => $entry->get_subtitle(),
'id' => $entry->getId(),
'author_email' => $entry->getAuthorEmail(),
'author_name' => $entry->getAuthorName(),
'created_on' => $entry->getCreatedOn()->format(DATE_ATOM),
'updated_on' => $entry->getUpdatedOn()->format(DATE_ATOM),
'title' => $entry->getTitle(),
'subtitle' => $entry->getSubtitle(),
'items' => $items,
'feed_id' => $entry->get_feed()->get_id(),
'feed_url' => '/feeds/' . $entry->get_feed()->get_id() . '/content/',
'url' => '/feeds/entry/' . $entry->get_id() . '/',
'feed_id' => $entry->getFeed()->getId(),
'feed_url' => '/feeds/' . $entry->getFeed()->getId() . '/content/',
'url' => '/feeds/entry/' . $entry->getId() . '/',
);
}
/**
* Retrieve detailled informations about one feed entry item
*
* @param Feed_Entry_Item $item
* @param FeedItem $item
* @return array
*/
protected function list_publication_entry_item(Feed_Entry_Item $item)
protected function list_publication_entry_item(FeedItem $item)
{
$datas = array(
'item_id' => $item->get_id()
, 'record' => $this->list_record($item->get_record())
'item_id' => $item->getId()
, 'record' => $this->list_record($item->getRecord($this->app))
);
return $datas;

View File

@@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Exception_Feed_EntryNotFound extends NotFoundHttpException
class Exception_FeedEntryNotFound extends NotFoundHttpException
{
}

View File

@@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Exception_Feed_ItemNotFound extends NotFoundHttpException
class Exception_FeedItemNotFound extends NotFoundHttpException
{
}

View File

@@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Exception_Feed_PublisherNotFound extends NotFoundHttpException
class Exception_FeedPublisherNotFound extends NotFoundHttpException
{
}

View File

@@ -1,98 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
abstract class Feed_Abstract
{
/**
*
*/
const FORMAT_RSS = 'rss';
/**
*
*/
const FORMAT_ATOM = 'atom';
/**
*
*/
const FORMAT_COOLIRIS = 'cooliris';
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $subtitle;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var DateTime
*/
protected $updated_on;
/**
*
* @return string
*/
public function get_title()
{
return $this->title;
}
/**
*
* @return string
*/
public function get_subtitle()
{
return $this->subtitle;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return DateTime
*/
public function get_updated_on()
{
return $this->updated_on;
}
}

View File

@@ -1,722 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Adapter extends Feed_Abstract implements Feed_Interface, cache_cacheableInterface
{
/**
*
* @var int
*/
protected $id;
/**
*
* @var collection
*/
protected $collection;
/**
*
* @var array
*/
protected $publishers;
/**
*
* @var boolean
*/
protected $public;
/**
*
* @var Feed_Publisher_Adapter
*/
protected $owner;
/**
*
* @var string
*/
protected $icon_url;
const CACHE_ENTRY_NUMBER = 'entrynumber';
const CACHE_USER_TOKEN = 'usr_token';
const MAX_ENTRIES = 20;
public function __construct(Application $app, $id)
{
$this->app = $app;
$this->id = (int) $id;
$this->load();
return $this;
}
protected function load()
{
try {
$datas = $this->get_data_from_cache();
$this->title = $datas['title'];
$this->subtitle = $datas['subtitle'];
$this->collection = $datas['base_id'] ? collection::get_from_base_id($this->app, $datas['base_id']) : null;
$this->created_on = $datas['created_on'];
$this->updated_on = $datas['updated_on'];
$this->public = $datas['public'];
return $this;
} catch (Exception $e) {
}
$sql = 'SELECT id, title, subtitle, created_on, updated_on, base_id, public
FROM feeds WHERE id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new NotFoundHttpException('Feed not found');
$this->title = $row['title'];
$this->subtitle = $row['subtitle'];
if (!is_null($row['base_id']))
$this->collection = collection::get_from_base_id($this->app, $row['base_id']);
$this->created_on = new DateTime($row['created_on']);
$this->updated_on = new DateTime($row['updated_on']);
$this->public = !!$row['public'];
$base_id = $this->collection instanceof collection ? $this->collection->get_base_id() : null;
$datas = array(
'title' => $this->title
, 'subtitle' => $this->subtitle
, 'base_id' => $base_id
, 'created_on' => $this->created_on
, 'updated_on' => $this->updated_on
, 'public' => $this->public
);
$this->set_data_to_cache($datas);
return $this;
}
/**
*
* @return string
*/
public function get_icon_url()
{
if ($this->icon_url) {
return $this->icon_url;
}
$url = '/skins/icons/rss32.gif';
$file = $this->app['root.path']
. '/www/custom/feed_' . $this->get_id() . '.jpg';
if (file_exists($file)) {
$url = '/custom/feed_' . $this->get_id() . '.jpg';
}
$this->icon_url = $url;
return $this->icon_url;
}
/**
*
* @param string $file The path to the file
* @return Feed_Adapter
*/
public function set_icon($file)
{
if (!file_exists($file)) {
throw new \Alchemy\Phrasea\Exception\InvalidArgumentException('File does not exists');
}
$config_file = $this->app['root.path'] . '/config/feed_' . $this->get_id() . '.jpg';
$www_file = $this->app['root.path'] . '/www/custom/feed_' . $this->get_id() . '.jpg';
copy($file, $config_file);
copy($file, $www_file);
$this->icon_url = null;
return $this;
}
public function set_created_on(DateTime $created_on)
{
$sql = 'UPDATE feeds SET created_on = :created_on
WHERE id = :feed_id';
$params = array(
':created_on' => $created_on->format(DATE_ISO8601)
, ':feed_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->created_on = $created_on;
$this->delete_data_from_cache();
return $this;
}
public function reset_icon()
{
$config_file = $this->app['root.path']
. '/config/feed_' . $this->get_id() . '.jpg';
$www_file = $this->app['root.path']
. '/www/custom/feed_' . $this->get_id() . '.jpg';
if (is_file($config_file))
unlink($config_file);
if (is_file($www_file))
unlink($www_file);
$this->icon_url = null;
return $this;
}
/**
*
* @return boolean
*/
public function is_aggregated()
{
return false;
}
/**
*
* @param User_Adapter $user
* @return boolean
*/
public function is_owner(User_Adapter $user)
{
$this->load_publishers();
if (!$this->owner) {
return false;
}
return $this->owner->get_user()->get_id() === $user->get_id();
}
/**
*
* @param User_Adapter $user
* @return boolean
*/
public function is_publisher(User_Adapter $user)
{
return in_array($user->get_id(), array_keys($this->get_publishers()));
}
/**
* Tells if a user has access to the feed
*
* @param User_Adapter $user
* @return type
*/
public function has_access(User_Adapter $user)
{
if ($this->get_collection() instanceof collection) {
return $user->ACL()->has_access_to_base($this->collection->get_base_id());
}
return true;
}
/**
*
* @return boolean
*/
public function is_public()
{
if ($this->get_collection() instanceof collection) {
return false;
}
return $this->public;
}
/**
*
* @return array
*/
public function get_publishers()
{
return $this->load_publishers();
}
/**
*
* @return collection
*/
public function get_collection()
{
return $this->collection;
}
/**
*
* @param User_Adapter $user
* @return Feed_Adapter
*/
public function add_publisher(User_Adapter $user)
{
if (in_array($user->get_id(), array_keys($this->get_publishers()))) {
return $this;
}
Feed_Publisher_Adapter::create($this->app, $user, $this, false);
$this->publishers = null;
return $this;
}
/**
*
* @return array
*/
protected function load_publishers()
{
if (is_array($this->publishers)) {
return $this->publishers;
}
$sql = 'SELECT id, usr_id, owner FROM feed_publishers
WHERE feed_id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_id' => $this->id));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach ($rs as $row) {
try {
$publisher = new Feed_Publisher_Adapter($this->app, $row['id']);
} catch (\Exception_Feed_PublisherNotFound $e) {
continue;
}
$this->publishers[$row['usr_id']] = $publisher;
if ($publisher->is_owner()) {
$this->owner = $publisher;
}
}
return $this->publishers;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @param collection $collection
* @return Feed_Adapter
*/
public function set_collection(collection $collection = null)
{
$base_id = null;
if ($collection instanceof collection) {
$base_id = $collection->get_base_id();
}
$sql = 'UPDATE feeds SET base_id = :base_id, updated_on = NOW()
WHERE id = :feed_id';
$params = array(':base_id' => $base_id, ':feed_id' => $this->get_id());
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->collection = $collection;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param boolean $boolean
* @return Feed_Adapter
*/
public function set_public($boolean)
{
$boolean = !!$boolean;
$sql = 'UPDATE feeds SET public = :public, updated_on = NOW()
WHERE id = :feed_id';
$params = array(
':public' => $boolean ? '1' : '0',
':feed_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->public = $boolean;
$this->delete_data_from_cache();
$feed_collection = new Feed_Collection($this->app, array());
$feed_collection->delete_data_from_cache(Feed_Collection::CACHE_PUBLIC);
return $this;
}
/**
*
* @param string $title
* @return Feed_Adapter
*/
public function set_title($title)
{
$title = trim(strip_tags($title));
if ($title === '')
throw new Exception_InvalidArgument();
$sql = 'UPDATE feeds SET title = :title, updated_on = NOW()
WHERE id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':title' => $title, ':feed_id' => $this->get_id()));
$stmt->closeCursor();
$this->title = $title;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param string $subtitle
* @return Feed_Adapter
*/
public function set_subtitle($subtitle)
{
$subtitle = strip_tags($subtitle);
$sql = 'UPDATE feeds SET subtitle = :subtitle, updated_on = NOW()
WHERE id = :feed_id';
$params = array(':subtitle' => $subtitle, ':feed_id' => $this->get_id());
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->subtitle = $subtitle;
$this->delete_data_from_cache();
return $this;
}
public static function create(Application $app, User_Adapter $user, $title, $subtitle)
{
$sql = 'INSERT INTO feeds (id, title, subtitle, created_on, updated_on)
VALUES (null, :title, :subtitle, NOW(), NOW())';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':title' => $title, ':subtitle' => $subtitle));
$stmt->closeCursor();
$feed_id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
$feed = new self($app, $feed_id);
Feed_Publisher_Adapter::create($app, $user, $feed, true);
return $feed;
}
public static function load_with_user(Application $app, User_Adapter $user, $id)
{
$feed = new self($app, $id);
$coll = $feed->get_collection();
if (
$feed->is_public()
|| $coll === null
|| in_array($coll->get_base_id(), array_keys($user->ACL()->get_granted_base()))
) {
return $feed;
}
throw new NotFoundHttpException('Feed not found');
}
/**
*
* @return int
*/
public function get_count_total_entries()
{
try {
return $this->get_data_from_cache(self::CACHE_ENTRY_NUMBER);
} catch (Exception $e) {
}
$sql = 'SELECT count(id) as number
FROM feed_entries WHERE feed_id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_id' => $this->get_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$number = $row ? (int) $row['number'] : 0;
$stmt->closeCursor();
$this->set_data_to_cache($number, self::CACHE_ENTRY_NUMBER);
return $number;
}
/**
*
* @return void
*/
public function delete()
{
$this->reset_icon();
while ($this->get_count_total_entries() > 0) {
$entries_coll = $this->get_entries(0, 10);
foreach ($entries_coll->get_entries() as $entry) {
$entry->delete();
}
unset($entries_coll);
$this->delete_data_from_cache(self::CACHE_ENTRY_NUMBER);
}
foreach ($this->get_publishers() as $publishers)
$publishers->delete();
$sql = 'DELETE FROM feed_tokens WHERE feed_id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_id' => $this->get_id()));
$stmt->closeCursor();
$sql = 'DELETE FROM feeds WHERE id = :feed_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_id' => $this->get_id()));
$stmt->closeCursor();
$this->delete_data_from_cache();
$feed_coll = new Feed_Collection($this->app, array());
$feed_coll->delete_data_from_cache(Feed_Collection::CACHE_PUBLIC);
return;
}
/**
*
* @param int $offset_start
* @param int $how_many
* @return Feed_Entry_Collection
*/
public function get_entries($offset_start, $how_many)
{
$offset_start = (int) $offset_start;
$how_many = $how_many > self::MAX_ENTRIES ? self::MAX_ENTRIES : (int) $how_many;
$sql = 'SELECT id
FROM feed_entries
WHERE feed_id = :feed_id
ORDER BY id DESC
LIMIT ' . $offset_start . ', ' . $how_many;
$params = array(
':feed_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$result = new Feed_Entry_Collection();
foreach ($rs as $row) {
$entry = new Feed_Entry_Adapter($this->app, $this, $row['id']);
$result->add_entry($entry);
}
return $result;
}
/**
*
* @param registryInterface $registry
* @param string $format
* @param int $page
* @return Feed_Link
*/
public function get_homepage_link(registryInterface $registry, $format, $page = null)
{
if (!$this->is_public()) {
return null;
}
switch ($format) {
case self::FORMAT_ATOM:
return new Feed_Link(
sprintf('%sfeeds/feed/%s/atom/%s'
, $registry->get('GV_ServerName')
, $this->get_id()
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'Atom')
, 'application/atom+xml'
);
break;
case self::FORMAT_RSS:
default:
return new Feed_Link(
sprintf('%sfeeds/feed/%s/rss/%s'
, $registry->get('GV_ServerName')
, $this->get_id()
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'RSS')
, 'application/rss+xml'
);
break;
}
}
/**
*
* @param User_Adapter $user
* @param boolean $renew
* @return string
*/
protected function get_token(User_Adapter $user, $renew = false)
{
$cache_key = self::CACHE_USER_TOKEN . '_' . $user->get_id();
try {
if (!$renew) {
return $this->get_data_from_cache($cache_key);
}
} catch (Exception $e) {
}
$sql = 'SELECT token FROM feed_tokens
WHERE usr_id = :usr_id AND feed_id = :feed_id
AND aggregated IS NULL';
$params = array(
':usr_id' => $user->get_id(),
':feed_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row || $renew === true) {
$token = random::generatePassword(12, random::LETTERS_AND_NUMBERS);
$sql = 'REPLACE INTO feed_tokens (id, token, feed_id, usr_id, aggregated)
VALUES (null, :token, :feed_id, :usr_id, :aggregated)';
$params = array(
':token' => $token
, ':feed_id' => $this->get_id()
, ':usr_id' => $user->get_id()
, ':aggregated' => null
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$this->delete_data_from_cache($cache_key);
} else {
$token = $row['token'];
}
$this->set_data_to_cache($token, $cache_key);
return $token;
}
/**
*
* @param registryInterface $registry
* @param User_Adapter $user
* @param string $format
* @param int $page
* @param boolean $renew_token
* @return Feed_Link
*/
public function get_user_link(registryInterface $registry, User_Adapter $user, $format, $page = null, $renew_token = false)
{
switch ($format) {
case self::FORMAT_ATOM:
return new Feed_Link(
sprintf('%sfeeds/userfeed/%s/%s/atom/'
, $registry->get('GV_ServerName')
, $this->get_token($user, $renew_token)
, $this->get_id()
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'Atom')
, 'application/atom+xml'
);
break;
case self::FORMAT_RSS:
return new Feed_Link(
sprintf('%sfeeds/userfeed/%s/%s/rss/%s'
, $registry->get('GV_ServerName')
, $this->get_token($user, $renew_token)
, $this->get_id()
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'RSS')
, 'application/rss+xml'
);
break;
}
}
public function get_cache_key($option = null)
{
return 'feed_adapter_' . $this->get_id() . '_' . ($option ? '_' . $option : '');
}
public function get_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->get_data_from_cache($this->get_cache_key($option));
}
public function set_data_to_cache($value, $option = null, $duration = 0)
{
return $this->app['phraseanet.appbox']->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
public function delete_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->delete_data_from_cache($this->get_cache_key($option));
}
}

View File

@@ -1,260 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Aggregate extends Feed_Abstract implements Feed_Interface
{
/**
*
* @var array
*/
protected $feeds;
public function __construct(Application $app, Array $feeds)
{
$this->title = 'AGGREGGATE';
$this->subtitle = 'AGREGGATE SUBTITLE';
$this->created_on = new DateTime();
$this->updated_on = new DateTime();
$this->app = $app;
$tmp_feeds = array();
foreach ($feeds as $feed) {
$tmp_feeds[$feed->get_id()] = $feed;
}
$this->feeds = $tmp_feeds;
return $this;
}
public function get_id()
{
throw new LogicException('Aggregate feed does not have an id');
}
/**
*
* @return string
*/
public function get_icon_url()
{
$url = '/skins/icons/rss32.gif';
return $url;
}
/**
*
* @return boolean
*/
public function is_aggregated()
{
return true;
}
/**
*
* @param int $offset_start
* @param int $how_many
* @return Feed_Entry_Collection
*/
public function get_entries($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;
$sql = 'SELECT id, feed_id
FROM feed_entries
WHERE feed_id IN (' . implode(', ', array_keys($this->feeds)) . ')
ORDER BY id DESC
LIMIT ' . $offset_start . ', ' . $how_many;
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach ($rs as $row) {
$entry = new Feed_Entry_Adapter($this->app, $this->feeds[$row['feed_id']], $row['id']);
$result->add_entry($entry);
}
return $result;
}
/**
*
* @return int
*/
public function get_count_total_entries()
{
if (count($this->feeds) === 0) {
return 0;
}
$sql = 'SELECT count(id) as number
FROM feed_entries
WHERE feed_id
IN (' . implode(', ', array_keys($this->feeds)) . ') ';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$number = $row ? (int) $row['number'] : 0;
$stmt->closeCursor();
return $number;
}
/**
*
* @param registryInterface $registry
* @param string $format
* @param int $page
* @return Feed_Link
*/
public function get_homepage_link(registryInterface $registry, $format, $page = null)
{
switch ($format) {
case self::FORMAT_ATOM:
return new Feed_Link(
sprintf('%sfeeds/aggregated/atom/%s'
, $registry->get('GV_ServerName')
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'Atom')
, 'application/atom+xml'
);
break;
case self::FORMAT_COOLIRIS:
return new Feed_Link(
sprintf('%sfeeds/cooliris/%s'
, $registry->get('GV_ServerName')
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'RSS')
, 'application/rss+xml'
);
break;
default:
case self::FORMAT_RSS:
return new Feed_Link(
sprintf('%sfeeds/aggregated/rss/%s'
, $registry->get('GV_ServerName')
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'RSS')
, 'application/rss+xml'
);
break;
}
}
/**
*
* @param User_Adapter $user
* @param boolean $renew
* @return string
*/
protected function get_token(User_Adapter $user, $renew = false)
{
$sql = 'SELECT token FROM feed_tokens
WHERE usr_id = :usr_id AND aggregated = "1"';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':usr_id' => $user->get_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row || $renew === true) {
$token = random::generatePassword(12, random::LETTERS_AND_NUMBERS);
$sql = 'REPLACE INTO feed_tokens (id, token, feed_id, usr_id, aggregated)
VALUES (null, :token, :feed_id, :usr_id, :aggregated)';
$params = array(
':token' => $token
, ':feed_id' => null
, ':usr_id' => $user->get_id()
, ':aggregated' => '1'
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
} else {
$token = $row['token'];
}
return $token;
}
/**
*
* @param Application $app
* @param User_Adapter $user
* @return Feed_Aggregate
*/
public static function load_with_user(Application $app, User_Adapter $user)
{
$feeds = Feed_Collection::load_all($app, $user);
return new self($app, $feeds->get_feeds());
}
/**
*
* @param registryInterface $registry
* @param User_Adapter $user
* @param string $format
* @param int $page
* @param boolean $renew_token
* @return Feed_Link
*/
public function get_user_link(registryInterface $registry, User_Adapter $user, $format, $page = null, $renew_token = false)
{
switch ($format) {
case self::FORMAT_ATOM:
return new Feed_Link(
sprintf('%sfeeds/userfeed/aggregated/%s/atom/%s'
, $registry->get('GV_ServerName')
, $this->get_token($user, $renew_token)
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'Atom')
, 'application/atom+xml'
);
break;
case self::FORMAT_RSS:
return new Feed_Link(
sprintf('%sfeeds/userfeed/aggregated/%s/rss/%s'
, $registry->get('GV_ServerName')
, $this->get_token($user, $renew_token)
, ($page ? '?page=' . $page : '')
)
, sprintf('%s - %s', $this->get_title(), 'RSS')
, 'application/rss+xml'
);
break;
}
}
}

View File

@@ -1,165 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Collection implements Feed_CollectionInterface, cache_cacheableInterface
{
/**
*
* @var Array
*/
protected $feeds;
/**
*
* @var Application
*/
protected $app;
const CACHE_PUBLIC = 'public';
/**
*
* @param Application $app
* @param array $feeds
* @return Feed_Collection
*/
public function __construct(Application $app, Array $feeds)
{
$this->feeds = $feeds;
$this->app = $app;
return $this;
}
/**
*
* @param Application $app
* @param User_Adapter $user
* @return Feed_Collection
*/
public static function load_all(Application $app, User_Adapter $user)
{
$base_ids = array_keys($user->ACL()->get_granted_base());
$sql = 'SELECT id FROM feeds
WHERE base_id IS NULL ';
if (count($base_ids) > 0) {
$sql .= ' OR base_id
IN (' . implode(', ', $base_ids) . ') ';
}
$sql .= ' OR public = "1"
ORDER BY created_on DESC';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$feeds = array();
foreach ($rs as $row) {
$feeds[] = new Feed_Adapter($app, $row['id']);
}
return new self($app, $feeds);
}
/**
*
* @return Array
*/
public function get_feeds()
{
return $this->feeds;
}
/**
*
* @return Feed_Aggregate
*/
public function get_aggregate()
{
return new Feed_Aggregate($this->app, $this->feeds);
}
/**
*
* @param Application $app
* @return Feed_Collection
*/
public static function load_public_feeds(Application $app)
{
$rs = self::retrieve_public_feed_ids($app['phraseanet.appbox']);
$feeds = array();
foreach ($rs as $feed_id) {
$feeds[] = new Feed_Adapter($app, $feed_id);
}
return new self($app, $feeds);
}
protected static function retrieve_public_feed_ids(appbox $appbox)
{
$key = 'feedcollection_' . self::CACHE_PUBLIC;
try {
return $appbox->get_data_from_cache($key);
} catch (Exception $e) {
}
$sql = 'SELECT id FROM feeds WHERE public = "1" AND base_id IS null ORDER BY created_on DESC';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$feeds = array();
foreach ($rs as $row) {
$feeds[] = $row['id'];
}
$appbox->set_data_to_cache($feeds, $key);
return $feeds;
}
public function get_cache_key($option = null)
{
return 'feedcollection_' . ($option ? '_' . $option : '');
}
public function get_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->get_data_from_cache($this->get_cache_key($option));
}
public function set_data_to_cache($value, $option = null, $duration = 0)
{
return $this->app['phraseanet.appbox']->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
public function delete_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->delete_data_from_cache($this->get_cache_key($option));
}
}

View File

@@ -1,24 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_CollectionInterface
{
public function get_feeds();
public function get_aggregate();
}

View File

@@ -1,593 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Entry_Adapter implements Feed_Entry_Interface, cache_cacheableInterface
{
/**
*
* @var appbox
*/
protected $app;
/**
*
* @var int
*/
protected $id;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $subtitle;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var DateTime
*/
protected $updated_on;
/**
*
* @var Feed_Publisher_Adapter
*/
protected $publisher;
/**
*
* @var int
*/
protected $publisher_id;
/**
*
* @var String
*/
protected $author_name;
/**
*
* @var String
*/
protected $author_email;
/**
*
* @var Feed_Adapter
*/
protected $feed;
/**
*
* @var array
*/
protected $items;
const CACHE_ELEMENTS = 'elements';
/**
*
* @param Application $app
* @param Feed_Adapter $feed
* @param int $id
* @return Feed_Entry_Adapter
*/
public function __construct(Application $app, Feed_Adapter $feed, $id)
{
$this->app = $app;
$this->feed = $feed;
$this->id = (int) $id;
$this->load();
return $this;
}
/**
*
* @return Feed_Entry_Adapter
*/
protected function load()
{
try {
$datas = $this->get_data_from_cache();
$this->title = $datas['title'];
$this->subtitle = $datas['subtitle'];
$this->author_name = $datas['author_name'];
$this->author_email = $datas['author_email'];
$this->publisher_id = $datas['publisher_id'];
$this->updated_on = $datas['updated_on'];
$this->created_on = $datas['created_on'];
return $this;
} catch (Exception $e) {
}
$sql = 'SELECT publisher, title, description, created_on, updated_on
, author_name, author_email
FROM feed_entries
WHERE id = :id ';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new Exception_Feed_EntryNotFound();
$this->title = $row['title'];
$this->subtitle = $row['description'];
$this->author_name = $row['author_name'];
$this->author_email = $row['author_email'];
$this->publisher_id = $row['publisher'];
$this->updated_on = new DateTime($row['updated_on']);
$this->created_on = new DateTime($row['created_on']);
$datas = array(
'title' => $this->title
, 'subtitle' => $this->subtitle
, 'author_name' => $this->author_name
, 'author_email' => $this->author_email
, 'publisher_id' => $this->publisher_id
, 'updated_on' => $this->updated_on
, 'created_on' => $this->created_on
);
$this->set_data_to_cache($datas);
return $this;
}
public function get_link()
{
$href = sprintf(
'%slightbox/feeds/entry/%d/'
, $this->app['phraseanet.registry']->get('GV_ServerName')
, $this->get_id()
);
return new Feed_Link($href, $this->get_title(), 'text/html');
}
/**
*
* @return Feed_Adapter
*/
public function get_feed()
{
return $this->feed;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @return string
*/
public function get_title()
{
return $this->title;
}
/**
*
* @return string
*/
public function get_subtitle()
{
return $this->subtitle;
}
/**
* Change the parent feed of the entry
*
* @param Feed_Adapter $feed
* @return \Feed_Entry_Adapter
*/
public function set_feed(Feed_Adapter $feed)
{
$sql = 'UPDATE feed_entries
SET feed_id = :feed_id, updated_on = NOW() WHERE id = :entry_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(
':feed_id' => $feed->get_id(),
':entry_id' => $this->get_id(),
));
$stmt->closeCursor();
$this->feed->delete_data_from_cache();
$this->feed = $feed;
$feed->delete_data_from_cache();
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param string $title
* @return Feed_Entry_Adapter
*/
public function set_title($title)
{
$title = trim(strip_tags($title));
if ($title === '')
throw new Exception_InvalidArgument();
$sql = 'UPDATE feed_entries
SET title = :title, updated_on = NOW() WHERE id = :entry_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':title' => $title, ':entry_id' => $this->get_id()));
$stmt->closeCursor();
$this->title = $title;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param string $subtitle
* @return Feed_Entry_Adapter
*/
public function set_subtitle($subtitle)
{
$subtitle = strip_tags($subtitle);
$sql = 'UPDATE feed_entries
SET description = :subtitle, updated_on = NOW()
WHERE id = :entry_id';
$params = array(':subtitle' => $subtitle, ':entry_id' => $this->get_id());
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->subtitle = $subtitle;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param string $author_name
* @return Feed_Entry_Adapter
*/
public function set_author_name($author_name)
{
$sql = 'UPDATE feed_entries
SET author_name = :author_name, updated_on = NOW()
WHERE id = :entry_id';
$params = array(
':author_name' => $author_name,
':entry_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->author_name = $author_name;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @param string $author_email
* @return Feed_Entry_Adapter
*/
public function set_author_email($author_email)
{
$sql = 'UPDATE feed_entries
SET author_email = :author_email, updated_on = NOW()
WHERE id = :entry_id';
$params = array(
':author_email' => $author_email,
':entry_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->author_email = $author_email;
$this->delete_data_from_cache();
return $this;
}
public function set_created_on(DateTime $datetime)
{
$sql = 'UPDATE feed_entries
SET created_on = :created_on
WHERE id = :entry_id';
$params = array(
':created_on' => $datetime->format(DATE_ISO8601),
':entry_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->created_on = $datetime;
$this->delete_data_from_cache();
return $this;
}
public function set_updated_on(DateTime $datetime)
{
$sql = 'UPDATE feed_entries
SET updated_on = :updated_on
WHERE id = :entry_id';
$params = array(
':updated_on' => $datetime->format(DATE_ISO8601),
':entry_id' => $this->get_id()
);
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->updated_on = $datetime;
$this->delete_data_from_cache();
return $this;
}
/**
*
* @return Feed_Publisher_Adapter
*/
public function get_publisher()
{
if (! $this->publisher instanceof Feed_Publisher_Adapter) {
try {
$this->publisher = new Feed_Publisher_Adapter($this->app, $this->publisher_id);
} catch (\Exception_Feed_PublisherNotFound $e) {
}
}
return $this->publisher;
}
/**
*
* @param User_adapter $user
* @return boolean
*/
public function is_publisher(User_adapter $user)
{
$publisher = $this->get_publisher();
if ($publisher instanceof Feed_Publisher_Interface) {
return $user->get_id() === $publisher->get_user()->get_id();
}
return false;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return DateTime
*/
public function get_updated_on()
{
return $this->updated_on;
}
/**
*
* @return string
*/
public function get_author_name()
{
return $this->author_name;
}
/**
*
* @return string
*/
public function get_author_email()
{
return $this->author_email;
}
/**
*
* @return array
*/
public function get_content()
{
if ($this->items) {
return $this->items;
}
$rs = $this->retrieve_elements();
$items = array();
foreach ($rs as $item_id) {
try {
$items[] = new Feed_Entry_Item($this->app['phraseanet.appbox'], $this, $item_id);
} catch (NotFoundHttpException $e) {
}
}
$this->items = $items;
return $this->items;
}
protected function retrieve_elements()
{
try {
return $this->get_data_from_cache(self::CACHE_ELEMENTS);
} catch (Exception $e) {
}
$sql = 'SELECT id FROM feed_entry_elements
WHERE entry_id = :entry_id ORDER BY ord ASC';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':entry_id' => $this->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$items = array();
foreach ($rs as $row) {
$items[] = (int) $row['id'];
}
$this->set_data_to_cache($items, self::CACHE_ELEMENTS);
return $items;
}
/**
*
* @return void
*/
public function delete()
{
foreach ($this->get_content() as $content) {
$content->delete();
}
$sql = 'DELETE FROM feed_entries WHERE id = :entry_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':entry_id' => $this->get_id()));
$stmt->closeCursor();
return;
}
public static function create(Application $app, Feed_Adapter $feed
, Feed_Publisher_Adapter $publisher, $title, $subtitle, $author_name, $author_mail)
{
if ( ! $feed->is_publisher($publisher->get_user())) {
throw new Exception_Feed_PublisherNotFound("Publisher not found");
}
if ( ! $feed->is_public() && $feed->get_collection() instanceof Collection) {
if ( ! $publisher->get_user()->ACL()->has_access_to_base($feed->get_collection()->get_base_id())) {
throw new AccessDeniedHttpException("User has no rights to publish in current feed");
}
}
$sql = 'INSERT INTO feed_entries (id, feed_id, publisher, title
, description, created_on, updated_on, author_name, author_email)
VALUES (null, :feed_id, :publisher_id, :title
, :description, NOW(), NOW(), :author_name, :author_email)';
$params = array(
':feed_id' => $feed->get_id(),
':publisher_id' => $publisher->get_id(),
':title' => trim($title),
':description' => trim($subtitle),
':author_name' => trim($author_name),
':author_email' => trim($author_mail),
);
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$entry_id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
$feed->delete_data_from_cache();
$entry = new self($app, $feed, $entry_id);
$app['events-manager']->trigger('__FEED_ENTRY_CREATE__', array('entry_id' => $entry_id), $entry);
return $entry;
}
/**
*
* @param Application $app
* @param type $id
* @return Feed_Entry_Adapter
*/
public static function load_from_id(Application $app, $id)
{
$sql = 'SELECT feed_id FROM feed_entries WHERE id = :entry_id';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':entry_id' => $id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new Exception_Feed_EntryNotFound();
$feed = new Feed_Adapter($app, $row['feed_id']);
return new self($app, $feed, $id);
}
public function get_cache_key($option = null)
{
return 'feedentry_' . $this->get_id() . '_' . ($option ? '_' . $option : '');
}
public function get_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->get_data_from_cache($this->get_cache_key($option));
}
public function set_data_to_cache($value, $option = null, $duration = 0)
{
return $this->app['phraseanet.appbox']->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
public function delete_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->delete_data_from_cache($this->get_cache_key($option));
}
}

View File

@@ -1,73 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Entry_Collection implements Feed_Entry_CollectionInterface
{
/**
*
* @var array
*/
protected $entries = array();
/**
*
* @var DateTime
*/
protected $updated_on;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $subtitle;
/**
*
* @return Feed_Entry_Collection
*/
public function __construct()
{
return $this;
}
/**
*
* @param Feed_Entry_Adapter $entry
* @return Feed_Entry_Collection
*/
public function add_entry(Feed_Entry_Adapter $entry)
{
$this->entries[] = $entry;
return $this;
}
/**
*
* @return Array
*/
public function get_entries()
{
return $this->entries;
}
}

View File

@@ -1,26 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_Entry_CollectionInterface
{
public function __construct();
public function add_entry(Feed_Entry_Adapter $entry);
public function get_entries();
}

View File

@@ -1,59 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_Entry_Interface
{
public function __construct(Application $app, Feed_Adapter $feed, $id);
public function get_feed();
public function get_id();
public function get_title();
public function get_subtitle();
public function set_title($title);
public function set_subtitle($subtitle);
public function set_author_name($author_name);
public function set_author_email($author_email);
public function get_publisher();
public function get_created_on();
public function get_updated_on();
public function get_author_name();
public function get_author_email();
public function get_content();
public function delete();
public static function create(Application $app, Feed_Adapter $feed
, Feed_Publisher_Adapter $publisher, $title, $subtitle, $author_name, $author_mail);
public static function load_from_id(Application $app, $id);
}

View File

@@ -1,229 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Entry_Item implements Feed_Entry_ItemInterface, cache_cacheableInterface
{
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @var int
*/
protected $id;
/**
*
* @var record_adapter
*/
protected $record;
/**
*
* @var Feed_Entry_Adapter
*/
protected $entry;
/**
*
* @var int
*/
protected $ord;
/**
*
* @param appbox $appbox
* @param Feed_Entry_Adapter $entry
* @param int $id
* @return Feed_Entry_Item
*/
public function __construct(appbox $appbox, Feed_Entry_Adapter $entry, $id)
{
$this->appbox = $appbox;
$this->id = (int) $id;
$this->entry = $entry;
$this->load();
return $this;
}
public function get_entry()
{
return $this->entry;
}
/**
*
* @return Feed_Entry_Item
*/
protected function load()
{
try {
$datas = $this->get_data_from_cache();
$this->record = $this->appbox->get_databox($datas['sbas_id'])
->get_record($datas['record_id'], $datas['ord']);
$this->ord = $datas['ord'];
return $this;
} catch (Exception $e) {
}
$sql = 'SELECT id, sbas_id, record_id, ord
FROM feed_entry_elements WHERE id = :id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new Exception_Feed_ItemNotFound();
$this->record = $this->appbox->get_databox($row['sbas_id'])
->get_record($row['record_id']);
$this->ord = (int) $row['ord'];
$datas = array(
'record_id' => $this->record->get_record_id()
, 'sbas_id' => $this->record->get_sbas_id()
, 'ord' => $this->ord
);
$this->set_data_to_cache($datas);
return $this;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @return record_adapter
*/
public function get_record()
{
return $this->record;
}
/**
*
* @return int
*/
public function get_ord()
{
return $this->ord;
}
public function set_ord($order)
{
$order = (int) $order;
$sql = 'UPDATE feed_entry_elements SET ord = :ord WHERE id = :item_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':ord' => $order, ':item_id' => $this->get_id()));
$stmt->closeCursor();
$this->ord = $order;
return $this;
}
/**
*
* @return void
*/
public function delete()
{
$sql = 'DELETE FROM feed_entry_elements WHERE id = :id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':id' => $this->get_id()));
$stmt->closeCursor();
return;
}
/**
*
* @param appbox $appbox
* @param Feed_Entry_Adapter $entry
* @param record_adapter $record
* @return Feed_Entry_Item
*/
public static function create(appbox $appbox, Feed_Entry_Adapter $entry, record_adapter $record)
{
$sql = 'SELECT (MAX(ord)+1) as sorter FROM feed_entry_elements
WHERE entry_id = :entry_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':entry_id' => $entry->get_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$sorter = ($row && $row['sorter'] > 0) ? (int) $row['sorter'] : 1;
$sql = 'INSERT INTO feed_entry_elements
(id, entry_id, sbas_id, record_id, ord)
VALUES (null, :entry_id, :sbas_id, :record_id, :ord)';
$params = array(
':entry_id' => $entry->get_id()
, ':sbas_id' => $record->get_sbas_id()
, ':record_id' => $record->get_record_id()
, ':ord' => $sorter
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$item_id = $appbox->get_connection()->lastInsertId();
$entry->delete_data_from_cache(Feed_Entry_Adapter::CACHE_ELEMENTS);
return new self($appbox, $entry, $item_id);
}
public function get_cache_key($option = null)
{
return 'feedentryitem_' . $this->get_id() . '_' . ($option ? '_' . $option : '');
}
public function get_data_from_cache($option = null)
{
return $this->appbox->get_data_from_cache($this->get_cache_key($option));
}
public function set_data_to_cache($value, $option = null, $duration = 0)
{
return $this->appbox->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
public function delete_data_from_cache($option = null)
{
return $this->appbox->delete_data_from_cache($this->get_cache_key($option));
}
}

View File

@@ -1,32 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_Entry_ItemInterface
{
public function __construct(appbox $appbox, Feed_Entry_Adapter $entry, $id);
public function get_id();
public function get_record();
public function get_ord();
public function delete();
public static function create(appbox $appbox, Feed_Entry_Adapter $entry, record_adapter $record);
}

View File

@@ -1,40 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_Interface
{
public function get_title();
public function get_subtitle();
public function get_created_on();
public function get_updated_on();
public function get_entries($offset_start, $how_many);
public function get_count_total_entries();
public function get_homepage_link(registryInterface $registry, $format, $page = null);
public function get_user_link(registryInterface $registry, User_Adapter $user, $format, $page = null, $renew_token = false);
public function get_icon_url();
public function is_aggregated();
}

View File

@@ -1,80 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Link implements Feed_LinkInterface
{
/**
*
* @var string
*/
protected $mimetype;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $href;
/**
*
* @param string $href
* @param string $title
* @param string $mimetype
* @return Feed_Link
*/
public function __construct($href, $title, $mimetype)
{
$this->mimetype = $mimetype;
$this->href = $href;
$this->title = $title;
return $this;
}
/**
*
* @return string
*/
public function get_mimetype()
{
return $this->mimetype;
}
/**
*
* @return string
*/
public function get_title()
{
return $this->title;
}
/**
*
* @return string
*/
public function get_href()
{
return $this->href;
}
}

View File

@@ -1,26 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_LinkInterface
{
public function get_mimetype();
public function get_title();
public function get_href();
}

View File

@@ -1,240 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Publisher_Adapter implements Feed_Publisher_Interface, cache_cacheableInterface
{
/**
*
* @var Application
*/
protected $app;
/**
*
* @var int
*/
protected $id;
/**
*
* @var User_Adapter
*/
protected $user;
/**
*
* @var boolean
*/
protected $owner;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var User_Adapter
*/
protected $added_by;
/**
*
* @param Application $app
* @param int $id
* @return Feed_Publisher_Adapter
*/
public function __construct(Application $app, $id)
{
$this->app = $app;
$this->id = (int) $id;
$this->load();
return $this;
}
/**
*
* @return Feed_Publisher_Adapter
*/
protected function load()
{
try {
$datas = $this->get_data_from_cache();
$this->user = User_Adapter::getInstance($datas['usr_id'], $this->app);
$this->added_by = User_Adapter::getInstance($datas['added_by_usr_id'], $this->app);
$this->created_on = $datas['created_on'];
$this->owner = $datas['owner'];
return $this;
} catch (Exception $e) {
}
$sql = 'SELECT id, usr_id, owner, created_on, added_by
FROM feed_publishers WHERE id = :feed_publisher_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_publisher_id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new Exception_Feed_PublisherNotFound('Publisher is not Found');
$this->user = User_Adapter::getInstance($row['usr_id'], $this->app);
$this->owner = ! ! $row['owner'];
$this->created_on = new DateTime($row['created_on']);
$this->added_by = User_Adapter::getInstance($row['added_by'], $this->app);
$datas = array(
'usr_id' => $this->user->get_id()
, 'owner' => $this->owner
, 'created_on' => $this->created_on
, 'added_by_usr_id' => $this->added_by->get_id()
);
$this->set_data_to_cache($datas);
return $this;
}
/**
*
* @return User_Adapter
*/
public function get_user()
{
return $this->user;
}
/**
*
* @return boolean
*/
public function is_owner()
{
return $this->owner;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return User_Adapter
*/
public function get_added_by()
{
return $this->added_by;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @return void
*/
public function delete()
{
$sql = 'DELETE FROM feed_publishers WHERE id = :feed_publisher_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':feed_publisher_id' => $this->get_id()));
$stmt->closeCursor();
return;
}
/**
*
* @param Application $app
* @param User_Adapter $user
* @param Feed_Adapter $feed
* @param boolean $owner
* @return Feed_Publisher_Adapter
*/
public static function create(Application $app, User_Adapter $user, Feed_Adapter $feed, $owner)
{
$sql = 'INSERT INTO feed_publishers (id, usr_id, feed_id, owner, created_on, added_by)
VALUES (null, :usr_id, :feed_id, :owner, NOW(), :added_by)';
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$params = array(
':usr_id' => $user->get_id()
, ':feed_id' => $feed->get_id()
, ':owner' => $owner ? '1' : null
, ':added_by' => $owner ? $user->get_id() : $app['authentication']->getUser()->get_id()
);
$stmt->execute($params);
$id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
$stmt->closeCursor();
return new self($app, $id);
}
/**
*
* @param appbox $appbox
* @param Feed_Adapter $feed
* @param User_Adapter $user
* @return Feed_Publisher_Adapter
*/
public static function getPublisher(appbox $appbox, Feed_Adapter $feed, User_Adapter $user)
{
foreach ($feed->get_publishers() as $publisher) {
if ($publisher->get_user()->get_id() === $user->get_id()) {
return $publisher;
}
}
throw new Exception_Feed_PublisherNotFound('Publisher not found');
}
public function get_cache_key($option = null)
{
return 'feedpublisher_' . $this->get_id() . '_' . ($option ? '_' . $option : '');
}
public function get_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->get_data_from_cache($this->get_cache_key($option));
}
public function set_data_to_cache($value, $option = null, $duration = 0)
{
return $this->app['phraseanet.appbox']->set_data_to_cache($value, $this->get_cache_key($option), $duration);
}
public function delete_data_from_cache($option = null)
{
return $this->app['phraseanet.appbox']->delete_data_from_cache($this->get_cache_key($option));
}
}

View File

@@ -1,40 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_Publisher_Interface
{
public function __construct(Application $app, $id);
public function get_user();
public function is_owner();
public function get_created_on();
public function get_added_by();
public function get_id();
public function delete();
public static function create(Application $app, User_Adapter $user, Feed_Adapter $feed, $owner);
public static function getPublisher(appbox $appbox, Feed_Adapter $feed, User_Adapter $user);
}

View File

@@ -1,110 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_Token
{
/**
*
* @var int
*/
protected $usr_id;
/**
*
* @var int
*/
protected $feed_id;
/**
*
* @var User_Adapter
*/
protected $user;
/**
*
* @var Feed_Adapter
*/
protected $feed;
/**
*
* @var appbox
*/
protected $app;
/**
*
* @param Application $app
* @param string $token
* @param int $feed_id
*
* @return Feed_Token
*/
public function __construct(Application $app, $token, $feed_id)
{
$sql = 'SELECT feed_id, usr_id FROM feed_tokens
WHERE feed_id = :feed_id
AND aggregated IS NULL AND token = :token';
$params = array(
':feed_id' => $feed_id
, ':token' => $token
);
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new NotFoundHttpException('Feed not found.');
$this->feed_id = (int) $row['feed_id'];
$this->usr_id = (int) $row['usr_id'];
$this->app = $app;
return $this;
}
/**
*
* @return User_Adapter
*/
public function get_user()
{
if ( ! $this->user)
$this->user = User_Adapter::getInstance($this->usr_id, $this->app);
return $this->user;
}
/**
*
* @return Feed_Adapter
*/
public function get_feed()
{
if ( ! $this->feed)
$this->feed = Feed_Adapter::load_with_user($this->app, $this->get_user(), $this->feed_id);
return $this->feed;
}
}

View File

@@ -1,66 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_TokenAggregate extends Feed_Token
{
/**
*
* @param Application $app
* @param string $token
* @return Feed_TokenAggregate
*/
public function __construct(Application $app, $token)
{
$sql = 'SELECT usr_id FROM feed_tokens
WHERE aggregated = "1" AND token = :token';
$params = array(
':token' => $token
);
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ( ! $row)
throw new NotFoundHttpException('Feed not found.');
$this->usr_id = $row['usr_id'];
$this->app = $app;
return $this;
}
/**
*
* @return Feed_Aggregate
*/
public function get_feed()
{
if (! $this->feed) {
$this->feed = Feed_Aggregate::load_with_user($this->app, $this->get_user());
}
return $this->feed;
}
}

View File

@@ -1,192 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_XML_Atom extends Feed_XML_Abstract implements Feed_XML_Interface
{
/**
*
* @var string
*/
protected $id;
/**
*
* @var string
*/
protected $author_name;
/**
*
* @var string
*/
protected $author_email;
/**
*
* @var string
*/
protected $author_url;
/**
*
* @var boolean
*/
protected $author = false;
/**
*
* @var string
*/
protected $icon;
/**
*
* @var string
*/
protected $mimetype = 'application/atom+xml';
/**
*
* @return string
*/
public function render()
{
$document = new DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$document->standalone = true;
$root = $this->addTag($document, $document, 'feed');
$root->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$this->addTag($document, $root, 'title', $this->title);
if ($this->updated_on instanceof DateTime) {
$updated_on = $this->updated_on->format(DATE_ATOM);
$this->addTag($document, $root, 'updated', $updated_on);
}
if ($this->link instanceof Feed_Link) {
$link = $this->addTag($document, $root, 'link');
$link->setAttribute('rel', 'self');
$link->setAttribute('href', $this->link->get_href());
$this->addTag($document, $root, 'id', $this->link->get_href());
}
$this->add_navigation($document, $root, false);
if ($this->generator)
$this->addTag($document, $root, 'generator', $this->generator);
if ($this->subtitle)
$this->addTag($document, $root, 'subtitle', $this->subtitle);
if ($this->icon)
$this->addTag($document, $root, 'icon', $this->icon);
if ($this->author) {
$author = $this->addTag($document, $root, 'author');
if ($this->author_email)
$this->addTag($document, $author, 'email', $this->author_email);
if ($this->author_name)
$this->addTag($document, $author, 'name', $this->author_name);
if ($this->author_url)
$this->addTag($document, $author, 'uri', $this->author_url);
}
foreach ($this->items as $item) {
$this->add_item($document, $root, $item);
}
return $document->saveXML();
}
/**
*
* @param DOMDocument $document
* @param DOMElement $feed
* @param Feed_Entry_Adapter $entry
* @return DOMElement
*/
protected function add_item(DOMDocument $document, DOMElement $feed, Feed_Entry_Adapter $entry)
{
$entry_node = $this->addTag($document, $feed, 'entry');
$link = sprintf('%sentry/%d/', $this->link->get_href(), $entry->get_id());
$this->addTag($document, $entry_node, 'id', $link);
$link_tag = $this->addTag($document, $entry_node, 'link');
$link_tag->setAttribute('rel', 'self');
$link_tag->setAttribute('href', $link);
$updated_on = $entry->get_updated_on()->format(DATE_ATOM);
$created_on = $entry->get_created_on()->format(DATE_ATOM);
$this->addTag($document, $entry_node, 'updated', $updated_on);
$this->addTag($document, $entry_node, 'published', $created_on);
$this->addTag($document, $entry_node, 'title', $entry->get_title());
$author = $this->addTag($document, $entry_node, 'author');
if ($entry->get_author_email())
$this->addTag($document, $author, 'email', $entry->get_author_email());
if ($entry->get_author_name())
$this->addTag($document, $author, 'name', $entry->get_author_name());
$this->addTag($document, $entry_node, 'content', $entry->get_subtitle());
foreach ($entry->get_content() as $content) {
$this->addContent($document, $entry_node, $entry, $content);
}
return $entry_node;
}
/**
*
* @param string $author_name
* @return Feed_XML_Atom
*/
public function set_author_name($author_name)
{
$this->author = true;
$this->author_name = $author_name;
return $this;
}
/**
*
* @param string $author_email
* @return Feed_XML_Atom
*/
public function set_author_email($author_email)
{
$this->author = true;
$this->author_email = $author_email;
return $this;
}
/**
*
* @param string $author_url
* @return Feed_XML_Atom
*/
public function set_author_url($author_url)
{
$this->author = true;
$this->author_url = $author_url;
return $this;
}
}

View File

@@ -1,440 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_XML_Cooliris extends Feed_XML_Abstract implements Feed_XML_Interface
{
/**
* RSS version
*/
const VERSION = '2.0';
/**
*
* @var Array
*/
protected $required_fields = array('title', 'subtitle', 'link');
/**
*
* @var string
*/
protected $language;
/**
*
* @var string
*/
protected $copyright;
/**
*
* @var string
*/
protected $managingEditor;
/**
*
* @var string
*/
protected $webMaster;
/**
*
* @var DateTime
*/
protected $lastBuildDate;
/**
*
* @var string
*/
protected $categories;
/**
*
* @var string
*/
protected $docs = 'http://blogs.law.harvard.edu/tech/rss';
/**
*
* @var int
*/
protected $ttl;
/**
*
* @var Feed_XML_RSS_Image
*/
protected $image;
/**
*
* @var string
*/
protected $skipHours = array();
/**
*
* @var string
*/
protected $skipDays = array();
/**
*
* @var string
*/
protected $mimetype = 'application/rss+xml';
/**
*
* @param string $language
* @return Feed_XML_RSS
*/
public function set_language($language)
{
$this->language = $language;
return $this;
}
/**
*
* @param string $copyright
* @return Feed_XML_RSS
*/
public function set_copyright($copyright)
{
$this->copyright = $copyright;
return $this;
}
/**
*
* @param string $managingEditor
* @return Feed_XML_RSS
*/
public function set_managingEditor($managingEditor)
{
$this->managingEditor = $managingEditor;
return $this;
}
/**
*
* @param string $webMaster
* @return Feed_XML_RSS
*/
public function set_webMaster($webMaster)
{
$this->webMaster = $webMaster;
return $this;
}
/**
*
* @param DateTime $lastBuildDate
* @return Feed_XML_RSS
*/
public function set_lastBuildDate(DateTime $lastBuildDate)
{
$this->lastBuildDate = $lastBuildDate;
return $this;
}
/**
*
* @param string $category
* @return Feed_XML_RSS
*/
public function set_category($category)
{
$this->categories[] = $category;
return $this;
}
/**
*
* @param string $docs
* @return Feed_XML_RSS
*/
public function set_docs($docs)
{
$this->docs = $docs;
return $this;
}
/**
*
* @param int $ttl
* @return Feed_XML_RSS
*/
public function set_ttl($ttl)
{
$this->ttl = $ttl;
return $this;
}
/**
*
* @param Feed_XML_RSS_Image $image
* @return Feed_XML_RSS
*/
public function set_image(Feed_XML_RSS_Image $image)
{
$this->image = $image;
return $this;
}
/**
*
* @param string $hour
* @return Feed_XML_RSS
*/
public function set_skipHour($hour)
{
$this->skipHours[] = (int) $hour;
return $this;
}
/**
*
* @param string $day
* @return Feed_XML_RSS
*/
public function set_skipDays($day)
{
$this->skipDays[] = $day;
return $this;
}
/**
*
* @return string
*/
public function render()
{
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$doc->standalone = true;
$root = $this->addTag($doc, $doc, 'rss');
$root->setAttribute('version', self::VERSION);
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$channel = $this->addTag($doc, $root, 'channel');
$this->addTag($doc, $channel, 'title', $this->title);
$this->addTag($doc, $channel, 'dc:title', $this->title);
$this->addTag($doc, $channel, 'description', $this->subtitle);
if ($this->link instanceof Feed_Link)
$this->addTag($doc, $channel, 'link', $this->link->get_href());
if ($this->language)
$this->addTag($doc, $channel, 'language', $this->language);
if ($this->copyright)
$this->addTag($doc, $channel, 'copyright', $this->copyright);
if ($this->managingEditor)
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if ($this->webMaster)
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
if ($this->updated_on instanceof DateTime) {
$updated_on = $this->updated_on->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
if ($this->lastBuildDate instanceof DateTime) {
$last_build = $this->lastBuildDate->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'lastBuildDate', $last_build);
}
if (count($this->categories) > 0) {
foreach ($this->categories as $category) {
$this->addTag($doc, $channel, 'category', $category);
}
}
if ($this->generator)
$this->addTag($doc, $channel, 'generator', $this->generator);
if ($this->docs)
$this->addTag($doc, $channel, 'docs', $this->docs);
if ($this->ttl)
$this->addTag($doc, $channel, 'ttl', $this->ttl);
if ($this->image instanceof Feed_XML_RSS_Image) {
$image = $this->addTag($doc, $channel, 'image');
$this->addTag($doc, $image, 'url', $this->image->get_url());
$this->addTag($doc, $image, 'title', $this->image->get_title());
$this->addTag($doc, $image, 'link', $this->image->get_link());
if ($this->image->get_width())
$this->addTag($doc, $image, 'width', $this->image->get_width());
if ($this->image->get_height())
$this->addTag($doc, $image, 'height', $this->image->get_height());
if ($this->image->get_description())
$this->addTag($doc, $image, 'description', $this->image->get_description());
}
if (count($this->skipHours)) {
$skipHours = $this->addTag($doc, $channel, 'skipHours');
foreach ($this->skipHours as $hour) {
$this->addTag($doc, $skipHours, 'hour', $hour);
}
}
if (count($this->skipDays) > 0) {
$skipDays = $this->addTag($doc, $channel, 'skipDays');
foreach ($this->skipDays as $day) {
$this->addTag($doc, $skipDays, 'day', $day);
}
}
if ($this->link instanceof Feed_Link) {
$self_link = $this->addTag($doc, $channel, 'atom:link');
$self_link->setAttribute('rel', 'self');
$self_link->setAttribute('href', $this->link->get_href());
}
$this->add_navigation($doc, $channel, true);
foreach ($this->items as $item) {
$this->add_item($doc, $channel, $item);
}
return $doc->saveXML();
}
/**
*
* @param DOMDocument $document
* @param DOMNode $node
* @param Feed_Entry_Adapter $entry
* @return DOMElement
*/
protected function add_item(DOMDocument $document, DOMNode $node, Feed_Entry_Adapter $entry)
{
foreach ($entry->get_content() as $content) {
$this->addContent($document, $node, $entry, $content);
}
return;
}
/**
*
* @param DOMDocument $document
* @param DOMNode $item
* @param Feed_Entry_Item $content
* @return Feed_XML_Interface
*/
protected function addContent(DOMDocument $document, DOMNode $node, Feed_Entry_Adapter $entry, Feed_Entry_Item $content)
{
$preview_sd = $content->get_record()->get_subdef('preview');
$preview_permalink = $preview_sd->get_permalink();
$thumbnail_sd = $content->get_record()->get_thumbnail();
$thumbnail_permalink = $thumbnail_sd->get_permalink();
$medium = strtolower($content->get_record()->get_type());
if ( ! in_array($medium, array('image', 'audio', 'video'))) {
return $this;
}
if (! $preview_permalink || ! $thumbnail_permalink) {
return $this;
}
//add item node to channel node
$item = $this->addTag($document, $node, 'item');
$caption = $content->get_record()->get_caption();
$title_field = $caption->get_dc_field(databox_Field_DCESAbstract::Title);
if ($title_field) {
$str_title = $title_field->get_serialized_values(' ');
} else {
$str_title = $content->get_record()->get_title();
}
//attach tile node to item node
$title = $this->addTag($document, $item, 'title', $str_title);
$desc_field = $caption->get_dc_field(databox_Field_DCESAbstract::Description);
if ($desc_field) {
$str_desc = $desc_field->get_serialized_values(' ');
} else {
$str_desc = '';
}
//attach desc node to item node
$desc = $this->addTag($document, $item, 'description', $str_desc);
$duration = $content->get_record()->get_duration();
if ($preview_permalink) {
$preview = $this->addTag($document, $item, 'media:content');
$preview->setAttribute('url', $preview_permalink->get_url());
$preview->setAttribute('fileSize', $preview_sd->get_size());
$preview->setAttribute('type', $preview_sd->get_mime());
$preview->setAttribute('medium', $medium);
$preview->setAttribute('expression', 'full');
$preview->setAttribute('isDefault', 'true');
if ($preview_sd->get_width())
$preview->setAttribute('width', $preview_sd->get_width());
if ($preview_sd->get_height())
$preview->setAttribute('height', $preview_sd->get_height());
if ($duration)
$preview->setAttribute('duration', $duration);
}
if ($thumbnail_permalink) {
$thumbnail = $this->addTag($document, $item, 'media:thumbnail');
$thumbnail->setAttribute('url', $thumbnail_permalink->get_url());
if ($thumbnail_sd->get_width())
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
if ($thumbnail_sd->get_height())
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
$thumbnail = $this->addTag($document, $item, 'media:content');
$thumbnail->setAttribute('url', $thumbnail_permalink->get_url());
$thumbnail->setAttribute('fileSize', $thumbnail_sd->get_size());
$thumbnail->setAttribute('type', $thumbnail_sd->get_mime());
$thumbnail->setAttribute('medium', $medium);
$thumbnail->setAttribute('isDefault', 'false');
if ($thumbnail_sd->get_width())
$thumbnail->setAttribute('width', $thumbnail_sd->get_width());
if ($thumbnail_sd->get_height())
$thumbnail->setAttribute('height', $thumbnail_sd->get_height());
if ($duration)
$thumbnail->setAttribute('duration', $duration);
}
return $this;
}
}

View File

@@ -1,40 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface Feed_XML_Interface
{
public function set_title($title);
public function set_updated_on(DateTime $datetime);
public function set_subtitle($subtitle);
public function set_link(Feed_Link $link);
public function set_next_page(Feed_Link $next_page);
public function set_previous_page(Feed_Link $previous_page);
public function set_item(Feed_Entry_Adapter $entry);
public function set_generator($generator);
public function add_navigation(DOMDocument $document, DOMNode $node, $namespaced);
public function get_mimetype();
}

View File

@@ -1,369 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package Feeds
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class Feed_XML_RSS extends Feed_XML_Abstract implements Feed_XML_Interface
{
/**
* RSS version
*/
const VERSION = '2.0';
/**
*
* @var Array
*/
protected $required_fields = array('title', 'subtitle', 'link');
/**
*
* @var string
*/
protected $language;
/**
*
* @var string
*/
protected $copyright;
/**
*
* @var string
*/
protected $managingEditor;
/**
*
* @var string
*/
protected $webMaster;
/**
*
* @var DateTime
*/
protected $lastBuildDate;
/**
*
* @var string
*/
protected $categories;
/**
*
* @var string
*/
protected $docs = 'http://blogs.law.harvard.edu/tech/rss';
/**
*
* @var int
*/
protected $ttl;
/**
*
* @var Feed_XML_RSS_Image
*/
protected $image;
/**
*
* @var string
*/
protected $skipHours = array();
/**
*
* @var string
*/
protected $skipDays = array();
/**
*
* @var string
*/
protected $mimetype = 'application/rss+xml';
/**
*
* @param string $language
* @return Feed_XML_RSS
*/
public function set_language($language)
{
$this->language = $language;
return $this;
}
/**
*
* @param string $copyright
* @return Feed_XML_RSS
*/
public function set_copyright($copyright)
{
$this->copyright = $copyright;
return $this;
}
/**
*
* @param string $managingEditor
* @return Feed_XML_RSS
*/
public function set_managingEditor($managingEditor)
{
$this->managingEditor = $managingEditor;
return $this;
}
/**
*
* @param string $webMaster
* @return Feed_XML_RSS
*/
public function set_webMaster($webMaster)
{
$this->webMaster = $webMaster;
return $this;
}
/**
*
* @param DateTime $lastBuildDate
* @return Feed_XML_RSS
*/
public function set_lastBuildDate(DateTime $lastBuildDate)
{
$this->lastBuildDate = $lastBuildDate;
return $this;
}
/**
*
* @param string $category
* @return Feed_XML_RSS
*/
public function set_category($category)
{
$this->categories[] = $category;
return $this;
}
/**
*
* @param string $docs
* @return Feed_XML_RSS
*/
public function set_docs($docs)
{
$this->docs = $docs;
return $this;
}
/**
*
* @param int $ttl
* @return Feed_XML_RSS
*/
public function set_ttl($ttl)
{
$this->ttl = $ttl;
return $this;
}
/**
*
* @param Feed_XML_RSS_Image $image
* @return Feed_XML_RSS
*/
public function set_image(Feed_XML_RSS_Image $image)
{
$this->image = $image;
return $this;
}
/**
*
* @param string $hour
* @return Feed_XML_RSS
*/
public function set_skipHour($hour)
{
$this->skipHours[] = (int) $hour;
return $this;
}
/**
*
* @param string $day
* @return Feed_XML_RSS
*/
public function set_skipDays($day)
{
$this->skipDays[] = $day;
return $this;
}
/**
*
* @return string
*/
public function render()
{
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$doc->standalone = true;
$root = $this->addTag($doc, $doc, 'rss');
$root->setAttribute('version', self::VERSION);
$root->setAttribute('xmlns:media', 'http://search.yahoo.com/mrss/');
$root->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
$root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$channel = $this->addTag($doc, $root, 'channel');
$this->addTag($doc, $channel, 'title', $this->title);
$this->addTag($doc, $channel, 'dc:title', $this->title);
$this->addTag($doc, $channel, 'description', $this->subtitle);
if ($this->link instanceof Feed_Link)
$this->addTag($doc, $channel, 'link', $this->link->get_href());
if ($this->language)
$this->addTag($doc, $channel, 'language', $this->language);
if ($this->copyright)
$this->addTag($doc, $channel, 'copyright', $this->copyright);
if ($this->managingEditor)
$this->addTag($doc, $channel, 'managingEditor', $this->managingEditor);
if ($this->webMaster)
$this->addTag($doc, $channel, 'webMaster', $this->webMaster);
if ($this->updated_on instanceof DateTime) {
$updated_on = $this->updated_on->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'pubDate', $updated_on);
}
if ($this->lastBuildDate instanceof DateTime) {
$last_build = $this->lastBuildDate->format(DATE_RFC2822);
$this->addTag($doc, $channel, 'lastBuildDate', $last_build);
}
if (count($this->categories) > 0) {
foreach ($this->categories as $category) {
$this->addTag($doc, $channel, 'category', $category);
}
}
if ($this->generator)
$this->addTag($doc, $channel, 'generator', $this->generator);
if ($this->docs)
$this->addTag($doc, $channel, 'docs', $this->docs);
if ($this->ttl)
$this->addTag($doc, $channel, 'ttl', $this->ttl);
if ($this->image instanceof Feed_XML_RSS_Image) {
$image = $this->addTag($doc, $channel, 'image');
$this->addTag($doc, $image, 'url', $this->image->get_url());
$this->addTag($doc, $image, 'title', $this->image->get_title());
$this->addTag($doc, $image, 'link', $this->image->get_link());
if ($this->image->get_width())
$this->addTag($doc, $image, 'width', $this->image->get_width());
if ($this->image->get_height())
$this->addTag($doc, $image, 'height', $this->image->get_height());
if ($this->image->get_description())
$this->addTag($doc, $image, 'description', $this->image->get_description());
}
if (count($this->skipHours)) {
$skipHours = $this->addTag($doc, $channel, 'skipHours');
foreach ($this->skipHours as $hour) {
$this->addTag($doc, $skipHours, 'hour', $hour);
}
}
if (count($this->skipDays) > 0) {
$skipDays = $this->addTag($doc, $channel, 'skipDays');
foreach ($this->skipDays as $day) {
$this->addTag($doc, $skipDays, 'day', $day);
}
}
if ($this->link instanceof Feed_Link) {
$self_link = $this->addTag($doc, $channel, 'atom:link');
$self_link->setAttribute('rel', 'self');
$self_link->setAttribute('href', $this->link->get_href());
}
$this->add_navigation($doc, $channel, true);
foreach ($this->items as $item) {
$this->add_item($doc, $channel, $item);
}
return $doc->saveXML();
}
/**
*
* @param DOMDocument $document
* @param DOMNode $node
* @param Feed_Entry_Adapter $entry
* @return DOMElement
*/
protected function add_item(DOMDocument $document, DOMNode $node, Feed_Entry_Adapter $entry)
{
$item = $this->addTag($document, $node, 'item');
$link = $entry->get_link();
$this->addTag($document, $item, 'title', $entry->get_title());
$this->addTag($document, $item, 'description', $entry->get_subtitle());
$author = sprintf(
'%s (%s)'
, $entry->get_author_email()
, $entry->get_author_name()
);
$created_on = $entry->get_created_on()->format(DATE_RFC2822);
$this->addTag($document, $item, 'author', $author);
$this->addTag($document, $item, 'pubDate', $created_on);
$this->addTag($document, $item, 'guid', $link->get_href());
$this->addTag($document, $item, 'link', $link->get_href());
/**
* Missing :
*
* category Includes the item in one or more categories. More.
* comments URL of a page for comments relating to the item. More.
* enclosure Describes a media object that is attached to the item. More.
* source The RSS channel that the item came from. More.
*
*/
foreach ($entry->get_content() as $content) {
$this->addContent($document, $item, $entry, $content);
}
return $item;
}
}

View File

@@ -305,6 +305,8 @@ class appbox extends base
$upgrader->set_current_message(_('Creating new tables'));
//create schema
$app['phraseanet.pre-schema-upgrader']->apply($app);
if ($app['EM']->getConnection()->getDatabasePlatform()->supportsAlterTable()) {
$tool = new \Doctrine\ORM\Tools\SchemaTool($app['EM']);
$metas = $app['EM']->getMetadataFactory()->getAllMetadata();

View File

@@ -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;
@@ -133,17 +138,17 @@ 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);
} catch (\Exception $e) {
$entry = $this->app['EM']->getRepository('Entities\FeedEntry')->find((int) $sx->entry_id);
if (null === $entry) {
return array();
}
$ret = array(
'text' => sprintf(
_('%1$s has published %2$s')
, $entry->get_author_name()
, '<a href="/lightbox/feeds/entry/' . $entry->get_id() . '/" target="_blank">' . $entry->get_title() . '</a>'
, $entry->getAuthorName()
, '<a href="/lightbox/feeds/entry/' . $entry->getId() . '/" target="_blank">' . $entry->getTitle() . '</a>'
)
, 'class' => ($unread == 1 ? 'reload_baskets' : '')
);

View File

@@ -10,6 +10,11 @@
*/
use Alchemy\Phrasea\Application;
use Entities\Feed;
use Entities\FeedEntry;
use Entities\FeedItem;
use Entities\FeedPublisher;
use Gedmo\Timestampable\TimestampableListener;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -77,26 +82,37 @@ class patch_320f implements patchInterface
$stmt->closeCursor();
$date_ref = new DateTime();
$n = 0;
$app['EM']->getEventManager()->removeEventSubscriber(new TimestampableListener());
foreach ($rs as $row) {
$user = User_Adapter::getInstance($row['usr_id'], $app);
$feed = $this->get_feed($appbox, $user, $row['pub_restrict'], $row['homelink']);
$feed = $this->get_feed($appbox, $user, $row['pub_restrict'], $row['homelink'], $app);
if (! $feed instanceof Feed_Adapter) {
if (! $feed instanceof Feed) {
continue;
}
$publishers = $feed->get_publishers();
$entry = Feed_Entry_Adapter::create($app, $feed, array_shift($publishers), $row['name'], $row['descript'], $user->get_display_name(), $user->get_email());
$publishers = $feed->getPublishers();
$entry = new FeedEntry();
$entry->setAuthorEmail($user->get_email());
$entry->setAuthorName($user->get_display_name());
$entry->setFeed($feed);
$entry->setPublisher($publishers->first());
$entry->setTitle($row['name']);
$entry->setSubtitle($row['descript']);
$feed->addEntry($entry);
$date_create = new DateTime($row['pub_date']);
if ($date_create < $date_ref) {
$date_ref = $date_create;
}
$entry->set_created_on($date_create);
$entry->setCreatedOn($date_create);
if ($row['updater'] != '0000-00-00 00:00:00') {
$date_update = new DateTime($row['updater']);
$entry->set_updated_on($date_update);
$entry->setUpdatedOn($date_update);
}
$sql = 'SELECT sselcont_id, ssel_id, base_id, record_id
@@ -109,19 +125,36 @@ class patch_320f implements patchInterface
foreach ($rs as $row) {
try {
$record = new record_adapter($app, phrasea::sbasFromBas($app, $row['base_id']), $row['record_id']);
$item = Feed_Entry_Item::create($appbox, $entry, $record);
$item = new FeedItem();
$item->setEntry($entry);
$entry->addItem($item);
$item->setRecordId($record->get_record_id());
$item->setSbasId($record->get_sbas_id());
$app['EM']->persist($item);
} catch (NotFoundHttpException $e) {
}
}
$app['EM']->persist($entry);
$sql = 'UPDATE ssel SET deleted = "1", migrated="1"
WHERE ssel_id = :ssel_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':ssel_id' => $row['ssel_id']));
$stmt->closeCursor();
$app['EM']->persist($feed);
$n++;
if ($n % 1000 == 0) {
$app['EM']->flush();
$app['EM']->clear();
}
}
$this->set_feed_dates($date_ref);
$app['EM']->flush();
$app['EM']->clear();
$app['EM']->getEventManager()->removeEventSubscriber(new TimestampableListener());
return true;
}
@@ -130,7 +163,7 @@ class patch_320f implements patchInterface
{
foreach (self::$feeds as $array_feeds) {
foreach ($array_feeds as $feed) {
$feed->set_created_on($date_ref);
$feed->setCreatedOn($date_ref);
}
}
@@ -138,15 +171,16 @@ class patch_320f implements patchInterface
}
protected static $feeds = array();
protected function get_feed(appbox $appbox, User_Adapter $user, $pub_restrict, $homelink)
protected function get_feed(appbox $appbox, User_Adapter $user, $pub_restrict, $homelink, Application $app)
{
$user_key = 'user_' . $user->get_id();
if ($homelink == '1')
if ($homelink == '1') {
$feed_key = 'feed_homelink';
elseif ($pub_restrict == '1')
} elseif ($pub_restrict == '1') {
$feed_key = 'feed_restricted';
else
} else {
$feed_key = 'feed_public';
}
if ( ! array_key_exists($user_key, self::$feeds) || ! isset(self::$feeds[$user_key][$feed_key])) {
if ($homelink == '1')
@@ -156,10 +190,22 @@ class patch_320f implements patchInterface
else
$title = $user->get_display_name() . ' - ' . 'public Feed';
$feed = Feed_Adapter::create($app, $user, $title, '');
$feed = new Feed();
$publisher = new FeedPublisher();
$feed->setTitle('title');
$feed->setSubtitle('');
$feed->addPublisher($publisher);
$publisher->setFeed($feed);
$publisher->setOwner(true);
$publisher->setUsrId($user->get_id());
if ($homelink) {
$feed->set_public(true);
$feed->setPublic(true);
$app['EM']->persist($feed);
$app['EM']->persist($user);
$app['EM']->flush();
} elseif ($pub_restrict == 1) {
$collections = $user->ACL()->get_granted_base();
$collection = array_shift($collections);
@@ -177,7 +223,7 @@ class patch_320f implements patchInterface
if ( ! ($collection instanceof collection)) {
return false;
}
$feed->set_collection($collection);
$feed->setCollection($collection);
}
self::$feeds[$user_key][$feed_key] = $feed;
} else {

193
lib/classes/patch/3907.php Normal file
View File

@@ -0,0 +1,193 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2012 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
use Entities\AggregateToken;
use Entities\Feed;
use Entities\FeedEntry;
use Entities\FeedItem;
use Entities\FeedPublisher;
use Entities\FeedToken;
class patch_3907 implements patchInterface
{
/** @var string */
private $release = '3.9.0.a7';
/** @var array */
private $concern = array(base::APPLICATION_BOX);
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function apply(base $appbox, Application $app)
{
$conn = $app['phraseanet.appbox']->get_connection();
$sql = 'SHOW TABLE STATUS;';
$stmt = $conn->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$found = false;
foreach ($rs as $row) {
if ('feeds_backup' === $row['Name']) {
$found = true;
break;
}
}
if (!$found) {
return;
}
$sql = 'SELECT id, title, subtitle, public, created_on, updated_on, base_id FROM feeds_backup;';
$stmt = $conn->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
$n = 0;
$em = $app['EM'];
$fpSql = 'SELECT id, usr_id, owner, created_on FROM feed_publishers WHERE feed_id = :feed_id;';
$fpStmt = $conn->prepare($fpSql);
$feSql = 'SELECT id, title, description, created_on, updated_on, author_name, author_email FROM feed_entries WHERE feed_id = :feed_id AND publisher = :publisher_id;';
$feStmt = $conn->prepare($feSql);
$fiSql = 'SELECT sbas_id, record_id, ord FROM feed_entry_elements WHERE entry_id = :entry_id;';
$fiStmt = $conn->prepare($fiSql);
$ftSql = 'SELECT token, usr_id, aggregated FROM feed_tokens WHERE feed_id = :feed_id;';
$ftStmt = $conn->prepare($ftSql);
$faSql = 'SELECT token, usr_id FROM feed_tokens WHERE aggregated = 1;';
$faStmt = $conn->prepare($faSql);
foreach ($rs as $row) {
$feed = new Feed();
$feed->setTitle($row['title']);
$feed->setSubtitle($row['subtitle']);
$feed->setIconUrl(false);
$feed->setIsPublic($row['public']);
$feed->setCreatedOn(new \DateTime($row['created_on']));
$feed->setUpdatedOn(new \DateTime($row['updated_on']));
$feed->setCollection($row['base_id'] ? collection::get_from_base_id($app, $row['base_id']) : null);
$fpStmt->execute(array(':feed_id' => $row['id']));
$fpRes = $fpStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($fpRes as $fpRow) {
$feedPublisher = new FeedPublisher();
$feedPublisher->setFeed($feed);
$feed->addPublisher($feedPublisher);
$feedPublisher->setCreatedOn(new \DateTime($fpRow['created_on']));
$feedPublisher->setIsOwner($fpRow['owner']);
$feedPublisher->setUsrId($fpRow['usr_id']);
$feStmt->execute(array(':feed_id' => $row['id'], ':publisher_id' => $fpRow['id']));
$feRes = $feStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($feRes as $feRow) {
$feedEntry = new FeedEntry();
$feedEntry->setFeed($feed);
$feed->addEntry($feedEntry);
$feedEntry->setPublisher($feedPublisher);
$feedEntry->setTitle($feRow['title']);
$feedEntry->setSubtitle($feRow['description']);
$feedEntry->setAuthorName($feRow['author_name']);
$feedEntry->setAuthorEmail($feRow['author_email']);
$feedEntry->setCreatedOn(new \DateTime($feRow['created_on']));
$feedEntry->setUpdatedOn(new \DateTime($feRow['updated_on']));
$fiStmt->execute(array(':entry_id' => $feRow['id']));
$fiRes = $fiStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($fiRes as $fiRow) {
$feedItem = new FeedItem();
$feedItem->setEntry($feedEntry);
$feedEntry->addItem($feedItem);
$feedItem->setOrd($fiRow['ord']);
$feedItem->setSbasId($fiRow['sbas_id']);
$feedItem->setRecordId($fiRow['record_id']);
$em->persist($feedItem);
}
$em->persist($feedEntry);
}
$em->persist($feedPublisher);
}
$ftStmt->execute(array(':feed_id' => $row['id']));
$ftRes = $ftStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($ftRes as $ftRow)
{
$token = new FeedToken();
$token->setFeed($feed);
$feed->addToken($token);
$token->setUsrId($ftRow['usr_id']);
$token->setValue($ftRow['token']);
$em->persist($token);
}
$em->persist($feed);
$n++;
if ($n % 100 === 0) {
$em->flush();
$em->clear();
}
}
$fiStmt->closeCursor();
$feStmt->closeCursor();
$fpStmt->closeCursor();
$ftStmt->closeCursor();
$faStmt->execute();
$faRes = $faStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($faRes as $faRow)
{
$token = new AggregateToken();
$token->setUsrId($faRow['usr_id']);
$token->setValue($faRow['token']);
$em->persist($token);
}
$faStmt->closeCursor();
$em->flush();
$em->clear();
}
}

View File

@@ -175,30 +175,30 @@ class record_preview extends record_adapter
}
break;
case "FEED":
$entry = Feed_Entry_Adapter::load_from_id($app, $contId);
$entry = $app['EM']->getRepository('Entities\FeedEntry')->find($contId);
$this->container = $entry;
$this->total = count($entry->get_content());
$this->total = count($entry->getItems());
$i = 0;
$first = true;
foreach ($entry->get_content() as $element) {
foreach ($entry->getItems() as $element) {
$i ++;
if ($first) {
$sbas_id = $element->get_record()->get_sbas_id();
$record_id = $element->get_record()->get_record_id();
$sbas_id = $element->getRecord($this->app)->get_sbas_id();
$record_id = $element->getRecord($this->app)->get_record_id();
$this->name = $entry->getTitle();
$this->original_item = $element;
$this->name = $entry->get_title();
$number = $element->get_ord();
$number = $element->getOrd();
}
$first = false;
if ($element->get_ord() == $pos) {
$sbas_id = $element->get_record()->get_sbas_id();
$record_id = $element->get_record()->get_record_id();
if ($element->getOrd() == $pos) {
$sbas_id = $element->getRecord($this->app)->get_sbas_id();
$record_id = $element->getRecord($this->app)->get_record_id();
$this->name = $entry->getTitle();
$this->original_item = $element;
$this->name = $entry->get_title();
$number = $element->get_ord();
$number = $element->getOrd();
}
}
break;

View File

@@ -0,0 +1,94 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhraseaFixture\Feed;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Entities\Feed;
class LoadOneFeed extends AbstractFixture implements FixtureInterface
{
/**
*
* @var \Entities\Feed
*/
public $feed;
public $user;
public $title;
public $public;
public function load(ObjectManager $manager)
{
if (null === $this->user) {
throw new \LogicException('Fill a user to store a new feed');
}
$feed = new Feed();
$publisher = new \Entities\FeedPublisher();
$publisher->setUsrId($this->user->get_id());
$publisher->setIsOwner(true);
$publisher->setFeed($feed);
$feed->addPublisher($publisher);
if (isset($this->title) && $this->title !== null) {
$feed->setTitle($this->title);
} else {
$feed->setTitle("test");
}
if (isset($this->public) && $this->public !== null) {
$feed->setIsPublic($this->public);
}
$feed->setSubtitle("description");
$manager->persist($feed);
$manager->persist($publisher);
$manager->flush();
$this->feed = $feed;
$this->addReference('one-feed', $feed);
}
public function setUser(\User_Adapter $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setPublic($public)
{
$this->public = $public;
}
public function getPublic()
{
return $this->public;
}
}

View File

@@ -2498,440 +2498,6 @@
<engine>InnoDB</engine>
</table>
<table name="feed_publishers">
<fields>
<field>
<name>id</name>
<type>int(11) unsigned</type>
<null></null>
<extra>auto_increment</extra>
<default></default>
<comment></comment>
</field>
<field>
<name>usr_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>feed_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>owner</name>
<type>tinyint(11) unsigned</type>
<null>YES</null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>created_on</name>
<type>datetime</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>added_by</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
</fields>
<indexes>
<index>
<name>id</name>
<type>PRIMARY</type>
<fields>
<field>id</field>
</fields>
</index>
<index>
<name>couple</name>
<type>UNIQUE</type>
<fields>
<field>usr_id</field>
<field>feed_id</field>
</fields>
</index>
<index>
<name>owners</name>
<type>UNIQUE</type>
<fields>
<field>owner</field>
<field>feed_id</field>
</fields>
</index>
</indexes>
<engine>InnoDB</engine>
</table>
<table name="feeds">
<fields>
<field>
<name>id</name>
<type>int(11) unsigned</type>
<null></null>
<extra>auto_increment</extra>
<default></default>
<comment></comment>
</field>
<field>
<name>title</name>
<type>varchar(128)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>subtitle</name>
<type>varchar(8192)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>created_on</name>
<type>datetime</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>updated_on</name>
<type>datetime</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>base_id</name>
<type>int(11) unsigned</type>
<null>YES</null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>public</name>
<type>tinyint(1) unsigned</type>
<null></null>
<extra></extra>
<default>0</default>
<comment></comment>
</field>
</fields>
<indexes>
<index>
<name>id</name>
<type>PRIMARY</type>
<fields>
<field>id</field>
</fields>
</index>
<index>
<name>base_id</name>
<type>INDEX</type>
<fields>
<field>base_id</field>
</fields>
</index>
</indexes>
<engine>InnoDB</engine>
</table>
<table name="feed_tokens">
<fields>
<field>
<name>id</name>
<type>int(11) unsigned</type>
<null></null>
<extra>auto_increment</extra>
<default></default>
<comment></comment>
</field>
<field>
<name>token</name>
<type>varchar(12)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>feed_id</name>
<type>int(11) unsigned</type>
<null>YES</null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>usr_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>aggregated</name>
<type>tinyint(1) unsigned</type>
<null>YES</null>
<extra></extra>
<default></default>
<comment></comment>
</field>
</fields>
<indexes>
<index>
<name>id</name>
<type>PRIMARY</type>
<fields>
<field>id</field>
</fields>
</index>
<index>
<name>token</name>
<type>INDEX</type>
<fields>
<field>token</field>
</fields>
</index>
<index>
<name>usr_id</name>
<type>INDEX</type>
<fields>
<field>usr_id</field>
</fields>
</index>
<index>
<name>feed_id</name>
<type>INDEX</type>
<fields>
<field>feed_id</field>
</fields>
</index>
<index>
<name>aggregated</name>
<type>INDEX</type>
<fields>
<field>aggregated</field>
</fields>
</index>
<index>
<name>unikaggregated</name>
<type>UNIQUE</type>
<fields>
<field>aggregated</field>
<field>usr_id</field>
</fields>
</index>
<index>
<name>unikfeed</name>
<type>UNIQUE</type>
<fields>
<field>feed_id</field>
<field>usr_id</field>
</fields>
</index>
</indexes>
<engine>InnoDB</engine>
</table>
<table name="feed_entries">
<fields>
<field>
<name>id</name>
<type>int(11) unsigned</type>
<null></null>
<extra>auto_increment</extra>
<default></default>
<comment></comment>
</field>
<field>
<name>feed_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>publisher</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>title</name>
<type>varchar(128)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>author_name</name>
<type>varchar(128)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>author_email</name>
<type>varchar(128)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>description</name>
<type>varchar(8192)</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>created_on</name>
<type>datetime</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>updated_on</name>
<type>datetime</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
</fields>
<indexes>
<index>
<name>id</name>
<type>PRIMARY</type>
<fields>
<field>id</field>
</fields>
</index>
</indexes>
<engine>InnoDB</engine>
</table>
<table name="feed_entry_elements">
<fields>
<field>
<name>id</name>
<type>int(11) unsigned</type>
<null></null>
<extra>auto_increment</extra>
<default></default>
<comment></comment>
</field>
<field>
<name>entry_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>sbas_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>record_id</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
<field>
<name>ord</name>
<type>int(11) unsigned</type>
<null></null>
<extra></extra>
<default></default>
<comment></comment>
</field>
</fields>
<indexes>
<index>
<name>id</name>
<type>PRIMARY</type>
<fields>
<field>id</field>
</fields>
</index>
<index>
<name>element</name>
<type>INDEX</type>
<fields>
<field>sbas_id</field>
<field>record_id</field>
</fields>
</index>
<index>
<name>sbas_id</name>
<type>INDEX</type>
<fields>
<field>sbas_id</field>
</fields>
</index>
<index>
<name>record_id</name>
<type>INDEX</type>
<fields>
<field>record_id</field>
</fields>
</index>
</indexes>
<engine>InnoDB</engine>
</table>
<table name="sselnew">
<fields>
<field>

View File

View File

View File

@@ -12,26 +12,26 @@
{% block content %}
<div id="home" data-role="page">
<div data-role="header">
<h1>{{feed_entry.get_title()}}</h1>
<h1>{{feed_entry.getTitle()}}</h1>
<a rel="external" href="{{ path('lightbox') }}" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">{% trans 'Home' %}</a>
</div>
<div data-role="content">
<p>
{{feed_entry.get_subtitle()|nl2br|raw}}
{{feed_entry.getSubtitle()|nl2br|raw}}
</p>
<p>
{% set author = feed_entry.get_author_name() %}
{% set author = feed_entry.getAuthorName() %}
<span class="author">{% trans %}Par {{ author }}{% endtrans %}</span>
{% set entry_length = feed_entry.get_content()|length %}
{% set entry_length = feed_entry.getItems()|length %}
{% trans %}{{entry_length}} documents{% endtrans %}
</p>
<ul class="image_set">
{% for item in feed_entry.get_content() %}
<li class="image_box" id="item_{{item.get_id()}}">
<a href="{{ path('lightbox_ajax_load_feeditem', { 'entry_id' : feed_entry.get_id(), 'item_id' : item.get_id()}) }}">
{{thumbnail.format(item.get_record().get_thumbnail(), 80, 80, '', true, false)}}
{% for item in feed_entry.getItems() %}
<li class="image_box" id="item_{{item.getId()}}">
<a href="{{ path('lightbox_ajax_load_feeditem', { 'entry_id' : feed_entry.getId(), 'item_id' : item.getId()}) }}">
{{thumbnail.format(item.getRecord(app).get_thumbnail(), 80, 80, '', true, false)}}
</a>
<input type="hidden" class="display_id" name="display_id" value="{{item.get_ord()}}" />
<input type="hidden" class="display_id" name="display_id" value="{{item.getOrd()}}" />
</li>
{% endfor %}
</ul>

View File

@@ -11,11 +11,11 @@
{% endblock %}
{% block content %}
{% set record = feed_element.get_record() %}
{% set record = feed_element.getRecord(app) %}
<div data-role="page">
<div data-role="header">
<a href="{{ path('lightbox_feed_entry', { 'entry_id' : feed_element.get_entry().get_id() }) }}" data-rel="back" data-icon="arrow-l">Back</a>
<h1>{{feed_element.get_ord()}} - {{record.get_title()}}</h1>
<a href="{{ path('lightbox_feed_entry', { 'entry_id' : feed_element.getEntry().getId() }) }}" data-rel="back" data-icon="arrow-l">Back</a>
<h1>{{feed_element.getOrd()}} - {{record.get_title()}}</h1>
<a rel="external" href="{{ path('lightbox') }}" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Home</a>
</div>
<div data-role="content">

View File

@@ -6,16 +6,20 @@
{% if error %}
<div class="error alert alert-error">{{ error }}</div>
{% endif %}
{% if feed.is_owner(app['authentication'].getUser()) %}
{% if feed.isOwner(app['authentication'].getUser()) %}
<h2>{% trans 'Edition' %}</h2>
<div class="control-group">
<div id="pub_icon">
<div class="thumb_wrapper">
<img id="img_before" src="{{ feed.get_icon_url() }}" />
<img id="img_before" src="{% if feed.getIconUrl() == false %}
/skins/icons/rss32.gif
{% else %}
/custom/feed_{{ feed.getId() }}.jpg
{% endif %}" />
</div>
</div>
<div id="pub_fileupload">
<input id="fileupload-feed" type="file" name="files[]" accept="image/*" data-url="/admin/publications/feed/{{ feed.get_id() }}/iconupload/">
<input id="fileupload-feed" type="file" name="files[]" accept="image/*" data-url="/admin/publications/feed/{{ feed.getId() }}/iconupload/">
</div>
</div>
<div class="clear"></div>
@@ -79,28 +83,28 @@
});
</script>
<form class="no-ajax form_publication form-vertical" name="form_publication" enctype="multipart/form-data" method="post" action="{{ path('admin_feeds_feed_update', { 'id' : feed.get_id() }) }}">
<form class="no-ajax form_publication form-vertical" name="form_publication" enctype="multipart/form-data" method="post" action="{{ path('admin_feeds_feed_update', { 'id' : feed.getId() }) }}">
<div class="control-group">
<label class="control-label" for="edit_pub_titre">{% trans 'Titre' %} :</label>
<div class="controls">
<input id="edit_pub_titre" class="required_text input-large" maxlength="128" name="title" type="text" value="{{ feed.get_title() }}" />
<input id="edit_pub_titre" class="required_text input-large" maxlength="128" name="title" type="text" value="{{ feed.getTitle() }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="edit_pub_subtitre">{% trans 'Sous-titre' %} :</label>
<div class="controls">
<input placeholder="{% trans 'Short description' %}" id="edit_pub_subtitre" class="input-large" maxlength="512" name="subtitle" type="text" value="{{ feed.get_subtitle() }}" />
<input placeholder="{% trans 'Short description' %}" id="edit_pub_subtitre" class="input-large" maxlength="512" name="subtitle" type="text" value="{{ feed.getSubtitle() }}" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="edit_pub_base_id">{% trans 'Etendue de la publication' %} :</label>
<div class="controls">
<select id="edit_pub_base_id" class="input-large" name="base_id" {% if feed.is_public() %}disabled="disabled"{% endif %}>
<select id="edit_pub_base_id" class="input-large" name="base_id" {% if feed.isPublic() %}disabled="disabled"{% endif %}>
<option value="">{% trans 'Non-Restreinte (publique)' %}</option>
{% for databox in app['authentication'].getUser().ACL().get_granted_sbas('bas_chupub') %}
<optgroup label="{{ databox.get_label(app['locale.I18n']) }}">
{% for collection in databox.get_collections() %}
<option {% if feed.get_collection() and feed.get_collection().get_base_id() == collection.get_base_id() %}selected="selected"{% endif %} value="{{ collection.get_base_id() }}">{{ collection.get_name() }}</option>
<option {% if feed.getBaseId() and feed.getCollection(app).get_base_id() == collection.get_base_id() %}selected="selected"{% endif %} value="{{ collection.get_base_id() }}">{{ collection.get_name() }}</option>
{% endfor %}
</optgroup>
{% endfor %}
@@ -110,7 +114,7 @@
<div class="control-group">
<div class="controls">
<label class="checkbox" for="edit_pub_public">
<input type="checkbox" id="edit_pub_public" class="input-large" name="public" value="1" {% if feed.is_public() %}checked="checked"{% endif %} />
<input type="checkbox" id="edit_pub_public" class="input-large" name="public" value="1" {% if feed.isPublic() %}checked="checked"{% endif %} />
{% trans 'Publique' %}
</label>
</div>
@@ -133,23 +137,23 @@
</tr>
</thead>
<tbody>
{% for publisher in feed.get_publishers() %}
{% for publisher in feed.getPublishers() %}
<tr class="{% if loop.index is odd %}odd{% else %}even{% endif %}">
<td valign="center" align="left">
{{ publisher.get_user().get_id() }}
{{ publisher.getUsrId() }}
</td>
<td valign="center" align="left">
{{ publisher.get_user().get_display_name() }}
{{ publisher.getUser(app).get_display_name() }}
</td>
<td valign="center" align="left">
{{ publisher.get_user().get_email() }}
{{ publisher.getUser(app).get_email() }}
</td>
<td valign="center" align="center">
{% if publisher.is_owner() == true %}
{% if publisher.isOwner() == true %}
X
{% else %}
<form class="no-ajax form_publication" method="post" action="{{ path('admin_feeds_feed_remove_publisher', { 'id' : feed.get_id() }) }}" style="margin:0;">
<input type="hidden" value="{{ publisher.get_id() }}" name="publisher_id"/>
<form class="no-ajax form_publication" method="post" action="{{ path('admin_feeds_feed_remove_publisher', { 'id' : feed.getId() }) }}" style="margin:0;">
<input type="hidden" value="{{ publisher.getId() }}" name="publisher_id"/>
<button class="btn btn-mini">{% trans 'boutton::supprimer' %}</button>
</form>
{% endif %}
@@ -159,7 +163,7 @@
</tbody>
</table>
<div>
<form class="no-ajax form_publication" id="publisher_adder" method="post" action="{{ path('admin_feeds_feed_add_publisher', { 'id' : feed.get_id() }) }}">
<form class="no-ajax form_publication" id="publisher_adder" method="post" action="{{ path('admin_feeds_feed_add_publisher', { 'id' : feed.getId() }) }}">
<div class="control-group">
<label class="control-label">{% trans 'Ajouter un publisher' %} :</label>
<div class="controls">

View File

@@ -59,35 +59,39 @@
</tr>
</thead>
<tbody>
{% for feed in feeds.get_feeds %}
{% for feed in feeds %}
<tr class="{% if loop.index is odd %}odd{% else %}even{% endif %}">
<td>
<div style="border:1px solid #ccc; width:22px; height:22px; margin:2px;">
<a href="{{ path('admin_feeds_feed', { 'id' : feed.get_id() }) }}">
<img src="{{feed.get_icon_url() ~ '?' ~ random(1000) }}" id="pub_icon" style="margin:3px; width:16px; height:16px;"/>
<a href="{{ path('admin_feeds_feed', { 'id' : feed.getId() }) }}">
<img src="{% if feed.getIconUrl() == false %}
/skins/icons/rss32.gif
{% else %}
/custom/feed_{{ feed.getId() }}.jpg
{% endif %}" id="pub_icon" style="margin:3px; width:16px; height:16px;"/>
</a>
</div>
</td>
<td valign="center" align="left">
<a href="{{ path('admin_feeds_feed', { 'id' : feed.get_id() }) }}" style="display:block;">{{ feed.get_title() }}</a>
<a href="{{ path('admin_feeds_feed', { 'id' : feed.getId() }) }}" style="display:block;">{{ feed.getTitle() }}</a>
</td>
<td style="text-align: center;">
{{ app['date-formatter'].getDate(feed.get_created_on()) }}
{{ app['date-formatter'].getDate(feed.getCreatedOn()) }}
</td>
<td valign="center" align="center">
{% 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 %}
</td>
<td valign="center" align="center">
{% if feed.is_public() %}
{% if feed.isPublic() %}
<img src="/skins/icons/ligth-on.png" title="{% trans 'This feed is public' %}"/>
{% endif %}
</td>
<td valign="center" align="center">
{% if feed.is_owner(app['authentication'].getUser()) %}
<form class="no-ajax form_publication" action="{{ path('admin_feeds_feed_delete', { 'id' : feed.get_id() }) }}" method="post" style="margin:0;">
{% if feed.isOwner(app['authentication'].getUser()) %}
<form class="no-ajax form_publication" action="{{ path('admin_feeds_feed_delete', { 'id' : feed.getId() }) }}" method="post" style="margin:0;">
<button class="feed_remover btn btn-mini">{% trans 'boutton::supprimer' %}</button>
</form>
{% endif %}

View File

@@ -5,24 +5,24 @@
</div>
<div>
{% for entry in feeds.get_aggregate().get_entries(0, 5).get_entries() %}
{% for entry in feeds.getEntries(0, 5) %}
<div class="boxPubli">
<div class="titlePubli">
<h2 class="htitlePubli">
<a class="homePubTitle" onclick="openCompare('{{ entry.get_id() }}');">
{{ entry.get_title() }}
<a class="homePubTitle" onclick="openCompare('{{ entry.getId() }}');">
{{ entry.getTitle() }}
</a>
</h2>
<span class="publiInfos">
{{ app['date-formatter'].getPrettyString(entry.get_created_on()) }}
{% if entry.get_author_email() %}
<a class="homePubLink" href="mailto:{{ entry.get_author_email() }}">
{{ entry.get_author_name() }}
{{ app['date-formatter'].getPrettyString(entry.getCreatedOn()) }}
{% if entry.getAuthorEmail() %}
<a class="homePubLink" href="mailto:{{ entry.getAuthorEmail() }}">
{{ entry.getAuthorName() }}
</a>
{% if entry.get_updated_on() > entry.get_created_on() %}
{% if entry.getUpdatedOn() > entry.getCreatedOn() %}
<br/>
<span style="font-style:italic;">
{% trans "publications:: derniere mise a jour" %} {{ app['date-formatter'].getPrettyString(entry.get_updated_on()) }}
{% trans "publications:: derniere mise a jour" %} {{ app['date-formatter'].getPrettyString(entry.getUpdatedOn()) }}
</span>
<br />
<br />
@@ -32,14 +32,14 @@
</div>
<div class="descPubli">
<div style="margin:10px 0 10px 20px;width:80%;">
{% if entry.get_subtitle()|trim is not empty %}
{{ entry.get_subtitle()|nl2br }}
{% if entry.getSubtitle()|trim is not empty %}
{{ entry.getSubtitle()|nl2br }}
{% endif %}
</div>
</div>
<div style="width:100%;position:relative;float:left;" id="PUBLICONT{{ entry.get_id() }}">
{% for item in entry.get_content() %}
{% set record = item.get_record() %}
<div style="width:100%;position:relative;float:left;" id="PUBLICONT{{ entry.getId() }}">
{% for item in entry.getItems() %}
{% set record = item.getRecord(app) %}
{% set thumbnail = record.get_thumbnail() %}
{% set docType = record.get_type() %}
{% set duration = "" %}
@@ -76,7 +76,7 @@
{% endset %}
{% endif %}
<div style="width:{{ wrapper_size }}px;" sbas="{{ record.get_sbas_id() }}" id="{{"IMGT_" ~ record.get_serialize_key() ~ "_PUB_" ~ entry.get_id() }}" class="IMGT diapo" onclick="openPreview('FEED','{{ item.get_ord() }}','{{ entry.get_id() }}');">
<div style="width:{{ wrapper_size }}px;" sbas="{{ record.get_sbas_id() }}" id="{{"IMGT_" ~ record.get_serialize_key() ~ "_PUB_" ~ entry.getId() }}" class="IMGT diapo" onclick="openPreview('FEED','{{ item.getOrd() }}','{{ entry.getId() }}');">
<div>
<div class="title" style="height:40px;">
{{ record.get_title() }}

View File

@@ -18,11 +18,11 @@
<tr valign="middle">
<td style="width:10px;"></td>
<td style="width:35px;text-align:center;">
<div class="display_id">{% if first_item %}{{first_item.get_ord()}}{% endif %}</div>
<div class="display_id">{% if first_item %}{{first_item.getOrd()}}{% endif %}</div>
</td>
<td style="text-align:left;width:auto;">
<div class="title title15" title="{% if first_item %}{{first_item.get_record().get_title|e}}{% endif %}">
{% if first_item %}{{first_item.get_record().get_title}}{% endif %}
<div class="title title15" title="{% if first_item %}{{first_item.getRecord(app).get_title|e}}{% endif %}">
{% if first_item %}{{first_item.getRecord(app).get_title}}{% endif %}
</div>
</td>
<td style="text-align:right;width:230px;">
@@ -34,10 +34,10 @@
</div>
<div class="lightbox_container left">
{% if first_item %}
{% if app['authentication'].getUser().ACL().has_access_to_subdef(first_item.get_record(), 'preview') %}
{% set preview = first_item.get_record().get_preview() %}
{% if app['authentication'].getUser().ACL().has_access_to_subdef(first_item.getRecord(app), 'preview') %}
{% set preview = first_item.getRecord(app).get_preview() %}
{% else %}
{% set preview = first_item.get_record().get_thumbnail() %}
{% set preview = first_item.getRecord(app).get_thumbnail() %}
{% endif %}
{{thumbnail.format(preview, preview.get_width(), preview.get_height(),'', false, false)}}
{% endif %}
@@ -52,8 +52,8 @@
<div class="display_id"></div>
</td>
<td style="text-align:left;width:auto;">
<div class="title title15" title="{% if first_item %}{{first_item.get_record().get_title|e}}{% endif %}">
{% if first_item %}{{first_item.get_record().get_title}}{% endif %}
<div class="title title15" title="{% if first_item %}{{first_item.getRecord(app).get_title|e}}{% endif %}">
{% if first_item %}{{first_item.getRecord(app).get_title}}{% endif %}
</div>
</td>
<td style="text-align:right;width:230px;">
@@ -81,9 +81,9 @@
<div class="right_column_wrapper right_column_wrapper_caption left unselectable" style="width:230px;height:auto;">
<div id="record_infos">
<div class="lightbox_container">
{% set business = app['authentication'].getUser().ACL().has_right_on_base(first_item.get_record().get_base_id(), 'canmodifrecord') %}
{% set business = app['authentication'].getUser().ACL().has_right_on_base(first_item.getRecord(app).get_base_id(), 'canmodifrecord') %}
{% if first_item %}
{{caption.format_caption(first_item.get_record(), '', null, business)}}
{{caption.format_caption(first_item.getRecord(app), '', null, business)}}
{% endif %}
</div>
</div>

View File

@@ -1,16 +1,16 @@
{% block basket %}
<div id="sc_container">
{% for element in feed_entry.get_content() %}
{% for element in feed_entry.getItems() %}
<div class="basket_element_wrapper">
<a href="{{ path('lightbox_ajax_load_feeditem', { 'entry_id' : feed_entry.get_id(), 'item_id' : element.get_id()}) }}">
<div id="scid_{{element.get_id()}}" class="basket_element ui-corner-all {% if first_item and first_item.get_id() == element.get_id() %}selected{% endif %}">
<div class="display_id">{{element.get_ord()}}</div>
{{thumbnail.format(element.get_record().get_thumbnail() ,114,85, '', true, false)}}
<a href="{{ path('lightbox_ajax_load_feeditem', { 'entry_id' : feed_entry.getId(), 'item_id' : element.getId()}) }}">
<div id="scid_{{element.getId()}}" class="basket_element ui-corner-all {% if first_item and first_item.getId() == element.getId() %}selected{% endif %}">
<div class="display_id">{{element.getOrd()}}</div>
{{thumbnail.format(element.getRecord(app).get_thumbnail() ,114,85, '', true, false)}}
<form name="download_form" class="download_form" style="display:none;">
<input type="hidden" name="basrec" value="{{element.get_record().get_serialize_key()}}"/>
<input type="hidden" name="basrec" value="{{element.getRecord(app).get_serialize_key()}}"/>
</form>
<div tooltipsrc="{{ path('prod_tooltip_preview', { 'sbas_id' : element.get_record().get_sbas_id(), 'record_id' : element.get_record().get_record_id() }) }}" class="previewTips"></div>
<div tooltipsrc="{{ path('prod_tooltip_preview', { 'sbas_id' : element.getRecord(app).get_sbas_id(), 'record_id' : element.getRecord(app).get_record_id() }) }}" class="previewTips"></div>
</div>
</a>
</div>

View File

@@ -22,7 +22,7 @@
<img src="/skins/lightbox/saveie6.png"/>
</button>
<form name="download_form" style="display:none;">
<input type="hidden" name="basrec" value="{{feed_element.get_record().get_serialize_key()}}"/>
<input type="hidden" name="basrec" value="{{feed_element.getRecord(app).get_serialize_key()}}"/>
</form>
|
{% endif %}

View File

@@ -24,11 +24,11 @@
<tr valign="middle">
<td style="width:10px;"></td>
<td style="width:35px;text-align:center;">
<div class="display_id">{% if first_item %}{{first_item.get_ord()}}{% endif %}</div>
<div class="display_id">{% if first_item %}{{first_item.getOrd()}}{% endif %}</div>
</td>
<td style="text-align:left;width:auto;">
<div class="title title15" title="{% if first_item %}{{first_item.get_record().get_title|e}}{% endif %}">
{% if first_item %}{{first_item.get_record().get_title|raw}}{% endif %}
<div class="title title15" title="{% if first_item %}{{first_item.getRecord(app).get_title|e}}{% endif %}">
{% if first_item %}{{first_item.getRecord(app).get_title|raw}}{% endif %}
</div>
</td>
<td style="text-align:right;width:230px;">
@@ -42,10 +42,10 @@
</div>
<div class="lightbox_container PNB record_display_box">
{% if first_item %}
{% if app['authentication'].getUser().ACL().has_access_to_subdef(first_item.get_record(), 'preview') %}
{% set bask_prev = first_item.get_record().get_preview() %}
{% if app['authentication'].getUser().ACL().has_access_to_subdef(first_item.getRecord(app), 'preview') %}
{% set bask_prev = first_item.getRecord(app).get_preview() %}
{% else %}
{% set bask_prev = first_item.get_record().get_thumbnail() %}
{% set bask_prev = first_item.getRecord(app).get_thumbnail() %}
{% endif %}
{{thumbnail.format(bask_prev,bask_prev.get_width(),bask_prev.get_height(),'', false, false)}}
{% endif %}
@@ -60,8 +60,8 @@
<div class="display_id"></div>
</td>
<td style="text-align:left;width:auto;">
<div class="title title15" title="{% if first_item %}{{first_item.get_record().get_title|e}}{% endif %}">
{% if first_item %}{{first_item.get_record().get_title}}{% endif %}
<div class="title title15" title="{% if first_item %}{{first_item.getRecord(app).get_title|e}}{% endif %}">
{% if first_item %}{{first_item.getRecord(app).get_title}}{% endif %}
</div>
</td>
<td style="text-align:right;width:230px;">
@@ -81,9 +81,9 @@
<div class="right_column_wrapper caption right_column_wrapper_caption PNB">
<div id="record_infos" class="PNB">
<div class="lightbox_container PNB">
{% set business = app['authentication'].getUser().ACL().has_right_on_base(first_item.get_record().get_base_id(), 'canmodifrecord') %}
{% set business = app['authentication'].getUser().ACL().has_right_on_base(first_item.getRecord(app).get_base_id(), 'canmodifrecord') %}
{% if first_item %}
{{caption.format_caption(first_item.get_record(), '', null, business)}}
{{caption.format_caption(first_item.getRecord(app), '', null, business)}}
{% endif %}
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More