From 4161ef2e316b639ca33b6b301508a1bf0b7df084 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Tue, 11 Jun 2013 18:29:40 +0200 Subject: [PATCH] Use url generator everywhere --- lib/Alchemy/Phrasea/Application.php | 56 +- lib/Alchemy/Phrasea/Application/Root.php | 2 +- lib/Alchemy/Phrasea/CLI.php | 9 - .../Phrasea/Command/Setup/LessCompile.php | 6 +- .../Phrasea/Controller/Admin/Collection.php | 176 +- .../Controller/Admin/ConnectedUsers.php | 3 +- .../Phrasea/Controller/Admin/Dashboard.php | 12 +- .../Phrasea/Controller/Admin/Databox.php | 107 +- .../Phrasea/Controller/Admin/Databoxes.php | 38 +- .../Phrasea/Controller/Admin/Publications.php | 40 +- lib/Alchemy/Phrasea/Controller/Admin/Root.php | 90 +- .../Phrasea/Controller/Admin/Setup.php | 8 +- .../Phrasea/Controller/Admin/Subdefs.php | 10 +- .../Phrasea/Controller/Admin/TaskManager.php | 77 +- .../Phrasea/Controller/Admin/Users.php | 28 +- lib/Alchemy/Phrasea/Controller/Api/Oauth2.php | 6 +- .../Phrasea/Controller/Client/Baskets.php | 14 +- .../Phrasea/Controller/Client/Root.php | 6 +- lib/Alchemy/Phrasea/Controller/Datafiles.php | 5 +- .../{Application => Controller}/Lightbox.php | 65 +- lib/Alchemy/Phrasea/Controller/Permalink.php | 28 +- .../Phrasea/Controller/Prod/Basket.php | 26 +- .../Phrasea/Controller/Prod/Bridge.php | 50 +- .../Phrasea/Controller/Prod/Download.php | 4 +- .../Phrasea/Controller/Prod/Export.php | 2 +- lib/Alchemy/Phrasea/Controller/Prod/Feed.php | 46 +- .../Controller/Prod/MoveCollection.php | 4 +- lib/Alchemy/Phrasea/Controller/Prod/Order.php | 12 +- .../Phrasea/Controller/Prod/Printer.php | 2 +- lib/Alchemy/Phrasea/Controller/Prod/Push.php | 34 +- lib/Alchemy/Phrasea/Controller/Prod/Root.php | 6 +- lib/Alchemy/Phrasea/Controller/Prod/Story.php | 20 +- lib/Alchemy/Phrasea/Controller/Prod/Tools.php | 8 +- .../Phrasea/Controller/Prod/Tooltip.php | 27 +- .../Phrasea/Controller/Prod/UsrLists.php | 8 +- .../Phrasea/Controller/Prod/WorkZone.php | 15 +- .../Phrasea/Controller/Report/Root.php | 2 +- .../Phrasea/Controller/Root/Account.php | 20 +- .../Phrasea/Controller/Root/Developers.php | 2 +- lib/Alchemy/Phrasea/Controller/Root/Login.php | 98 +- .../Phrasea/Controller/Root/RSSFeeds.php | 21 +- lib/Alchemy/Phrasea/Controller/Root/Root.php | 12 +- lib/Alchemy/Phrasea/Controller/Setup.php | 20 +- .../Controller/Thesaurus/Thesaurus.php | 6 +- lib/Alchemy/Phrasea/Helper/User/Manage.php | 4 +- .../Notification/Mail/AbstractMail.php | 2 +- .../Notification/Mail/MailInfoNewOrder.php | 2 +- .../Mail/MailInfoOrderCancelled.php | 2 +- .../Mail/MailInfoOrderDelivered.php | 2 +- .../Mail/MailInfoRecordQuarantined.php | 2 +- .../Mail/MailInfoSomebodyAutoregistered.php | 2 +- .../Mail/MailInfoUserRegistered.php | 2 +- .../Mail/MailSuccessAccessRequest.php | 2 +- ...MailSuccessEmailConfirmationRegistered.php | 2 +- ...ilSuccessEmailConfirmationUnregistered.php | 2 +- .../Mail/MailSuccessEmailUpdate.php | 2 +- .../Phrasea/Notification/Mail/MailTest.php | 2 +- .../Phrasea/ConfigurationPanel.php | 2 +- .../SphinxSearch/ConfigurationPanel.php | 2 +- lib/Alchemy/Phrasea/Security/Firewall.php | 12 +- lib/classes/Bridge/Api.php | 25 +- lib/classes/Bridge/Api/Abstract.php | 6 +- lib/classes/Bridge/Api/Dailymotion.php | 2 +- lib/classes/Bridge/Api/Interface.php | 4 +- lib/classes/Bridge/Api/Youtube.php | 2 +- lib/classes/eventsmanager/notify/feed.php | 2 +- lib/classes/eventsmanager/notify/register.php | 2 +- lib/classes/eventsmanager/notify/validate.php | 4 +- lib/classes/media/Permalink/Adapter.php | 31 +- lib/conf.d/minifyGroupsConfig.php | 24 +- .../api/auth/end_user_authorization.html.twig | 25 +- .../auth/native_app_access_token.html.twig | 25 +- templates/mobile/common/index.html.twig | 6 +- .../mobile/lightbox/basket_element.html.twig | 10 +- templates/mobile/lightbox/error.html.twig | 2 +- templates/mobile/lightbox/feed.html.twig | 8 +- .../mobile/lightbox/feed_element.html.twig | 8 +- templates/mobile/lightbox/index.html.twig | 10 +- templates/mobile/lightbox/note_form.html.twig | 4 +- templates/mobile/lightbox/validate.html.twig | 10 +- templates/mobile/login/index.html.twig | 5 +- .../Prod/Feedback-Badge.Mustache.html | 12 +- .../Mustache/Prod/Push-Badge.Mustache.html | 4 +- templates/web/account/account.html.twig | 4 +- templates/web/account/base.html.twig | 4 +- templates/web/account/reset-email.html.twig | 2 +- .../web/admin/collection/collection.html.twig | 30 +- .../web/admin/collection/details.html.twig | 2 +- .../collection/suggested_value.html.twig | 4 +- .../web/admin/common/iframe_wrap.html.twig | 2 +- templates/web/admin/dashboard.html.twig | 8 +- templates/web/admin/databox/details.html.twig | 2 +- templates/web/admin/editusers.html.twig | 4 +- templates/web/admin/fields/index.html.twig | 4 +- templates/web/admin/index.html.twig | 4 +- .../web/admin/publications/fiche.html.twig | 10 +- .../web/admin/publications/list.html.twig | 8 +- templates/web/admin/statusbit.html.twig | 6 +- templates/web/admin/statusbit/edit.html.twig | 4 +- templates/web/admin/structure.html.twig | 2 +- templates/web/admin/subdefs.html.twig | 8 +- templates/web/admin/tasks/list.html.twig | 4 +- templates/web/admin/tree.html.twig | 36 +- templates/web/admin/user/demand.html.twig | 2 +- .../web/admin/user/import/file.html.twig | 6 +- .../web/admin/user/import/view.html.twig | 2 +- templates/web/admin/users.html.twig | 14 +- .../api/auth/end_user_authorization.html.twig | 25 +- .../auth/native_app_access_token.html.twig | 24 +- templates/web/client/answers.html.twig | 4 +- templates/web/client/baskets.html.twig | 2 +- .../client/home_inter_pub_basket.html.twig | 2 +- templates/web/client/index.html.twig | 26 +- templates/web/common/dialog_export.html.twig | 10 +- .../web/common/index_bootstrap.html.twig | 10 +- templates/web/common/menubar.html.twig | 16 +- templates/web/lightbox/IE6/feed.html.twig | 8 +- .../web/lightbox/IE6/feed_container.html.twig | 4 +- templates/web/lightbox/IE6/index.html.twig | 8 +- .../web/lightbox/IE6/sc_container.html.twig | 4 +- templates/web/lightbox/IE6/validate.html.twig | 8 +- templates/web/lightbox/error.html.twig | 4 +- templates/web/lightbox/feed.html.twig | 8 +- .../web/lightbox/feed_container.html.twig | 4 +- templates/web/lightbox/index.html.twig | 8 +- templates/web/lightbox/sc_container.html.twig | 4 +- templates/web/lightbox/validate.html.twig | 8 +- .../web/login/layout/base-layout.html.twig | 7 +- templates/web/overview.html.twig | 6 +- templates/web/prod/Baskets/Create.html.twig | 2 +- templates/web/prod/Baskets/Reorder.html.twig | 2 +- templates/web/prod/Baskets/Update.html.twig | 2 +- templates/web/prod/Story/Create.html.twig | 2 +- templates/web/prod/Story/Reorder.html.twig | 2 +- templates/web/prod/User/Add.html.twig | 2 +- .../prod/WorkZone/Browser/Basket.html.twig | 14 +- .../prod/WorkZone/Browser/Browser.html.twig | 2 +- .../prod/WorkZone/Browser/Results.html.twig | 20 +- templates/web/prod/WorkZone/Macros.html.twig | 34 +- .../Dailymotion/actioncontainers.html.twig | 4 +- .../Dailymotion/actionelement.html.twig | 2 +- .../Dailymotion/actionelements.html.twig | 4 +- .../playlist_createcontainer.html.twig | 2 +- .../playlist_deleteelement.html.twig | 2 +- .../Bridge/Dailymotion/upload.html.twig | 2 +- .../Dailymotion/video_deleteelement.html.twig | 2 +- .../Bridge/Dailymotion/video_modify.html.twig | 2 +- .../video_moveinto_playlist.html.twig | 2 +- .../Bridge/Flickr/actioncontainers.html.twig | 4 +- .../Bridge/Flickr/actionelement.html.twig | 2 +- .../Bridge/Flickr/actionelements.html.twig | 4 +- .../Flickr/photo_deleteelement.html.twig | 2 +- .../Bridge/Flickr/photo_modify.html.twig | 2 +- .../Flickr/photo_moveinto_photoset.html.twig | 2 +- .../Flickr/photoset_createcontainer.html.twig | 2 +- .../Flickr/photoset_deleteelement.html.twig | 2 +- .../actions/Bridge/Flickr/upload.html.twig | 2 +- .../Bridge/Youtube/actioncontainers.html.twig | 4 +- .../Bridge/Youtube/actionelement.html.twig | 2 +- .../Bridge/Youtube/actionelements.html.twig | 4 +- .../playlist_createcontainer.html.twig | 2 +- .../Youtube/playlist_deleteelement.html.twig | 2 +- .../actions/Bridge/Youtube/upload.html.twig | 2 +- .../Youtube/video_deleteelement.html.twig | 2 +- .../Bridge/Youtube/video_modify.html.twig | 2 +- .../Youtube/video_moveinto_playlist.html.twig | 2 +- .../actions/Bridge/disconnected.html.twig | 2 +- .../web/prod/actions/Bridge/index.html.twig | 8 +- .../web/prod/actions/Bridge/wrapper.html.twig | 8 +- .../web/prod/actions/Feedback/list.html.twig | 6 +- .../prod/actions/Feedback/lists-all.html.twig | 6 +- .../web/prod/actions/Property/index.html.twig | 4 +- .../web/prod/actions/Property/type.html.twig | 2 +- templates/web/prod/actions/Push.html.twig | 11 +- .../web/prod/actions/Tools/index.html.twig | 8 +- .../prod/actions/collection_default.html.twig | 2 +- .../actions/delete_records_confirm.html.twig | 2 +- .../web/prod/actions/edit_default.html.twig | 8 +- .../prod/actions/printer_default.html.twig | 2 +- .../prod/actions/publish/publish.html.twig | 2 +- .../actions/publish/publish_edit.html.twig | 2 +- .../web/prod/feeds/entry_macro.html.twig | 6 +- templates/web/prod/feeds/feeds.html.twig | 14 +- templates/web/prod/index.html.twig | 28 +- .../web/prod/orders/order_item.html.twig | 6 +- .../web/prod/preview/appears_in.html.twig | 2 +- .../web/prod/preview/basket_train.html.twig | 2 +- .../web/prod/preview/feed_train.html.twig | 2 +- .../web/prod/preview/reg_train.html.twig | 2 +- templates/web/prod/results/record.html.twig | 12 +- templates/web/prod/upload/lazaret.html.twig | 2 +- .../web/prod/upload/upload-flash.html.twig | 8 +- templates/web/prod/upload/upload.html.twig | 6 +- templates/web/report/all_content.html.twig | 12 +- templates/web/setup/wrapper.html.twig | 10 +- templates/web/thesaurus/accept.html.twig | 4 +- .../thesaurus/export-text-dialog.html.twig | 2 +- templates/web/thesaurus/export-text.html.twig | 2 +- .../thesaurus/export-topics-dialog.html.twig | 2 +- .../web/thesaurus/export-topics.html.twig | 2 +- .../web/thesaurus/import-dialog.html.twig | 2 +- templates/web/thesaurus/index.html.twig | 4 +- .../web/thesaurus/link-field-step1.html.twig | 2 +- .../web/thesaurus/link-field-step2.html.twig | 4 +- .../web/thesaurus/link-field-step3.html.twig | 2 +- .../thesaurus/new-synonym-dialog.html.twig | 2 +- templates/web/thesaurus/new-term.html.twig | 6 +- templates/web/thesaurus/properties.html.twig | 10 +- templates/web/thesaurus/search.html.twig | 2 +- templates/web/thesaurus/thesaurus.html.twig | 13 +- .../Tests/Phrasea/Application/ApiAbstract.php | 35 +- .../Alchemy/Tests/Phrasea/ApplicationTest.php | 13 + .../Phrasea/Controller/Prod/BridgeTest.php | 14 +- .../Phrasea/Controller/Root/RootTest.php | 2 +- .../Notification/Mail/AbstractMailTest.php | 11 +- .../Bridge/Api/Bridge_Api_AbstractTest.php | 2 +- tests/classes/Bridge/Bridge_ApiTest.php | 95 - tests/classes/Bridge/Bridge_datas.inc | 10 +- .../Permalink/media_Permalink_AdapterTest.php | 6 +- www/include/jslibs/jquery-1.7.1.js | 9266 ----------------- www/skins/html5/Boilerplate/css/style.css | 293 - .../Boilerplate/js/modernizr-2.5.2.min.js | 4 - .../bootstrap/css/bootstrap-responsive.css | 808 -- .../css/bootstrap-responsive.min.css | 9 - www/skins/html5/bootstrap/css/bootstrap.css | 4960 --------- .../html5/bootstrap/css/bootstrap.min.css | 9 - .../img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes .../bootstrap/img/glyphicons-halflings.png | Bin 13826 -> 0 bytes www/skins/html5/bootstrap/js/bootstrap.js | 1824 ---- www/skins/html5/bootstrap/js/bootstrap.min.js | 6 - 230 files changed, 1360 insertions(+), 18277 deletions(-) rename lib/Alchemy/Phrasea/{Application => Controller}/Lightbox.php (92%) delete mode 100644 www/include/jslibs/jquery-1.7.1.js delete mode 100644 www/skins/html5/Boilerplate/css/style.css delete mode 100644 www/skins/html5/Boilerplate/js/modernizr-2.5.2.min.js delete mode 100644 www/skins/html5/bootstrap/css/bootstrap-responsive.css delete mode 100644 www/skins/html5/bootstrap/css/bootstrap-responsive.min.css delete mode 100644 www/skins/html5/bootstrap/css/bootstrap.css delete mode 100644 www/skins/html5/bootstrap/css/bootstrap.min.css delete mode 100644 www/skins/html5/bootstrap/img/glyphicons-halflings-white.png delete mode 100644 www/skins/html5/bootstrap/img/glyphicons-halflings.png delete mode 100644 www/skins/html5/bootstrap/js/bootstrap.js delete mode 100644 www/skins/html5/bootstrap/js/bootstrap.min.js diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index f05df5d72a..070a467cd8 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -11,7 +11,7 @@ namespace Alchemy\Phrasea; -use Alchemy\Phrasea\Application\Lightbox; +use Alchemy\Phrasea\Controller\Lightbox; use Alchemy\Phrasea\Controller\Datafiles; use Alchemy\Phrasea\Controller\Permalink; use Alchemy\Phrasea\Controller\Admin\Collection; @@ -135,6 +135,7 @@ use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Form\FormFactory; use Symfony\Component\Form\FormTypeInterface; @@ -280,6 +281,7 @@ class Application extends SilexApplication $this->setupTwig(); $this->register(new UnoconvServiceProvider()); $this->register(new UrlGeneratorServiceProvider()); + $this->setupUrlGenerator(); $this->register(new UnicodeServiceProvider()); $this->register(new ValidatorServiceProvider()); @@ -390,6 +392,10 @@ class Application extends SilexApplication $this->register(new LocaleServiceProvider()); + $this->mount('/include/minify/', new Minifier()); + $this->mount('/permalink/', new Permalink()); + $this->mount('/lightbox/', new Lightbox()); + call_user_func(function ($app) { require $app['plugins.directory'] . '/services.php'; }, $this); @@ -428,7 +434,20 @@ class Application extends SilexApplication } /** - * Generates an absolute URL from the given parameters. + * Returns a redirect response with a relative path related to a route name. + * + * @param string $route The name of the route + * @param mixed $parameters An array of parameters + * + * @return RedirectResponse + */ + public function redirectPath($route, $parameters = array()) + { + return $this->redirect($this->path($route, $parameters)); + } + + /** + * Returns an absolute URL from the given parameters. * * @param string $route The name of the route * @param mixed $parameters An array of parameters @@ -440,6 +459,19 @@ class Application extends SilexApplication return $this['url_generator']->generate($route, $parameters, UrlGenerator::ABSOLUTE_URL); } + /** + * Returns a redirect response with a fully qualified URI related to a route name. + * + * @param string $route The name of the route + * @param mixed $parameters An array of parameters + * + * @return RedirectResponse + */ + public function redirectUrl($route, $parameters = array()) + { + return $this->redirect($this->url($route, $parameters)); + } + public function initSession(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { @@ -491,6 +523,22 @@ class Application extends SilexApplication $event->setResponse($response); } + private function setupUrlGenerator() + { + $this['url_generator'] = $this->share($this->extend('url_generator', function($urlGenerator, $app) { + $data = parse_url($app['phraseanet.configuration']['main']['servername']); + + if (isset($data['scheme'])) { + $urlGenerator->getContext()->setScheme($data['scheme']); + } + if (isset($data['host'])) { + $urlGenerator->getContext()->setHost($data['host']); + } + + return $urlGenerator; + })); + } + public function setupTwig() { $this['twig'] = $this->share( @@ -654,12 +702,8 @@ class Application extends SilexApplication $this->mount('/account/', new Account()); $this->mount('/login/', new Login()); $this->mount('/developers/', new Developers()); - $this->mount('/lightbox/', new Lightbox()); $this->mount('/datafiles/', new Datafiles()); - $this->mount('/permalink/', new Permalink()); - - $this->mount('/include/minify/', new Minifier()); $this->mount('/admin/', new AdminRoot()); $this->mount('/admin/dashboard', new Dashboard()); diff --git a/lib/Alchemy/Phrasea/Application/Root.php b/lib/Alchemy/Phrasea/Application/Root.php index b5f5bd7a3a..b8c482eff6 100644 --- a/lib/Alchemy/Phrasea/Application/Root.php +++ b/lib/Alchemy/Phrasea/Application/Root.php @@ -24,7 +24,7 @@ return call_user_func(function($environment = null) { $app->before(function (Request $request) use ($app) { if (0 === strpos($request->getPathInfo(), '/setup')) { if (!$app['phraseanet.configuration-tester']->isBlank()) { - return $app->redirect($app->path('homepage')); + return $app->redirectPath('homepage'); } } else { $app['firewall']->requireSetup(); diff --git a/lib/Alchemy/Phrasea/CLI.php b/lib/Alchemy/Phrasea/CLI.php index aa3f0b5e9f..dd9edb294a 100644 --- a/lib/Alchemy/Phrasea/CLI.php +++ b/lib/Alchemy/Phrasea/CLI.php @@ -46,15 +46,6 @@ class CLI extends Application }); $this->bindRoutes(); - - $data = parse_url($this['phraseanet.registry']->get('GV_ServerName')); - - if (isset($data['scheme'])) { - $this['url_generator']->getContext()->setScheme($data['scheme']); - } - if (isset($data['host'])) { - $this['url_generator']->getContext()->setHost($data['host']); - } } /** diff --git a/lib/Alchemy/Phrasea/Command/Setup/LessCompile.php b/lib/Alchemy/Phrasea/Command/Setup/LessCompile.php index eb4da63bd7..138c41902c 100644 --- a/lib/Alchemy/Phrasea/Command/Setup/LessCompile.php +++ b/lib/Alchemy/Phrasea/Command/Setup/LessCompile.php @@ -34,8 +34,10 @@ class LessCompile extends Command protected function doExecute(InputInterface $input, OutputInterface $output) { $files = array( - __DIR__ . '/../../../../../www/skins/build/login.css' => realpath(__DIR__ . '/../../../../../www/skins/login/less/login.less'), - __DIR__ . '/../../../../../www/skins/build/account.css' => realpath(__DIR__ . '/../../../../../www/skins/account/account.less'), + $this->container['root.path'] . '/www/skins/build/login.css' => realpath($this->container['root.path'] . '/www/skins/login/less/login.less'), + $this->container['root.path'] . '/www/skins/build/account.css' => realpath($this->container['root.path'] . '/www/skins/account/account.less'), + $this->container['root.path'] . '/www/skins/build/bootstrap.css' => realpath($this->container['root.path'] . '/www/assets/bootstrap/less/bootstrap.less'), + $this->container['root.path'] . '/www/skins/build/bootstrap-responsive.css' => realpath($this->container['root.path'] . '/www/assets/bootstrap/less/responsive.less'), ); $output->writeln('Building Assets...'); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php b/lib/Alchemy/Phrasea/Controller/Admin/Collection.php index 8a2ec82d81..fb32a98427 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Collection.php @@ -469,7 +469,10 @@ class Collection implements ControllerProviderInterface } } - return $app->redirect('/admin/collection/' . $bas_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => (int) $success, + )); } /** @@ -510,7 +513,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + )); } /** @@ -542,7 +548,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + )); } /** @@ -574,7 +583,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + )); } /** @@ -606,7 +618,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + )); } /** @@ -639,7 +654,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + )); } /** @@ -657,11 +675,19 @@ class Collection implements ControllerProviderInterface } if ($file->getClientSize() > 1024 * 1024) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-too-big'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + )); } if (!$file->isValid()) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-invalid'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + )); } $collection = \collection::get_from_base_id($app, $bas_id); @@ -671,10 +697,17 @@ class Collection implements ControllerProviderInterface $app['filesystem']->remove($file->getPathname()); } catch (\Exception $e) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-error'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + )); } - return $app->redirect('/admin/collection/' . $bas_id . '/?success=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 1, + )); } /** @@ -692,11 +725,19 @@ class Collection implements ControllerProviderInterface } if ($file->getClientSize() > 1024 * 1024) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-too-big'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + )); } if (!$file->isValid()) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-invalid'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + )); } $collection = \collection::get_from_base_id($app, $bas_id); @@ -706,10 +747,17 @@ class Collection implements ControllerProviderInterface $app['filesystem']->remove($file->getPathname()); } catch (\Exception $e) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-error'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + )); } - return $app->redirect('/admin/collection/' . $bas_id . '/?success=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 1, + )); } /** @@ -727,11 +775,19 @@ class Collection implements ControllerProviderInterface } if ($file->getClientSize() > 65535) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-too-big'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + )); } if (!$file->isValid()) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-invalid'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + )); } $collection = \collection::get_from_base_id($app, $bas_id); @@ -740,10 +796,17 @@ class Collection implements ControllerProviderInterface $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, $file, \collection::PIC_WM); $app['filesystem']->remove($file->getPathname()); } catch (\Exception $e) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-error'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + )); } - return $app->redirect('/admin/collection/' . $bas_id . '/?success=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 1, + )); } /** @@ -761,11 +824,19 @@ class Collection implements ControllerProviderInterface } if ($file->getClientSize() > 65535) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-too-big'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + )); } if (!$file->isValid()) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-invalid'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + )); } $collection = \collection::get_from_base_id($app, $bas_id); @@ -774,10 +845,17 @@ class Collection implements ControllerProviderInterface $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, $file, \collection::PIC_LOGO); $app['filesystem']->remove($file->getPathname()); } catch (\Exception $e) { - return $app->redirect('/admin/collection/' . $bas_id . '/?success=0&error=file-error'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + )); } - return $app->redirect('/admin/collection/' . $bas_id . '/?success=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $bas_id, + 'success' => 1, + )); } /** @@ -816,14 +894,25 @@ class Collection implements ControllerProviderInterface } if ($collection->get_record_amount() > 0) { - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=0&error=collection-not-empty'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => 0, + 'error' => 'collection-not-empty', + )); } if ($success) { - return $app->redirect('/admin/databox/' . $collection->get_sbas_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1, + )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=0'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => 0, + )); } /** @@ -854,7 +943,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + )); } /** @@ -889,7 +981,11 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success . '&reload-tree=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + 'reload-tree' => 1, + )); } public function labels(Application $app, Request $request, $bas_id) @@ -923,7 +1019,11 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success . '&reload-tree=1'); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + 'reload-tree' => 1, + )); } /** @@ -958,7 +1058,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + )); } /** @@ -989,7 +1092,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + )); } /** @@ -1020,7 +1126,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=' . (int) $success); + return $app->redirectPath('admin_display_collection', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + )); } /** @@ -1117,7 +1226,10 @@ class Collection implements ControllerProviderInterface )); } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/suggested-values/?success=' . (int) $success); + return $app->redirectPath('admin_collection_display_suggested_values', array( + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + )); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php index 70d8324663..19bf730716 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php @@ -26,7 +26,8 @@ class ConnectedUsers implements ControllerProviderInterface $app['firewall']->requireAccessToModule('Admin'); }); - $controllers->get('/', $this->call('listConnectedUsers')); + $controllers->get('/', $this->call('listConnectedUsers')) + ->bind('admin_connected_users'); return $controllers; } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php b/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php index 64409fec4f..00c3afcf81 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php @@ -155,10 +155,10 @@ class Dashboard implements ControllerProviderInterface public function flush(Application $app, Request $request) { if ($app['phraseanet.cache-service']->flushAll()) { - return $app->redirect('/admin/dashboard/?flush_cache=ok'); + return $app->redirectPath('admin_dashbord', array('flush_cache' => 'ok')); } - return $app->redirect('/admin/dashboard/?flush_cache=ko'); + return $app->redirectPath('admin_dashbord', array('flush_cache' => 'ko')); } /** @@ -181,7 +181,7 @@ class Dashboard implements ControllerProviderInterface try { $receiver = new Receiver(null, $mail); } catch (InvalidArgumentException $e) { - return $app->redirect('/admin/dashboard/?email=not-sent'); + return $app->redirectPath('admin_dashbord', array('email' => 'not-sent')); } $mail = MailTest::create($app, $receiver); @@ -189,7 +189,7 @@ class Dashboard implements ControllerProviderInterface $app['notification.deliverer']->deliver($mail); $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); - return $app->redirect('/admin/dashboard/?email=sent'); + return $app->redirectPath('admin_dashbord', array('email' => 'sent')); } /** @@ -203,7 +203,7 @@ class Dashboard implements ControllerProviderInterface { \User_Adapter::reset_sys_admins_rights($app); - return $app->redirect('/admin/dashboard/'); + return $app->redirectPath('admin_dashbord'); } /** @@ -227,7 +227,7 @@ class Dashboard implements ControllerProviderInterface } } - return $app->redirect('/admin/dashboard/'); + return $app->redirectPath('admin_dashbord'); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php b/lib/Alchemy/Phrasea/Controller/Admin/Databox.php index 9c37ab1d9b..fe10e81c2f 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Databox.php @@ -162,7 +162,8 @@ class Databox implements ControllerProviderInterface ->assert('databox_id', '\d+') ->before(function(Request $request) use ($app) { $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_submit_collection'); + }) + ->bind('admin_database_submit_collection'); /** * Get database CGU @@ -481,7 +482,16 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox->get_sbas_id() . '/?success=' . (int) $success . ($databox->get_record_amount() > 0 ? '&error=databox-not-empty' : '')); + $params = array( + 'databox_id' => $databox->get_sbas_id(), + 'success' => (int) $success, + ); + + if ($databox->get_record_amount() > 0) { + $params['error'] = 'databox-not-empty'; + } + + return $app->redirectPath('admin_database', $params); } /** @@ -511,7 +521,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => (int) $success, + )); } /** @@ -541,7 +554,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => (int) $success, + )); } /** @@ -561,10 +577,16 @@ class Databox implements ControllerProviderInterface $databox->update_cgus($loc, $terms, !!$request->request->get('valid', false)); } } catch (\Exception $e) { - return $app->redirect('/admin/databox/' . $databox_id . '/cgus/?success=0'); + return $app->redirectPath('admin_database_display_cgus', array( + 'databox_id' => $databox_id, + 'success' => 0, + )); } - return $app->redirect('/admin/databox/' . $databox_id . '/cgus/?success=1'); + return $app->redirectPath('admin_database_display_cgus', array( + 'databox_id' => $databox_id, + 'success' => 1, + )); } /** @@ -601,11 +623,17 @@ class Databox implements ControllerProviderInterface $app['phraseanet.appbox']->get_connection()->commit(); - return $app->redirect('/admin/databox/' . $databox_id . '/?mount=ok'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'mount' => 'ok', + )); } catch (\Exception $e) { $app['phraseanet.appbox']->get_connection()->rollBack(); - return $app->redirect('/admin/databox/' . $databox_id . '/?mount=ko'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'mount' => 'ko', + )); } } @@ -627,15 +655,30 @@ class Databox implements ControllerProviderInterface $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, $file, \databox::PIC_PDF); unlink($file->getPathname()); - return $app->redirect('/admin/databox/' . $databox_id . '/?success=1'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => '1', + )); } else { - return $app->redirect('/admin/databox/' . $databox_id . '/?success=0&error=file-too-big'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-too-big', + )); } } else { - return $app->redirect('/admin/databox/' . $databox_id . '/?success=0&error=file-invalid'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-invalid', + )); } } catch (\Exception $e) { - return $app->redirect('/admin/databox/' . $databox_id . '/??success=0&error=file-error'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-error', + )); } } @@ -666,7 +709,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + )); } /** @@ -696,7 +742,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + )); } /** @@ -730,7 +779,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + )); } /** @@ -762,7 +814,11 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success . '&reload-tree=1'); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + 'reload-tree' => 1, + )); } /** @@ -805,7 +861,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/?success=' . (int) $success); + return $app->redirectPath('admin_database', array( + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + )); } /** @@ -907,7 +966,10 @@ class Databox implements ControllerProviderInterface )); } - return $app->redirect('/admin/databox/' . $databox_id . '/collections/order?success=' . (int) $success); + return $app->redirectPath('admin_database_display_collections_order', array( + 'databox_id' => $databox_id, + 'success' => (int) $success, + )); } /** @@ -934,7 +996,10 @@ class Databox implements ControllerProviderInterface public function createCollection(Application $app, Request $request, $databox_id) { if (($name = trim($request->request->get('name', ''))) === '') { - return $app->redirect('/admin/databox/' . $databox_id . '/collection/error=name'); + return $app->redirectPath('admin_database_display_new_collection_form', array( + 'databox_id' => $databox_id, + 'error' => 'name', + )); } try { @@ -955,9 +1020,9 @@ class Databox implements ControllerProviderInterface } } - return $app->redirect('/admin/collection/' . $collection->get_base_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_display_collection', array('bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1)); } catch (\Exception $e) { - return $app->redirect('/admin/databox/' . $databox_id . '/collection/error=error'); + return $app->redirectPath('admin_database_submit_collection', array('databox_id' => $databox_id, 'error' => 'error')); } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php b/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php index 4372031916..84fe353eb4 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php @@ -200,11 +200,11 @@ class Databoxes implements ControllerProviderInterface public function createDatabase(Application $app, Request $request) { if ('' === $dbName = $request->request->get('new_dbname', '')) { - return $app->redirect('/admin/databoxes/?error=no-empty'); + return $app->redirectPath('admin_databases', array('error' => 'no-empty')); } if (\p4string::hasAccent($dbName)) { - return $app->redirect('/admin/databoxes/?error=special-chars'); + return $app->redirectPath('admin_databases', array('error' => 'special-chars')); } if ((null === $request->request->get('new_settings')) && (null !== $dataTemplate = $request->request->get('new_data_template'))) { @@ -222,7 +222,7 @@ class Databoxes implements ControllerProviderInterface try { $connbas = new \connection_pdo('databox_creation', $hostname, $port, $user, $password, $dbName, array(), $app['debug']); } catch (\PDOException $e) { - return $app->redirect('/admin/databoxes/?success=0&error=database-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'database-failed')); } try { @@ -230,9 +230,9 @@ class Databoxes implements ControllerProviderInterface $base->registerAdmin($app['authentication']->getUser()); $app['authentication']->getUser()->ACL()->delete_data_from_cache(); - return $app->redirect('/admin/databox/' . $base->get_sbas_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_database', array('databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1)); } catch (\Exception $e) { - return $app->redirect('/admin/databoxes/?success=0&error=base-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'base-failed')); } } @@ -251,12 +251,12 @@ class Databoxes implements ControllerProviderInterface $base = \databox::create($app, $connbas, $data_template, $app['phraseanet.registry']); $base->registerAdmin($app['authentication']->getUser()); - return $app->redirect('/admin/databox/' . $base->get_sbas_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_database', array('databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1)); } catch (\Exception $e) { - return $app->redirect('/admin/databoxes/?success=0&error=base-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'base-failed')); } } catch (\Exception $e) { - return $app->redirect('/admin/databoxes/?success=0&error=database-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'database-failed')); } } } @@ -271,11 +271,11 @@ class Databoxes implements ControllerProviderInterface public function databaseMount(Application $app, Request $request) { if ('' === $dbName = trim($request->request->get('new_dbname', ''))) { - return $app->redirect('/admin/databoxes/?success=0&error=no-empty'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'no-empty')); } if (\p4string::hasAccent($dbName)) { - return $app->redirect('/admin/databoxes/?success=0&error=special-chars'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'special-chars')); } if ((null === $request->request->get('new_settings'))) { @@ -293,11 +293,11 @@ class Databoxes implements ControllerProviderInterface $base->registerAdmin($app['authentication']->getUser()); $app['phraseanet.appbox']->get_connection()->commit(); - return $app->redirect('/admin/databox/' . $base->get_sbas_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_database', array('databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1)); } catch (\Exception $e) { $app['phraseanet.appbox']->get_connection()->rollBack(); - return $app->redirect('/admin/databoxes/?success=0&error=mount-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'mount-failed')); } } @@ -314,11 +314,11 @@ class Databoxes implements ControllerProviderInterface $base->registerAdmin($app['authentication']->getUser()); $app['phraseanet.appbox']->get_connection()->commit(); - return $app->redirect('/admin/databox/' . $base->get_sbas_id() . '/?success=1&reload-tree=1'); + return $app->redirectPath('admin_database', array('databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1)); } catch (\Exception $e) { $app['phraseanet.appbox']->get_connection()->rollBack(); - return $app->redirect('/admin/databoxes/?success=0&error=mount-failed'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'mount-failed')); } } } @@ -333,20 +333,20 @@ class Databoxes implements ControllerProviderInterface public function databasesUpgrade(Application $app, Request $request) { if (\phrasea::is_scheduler_started($app)) { - return $app->redirect('/admin/databoxes/?success=0&error=scheduler-started'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'scheduler-started')); } try { $upgrader = new \Setup_Upgrade($app); $advices = $app['phraseanet.appbox']->forceUpgrade($upgrader, $app); - return $app->redirect('/admin/databoxes/?success=1¬ice=restart&' . http_build_query(array('advices' => $advices))); + return $app->redirectPath('admin_databases', array('success' => 1, 'notice' => 'restart', 'advices' => $advices)); } catch (\Exception_Setup_UpgradeAlreadyStarted $e) { - return $app->redirect('/admin/databoxes/?success=0&error=already-started'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'already-started')); } catch (\Exception_Setup_FixBadEmailAddresses $e) { - return $app->redirect('/admin/databoxes/?success=0&error=bad-email'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'bad-email')); } catch (\Exception $e) { - return $app->redirect('/admin/databoxes/?success=0&error=unknow'); + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'unknow')); } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php index 0df6fc6207..20e77170a4 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Publications.php @@ -41,7 +41,7 @@ class Publications implements ControllerProviderInterface return $app['twig'] ->render('admin/publications/list.html.twig', array('feeds' => $feeds)); - }); + })->bind('admin_feeds_list'); $controllers->post('/create/', function(PhraseaApplication $app, Request $request) { @@ -55,15 +55,17 @@ class Publications implements ControllerProviderInterface $feed->set_collection(\collection::get_from_base_id($app, $request->request->get('base_id'))); } - return $app->redirect('/admin/publications/list/'); - }); + 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); return $app['twig'] ->render('admin/publications/fiche.html.twig', array('feed' => $feed, 'error' => $app['request']->query->get('error'))); - })->assert('id', '\d+'); + }) + ->bind('admin_feeds_feed') + ->assert('id', '\d+'); $controllers->post('/feed/{id}/update/', function(PhraseaApplication $app, Request $request, $id) { @@ -80,14 +82,16 @@ class Publications implements ControllerProviderInterface $feed->set_collection($collection); $feed->set_public($request->request->get('public')); - return $app->redirect('/admin/publications/list/'); + return $app->redirectPath('admin_feeds_list'); })->before(function(Request $request) use ($app) { $feed = new \Feed_Adapter($app, $request->attributes->get('id')); if (!$feed->is_owner($app['authentication']->getUser())) { - return $app->redirect('/admin/publications/feed/' . $request->attributes->get('id') . '/?error=' . _('You are not the owner of this feed, you can not edit it')); + 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'))); } - })->assert('id', '\d+'); + }) + ->bind('admin_feeds_feed_update') + ->assert('id', '\d+'); $controllers->post('/feed/{id}/iconupload/', function(PhraseaApplication $app, Request $request, $id) { $datas = array( @@ -156,7 +160,9 @@ class Publications implements ControllerProviderInterface } return $app->json($datas); - })->assert('id', '\d+'); + }) + ->bind('admin_feeds_feed_icon') + ->assert('id', '\d+'); $controllers->post('/feed/{id}/addpublisher/', function(PhraseaApplication $app, $id) { $error = ''; @@ -169,8 +175,10 @@ class Publications implements ControllerProviderInterface $error = $e->getMessage(); } - return $app->redirect('/admin/publications/feed/' . $id . '/?err=' . $error); - })->assert('id', '\d+'); + return $app->redirectPath('admin_feeds_feed', array('id' => $id, 'error' => $error)); + }) + ->bind('admin_feeds_feed_add_publisher') + ->assert('id', '\d+'); $controllers->post('/feed/{id}/removepublisher/', function(PhraseaApplication $app, $id) { try { @@ -185,15 +193,19 @@ class Publications implements ControllerProviderInterface $error = $e->getMessage(); } - return $app->redirect('/admin/publications/feed/' . $id . '/?err=' . $error); - })->assert('id', '\d+'); + return $app->redirectPath('admin_feeds_feed', array('id' => $id, 'error' => $error)); + }) + ->bind('admin_feeds_feed_remove_publisher') + ->assert('id', '\d+'); $controllers->post('/feed/{id}/delete/', function(PhraseaApplication $app, $id) { $feed = new \Feed_Adapter($app, $id); $feed->delete(); - return $app->redirect('/admin/publications/list/'); - })->assert('id', '\d+'); + return $app->redirectPath('admin_feeds_list'); + }) + ->bind('admin_feeds_feed_delete') + ->assert('id', '\d+'); return $controllers; } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Root.php b/lib/Alchemy/Phrasea/Controller/Admin/Root.php index 4563c201f3..45c2acd2c7 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Root.php @@ -36,7 +36,7 @@ class Root implements ControllerProviderInterface try { \User_Adapter::updateClientInfos($app, 3); } catch (SessionNotFound $e) { - return $app->redirect($app['url_generator']->generate('logout')); + return $app->redirectPath('logout'); } $section = $request->query->get('section', false); @@ -104,7 +104,7 @@ class Root implements ControllerProviderInterface try { \User_Adapter::updateClientInfos($app, 3); } catch (SessionNotFound $e) { - return $app->redirect($app['url_generator']->generate('logout')); + return $app->redirectPath('logout'); } $section = $request->query->get('section', false); @@ -191,7 +191,8 @@ class Root implements ControllerProviderInterface } return $app->json(array('results' => $result)); - }); + }) + ->bind('admin_test_paths'); $controllers->get('/structure/{databox_id}/', function(Application $app, Request $request, $databox_id) { if (!$app['authentication']->getUser()->ACL()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { @@ -239,9 +240,9 @@ class Root implements ControllerProviderInterface $databox = $app['phraseanet.appbox']->get_databox($databox_id); $databox->saveStructure($domst); - return $app->redirect('/admin/structure/' . $databox_id . '/?success=1'); + return $app->redirectPath('database_display_stucture', array('sbas_id' => $databox_id, 'success' => 1)); } else { - return $app->redirect('/admin/structure/' . $databox_id . '/?success=0&error=struct'); + return $app->redirectPath('database_display_stucture', array('sbas_id' => $databox_id, 'success' => 0, 'error' => 'struct')); } })->assert('databox_id', '\d+') ->bind('database_submit_stucture'); @@ -310,7 +311,10 @@ class Root implements ControllerProviderInterface } return $app->json(array('success' => !$error)); - })->assert('databox_id', '\d+')->assert('bit', '\d+'); + }) + ->bind('admin_statusbit_delete') + ->assert('databox_id', '\d+') + ->assert('bit', '\d+'); $controllers->post('/statusbit/{databox_id}/status/{bit}/', function(Application $app, Request $request, $databox_id, $bit) { if (!$app['authentication']->getUser()->ACL()->has_right_on_sbas($databox_id, 'bas_modify_struct')) { @@ -335,17 +339,41 @@ class Root implements ControllerProviderInterface try { \databox_status::updateIcon($app, $databox_id, $bit, 'off', $file); } catch (\Exception_Forbidden $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=rights'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'rights', + )); } catch (\Exception_InvalidArgument $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=unknow-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'unknow-error', + )); } catch (\Exception_Upload_FileTooBig $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=too-big'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'too-big', + )); } catch (\Exception_Upload_Error $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=upload-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'upload-error', + )); } catch (\Exception_Upload_CannotWriteFile $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=wright-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'wright-error', + )); } catch (\Exception $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=unknow-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'unknow-error', + )); } } @@ -357,21 +385,45 @@ class Root implements ControllerProviderInterface try { \databox_status::updateIcon($app, $databox_id, $bit, 'on', $file); } catch (\Exception_Forbidden $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=rights'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'rights', + )); } catch (\Exception_InvalidArgument $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=unknow-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'unknow-error', + )); } catch (\Exception_Upload_FileTooBig $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=too-big'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'too-big', + )); } catch (\Exception_Upload_Error $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=upload-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'upload-error', + )); } catch (\Exception_Upload_CannotWriteFile $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=wright-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'wright-error', + )); } catch (\Exception $e) { - return $app->redirect('/admin/statusbit/' . $databox_id . '/status/' . $bit . '/?error=unknow-error'); + return $app->redirectPath('database_display_statusbit_form', array( + 'databox_id' => $databox_id, + 'bit' => $bit, + 'error' => 'unknow-error', + )); } } - return $app->redirect('/admin/statusbit/' . $databox_id . '/?success=1'); + return $app->redirectPath('database_display_stucture', array('sbas_id' => $databox_id, 'success' => 1)); })->assert('databox_id', '\d+') ->assert('bit', '\d+') ->bind('database_submit_statusbit'); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Setup.php b/lib/Alchemy/Phrasea/Controller/Admin/Setup.php index ace489dbc6..d13174956e 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Setup.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Setup.php @@ -110,14 +110,14 @@ class Setup implements ControllerProviderInterface public function postGlobals(Application $app, Request $request) { if (\setup::create_global_values($app, $request->request->all())) { - return $app->redirect($app['url_generator']->generate('setup_display_globals', array( + return $app->redirectPath('setup_display_globals', array( 'success' => 1 - ))); + )); } - return $app->redirect($app['url_generator']->generate('setup_display_globals', array( + return $app->redirectPath('setup_display_globals', array( 'success' => 0 - ))); + )); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php b/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php index cd1518abda..95f7cd0157 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php @@ -40,7 +40,9 @@ class Subdefs implements ControllerProviderInterface 'databox' => $databox, 'subdefs' => $databox->get_subdef_structure() )); - })->assert('sbas_id', '\d+'); + }) + ->bind('admin_subdefs_subdef') + ->assert('sbas_id', '\d+'); $controllers->post('/{sbas_id}/', function(Application $app, Request $request, $sbas_id) { $delete_subdef = $request->request->get('delete_subdef'); @@ -117,8 +119,10 @@ class Subdefs implements ControllerProviderInterface } } - return $app->redirect('/admin/subdefs/' . $databox->get_sbas_id() . '/'); - })->assert('sbas_id', '\d+'); + return $app->redirectPath('admin_subdefs_subdef', array('sbas_id' => $databox->get_sbas_id())); + }) + ->bind('admin_subdefs_subdef_update') + ->assert('sbas_id', '\d+'); return $controllers; } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php b/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php index 5993dbedaf..e7aaf0553f 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php @@ -29,15 +29,9 @@ class TaskManager implements ControllerProviderInterface }); $controllers->get('/', function(Application $app, Request $request) { - return $app->redirect('/admin/task-manager/tasks/'); - }); + return $app->redirectPath('admin_tasks_list'); + })->bind('admin_tasks'); - /* - * route /admin/task-manager/tasks/ - * tasks status in json - * or - * task manager page in html - */ $controllers->get('/tasks/', function(Application $app, Request $request) { if ($request->getContentType() == 'json') { @@ -51,23 +45,20 @@ class TaskManager implements ControllerProviderInterface 'scheduler_key' => \phrasea::scheduler_key($app) )); } - }); + })->bind('admin_tasks_list'); - /** - * route /admin/task-manager/tasks/create - */ $controllers->post('/tasks/create/', function(Application $app, Request $request) { - $task = \task_abstract::create($app, $request->request->get('tcl')); $tid = $task->getId(); - return $app->redirect('/admin/task-manager/task/' . $tid); - }); + return $app->redirectPath('admin_tasks_task_show', array('id' => $tid)); + })->bind('admin_tasks_task_create'); /* * route /admin/taskmanager/scheduler/start */ - $controllers->get('/scheduler/start', $this->call('startScheduler')); + $controllers->get('/scheduler/start', $this->call('startScheduler')) + ->bind('admin_tasks_scheduler_start'); /* * route /admin/scheduler/stop @@ -82,7 +73,7 @@ class TaskManager implements ControllerProviderInterface } return $app->json(false); - }); + })->bind('admin_tasks_scheduler_stop'); $controllers->get('/scheduler/log', function(Application $app, Request $request) { $logdir = \p4string::addEndSlash($app['phraseanet.registry']->get('GV_RootPath') . 'logs'); @@ -103,14 +94,13 @@ class TaskManager implements ControllerProviderInterface } } if ($found) { - return $app->redirect("/admin/task-manager/scheduler/log"); + return $app->redirectPath('admin_tasks_scheduler_log'); } return $app->stream(function() use ($finder) { foreach ($finder->getIterator() as $file) { printf("

%s\n", $file->getRealPath()); - printf(" %s" - , urlencode($file->getFilename()) + printf(" path('admin_tasks_scheduler_log', array('clr' => $file->getFilename()))."\">%s" , _('Clear') ); print("

\n
\n");
@@ -121,7 +111,7 @@ class TaskManager implements ControllerProviderInterface
                     flush();
                 }
             }, 200, array('Content-Type' => 'text/html'));
-        });
+        })->bind('admin_tasks_scheduler_log');
 
         $controllers->get('/task/{id}/log', function(Application $app, Request $request, $id) {
             $logdir = \p4string::addEndSlash($app['phraseanet.registry']->get('GV_RootPath') . 'logs');
@@ -142,7 +132,7 @@ class TaskManager implements ControllerProviderInterface
                 }
             }
             if ($found) {
-                return $app->redirect(sprintf("/admin/task-manager/task/%s/log", urlencode($id)));
+                return $app->redirectPath('admin_tasks_task_log', array('id' => $id));
             }
 
             return $app->stream(function() use ($finder, $id) {
@@ -161,33 +151,24 @@ class TaskManager implements ControllerProviderInterface
                     flush();
                 }
             });
-        });
+        })->bind('admin_tasks_task_log');
 
-        /*
-         * route /admin/task-manager/task/{id}/delete
-         *  delete a task
-         */
         $controllers->get('/task/{id}/delete', function(Application $app, Request $request, $id) {
 
             try {
                 $task = $app['task-manager']->getTask($id);
                 $task->delete();
 
-                return $app->redirect('/admin/task-manager/tasks/');
+                return $app->redirectPath('admin_tasks_list');
             } catch (\Exception $e) {
 
-                /*
+                /**
                  * todo : add a message back
                  */
-
-                return $app->redirect('/admin/task-manager/tasks/');
+                return $app->redirectPath('admin_tasks_list');
             }
-        });
+        })->bind('admin_tasks_task_delete');
 
-        /*
-         * route /admin/task-manager/task/{id}/start
-         *  set a task to 'tostart'
-         */
         $controllers->get('/task/{id}/tostart', function(Application $app, Request $request, $id) {
 
             $ret = false;
@@ -203,12 +184,8 @@ class TaskManager implements ControllerProviderInterface
             }
 
             return $app->json($ret);
-        });
+        })->bind('admin_tasks_task_start');
 
-        /*
-         * route /admin/task-manager/task/{id}/stop
-         *  set a task to 'tostop'
-         */
         $controllers->get('/task/{id}/tostop', function(Application $app, Request $request, $id) {
 
             $ret = false;
@@ -228,12 +205,8 @@ class TaskManager implements ControllerProviderInterface
             }
 
             return $app->json($ret);
-        });
+        })->bind('admin_tasks_task_stop');
 
-        /*
-         * route /admin/task-manager/task/{id}/resetcrashcounter
-         * return json
-         */
         $controllers->get('/task/{id}/resetcrashcounter/', function(Application $app, Request $request, $id) {
 
             try {
@@ -245,7 +218,7 @@ class TaskManager implements ControllerProviderInterface
             } catch (\Exception $e) {
                 return $app->json(false);
             }
-        });
+        })->bind('admin_tasks_task_reset');
 
         /*
          * route /admin/task-manager/task/{id}/save
@@ -280,7 +253,7 @@ class TaskManager implements ControllerProviderInterface
                         404    // Not Found
                 );
             }
-        });
+        })->bind('admin_tasks_task_save');
 
         /*
          * route /admin/task-manager/task/{id}/facility/
@@ -324,12 +297,8 @@ class TaskManager implements ControllerProviderInterface
             }
 
             return $ret;
-        });
+        })->bind('admin_tasks_task_facility');
 
-        /*
-         * route /admin/task-manager/task/{id}
-         *  render a task editing interface
-         */
         $controllers->get('/task/{id}', function(Application $app, Request $request, $id) {
 
             $task = $app['task-manager']->getTask($id);
@@ -340,7 +309,7 @@ class TaskManager implements ControllerProviderInterface
                     'task' => $task,
                     'view' => 'XML'
                 ));
-        });
+        })->bind('admin_tasks_task_show');
 
         /*
          * route /admin/task/checkxml/
diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php
index 893d2e66d4..43b9319c46 100644
--- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php
+++ b/lib/Alchemy/Phrasea/Controller/Admin/Users.php
@@ -58,13 +58,13 @@ class Users implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        });
+        })->bind('admin_users_rights_reset');
 
         $controllers->post('/delete/', function(Application $app) {
             $module = new UserHelper\Edit($app, $app['request']);
             $module->delete_users();
 
-            return $app->redirect('/admin/users/search/');
+            return $app->redirectPath('admin_users_search');
         });
 
         $controllers->post('/rights/apply/', function(Application $app) {
@@ -86,7 +86,7 @@ class Users implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        });
+        })->bind('admin_users_rights_apply');
 
         $controllers->post('/rights/quotas/', function(Application $app) {
             $rights = new UserHelper\Edit($app, $app['request']);
@@ -131,7 +131,7 @@ class Users implements ControllerProviderInterface
             $users = new UserHelper\Manage($app, $app['request']);
 
             return $app['twig']->render('admin/users.html.twig', $users->search());
-        });
+        })->bind('admin_users_search');
 
         $controllers->post('/search/export/', function() use ($app) {
             $request = $app['request'];
@@ -187,15 +187,15 @@ class Users implements ControllerProviderInterface
             $response->headers->set('Content-Disposition', 'attachment; filename=export.csv');
 
             return $response;
-        });
+        })->bind('admin_users_search_export');
 
         $controllers->post('/apply_template/', function() use ($app) {
             $users = new UserHelper\Edit($app, $app['request']);
 
             $users->apply_template();
 
-            return $app->redirect('/admin/users/search/');
-        });
+            return $app->redirectPath('admin_users_search');
+        })->bind('admin_users_apply_template');
 
         $controllers->get('/typeahead/search/', function(Application $app) {
             $request = $app['request'];
@@ -331,7 +331,7 @@ class Users implements ControllerProviderInterface
             $response->setCharset('UTF-8');
 
             return $response;
-        });
+        })->bind('admin_users_export_csv');
 
         $controllers->get('/demands/', function(Application $app, Request $request) {
 
@@ -562,7 +562,7 @@ class Users implements ControllerProviderInterface
                 }
             }
 
-            return $app->redirect('/admin/users/demands/?success=1');
+            return $app->redirectPath('users_display_demands', array('success' => 1));
         })->bind('users_submit_demands');
 
         $controllers->get('/import/file/', function(Application $app, Request $request) {
@@ -572,7 +572,7 @@ class Users implements ControllerProviderInterface
         $controllers->post('/import/file/', function(Application $app, Request $request) {
 
             if ((null === $file = $request->files->get('files')) || !$file->isValid()) {
-                return $app->redirect('/admin/users/import/file/?error=file-invalid');
+                return $app->redirectPath('users_display_import_file', array('error' => 'file-invalid'));
             }
 
             $array = \format::csv_to_arr($file->getPathname());
@@ -600,11 +600,11 @@ class Users implements ControllerProviderInterface
             }
 
             if (!$loginDefined) {
-                return $app->redirect('/admin/users/import/file/?error=row-login');
+                return $app->redirectPath('users_display_import_file', array('error' => 'row-login'));
             }
 
             if (!$pwdDefined) {
-                return $app->redirect('/admin/users/import/file/?error=row-pwd');
+                return $app->redirectPath('users_display_import_file', array('error' => 'row-pwd'));
             }
 
             $nbLines = sizeof($array);
@@ -665,7 +665,7 @@ class Users implements ControllerProviderInterface
                         'errors' => $out['errors']
                     ));
             } elseif ($nbUsrToAdd === 0) {
-                return $app->redirect('/admin/users/import/file/?error=no-user');
+                return $app->redirectPath('users_display_import_file', array('error' => 'no-user'));
             } else {
                 for ($i = 1; $i < sizeof($array); $i++) {
                     for ($j = 0; $j < sizeof($array[0]); $j++) { {
@@ -821,7 +821,7 @@ class Users implements ControllerProviderInterface
                 }
             }
 
-            return $app->redirect('/admin/users/search/?user-updated=' . $nbCreation);
+            return $app->redirectPath('admin_users_search', array('user-updated' => $nbCreation));
         })->bind('users_submit_import');
 
         $controllers->get('/import/example/csv/', function(Application $app, Request $request) {
diff --git a/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php b/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php
index a561987c46..4f2d913a2b 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php
@@ -81,12 +81,12 @@ class Oauth2 implements ControllerProviderInterface
                         if (null === $usr_id) {
                             $app['session']->getFlashBag()->set('error', _('login::erreur: Erreur d\'authentification'));
 
-                            return $app->redirect($app->path('oauth2_authorize'));
+                            return $app->redirectPath('oauth2_authorize');
                         }
                     } catch (RequireCaptchaException $e) {
-                        return $app->redirect($app->path('oauth2_authorize'), array('error' => 'captcha'));
+                        return $app->redirectPath('oauth2_authorize', array('error' => 'captcha'));
                     } catch (AccountLockedException $e) {
-                        return $app->redirect($app->path('oauth2_authorize'), array('error' => 'account-locked'));
+                        return $app->redirectPath('oauth2_authorize', array('error' => 'account-locked'));
                     }
 
                     $app['authentication']->openAccount(\User_Adapter::getInstance($usr_id, $app));
diff --git a/lib/Alchemy/Phrasea/Controller/Client/Baskets.php b/lib/Alchemy/Phrasea/Controller/Client/Baskets.php
index aab2efdf1d..0621669926 100644
--- a/lib/Alchemy/Phrasea/Controller/Client/Baskets.php
+++ b/lib/Alchemy/Phrasea/Controller/Client/Baskets.php
@@ -147,9 +147,9 @@ class Baskets implements ControllerProviderInterface
 
         }
 
-        return $app->redirect($app['url_generator']->generate('get_client_baskets', array(
+        return $app->redirectPath('get_client_baskets', array(
             'courChuId' => $request->request->get('courChuId', '')
-        )));
+        ));
     }
 
     /**
@@ -173,7 +173,7 @@ class Baskets implements ControllerProviderInterface
 
         }
 
-        return $app->redirect($app['url_generator']->generate('get_client_baskets'));
+        return $app->redirectPath('get_client_baskets');
     }
 
     /**
@@ -199,9 +199,9 @@ class Baskets implements ControllerProviderInterface
 
         }
 
-        return $app->redirect($app['url_generator']->generate('get_client_baskets', array(
+        return $app->redirectPath('get_client_baskets', array(
             'courChuId' => null !== $basket ? $basket->getId() : ''
-        )));
+        ));
     }
 
     /**
@@ -234,9 +234,9 @@ class Baskets implements ControllerProviderInterface
             }
         }
 
-        return $app->redirect($app['url_generator']->generate('get_client_baskets', array(
+        return $app->redirectPath('get_client_baskets', array(
             'courChuId' => $basket ? $basket->getId() : ''
-        )));
+        ));
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php
index 010c157eaf..a155d72804 100644
--- a/lib/Alchemy/Phrasea/Controller/Client/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php
@@ -29,9 +29,7 @@ class Root implements ControllerProviderInterface
 
         $controllers->before(function(Request $request) use ($app) {
             if (!$app['authentication']->isAuthenticated() && null !== $request->query->get('nolog')) {
-                return $app->redirect(
-                    $app->path('login_authenticate_as_guest', array('redirect' => '/prod/'))
-                );
+                return $app->redirectPath('login_authenticate_as_guest', array('redirect' => 'client'));
             }
             $app['firewall']->requireAuthentication();
         });
@@ -294,7 +292,7 @@ class Root implements ControllerProviderInterface
         try {
             \User_Adapter::updateClientInfos($app, 2);
         } catch (SessionNotFound $e) {
-            return $app->redirect($app['url_generator']->generate('logout'));
+            return $app->redirectPath('logout');
         }
         $renderTopics = '';
 
diff --git a/lib/Alchemy/Phrasea/Controller/Datafiles.php b/lib/Alchemy/Phrasea/Controller/Datafiles.php
index b965cce502..3e2690224c 100644
--- a/lib/Alchemy/Phrasea/Controller/Datafiles.php
+++ b/lib/Alchemy/Phrasea/Controller/Datafiles.php
@@ -100,7 +100,10 @@ class Datafiles extends AbstractDelivery
             }
 
             return $that->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('datafile')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Application/Lightbox.php b/lib/Alchemy/Phrasea/Controller/Lightbox.php
similarity index 92%
rename from lib/Alchemy/Phrasea/Application/Lightbox.php
rename to lib/Alchemy/Phrasea/Controller/Lightbox.php
index 6fbf3fdc59..d7cd0d97bb 100644
--- a/lib/Alchemy/Phrasea/Application/Lightbox.php
+++ b/lib/Alchemy/Phrasea/Controller/Lightbox.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Alchemy\Phrasea\Application;
+namespace Alchemy\Phrasea\Controller;
 
 use Alchemy\Phrasea\Exception\SessionNotFound;
 use Alchemy\Phrasea\Controller\Exception as ControllerException;
@@ -36,7 +36,7 @@ class Lightbox implements ControllerProviderInterface
             if (false === $usr_id = $app['authentication.token-validator']->isValid($request->query->get('LOG'))) {
                 $app->addFlash('error', _('The URL you used is out of date, please login'));
 
-                return $app->redirect($app->path('homepage'));
+                return $app->redirectPath('homepage');
             }
 
             $app['authentication']->openAccount(\User_Adapter::getInstance($usr_id, $app));
@@ -48,11 +48,11 @@ class Lightbox implements ControllerProviderInterface
             }
             switch ($datas['type']) {
                 case \random::TYPE_FEED_ENTRY:
-                    return $app->redirect("/lightbox/feeds/entry/" . $datas['datas'] . "/");
+                    return $app->redirectPath('lightbox_feed_entry', array('entry_id' => $datas['datas']));
                     break;
                 case \random::TYPE_VALIDATE:
                 case \random::TYPE_VIEW:
-                    return $app->redirect("/lightbox/validate/" . $datas['datas'] . "/");
+                    return $app->redirectPath('lightbox_validation', array('ssel_id' => $datas['datas']));
                     break;
             }
         });
@@ -65,7 +65,7 @@ class Lightbox implements ControllerProviderInterface
             try {
                 \User_Adapter::updateClientInfos($app, 6);
             } catch (SessionNotFound $e) {
-                return $app->redirect($app['url_generator']->generate('logout'));
+                return $app->redirectPath('logout');
             }
 
             $repository = $app['EM']->getRepository('\Entities\Basket');
@@ -88,7 +88,8 @@ class Lightbox implements ControllerProviderInterface
                     'module'             => 'lightbox'
                     )
             ));
-        });
+        })
+            ->bind('lightbox');
 
         $controllers->get('/ajax/NOTE_FORM/{sselcont_id}/', function(SilexApplication $app, $sselcont_id) {
 
@@ -106,7 +107,9 @@ class Lightbox implements ControllerProviderInterface
             );
 
             return $app['twig']->render('lightbox/note_form.html.twig', $parameters);
-        })->assert('sselcont_id', '\d+');
+        })
+            ->bind('lightbox_ajax_note_form')
+            ->assert('sselcont_id', '\d+');
 
         $controllers->get('/ajax/LOAD_BASKET_ELEMENT/{sselcont_id}/', function(SilexApplication $app, $sselcont_id) {
             /* @var $repository \Repositories\BasketElementRepository */
@@ -150,7 +153,9 @@ class Lightbox implements ControllerProviderInterface
 
                 return $app->json($ret);
             }
-        })->assert('sselcont_id', '\d+');
+        })
+            ->bind('lightbox_ajax_load_basketelement')
+            ->assert('sselcont_id', '\d+');
 
         $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function(SilexApplication $app, $entry_id, $item_id) {
 
@@ -186,14 +191,17 @@ class Lightbox implements ControllerProviderInterface
 
                 return $app->json($ret);
             }
-        })->assert('entry_id', '\d+')->assert('item_id', '\d+');
+        })
+            ->bind('lightbox_ajax_load_feeditem')
+            ->assert('entry_id', '\d+')
+            ->assert('item_id', '\d+');
 
         $controllers->get('/validate/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
 
             try {
                 \User_Adapter::updateClientInfos($app, 6);
             } catch (SessionNotFound $e) {
-                return $app->redirect($app['url_generator']->generate('logout'));
+                return $app->redirectPath('logout');
             }
 
             $repository = $app['EM']->getRepository('\Entities\Basket');
@@ -238,14 +246,16 @@ class Lightbox implements ControllerProviderInterface
             $response->setCharset('UTF-8');
 
             return $response;
-        })->assert('ssel_id', '\d+');
+        })
+            ->bind('lightbox_validation')
+            ->assert('ssel_id', '\d+');
 
         $controllers->get('/compare/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
 
             try {
                 \User_Adapter::updateClientInfos($app, 6);
             } catch (SessionNotFound $e) {
-                return $app->redirect($app['url_generator']->generate('logout'));
+                return $app->redirectPath('logout');
             }
 
             $repository = $app['EM']->getRepository('\Entities\Basket');
@@ -291,15 +301,15 @@ class Lightbox implements ControllerProviderInterface
 
             return $response;
         })
-        ->assert('ssel_id', '\d+')
-        ->bind('lightbox_compare')    ;
+            ->bind('lightbox_compare')
+            ->assert('ssel_id', '\d+');
 
         $controllers->get('/feeds/entry/{entry_id}/', function (SilexApplication $app, $entry_id) {
 
             try {
                 \User_Adapter::updateClientInfos($app, 6);
             } catch (SessionNotFound $e) {
-                return $app->redirect($app['url_generator']->generate('logout'));
+                return $app->redirectPath('logout');
             }
 
             $feed_entry = \Feed_Entry_Adapter::load_from_id($app, $entry_id);
@@ -324,7 +334,9 @@ class Lightbox implements ControllerProviderInterface
             $response->setCharset('UTF-8');
 
             return $response;
-        })->assert('entry_id', '\d+');
+        })
+            ->bind('lightbox_feed_entry')
+            ->assert('entry_id', '\d+');
 
         $controllers->get('/ajax/LOAD_REPORT/{ssel_id}/', function(SilexApplication $app, $ssel_id) {
 
@@ -343,7 +355,9 @@ class Lightbox implements ControllerProviderInterface
             $response->setCharset('UTF-8');
 
             return $response;
-        })->assert('ssel_id', '\d+');
+        })
+            ->bind('lightbox_ajax_report')
+            ->assert('ssel_id', '\d+');
 
         $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) {
             $output = array('error' => true, 'datas' => _('Erreur lors de l\'enregistrement des donnees'));
@@ -381,7 +395,9 @@ class Lightbox implements ControllerProviderInterface
             }
 
             return $app->json($output);
-        })->assert('sselcont_id', '\d+');
+        })
+            ->bind('lightbox_ajax_set_note')
+            ->assert('sselcont_id', '\d+');
 
         $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', function(SilexApplication $app, $sselcont_id) {
             $request = $app['request'];
@@ -442,7 +458,9 @@ class Lightbox implements ControllerProviderInterface
             }
 
             return $app->json($ret);
-        })->assert('sselcont_id', '\d+');
+        })
+            ->bind('lightbox_ajax_set_element_agreement')
+            ->assert('sselcont_id', '\d+');
 
         $controllers->post('/ajax/SET_RELEASE/{ssel_id}/', function(SilexApplication $app, $ssel_id) {
 
@@ -482,13 +500,12 @@ class Lightbox implements ControllerProviderInterface
                 $participant = $basket->getValidation()->getParticipant($app['authentication']->getUser(), $app);
 
                 $expires = new \DateTime('+10 days');
-                $url = $app['phraseanet.registry']->get('GV_ServerName')
-                    . 'lightbox/index.php?LOG=' . $app['tokens']->getUrlToken(
+                $url = $app->url('lightbox', array('LOG' => $app['tokens']->getUrlToken(
                         \random::TYPE_VALIDATE
                         , $basket->getValidation()->getInitiator($app)->get_id()
                         , $expires
                         , $basket->getId()
-                );
+                )));
 
                 $to = $basket->getValidation()->getInitiator($app)->get_id();
                 $params = array(
@@ -511,7 +528,9 @@ class Lightbox implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        })->assert('ssel_id', '\d+');
+        })
+            ->bind('lightbox_ajax_set_release')
+            ->assert('ssel_id', '\d+');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Permalink.php b/lib/Alchemy/Phrasea/Controller/Permalink.php
index 491827bf61..8779a2d2ed 100644
--- a/lib/Alchemy/Phrasea/Controller/Permalink.php
+++ b/lib/Alchemy/Phrasea/Controller/Permalink.php
@@ -78,7 +78,7 @@ class Permalink extends AbstractDelivery
                 }
                 $response = $that->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app);
 
-                $linkToCaption = $app->path("view_caption", array('sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token));
+                $linkToCaption = $app->path("permalinks_caption", array('sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token));
                 $response->headers->set('Link', $linkToCaption);
 
                 return $response;
@@ -100,7 +100,7 @@ class Permalink extends AbstractDelivery
 
             $response = $that->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app);
 
-            $linkToCaption = $app->path("view_caption", array('sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token));
+            $linkToCaption = $app->path("permalinks_caption", array('sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token));
             $response->headers->set('Link', $linkToCaption);
 
             return $response;
@@ -119,28 +119,40 @@ class Permalink extends AbstractDelivery
 
             return new Response($caption->serialize(\caption_record::SERIALIZE_JSON), 200, array("Content-Type" => 'application/json'));
         })
-        ->assert('sbas_id', '\d+')->assert('record_id', '\d+')
-        ->bind('view_caption');
+            ->assert('sbas_id', '\d+')->assert('record_id', '\d+')
+            ->bind('permalinks_caption');
 
         $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/', function (PhraseaApplication $app, Request $request, $sbas_id, $record_id, $subdef) use ($deliverPermaview) {
             $token = $request->query->get('token');
 
             return $deliverPermaview($sbas_id, $record_id, $token, $subdef, $app);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('permalinks_permaview')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         $controllers->get('/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/view/', function(PhraseaApplication $app, $label, $sbas_id, $record_id, $token, $subdef) use ($deliverPermaview) {
             return $deliverPermaview($sbas_id, $record_id, $token, $subdef, $app);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('permalinks_permaview_old')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/{label}', function (PhraseaApplication $app, Request $request, $sbas_id, $record_id, $subdef, $label) use ($deliverPermalink) {
             $token = $request->query->get('token');
 
             return $deliverPermalink($app, $sbas_id, $record_id, $token, $subdef);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('permalinks_permalink')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         $controllers->get('/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/', function(PhraseaApplication $app, $label, $sbas_id, $record_id, $token, $subdef) use ($deliverPermalink) {
             return $deliverPermalink($app, $sbas_id, $record_id, $token, $subdef);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('permalinks_permalink_old')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Basket.php b/lib/Alchemy/Phrasea/Controller/Prod/Basket.php
index b823d76361..389c37fd1e 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Basket.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Basket.php
@@ -39,6 +39,7 @@ class Basket implements ControllerProviderInterface
          * Get a basket
          */
         $controllers->get('/{basket_id}/', $this->call('displayBasket'))
+            ->bind('prod_baskets_basket')
             ->assert('basket_id', '\d+');
 
         /**
@@ -51,7 +52,8 @@ class Basket implements ControllerProviderInterface
          * @accept JSON / YAML
          *
          */
-        $controllers->post('/', $this->call('createBasket'));
+        $controllers->post('/', $this->call('createBasket'))
+            ->bind('prod_baskets');
 
         /**
          * This route is used to delete a basket
@@ -67,6 +69,7 @@ class Basket implements ControllerProviderInterface
          * Removes a BasketElement
          */
         $controllers->post('/{basket_id}/delete/{basket_element_id}/', $this->call('removeBasketElement'))
+            ->bind('prod_baskets_basket_element_remove')
             ->assert('basket_id', '\d+')
             ->assert('basket_element_id', '\d+');
 
@@ -78,6 +81,7 @@ class Basket implements ControllerProviderInterface
          *
          */
         $controllers->post('/{basket_id}/update/', $this->call('updateBasket'))
+            ->bind('prod_baskets_basket_update')
             ->assert('basket_id', '\d+');
 
         /**
@@ -90,7 +94,8 @@ class Basket implements ControllerProviderInterface
          * Get the Basket reorder form
          */
         $controllers->get('/{basket_id}/reorder/', $this->call('displayReorderForm'))
-            ->assert('basket_id', '\d+');
+            ->assert('basket_id', '\d+')
+            ->bind('prod_baskets_basket_reorder');
 
         $controllers->post('/{basket_id}/reorder/', $this->call('reorder'))
             ->assert('basket_id', '\d+');
@@ -103,6 +108,7 @@ class Basket implements ControllerProviderInterface
          * @returns JSON / HTML
          */
         $controllers->post('/{basket_id}/archive/', $this->call('archiveBasket'))
+            ->bind('prod_baskets_basket_archive')
             ->assert('basket_id', '\d+');
 
         /**
@@ -124,7 +130,7 @@ class Basket implements ControllerProviderInterface
         /**
          * Get basket creation form
          */
-        $controllers->get('/create/', $this->call('displayCreateForm'));
+        $controllers->get('/create/', $this->call('displayCreateForm'))->bind('prod_baskets_create');
 
         return $controllers;
     }
@@ -200,7 +206,7 @@ class Basket implements ControllerProviderInterface
 
             return $app->json($data);
         } else {
-            return $app->redirect(sprintf('/%d/', $Basket->getId()));
+            return $app->redirectPath('prod_baskets_basket', array('basket_id' => $Basket->getId()));
         }
     }
 
@@ -220,7 +226,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
@@ -246,7 +252,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
@@ -283,7 +289,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
@@ -359,7 +365,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
@@ -410,7 +416,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
@@ -444,7 +450,7 @@ class Basket implements ControllerProviderInterface
         if ($request->getRequestFormat() == 'json') {
             return $app->json($data);
         } else {
-            return $app->redirect('/');
+            return $app->redirectPath('prod_workzone_show');
         }
     }
 
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php b/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php
index 23db120943..86aa32c332 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php
@@ -62,10 +62,10 @@ class Bridge implements ControllerProviderInterface
         });
 
         $controllers->get('/login/{api_name}/', function(Application $app, $api_name) {
-            $connector = \Bridge_Api::get_connector_by_name($app['phraseanet.registry'], $api_name);
+            $connector = \Bridge_Api::get_connector_by_name($app, $api_name);
 
             return $app->redirect($connector->get_auth_url());
-        });
+        })->bind('prod_bridge_login');
 
         $controllers->get('/callback/{api_name}/', function(Application $app, $api_name) {
             $error_message = '';
@@ -99,15 +99,20 @@ class Bridge implements ControllerProviderInterface
             $params = array('error_message' => $error_message);
 
             return $app['twig']->render('prod/actions/Bridge/callback.html.twig', $params);
-        });
+        })->bind('prod_bridge_callback');
 
         $controllers->get('/adapter/{account_id}/logout/', function(Application $app, $account_id) {
             $account = \Bridge_Account::load_account($app, $account_id);
             $app['require_connection']($account);
             $account->get_api()->get_connector()->disconnect();
 
-            return $app->redirect('/prod/bridge/adapter/' . $account_id . '/load-elements/' . $account->get_api()->get_connector()->get_default_element_type() . '/');
-        })->assert('account_id', '\d+');
+            return $app->redirectPath('bridge_load_elements', array(
+                'account_id' => $account_id,
+                'type'       => $account->get_api()->get_connector()->get_default_element_type(),
+            ));
+        })
+            ->bind('prod_bridge_account_logout')
+            ->assert('account_id', '\d+');
 
         $controllers->post('/adapter/{account_id}/delete/'
             , function($account_id) use ($app) {
@@ -149,7 +154,9 @@ class Bridge implements ControllerProviderInterface
             );
 
             return $app['twig']->render('prod/actions/Bridge/records_list.html.twig', $params);
-        })->assert('account_id', '\d+');
+        })
+            ->bind('prod_bridge_account_loadrecords')
+            ->assert('account_id', '\d+');
 
         $controllers->get('/adapter/{account_id}/load-elements/{type}/', function($account_id, $type) use ($app) {
             $page = max((int) $app['request']->query->get('page'), 0);
@@ -171,7 +178,9 @@ class Bridge implements ControllerProviderInterface
             );
 
             return $app['twig']->render('prod/actions/Bridge/element_list.html.twig', $params);
-        })->assert('account_id', '\d+');
+        })
+            ->bind('bridge_load_elements')
+            ->assert('account_id', '\d+');
 
         $controllers->get('/adapter/{account_id}/load-containers/{type}/', function(Application $app, $account_id, $type) {
 
@@ -193,7 +202,9 @@ class Bridge implements ControllerProviderInterface
             );
 
             return $app['twig']->render('prod/actions/Bridge/element_list.html.twig', $params);
-        })->assert('account_id', '\d+');
+        })
+            ->bind('prod_bridge_account_loadcontainers')
+            ->assert('account_id', '\d+');
 
         $controllers->get('/action/{account_id}/{action}/{element_type}/', function(Application $app, $account_id, $action, $element_type) {
 
@@ -214,7 +225,12 @@ class Bridge implements ControllerProviderInterface
 
                 case 'modify':
                     if (count($elements) != 1) {
-                        return $app->redirect('/prod/bridge/adapter/' . $account_id . '/load-elements/' . $element_type . '/?page=&error=' . _('Vous ne pouvez pas editer plusieurs elements simultanement'));
+                        return $app->redirectPath('bridge_load_elements', array(
+                            'account_id' => $account_id,
+                            'type'       => $element_type,
+                            'page'       => '',
+                            'error'      => _('Vous ne pouvez pas editer plusieurs elements simultanement'),
+                        ));
                     }
                     foreach ($elements as $element_id) {
                         if ($class === \Bridge_Api_Interface::OBJECT_CLASS_ELEMENT) {
@@ -257,7 +273,9 @@ class Bridge implements ControllerProviderInterface
             $template = 'prod/actions/Bridge/' . $account->get_api()->get_connector()->get_name() . '/' . $element_type . '_' . $action . ($destination ? '_' . $destination : '') . '.html.twig';
 
             return $app['twig']->render($template, $params);
-        })->assert('account_id', '\d+');
+        })
+            ->bind('bridge_account_action')
+            ->assert('account_id', '\d+');
 
         $controllers->post('/action/{account_id}/{action}/{element_type}/', function(Application $app, $account_id, $action, $element_type) {
             $account = \Bridge_Account::load_account($app, $account_id);
@@ -357,7 +375,9 @@ class Bridge implements ControllerProviderInterface
             }
 
             return new Response($html);
-        })->assert('account_id', '\d+');
+        })
+            ->bind('bridge_account_do_action')
+            ->assert('account_id', '\d+');
 
         $controllers->get('/upload/', function(Application $app) {
             $request = $app['request'];
@@ -378,9 +398,9 @@ class Bridge implements ControllerProviderInterface
             );
 
             return $app['twig']->render(
-                        'prod/actions/Bridge/' . $account->get_api()->get_connector()->get_name() . '/upload.html.twig', $params
-                );
-        });
+                'prod/actions/Bridge/' . $account->get_api()->get_connector()->get_name() . '/upload.html.twig', $params
+            );
+        })->bind('prod_bridge_upload');
 
         $controllers->post('/upload/', function(Application $app) {
             $errors = array();
@@ -422,7 +442,7 @@ class Bridge implements ControllerProviderInterface
             }
 
             return $app->redirect('/prod/bridge/adapter/' . $account->get_id() . '/load-records/?notice=' . sprintf(_('%d elements en attente'), count($route->get_elements())));
-        });
+        })->bind('prod_bridge_do_upload');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Download.php b/lib/Alchemy/Phrasea/Controller/Prod/Download.php
index 71dc1a1ae4..4fe68cf0ac 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Download.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Download.php
@@ -97,9 +97,7 @@ class Download implements ControllerProviderInterface
             'export_file' => $download->getExportName()
         ));
 
-        return $app->redirect($app['url_generator']->generate(
-            'prepare_download', array('token' => $token)
-        ));
+        return $app->redirectPath('prepare_download', array('token' => $token));
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Export.php b/lib/Alchemy/Phrasea/Controller/Prod/Export.php
index e599da3a8a..088c064c6e 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Export.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Export.php
@@ -280,7 +280,7 @@ class Export implements ControllerProviderInterface
 
             $remaingEmails = $destMails;
 
-            $url = $app['phraseanet.registry']->get('GV_ServerName') . 'download/' . $token . '/prepare/?anonymous';
+            $url = $app->url('prepare_download', array('token' => $token, 'anonymous'));
 
             $emitter = new Emitter($app['authentication']->getUser()->get_display_name(), $app['authentication']->getUser()->get_email());
 
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php
index 0ba93ab10e..7cce1ae8b5 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Feed.php
@@ -69,9 +69,11 @@ class Feed implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        })->before(function(Request $request) use ($app) {
-            $app['firewall']->requireRight('bas_chupub');
-        });
+        })
+            ->bind('prod_feeds_entry_create')
+            ->before(function(Request $request) use ($app) {
+                $app['firewall']->requireRight('bas_chupub');
+            });
 
         $controllers->get('/entry/{id}/edit/', function(Application $app, Request $request, $id) {
             $entry = \Feed_Entry_Adapter::load_from_id($app, $id);
@@ -85,10 +87,12 @@ class Feed implements ControllerProviderInterface
             $datas = $app['twig']->render('prod/actions/publish/publish_edit.html.twig', array('entry' => $entry, 'feeds' => $feeds));
 
             return new Response($datas);
-        })->assert('id', '\d+')
-          ->before(function(Request $request) use ($app) {
-            $app['firewall']->requireRight('bas_chupub');
-        });
+        })
+            ->bind('prod_feeds_feed_edit')
+            ->assert('id', '\d+')
+            ->before(function(Request $request) use ($app) {
+                $app['firewall']->requireRight('bas_chupub');
+            });
 
         $controllers->post('/entry/{id}/update/', function(Application $app, Request $request, $id) {
             $datas = array('error'   => true, 'message' => '', 'datas'   => '');
@@ -159,9 +163,11 @@ class Feed implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        })->assert('id', '\d+')->before(function(Request $request) use ($app) {
-            $app['firewall']->requireRight('bas_chupub');
-        });
+        })
+            ->bind('prod_feeds_entry_update')
+            ->assert('id', '\d+')->before(function(Request $request) use ($app) {
+                $app['firewall']->requireRight('bas_chupub');
+            });
 
         $controllers->post('/entry/{id}/delete/', function(Application $app, Request $request, $id) {
             $datas = array('error'   => true, 'message' => '');
@@ -188,9 +194,11 @@ class Feed implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        })->assert('id', '\d+')->before(function(Request $request) use ($app) {
-            $app['firewall']->requireRight('bas_chupub');
-        });
+        })
+            ->bind('prod_feeds_feed_delete')
+            ->assert('id', '\d+')->before(function(Request $request) use ($app) {
+                $app['firewall']->requireRight('bas_chupub');
+            });
 
         $controllers->get('/', function(Application $app, Request $request) {
             $request = $app['request'];
@@ -208,7 +216,7 @@ class Feed implements ControllerProviderInterface
             );
 
             return new Response($datas);
-        });
+        })->bind('prod_feeds');
 
         $controllers->get('/feed/{id}/', function(Application $app, Request $request, $id) {
             $page = (int) $request->query->get('page');
@@ -220,7 +228,9 @@ class Feed implements ControllerProviderInterface
             $datas = $app['twig']->render('prod/feeds/feeds.html.twig', array('feed'  => $feed, 'feeds' => $feeds, 'page'  => $page));
 
             return new Response($datas);
-        })->assert('id', '\d+');
+        })
+            ->bind('prod_feeds_feed')
+            ->assert('id', '\d+');
 
         $controllers->get('/subscribe/aggregated/', function(Application $app, Request $request) {
             $renew = ($request->query->get('renew') === 'true');
@@ -235,7 +245,7 @@ class Feed implements ControllerProviderInterface
             );
 
             return $app->json($output);
-        });
+        })->bind('prod_feeds_subscribe_aggregated');
 
         $controllers->get('/subscribe/{id}/', function(Application $app, Request $request, $id) {
             $renew = ($request->query->get('renew') === 'true');
@@ -249,7 +259,9 @@ class Feed implements ControllerProviderInterface
             );
 
             return $app->json($output);
-        })->assert('id', '\d+');
+        })
+            ->bind('prod_feeds_subscribe_feed')
+            ->assert('id', '\d+');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php
index 714e155bf9..3fcbf03fd7 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php
@@ -34,8 +34,8 @@ class MoveCollection implements ControllerProviderInterface
                 ->requireRight('deleterecord');
         });
 
-        $controllers->post('/', $this->call('displayForm'));
-        $controllers->post('/apply/', $this->call('apply'));
+        $controllers->post('/', $this->call('displayForm'))->bind('prod_move_collection');
+        $controllers->post('/apply/', $this->call('apply'))->bind('prod_move_collection_apply');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Order.php b/lib/Alchemy/Phrasea/Controller/Prod/Order.php
index 78bbe7072a..4771b3260e 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Order.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Order.php
@@ -209,10 +209,10 @@ class Order implements ControllerProviderInterface
             ));
         }
 
-        return $app->redirect($app['url_generator']->generate('prod_orders', array(
+        return $app->redirectPath('prod_orders', array(
             'success' => (int) $success,
             'action'  => 'send'
-        )));
+        ));
     }
 
     /**
@@ -299,10 +299,10 @@ class Order implements ControllerProviderInterface
             ));
         }
 
-        return $app->redirect($app['url_generator']->generate('prod_orders', array(
+        return $app->redirectPath('prod_orders', array(
             'success' => (int) $success,
             'action'  => 'send'
-        )));
+        ));
     }
 
     /**
@@ -338,10 +338,10 @@ class Order implements ControllerProviderInterface
             ));
         }
 
-        return $app->redirect($app['url_generator']->generate('prod_orders', array(
+        return $app->redirectPath('prod_orders', array(
             'success' => (int) $success,
             'action'  => 'send'
-        )));
+        ));
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Printer.php b/lib/Alchemy/Phrasea/Controller/Prod/Printer.php
index 4ca259d672..96930d2a43 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Printer.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Printer.php
@@ -54,7 +54,7 @@ class Printer implements ControllerProviderInterface
             $response->setMaxAge(0);
 
             return $response;
-        });
+        })->bind('prod_printer_print');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Push.php b/lib/Alchemy/Phrasea/Controller/Prod/Push.php
index 8cbd02ad61..540b0d5825 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Push.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Push.php
@@ -216,9 +216,12 @@ class Push implements ControllerProviderInterface
 
                     $app['EM']->flush();
 
-                    $url = $app['phraseanet.registry']->get('GV_ServerName')
-                        . 'lightbox/index.php?LOG='
-                        . $app['tokens']->getUrlToken(\random::TYPE_VALIDATE, $user_receiver->get_id(), null, $Basket->getId());
+                    $url = $app->url('lightbox', array('LOG' => $app['tokens']->getUrlToken(
+                        \random::TYPE_VALIDATE,
+                        $user_receiver->get_id(),
+                        null,
+                        $Basket->getId()
+                    )));
 
                     $receipt = $request->get('recept') ? $app['authentication']->getUser()->get_email() : '';
 
@@ -257,7 +260,7 @@ class Push implements ControllerProviderInterface
             }
 
             return $app->json($ret);
-        });
+        })->bind('prod_push_send');
 
         $controllers->post('/validate/', function(Application $app) {
             $request = $app['request'];
@@ -413,9 +416,12 @@ class Push implements ControllerProviderInterface
 
                     $app['EM']->flush();
 
-                    $url = $app['phraseanet.registry']->get('GV_ServerName')
-                        . 'lightbox/index.php?LOG='
-                        . $app['tokens']->getUrlToken(\random::TYPE_VIEW, $participant_user->get_id(), null, $Basket->getId());
+                    $url = $app->url('lightbox', array('LOG' => $app['tokens']->getUrlToken(
+                        \random::TYPE_VIEW,
+                        $participant_user->get_id(),
+                        null,
+                        $Basket->getId()
+                    )));
 
                     $receipt = $request->get('recept') ? $app['authentication']->getUser()->get_email() : '';
 
@@ -457,7 +463,7 @@ class Push implements ControllerProviderInterface
             }
 
             return $app->json($ret);
-        });
+        })->bind('prod_push_validate');
 
         $controllers->get('/user/{usr_id}/', function(Application $app, $usr_id) use ($userFormatter) {
             $datas = null;
@@ -495,7 +501,9 @@ class Push implements ControllerProviderInterface
             }
 
             return $app->json($datas);
-        })->assert('list_id', '\d+');
+        })
+            ->bind('prod_push_lists_list')
+            ->assert('list_id', '\d+');
 
         $controllers->post('/add-user/', function(Application $app, Request $request) use ($userFormatter) {
             $result = array('success' => false, 'message' => '', 'user'    => null);
@@ -560,13 +568,13 @@ class Push implements ControllerProviderInterface
             }
 
             return $app->json($result);
-        });
+        })->bind('prod_push_do_add_user');
 
         $controllers->get('/add-user/', function(Application $app, Request $request) {
             $params = array('callback' => $request->query->get('callback'));
 
             return $app['twig']->render('prod/User/Add.html.twig', $params);
-        });
+        })->bind('prod_push_add_user');
 
         $controllers->get('/search-user/', function(Application $app) use ($userFormatter, $listFormatter) {
             $request = $app['request'];
@@ -664,7 +672,9 @@ class Push implements ControllerProviderInterface
                         $app['twig']->render('prod/actions/Feedback/list.html.twig', $params)
                 );
             }
-        })->assert('list_id', '\d+');
+        })
+            ->bind('prod_push_list_edit')
+            ->assert('list_id', '\d+');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/Controller/Prod/Root.php
index 3cea296ca4..74027111f8 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Root.php
@@ -34,9 +34,7 @@ class Root implements ControllerProviderInterface
         $controllers->before(function(Request $request) use ($app) {
 
             if (!$app['authentication']->isAuthenticated() && null !== $request->query->get('nolog')) {
-                return $app->redirect(
-                    $app->path('login_authenticate_as_guest', array('redirect' => '/prod/'))
-                );
+                return $app->redirectPath('login_authenticate_as_guest');
             }
 
             $app['firewall']->requireAuthentication();
@@ -46,7 +44,7 @@ class Root implements ControllerProviderInterface
             try {
                 \User_Adapter::updateClientInfos($app, 1);
             } catch (SessionNotFound $e) {
-                return $app->redirect($app['url_generator']->generate('logout'));
+                return $app->redirectPath('logout');
             }
 
             $cssPath = $app['phraseanet.registry']->get('GV_RootPath') . 'www/skins/prod/';
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Story.php b/lib/Alchemy/Phrasea/Controller/Prod/Story.php
index 0995908b4e..be3de67a06 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Story.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Story.php
@@ -36,7 +36,7 @@ class Story implements ControllerProviderInterface
 
         $controllers->get('/create/', function(Application $app) {
             return $app['twig']->render('prod/Story/Create.html.twig', array());
-        });
+        })->bind('prod_stories_create');
 
         $controllers->post('/', function(Application $app, Request $request) {
             /* @var $request \Symfony\Component\HttpFoundation\Request */
@@ -99,9 +99,12 @@ class Story implements ControllerProviderInterface
 
                 return $app->json($data);
             } else {
-                return $app->redirect(sprintf('/%d/', $StoryWZ->getId()));
+                return $app->redirectPath('prod_stories_story', array(
+                    'sbas_id' => $StoryWZ->getSbasId(),
+                    'record_id' => $StoryWZ->getRecordId(),
+                ));
             }
-        });
+        })->bind('prod_stories_do_create');
 
         $controllers->get('/{sbas_id}/{record_id}/', function(Application $app, $sbas_id, $record_id) {
             $Story = new \record_adapter($app, $sbas_id, $record_id);
@@ -109,7 +112,10 @@ class Story implements ControllerProviderInterface
             $html = $app['twig']->render('prod/WorkZone/Story.html.twig', array('Story' => $Story));
 
             return new Response($html);
-        })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
+        })
+            ->bind('prod_stories_story')
+            ->assert('sbas_id', '\d+')
+            ->assert('record_id', '\d+');
 
         $controllers->post('/{sbas_id}/{record_id}/addElements/', function(Application $app, Request $request, $sbas_id, $record_id) {
             $Story = new \record_adapter($app, $sbas_id, $record_id);
@@ -138,7 +144,7 @@ class Story implements ControllerProviderInterface
             if ($request->getRequestFormat() == 'json') {
                 return $app->json($data);
             } else {
-                return $app->redirect('/');
+                return $app->redirectPath('prod_stories_story', array('sbas_id' => $sbas_id,'record_id' => $record_id));
             }
         })->assert('sbas_id', '\d+')->assert('record_id', '\d+');
 
@@ -160,9 +166,10 @@ class Story implements ControllerProviderInterface
             if ($request->getRequestFormat() == 'json') {
                 return $app->json($data);
             } else {
-                return $app->redirect('/');
+                return $app->redirectPath('prod_stories_story', array('sbas_id' => $sbas_id,'record_id' => $record_id));
             }
         })
+            ->bind('prod_stories_story_remove_element')
             ->assert('sbas_id', '\d+')
             ->assert('record_id', '\d+')
             ->assert('child_sbas_id', '\d+')
@@ -185,6 +192,7 @@ class Story implements ControllerProviderInterface
                     )
             );
         })
+            ->bind('prod_stories_story_reorder')
             ->assert('sbas_id', '\d+')
             ->assert('record_id', '\d+');
 
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
index d8a4430715..87b58e51d9 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php
@@ -87,7 +87,7 @@ class Tools implements ControllerProviderInterface
             }
 
             return $app->json($return);
-        });
+        })->bind('prod_tools_rotate');
 
         $controllers->post('/image/', function(Application $app, Request $request) {
             $return = array('success' => true);
@@ -110,7 +110,7 @@ class Tools implements ControllerProviderInterface
             }
 
             return $app->json($return);
-        });
+        })->bind('prod_tools_image');
 
         $controllers->post('/hddoc/', function(Application $app, Request $request) {
             $success = false;
@@ -165,7 +165,7 @@ class Tools implements ControllerProviderInterface
                 'success'   => $success,
                 'message'   => $message,
             ));
-        });
+        })->bind('prod_tools_hd_substitution');
 
         $controllers->post('/chgthumb/', function(Application $app, Request $request) {
             $success = false;
@@ -213,7 +213,7 @@ class Tools implements ControllerProviderInterface
                 'success'   => $success,
                 'message'   => $message,
             ));
-        });
+        })->bind('prod_tools_thumbnail_substitution');
 
         $controllers->post('/thumb-extractor/confirm-box/', function(Application $app, Request $request) {
             $return = array('error'   => false, 'datas'   => '');
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php b/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php
index b551434f55..bf39cdd29a 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php
@@ -33,38 +33,47 @@ class Tooltip implements ControllerProviderInterface
         });
 
         $controllers->post('/basket/{basket_id}/', $this->call('displayBasket'))
-            ->assert('basket_id', '\d+');
+            ->assert('basket_id', '\d+')
+            ->bind('prod_tooltip_basket');
 
         $controllers->post('/Story/{sbas_id}/{record_id}/', $this->call('displayStory'))
             ->assert('sbas_id', '\d+')
-            ->assert('record_id', '\d+');
+            ->assert('record_id', '\d+')
+            ->bind('prod_tooltip_story');
 
         $controllers->post('/user/{usr_id}/', $this->call('displayUserBadge'))
-            ->assert('usr_id', '\d+');
+            ->assert('usr_id', '\d+')
+            ->bind('prod_tooltip_user');
 
         $controllers->post('/preview/{sbas_id}/{record_id}/', $this->call('displayPreview'))
             ->assert('sbas_id', '\d+')
-            ->assert('record_id', '\d+');
+            ->assert('record_id', '\d+')
+            ->bind('prod_tooltip_preview');
 
         $controllers->post('/caption/{sbas_id}/{record_id}/{context}/', $this->call('displayCaption'))
             ->assert('sbas_id', '\d+')
-            ->assert('record_id', '\d+');
+            ->assert('record_id', '\d+')
+            ->bind('prod_tooltip_caption');
 
         $controllers->post('/tc_datas/{sbas_id}/{record_id}/', $this->call('displayTechnicalDatas'))
             ->assert('sbas_id', '\d+')
-            ->assert('record_id', '\d+');
+            ->assert('record_id', '\d+')
+            ->bind('prod_tooltip_technical_data');
 
         $controllers->post('/metas/FieldInfos/{sbas_id}/{field_id}/', $this->call('displayFieldInfos'))
             ->assert('sbas_id', '\d+')
-            ->assert('field_id', '\d+');
+            ->assert('field_id', '\d+')
+            ->bind('prod_tooltip_metadata');
 
         $controllers->post('/DCESInfos/{sbas_id}/{field_id}/', $this->call('displayDCESInfos'))
             ->assert('sbas_id', '\d+')
-            ->assert('field_id', '\d+');
+            ->assert('field_id', '\d+')
+            ->bind('prod_tooltip_dces');
 
         $controllers->post('/metas/restrictionsInfos/{sbas_id}/{field_id}/', $this->call('displayMetaRestrictions'))
             ->assert('sbas_id', '\d+')
-            ->assert('field_id', '\d+');
+            ->assert('field_id', '\d+')
+            ->bind('prod_tooltip_metadata_restrictions');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php b/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php
index 71a01ab33c..c543431ddd 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php
@@ -39,12 +39,12 @@ class UsrLists implements ControllerProviderInterface
         /**
          * Get all lists
          */
-        $controllers->get('/all/', $this->call('getAll'));
+        $controllers->get('/all/', $this->call('getAll'))->bind('prod_lists_all');
 
         /**
          * Creates a list
          */
-        $controllers->post('/list/', $this->call('createList'));
+        $controllers->post('/list/', $this->call('createList'))->bind('prod_lists_list');
 
         /**
          * Gets a list
@@ -56,6 +56,7 @@ class UsrLists implements ControllerProviderInterface
          * Update a list
          */
         $controllers->post('/list/{list_id}/update/', $this->call('updateList'))
+            ->bind('prod_lists_list_update')
             ->assert('list_id', '\d+');
 
         /**
@@ -78,7 +79,8 @@ class UsrLists implements ControllerProviderInterface
             ->assert('list_id', '\d+');
 
         $controllers->get('/list/{list_id}/share/', $this->call('displayShares'))
-            ->assert('list_id', '\d+');
+            ->assert('list_id', '\d+')
+            ->bind('prod_lists_list_share');
 
         /**
          * Share a list to a user with an optionnal role
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php b/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php
index 7f38e5cc65..19b658cfd4 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php
@@ -33,18 +33,23 @@ class WorkZone implements ControllerProviderInterface
             $app['firewall']->requireAuthentication();
         });
 
-        $controllers->get('/', $this->call('displayWorkzone'));
+        $controllers->get('/', $this->call('displayWorkzone'))
+            ->bind('prod_workzone_show');
 
-        $controllers->get('/Browse/', $this->call('browse'));
+        $controllers->get('/Browse/', $this->call('browse'))
+            ->bind('prod_workzone_browse');
 
-        $controllers->get('/Browse/Search/', $this->call('browserSearch'));
+        $controllers->get('/Browse/Search/', $this->call('browserSearch'))
+            ->bind('prod_workzone_search');
 
         $controllers->get('/Browse/Basket/{basket_id}/', $this->call('browseBasket'))
+            ->bind('prod_workzone_basket')
             ->assert('basket_id', '\d+');
 
         $controllers->post('/attachStories/', $this->call('attachStories'));
 
         $controllers->post('/detachStory/{sbas_id}/{record_id}/', $this->call('detachStory'))
+            ->bind('prod_workzone_detach_story')
             ->assert('sbas_id', '\d+')
             ->assert('record_id', '\d+');
 
@@ -187,7 +192,7 @@ class WorkZone implements ControllerProviderInterface
             ));
         }
 
-        return $app->redirect('/{sbas_id}/{record_id}/');
+        return $app->redirectPath('prod_workzone_show');
     }
 
     public function detachStory(Application $app, Request $request, $sbas_id, $record_id)
@@ -213,7 +218,7 @@ class WorkZone implements ControllerProviderInterface
             ));
         }
 
-        return $app->redirect('/');
+        return $app->redirectPath('prod_workzone_show');
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Controller/Report/Root.php b/lib/Alchemy/Phrasea/Controller/Report/Root.php
index 41f0b2fd54..8ebdd99b98 100644
--- a/lib/Alchemy/Phrasea/Controller/Report/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Report/Root.php
@@ -29,7 +29,7 @@ class Root implements ControllerProviderInterface
         });
 
         $controllers->get('/', function(Application $app) {
-            return $app->redirect($app->path('report_dashboard'));
+            return $app->redirectPath('report_dashboard');
         })->bind('report');
 
         $controllers->get('/dashboard', $this->call('getDashboard'))
diff --git a/lib/Alchemy/Phrasea/Controller/Root/Account.php b/lib/Alchemy/Phrasea/Controller/Root/Account.php
index a72b11e7de..cb23bee256 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/Account.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/Account.php
@@ -107,7 +107,7 @@ class Account implements ControllerProviderInterface
                     $user->set_password($passwordConfirm);
                     $app->addFlash('success', _('login::notification: Mise a jour du mot de passe avec succes'));
 
-                    return $app->redirect($app->path('account'));
+                    return $app->redirectPath('account');
                 } else {
                     $app->addFlash('error', _('Invalid password provided'));
                 }
@@ -139,31 +139,31 @@ class Account implements ControllerProviderInterface
         if (!$app['auth.password-encoder']->isPasswordValid($user->get_password(), $password, $user->get_nonce())) {
             $app->addFlash('error', _('admin::compte-utilisateur:ftp: Le mot de passe est errone'));
 
-            return $app->redirect($app->path('account_reset_email'));
+            return $app->redirectPath('account_reset_email');
         }
 
         if (!\Swift_Validate::email($email)) {
             $app->addFlash('error', _('forms::l\'email semble invalide'));
 
-            return $app->redirect($app->path('account_reset_email'));
+            return $app->redirectPath('account_reset_email');
         }
 
         if ($email !== $emailConfirm) {
             $app->addFlash('error', _('forms::les emails ne correspondent pas'));
 
-            return $app->redirect($app->path('account_reset_email'));
+            return $app->redirectPath('account_reset_email');
         }
 
         $date = new \DateTime('1 day');
         $token = $app['tokens']->getUrlToken(\random::TYPE_EMAIL, $app['authentication']->getUser()->get_id(), $date, $app['authentication']->getUser()->get_email());
-        $url = $app['phraseanet.registry']->get('GV_ServerName') . 'account/reset-email/?token=' . $token;
+        $url = $app->url('account_reset_email', array('token' => $token));
 
         try {
             $receiver = Receiver::fromUser($app['authentication']->getUser());
         } catch (InvalidArgumentException $e) {
             $app->addFlash('error', _('phraseanet::erreur: echec du serveur de mail'));
 
-            return $app->redirect($app->path('account_reset_email'));
+            return $app->redirectPath('account_reset_email');
         }
 
         $mail = MailRequestEmailUpdate::create($app, $receiver, null);
@@ -174,7 +174,7 @@ class Account implements ControllerProviderInterface
 
         $app->addFlash('info', _('admin::compte-utilisateur un email de confirmation vient de vous etre envoye. Veuillez suivre les instructions contenue pour continuer'));
 
-        return $app->redirect($app->path('account'));
+        return $app->redirectPath('account');
     }
 
     /**
@@ -195,11 +195,11 @@ class Account implements ControllerProviderInterface
 
                 $app->addFlash('success', _('admin::compte-utilisateur: L\'email a correctement ete mis a jour'));
 
-                return $app->redirect($app->path('account'));
+                return $app->redirectPath('account');
             } catch (\Exception $e) {
                 $app->addFlash('error', _('admin::compte-utilisateur: erreur lors de la mise a jour'));
 
-                return $app->redirect($app->path('account'));
+                return $app->redirectPath('account');
             }
         }
 
@@ -412,6 +412,6 @@ class Account implements ControllerProviderInterface
             }
         }
 
-        return $app->redirect($app->path('account'));
+        return $app->redirectPath('account');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Controller/Root/Developers.php b/lib/Alchemy/Phrasea/Controller/Root/Developers.php
index ce20f66438..ae15b62746 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/Developers.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/Developers.php
@@ -315,7 +315,7 @@ class Developers implements ControllerProviderInterface
                 ->set_type($form->getType())
                 ->set_website($form->getSchemeWebsite() . $form->getWebsite());
 
-            return $app->redirect(sprintf('/developers/application/%d/', $application->get_id()));
+            return $app->redirectPath('developers_application', array('id' => $application->get_id()));
         }
 
         $var = array(
diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php
index 28c8021d38..3baf64ff8c 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/Login.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php
@@ -77,7 +77,13 @@ class Login implements ControllerProviderInterface
                         // then post login operation like getting baskets from an invit session
                         // could be done by Session_handler authentication process
 
-                        $response = new RedirectResponse("/login/logout/?redirect=" . ltrim($request->query->get('redirect', 'prod'), '/'));
+                        $params = array();
+
+                        if (null !== $redirect = $request->query->get('redirect')) {
+                            $params = array('redirect' => ltrim($redirect, '/'));
+                        }
+
+                        $response = $app->redirectPath('logout', $params);
                         $response->headers->setCookie(new Cookie('postlog', 1));
 
                         return $response;
@@ -190,7 +196,7 @@ class Login implements ControllerProviderInterface
                 } catch (NotFoundHttpException $e) {
                     $app->addFlash('error', _('You tried to register with an unknown provider'));
 
-                    return $app->redirect($app->path('login_register'));
+                    return $app->redirectPath('login_register');
                 }
 
                 try {
@@ -198,7 +204,7 @@ class Login implements ControllerProviderInterface
                 } catch (NotAuthenticatedException $e) {
                     $app->addFlash('error', _('You tried to register with an unknown provider'));
 
-                    return $app->redirect($app->path('login_register'));
+                    return $app->redirectPath('login_register');
                 }
 
                 $userAuthProvider = $app['EM']
@@ -208,7 +214,13 @@ class Login implements ControllerProviderInterface
                 if (null !== $userAuthProvider) {
                     $this->postAuthProcess($app, $userAuthProvider->getUser($app));
 
-                    return $app->redirect($request->query->get('redirect', $app->path('prod')));
+                    if (null !== $redirect = $request->query->get('redirect')) {
+                        $redirection = '../' . $redirect;
+                    } else {
+                        $redirection = $app->path('prod');
+                    }
+
+                    return $app->redirect($redirection);
                 }
             }
 
@@ -328,7 +340,7 @@ class Login implements ControllerProviderInterface
                         $app->addFlash('error', _('Unable to send your account unlock email.'));
                     }
 
-                    return $app->redirect($app->path('homepage'));
+                    return $app->redirectPath('homepage');
                 }
             } catch (FormProcessingException $e) {
                 $app->addFlash('error', $e->getMessage());
@@ -388,7 +400,7 @@ class Login implements ControllerProviderInterface
         } catch (\Exception $e) {
             $app->addFlash('error', _('Invalid link.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         try {
@@ -399,7 +411,7 @@ class Login implements ControllerProviderInterface
             $app->addFlash('error', _('Unable to send your account unlock email.'));
         }
 
-        return $app->redirect($app->path('homepage'));
+        return $app->redirectPath('homepage');
     }
 
     /**
@@ -437,7 +449,7 @@ class Login implements ControllerProviderInterface
         if (null === $code = $request->query->get('code')) {
             $app->addFlash('error', _('Invalid unlock link.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         try {
@@ -445,7 +457,7 @@ class Login implements ControllerProviderInterface
         } catch (\Exception_NotFound $e) {
             $app->addFlash('error', _('Invalid unlock link.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         try {
@@ -453,13 +465,13 @@ class Login implements ControllerProviderInterface
         } catch (\Exception $e) {
             $app->addFlash('error', _('Invalid unlock link.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         if (!$user->get_mail_locked()) {
             $app->addFlash('info', _('Account is already unlocked, you can login.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         $app['tokens']->removeToken($code);
@@ -470,7 +482,7 @@ class Login implements ControllerProviderInterface
         } catch (InvalidArgumentException $e) {
             $app->addFlash('success', _('Account has been unlocked, you can now login.'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         $app['tokens']->removeToken($code);
@@ -487,7 +499,7 @@ class Login implements ControllerProviderInterface
             $app->addFlash('info', _('Account has been unlocked, you still have to wait for admin approval.'));
         }
 
-        return $app->redirect($app->path('homepage'));
+        return $app->redirectPath('homepage');
     }
 
     public function renewPassword(PhraseaApplication $app, Request $request)
@@ -527,7 +539,7 @@ class Login implements ControllerProviderInterface
 
                     $app->addFlash('success', _('login::notification: Mise a jour du mot de passe avec succes'));
 
-                    return $app->redirect($app->path('homepage'));
+                    return $app->redirectPath('homepage');
                 }
             } catch (FormProcessingException $e) {
                 $app->addFlash('error', $e->getMessage());
@@ -584,7 +596,7 @@ class Login implements ControllerProviderInterface
                     $app['notification.deliverer']->deliver($mail);
                     $app->addFlash('info', _('phraseanet:: Un email vient de vous etre envoye'));
 
-                    return $app->redirect($app->path('login_forgot_password'));
+                    return $app->redirectPath('login_forgot_password');
                 }
             }
         } catch (FormProcessingException $e) {
@@ -615,7 +627,7 @@ class Login implements ControllerProviderInterface
                 'login' => new \login(),
             ));
         } else {
-            return $app->redirect($app->path('login_register_classic'));
+            return $app->redirectPath('login_register_classic');
         }
     }
 
@@ -633,9 +645,9 @@ class Login implements ControllerProviderInterface
 
         $app->addFlash('info', _('Vous etes maintenant deconnecte. A bientot.'));
 
-        $response = new RedirectResponse($app->path('root', array(
+        $response = $app->redirectPath('homepage', array(
             'redirect' => $request->query->get("redirect")
-        )));
+        ));
 
         $response->headers->removeCookie('persistent');
         $response->headers->removeCookie('last_act');
@@ -693,7 +705,7 @@ class Login implements ControllerProviderInterface
     {
         $form = $app->form(new PhraseaAuthenticationForm());
         $redirector = function (array $params = array()) use ($app) {
-            return $app->redirect($app->path('homepage', $params));
+            return $app->redirectPath('homepage', $params);
         };
 
         try {
@@ -726,7 +738,7 @@ class Login implements ControllerProviderInterface
 
         $this->postAuthProcess($app, $user);
 
-        $response = $this->generateAuthResponse($app['browser'], $request->request->get('redirect'));
+        $response = $this->generateAuthResponse($app, $app['browser'], $request->request->get('redirect'));
         $response->headers->setCookie(new Cookie('invite-usr-id', $user->get_id()));
 
         $event = new PostAuthenticate($request, $response, $user, $context);
@@ -735,16 +747,16 @@ class Login implements ControllerProviderInterface
         return $response;
     }
 
-    private function generateAuthResponse(\Browser $browser, $redirect)
+    private function generateAuthResponse(Application $app, \Browser $browser, $redirect)
     {
         if ($browser->isMobile()) {
-            $response = new RedirectResponse("/lightbox/");
+            $response = $app->redirectPath('lightbox');
         } elseif ($redirect) {
-            $response = new RedirectResponse('/' . ltrim($redirect,'/'));
+            $response = new RedirectResponse('../' . ltrim($redirect,'/'));
         } elseif (true !== $browser->isNewGeneration()) {
-            $response = new RedirectResponse('/client/');
+            $response = $app->redirectPath('get_client');
         } else {
-            $response = new RedirectResponse('/prod/');
+            $response = $app->redirectPath('prod');
         }
 
         $response->headers->removeCookie('postlog');
@@ -779,7 +791,7 @@ class Login implements ControllerProviderInterface
                 'ssel_id'     => $basketId,
                 'from'        => $validationSession->getInitiatorId(),
                 'validate_id' => $validationSession->getId(),
-                'url'         => $app['phraseanet.registry']->get('GV_ServerName') . 'lightbox/validate/' . $basketId . '/?LOG=' . $token
+                'url'         => $app->url('lightbox_validation', array('ssel_id' => $basketId, 'LOG' => $token)),
             ));
 
             $participant->setReminded(new \DateTime('now'));
@@ -829,7 +841,7 @@ class Login implements ControllerProviderInterface
         } catch (NotAuthenticatedException $e) {
             $app['session']->getFlashBag()->add('error', sprintf(_('Unable to authenticate with %s'), $provider->getName()));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         $userAuthProvider = $app['EM']
@@ -839,7 +851,13 @@ class Login implements ControllerProviderInterface
         if (null !== $userAuthProvider) {
             $this->postAuthProcess($app, $userAuthProvider->getUser($app));
 
-            return $app->redirect($request->query->get('redirect', $app->path('prod')));
+            if (null !== $redirect = $request->query->get('redirect')) {
+                $redirection = '../' . $redirect;
+            } else {
+                $redirection = $app->path('prod');
+            }
+
+            return $app->redirect($redirection);
         }
 
         try {
@@ -847,7 +865,7 @@ class Login implements ControllerProviderInterface
         } catch (NotAuthenticatedException $e) {
             $app->addFlash('error', _('Unable to retrieve provider identity'));
 
-            return $app->redirect($app->path('homepage'));
+            return $app->redirectPath('homepage');
         }
 
         if (null !== $user) {
@@ -856,7 +874,13 @@ class Login implements ControllerProviderInterface
 
             $this->postAuthProcess($app, $user);
 
-            return $app->redirect($request->query->get('redirect', $app->path('prod')));
+            if (null !== $redirect = $request->query->get('redirect')) {
+                $redirection = '../' . $redirect;
+            } else {
+                $redirection = $app->path('prod');
+            }
+
+            return $app->redirect($redirection);
         }
 
         if ($app['authentication.providers.account-creator']->isEnabled()) {
@@ -867,14 +891,20 @@ class Login implements ControllerProviderInterface
 
             $this->postAuthProcess($app, $user);
 
-            return $app->redirect($request->query->get('redirect', $app->path('prod')));
+            if (null !== $redirect = $request->query->get('redirect')) {
+                $redirection = '../' . $redirect;
+            } else {
+                $redirection = $app->path('prod');
+            }
+
+            return $app->redirect($redirection);
         } elseif ($app['registration.enabled']) {
-            return $app->redirect($app->path('login_register_classic', array('providerId' => $providerId)));
+            return $app->redirectPath('login_register_classic', array('providerId' => $providerId));
         }
 
         $app->addFlash('error', _('Your identity is not recognized.'));
 
-        return $app->redirect($app->path('homepage'));
+        return $app->redirectPath('homepage');
     }
 
     /**
@@ -939,7 +969,7 @@ class Login implements ControllerProviderInterface
 
         $session = $this->postAuthProcess($app, $user);
 
-        $response = $this->generateAuthResponse($app['browser'], $request->request->get('redirect'));
+        $response = $this->generateAuthResponse($app, $app['browser'], $request->request->get('redirect'));
         $response->headers->setCookie(new Cookie('invite-usr-id', $user->get_id()));
 
         $user->ACL()->inject_rights();
diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php
index d05d8a081b..7855fbf691 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php
@@ -89,7 +89,10 @@ class RSSFeeds implements ControllerProviderInterface
             $page = $page < 1 ? 1 : $page;
 
             return $display_feed($app, $feed, $format, $page);
-        })->assert('id', '\d+')->assert('format', '(rss|atom)');
+        })
+            ->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);
@@ -101,7 +104,10 @@ class RSSFeeds implements ControllerProviderInterface
             $page = $page < 1 ? 1 : $page;
 
             return $display_feed($app, $feed, $format, $page, $token->get_user());
-        })->assert('id', '\d+')->assert('format', '(rss|atom)');
+        })
+            ->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);
@@ -113,7 +119,9 @@ class RSSFeeds implements ControllerProviderInterface
             $page = $page < 1 ? 1 : $page;
 
             return $display_feed($app, $feed, $format, $page, $token->get_user());
-        })->assert('format', '(rss|atom)');
+        })
+            ->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);
@@ -124,7 +132,9 @@ class RSSFeeds implements ControllerProviderInterface
             $page = $page < 1 ? 1 : $page;
 
             return $display_feed($app, $feed, $format, $page);
-        })->assert('format', '(rss|atom)');
+        })
+            ->bind('feed_public_aggregated')
+            ->assert('format', '(rss|atom)');
 
         $controllers->get('/cooliris/', function(Application $app) use ($display_feed) {
             $feeds = \Feed_Collection::load_public_feeds($app);
@@ -135,7 +145,8 @@ class RSSFeeds implements ControllerProviderInterface
             $page = $page < 1 ? 1 : $page;
 
             return $display_feed($app, $feed, \Feed_Adapter::FORMAT_COOLIRIS, $page);
-        });
+        })
+            ->bind('feed_public_cooliris');
 
         return $controllers;
     }
diff --git a/lib/Alchemy/Phrasea/Controller/Root/Root.php b/lib/Alchemy/Phrasea/Controller/Root/Root.php
index 4b755d5e71..624e2b03b9 100644
--- a/lib/Alchemy/Phrasea/Controller/Root/Root.php
+++ b/lib/Alchemy/Phrasea/Controller/Root/Root.php
@@ -55,20 +55,12 @@ class Root implements ControllerProviderInterface
 
     public function getRoot(Application $app, Request $request)
     {
-        if ($app['browser']->isMobile()) {
-            return $app->redirect("/login/?redirect=lightbox");
-        } elseif ($app['browser']->isNewGeneration()) {
-            return $app->redirect("/login/?redirect=prod");
-        }
-
-        return $app->redirect("/login/?redirect=client");
+        return $app->redirectPath('homepage');
     }
 
     public function setLocale(Application $app, Request $request, $locale)
     {
-        $redirect = $request->query->get('redirect') ? : $app->path('root');
-
-        $response = $app->redirect($redirect);
+        $response = $app->redirectPath('root');
         $response->headers->setCookie(new Cookie('locale', $locale));
 
         return $response;
diff --git a/lib/Alchemy/Phrasea/Controller/Setup.php b/lib/Alchemy/Phrasea/Controller/Setup.php
index 116c852cc3..bb3936bf7b 100644
--- a/lib/Alchemy/Phrasea/Controller/Setup.php
+++ b/lib/Alchemy/Phrasea/Controller/Setup.php
@@ -31,8 +31,8 @@ class Setup implements ControllerProviderInterface
         $app['controller.setup'] = $this;
 
         $controllers->get('/', function(Application $app) {
-            return $app->redirect($app->path('install_root'));
-        });
+            return $app->redirectPath('install_root');
+        })->bind('setup');
 
         $controllers->get('/installer/', 'controller.setup:rootInstaller')
             ->bind('install_root');
@@ -119,9 +119,9 @@ class Setup implements ControllerProviderInterface
         try {
             $abConn = new \connection_pdo('appbox', $hostname, $port, $user_ab, $ab_password, $appbox_name, array(), $app['debug']);
         } catch (\Exception $e) {
-            return $app->redirect($app->path('install_step2', array(
+            return $app->redirectPath('install_step2', array(
                 'error' => _('Appbox is unreachable'),
-            )));
+            ));
         }
 
         try {
@@ -129,9 +129,9 @@ class Setup implements ControllerProviderInterface
                 $dbConn = new \connection_pdo('databox', $hostname, $port, $user_ab, $ab_password, $databox_name, array(), $app['debug']);
             }
         } catch (\Exception $e) {
-            return $app->redirect($app->path('install_step2', array(
+            return $app->redirectPath('install_step2', array(
                 'error' => _('Databox is unreachable'),
-            )));
+            ));
         }
 
         $email = $request->request->get('email');
@@ -164,16 +164,16 @@ class Setup implements ControllerProviderInterface
 
             $app['authentication']->openAccount($user);
 
-            return $app->redirect($app->path('admin', array(
+            return $app->redirectPath('admin', array(
                 'section' => 'taskmanager',
                 'notice'  => 'install_success',
-            )));
+            ));
         } catch (\Exception $e) {
 
         }
 
-        return $app->redirect($app->path('install_step2', array(
+        return $app->redirectPath('install_step2', array(
             'error' => sprintf(_('an error occured : %s'), $e->getMessage()),
-        )));
+        ));
     }
 }
diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php b/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php
index 9024dcc9c1..ddf5354aea 100644
--- a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php
+++ b/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php
@@ -28,7 +28,7 @@ class Thesaurus implements ControllerProviderInterface
             $app['firewall']->requireAccessToModule('thesaurus');
         });
 
-        $controllers->match('/', $this->call('indexThesaurus'));
+        $controllers->match('/', $this->call('indexThesaurus'))->bind('thesaurus');
         $controllers->match('accept.php', $this->call('accept'));
         $controllers->match('export_text.php', $this->call('exportText'));
         $controllers->match('export_text_dlg.php', $this->call('exportTextDialog'));
@@ -39,12 +39,12 @@ class Thesaurus implements ControllerProviderInterface
         $controllers->match('linkfield.php', $this->call('linkFieldStep1'));
         $controllers->match('linkfield2.php', $this->call('linkFieldStep2'));
         $controllers->match('linkfield3.php', $this->call('linkFieldStep3'));
-        $controllers->match('loadth.php', $this->call('loadThesaurus'));
+        $controllers->match('loadth.php', $this->call('loadThesaurus'))->bind('thesaurus_loadth');
         $controllers->match('newsy_dlg.php', $this->call('newSynonymDialog'));
         $controllers->match('newterm.php', $this->call('newTerm'));
         $controllers->match('properties.php', $this->call('properties'));
         $controllers->match('search.php', $this->call('search'));
-        $controllers->match('thesaurus.php', $this->call('thesaurus'));
+        $controllers->match('thesaurus.php', $this->call('thesaurus'))->bind('thesaurus_thesaurus');
 
         $controllers->match('xmlhttp/accept.x.php', $this->call('acceptXml'));
         $controllers->match('xmlhttp/acceptcandidates.x.php', $this->call('acceptCandidatesXml'));
diff --git a/lib/Alchemy/Phrasea/Helper/User/Manage.php b/lib/Alchemy/Phrasea/Helper/User/Manage.php
index a87541d635..bf04fc72f9 100644
--- a/lib/Alchemy/Phrasea/Helper/User/Manage.php
+++ b/lib/Alchemy/Phrasea/Helper/User/Manage.php
@@ -183,7 +183,7 @@ class Manage extends Helper
                     $token = $this->app['tokens']->getUrlToken(\random::TYPE_PASSWORD, $createdUser->get_id(), $expire, $createdUser->get_email());
 
                     $mail = MailRequestPasswordSetup::create($this->app, $receiver);
-                    $mail->setButtonUrl($this->app['phraseanet.registry']->get('GV_ServerName') . "register-confirm/?code=" . $token);
+                    $mail->setButtonUrl($this->app->url('login_register_confirm', array('code' => $token)));
                     $mail->setExpiration($expire);
 
                     $this->app['notification.deliverer']->deliver($mail);
@@ -195,7 +195,7 @@ class Manage extends Helper
 
                 if ($receiver && false !== $urlToken) {
                     $mail = MailSuccessEmailConfirmationUnregistered::create($this->app, $receiver);
-                    $mail->setButtonUrl($this->app['url_generator']->generate('login_forgot_password', array('token' => $urlToken), true));
+                    $mail->setButtonUrl($this->app->url('login_forgot_password', array('token' => $urlToken)));
                     $this->app['notification.deliverer']->deliver($mail);
                 }
             }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/AbstractMail.php b/lib/Alchemy/Phrasea/Notification/Mail/AbstractMail.php
index 010fe26750..016b724962 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/AbstractMail.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/AbstractMail.php
@@ -75,7 +75,7 @@ abstract class AbstractMail implements MailInterface
      */
     public function getPhraseanetURL()
     {
-        return $this->app['url_generator']->generate('root', array(), true);
+        return $this->app->url('root');
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoNewOrder.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoNewOrder.php
index ec7e07643b..cba9c3ca38 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoNewOrder.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoNewOrder.php
@@ -64,6 +64,6 @@ class MailInfoNewOrder extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('prod', array(), true);
+        return $this->app->url('prod');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderCancelled.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderCancelled.php
index 8ba00127c0..8bed0f4aa2 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderCancelled.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderCancelled.php
@@ -80,6 +80,6 @@ class MailInfoOrderCancelled extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('prod', array(), true);
+        return $this->app->url('prod');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderDelivered.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderDelivered.php
index dba74c360f..3681db3658 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderDelivered.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoOrderDelivered.php
@@ -87,6 +87,6 @@ class MailInfoOrderDelivered extends AbstractMail
             throw new LogicException('You must set a basket before calling getSubject');
         }
 
-        return $this->app['url_generator']->generate('lightbox_compare', array('ssel_id' => $this->basket->getId()), true);
+        return $this->app->url('lightbox_compare', array('ssel_id' => $this->basket->getId()));
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoRecordQuarantined.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoRecordQuarantined.php
index e4b8ad139d..3f84919f2b 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoRecordQuarantined.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoRecordQuarantined.php
@@ -42,6 +42,6 @@ class MailInfoRecordQuarantined extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('root', array(), true);
+        return $this->app->url('root');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoSomebodyAutoregistered.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoSomebodyAutoregistered.php
index 66282120c7..17cd0b220c 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoSomebodyAutoregistered.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoSomebodyAutoregistered.php
@@ -45,6 +45,6 @@ class MailInfoSomebodyAutoregistered extends AbstractMailWithLink
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('admin', array('section' => 'users'), true);
+        return $this->app->url('admin', array('section' => 'users'));
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoUserRegistered.php b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoUserRegistered.php
index 56d803e14e..0981334531 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailInfoUserRegistered.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailInfoUserRegistered.php
@@ -65,6 +65,6 @@ class MailInfoUserRegistered extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('admin', array('section' => 'registrations'), true);
+        return $this->app->url('admin', array('section' => 'registrations'));
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessAccessRequest.php b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessAccessRequest.php
index 2e9209b92f..f6e05e05ef 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessAccessRequest.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessAccessRequest.php
@@ -44,6 +44,6 @@ class MailSuccessAccessRequest extends AbstractMailWithLink
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('account_access', array(), true);
+        return $this->app->url('account_access');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationRegistered.php b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationRegistered.php
index 29893be51c..7b3f0d95c7 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationRegistered.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationRegistered.php
@@ -42,6 +42,6 @@ class MailSuccessEmailConfirmationRegistered extends AbstractMailWithLink
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('root', array(), true);
+        return $this->app->url('root');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationUnregistered.php b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationUnregistered.php
index 3e68b23b3d..907aa73595 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationUnregistered.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailConfirmationUnregistered.php
@@ -44,6 +44,6 @@ class MailSuccessEmailConfirmationUnregistered extends AbstractMailWithLink
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('account_access', array(), true);
+        return $this->app->url('account_access');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailUpdate.php b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailUpdate.php
index 69dfa47f80..f5909b904b 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailUpdate.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailSuccessEmailUpdate.php
@@ -46,6 +46,6 @@ class MailSuccessEmailUpdate extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('root', array(), true);
+        return $this->app->url('root');
     }
 }
diff --git a/lib/Alchemy/Phrasea/Notification/Mail/MailTest.php b/lib/Alchemy/Phrasea/Notification/Mail/MailTest.php
index 2ffbfd8796..f7586c7bb8 100644
--- a/lib/Alchemy/Phrasea/Notification/Mail/MailTest.php
+++ b/lib/Alchemy/Phrasea/Notification/Mail/MailTest.php
@@ -45,6 +45,6 @@ class MailTest extends AbstractMail
      */
     public function getButtonURL()
     {
-        return $this->app['url_generator']->generate('root', array(), true);
+        return $this->app->url('root');
     }
 }
diff --git a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/ConfigurationPanel.php b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/ConfigurationPanel.php
index 639c190c0f..ae37dcf601 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/ConfigurationPanel.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/ConfigurationPanel.php
@@ -65,7 +65,7 @@ class ConfigurationPanel extends AbstractConfigurationPanel
 
         file_put_contents($this->getConfigPathFile(), json_encode($configuration));
 
-        return $app->redirect($app['url_generator']->generate('admin_searchengine_get'));
+        return $app->redirectPath('admin_searchengine_get');
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/ConfigurationPanel.php b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/ConfigurationPanel.php
index ea4a74ab06..ff6a284708 100644
--- a/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/ConfigurationPanel.php
+++ b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/ConfigurationPanel.php
@@ -76,7 +76,7 @@ class ConfigurationPanel extends AbstractConfigurationPanel
 
         $this->saveConfiguration($configuration);
 
-        return $app->redirect($app['url_generator']->generate('admin_searchengine_get'));
+        return $app->redirectPath('admin_searchengine_get');
     }
 
     /**
diff --git a/lib/Alchemy/Phrasea/Security/Firewall.php b/lib/Alchemy/Phrasea/Security/Firewall.php
index a054d74f7a..ab9307d968 100644
--- a/lib/Alchemy/Phrasea/Security/Firewall.php
+++ b/lib/Alchemy/Phrasea/Security/Firewall.php
@@ -16,7 +16,9 @@ class Firewall
     public function requireSetUp()
     {
         if (!$this->app['phraseanet.configuration-tester']->isInstalled()) {
-            $this->app->abort(302, 'Phraseanet is not installed', array('X-Phraseanet-Redirect' => '/setup/'));
+            $this->app->abort(302, 'Phraseanet is not installed', array(
+                'X-Phraseanet-Redirect' => $this->app->path('setup')
+            ));
         }
 
         return null;
@@ -113,7 +115,9 @@ class Firewall
     public function requireAuthentication()
     {
         if (!$this->app['authentication']->isAuthenticated()) {
-            $this->app->abort(302, 'You are not authenticated', array('X-Phraseanet-Redirect' => '/login/'));
+            $this->app->abort(302, 'You are not authenticated', array(
+                'X-Phraseanet-Redirect' => $this->app->path('homepage')
+            ));
         }
 
         return $this;
@@ -122,7 +126,9 @@ class Firewall
     public function requireNotAuthenticated()
     {
         if ($this->app['authentication']->isAuthenticated()) {
-            $this->app->abort(302, 'You are authenticated', array('X-Phraseanet-Redirect' => '/prod/'));
+            $this->app->abort(302, 'You are authenticated', array(
+                'X-Phraseanet-Redirect' => $this->app->path('prod')
+            ));
         }
 
         return $this;
diff --git a/lib/classes/Bridge/Api.php b/lib/classes/Bridge/Api.php
index 017da86591..f430e8eccf 100644
--- a/lib/classes/Bridge/Api.php
+++ b/lib/classes/Bridge/Api.php
@@ -11,6 +11,7 @@
 
 use Alchemy\Phrasea\Application;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Generator\UrlGenerator;
 
 /**
  *
@@ -77,7 +78,7 @@ class Bridge_Api
         if ( ! $row)
             throw new Bridge_Exception_ApiNotFound('Api Not Found');
 
-        $this->connector = self::get_connector_by_name($this->app['phraseanet.registry'], $row['name']);
+        $this->connector = self::get_connector_by_name($this->app, $row['name']);
         $this->disable_time = $row['disable_time'] ? new DateTime($row['disable_time']) : null;
         $this->updated_on = new DateTime($row['updated_on']);
         $this->created_on = new DateTime($row['created_on']);
@@ -460,13 +461,9 @@ class Bridge_Api
      * @param  string            $api_name
      * @return string
      */
-    public static function generate_callback_url(registryInterface $registry, $api_name)
+    public static function generate_callback_url(UrlGenerator $generator, $api_name)
     {
-        return sprintf(
-                '%sprod/bridge/callback/%s/'
-                , $registry->get('GV_ServerName')
-                , mb_strtolower($api_name)
-        );
+        return $generator->generate('prod_bridge_callback', array('api_name' => strtolower($api_name)), UrlGenerator::ABSOLUTE_URL);
     }
 
     /**
@@ -475,22 +472,18 @@ class Bridge_Api
      * @param  string            $api_name
      * @return string
      */
-    public static function generate_login_url(registryInterface $registry, $api_name)
+    public static function generate_login_url(UrlGenerator $generator, $api_name)
     {
-        return sprintf(
-                '%sprod/bridge/login/%s/'
-                , $registry->get('GV_ServerName')
-                , mb_strtolower($api_name)
-        );
+        return $generator->generate('prod_bridge_login', array('api_name' => strtolower($api_name)), UrlGenerator::ABSOLUTE_URL);
     }
 
     /**
      *
-     * @param  registryInterface    $registry
+     * @param  Application          $app
      * @param  string               $name
      * @return Bridge_Api_Interface
      */
-    public static function get_connector_by_name(registryInterface $registry, $name)
+    public static function get_connector_by_name(Application $app, $name)
     {
         $name = ucfirst(strtolower($name));
         $classname = 'Bridge_Api_' . $name;
@@ -502,7 +495,7 @@ class Bridge_Api
         $auth_classname = 'Bridge_Api_Auth_' . $classname::AUTH_TYPE;
         $auth = new $auth_classname;
 
-        return new $classname($registry, $auth);
+        return new $classname($app['url_generator'], $app['phraseanet.registry'], $auth);
     }
 
     public static function get_by_api_name(Application $app, $name)
diff --git a/lib/classes/Bridge/Api/Abstract.php b/lib/classes/Bridge/Api/Abstract.php
index fb2d94a549..123901dcc9 100644
--- a/lib/classes/Bridge/Api/Abstract.php
+++ b/lib/classes/Bridge/Api/Abstract.php
@@ -9,6 +9,8 @@
  * file that was distributed with this source code.
  */
 
+use Symfony\Component\Routing\Generator\UrlGenerator;
+
 /**
  *
  * @package     Bridge
@@ -28,6 +30,7 @@ abstract class Bridge_Api_Abstract
      * @var string
      */
     protected $locale = 'en_US';
+    protected $generator;
 
     /**
      *
@@ -35,8 +38,9 @@ abstract class Bridge_Api_Abstract
      * @param  Bridge_Api_Auth_Interface $auth
      * @return Bridge_Api_Abstract
      */
-    public function __construct(registryInterface $registry, Bridge_Api_Auth_Interface $auth)
+    public function __construct(UrlGenerator $generator, registryInterface $registry, Bridge_Api_Auth_Interface $auth)
     {
+        $this->generator = $generator;
         $this->registry = $registry;
         $this->_auth = $auth;
         $this->initialize_transport();
diff --git a/lib/classes/Bridge/Api/Dailymotion.php b/lib/classes/Bridge/Api/Dailymotion.php
index 975554043c..de5c7c921d 100644
--- a/lib/classes/Bridge/Api/Dailymotion.php
+++ b/lib/classes/Bridge/Api/Dailymotion.php
@@ -689,7 +689,7 @@ class Bridge_Api_Dailymotion extends Bridge_Api_Abstract implements Bridge_Api_I
             array(
                 'client_id'      => $this->registry->get('GV_dailymotion_client_id')
                 , 'client_secret'  => $this->registry->get('GV_dailymotion_client_secret')
-                , 'redirect_uri'   => Bridge_Api::generate_callback_url($this->registry, $this->get_name())
+                , 'redirect_uri'   => Bridge_Api::generate_callback_url($this->generator, $this->get_name())
                 , 'scope'          => ''
                 , 'response_type'  => 'code'
                 , 'token_endpoint' => self::OAUTH2_TOKEN_ENDPOINT
diff --git a/lib/classes/Bridge/Api/Interface.php b/lib/classes/Bridge/Api/Interface.php
index b1eaf79347..95ae4bfd85 100644
--- a/lib/classes/Bridge/Api/Interface.php
+++ b/lib/classes/Bridge/Api/Interface.php
@@ -9,6 +9,8 @@
  * file that was distributed with this source code.
  */
 
+use Symfony\Component\Routing\Generator\UrlGenerator;
+
 /**
  *
  * @package     Bridge
@@ -20,7 +22,7 @@ interface Bridge_Api_Interface
     const OBJECT_CLASS_ELEMENT = 'element';
     const OBJECT_CLASS_CONTAINER = 'container';
 
-    public function __construct(registryInterface $registry, Bridge_Api_Auth_Interface $auth);
+    public function __construct(UrlGenerator $generator, registryInterface $registry, Bridge_Api_Auth_Interface $auth);
 
     /**
      *
diff --git a/lib/classes/Bridge/Api/Youtube.php b/lib/classes/Bridge/Api/Youtube.php
index 75b1c39d51..576ef05448 100644
--- a/lib/classes/Bridge/Api/Youtube.php
+++ b/lib/classes/Bridge/Api/Youtube.php
@@ -819,7 +819,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter
             array(
                 'client_id'      => $this->registry->get('GV_youtube_client_id')
                 , 'client_secret'  => $this->registry->get('GV_youtube_client_secret')
-                , 'redirect_uri'   => Bridge_Api::generate_callback_url($this->registry, $this->get_name())
+                , 'redirect_uri'   => Bridge_Api::generate_callback_url($this->generator, $this->get_name())
                 , 'scope'          => 'http://gdata.youtube.com'
                 , 'response_type'  => 'code'
                 , 'token_endpoint' => self::OAUTH2_TOKEN_ENDPOINT
diff --git a/lib/classes/eventsmanager/notify/feed.php b/lib/classes/eventsmanager/notify/feed.php
index fc1bff7c28..8d1fd19a3a 100644
--- a/lib/classes/eventsmanager/notify/feed.php
+++ b/lib/classes/eventsmanager/notify/feed.php
@@ -101,7 +101,7 @@ class eventsmanager_notify_feed extends eventsmanager_notifyAbstract
                                 , $entry->get_id()
                         );
 
-                        $url = $this->app['phraseanet.registry']->get('GV_ServerName') . 'lightbox/index.php?LOG=' . $token;
+                        $url = $this->app->url('lightbox', array('LOG' => $token));
 
                         $receiver = Receiver::fromUser($user_to_notif);
                         $readyToSend = true;
diff --git a/lib/classes/eventsmanager/notify/register.php b/lib/classes/eventsmanager/notify/register.php
index 17f924b93a..d735d35d26 100644
--- a/lib/classes/eventsmanager/notify/register.php
+++ b/lib/classes/eventsmanager/notify/register.php
@@ -166,7 +166,7 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
 
         $ret = array(
             'text'  => sprintf(
-                _('%1$s demande votre approbation sur une ou plusieurs %2$scollections%3$s'), $sender, '', ''
+                _('%1$s demande votre approbation sur une ou plusieurs %2$scollections%3$s'), $sender, '', ''
             )
             , 'class' => ''
         );
diff --git a/lib/classes/eventsmanager/notify/validate.php b/lib/classes/eventsmanager/notify/validate.php
index 0ea9b9364b..7cf1abb7a1 100644
--- a/lib/classes/eventsmanager/notify/validate.php
+++ b/lib/classes/eventsmanager/notify/validate.php
@@ -154,8 +154,8 @@ class eventsmanager_notify_validate extends eventsmanager_notifyAbstract
         }
 
         $bask_link = ''
+            . $this->app->url('lightbox_validation', array('ssel_id' => (string) $sx->ssel_id))
+            . '" target="_blank">'
             . $basket_name . '';
 
         $ret = array(
diff --git a/lib/classes/media/Permalink/Adapter.php b/lib/classes/media/Permalink/Adapter.php
index 9a98b7b422..f5e5936bf9 100644
--- a/lib/classes/media/Permalink/Adapter.php
+++ b/lib/classes/media/Permalink/Adapter.php
@@ -146,15 +146,15 @@ class media_Permalink_Adapter implements media_Permalink_Interface, cache_cachea
      */
     public function get_url()
     {
-        return sprintf('%spermalink/v1/%d/%d/%s/%s.%s?token=%s',
-            $this->app['phraseanet.registry']->get('GV_ServerName'),
-            $this->media_subdef->get_sbas_id(),
-            $this->media_subdef->get_record_id(),
-            $this->media_subdef->get_name(),
-            $this->get_label(),
-            pathinfo($this->media_subdef->get_file(), PATHINFO_EXTENSION),
-            $this->get_token()
-        );
+        $label = $this->get_label() . '.' . pathinfo($this->media_subdef->get_file(), PATHINFO_EXTENSION);
+
+        return $this->app->url('permalinks_permalink', array(
+            'sbas_id'   => $this->media_subdef->get_sbas_id(),
+            'record_id' => $this->media_subdef->get_record_id(),
+            'subdef'    => $this->media_subdef->get_name(),
+            'label'     => $label,
+            'token'     => $this->get_token(),
+        ));
     }
 
     /**
@@ -163,13 +163,12 @@ class media_Permalink_Adapter implements media_Permalink_Interface, cache_cachea
      */
     public function get_page()
     {
-        return sprintf('%spermalink/v1/%d/%d/%s/?token=%s',
-            $this->app['phraseanet.registry']->get('GV_ServerName'),
-            $this->media_subdef->get_sbas_id(),
-            $this->media_subdef->get_record_id(),
-            $this->media_subdef->get_name(),
-            $this->get_token()
-        );
+        return $this->app->url('permalinks_permaview', array(
+            'sbas_id'   => $this->media_subdef->get_sbas_id(),
+            'record_id' => $this->media_subdef->get_record_id(),
+            'subdef'    => $this->media_subdef->get_name(),
+            'token'     => $this->get_token(),
+        ));
     }
 
     /**
diff --git a/lib/conf.d/minifyGroupsConfig.php b/lib/conf.d/minifyGroupsConfig.php
index b7db49f126..ba9eb8df93 100644
--- a/lib/conf.d/minifyGroupsConfig.php
+++ b/lib/conf.d/minifyGroupsConfig.php
@@ -15,22 +15,24 @@ $groups = array(
         '//skins/build/login.css',
         '//assets/font-awesome/css/font-awesome.css',
     ),
-    'authentication' => array(
-        '//assets/modernizr/modernizr.js',
-        '//assets/jquery/jquery.js',
-        '//assets/bootstrap/js/bootstrap-transition.js',
+    'bootstrap_js' => array(
+        '//assets/bootstrap/js/bootstrap-affix.js',
         '//assets/bootstrap/js/bootstrap-alert.js',
-        '//assets/bootstrap/js/bootstrap-modal.js',
+        '//assets/bootstrap/js/bootstrap-button.js',
+        '//assets/bootstrap/js/bootstrap-carousel.js',
+        '//assets/bootstrap/js/bootstrap-collapse.js',
         '//assets/bootstrap/js/bootstrap-dropdown.js',
+        '//assets/bootstrap/js/bootstrap-modal.js',
+        '//assets/bootstrap/js/bootstrap-popover.js',
         '//assets/bootstrap/js/bootstrap-scrollspy.js',
         '//assets/bootstrap/js/bootstrap-tab.js',
         '//assets/bootstrap/js/bootstrap-tooltip.js',
-        '//assets/bootstrap/js/bootstrap-popover.js',
-        '//assets/bootstrap/js/bootstrap-button.js',
-        '//assets/bootstrap/js/bootstrap-collapse.js',
-        '//assets/bootstrap/js/bootstrap-carousel.js',
+        '//assets/bootstrap/js/bootstrap-transition.js',
         '//assets/bootstrap/js/bootstrap-typeahead.js',
-        '//assets/bootstrap/js/bootstrap-affix.js',
+    ),
+    'authentication' => array(
+        '//assets/modernizr/modernizr.js',
+        '//assets/jquery/jquery.js',
         '//assets/angular/angular.js',
         '//assets/angular-ui/build/angular-ui.js',
         '//assets/bootstrap-switch/static/js/bootstrapSwitch.js',
@@ -54,7 +56,7 @@ $groups = array(
         , '//include/jquery.image_enhancer.js'
         , '//include/jslibs/jquery.contextmenu_scroll.js'),
     'admin' => array(
-        '//include/jslibs/jquery-1.7.1.js'
+        '//assets/jquery/jquery.js'
         , '//include/jslibs/jquery.validate.js'
         , '//include/jslibs/jquery.validate.password.js'
         , '//include/jslibs/jquery-ui-1.8.17/js/jquery-ui-1.8.17.custom.min.js'
diff --git a/templates/mobile/api/auth/end_user_authorization.html.twig b/templates/mobile/api/auth/end_user_authorization.html.twig
index ac49973ff9..252ce8a268 100644
--- a/templates/mobile/api/auth/end_user_authorization.html.twig
+++ b/templates/mobile/api/auth/end_user_authorization.html.twig
@@ -9,13 +9,13 @@
         
 
         
-        
-        
-        
+        
+        
+        
 
         
-        
+        
 
         
         
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-
+        
+        
     
 
diff --git a/templates/mobile/api/auth/native_app_access_token.html.twig b/templates/mobile/api/auth/native_app_access_token.html.twig
index a78256bc70..60cdf05c94 100644
--- a/templates/mobile/api/auth/native_app_access_token.html.twig
+++ b/templates/mobile/api/auth/native_app_access_token.html.twig
@@ -15,13 +15,13 @@
         
 
         
-        
-        
-        
+        
+        
+        
 
         
-        
+        
 
         
         
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-
+        
+        
     
 
diff --git a/templates/mobile/common/index.html.twig b/templates/mobile/common/index.html.twig
index 0a10de5259..0e580698ba 100644
--- a/templates/mobile/common/index.html.twig
+++ b/templates/mobile/common/index.html.twig
@@ -5,12 +5,12 @@
         
         
         {{ app['phraseanet.registry'].get('GV_homeTitle') }} - {{ module_name }} 
-        
-        
+        
+        
         {% block stylesheet %}{% endblock %}
         {% block icon %}{% endblock %}
         {% block javascript %}{% endblock %}
-        
+        
     
     
         {% block content %}{% endblock %}
diff --git a/templates/mobile/lightbox/basket_element.html.twig b/templates/mobile/lightbox/basket_element.html.twig
index d2c10e210f..2431c258c4 100644
--- a/templates/mobile/lightbox/basket_element.html.twig
+++ b/templates/mobile/lightbox/basket_element.html.twig
@@ -3,20 +3,20 @@
 {% extends "common/index.html.twig" %}
 
 {% block javascript %}
-
+
 {% endblock %}
 
 {% block stylesheet %}
-  
+  
 {% endblock %}
 
 {% block content %}
   {% set record = basket_element.getRecord(app) %}
 
- Back + Back

{{basket_element.getOrd()}} - {{record.get_title()}}

- Home + Home
{{ thumbnail.format100percent(record.get_preview(),'', record.get_thumbnail()) }} @@ -31,7 +31,7 @@ {% endif %}
- + {% trans 'validation:: editer ma note' %}
diff --git a/templates/mobile/lightbox/error.html.twig b/templates/mobile/lightbox/error.html.twig index 71a9d2bf40..ada374a922 100644 --- a/templates/mobile/lightbox/error.html.twig +++ b/templates/mobile/lightbox/error.html.twig @@ -15,7 +15,7 @@

{% trans 'Erreur !' %}

{% trans 'Le panier demande nexiste plus' %}

{{error}}

-

{% trans 'Retour a l\'accueil' %}

+

{% trans 'Retour a l\'accueil' %}

diff --git a/templates/mobile/lightbox/feed.html.twig b/templates/mobile/lightbox/feed.html.twig index a0500f6ad9..c3eeeb2006 100644 --- a/templates/mobile/lightbox/feed.html.twig +++ b/templates/mobile/lightbox/feed.html.twig @@ -2,18 +2,18 @@ {% extends "common/index.html.twig" %} {% block javascript %} - + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block content %}

{{feed_entry.get_title()}}

- {% trans 'Home' %} + {% trans 'Home' %}

@@ -28,7 +28,7 @@

    {% for item in feed_entry.get_content() %}
  • - + {{thumbnail.format(item.get_record().get_thumbnail(), 80, 80, '', true, false)}} diff --git a/templates/mobile/lightbox/feed_element.html.twig b/templates/mobile/lightbox/feed_element.html.twig index 268d5679c2..66006c3a6f 100644 --- a/templates/mobile/lightbox/feed_element.html.twig +++ b/templates/mobile/lightbox/feed_element.html.twig @@ -3,20 +3,20 @@ {% extends "common/index.html.twig" %} {% block javascript %} - + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block content %} {% set record = feed_element.get_record() %}
    - Back + Back

    {{feed_element.get_ord()}} - {{record.get_title()}}

    - Home + Home
    {{ thumbnail.format100percent(record.get_preview(),'', record.get_thumbnail()) }} diff --git a/templates/mobile/lightbox/index.html.twig b/templates/mobile/lightbox/index.html.twig index f03b506814..0960f6b65b 100644 --- a/templates/mobile/lightbox/index.html.twig +++ b/templates/mobile/lightbox/index.html.twig @@ -1,11 +1,11 @@ {% extends "common/index.html.twig" %} {% block javascript %} - + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block icon %} @@ -50,7 +50,7 @@
@@ -94,7 +94,7 @@ {% if basket.getElements().first() %} {% endif %} -

{{basket.getName()}}

+

{{basket.getName()}}

{{ basket.getDescription() }}

{{ basket_length }} @@ -123,7 +123,7 @@ {% if basket.getElements().first() %} {% endif %} -

{{ basket.getName() }}

+

{{ basket.getName() }}

{{ basket.getDescription() }}

{{basket_length}} diff --git a/templates/mobile/lightbox/note_form.html.twig b/templates/mobile/lightbox/note_form.html.twig index 9578539c54..52fc51582b 100644 --- a/templates/mobile/lightbox/note_form.html.twig +++ b/templates/mobile/lightbox/note_form.html.twig @@ -3,11 +3,11 @@ {% extends "common/index.html.twig" %} {% block javascript %} - + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block content %} diff --git a/templates/mobile/lightbox/validate.html.twig b/templates/mobile/lightbox/validate.html.twig index 650b25bafe..0ad8ba09da 100644 --- a/templates/mobile/lightbox/validate.html.twig +++ b/templates/mobile/lightbox/validate.html.twig @@ -2,19 +2,19 @@ {% extends "common/index.html.twig" %} {% block javascript %} - + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block content %}

@@ -28,7 +28,7 @@

{% endif %} - + {{thumbnail.format(basket_element.getRecord(app).get_thumbnail(), 80, 80, '', true, false)}} diff --git a/templates/mobile/login/index.html.twig b/templates/mobile/login/index.html.twig index 922acc4051..11a8bbbe43 100644 --- a/templates/mobile/login/index.html.twig +++ b/templates/mobile/login/index.html.twig @@ -17,7 +17,7 @@

{{ app['phraseanet.registry'].get('GV_homeTitle') }}

-
+ + + + + {% block head %}{% endblock %} diff --git a/templates/web/account/reset-email.html.twig b/templates/web/account/reset-email.html.twig index 2412ee3f6f..ab7b0cc744 100644 --- a/templates/web/account/reset-email.html.twig +++ b/templates/web/account/reset-email.html.twig @@ -7,7 +7,7 @@ {% endblock %} {% block head %} - + + diff --git a/templates/web/admin/index.html.twig b/templates/web/admin/index.html.twig index 39636cf8f4..27d6094951 100644 --- a/templates/web/admin/index.html.twig +++ b/templates/web/admin/index.html.twig @@ -8,12 +8,12 @@ {% endblock %} {% block stylesheet %} - + {% endblock %} {% block javascript %} - + - +
@@ -117,7 +117,7 @@

@@ -148,7 +148,7 @@ {% if publisher.is_owner() == true %} X {% else %} -
+
@@ -159,7 +159,7 @@
-
+
@@ -211,7 +211,7 @@ {% else %} {% trans 'You are not the feed owner' %} - {% trans 'boutton::retour' %} + {% trans 'boutton::retour' %} {% endif %}
diff --git a/templates/web/admin/publications/list.html.twig b/templates/web/admin/publications/list.html.twig index 0edf231379..8b01782c0d 100644 --- a/templates/web/admin/publications/list.html.twig +++ b/templates/web/admin/publications/list.html.twig @@ -2,7 +2,7 @@ {% block content %} - +

{% trans 'Ajouter une publication' %}

@@ -58,13 +58,13 @@ - {{ feed.get_title() }} + {{ feed.get_title() }} {{ app['date-formatter'].getDate(feed.get_created_on()) }} @@ -82,7 +82,7 @@ {% if feed.is_owner(app['authentication'].getUser()) %} - + {% endif %} diff --git a/templates/web/admin/statusbit.html.twig b/templates/web/admin/statusbit.html.twig index a2cd21a9bc..22a282c20a 100644 --- a/templates/web/admin/statusbit.html.twig +++ b/templates/web/admin/statusbit.html.twig @@ -23,18 +23,18 @@ {% if attribute(status, bit) is defined %} - + -
+
{% else %} - + diff --git a/templates/web/admin/statusbit/edit.html.twig b/templates/web/admin/statusbit/edit.html.twig index 3058522423..e79c931d89 100644 --- a/templates/web/admin/statusbit/edit.html.twig +++ b/templates/web/admin/statusbit/edit.html.twig @@ -7,7 +7,7 @@

{% trans 'status:: numero de bit' %} {{ app['request'].get('bit') }}

-
+
diff --git a/templates/web/admin/structure.html.twig b/templates/web/admin/structure.html.twig index 028b1cb468..1254d65800 100644 --- a/templates/web/admin/structure.html.twig +++ b/templates/web/admin/structure.html.twig @@ -27,7 +27,7 @@

{% trans 'admin::base: structure' %}

- +
diff --git a/templates/web/admin/subdefs.html.twig b/templates/web/admin/subdefs.html.twig index 12ab151dfb..640315f6c1 100644 --- a/templates/web/admin/subdefs.html.twig +++ b/templates/web/admin/subdefs.html.twig @@ -2,7 +2,7 @@ {% extends "admin/common/iframe_wrap.html.twig" %} {% block stylesheet %} - + - - - + + + {% if css_file %} - + {% endif %} - - - - - + + + + + @@ -408,18 +408,18 @@ - + {##} - - - + + {% block stylesheet %}{% endblock %} {% block icon %}{% endblock %} diff --git a/templates/web/common/menubar.html.twig b/templates/web/common/menubar.html.twig index 9151141498..da71a15d18 100644 --- a/templates/web/common/menubar.html.twig +++ b/templates/web/common/menubar.html.twig @@ -9,7 +9,7 @@ {% if module != "lightbox" and app['authentication'].isAuthenticated() %}
  • {% if module == "prod" %} - + {% trans 'admin::monitor: Ancienne version (client)' %} @@ -17,13 +17,13 @@ {% else %} {% if app['browser'].isNewGeneration %} {% if module == "client" %} - + {% trans 'admin::monitor: Nouvelle version (prod)' %} {% else %} - + {% trans 'admin::monitor: production' %} @@ -35,7 +35,7 @@ {% if app['browser'].isNewGeneration and app['phraseanet.registry'].get('GV_thesaurus') == true and app['authentication'].getUser().ACL.has_access_to_module('thesaurus') %}
  • - + {% trans 'admin::monitor: module thesaurus' %} @@ -47,7 +47,7 @@ {# MODULE #} {% if app['authentication'].getUser().ACL.has_access_to_module('admin') %}
  • - + {% trans 'admin::monitor: module admin' %} @@ -68,7 +68,7 @@ {# MODULE #}
  • - + {% trans 'admin::monitor: module validation' %} @@ -143,7 +143,7 @@ {% trans 'Guest' %} {% else %} - + {{app['authentication'].getUser().get_login()}} @@ -181,7 +181,7 @@
  • {% if app['authentication'].isAuthenticated() %} - + {% trans 'phraseanet:: deconnection' %} diff --git a/templates/web/lightbox/IE6/feed.html.twig b/templates/web/lightbox/IE6/feed.html.twig index cf1a8a1c38..60c1cd6537 100644 --- a/templates/web/lightbox/IE6/feed.html.twig +++ b/templates/web/lightbox/IE6/feed.html.twig @@ -4,13 +4,13 @@ {% import 'common/caption_templates/preview.html.twig' as caption %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block content %} diff --git a/templates/web/lightbox/IE6/feed_container.html.twig b/templates/web/lightbox/IE6/feed_container.html.twig index 549ba0defa..0c74835877 100644 --- a/templates/web/lightbox/IE6/feed_container.html.twig +++ b/templates/web/lightbox/IE6/feed_container.html.twig @@ -3,14 +3,14 @@
    {% for element in feed_entry.get_content() %} diff --git a/templates/web/lightbox/IE6/index.html.twig b/templates/web/lightbox/IE6/index.html.twig index fe1e18c997..6b3477061b 100644 --- a/templates/web/lightbox/IE6/index.html.twig +++ b/templates/web/lightbox/IE6/index.html.twig @@ -3,13 +3,13 @@ {% import 'common/thumbnail.html.twig' as thumbnail %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} - + {% endblock %} {% block icon %} diff --git a/templates/web/lightbox/IE6/sc_container.html.twig b/templates/web/lightbox/IE6/sc_container.html.twig index 4e6a49fac5..4013d91409 100644 --- a/templates/web/lightbox/IE6/sc_container.html.twig +++ b/templates/web/lightbox/IE6/sc_container.html.twig @@ -3,7 +3,7 @@
    {% for element in basket.getElements() %} diff --git a/templates/web/lightbox/IE6/validate.html.twig b/templates/web/lightbox/IE6/validate.html.twig index 6c51b5787b..18a6ac230c 100644 --- a/templates/web/lightbox/IE6/validate.html.twig +++ b/templates/web/lightbox/IE6/validate.html.twig @@ -4,14 +4,14 @@ {% import 'common/caption_templates/preview.html.twig' as caption %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} + href="{{ path('minifier', { 'f' : 'include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,skins/lightbox/lightboxie6.css' }) }}" media="screen"/> {% endblock %} {% block content %} diff --git a/templates/web/lightbox/error.html.twig b/templates/web/lightbox/error.html.twig index 1cbc702ec3..18094b47d1 100644 --- a/templates/web/lightbox/error.html.twig +++ b/templates/web/lightbox/error.html.twig @@ -2,7 +2,7 @@ {% block stylesheet %} + href="{{ path('minifier', { 'f' : 'skins/lightbox/lightbox.css' }) }}" media="screen"/> {% endblock %} {% block content %} @@ -10,7 +10,7 @@

    {% trans 'Erreur !' %}

    {{ message }}

    {{error}}

    -

    {% trans 'Retour a laccueil' %}

    +

    {% trans 'Retour a laccueil' %}

    {% endblock %} diff --git a/templates/web/lightbox/feed.html.twig b/templates/web/lightbox/feed.html.twig index 29c88194e6..a628afc2ee 100644 --- a/templates/web/lightbox/feed.html.twig +++ b/templates/web/lightbox/feed.html.twig @@ -4,14 +4,14 @@ {% import 'common/caption_templates/preview.html.twig' as caption %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} + href="{{ path('minifier', { 'f' : 'include/jslibs/jquery.contextmenu.css,include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,skins/lightbox/lightbox.css' }) }}" media="screen"/> {% endblock %} diff --git a/templates/web/lightbox/feed_container.html.twig b/templates/web/lightbox/feed_container.html.twig index 549ba0defa..0c74835877 100644 --- a/templates/web/lightbox/feed_container.html.twig +++ b/templates/web/lightbox/feed_container.html.twig @@ -3,14 +3,14 @@
    {% for element in feed_entry.get_content() %} diff --git a/templates/web/lightbox/index.html.twig b/templates/web/lightbox/index.html.twig index 1418ffc328..59c85d3317 100644 --- a/templates/web/lightbox/index.html.twig +++ b/templates/web/lightbox/index.html.twig @@ -3,14 +3,14 @@ {% import 'common/thumbnail.html.twig' as thumbnail %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} + href="{{ path('minifier', { 'f' : 'include/jslibs/jquery.contextmenu.css,include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,skins/lightbox/lightbox.css' }) }}" media="screen"/> {% endblock %} {% block icon %} diff --git a/templates/web/lightbox/sc_container.html.twig b/templates/web/lightbox/sc_container.html.twig index 7c5a397ece..85de49b0a0 100644 --- a/templates/web/lightbox/sc_container.html.twig +++ b/templates/web/lightbox/sc_container.html.twig @@ -3,7 +3,7 @@
    {% for element in basket.getElements() %} diff --git a/templates/web/lightbox/validate.html.twig b/templates/web/lightbox/validate.html.twig index 143076c883..ef19e3a794 100644 --- a/templates/web/lightbox/validate.html.twig +++ b/templates/web/lightbox/validate.html.twig @@ -4,14 +4,14 @@ {% import 'common/caption_templates/preview.html.twig' as caption %} {% block javascript %} - - - + + + {% endblock %} {% block stylesheet %} + href="{{ path('minifier', { 'f' : 'include/jslibs/jquery.contextmenu.css,include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,skins/lightbox/lightbox.css' }) }}" media="screen"/> {% endblock %} diff --git a/templates/web/login/layout/base-layout.html.twig b/templates/web/login/layout/base-layout.html.twig index 48a795fa7b..cd8e0b376c 100644 --- a/templates/web/login/layout/base-layout.html.twig +++ b/templates/web/login/layout/base-layout.html.twig @@ -26,10 +26,10 @@ {% endblock favicon %} {% block header_stylesheet %} - + {% endblock header_stylesheet %} @@ -49,7 +49,8 @@ - + + {% endblock header_javascript %} {% endblock header %} diff --git a/templates/web/overview.html.twig b/templates/web/overview.html.twig index b723867574..513023247c 100644 --- a/templates/web/overview.html.twig +++ b/templates/web/overview.html.twig @@ -7,7 +7,7 @@ {% endblock %} {% block stylesheet %} - + {% endblock %} {% block javascript %} - - + + - - + + + - - - - + + + + diff --git a/templates/web/setup/wrapper.html.twig b/templates/web/setup/wrapper.html.twig index eb73b38a84..b2f443b05c 100644 --- a/templates/web/setup/wrapper.html.twig +++ b/templates/web/setup/wrapper.html.twig @@ -2,11 +2,11 @@ "http://www.w3.org/TR/html4/strict.dtd"> - - - - - + + + + + + + + {% if dlg is not none %} @@ -41,7 +41,7 @@
    - +
    {% for candidate in candidates %} diff --git a/templates/web/thesaurus/properties.html.twig b/templates/web/thesaurus/properties.html.twig index 7741578286..9e2604a036 100644 --- a/templates/web/thesaurus/properties.html.twig +++ b/templates/web/thesaurus/properties.html.twig @@ -7,7 +7,7 @@ {% trans 'thesaurus:: Proprietes' %} - + - - - - + + + + - - - + + +