From 6fd2d72eb19461e5b5519362e7fc82f34c410548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 26 Mar 2015 16:46:20 +0100 Subject: [PATCH 01/26] Set composer to use --no-progress --no-interaction options --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6f9f716fb8..20d6637d78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ services: - redis before_install: - - composer self-update + - composer self-update --no-progress --no-interaction - sudo apt-get purge elasticsearch - > wget --no-check-certificate https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.3.2.deb && From 2fde5a437e7ad1554d3f982eb1d7ef0d8776fcc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 11:59:48 +0100 Subject: [PATCH 02/26] AbstractDelivery does not provides any controllers --- lib/Alchemy/Phrasea/Controller/AbstractDelivery.php | 3 +-- lib/Alchemy/Phrasea/Controller/Datafiles.php | 3 ++- lib/Alchemy/Phrasea/Controller/Permalink.php | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php index b2dcf1ea25..a25d763cc2 100644 --- a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php +++ b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php @@ -13,10 +13,9 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Http\DeliverDataInterface; -use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; -abstract class AbstractDelivery implements ControllerProviderInterface +abstract class AbstractDelivery { public function deliverContent(Request $request, \record_adapter $record, $subdef, $watermark, $stamp, Application $app) { diff --git a/lib/Alchemy/Phrasea/Controller/Datafiles.php b/lib/Alchemy/Phrasea/Controller/Datafiles.php index a7a03906a7..3cfe8aa39d 100644 --- a/lib/Alchemy/Phrasea/Controller/Datafiles.php +++ b/lib/Alchemy/Phrasea/Controller/Datafiles.php @@ -13,11 +13,12 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application as PhraseaApplication; use Silex\Application; +use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -class Datafiles extends AbstractDelivery +class Datafiles extends AbstractDelivery implements ControllerProviderInterface { public function connect(Application $app) { diff --git a/lib/Alchemy/Phrasea/Controller/Permalink.php b/lib/Alchemy/Phrasea/Controller/Permalink.php index f86a45196b..988dbabe84 100644 --- a/lib/Alchemy/Phrasea/Controller/Permalink.php +++ b/lib/Alchemy/Phrasea/Controller/Permalink.php @@ -14,11 +14,12 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Model\Serializer\CaptionSerializer; use Silex\Application; +use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class Permalink extends AbstractDelivery +class Permalink extends AbstractDelivery implements ControllerProviderInterface { public function connect(Application $app) { From 1342756b841a6fa25599c8eb9dad4ace2d68b3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 12:53:10 +0100 Subject: [PATCH 03/26] Rename Controller to ControllerProvider --- lib/Alchemy/Phrasea/Application.php | 114 +++++++++--------- lib/Alchemy/Phrasea/Application/Api.php | 16 +-- lib/Alchemy/Phrasea/Controller/Api/Result.php | 2 +- .../Admin/Collection.php | 6 +- .../Admin/ConnectedUsers.php | 2 +- .../Admin/Dashboard.php | 3 +- .../Admin/Databox.php | 4 +- .../Admin/Databoxes.php | 2 +- .../Admin/Fields.php | 2 +- .../Admin/Publications.php | 2 +- .../Admin/Root.php | 2 +- .../Admin/SearchEngine.php | 2 +- .../Admin/Setup.php | 2 +- .../Admin/Subdefs.php | 2 +- .../Admin/TaskManager.php | 2 +- .../Admin/Users.php | 2 +- .../Api/Oauth2.php | 2 +- .../Api/V1.php | 16 ++- .../Client/Root.php | 2 +- .../Datafiles.php | 5 +- .../Lightbox.php | 2 +- .../Minifier.php | 2 +- .../Permalink.php | 3 +- .../Prod/BasketController.php | 2 +- .../Prod/Bridge.php | 3 +- .../Prod/DoDownload.php | 2 +- .../Prod/Download.php | 2 +- .../Prod/Edit.php | 3 +- .../Prod/Export.php | 2 +- .../Prod/Feed.php | 2 +- .../Prod/Language.php | 2 +- .../Prod/Lazaret.php | 2 +- .../Prod/MoveCollection.php | 2 +- .../Prod/Order.php | 2 +- .../Prod/Printer.php | 2 +- .../Prod/Property.php | 3 +- .../Prod/Push.php | 3 +- .../Prod/Query.php | 4 +- .../Prod/Records.php | 2 +- .../Prod/Root.php | 2 +- .../Prod/Share.php | 2 +- .../Prod/Story.php | 2 +- .../Prod/TOU.php | 2 +- .../Prod/Tools.php | 2 +- .../Prod/Tooltip.php | 2 +- .../Prod/Upload.php | 2 +- .../Prod/UsrLists.php | 2 +- .../Prod/WorkZone.php | 2 +- .../Report/Activity.php | 2 +- .../Report/Informations.php | 2 +- .../Report/Root.php | 2 +- .../Root/Account.php | 3 +- .../Root/Developers.php | 2 +- .../Root/Login.php | 2 +- .../Root/RSSFeeds.php | 3 +- .../Root/Root.php | 2 +- .../Root/Session.php | 3 +- .../Setup.php | 2 +- .../Thesaurus/Thesaurus.php | 2 +- .../Thesaurus/Xmlhttp.php | 5 +- .../User/Notifications.php | 2 +- .../User/Preferences.php | 2 +- .../Manipulator/ApiAccountManipulator.php | 3 +- .../Controller/Admin/ConnectedUserTest.php | 2 +- .../Phrasea/Controller/Api/ApiTestCase.php | 2 +- .../Phrasea/Controller/Api/ResultTest.php | 2 +- .../Phrasea/Controller/Prod/ShareTest.php | 2 +- .../Manipulator/ApiAccountManipulatorTest.php | 2 +- 68 files changed, 162 insertions(+), 138 deletions(-) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Collection.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/ConnectedUsers.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Dashboard.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Databox.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Databoxes.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Fields.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Publications.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Root.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/SearchEngine.php (96%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Setup.php (96%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Subdefs.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/TaskManager.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Admin/Users.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Api/Oauth2.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Api/V1.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Client/Root.php (96%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Datafiles.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Lightbox.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Minifier.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Permalink.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/BasketController.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Bridge.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/DoDownload.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Download.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Edit.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Export.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Feed.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Language.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Lazaret.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/MoveCollection.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Order.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Printer.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Property.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Push.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Query.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Records.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Root.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Share.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Story.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/TOU.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Tools.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Tooltip.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/Upload.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/UsrLists.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Prod/WorkZone.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Report/Activity.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Report/Informations.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Report/Root.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/Account.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/Developers.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/Login.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/RSSFeeds.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/Root.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Root/Session.php (98%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Setup.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Thesaurus/Thesaurus.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/Thesaurus/Xmlhttp.php (99%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/User/Notifications.php (97%) rename lib/Alchemy/Phrasea/{Controller => ControllerProvider}/User/Preferences.php (98%) diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index b208509542..9c245e0ce0 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -11,63 +11,63 @@ namespace Alchemy\Phrasea; -use Alchemy\Phrasea\Controller\Lightbox; -use Alchemy\Phrasea\Controller\Datafiles; -use Alchemy\Phrasea\Controller\Permalink; -use Alchemy\Phrasea\Controller\Admin\Collection; -use Alchemy\Phrasea\Controller\Admin\ConnectedUsers; -use Alchemy\Phrasea\Controller\Admin\Dashboard; -use Alchemy\Phrasea\Controller\Admin\Databox; -use Alchemy\Phrasea\Controller\Admin\Databoxes; -use Alchemy\Phrasea\Controller\Admin\Fields; -use Alchemy\Phrasea\Controller\Admin\Publications; -use Alchemy\Phrasea\Controller\Admin\Root as AdminRoot; -use Alchemy\Phrasea\Controller\Admin\Setup; -use Alchemy\Phrasea\Controller\Admin\SearchEngine; -use Alchemy\Phrasea\Controller\Admin\Subdefs; -use Alchemy\Phrasea\Controller\Admin\TaskManager; -use Alchemy\Phrasea\Controller\Admin\Users; -use Alchemy\Phrasea\Controller\Client\Root as ClientRoot; -use Alchemy\Phrasea\Controller\Minifier; -use Alchemy\Phrasea\Controller\Prod\BasketController; -use Alchemy\Phrasea\Controller\Prod\Bridge; -use Alchemy\Phrasea\Controller\Prod\Download; -use Alchemy\Phrasea\Controller\Prod\DoDownload; -use Alchemy\Phrasea\Controller\Prod\Edit; -use Alchemy\Phrasea\Controller\Prod\Export; -use Alchemy\Phrasea\Controller\Prod\Feed; -use Alchemy\Phrasea\Controller\Prod\Language; -use Alchemy\Phrasea\Controller\Prod\Lazaret; -use Alchemy\Phrasea\Controller\Prod\MoveCollection; -use Alchemy\Phrasea\Controller\Prod\Order; -use Alchemy\Phrasea\Controller\Prod\Printer; -use Alchemy\Phrasea\Controller\Prod\Push; -use Alchemy\Phrasea\Controller\Prod\Query; -use Alchemy\Phrasea\Controller\Prod\Property; -use Alchemy\Phrasea\Controller\Prod\Records; -use Alchemy\Phrasea\Controller\Prod\Root as Prod; -use Alchemy\Phrasea\Controller\Prod\Share; -use Alchemy\Phrasea\Controller\Prod\Story; -use Alchemy\Phrasea\Controller\Prod\Tools; -use Alchemy\Phrasea\Controller\Prod\Tooltip; -use Alchemy\Phrasea\Controller\Prod\TOU; -use Alchemy\Phrasea\Controller\Prod\Upload; -use Alchemy\Phrasea\Controller\Prod\UsrLists; -use Alchemy\Phrasea\Controller\Prod\WorkZone; -use Alchemy\Phrasea\Controller\Report\Activity as ReportActivity; -use Alchemy\Phrasea\Controller\Report\Informations as ReportInformations; -use Alchemy\Phrasea\Controller\Report\Root as ReportRoot; -use Alchemy\Phrasea\Controller\Root\Account; -use Alchemy\Phrasea\Controller\Root\Developers; -use Alchemy\Phrasea\Controller\Root\Login; -use Alchemy\Phrasea\Controller\Root\Root; -use Alchemy\Phrasea\Controller\Root\RSSFeeds; -use Alchemy\Phrasea\Controller\Root\Session; -use Alchemy\Phrasea\Controller\Setup as SetupController; -use Alchemy\Phrasea\Controller\Thesaurus\Thesaurus; -use Alchemy\Phrasea\Controller\Thesaurus\Xmlhttp as ThesaurusXMLHttp; -use Alchemy\Phrasea\Controller\User\Notifications; -use Alchemy\Phrasea\Controller\User\Preferences; +use Alchemy\Phrasea\ControllerProvider\Lightbox; +use Alchemy\Phrasea\ControllerProvider\Datafiles; +use Alchemy\Phrasea\ControllerProvider\Permalink; +use Alchemy\Phrasea\ControllerProvider\Admin\Collection; +use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; +use Alchemy\Phrasea\ControllerProvider\Admin\Dashboard; +use Alchemy\Phrasea\ControllerProvider\Admin\Databox; +use Alchemy\Phrasea\ControllerProvider\Admin\Databoxes; +use Alchemy\Phrasea\ControllerProvider\Admin\Fields; +use Alchemy\Phrasea\ControllerProvider\Admin\Publications; +use Alchemy\Phrasea\ControllerProvider\Admin\Root as AdminRoot; +use Alchemy\Phrasea\ControllerProvider\Admin\Setup; +use Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine; +use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; +use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; +use Alchemy\Phrasea\ControllerProvider\Admin\Users; +use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; +use Alchemy\Phrasea\ControllerProvider\Minifier; +use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; +use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; +use Alchemy\Phrasea\ControllerProvider\Prod\Download; +use Alchemy\Phrasea\ControllerProvider\Prod\DoDownload; +use Alchemy\Phrasea\ControllerProvider\Prod\Edit; +use Alchemy\Phrasea\ControllerProvider\Prod\Export; +use Alchemy\Phrasea\ControllerProvider\Prod\Feed; +use Alchemy\Phrasea\ControllerProvider\Prod\Language; +use Alchemy\Phrasea\ControllerProvider\Prod\Lazaret; +use Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection; +use Alchemy\Phrasea\ControllerProvider\Prod\Order; +use Alchemy\Phrasea\ControllerProvider\Prod\Printer; +use Alchemy\Phrasea\ControllerProvider\Prod\Push; +use Alchemy\Phrasea\ControllerProvider\Prod\Query; +use Alchemy\Phrasea\ControllerProvider\Prod\Property; +use Alchemy\Phrasea\ControllerProvider\Prod\Records; +use Alchemy\Phrasea\ControllerProvider\Prod\Root as Prod; +use Alchemy\Phrasea\ControllerProvider\Prod\Share; +use Alchemy\Phrasea\ControllerProvider\Prod\Story; +use Alchemy\Phrasea\ControllerProvider\Prod\Tools; +use Alchemy\Phrasea\ControllerProvider\Prod\Tooltip; +use Alchemy\Phrasea\ControllerProvider\Prod\TOU; +use Alchemy\Phrasea\ControllerProvider\Prod\Upload; +use Alchemy\Phrasea\ControllerProvider\Prod\UsrLists; +use Alchemy\Phrasea\ControllerProvider\Prod\WorkZone; +use Alchemy\Phrasea\ControllerProvider\Report\Activity as ReportActivity; +use Alchemy\Phrasea\ControllerProvider\Report\Informations as ReportInformations; +use Alchemy\Phrasea\ControllerProvider\Report\Root as ReportRoot; +use Alchemy\Phrasea\ControllerProvider\Root\Account; +use Alchemy\Phrasea\ControllerProvider\Root\Developers; +use Alchemy\Phrasea\ControllerProvider\Root\Login; +use Alchemy\Phrasea\ControllerProvider\Root\Root; +use Alchemy\Phrasea\ControllerProvider\Root\RSSFeeds; +use Alchemy\Phrasea\ControllerProvider\Root\Session; +use Alchemy\Phrasea\ControllerProvider\Setup as SetupController; +use Alchemy\Phrasea\ControllerProvider\Thesaurus\Thesaurus; +use Alchemy\Phrasea\ControllerProvider\Thesaurus\Xmlhttp as ThesaurusXMLHttp; +use Alchemy\Phrasea\ControllerProvider\User\Notifications; +use Alchemy\Phrasea\ControllerProvider\User\Preferences; use Alchemy\Phrasea\Core\Event\Subscriber\BasketSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ExportSubscriber; diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index 268bdac5a3..d8b86ac541 100644 --- a/lib/Alchemy/Phrasea/Application/Api.php +++ b/lib/Alchemy/Phrasea/Application/Api.php @@ -12,17 +12,17 @@ namespace Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application as PhraseaApplication; -use Alchemy\Phrasea\Controller\Minifier; -use Alchemy\Phrasea\Controller\Permalink; -use Alchemy\Phrasea\Controller\Datafiles; -use Alchemy\Phrasea\Core\Event\Subscriber\ApiCorsSubscriber; -use Alchemy\Phrasea\Core\PhraseaEvents; -use Alchemy\Phrasea\Controller\Api\Oauth2; use Alchemy\Phrasea\Controller\Api\Result; -use Alchemy\Phrasea\Controller\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Api\Oauth2; +use Alchemy\Phrasea\ControllerProvider\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Datafiles; +use Alchemy\Phrasea\ControllerProvider\Minifier; +use Alchemy\Phrasea\ControllerProvider\Permalink; use Alchemy\Phrasea\Core\Event\ApiResultEvent; -use Alchemy\Phrasea\Core\Event\Subscriber\ApiOauth2ErrorsSubscriber; +use Alchemy\Phrasea\Core\Event\Subscriber\ApiCorsSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ApiExceptionHandlerSubscriber; +use Alchemy\Phrasea\Core\Event\Subscriber\ApiOauth2ErrorsSubscriber; +use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\Provider\JsonSchemaServiceProvider; use Monolog\Logger; use Monolog\Processor\WebProcessor; diff --git a/lib/Alchemy/Phrasea/Controller/Api/Result.php b/lib/Alchemy/Phrasea/Controller/Api/Result.php index e01ab79862..fd849e10b2 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/Result.php +++ b/lib/Alchemy/Phrasea/Controller/Api/Result.php @@ -11,7 +11,7 @@ namespace Alchemy\Phrasea\Controller\Api; -use Silex\Application; +use Alchemy\Phrasea\ControllerProvider\Api\V1; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Collection.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php index 0d1d5ad807..ac64c19ea5 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php @@ -9,10 +9,11 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Exception\RuntimeException; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -25,11 +26,12 @@ class Collection implements ControllerProviderInterface { $app['controller.admin.collection'] = $this; + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; $app['firewall']->addMandatoryAuthentication($controllers); - $controllers->before(function (Request $request) use ($app) { + $controllers->before(function () use ($app) { $app['firewall']->requireAccessToModule('admin') ->requireRightOnBase($app['request']->attributes->get('bas_id'), 'canadmin'); }); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php index 6ed8fe1b67..a881a6fee8 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Geonames\Exception\ExceptionInterface as GeonamesExceptionInterface; use Silex\Application; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php index 4f21177602..b5fa997ff3 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Controller\Admin\RedirectResponse; use Alchemy\Phrasea\Notification\Receiver; use Alchemy\Phrasea\Notification\Mail\MailTest; use Alchemy\Phrasea\Exception\InvalidArgumentException; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Databox.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php index ee3fc77f34..d439998719 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php @@ -9,8 +9,10 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Controller\Admin\JsonResponse; +use Alchemy\Phrasea\Controller\Admin\RedirectResponse; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php index b2f78f8cd4..0e08f4b0c2 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Doctrine\DBAL\DBALException; use Silex\Application; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Fields.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Fields.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php index bbbbf967fb..a6cf25f42f 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Fields.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Metadata\TagProvider; use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Publications.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Publications.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Publications.php index 45fefa7c0c..f4de24e844 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Publications.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Publications.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Model\Entities\Feed; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Root.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Root.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Root.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Root.php index c7055443d5..8d043cb6cb 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Root.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Root.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Exception\SessionNotFound; use Alchemy\Phrasea\Helper\DatabaseHelper; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngine.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php similarity index 96% rename from lib/Alchemy/Phrasea/Controller/Admin/SearchEngine.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php index 45530d43fd..2d6efe97ea 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/SearchEngine.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/SearchEngine.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Application as PhraseaApplication; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php similarity index 96% rename from lib/Alchemy/Phrasea/Controller/Admin/Setup.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php index 42196b81f9..58694a7287 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Setup.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Setup.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Application; use Silex\Application as SilexApplication; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php index 1476378348..e51bd45020 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Subdefs.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php index 0f6eb6b888..83145dc8fb 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/TaskManager.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/TaskManager.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Exception\RuntimeException; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Admin/Users.php rename to lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php index 70702c73ec..2d68b30422 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Admin; +namespace Alchemy\Phrasea\ControllerProvider\Admin; use Alchemy\Phrasea\Core\Response\CSVFileResponse; use Alchemy\Phrasea\Helper\User as UserHelper; diff --git a/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/Oauth2.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Api/Oauth2.php rename to lib/Alchemy/Phrasea/ControllerProvider/Api/Oauth2.php index f212ea76b5..42e700ec3f 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/Oauth2.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/Oauth2.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Api; +namespace Alchemy\Phrasea\ControllerProvider\Api; use Alchemy\Phrasea\Authentication\Context; use Alchemy\Phrasea\Authentication\Exception\AccountLockedException; diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Api/V1.php rename to lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php index 0b69729251..c71927802d 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Api; +namespace Alchemy\Phrasea\ControllerProvider\Api; use Alchemy\Phrasea\Authentication\Context; use Alchemy\Phrasea\Border\Attribute\Status; @@ -17,6 +17,16 @@ use Alchemy\Phrasea\Border\File; use Alchemy\Phrasea\Border\Manager as BorderManager; use Alchemy\Phrasea\Border\Manager; use Alchemy\Phrasea\Cache\Cache as CacheInterface; +use Alchemy\Phrasea\Controller\Api\API_V1_exception_badrequest; +use Alchemy\Phrasea\Controller\Api\API_V1_exception_forbidden; +use Alchemy\Phrasea\Controller\Api\caption_field; +use Alchemy\Phrasea\Controller\Api\caption_record; +use Alchemy\Phrasea\Controller\Api\collection; +use Alchemy\Phrasea\Controller\Api\media_Permalink_Adapter; +use Alchemy\Phrasea\Controller\Api\media_subdef; +use Alchemy\Phrasea\Controller\Api\Result; +use Alchemy\Phrasea\Controller\Api\Symfony; +use Alchemy\Phrasea\Controller\Api\type; use Alchemy\Phrasea\Core\Event\ApiOAuth2EndEvent; use Alchemy\Phrasea\Core\Event\ApiOAuth2StartEvent; use Alchemy\Phrasea\Core\Event\PreAuthenticate; @@ -701,10 +711,10 @@ class V1 implements ControllerProviderInterface switch ($request->get('forceBehavior')) { case '0' : - $behavior = BorderManager::FORCE_RECORD; + $behavior = Manager::FORCE_RECORD; break; case '1' : - $behavior = BorderManager::FORCE_LAZARET; + $behavior = Manager::FORCE_LAZARET; break; case null: $behavior = null; diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/ControllerProvider/Client/Root.php similarity index 96% rename from lib/Alchemy/Phrasea/Controller/Client/Root.php rename to lib/Alchemy/Phrasea/ControllerProvider/Client/Root.php index 67fb145c03..af354d89be 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Client/Root.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Client; +namespace Alchemy\Phrasea\ControllerProvider\Client; use Alchemy\Phrasea\Feed\Aggregate; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; diff --git a/lib/Alchemy/Phrasea/Controller/Datafiles.php b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Datafiles.php rename to lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php index 3cfe8aa39d..9b313fd03a 100644 --- a/lib/Alchemy/Phrasea/Controller/Datafiles.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php @@ -9,14 +9,15 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller; +namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\Controller\AbstractDelivery; use Silex\Application; use Silex\ControllerProviderInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Datafiles extends AbstractDelivery implements ControllerProviderInterface { diff --git a/lib/Alchemy/Phrasea/Controller/Lightbox.php b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Lightbox.php rename to lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php index 9434052482..0378f6de37 100644 --- a/lib/Alchemy/Phrasea/Controller/Lightbox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller; +namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Core\Event\ValidationEvent; use Alchemy\Phrasea\Core\PhraseaEvents; diff --git a/lib/Alchemy/Phrasea/Controller/Minifier.php b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Minifier.php rename to lib/Alchemy/Phrasea/ControllerProvider/Minifier.php index fe471634c1..29946f1278 100644 --- a/lib/Alchemy/Phrasea/Controller/Minifier.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller; +namespace Alchemy\Phrasea\ControllerProvider; use Silex\ControllerProviderInterface; use Silex\Application; diff --git a/lib/Alchemy/Phrasea/Controller/Permalink.php b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Permalink.php rename to lib/Alchemy/Phrasea/ControllerProvider/Permalink.php index 988dbabe84..9dc9a44476 100644 --- a/lib/Alchemy/Phrasea/Controller/Permalink.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php @@ -9,9 +9,10 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller; +namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\Controller\AbstractDelivery; use Alchemy\Phrasea\Model\Serializer\CaptionSerializer; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/BasketController.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/BasketController.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/BasketController.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/BasketController.php index a4239ea019..ce26694168 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/BasketController.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/BasketController.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Model\Entities\Basket as BasketEntity; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Bridge.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php index 8cd68f601c..6bd482886b 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Bridge.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; +use Alchemy\Phrasea\Controller\Prod\HttpException; use Alchemy\Phrasea\Helper\Record as RecordHelper; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/DoDownload.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/DoDownload.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/DoDownload.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/DoDownload.php index c3062f2900..a3a74ba26f 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/DoDownload.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/DoDownload.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Http\DeliverDataInterface; use Alchemy\Phrasea\Model\Entities\Token; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Download.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Download.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Prod/Download.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Download.php index 65a03e26ce..98347f0317 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Download.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Download.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Core\Event\ExportEvent; use Alchemy\Phrasea\Core\PhraseaEvents; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Edit.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Edit.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php index 41706cbcc3..ab87c3d775 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Edit.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Edit.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; +use Alchemy\Phrasea\Controller\Prod\record_adapter; use Alchemy\Phrasea\Core\Event\RecordEdit; use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Export.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Export.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Export.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Export.php index 67a8b7150d..99a030a842 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Export.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Export.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Core\Event\ExportFailureEvent; use Alchemy\Phrasea\Core\PhraseaEvents; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Feed.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Feed.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Feed.php index 0d1868d1a7..4302911c6c 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Feed.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Feed.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Core\Event\FeedEntryEvent; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Language.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Language.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Language.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Language.php index ae9572e469..07e30c3cab 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Language.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Language.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php index 36631e2f23..1672d97d97 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Lazaret.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Lazaret.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Model\Entities\LazaretFile; use Alchemy\Phrasea\Border; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php index feded8b21c..c1d2bd6b09 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/MoveCollection.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Silex\Application; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Order.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Order.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php index a76c9c8d19..69d8cf8619 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Order.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Order.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Core\Event\OrderDeliveryEvent; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Printer.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Printer.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Prod/Printer.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Printer.php index 4fcecaab27..2dfdea170a 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Printer.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Printer.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Property.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Property.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Prod/Property.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Property.php index 23c5e9f92d..69e299ce28 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Property.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Property.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; +use Alchemy\Phrasea\Controller\Prod\type; use Alchemy\Phrasea\Controller\RecordsRequest; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Push.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Push.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php index 1874d89a43..10666ea1f9 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Push.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Push.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; +use Alchemy\Phrasea\Controller\Prod\record_adapter; use Alchemy\Phrasea\Core\Event\PushEvent; use Alchemy\Phrasea\Core\Event\ValidationEvent; use Alchemy\Phrasea\Core\PhraseaEvents; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Query.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Query.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Query.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Query.php index 958428fd41..a2af6fc1d6 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Query.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Query.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; use Alchemy\Phrasea\SearchEngine\SearchEngineResult; @@ -234,4 +234,4 @@ class Query implements ControllerProviderInterface ]) ]); } -} \ No newline at end of file +} diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Records.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Records.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Records.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Records.php index 1519263683..a432bc174e 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Records.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Records.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Root.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Root.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Root.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Root.php index 8c14998c7e..029d347cfe 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Root.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Root.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Exception\SessionNotFound; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Share.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Prod/Share.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php index d28213aab2..a423bddf89 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Share.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Story.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Story.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Story.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Story.php index 08682d064f..ee6b216c27 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Story.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Story.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\Exception as ControllerException; use Alchemy\Phrasea\Controller\RecordsRequest; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/TOU.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/TOU.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Prod/TOU.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/TOU.php index b784ab0006..d8b52f0e6c 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/TOU.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/TOU.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Tools.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php index 0e08f2a79d..3ef4dc7b38 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tools.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Exception\RuntimeException; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tooltip.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Tooltip.php index 45f98c337f..b63b5208b2 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Tooltip.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Tooltip.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Upload.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/Upload.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php index 4202438e2d..8af201d5a1 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Upload.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Border\File; use Alchemy\Phrasea\Border\Attribute\Status; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/UsrLists.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/UsrLists.php index c19cc93879..f787b62182 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/UsrLists.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/UsrLists.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Model\Entities\UsrList; use Alchemy\Phrasea\Model\Entities\UsrListEntry; diff --git a/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/WorkZone.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php rename to lib/Alchemy/Phrasea/ControllerProvider/Prod/WorkZone.php index 29bceffb21..8afb3253bf 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/WorkZone.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/WorkZone.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Prod; +namespace Alchemy\Phrasea\ControllerProvider\Prod; use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\Model\Entities\StoryWZ; diff --git a/lib/Alchemy/Phrasea/Controller/Report/Activity.php b/lib/Alchemy/Phrasea/ControllerProvider/Report/Activity.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Report/Activity.php rename to lib/Alchemy/Phrasea/ControllerProvider/Report/Activity.php index 4f4866b071..c43c386812 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/Activity.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Report/Activity.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Report; +namespace Alchemy\Phrasea\ControllerProvider\Report; use Alchemy\Phrasea\Core\Response\CSVFileResponse; use Goodby\CSV\Export\Standard\Collection\CallbackCollection; diff --git a/lib/Alchemy/Phrasea/Controller/Report/Informations.php b/lib/Alchemy/Phrasea/ControllerProvider/Report/Informations.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Report/Informations.php rename to lib/Alchemy/Phrasea/ControllerProvider/Report/Informations.php index 3028f4b632..7b6a847aec 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/Informations.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Report/Informations.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Report; +namespace Alchemy\Phrasea\ControllerProvider\Report; use Alchemy\Phrasea\Core\Response\CSVFileResponse; use Goodby\CSV\Export\Standard\Collection\CallbackCollection; diff --git a/lib/Alchemy/Phrasea/Controller/Report/Root.php b/lib/Alchemy/Phrasea/ControllerProvider/Report/Root.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Report/Root.php rename to lib/Alchemy/Phrasea/ControllerProvider/Report/Root.php index c78740f400..5f8097c6b1 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/Root.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Report/Root.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Report; +namespace Alchemy\Phrasea\ControllerProvider\Report; use Alchemy\Phrasea\Core\Response\CSVFileResponse; use Goodby\CSV\Export\Standard\Collection\CallbackCollection; diff --git a/lib/Alchemy/Phrasea/Controller/Root/Account.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/Account.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Root/Account.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/Account.php index 07b622916a..c5a9109991 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Account.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/Account.php @@ -9,10 +9,11 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; use Alchemy\Geonames\Exception\ExceptionInterface as GeonamesExceptionInterface; use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\ControllerProvider\Root\Login; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Model\Entities\FtpCredential; use Alchemy\Phrasea\Model\Entities\ApiApplication; diff --git a/lib/Alchemy/Phrasea/Controller/Root/Developers.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/Developers.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Root/Developers.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/Developers.php index 802161cc9d..1e2fecb91b 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Developers.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/Developers.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Model\Entities\ApiApplication; diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/Login.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Root/Login.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/Login.php index 74066f1c0a..9920d5b6c9 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/Login.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Authentication\Exception\NotAuthenticatedException; diff --git a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/RSSFeeds.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/RSSFeeds.php index 92fbcf5043..8555d1772a 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RSSFeeds.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/RSSFeeds.php @@ -9,9 +9,8 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; -use Alchemy\Phrasea\Model\Entities\Feed; use Alchemy\Phrasea\Feed\Aggregate; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Root/Root.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/Root.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/Root/Root.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/Root.php index 15966e7b11..09e2125238 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Root.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/Root.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Root/Session.php b/lib/Alchemy/Phrasea/ControllerProvider/Root/Session.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/Root/Session.php rename to lib/Alchemy/Phrasea/ControllerProvider/Root/Session.php index 34d049261d..868900393e 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Session.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Root/Session.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Root; +namespace Alchemy\Phrasea\ControllerProvider\Root; +use Alchemy\Phrasea\Controller\Root\RedirectResponse; use Alchemy\Phrasea\Model\Entities\SessionModule; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Setup.php rename to lib/Alchemy/Phrasea/ControllerProvider/Setup.php index 7dc349f001..0d102b78a1 100644 --- a/lib/Alchemy/Phrasea/Controller/Setup.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller; +namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Helper\DatabaseHelper; diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php b/lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Thesaurus.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php rename to lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Thesaurus.php index c3a6753f71..e45ac4dafa 100644 --- a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Thesaurus.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Thesaurus; +namespace Alchemy\Phrasea\ControllerProvider\Thesaurus; use Doctrine\DBAL\Driver\Connection; use Silex\Application; diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php b/lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Xmlhttp.php similarity index 99% rename from lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php rename to lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Xmlhttp.php index 37937954be..942ad18a58 100644 --- a/lib/Alchemy/Phrasea/Controller/Thesaurus/Xmlhttp.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Thesaurus/Xmlhttp.php @@ -9,8 +9,11 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\Thesaurus; +namespace Alchemy\Phrasea\ControllerProvider\Thesaurus; +use Alchemy\Phrasea\Controller\Thesaurus\caption_field; +use Alchemy\Phrasea\Controller\Thesaurus\caption_Field_Value; +use Alchemy\Phrasea\Controller\Thesaurus\databox; use Alchemy\Phrasea\Model\Entities\User; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/User/Notifications.php b/lib/Alchemy/Phrasea/ControllerProvider/User/Notifications.php similarity index 97% rename from lib/Alchemy/Phrasea/Controller/User/Notifications.php rename to lib/Alchemy/Phrasea/ControllerProvider/User/Notifications.php index d13c0b52da..4f82147c1a 100644 --- a/lib/Alchemy/Phrasea/Controller/User/Notifications.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/User/Notifications.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\User; +namespace Alchemy\Phrasea\ControllerProvider\User; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Controller/User/Preferences.php b/lib/Alchemy/Phrasea/ControllerProvider/User/Preferences.php similarity index 98% rename from lib/Alchemy/Phrasea/Controller/User/Preferences.php rename to lib/Alchemy/Phrasea/ControllerProvider/User/Preferences.php index a642cc8376..73bb361e52 100644 --- a/lib/Alchemy/Phrasea/Controller/User/Preferences.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/User/Preferences.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Controller\User; +namespace Alchemy\Phrasea\ControllerProvider\User; use Silex\Application; use Silex\ControllerProviderInterface; diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php index d00d8855f6..5598f290ee 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php @@ -11,8 +11,7 @@ namespace Alchemy\Phrasea\Model\Manipulator; -use Alchemy\Phrasea\Application; -use Alchemy\Phrasea\Controller\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Api\V1; use Alchemy\Phrasea\Model\Entities\ApiAccount; use Alchemy\Phrasea\Model\Entities\ApiApplication; use Alchemy\Phrasea\Model\Entities\User; diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php index 5bee91e76c..7007879dab 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php @@ -2,7 +2,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Admin; -use Alchemy\Phrasea\Controller\Admin\ConnectedUsers; +use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; class ConnectedUserTest extends \PhraseanetAuthenticatedWebTestCase { diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php index f473a7e34e..8ca5b4d93c 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Api/ApiTestCase.php @@ -4,7 +4,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Api; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Border\File; -use Alchemy\Phrasea\Controller\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Api\V1; use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Authentication\Context; use Alchemy\Phrasea\Model\Entities\LazaretSession; diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Api/ResultTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Api/ResultTest.php index 4911d99418..a8a2c1a3a8 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Api/ResultTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Api/ResultTest.php @@ -3,7 +3,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Api; use Alchemy\Phrasea\Controller\Api\Result; -use Alchemy\Phrasea\Controller\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Api\V1; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Yaml\Parser; diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Prod/ShareTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Prod/ShareTest.php index 72c3ef3f0a..e789ea40f7 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Prod/ShareTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Prod/ShareTest.php @@ -2,7 +2,7 @@ namespace Alchemy\Tests\Phrasea\Controller\Prod; -use Alchemy\Phrasea\Controller\Prod\Share; +use Alchemy\Phrasea\ControllerProvider\Prod\Share; class ShareTest extends \PhraseanetAuthenticatedWebTestCase { diff --git a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php index 5a0cd3203b..aaf276495d 100644 --- a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php @@ -2,7 +2,7 @@ namespace Alchemy\Tests\Phrasea\Model\Manipulator; -use Alchemy\Phrasea\Controller\Api\V1; +use Alchemy\Phrasea\ControllerProvider\Api\V1; use Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator; class ApiAccountManipulatorTest extends \PhraseanetTestCase From bf27dcff20786c788643e3c4d040d6b8c924895e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 12:58:07 +0100 Subject: [PATCH 04/26] Remove useless Dependency --- .../Provider/ManipulatorServiceProvider.php | 2 +- .../Manipulator/ApiAccountManipulator.php | 5 +-- .../Manipulator/ApiAccountManipulatorTest.php | 33 +++++++++++-------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php index b75c97ea6f..0320e8f22c 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/ManipulatorServiceProvider.php @@ -66,7 +66,7 @@ class ManipulatorServiceProvider implements ServiceProviderInterface }); $app['manipulator.api-account'] = $app->share(function ($app) { - return new ApiAccountManipulator($app['orm.em'], $app['repo.api-accounts']); + return new ApiAccountManipulator($app['orm.em']); }); $app['manipulator.api-oauth-code'] = $app->share(function ($app) { diff --git a/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php index 5598f290ee..86fdd4a7a2 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php @@ -16,17 +16,14 @@ use Alchemy\Phrasea\Model\Entities\ApiAccount; use Alchemy\Phrasea\Model\Entities\ApiApplication; use Alchemy\Phrasea\Model\Entities\User; use Doctrine\Common\Persistence\ObjectManager; -use Doctrine\ORM\EntityRepository; class ApiAccountManipulator implements ManipulatorInterface { private $om; - private $repository; - public function __construct(ObjectManager $om, EntityRepository $repo) + public function __construct(ObjectManager $om) { $this->om = $om; - $this->repository = $repo; } public function create(ApiApplication $application, User $user) diff --git a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php index aaf276495d..c21a870a2c 100644 --- a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php @@ -7,11 +7,20 @@ use Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator; class ApiAccountManipulatorTest extends \PhraseanetTestCase { + /** @var ApiAccountManipulator */ + private $sut; + + public function setUp() + { + parent::setUp(); + + $this->sut = new ApiAccountManipulator(self::$DI['app']['orm.em']); + } + public function testCreate() { - $manipulator = new ApiAccountManipulator(self::$DI['app']['orm.em'], self::$DI['app']['repo.api-accounts']); $nbApps = count(self::$DI['app']['repo.api-accounts']->findAll()); - $account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']); + $account = $this->sut->create(self::$DI['oauth2-app-user'], self::$DI['user']); $this->assertGreaterThan($nbApps, count(self::$DI['app']['repo.api-accounts']->findAll())); $this->assertFalse($account->isRevoked()); $this->assertEquals(V1::VERSION, $account->getApiVersion()); @@ -20,12 +29,11 @@ class ApiAccountManipulatorTest extends \PhraseanetTestCase public function testDelete() { - $manipulator = new ApiAccountManipulator(self::$DI['app']['orm.em'], self::$DI['app']['repo.api-accounts']); - $account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']); + $account = $this->sut->create(self::$DI['oauth2-app-user'], self::$DI['user']); $accountMem = clone $account; $countBefore = count(self::$DI['app']['repo.api-accounts']->findAll()); self::$DI['app']['manipulator.api-oauth-token']->create($account); - $manipulator->delete($account); + $this->sut->delete($account); $this->assertGreaterThan(count(self::$DI['app']['repo.api-accounts']->findAll()), $countBefore); $tokens = self::$DI['app']['repo.api-oauth-tokens']->findOauthTokens($accountMem); $this->assertEquals(0, count($tokens)); @@ -33,27 +41,24 @@ class ApiAccountManipulatorTest extends \PhraseanetTestCase public function testUpdate() { - $manipulator = new ApiAccountManipulator(self::$DI['app']['orm.em'], self::$DI['app']['repo.api-accounts']); - $account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']); + $account = $this->sut->create(self::$DI['oauth2-app-user'], self::$DI['user']); $account->setApiVersion(24); - $manipulator->update($account); + $this->sut->update($account); $account = self::$DI['app']['repo.api-accounts']->find($account->getId()); $this->assertEquals(24, $account->getApiVersion()); } public function testAuthorizeAccess() { - $manipulator = new ApiAccountManipulator(self::$DI['app']['orm.em'], self::$DI['app']['repo.api-accounts']); - $account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']); - $manipulator->authorizeAccess($account); + $account = $this->sut->create(self::$DI['oauth2-app-user'], self::$DI['user']); + $this->sut->authorizeAccess($account); $this->assertFalse($account->isRevoked()); } public function testRevokeAccess() { - $manipulator = new ApiAccountManipulator(self::$DI['app']['orm.em'], self::$DI['app']['repo.api-accounts']); - $account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']); - $manipulator->revokeAccess($account); + $account = $this->sut->create(self::$DI['oauth2-app-user'], self::$DI['user']); + $this->sut->revokeAccess($account); $this->assertTrue($account->isRevoked()); } } From ad51a350b7f3588687405d44acbf473080a07e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 13:42:31 +0100 Subject: [PATCH 05/26] Change content type negotiation in API. Fix typo in negotiator word. --- lib/Alchemy/Phrasea/Application/Api.php | 13 ++++++++----- .../Subscriber/ContentNegotiationSubscriber.php | 2 +- .../Provider/ContentNegotiationServiceProvider.php | 6 +++--- .../ContentNegotiationServiceProviderTest.php | 6 +++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index d8b86ac541..b1d6b04425 100644 --- a/lib/Alchemy/Phrasea/Application/Api.php +++ b/lib/Alchemy/Phrasea/Application/Api.php @@ -51,11 +51,14 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { $request->setFormat(Result::FORMAT_JSONP_EXTENDED, V1::$extendedContentTypes['jsonp']); $request->setFormat(Result::FORMAT_JSONP, array('text/javascript', 'application/javascript')); - // handle content negociation - $priorities = array('application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript'); - foreach (V1::$extendedContentTypes['json'] as $priorities[]); - foreach (V1::$extendedContentTypes['yaml'] as $priorities[]); - $format = $app['format.negociator']->getBest($request->headers->get('accept', 'application/json') ,$priorities); + $format = $app['format.negotiator']->getBest( + $request->headers->get('accept', 'application/json'), + array_merge( + ['application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript'], + V1::$extendedContentTypes['json'], + V1::$extendedContentTypes['yaml'] + ) + ); // throw unacceptable http error if API can not handle asked format if (null === $format) { diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php index 305fe27ddb..9e11b71cdd 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php @@ -39,7 +39,7 @@ class ContentNegotiationSubscriber implements EventSubscriberInterface public function onKernelRequest(GetResponseEvent $event) { $priorities = array('text/html', 'application/json', '*/*'); - $format = $this->app['format.negociator']->getBest($event->getRequest()->headers->get('accept', '*/*'), $priorities); + $format = $this->app['format.negotiator']->getBest($event->getRequest()->headers->get('accept', '*/*'), $priorities); if (null === $format) { $this->app->abort(406, 'Not acceptable'); diff --git a/lib/Alchemy/Phrasea/Core/Provider/ContentNegotiationServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/ContentNegotiationServiceProvider.php index c702f2d190..54e38cf88a 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/ContentNegotiationServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/ContentNegotiationServiceProvider.php @@ -21,15 +21,15 @@ class ContentNegotiationServiceProvider implements ServiceProviderInterface { public function register(Application $app) { - $app['negociator'] = $app->share(function ($app) { + $app['negotiator'] = $app->share(function ($app) { return new Negotiator(); }); - $app['format.negociator'] = $app->share(function ($app) { + $app['format.negotiator'] = $app->share(function ($app) { return new FormatNegotiator(); }); - $app['langage.negociator'] = $app->share(function ($app) { + $app['langage.negotiator'] = $app->share(function ($app) { return new LanguageNegotiator(); }); } diff --git a/tests/Alchemy/Tests/Phrasea/Core/Provider/ContentNegotiationServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/Provider/ContentNegotiationServiceProviderTest.php index 79defe4d14..c0bdde5845 100644 --- a/tests/Alchemy/Tests/Phrasea/Core/Provider/ContentNegotiationServiceProviderTest.php +++ b/tests/Alchemy/Tests/Phrasea/Core/Provider/ContentNegotiationServiceProviderTest.php @@ -12,17 +12,17 @@ class classContentNegotiationServiceProviderTest extends ServiceProviderTestCase return array( array( 'Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider', - 'negociator', + 'negotiator', 'Negotiation\Negotiator', ), array( 'Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider', - 'format.negociator', + 'format.negotiator', 'Negotiation\FormatNegotiator' ), array( 'Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider', - 'langage.negociator', + 'langage.negotiator', 'Negotiation\LanguageNegotiator' ) ); From 7b7b99e476ba78da276dec38e53c57d11f280b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 16:37:57 +0100 Subject: [PATCH 06/26] Prepare PhraseaApplication for ControllerProvider split --- lib/Alchemy/Phrasea/Application.php | 83 ++++++++++++++++------------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 9c245e0ce0..c076f84a64 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -11,9 +11,7 @@ namespace Alchemy\Phrasea; -use Alchemy\Phrasea\ControllerProvider\Lightbox; -use Alchemy\Phrasea\ControllerProvider\Datafiles; -use Alchemy\Phrasea\ControllerProvider\Permalink; +use Alchemy\Geonames\GeonamesServiceProvider; use Alchemy\Phrasea\ControllerProvider\Admin\Collection; use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; use Alchemy\Phrasea\ControllerProvider\Admin\Dashboard; @@ -22,17 +20,20 @@ use Alchemy\Phrasea\ControllerProvider\Admin\Databoxes; use Alchemy\Phrasea\ControllerProvider\Admin\Fields; use Alchemy\Phrasea\ControllerProvider\Admin\Publications; use Alchemy\Phrasea\ControllerProvider\Admin\Root as AdminRoot; -use Alchemy\Phrasea\ControllerProvider\Admin\Setup; use Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine; +use Alchemy\Phrasea\ControllerProvider\Admin\Setup; use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; use Alchemy\Phrasea\ControllerProvider\Admin\Users; use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; +use Alchemy\Phrasea\ControllerProvider\Datafiles; +use Alchemy\Phrasea\ControllerProvider\Lightbox; use Alchemy\Phrasea\ControllerProvider\Minifier; +use Alchemy\Phrasea\ControllerProvider\Permalink; use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; -use Alchemy\Phrasea\ControllerProvider\Prod\Download; use Alchemy\Phrasea\ControllerProvider\Prod\DoDownload; +use Alchemy\Phrasea\ControllerProvider\Prod\Download; use Alchemy\Phrasea\ControllerProvider\Prod\Edit; use Alchemy\Phrasea\ControllerProvider\Prod\Export; use Alchemy\Phrasea\ControllerProvider\Prod\Feed; @@ -41,9 +42,9 @@ use Alchemy\Phrasea\ControllerProvider\Prod\Lazaret; use Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection; use Alchemy\Phrasea\ControllerProvider\Prod\Order; use Alchemy\Phrasea\ControllerProvider\Prod\Printer; +use Alchemy\Phrasea\ControllerProvider\Prod\Property; use Alchemy\Phrasea\ControllerProvider\Prod\Push; use Alchemy\Phrasea\ControllerProvider\Prod\Query; -use Alchemy\Phrasea\ControllerProvider\Prod\Property; use Alchemy\Phrasea\ControllerProvider\Prod\Records; use Alchemy\Phrasea\ControllerProvider\Prod\Root as Prod; use Alchemy\Phrasea\ControllerProvider\Prod\Share; @@ -74,29 +75,28 @@ use Alchemy\Phrasea\Core\Event\Subscriber\ExportSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\FeedEntrySubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\LazaretSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\OrderSubscriber; +use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaInstallSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\RegistrationSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ValidationSubscriber; -use Alchemy\Phrasea\Core\Middleware\TokenMiddlewareProvider; -use Alchemy\Phrasea\Core\PhraseaExceptionHandler; -use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaInstallSubscriber; use Alchemy\Phrasea\Core\Middleware\ApiApplicationMiddlewareProvider; use Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider; +use Alchemy\Phrasea\Core\Middleware\TokenMiddlewareProvider; +use Alchemy\Phrasea\Core\PhraseaExceptionHandler; use Alchemy\Phrasea\Core\Provider\ACLServiceProvider; use Alchemy\Phrasea\Core\Provider\APIServiceProvider; use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider; -use Alchemy\Phrasea\Core\Provider\BrowserServiceProvider; use Alchemy\Phrasea\Core\Provider\BorderManagerServiceProvider; -use Alchemy\Phrasea\Core\Provider\CacheServiceProvider; +use Alchemy\Phrasea\Core\Provider\BrowserServiceProvider; use Alchemy\Phrasea\Core\Provider\CacheConnectionServiceProvider; +use Alchemy\Phrasea\Core\Provider\CacheServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider; use Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider; -use Alchemy\Phrasea\Core\Provider\CSVServiceProvider; use Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider; -use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider; +use Alchemy\Phrasea\Core\Provider\CSVServiceProvider; use Alchemy\Phrasea\Core\Provider\FeedServiceProvider; +use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider; use Alchemy\Phrasea\Core\Provider\FtpServiceProvider; -use Alchemy\Geonames\GeonamesServiceProvider; use Alchemy\Phrasea\Core\Provider\InstallerServiceProvider; use Alchemy\Phrasea\Core\Provider\JMSSerializerServiceProvider; use Alchemy\Phrasea\Core\Provider\LocaleServiceProvider; @@ -105,8 +105,8 @@ use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider; use Alchemy\Phrasea\Core\Provider\ORMServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseaEventServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider; -use Alchemy\Phrasea\Core\Provider\PluginServiceProvider; use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider; +use Alchemy\Phrasea\Core\Provider\PluginServiceProvider; use Alchemy\Phrasea\Core\Provider\RandomGeneratorServiceProvider; use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider; use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider; @@ -122,53 +122,50 @@ use Alchemy\Phrasea\Core\Provider\TranslationServiceProvider; use Alchemy\Phrasea\Core\Provider\UnicodeServiceProvider; use Alchemy\Phrasea\Core\Provider\ZippyServiceProvider; use Alchemy\Phrasea\Exception\InvalidArgumentException; -use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Form\Extension\HelpTypeExtension; -use Alchemy\Phrasea\Twig\JSUniqueID; -use Alchemy\Phrasea\Twig\Fit; -use Alchemy\Phrasea\Twig\Camelize; +use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Twig\BytesConverter; +use Alchemy\Phrasea\Twig\Camelize; +use Alchemy\Phrasea\Twig\Fit; +use Alchemy\Phrasea\Twig\JSUniqueID; use Alchemy\Phrasea\Twig\PhraseanetExtension; use Alchemy\Phrasea\Utilities\CachedTranslator; use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider; use FFMpeg\FFMpegServiceProvider; use Gedmo\DoctrineExtensions as GedmoExtension; +use MediaAlchemyst\MediaAlchemystServiceProvider; +use MediaVorus\MediaVorusServiceProvider; +use Monolog\Handler\NullHandler; use Monolog\Logger; use Monolog\Processor\IntrospectionProcessor; -use Neutron\Silex\Provider\ImagineServiceProvider; -use MediaVorus\MediaVorusServiceProvider; -use MediaAlchemyst\MediaAlchemystServiceProvider; -use Monolog\Handler\NullHandler; use MP4Box\MP4BoxServiceProvider; -use Neutron\Silex\Provider\FilesystemServiceProvider; use Neutron\ReCaptcha\ReCaptchaServiceProvider; +use Neutron\Silex\Provider\FilesystemServiceProvider; +use Neutron\Silex\Provider\ImagineServiceProvider; use PHPExiftool\PHPExiftoolServiceProvider; use Silex\Application as SilexApplication; -use Silex\Application\UrlGeneratorTrait; use Silex\Application\TranslationTrait; +use Silex\Application\UrlGeneratorTrait; use Silex\Provider\DoctrineServiceProvider; use Silex\Provider\FormServiceProvider; use Silex\Provider\MonologServiceProvider; +use Silex\Provider\ServiceControllerServiceProvider; use Silex\Provider\SessionServiceProvider; -use Silex\Provider\TwigServiceProvider; use Silex\Provider\SwiftmailerServiceProvider; +use Silex\Provider\TwigServiceProvider; use Silex\Provider\UrlGeneratorServiceProvider; use Silex\Provider\ValidatorServiceProvider; -use Silex\Provider\ServiceControllerServiceProvider; +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Component\Form\Exception\FormException; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormTypeInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; -use Symfony\Bridge\Twig\Extension\TranslationExtension; use Unoconv\UnoconvServiceProvider; use XPDF\PdfToText; use XPDF\XPDFServiceProvider; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\Form\FormTypeInterface; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\Exception\FormException; class Application extends SilexApplication { @@ -319,6 +316,12 @@ class Application extends SilexApplication return $handler; }); + + $providers = [ + ]; + foreach ($providers as $class => $values) { + $this->register(new $class, $values); + } } /** @@ -379,7 +382,7 @@ class Application extends SilexApplication public function setupTwig() { $this['twig'] = $this->share( - $this->extend('twig', function ($twig, $app) { + $this->extend('twig', function (\Twig_Environment $twig, $app) { $twig->setCache($app['cache.path'].'/twig'); $paths = require $app['plugin.path'] . '/twig-paths.php'; @@ -679,6 +682,12 @@ class Application extends SilexApplication $this->mount('/permalink/', new Permalink()); $this->mount('/lightbox/', new Lightbox()); + + $providers = [ + ]; + foreach ($providers as $prefix => $class) { + $this->mount($prefix, new $class); + } } /** From c2e458faaa0248c05432c84742a7a0f62936801f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 16:41:24 +0100 Subject: [PATCH 07/26] Split Datafile and Permalink --- lib/Alchemy/Phrasea/Application.php | 9 +- .../Phrasea/Controller/AbstractDelivery.php | 39 +++- .../Phrasea/Controller/DatafileController.php | 108 +++++++++ .../Controller/PermalinkController.php | 181 +++++++++++++++ .../Phrasea/ControllerProvider/Datafiles.php | 90 ++------ .../Phrasea/ControllerProvider/Permalink.php | 214 +++++------------- 6 files changed, 390 insertions(+), 251 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/DatafileController.php create mode 100644 lib/Alchemy/Phrasea/Controller/PermalinkController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index c076f84a64..8dc2d99217 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -26,10 +26,8 @@ use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; use Alchemy\Phrasea\ControllerProvider\Admin\Users; use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; -use Alchemy\Phrasea\ControllerProvider\Datafiles; use Alchemy\Phrasea\ControllerProvider\Lightbox; use Alchemy\Phrasea\ControllerProvider\Minifier; -use Alchemy\Phrasea\ControllerProvider\Permalink; use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; use Alchemy\Phrasea\ControllerProvider\Prod\DoDownload; @@ -318,6 +316,8 @@ class Application extends SilexApplication }); $providers = [ + 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], + 'Alchemy\Phrasea\ControllerProvider\Permalink' => [], ]; foreach ($providers as $class => $values) { $this->register(new $class, $values); @@ -620,8 +620,6 @@ class Application extends SilexApplication $this->mount('/login/', new Login()); $this->mount('/developers/', new Developers()); - $this->mount('/datafiles/', new Datafiles()); - $this->mount('/admin/', new AdminRoot()); $this->mount('/admin/dashboard', new Dashboard()); $this->mount('/admin/collection', new Collection()); @@ -679,11 +677,12 @@ class Application extends SilexApplication $this->mount('/xmlhttp', new ThesaurusXMLHttp()); $this->mount('/include/minify/', new Minifier()); - $this->mount('/permalink/', new Permalink()); $this->mount('/lightbox/', new Lightbox()); $providers = [ + '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', + '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', ]; foreach ($providers as $prefix => $class) { $this->mount($prefix, new $class); diff --git a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php index a25d763cc2..f26efa7fb0 100644 --- a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php +++ b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php @@ -13,36 +13,47 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Http\DeliverDataInterface; +use Session_Logger; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; abstract class AbstractDelivery { - public function deliverContent(Request $request, \record_adapter $record, $subdef, $watermark, $stamp, Application $app) + /** @var Application */ + protected $app; + + public function __construct(Application $app) + { + $this->app = $app; + } + + public function deliverContent(Request $request, \record_adapter $record, $subdef, $watermark, $stamp) { $file = $record->get_subdef($subdef); $pathOut = $file->get_pathfile(); if ($watermark === true && $file->get_type() === \media_subdef::TYPE_IMAGE) { - $pathOut = \recordutils_image::watermark($app, $file); + $pathOut = \recordutils_image::watermark($this->app, $file); } elseif ($stamp === true && $file->get_type() === \media_subdef::TYPE_IMAGE) { - $pathOut = \recordutils_image::stamp($app, $file); + $pathOut = \recordutils_image::stamp($this->app, $file); } $disposition = $request->query->get('download') ? DeliverDataInterface::DISPOSITION_ATTACHMENT : DeliverDataInterface::DISPOSITION_INLINE; - $response = $app['phraseanet.file-serve']->deliverFile($pathOut, $file->get_file(), $disposition, $file->get_mime()); + /** @var Response $response */ + $response = $this->app['phraseanet.file-serve']->deliverFile($pathOut, $file->get_file(), $disposition, $file->get_mime()); if (in_array($subdef, array('document', 'preview'))) { $response->setPrivate(); - $this->logView($app, $record, $request); + $this->logView($this->app, $record, $request); } elseif ($subdef !== 'thumbnail') { try { if ($file->getDataboxSubdef()->get_class() != \databox_subdef::CLASS_THUMBNAIL) { $response->setPrivate(); - $this->logView($app, $record, $request); + $this->logView($this->app, $record, $request); } } catch (\Exception $e) { - + // Ignore exception } } @@ -51,14 +62,20 @@ abstract class AbstractDelivery return $response; } - private function logView(Application $app, \record_adapter $record, Request $request) + private function logView(\record_adapter $record, Request $request) { try { - $logger = $app['phraseanet.logger']($record->get_databox()); + /** @var Session_Logger $logger */ + $logger = $this->app['phraseanet.logger']($record->get_databox()); $log_id = $logger->get_id(); - $record->log_view($log_id, $request->headers->get('referer', 'NO REFERRER'), $app['phraseanet.configuration']['main']['key']); + $record->log_view( + $log_id, + $request->headers->get('referer', 'NO REFERRER'), + $this->app['phraseanet.configuration']['main']['key'] + ) + ; } catch (\Exception $e) { - + // Ignore exception } } } diff --git a/lib/Alchemy/Phrasea/Controller/DatafileController.php b/lib/Alchemy/Phrasea/Controller/DatafileController.php new file mode 100644 index 0000000000..2451c4968b --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/DatafileController.php @@ -0,0 +1,108 @@ +appbox = $appbox; + $this->acl = $acl; + $this->authentication = $authenticator; + } + + public function getAction(Request $request, $sbas_id, $record_id, $subdef) + { + $databox = $this->appbox->get_databox((int) $sbas_id); + $record = new \record_adapter($this->app, $sbas_id, $record_id); + + $stamp = $watermark = false; + + if ($subdef != 'thumbnail') { + $all_access = false; + $subdefStruct = $databox->get_subdef_structure(); + + if ($subdefStruct->getSubdefGroup($record->get_type())) { + foreach ($subdefStruct->getSubdefGroup($record->get_type()) as $subdefObj) { + /** @var \databox_subdef $subdefObj */ + if ($subdefObj->get_name() == $subdef) { + if ($subdefObj->get_class() == 'thumbnail') { + $all_access = true; + } + break; + } + } + } + + if (!$record->has_subdef($subdef) || !$record->get_subdef($subdef)->is_physically_present()) { + throw new NotFoundHttpException; + } + + if (!$this->acl->get($this->authentication->getUser())->has_access_to_subdef($record, $subdef)) { + throw new AccessDeniedHttpException(sprintf('User has not access to subdef %s', $subdef)); + } + + $stamp = false; + $watermark = !$this->acl->get($this->authentication->getUser()) + ->has_right_on_base($record->get_base_id(), 'nowatermark'); + + if ($watermark && !$all_access) { + $subdef_class = null; + try { + $subdef_class = $databox + ->get_subdef_structure() + ->get_subdef($record->get_type(), $subdef) + ->get_class(); + } catch (\Exception_Databox_SubdefNotFound $e) { + + } + + if ($subdef_class == \databox_subdef::CLASS_PREVIEW && $this->acl->get($this->authentication->getUser())->has_preview_grant($record)) { + $watermark = false; + } elseif ($subdef_class == \databox_subdef::CLASS_DOCUMENT && $this->acl->get( + $this->authentication->getUser())->has_hd_grant($record)) { + $watermark = false; + } + } + + if ($watermark && !$all_access) { + $repository = $this->app['repo.basket-elements']; + + $ValidationByRecord = $repository->findReceivedValidationElementsByRecord($record, $this->authentication->getUser()); + $ReceptionByRecord = $repository->findReceivedElementsByRecord($record, $this->authentication->getUser()); + + if ($ValidationByRecord && count($ValidationByRecord) > 0) { + $watermark = false; + } elseif ($ReceptionByRecord && count($ReceptionByRecord) > 0) { + $watermark = false; + } + } + } + + return $this->deliverContent($request, $record, $subdef, $watermark, $stamp); + } +} diff --git a/lib/Alchemy/Phrasea/Controller/PermalinkController.php b/lib/Alchemy/Phrasea/Controller/PermalinkController.php new file mode 100644 index 0000000000..dc7c23a10e --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/PermalinkController.php @@ -0,0 +1,181 @@ +appbox = $appbox; + $this->acl = $acl; + $this->authentication = $authenticator; + } + + public function getOptionsResponse(Request $request, $sbas_id, $record_id) + { + $databox = $this->getDatabox($sbas_id); + $token = $request->query->get('token'); + $record = $this->retrieveRecord($databox, $token, $record_id, $request->get('subdef', 'thumbnail')); + + if (null === $record) { + throw new NotFoundHttpException("Record not found"); + } + + return new Response('', 200, ['Allow' => 'GET, HEAD, OPTIONS']); + } + + public function deliverCaption(Request $request, $sbas_id, $record_id) + { + $databox = $this->getDatabox($sbas_id); + $token = $request->query->get('token'); + $record = $this->retrieveRecord($this->app, $databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL); + + if (null === $record) { + throw new NotFoundHttpException("Caption not found"); + } + $caption = $record->get_caption(); + + return new Response($this->app['serializer.caption']->serialize($caption, CaptionSerializer::SERIALIZE_JSON), 200, ["Content-Type" => 'application/json']); + } + + public function deliverPermaview(Request $request, $sbas_id, $record_id, $subdef) + { + return $this->doDeliverPermaview($request, $sbas_id, $record_id, $request->query->get('token'), $subdef); + } + + public function deliverPermaviewOldWay(Request $request, $sbas_id, $record_id, $token, $subdef) + { + return $this->doDeliverPermaview($request, $sbas_id, $record_id, $token, $subdef); + } + + public function deliverPermalink(Request $request, $sbas_id, $record_id, $subdef) + { + return $this->doDeliverPermalink($request, $sbas_id, $record_id, $request->query->get('token'), $subdef); + } + + public function deliverPermalinkOldWay(Request $request, $sbas_id, $record_id, $token, $subdef) + { + return $this->doDeliverPermalink($request, $sbas_id, $record_id, $token, $subdef); + } + + /** + * @param \databox $databox + * @param $token + * @param $record_id + * @param string $subdef + * @return \record_adapter + */ + private function retrieveRecord(\databox $databox, $token, $record_id, $subdef) + { + if (in_array($subdef, [\databox_subdef::CLASS_PREVIEW, \databox_subdef::CLASS_THUMBNAIL]) + && $this->app['repo.feed-items']->isRecordInPublicFeed($this->app, $databox->get_sbas_id(), $record_id) + ) { + return $databox->get_record($record_id); + } + + $record = \media_Permalink_Adapter::challenge_token($this->app, $databox, $token, $record_id, $subdef); + + if (!($record instanceof \record_adapter)) { + throw new NotFoundHttpException('Wrong token.'); + } + + return $record; + } + + private function doDeliverPermaview($sbas_id, $record_id, $token, $subdef) + { + $databox = $this->getDatabox($sbas_id); + $record = $this->retrieveRecord($databox, $token, $record_id, $subdef); + + return $this->app['twig']->render('overview.html.twig', [ + 'subdef_name' => $subdef, + 'module_name' => 'overview', + 'module' => 'overview', + 'view' => 'overview', + 'record' => $record, + ]); + } + + private function doDeliverPermalink(Request $request, $sbas_id, $record_id, $token, $subdef) + { + $databox = $this->getDatabox($sbas_id); + $record = $this->retrieveRecord($databox, $token, $record_id, $subdef); + + $watermark = $stamp = false; + + if ($this->authentication->isAuthenticated()) { + $watermark = !$this->acl->get($this->authentication->getUser())->has_right_on_base($record->get_base_id(), 'nowatermark'); + + if ($watermark) { + $repository = $this->app['repo.basket-elements']; + + if (count($repository->findReceivedValidationElementsByRecord($record, $this->authentication->getUser())) > 0) { + $watermark = false; + } elseif (count($repository->findReceivedElementsByRecord($record, $this->authentication->getUser())) > 0) { + $watermark = false; + } + } + $response = $this->deliverContent($request, $record, $subdef, $watermark, $stamp); + + $linkToCaption = $this->app->url("permalinks_caption", ['sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token]); + $response->headers->set('Link', $linkToCaption); + + return $response; + } + + $collection = \collection::get_from_base_id($this->app, $record->get_base_id()); + switch ($collection->get_pub_wm()) { + default: + case 'none': + $watermark = false; + break; + case 'stamp': + $stamp = true; + break; + case 'wm': + $watermark = true; + break; + } + + $response = $this->deliverContent($request, $record, $subdef, $watermark, $stamp); + + $linkToCaption = $this->app->url("permalinks_caption", ['sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token]); + $response->headers->set('Link', $linkToCaption); + + return $response; + } + + /** + * @param int $databoxId + * @return \databox + */ + private function getDatabox($databoxId) + { + return $this->appbox->get_databox((int)$databoxId); + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php index 9b313fd03a..2d30735360 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php @@ -11,96 +11,36 @@ namespace Alchemy\Phrasea\ControllerProvider; -use Alchemy\Phrasea\Application as PhraseaApplication; -use Alchemy\Phrasea\Controller\AbstractDelivery; +use Alchemy\Phrasea\Controller\DatafileController; use Silex\Application; use Silex\ControllerProviderInterface; +use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class Datafiles extends AbstractDelivery implements ControllerProviderInterface +class Datafiles implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.datafiles'] = $app->share(function () use ($app) { + return new DatafileController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.datafiles'] = $this; - $controllers = $app['controllers_factory']; - $that = $this; - $controllers->before(function (Request $request) use ($app) { if (!$app['authentication']->isAuthenticated()) { $app->abort(403, sprintf('You are not authorized to access %s', $request->getRequestUri())); } }); - $controllers->get('/{sbas_id}/{record_id}/{subdef}/', function ($sbas_id, $record_id, $subdef, PhraseaApplication $app) use ($that) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $record = new \record_adapter($app, $sbas_id, $record_id); - - $stamp = $watermark = false; - - if ($subdef != 'thumbnail') { - $all_access = false; - $subdefStruct = $databox->get_subdef_structure(); - - if ($subdefStruct->getSubdefGroup($record->get_type())) { - foreach ($subdefStruct->getSubdefGroup($record->get_type()) as $subdefObj) { - if ($subdefObj->get_name() == $subdef) { - if ($subdefObj->get_class() == 'thumbnail') { - $all_access = true; - } - break; - } - } - } - - if (!$record->has_subdef($subdef) || !$record->get_subdef($subdef)->is_physically_present()) { - throw new NotFoundHttpException; - } - - if (!$app['acl']->get($app['authentication']->getUser())->has_access_to_subdef($record, $subdef)) { - throw new AccessDeniedHttpException(sprintf('User has not access to subdef %s', $subdef)); - } - - $stamp = false; - $watermark = !$app['acl']->get($app['authentication']->getUser())->has_right_on_base($record->get_base_id(), 'nowatermark'); - - if ($watermark && !$all_access) { - $subdef_class = null; - try { - $subdef_class = $databox - ->get_subdef_structure() - ->get_subdef($record->get_type(), $subdef) - ->get_class(); - } catch (\Exception_Databox_SubdefNotFound $e) { - - } - - if ($subdef_class == \databox_subdef::CLASS_PREVIEW && $app['acl']->get($app['authentication']->getUser())->has_preview_grant($record)) { - $watermark = false; - } elseif ($subdef_class == \databox_subdef::CLASS_DOCUMENT && $app['acl']->get($app['authentication']->getUser())->has_hd_grant($record)) { - $watermark = false; - } - } - - if ($watermark && !$all_access) { - $repository = $app['repo.basket-elements']; - - $ValidationByRecord = $repository->findReceivedValidationElementsByRecord($record, $app['authentication']->getUser()); - $ReceptionByRecord = $repository->findReceivedElementsByRecord($record, $app['authentication']->getUser()); - - if ($ValidationByRecord && count($ValidationByRecord) > 0) { - $watermark = false; - } elseif ($ReceptionByRecord && count($ReceptionByRecord) > 0) { - $watermark = false; - } - } - } - - return $that->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app); - }) + $controllers->get('/{sbas_id}/{record_id}/{subdef}/', 'controller.datafiles:getAction') ->bind('datafile') ->assert('sbas_id', '\d+') ->assert('record_id', '\d+'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php index 9dc9a44476..6c59c324ab 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php @@ -12,188 +12,82 @@ namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application as PhraseaApplication; -use Alchemy\Phrasea\Controller\AbstractDelivery; -use Alchemy\Phrasea\Model\Serializer\CaptionSerializer; +use Alchemy\Phrasea\Controller\PermalinkController; use Silex\Application; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Silex\ServiceProviderInterface; -class Permalink extends AbstractDelivery implements ControllerProviderInterface +class Permalink implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.permalink'] = $app->share(function () use ($app) { + return new PermalinkController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.permalink'] = $this; - $controllers = $app['controllers_factory']; $controllers->get('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:deliverCaption') - ->assert('sbas_id', '\d+')->assert('record_id', '\d+') - ->bind('permalinks_caption'); + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ->bind('permalinks_caption') + ; $controllers->match('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:getOptionsResponse') - ->assert('sbas_id', '\d+')->assert('record_id', '\d+') - ->method('OPTIONS'); + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ->method('OPTIONS') + ; $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:deliverPermaview') - ->bind('permalinks_permaview') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + ->bind('permalinks_permaview') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:getOptionsResponse') - ->method('OPTIONS') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + ->method('OPTIONS') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; - $controllers->get('/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/view/', 'controller.permalink:deliverPermaviewOldWay') - ->bind('permalinks_permaview_old') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + $controllers->get( + '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/view/', + 'controller.permalink:deliverPermaviewOldWay' + ) + ->bind('permalinks_permaview_old') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:deliverPermalink') - ->bind('permalinks_permalink') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + ->bind('permalinks_permalink') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:getOptionsResponse') - ->method('OPTIONS') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + ->method('OPTIONS') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; - $controllers->get('/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/', 'controller.permalink:deliverPermalinkOldWay') - ->bind('permalinks_permalink_old') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); + $controllers->get( + '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/', + 'controller.permalink:deliverPermalinkOldWay' + ) + ->bind('permalinks_permalink_old') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+') + ; return $controllers; } - - public function getOptionsResponse(PhraseaApplication $app, Request $request, $sbas_id, $record_id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - $record = $this->retrieveRecord($app, $databox, $request->query->get('token'), $record_id, $request->get('subdef', 'thumbnail')); - - if (null === $record) { - throw new NotFoundHttpException("Record not found"); - } - - return new Response('', 200, ['Allow' => 'GET, HEAD, OPTIONS']); - } - - public function deliverCaption(PhraseaApplication $app, Request $request, $sbas_id, $record_id) - { - $token = $request->query->get('token'); - - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - $record = $this->retrieveRecord($app, $databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL); - if (null === $record) { - throw new NotFoundHttpException("Caption not found"); - } - $caption = $record->get_caption(); - - return new Response($app['serializer.caption']->serialize($caption, CaptionSerializer::SERIALIZE_JSON), 200, ["Content-Type" => 'application/json']); - } - - public function deliverPermaview(PhraseaApplication $app, Request $request, $sbas_id, $record_id, $subdef) - { - return $this->doDeliverPermaview($sbas_id, $record_id, $request->query->get('token'), $subdef, $app); - } - - public function deliverPermaviewOldWay(PhraseaApplication $app, $label, $sbas_id, $record_id, $token, $subdef) - { - return $this->doDeliverPermaview($sbas_id, $record_id, $token, $subdef, $app); - } - - public function deliverPermalink(PhraseaApplication $app, Request $request, $sbas_id, $record_id, $subdef, $label) - { - return $this->doDeliverPermalink($app, $sbas_id, $record_id, $request->query->get('token'), $subdef); - } - - public function deliverPermalinkOldWay(PhraseaApplication $app, $label, $sbas_id, $record_id, $token, $subdef) - { - return $this->doDeliverPermalink($app, $sbas_id, $record_id, $token, $subdef); - } - - private function retrieveRecord($app, $databox, $token, $record_id, $subdef) - { - if (in_array($subdef, [\databox_subdef::CLASS_PREVIEW, \databox_subdef::CLASS_THUMBNAIL]) && $app['repo.feed-items']->isRecordInPublicFeed($app, $databox->get_sbas_id(), $record_id)) { - $record = $databox->get_record($record_id); - } else { - $record = \media_Permalink_Adapter::challenge_token($app, $databox, $token, $record_id, $subdef); - - if (!($record instanceof \record_adapter)) { - throw new NotFoundHttpException('Wrong token.'); - } - } - - return $record; - } - - private function doDeliverPermaview($sbas_id, $record_id, $token, $subdef, PhraseaApplication $app) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - $record = $this->retrieveRecord($app, $databox, $token, $record_id, $subdef); - - return $app['twig']->render('overview.html.twig', [ - 'subdef_name' => $subdef, - 'module_name' => 'overview', - 'module' => 'overview', - 'view' => 'overview', - 'record' => $record, - ]); - } - - private function doDeliverPermalink(PhraseaApplication $app, $sbas_id, $record_id, $token, $subdef) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - $record = $this->retrieveRecord($app, $databox, $token, $record_id, $subdef); - - $watermark = $stamp = false; - - if ($app['authentication']->isAuthenticated()) { - $watermark = !$app['acl']->get($app['authentication']->getUser())->has_right_on_base($record->get_base_id(), 'nowatermark'); - - if ($watermark) { - $repository = $app['repo.basket-elements']; - - if (count($repository->findReceivedValidationElementsByRecord($record, $app['authentication']->getUser())) > 0) { - $watermark = false; - } elseif (count($repository->findReceivedElementsByRecord($record, $app['authentication']->getUser())) > 0) { - $watermark = false; - } - } - $response = $this->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app); - - $linkToCaption = $app->url("permalinks_caption", ['sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token]); - $response->headers->set('Link', $linkToCaption); - - return $response; - } - - $collection = \collection::get_from_base_id($app, $record->get_base_id()); - switch ($collection->get_pub_wm()) { - default: - case 'none': - $watermark = false; - break; - case 'stamp': - $stamp = true; - break; - case 'wm': - $watermark = true; - break; - } - - $response = $this->deliverContent($app['request'], $record, $subdef, $watermark, $stamp, $app); - - $linkToCaption = $app->url("permalinks_caption", ['sbas_id' => $sbas_id, 'record_id' => $record_id, 'token' => $token]); - $response->headers->set('Link', $linkToCaption); - - return $response; - } } From 797916734365fe3dcbdc0a35b7ccc7d3591e1d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 17:03:21 +0100 Subject: [PATCH 08/26] Call to logView should not include application --- lib/Alchemy/Phrasea/Controller/AbstractDelivery.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php index f26efa7fb0..9847117929 100644 --- a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php +++ b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php @@ -45,12 +45,12 @@ abstract class AbstractDelivery if (in_array($subdef, array('document', 'preview'))) { $response->setPrivate(); - $this->logView($this->app, $record, $request); + $this->logView($record, $request); } elseif ($subdef !== 'thumbnail') { try { if ($file->getDataboxSubdef()->get_class() != \databox_subdef::CLASS_THUMBNAIL) { $response->setPrivate(); - $this->logView($this->app, $record, $request); + $this->logView($record, $request); } } catch (\Exception $e) { // Ignore exception From fa9d2a7f079385eb238c801836a7c40530e00626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 17:42:18 +0100 Subject: [PATCH 09/26] Some more errors in Permalink controller --- lib/Alchemy/Phrasea/Controller/PermalinkController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/PermalinkController.php b/lib/Alchemy/Phrasea/Controller/PermalinkController.php index dc7c23a10e..37fd8a5cd6 100644 --- a/lib/Alchemy/Phrasea/Controller/PermalinkController.php +++ b/lib/Alchemy/Phrasea/Controller/PermalinkController.php @@ -53,7 +53,7 @@ class PermalinkController extends AbstractDelivery { $databox = $this->getDatabox($sbas_id); $token = $request->query->get('token'); - $record = $this->retrieveRecord($this->app, $databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL); + $record = $this->retrieveRecord($databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL); if (null === $record) { throw new NotFoundHttpException("Caption not found"); @@ -65,12 +65,12 @@ class PermalinkController extends AbstractDelivery public function deliverPermaview(Request $request, $sbas_id, $record_id, $subdef) { - return $this->doDeliverPermaview($request, $sbas_id, $record_id, $request->query->get('token'), $subdef); + return $this->doDeliverPermaview($sbas_id, $record_id, $request->query->get('token'), $subdef); } - public function deliverPermaviewOldWay(Request $request, $sbas_id, $record_id, $token, $subdef) + public function deliverPermaviewOldWay($sbas_id, $record_id, $token, $subdef) { - return $this->doDeliverPermaview($request, $sbas_id, $record_id, $token, $subdef); + return $this->doDeliverPermaview($sbas_id, $record_id, $token, $subdef); } public function deliverPermalink(Request $request, $sbas_id, $record_id, $subdef) From bcf59c560d79c27724113af1a025b560d8e4ccd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 27 Mar 2015 19:13:07 +0100 Subject: [PATCH 10/26] Partial LightboxController refactor --- lib/Alchemy/Phrasea/Application.php | 4 +- .../Phrasea/Controller/LightboxController.php | 121 +++++++++++ .../Phrasea/ControllerProvider/Lightbox.php | 197 +++++++----------- .../Model/Repositories/BasketRepository.php | 8 +- 4 files changed, 198 insertions(+), 132 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/LightboxController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 8dc2d99217..dba22a0f7e 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -317,6 +317,7 @@ class Application extends SilexApplication $providers = [ 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], + 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Permalink' => [], ]; foreach ($providers as $class => $values) { @@ -678,10 +679,9 @@ class Application extends SilexApplication $this->mount('/include/minify/', new Minifier()); - $this->mount('/lightbox/', new Lightbox()); - $providers = [ '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', + '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', ]; foreach ($providers as $prefix => $class) { diff --git a/lib/Alchemy/Phrasea/Controller/LightboxController.php b/lib/Alchemy/Phrasea/Controller/LightboxController.php new file mode 100644 index 0000000000..cf933a6866 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/LightboxController.php @@ -0,0 +1,121 @@ +app = $app; + } + + public function rootAction() + { + try { + \Session_Logger::updateClientInfos($this->app, 6); + } catch (SessionNotFound $e) { + return $this->app->redirectPath('logout'); + } + + /** @var BasketRepository $repository */ + $repository = $this->app['repo.baskets']; + $basket_collection = array_merge( + $repository->findActiveByUser($this->app['authentication']->getUser()), + $repository->findActiveValidationByUser($this->app['authentication']->getUser()) + ); + + $template = 'lightbox/index.html.twig'; + if (!$this->app['browser']->isNewGeneration() && !$this->app['browser']->isMobile()) { + $template = 'lightbox/IE6/index.html.twig'; + } + + return new Response($this->app['twig']->render($template, [ + 'baskets_collection' => $basket_collection, + 'module_name' => 'Lightbox', + 'module' => 'lightbox' + ] + )); + } + + public function ajaxNoteFormAction($sselcont_id) + { + if (!$this->app['browser']->isMobile()) { + return new Response(''); + } + + /** @var BasketElementRepository $basketElementRepository */ + $basketElementRepository = $this->app['repo.basket-elements']; + $basketElement = $basketElementRepository + ->findUserElement($sselcont_id, $this->app['authentication']->getUser()); + + return $this->app['twig']->render('lightbox/note_form.html.twig', [ + 'basket_element' => $basketElement, + 'module_name' => '', + ]); + } + + public function ajaxLoadBasketElementAction($sselcont_id) + { + /** @var BasketElementRepository $repository */ + $repository = $this->app['repo.basket-elements']; + + $basketElement = $repository->findUserElement($sselcont_id, $this->app['authentication']->getUser()); + + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + if ($this->app['browser']->isMobile()) { + $output = $twig->render('lightbox/basket_element.html.twig', [ + 'basket_element' => $basketElement, + 'module_name' => $basketElement->getRecord($this->app)->get_title() + ] + ); + + return new Response($output); + } + + $isNewGenerationBrowser = $this->app['browser']->isNewGeneration(); + $basket = $basketElement->getBasket(); + + $ret = []; + $ret['number'] = $basketElement->getRecord($this->app)->get_number(); + $ret['title'] = $basketElement->getRecord($this->app)->get_title(); + + $ret['preview'] = $twig->render( + 'common/preview.html.twig', + ['record' => $basketElement->getRecord($this->app), 'not_wrapped' => true] + ); + $ret['options_html'] = $twig->render( + $isNewGenerationBrowser ? 'lightbox/sc_options_box.html.twig' : 'lightbox/IE6/sc_options_box.html.twig', + ['basket_element' => $basketElement] + ); + $ret['agreement_html'] = $twig->render( + $isNewGenerationBrowser ? 'lightbox/agreement_box.html.twig' : 'lightbox/IE6/agreement_box.html.twig', + ['basket' => $basket, 'basket_element' => $basketElement] + ); + $ret['selector_html'] = $twig->render('lightbox/selector_box.html.twig', ['basket_element' => $basketElement]); + $ret['note_html'] = $twig->render('lightbox/sc_note.html.twig', ['basket_element' => $basketElement]); + $ret['caption'] = $twig->render( + 'common/caption.html.twig', + ['view' => 'preview', 'record' => $basketElement->getRecord($this->app)] + ); + + return $this->app->json($ret); + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php index 0378f6de37..57f02a5282 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php @@ -11,53 +11,41 @@ namespace Alchemy\Phrasea\ControllerProvider; +use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\Controller\LightboxController; use Alchemy\Phrasea\Core\Event\ValidationEvent; use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\Model\Entities\BasketElement; use Alchemy\Phrasea\Exception\SessionNotFound; use Alchemy\Phrasea\Controller\Exception as ControllerException; +use Alchemy\Phrasea\Model\Entities\Token; use Alchemy\Phrasea\Model\Manipulator\TokenManipulator; use Silex\ControllerProviderInterface; -use Silex\Application as SilexApplication; +use Silex\Application; +use Silex\ServiceProviderInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class Lightbox implements ControllerProviderInterface +class Lightbox implements ControllerProviderInterface, ServiceProviderInterface { - public function connect(SilexApplication $app) + public function register(Application $app) { - $app['controller.lightbox'] = $this; + $app['controller.lightbox'] = $app->share(function () use ($app) { + return new LightboxController($app); + }); + } + public function boot(Application $app) + { + } + + public function connect(Application $app) + { $controllers = $app['controllers_factory']; - $controllers->before(function (Request $request) use ($app) { - if (!$request->query->has('LOG')) { - return; - } - - if ($app['authentication']->isAuthenticated()) { - $app['authentication']->closeAccount(); - } - - if (null === $token = $app['repo.tokens']->findValidToken($request->query->get('LOG'))) { - $app->addFlash('error', $app->trans('The URL you used is out of date, please login')); - - return $app->redirectPath('homepage'); - } - - $app['authentication']->openAccount($token->getUser()); - - switch ($token->getType()) { - case TokenManipulator::TYPE_FEED_ENTRY: - return $app->redirectPath('lightbox_feed_entry', ['entry_id' => $token->getData()]); - break; - case TokenManipulator::TYPE_VALIDATE: - case TokenManipulator::TYPE_VIEW: - return $app->redirectPath('lightbox_validation', ['basket' => $token->getData()]); - break; - } - }); + $controllers->before([$this, 'redirectOnLogRequests']); $app['firewall']->addMandatoryAuthentication($controllers); @@ -66,99 +54,21 @@ class Lightbox implements ControllerProviderInterface ->before($app['middleware.basket.converter']) ->before($app['middleware.basket.user-access']); - $controllers->get('/', function (SilexApplication $app) { - try { - \Session_Logger::updateClientInfos($app, 6); - } catch (SessionNotFound $e) { - return $app->redirectPath('logout'); - } + $controllers->get('/', 'controller.lightbox:rootAction') + ->bind('lightbox') + ; - $repository = $app['repo.baskets']; - - $basket_collection = array_merge( - $repository->findActiveByUser($app['authentication']->getUser()) - , $repository->findActiveValidationByUser($app['authentication']->getUser()) - ); - - $template = 'lightbox/index.html.twig'; - if (!$app['browser']->isNewGeneration() && !$app['browser']->isMobile()) { - $template = 'lightbox/IE6/index.html.twig'; - } - - return new Response($app['twig']->render($template, [ - 'baskets_collection' => $basket_collection, - 'module_name' => 'Lightbox', - 'module' => 'lightbox' - ] - )); - }) - ->bind('lightbox'); - - $controllers->get('/ajax/NOTE_FORM/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) { - - if (!$app['browser']->isMobile()) { - return new Response(''); - } - - $basketElement = $app['repo.basket-elements'] - ->findUserElement($sselcont_id, $app['authentication']->getUser()); - - $parameters = [ - 'basket_element' => $basketElement, - 'module_name' => '', - ]; - - return $app['twig']->render('lightbox/note_form.html.twig', $parameters); - }) + $controllers->get('/ajax/NOTE_FORM/{sselcont_id}/', 'controller.lightbox:ajaxNoteFormAction') ->bind('lightbox_ajax_note_form') - ->assert('sselcont_id', '\d+'); + ->assert('sselcont_id', '\d+') + ; - $controllers->get('/ajax/LOAD_BASKET_ELEMENT/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) { - $repository = $app['repo.basket-elements']; - - $BasketElement = $repository->findUserElement($sselcont_id, $app['authentication']->getUser()); - - if ($app['browser']->isMobile()) { - $output = $app['twig']->render('lightbox/basket_element.html.twig', [ - 'basket_element' => $BasketElement, - 'module_name' => $BasketElement->getRecord($app)->get_title() - ] - ); - - return new Response($output); - } else { - $template_options = 'lightbox/sc_options_box.html.twig'; - $template_agreement = 'lightbox/agreement_box.html.twig'; - $template_selector = 'lightbox/selector_box.html.twig'; - $template_note = 'lightbox/sc_note.html.twig'; - $template_preview = 'common/preview.html.twig'; - $template_caption = 'common/caption.html.twig'; - - if (!$app['browser']->isNewGeneration()) { - $template_options = 'lightbox/IE6/sc_options_box.html.twig'; - $template_agreement = 'lightbox/IE6/agreement_box.html.twig'; - } - - $Basket = $BasketElement->getBasket(); - - $ret = []; - $ret['number'] = $BasketElement->getRecord($app)->get_number(); - $ret['title'] = $BasketElement->getRecord($app)->get_title(); - - $ret['preview'] = $app['twig']->render($template_preview, ['record' => $BasketElement->getRecord($app), 'not_wrapped' => true]); - $ret['options_html'] = $app['twig']->render($template_options, ['basket_element' => $BasketElement]); - $ret['agreement_html'] = $app['twig']->render($template_agreement, ['basket' => $Basket, 'basket_element' => $BasketElement]); - $ret['selector_html'] = $app['twig']->render($template_selector, ['basket_element' => $BasketElement]); - $ret['note_html'] = $app['twig']->render($template_note, ['basket_element' => $BasketElement]); - $ret['caption'] = $app['twig']->render($template_caption, ['view' => 'preview', 'record' => $BasketElement->getRecord($app)]); - - return $app->json($ret); - } - }) + $controllers->get('/ajax/LOAD_BASKET_ELEMENT/{sselcont_id}/', 'controller.lightbox:ajaxLoadBasketElementAction') ->bind('lightbox_ajax_load_basketelement') - ->assert('sselcont_id', '\d+'); + ->assert('sselcont_id', '\d+') + ; - $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function (SilexApplication $app, $entry_id, $item_id) { + $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function (Application $app, $entry_id, $item_id) { $entry = $app['repo.feed-entries']->find($entry_id); $item = $entry->getItem($item_id); @@ -197,7 +107,7 @@ class Lightbox implements ControllerProviderInterface ->assert('entry_id', '\d+') ->assert('item_id', '\d+'); - $controllers->get('/validate/{basket}/', function (SilexApplication $app, $basket) { + $controllers->get('/validate/{basket}/', function (Application $app, $basket) { try { \Session_Logger::updateClientInfos($app, 6); } catch (SessionNotFound $e) { @@ -243,7 +153,7 @@ class Lightbox implements ControllerProviderInterface ->bind('lightbox_validation') ->assert('basket', '\d+'); - $controllers->get('/compare/{basket}/', function (SilexApplication $app, Basket $basket) { + $controllers->get('/compare/{basket}/', function (Application $app, Basket $basket) { try { \Session_Logger::updateClientInfos($app, 6); @@ -290,7 +200,7 @@ class Lightbox implements ControllerProviderInterface ->bind('lightbox_compare') ->assert('basket', '\d+'); - $controllers->get('/feeds/entry/{entry_id}/', function (SilexApplication $app, $entry_id) { + $controllers->get('/feeds/entry/{entry_id}/', function (Application $app, $entry_id) { try { \Session_Logger::updateClientInfos($app, 6); } catch (SessionNotFound $e) { @@ -324,13 +234,13 @@ class Lightbox implements ControllerProviderInterface ->bind('lightbox_feed_entry') ->assert('entry_id', '\d+'); - $controllers->get('/ajax/LOAD_REPORT/{basket}/', function (SilexApplication $app, Basket $basket) { + $controllers->get('/ajax/LOAD_REPORT/{basket}/', function (Application $app, Basket $basket) { return new Response($app['twig']->render('lightbox/basket_content_report.html.twig', ['basket' => $basket])); }) ->bind('lightbox_ajax_report') ->assert('basket', '\d+'); - $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) { + $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', function (Application $app, $sselcont_id) { $output = ['error' => true, 'datas' => $app->trans('Erreur lors de l\'enregistrement des donnees')]; $request = $app['request']; @@ -369,7 +279,7 @@ class Lightbox implements ControllerProviderInterface ->bind('lightbox_ajax_set_note') ->assert('sselcont_id', '\d+'); - $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) { + $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', function (Application $app, $sselcont_id) { $request = $app['request']; $agreement = $request->request->get('agreement'); @@ -431,7 +341,7 @@ class Lightbox implements ControllerProviderInterface ->bind('lightbox_ajax_set_element_agreement') ->assert('sselcont_id', '\d+'); - $controllers->post('/ajax/SET_RELEASE/{basket}/', function (SilexApplication $app, Basket $basket) { + $controllers->post('/ajax/SET_RELEASE/{basket}/', function (Application $app, Basket $basket) { $datas = ['error' => true, 'datas' => '']; @@ -483,4 +393,39 @@ class Lightbox implements ControllerProviderInterface return $controllers; } + + /** + * @param Request $request + * @param PhraseaApplication $app + * @return RedirectResponse|null + */ + public function redirectOnLogRequests(Request $request, PhraseaApplication $app) + { + if (!$request->query->has('LOG')) { + return null; + } + + if ($app['authentication']->isAuthenticated()) { + $app['authentication']->closeAccount(); + } + + if (null === $token = $app['repo.tokens']->findValidToken($request->query->get('LOG'))) { + $app->addFlash('error', $app->trans('The URL you used is out of date, please login')); + + return $app->redirectPath('homepage'); + } + + /** @var Token $token */ + $app['authentication']->openAccount($token->getUser()); + + switch ($token->getType()) { + case TokenManipulator::TYPE_FEED_ENTRY: + return $app->redirectPath('lightbox_feed_entry', ['entry_id' => $token->getData()]); + case TokenManipulator::TYPE_VALIDATE: + case TokenManipulator::TYPE_VIEW: + return $app->redirectPath('lightbox_validation', ['basket' => $token->getData()]); + } + + return null; + } } diff --git a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php index d2a65b80ed..800279a8a9 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php @@ -28,7 +28,7 @@ class BasketRepository extends EntityRepository * Returns all basket for a given user that are not marked as archived * * @param User $user - * @return \Doctrine\Common\Collections\ArrayCollection + * @return Basket[] */ public function findActiveByUser(User $user, $sort = null) { @@ -54,7 +54,7 @@ class BasketRepository extends EntityRepository * Returns all unread basket for a given user that are not marked as archived * * @param User $user - * @return \Doctrine\Common\Collections\ArrayCollection + * @return Basket[] */ public function findUnreadActiveByUser(User $user) { @@ -89,7 +89,7 @@ class BasketRepository extends EntityRepository * where a specified user is participant (not owner) * * @param User $user - * @return \Doctrine\Common\Collections\ArrayCollection + * @return Basket[] */ public function findActiveValidationByUser(User $user, $sort = null) { @@ -271,7 +271,7 @@ class BasketRepository extends EntityRepository * * @param User $user * @param type $sort - * @return Array + * @return Basket[] */ public function findActiveValidationAndBasketByUser(User $user, $sort = null) { From 054195d3c0d7ab01627471c76bea65009a6b06c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Mon, 30 Mar 2015 12:38:14 +0200 Subject: [PATCH 11/26] Finish Lightbox Controller --- lib/Alchemy/Phrasea/Application.php | 1 - .../Phrasea/Controller/LightboxController.php | 449 ++++++++++++++++-- .../Phrasea/ControllerProvider/Lightbox.php | 334 +------------ .../Phrasea/Model/Entities/FeedEntry.php | 2 +- .../Model/Repositories/BasketRepository.php | 2 +- 5 files changed, 443 insertions(+), 345 deletions(-) diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index dba22a0f7e..63323a2a77 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -26,7 +26,6 @@ use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; use Alchemy\Phrasea\ControllerProvider\Admin\Users; use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; -use Alchemy\Phrasea\ControllerProvider\Lightbox; use Alchemy\Phrasea\ControllerProvider\Minifier; use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; diff --git a/lib/Alchemy/Phrasea/Controller/LightboxController.php b/lib/Alchemy/Phrasea/Controller/LightboxController.php index cf933a6866..3d27e80964 100644 --- a/lib/Alchemy/Phrasea/Controller/LightboxController.php +++ b/lib/Alchemy/Phrasea/Controller/LightboxController.php @@ -11,9 +11,17 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Core\Event\ValidationEvent; +use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Exception\SessionNotFound; +use Alchemy\Phrasea\Model\Entities\Basket; +use Alchemy\Phrasea\Model\Entities\FeedEntry; +use Alchemy\Phrasea\Model\Entities\Token; +use Alchemy\Phrasea\Model\Entities\ValidationData; use Alchemy\Phrasea\Model\Repositories\BasketElementRepository; use Alchemy\Phrasea\Model\Repositories\BasketRepository; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class LightboxController @@ -37,23 +45,47 @@ class LightboxController /** @var BasketRepository $repository */ $repository = $this->app['repo.baskets']; $basket_collection = array_merge( - $repository->findActiveByUser($this->app['authentication']->getUser()), - $repository->findActiveValidationByUser($this->app['authentication']->getUser()) + $repository->findActiveByUser($this->getAuthenticatedUser()), + $repository->findActiveValidationByUser($this->getAuthenticatedUser()) ); - $template = 'lightbox/index.html.twig'; - if (!$this->app['browser']->isNewGeneration() && !$this->app['browser']->isMobile()) { - $template = 'lightbox/IE6/index.html.twig'; - } + $template = $this->isBrowserNewGenerationOrMobile() + ? 'lightbox/index.html.twig' + : 'lightbox/IE6/index.html.twig'; - return new Response($this->app['twig']->render($template, [ - 'baskets_collection' => $basket_collection, - 'module_name' => 'Lightbox', - 'module' => 'lightbox' - ] - )); + return $this->renderResponse($template, [ + 'baskets_collection' => $basket_collection, + 'module_name' => 'Lightbox', + 'module' => 'lightbox', + ]); } + /** + * @param string $template + * @param array $parameters + * @return Response + */ + private function renderResponse($template, array $parameters = []) + { + return new Response($this->render($template, $parameters)); + } + + /** + * @param string $template + * @param array $parameters + * @return string + */ + private function render($template, array $parameters = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render($template, $parameters); + } + + /** + * @param int $sselcont_id + * @return Response + */ public function ajaxNoteFormAction($sselcont_id) { if (!$this->app['browser']->isMobile()) { @@ -63,31 +95,30 @@ class LightboxController /** @var BasketElementRepository $basketElementRepository */ $basketElementRepository = $this->app['repo.basket-elements']; $basketElement = $basketElementRepository - ->findUserElement($sselcont_id, $this->app['authentication']->getUser()); + ->findUserElement($sselcont_id, $this->getAuthenticatedUser()); - return $this->app['twig']->render('lightbox/note_form.html.twig', [ + return $this->renderResponse('lightbox/note_form.html.twig', [ 'basket_element' => $basketElement, 'module_name' => '', ]); } + /** + * @param int $sselcont_id + * @return Response + */ public function ajaxLoadBasketElementAction($sselcont_id) { /** @var BasketElementRepository $repository */ $repository = $this->app['repo.basket-elements']; - $basketElement = $repository->findUserElement($sselcont_id, $this->app['authentication']->getUser()); + $basketElement = $repository->findUserElement($sselcont_id, $this->getAuthenticatedUser()); - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; if ($this->app['browser']->isMobile()) { - $output = $twig->render('lightbox/basket_element.html.twig', [ - 'basket_element' => $basketElement, - 'module_name' => $basketElement->getRecord($this->app)->get_title() - ] - ); - - return new Response($output); + return $this->renderResponse('lightbox/basket_element.html.twig', [ + 'basket_element' => $basketElement, + 'module_name' => $basketElement->getRecord($this->app)->get_title() + ]); } $isNewGenerationBrowser = $this->app['browser']->isNewGeneration(); @@ -97,25 +128,383 @@ class LightboxController $ret['number'] = $basketElement->getRecord($this->app)->get_number(); $ret['title'] = $basketElement->getRecord($this->app)->get_title(); - $ret['preview'] = $twig->render( + $ret['preview'] = $this->render( 'common/preview.html.twig', ['record' => $basketElement->getRecord($this->app), 'not_wrapped' => true] ); - $ret['options_html'] = $twig->render( + $ret['options_html'] = $this->render( $isNewGenerationBrowser ? 'lightbox/sc_options_box.html.twig' : 'lightbox/IE6/sc_options_box.html.twig', ['basket_element' => $basketElement] ); - $ret['agreement_html'] = $twig->render( + $ret['agreement_html'] = $this->render( $isNewGenerationBrowser ? 'lightbox/agreement_box.html.twig' : 'lightbox/IE6/agreement_box.html.twig', ['basket' => $basket, 'basket_element' => $basketElement] ); - $ret['selector_html'] = $twig->render('lightbox/selector_box.html.twig', ['basket_element' => $basketElement]); - $ret['note_html'] = $twig->render('lightbox/sc_note.html.twig', ['basket_element' => $basketElement]); - $ret['caption'] = $twig->render( + $ret['selector_html'] = $this->render('lightbox/selector_box.html.twig', ['basket_element' => $basketElement]); + $ret['note_html'] = $this->render('lightbox/sc_note.html.twig', ['basket_element' => $basketElement]); + $ret['caption'] = $this->render( 'common/caption.html.twig', ['view' => 'preview', 'record' => $basketElement->getRecord($this->app)] ); return $this->app->json($ret); } + + /** + * @param int $entry_id + * @param int $item_id + * @return Response + */ + public function ajaxLoadFeedItemAction($entry_id, $item_id) { + /** @var FeedEntry $entry */ + $entry = $this->app['repo.feed-entries']->find($entry_id); + $item = $entry->getItem($item_id); + + $record = $item->getRecord($this->app); + + /** @var \Browser $browser */ + $browser = $this->app['browser']; + if ($browser->isMobile()) { + return $this->renderResponse('lightbox/feed_element.html.twig', [ + 'feed_element' => $item, + 'module_name' => $record->get_title() + ]); + } + + $ret = []; + $ret['number'] = $record->get_number(); + $ret['title'] = $record->get_title(); + $ret['preview'] = $this->render('common/preview.html.twig', [ + 'record' => $record, + 'not_wrapped' => true, + ]); + $template_options = $browser->isNewGeneration() + ? 'lightbox/feed_options_box.html.twig' + : 'lightbox/IE6/feed_options_box.html.twig'; + $ret['options_html'] = $this->render($template_options, ['feed_element' => $item]); + $ret['caption'] = $this->render( + 'common/caption.html.twig', [ + 'view' => 'preview', + 'record' => $record, + ]); + $ret['agreement_html'] = $ret['selector_html'] = $ret['note_html'] = ''; + + return $this->app->json($ret); + } + + /** + * @param Basket $basket + * @return Response + */ + public function validationAction(Basket $basket) { + try { + \Session_Logger::updateClientInfos($this->app, 6); + } catch (SessionNotFound $e) { + return $this->app->redirectPath('logout'); + } + + /** @var BasketRepository $repository */ + $repository = $this->app['repo.baskets']; + + $basket_collection = $repository->findActiveValidationAndBasketByUser($this->getAuthenticatedUser()); + + $basket = $this->markBasketRead($basket); + $basket = $this->markBasketUserAwareOfValidation($basket); + + $response = $this->renderResponse( + $this->getValidationTemplate(), [ + 'baskets_collection' => $basket_collection, + 'basket' => $basket, + 'local_title' => strip_tags($basket->getName()), + 'module' => 'lightbox', + 'module_name' => $this->app->trans('admin::monitor: module validation'), + ]); + $response->setCharset('UTF-8'); + + return $response; + } + + /** + * @param Basket $basket + * @return Response + */ + public function compareAction(Basket $basket) { + try { + \Session_Logger::updateClientInfos($this->app, 6); + } catch (SessionNotFound $e) { + return $this->app->redirectPath('logout'); + } + + /** @var BasketRepository $repository */ + $repository = $this->app['repo.baskets']; + + $basket_collection = $repository->findActiveValidationAndBasketByUser($this->getAuthenticatedUser()); + + $basket = $this->markBasketRead($basket); + $basket = $this->markBasketUserAwareOfValidation($basket); + + $response = $this->renderResponse($this->getValidationTemplate(), [ + 'baskets_collection' => $basket_collection, + 'basket' => $basket, + 'local_title' => strip_tags($basket->getName()), + 'module' => 'lightbox', + 'module_name' => $this->app->trans('admin::monitor: module validation'), + ]); + $response->setCharset('UTF-8'); + + return $response; + } + + /** + * @param Basket $basket + * @return Basket + */ + private function markBasketRead(Basket $basket) + { + if ($basket->getIsRead() === false) { + /** @var Basket $basket */ + $basket = $this->app['orm.em']->merge($basket); + $basket->setIsRead(true); + $this->app['orm.em']->flush(); + } + + return $basket; + } + + /** + * @return bool + */ + private function isBrowserNewGenerationOrMobile() + { + /** @var \Browser $browser */ + $browser = $this->app['browser']; + return $browser->isNewGeneration() || $browser->isMobile(); + } + + /** + * @return string + */ + private function getValidationTemplate() + { + return $this->isBrowserNewGenerationOrMobile() + ? 'lightbox/validate.html.twig' + : 'lightbox/IE6/validate.html.twig'; + } + + /** + * @param Basket $basket + * @return Basket + */ + private function markBasketUserAwareOfValidation(Basket $basket) + { + if ($basket->getValidation() && $basket->getValidation() + ->getParticipant($this->getAuthenticatedUser()) + ->getIsAware() === false + ) { + /** @var Basket $basket */ + $basket = $this->app['orm.em']->merge($basket); + $basket->getValidation() + ->getParticipant($this->getAuthenticatedUser()) + ->setIsAware(true) + ; + $this->app['orm.em']->flush(); + } + + return $basket; + } + + /** + * @param int $entry_id + * @return Response + */ + public function getFeedEntryAction($entry_id) + { + $app = $this->app; + try { + \Session_Logger::updateClientInfos($app, 6); + } catch (SessionNotFound $e) { + return $app->redirectPath('logout'); + } + + /** @var FeedEntry $feed_entry */ + $feed_entry = $app['repo.feed-entries']->find($entry_id); + + $template = $this->isBrowserNewGenerationOrMobile() + ? 'lightbox/feed.html.twig' + : 'lightbox/IE6/feed.html.twig'; + + $content = $feed_entry->getItems(); + $first = $content->first(); + + $response = $this->renderResponse($template, [ + 'feed_entry' => $feed_entry, + 'first_item' => $first, + 'local_title' => $feed_entry->getTitle(), + 'module' => 'lightbox', + 'module_name' => $app->trans('admin::monitor: module validation') + ]); + $response->setCharset('UTF-8'); + + return $response; + } + + /** + * @param Basket $basket + * @return Response + */ + public function ajaxReportAction(Basket $basket) + { + return $this->renderResponse('lightbox/basket_content_report.html.twig', [ + 'basket' => $basket, + ]); + } + + /** + * @param Request $request + * @param int $sselcont_id + * @return Response + */ + public function ajaxSetNoteAction(Request $request, $sselcont_id) + { + $note = $request->request->get('note'); + + if (is_null($note)) { + return new Response('You must provide a note value', 400); + } + + /** @var BasketElementRepository $repository */ + $repository = $this->app['repo.basket-elements']; + + $basket_element = $repository->findUserElement($sselcont_id, $this->getAuthenticatedUser()); + + $validationData = $basket_element->getUserValidationDatas($this->getAuthenticatedUser()); + /** @var ValidationData $validationData */ + $validationData = $this->app['orm.em']->merge($validationData); + $validationData->setNote($note); + $this->app['orm.em']->flush(); + + $data = $this->render('lightbox/sc_note.html.twig', ['basket_element' => $basket_element]); + $output = ['error' => false, 'datas' => $data]; + + return $this->app->json($output); + } + + public function ajaxSetElementAgreementAction(Request $request, $sselcont_id) + { + $agreement = $request->request->get('agreement'); + + if (is_null($agreement)) { + return new Response('You must provide an agreement value', 400); + } + + $agreement = $agreement > 0; + + try { + $ret = [ + 'error' => true, + 'releasable' => false, + 'datas' => $this->app->trans('Erreur lors de la mise a jour des donnes') + ]; + + /** @var BasketElementRepository $repository */ + $repository = $this->app['repo.basket-elements']; + + $basketElement = $repository->findUserElement($sselcont_id, $this->getAuthenticatedUser()); + $validationData = $basketElement->getUserValidationDatas($this->getAuthenticatedUser()); + + if (!$basketElement->getBasket() + ->getValidation() + ->getParticipant($this->getAuthenticatedUser())->getCanAgree() + ) { + throw new Exception('You can not agree on this'); + } + + $validationData->setAgreement($agreement); + + $participant = $basketElement->getBasket() + ->getValidation() + ->getParticipant($this->getAuthenticatedUser()); + + $this->app['orm.em']->merge($basketElement); + $this->app['orm.em']->flush(); + + $releasable = ($participant->isReleasable()) + ? $releasable = $this->app->trans('Do you want to send your report ?') + : false; + + $ret = [ + 'error' => false, + 'datas' => '', + 'releasable' => $releasable, + ]; + } catch (Exception $e) { + $ret['datas'] = $e->getMessage(); + } + + return $this->app->json($ret); + } + + /** + * @return mixed + */ + private function getAuthenticatedUser() + { + /** @var Authenticator $authentication */ + $authentication = $this->app['authentication']; + return $authentication->getUser(); + } + + /** + * @param Basket $basket + * @return Response + */ + public function ajaxSetReleaseAction(Basket $basket) + { + try { + if (!$basket->getValidation()) { + throw new Exception('There is no validation session attached to this basket'); + } + + if (!$basket->getValidation()->getParticipant($this->getAuthenticatedUser())->getCanAgree()) { + throw new Exception('You have not right to agree'); + } + + $this->assertAtLeastOneElementAgreed($basket); + $participant = $basket->getValidation()->getParticipant($this->getAuthenticatedUser()); + + /** @var Token $token */ + $token = $this->app['manipulator.token']->createBasketValidationToken($basket); + $url = $this->app->url('lightbox', ['LOG' => $token->getValue()]); + + $this->app['dispatcher'] + ->dispatch(PhraseaEvents::VALIDATION_DONE, new ValidationEvent($participant, $basket, $url)); + + $participant->setIsConfirmed(true); + + $this->app['orm.em']->merge($participant); + $this->app['orm.em']->flush(); + + $data = ['error' => false, 'datas' => $this->app->trans('Envoie avec succes')]; + } catch (Exception $e) { + $data = ['error' => true, 'datas' => $e->getMessage()]; + } + + return $this->app->json($data); + } + + /** + * @param Basket $basket + * @throws Exception + */ + private function assertAtLeastOneElementAgreed(Basket $basket) + { + foreach ($basket->getElements() as $element) { + if (null !== $element->getUserValidationDatas($this->getAuthenticatedUser())->getAgreement()) { + return; + } + } + + $message = $this->app->trans('You have to give your feedback at least on one document to send a report'); + throw new Exception($message); + } } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php index 57f02a5282..a608c0e164 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php @@ -13,12 +13,6 @@ namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\LightboxController; -use Alchemy\Phrasea\Core\Event\ValidationEvent; -use Alchemy\Phrasea\Core\PhraseaEvents; -use Alchemy\Phrasea\Model\Entities\Basket; -use Alchemy\Phrasea\Model\Entities\BasketElement; -use Alchemy\Phrasea\Exception\SessionNotFound; -use Alchemy\Phrasea\Controller\Exception as ControllerException; use Alchemy\Phrasea\Model\Entities\Token; use Alchemy\Phrasea\Model\Manipulator\TokenManipulator; use Silex\ControllerProviderInterface; @@ -26,7 +20,6 @@ use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; class Lightbox implements ControllerProviderInterface, ServiceProviderInterface { @@ -68,328 +61,45 @@ class Lightbox implements ControllerProviderInterface, ServiceProviderInterface ->assert('sselcont_id', '\d+') ; - $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function (Application $app, $entry_id, $item_id) { - - $entry = $app['repo.feed-entries']->find($entry_id); - $item = $entry->getItem($item_id); - - if ($app['browser']->isMobile()) { - $output = $app['twig']->render('lightbox/feed_element.html.twig', [ - 'feed_element' => $item, - 'module_name' => $item->getRecord($app)->get_title() - ] - ); - - return new Response($output); - } else { - $template_options = 'lightbox/feed_options_box.html.twig'; - $template_preview = 'common/preview.html.twig'; - $template_caption = 'common/caption.html.twig'; - - if (!$app['browser']->isNewGeneration()) { - $template_options = 'lightbox/IE6/feed_options_box.html.twig'; - } - - $ret = []; - $ret['number'] = $item->getRecord($app)->get_number(); - $ret['title'] = $item->getRecord($app)->get_title(); - - $ret['preview'] = $app['twig']->render($template_preview, ['record' => $item->getRecord($app), 'not_wrapped' => true]); - $ret['options_html'] = $app['twig']->render($template_options, ['feed_element' => $item]); - $ret['caption'] = $app['twig']->render($template_caption, ['view' => 'preview', 'record' => $item->getRecord($app)]); - - $ret['agreement_html'] = $ret['selector_html'] = $ret['note_html'] = ''; - - return $app->json($ret); - } - }) + $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', 'controller.lightbox:ajaxLoadFeedItemAction') ->bind('lightbox_ajax_load_feeditem') ->assert('entry_id', '\d+') - ->assert('item_id', '\d+'); + ->assert('item_id', '\d+') + ; - $controllers->get('/validate/{basket}/', function (Application $app, $basket) { - try { - \Session_Logger::updateClientInfos($app, 6); - } catch (SessionNotFound $e) { - return $app->redirectPath('logout'); - } - - $repository = $app['repo.baskets']; - - $basket_collection = $repository->findActiveValidationAndBasketByUser( - $app['authentication']->getUser() - ); - - if ($basket->getIsRead() === false) { - $basket = $app['orm.em']->merge($basket); - $basket->setIsRead(true); - $app['orm.em']->flush(); - } - - if ($basket->getValidation() && $basket->getValidation()->getParticipant($app['authentication']->getUser())->getIsAware() === false) { - $basket = $app['orm.em']->merge($basket); - $basket->getValidation()->getParticipant($app['authentication']->getUser())->setIsAware(true); - $app['orm.em']->flush(); - } - - $template = 'lightbox/validate.html.twig'; - - if (!$app['browser']->isNewGeneration() && !$app['browser']->isMobile()) { - $template = 'lightbox/IE6/validate.html.twig'; - } - - $response = new Response($app['twig']->render($template, [ - 'baskets_collection' => $basket_collection, - 'basket' => $basket, - 'local_title' => strip_tags($basket->getName()), - 'module' => 'lightbox', - 'module_name' => $app->trans('admin::monitor: module validation') - ] - )); - $response->setCharset('UTF-8'); - - return $response; - }) + $controllers->get('/validate/{basket}/', 'controller.lightbox:validationAction') ->bind('lightbox_validation') - ->assert('basket', '\d+'); + ->assert('basket', '\d+') + ; - $controllers->get('/compare/{basket}/', function (Application $app, Basket $basket) { - - try { - \Session_Logger::updateClientInfos($app, 6); - } catch (SessionNotFound $e) { - return $app->redirectPath('logout'); - } - - $repository = $app['repo.baskets']; - - $basket_collection = $repository->findActiveValidationAndBasketByUser( - $app['authentication']->getUser() - ); - - if ($basket->getIsRead() === false) { - $basket = $app['orm.em']->merge($basket); - $basket->setIsRead(true); - $app['orm.em']->flush(); - } - - if ($basket->getValidation() && $basket->getValidation()->getParticipant($app['authentication']->getUser())->getIsAware() === false) { - $basket = $app['orm.em']->merge($basket); - $basket->getValidation()->getParticipant($app['authentication']->getUser())->setIsAware(true); - $app['orm.em']->flush(); - } - - $template = 'lightbox/validate.html.twig'; - - if (!$app['browser']->isNewGeneration() && !$app['browser']->isMobile()) { - $template = 'lightbox/IE6/validate.html.twig'; - } - - $response = new Response($app['twig']->render($template, [ - 'baskets_collection' => $basket_collection, - 'basket' => $basket, - 'local_title' => strip_tags($basket->getName()), - 'module' => 'lightbox', - 'module_name' => $app->trans('admin::monitor: module validation') - ] - )); - $response->setCharset('UTF-8'); - - return $response; - }) + $controllers->get('/compare/{basket}/', 'controller.lightbox:compareAction') ->bind('lightbox_compare') ->assert('basket', '\d+'); - $controllers->get('/feeds/entry/{entry_id}/', function (Application $app, $entry_id) { - try { - \Session_Logger::updateClientInfos($app, 6); - } catch (SessionNotFound $e) { - return $app->redirectPath('logout'); - } - - $feed_entry = $app['repo.feed-entries']->find($entry_id); - - $template = 'lightbox/feed.html.twig'; - - if (!$app['browser']->isNewGeneration() && !$app['browser']->isMobile()) { - $template = 'lightbox/IE6/feed.html.twig'; - } - - $content = $feed_entry->getItems(); - $first = $content->first(); - - $output = $app['twig']->render($template, [ - 'feed_entry' => $feed_entry, - 'first_item' => $first, - 'local_title' => $feed_entry->getTitle(), - 'module' => 'lightbox', - 'module_name' => $app->trans('admin::monitor: module validation') - ] - ); - $response = new Response($output, 200); - $response->setCharset('UTF-8'); - - return $response; - }) + $controllers->get('/feeds/entry/{entry_id}/', 'controller.lightbox:getFeedEntryAction') ->bind('lightbox_feed_entry') - ->assert('entry_id', '\d+'); + ->assert('entry_id', '\d+') + ; - $controllers->get('/ajax/LOAD_REPORT/{basket}/', function (Application $app, Basket $basket) { - return new Response($app['twig']->render('lightbox/basket_content_report.html.twig', ['basket' => $basket])); - }) + $controllers->get('/ajax/LOAD_REPORT/{basket}/', 'controller.lightbox:ajaxReportAction') ->bind('lightbox_ajax_report') - ->assert('basket', '\d+'); + ->assert('basket', '\d+') + ; - $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', function (Application $app, $sselcont_id) { - $output = ['error' => true, 'datas' => $app->trans('Erreur lors de l\'enregistrement des donnees')]; - - $request = $app['request']; - $note = $request->request->get('note'); - - if (is_null($note)) { - Return new Response('You must provide a note value', 400); - } - - $repository = $app['repo.basket-elements']; - - $basket_element = $repository->findUserElement($sselcont_id, $app['authentication']->getUser()); - - $validationDatas = $basket_element->getUserValidationDatas($app['authentication']->getUser()); - - $validationDatas->setNote($note); - - $app['orm.em']->merge($validationDatas); - - $app['orm.em']->flush(); - - if ($app['browser']->isMobile()) { - $datas = $app['twig']->render('lightbox/sc_note.html.twig', ['basket_element' => $basket_element]); - - $output = ['error' => false, 'datas' => $datas]; - } else { - $template = 'lightbox/sc_note.html.twig'; - - $datas = $app['twig']->render($template, ['basket_element' => $basket_element]); - - $output = ['error' => false, 'datas' => $datas]; - } - - return $app->json($output); - }) + $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', 'controller.lightbox:ajaxSetNoteAction') ->bind('lightbox_ajax_set_note') - ->assert('sselcont_id', '\d+'); + ->assert('sselcont_id', '\d+') + ; - $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', function (Application $app, $sselcont_id) { - $request = $app['request']; - $agreement = $request->request->get('agreement'); - - if (is_null($agreement)) { - Return new Response('You must provide an agreement value', 400); - } - - $agreement = $agreement > 0; - - $releasable = false; - try { - $ret = [ - 'error' => true, - 'releasable' => false, - 'datas' => $app->trans('Erreur lors de la mise a jour des donnes') - ]; - - $repository = $app['repo.basket-elements']; - - $basket_element = $repository->findUserElement( - $sselcont_id - , $app['authentication']->getUser() - ); - /* @var $basket_element BasketElement */ - $validationDatas = $basket_element->getUserValidationDatas($app['authentication']->getUser()); - - if (!$basket_element->getBasket() - ->getValidation() - ->getParticipant($app['authentication']->getUser())->getCanAgree()) { - throw new ControllerException('You can not agree on this'); - } - - $validationDatas->setAgreement($agreement); - - $participant = $basket_element->getBasket() - ->getValidation() - ->getParticipant($app['authentication']->getUser()); - - $app['orm.em']->merge($basket_element); - - $app['orm.em']->flush(); - - $releasable = false; - if ($participant->isReleasable() === true) { - $releasable = $app->trans('Do you want to send your report ?'); - } - - $ret = [ - 'error' => false - , 'datas' => '' - , 'releasable' => $releasable - ]; - } catch (ControllerException $e) { - $ret['datas'] = $e->getMessage(); - } - - return $app->json($ret); - }) + $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', 'controller.lightbox:ajaxSetElementAgreementAction') ->bind('lightbox_ajax_set_element_agreement') - ->assert('sselcont_id', '\d+'); + ->assert('sselcont_id', '\d+') + ; - $controllers->post('/ajax/SET_RELEASE/{basket}/', function (Application $app, Basket $basket) { - - $datas = ['error' => true, 'datas' => '']; - - try { - if (!$basket->getValidation()) { - throw new ControllerException('There is no validation session attached to this basket'); - } - - if (!$basket->getValidation()->getParticipant($app['authentication']->getUser())->getCanAgree()) { - throw new ControllerException('You have not right to agree'); - } - - $agreed = false; - /* @var $basket Basket */ - foreach ($basket->getElements() as $element) { - if (null !== $element->getUserValidationDatas($app['authentication']->getUser())->getAgreement()) { - $agreed = true; - } - } - - if (!$agreed) { - throw new ControllerException($app->trans('You have to give your feedback at least on one document to send a report')); - } - - /* @var $basket Basket */ - $participant = $basket->getValidation()->getParticipant($app['authentication']->getUser()); - - $token = $app['manipulator.token']->createBasketValidationToken($basket); - $url = $app->url('lightbox', ['LOG' => $token->getValue()]); - - $to = $basket->getValidation()->getInitiator($app)->getId(); - - $app['dispatcher']->dispatch(PhraseaEvents::VALIDATION_DONE, new ValidationEvent($participant, $basket, $url)); - - $participant->setIsConfirmed(true); - - $app['orm.em']->merge($participant); - $app['orm.em']->flush(); - - $datas = ['error' => false, 'datas' => $app->trans('Envoie avec succes')]; - } catch (ControllerException $e) { - $datas = ['error' => true, 'datas' => $e->getMessage()]; - } - - return $app->json($datas); - }) + $controllers->post('/ajax/SET_RELEASE/{basket}/', 'controller.lightbox:ajaxSetReleaseAction') ->bind('lightbox_ajax_set_release') - ->assert('basket', '\d+'); + ->assert('basket', '\d+') + ; return $controllers; } diff --git a/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php b/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php index 0ab608482b..b8fe006db2 100644 --- a/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php +++ b/lib/Alchemy/Phrasea/Model/Entities/FeedEntry.php @@ -335,7 +335,7 @@ class FeedEntry * * @param int $id * - * @return null + * @return null|FeedItem */ public function getItem($id) { diff --git a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php index 800279a8a9..3422629d40 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php @@ -270,7 +270,7 @@ class BasketRepository extends EntityRepository * Return all actives validation where current user is involved and user basket * * @param User $user - * @param type $sort + * @param string $sort * @return Basket[] */ public function findActiveValidationAndBasketByUser(User $user, $sort = null) From 0bbd745a87932d7509b70a9879acd5fdf2285082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Mon, 30 Mar 2015 14:41:58 +0200 Subject: [PATCH 12/26] Add Minifier Controller --- lib/Alchemy/Phrasea/Application.php | 5 +- .../Phrasea/Controller/MinifierController.php | 146 +++++++++++++++++ .../Phrasea/ControllerProvider/Minifier.php | 147 +++--------------- 3 files changed, 170 insertions(+), 128 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/MinifierController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 63323a2a77..0e2342dd3e 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -26,7 +26,6 @@ use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; use Alchemy\Phrasea\ControllerProvider\Admin\Users; use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; -use Alchemy\Phrasea\ControllerProvider\Minifier; use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; use Alchemy\Phrasea\ControllerProvider\Prod\DoDownload; @@ -317,6 +316,7 @@ class Application extends SilexApplication $providers = [ 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], + 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], 'Alchemy\Phrasea\ControllerProvider\Permalink' => [], ]; foreach ($providers as $class => $values) { @@ -676,10 +676,9 @@ class Application extends SilexApplication $this->mount('/thesaurus', new Thesaurus()); $this->mount('/xmlhttp', new ThesaurusXMLHttp()); - $this->mount('/include/minify/', new Minifier()); - $providers = [ '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', + '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', ]; diff --git a/lib/Alchemy/Phrasea/Controller/MinifierController.php b/lib/Alchemy/Phrasea/Controller/MinifierController.php new file mode 100644 index 0000000000..bc173b038b --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/MinifierController.php @@ -0,0 +1,146 @@ +cachePath = $cachePath; + $this->debug = (bool) $debug; + } + + public function minifyAction(Request $request) + { + /** + * Cache file locking. Set to false if filesystem is NFS. On at least one + * NFS system flock-ing attempts stalled PHP for 30 seconds! + */ + $min_cacheFileLocking = true; + + /** + * Combining multiple CSS files can place @import declarations after rules, which + * is invalid. Minify will attempt to detect when this happens and place a + * warning comment at the top of the CSS output. To resolve this you can either + * move the @imports within your CSS files, or enable this option, which will + * move all @imports to the top of the output. Note that moving @imports could + * affect CSS values (which is why this option is disabled by default). + */ + $min_serveOptions['bubbleCssImports'] = false; + + $min_serveOptions['debug'] = false; + $min_serveOptions['maxAge'] = 1800; + if ($this->debug) { + // may cause js errors + $min_serveOptions['debug'] = false; + // disallow minification instead + $min_serveOptions['minApp']['noMinPattern'] = '#\.(?:js|css)$#i'; + $min_serveOptions['maxAge'] = 0; + } + + /** + * Set to true to disable the "f" GET parameter for specifying files. + * Only the "g" parameter will be considered. + */ + $min_serveOptions['minApp']['groupsOnly'] = false; + + /** + * Maximum # of files that can be specified in the "f" GET parameter + */ + $min_serveOptions['minApp']['maxFiles'] = 10; + + /** + * If you minify CSS files stored in symlink-ed directories, the URI rewriting + * algorithm can fail. To prevent this, provide an array of link paths to + * target paths, where the link paths are within the document root. + * + * Because paths need to be normalized for this to work, use "//" to substitute + * the doc root in the link paths (the array keys). E.g.: + * + * array('//symlink' => '/real/target/path') // unix + * array('//static' => 'D:\\staticStorage') // Windows + * + */ + $min_symlinks = []; + + /** + * If you upload files from Windows to a non-Windows server, Windows may report + * incorrect mtimes for the files. This may cause Minify to keep serving stale + * cache files when source file changes are made too frequently (e.g. more than + * once an hour). + * + * Immediately after modifying and uploading a file, use the touch command to + * update the mtime on the server. If the mtime jumps ahead by a number of hours, + * set this variable to that number. If the mtime moves back, this should not be + * needed. + * + * In the Windows SFTP client WinSCP, there's an option that may fix this + * issue without changing the variable below. Under login > environment, + * select the option "Adjust remote timestamp with DST". + * @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time + */ + $min_uploaderHoursBehind = 0; + + // return an array instead of echoing output + $min_serveOptions['quiet'] = true; + + \Minify::$uploaderHoursBehind = $min_uploaderHoursBehind; + \Minify::setCache(isset($min_cachePath) ? $min_cachePath : '', $min_cacheFileLocking); + + // required to work well :( + $_SERVER['DOCUMENT_ROOT'] = __DIR__ . '/../../../../www/'; + \Minify::$isDocRootSet = true; + + $min_serveOptions['minifierOptions']['text/css']['symlinks'] = $min_symlinks; + // auto-add targets to allowDirs + foreach ($min_symlinks as $uri => $target) { + $min_serveOptions['minApp']['allowDirs'][] = $target; + } + + if (null !== $request->query->get('g')) { + // well need groups config + $min_serveOptions['minApp']['groups'] = require __DIR__ . '/../../../conf.d/minifyGroupsConfig.php'; + } + + if (null === $request->query->get('f') && null === $request->query->get('g')) { + throw new HttpException(400, 'Please provide an argument'); + } + + $ret = \Minify::serve(new \Minify_Controller_MinApp(), $min_serveOptions); + + if (!$ret['success']) { + throw new HttpException(500, 'Unable to generate data'); + } + + $response = new Response($ret['content'], $ret['statusCode']); + $response->setMaxAge($min_serveOptions['maxAge']); + + foreach ($ret['headers'] as $key => $value) { + $response->headers->set($key, $value); + } + + return $response; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php index 29946f1278..11a47e0abf 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php @@ -11,139 +11,36 @@ namespace Alchemy\Phrasea\ControllerProvider; +use Alchemy\Phrasea\Controller\MinifierController; use Silex\ControllerProviderInterface; use Silex\Application; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\HttpException; +use Silex\ServiceProviderInterface; +use Symfony\Component\Filesystem\Filesystem; -class Minifier implements ControllerProviderInterface +class Minifier implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.minifier'] = $app->share(function ($app) { + $cachePath = $app['cache.path'] . '/minify'; + /** @var Filesystem $fs */ + $fs = $app['filesystem']; + // ensure cache path created + $fs->mkdir($cachePath); + + return new MinifierController($cachePath, $app['debug']); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.minifier'] = $this; - $controllers = $app['controllers_factory']; - $controllers->get('/', function (Application $app, Request $request) { - // cache directory path - $min_cachePath = $app['cache.path'].'/minify'; - // ensure path is created - $app['filesystem']->mkdir($min_cachePath); - - /** - * Cache file locking. Set to false if filesystem is NFS. On at least one - * NFS system flock-ing attempts stalled PHP for 30 seconds! - */ - $min_cacheFileLocking = true; - - /** - * Combining multiple CSS files can place @import declarations after rules, which - * is invalid. Minify will attempt to detect when this happens and place a - * warning comment at the top of the CSS output. To resolve this you can either - * move the @imports within your CSS files, or enable this option, which will - * move all @imports to the top of the output. Note that moving @imports could - * affect CSS values (which is why this option is disabled by default). - */ - $min_serveOptions['bubbleCssImports'] = false; - - if ($app['debug']) { - // may cause js errors - $min_serveOptions['debug'] = false; - // disallow minification instead - $min_serveOptions['minApp']['noMinPattern'] = '#\.(?:js|css)$#i'; - $min_serveOptions['maxAge'] = 0; - } else { - $min_serveOptions['debug'] = false; - $min_serveOptions['maxAge'] = 1800; - } - - /** - * Set to true to disable the "f" GET parameter for specifying files. - * Only the "g" parameter will be considered. - */ - $min_serveOptions['minApp']['groupsOnly'] = false; - - /** - * Maximum # of files that can be specified in the "f" GET parameter - */ - $min_serveOptions['minApp']['maxFiles'] = 10; - - /** - * If you minify CSS files stored in symlink-ed directories, the URI rewriting - * algorithm can fail. To prevent this, provide an array of link paths to - * target paths, where the link paths are within the document root. - * - * Because paths need to be normalized for this to work, use "//" to substitute - * the doc root in the link paths (the array keys). E.g.: - * - * array('//symlink' => '/real/target/path') // unix - * array('//static' => 'D:\\staticStorage') // Windows - * - */ - $min_symlinks = []; - - /** - * If you upload files from Windows to a non-Windows server, Windows may report - * incorrect mtimes for the files. This may cause Minify to keep serving stale - * cache files when source file changes are made too frequently (e.g. more than - * once an hour). - * - * Immediately after modifying and uploading a file, use the touch command to - * update the mtime on the server. If the mtime jumps ahead by a number of hours, - * set this variable to that number. If the mtime moves back, this should not be - * needed. - * - * In the Windows SFTP client WinSCP, there's an option that may fix this - * issue without changing the variable below. Under login > environment, - * select the option "Adjust remote timestamp with DST". - * @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time - */ - $min_uploaderHoursBehind = 0; - - // return an array instead of echoing output - $min_serveOptions['quiet'] = true; - - \Minify::$uploaderHoursBehind = $min_uploaderHoursBehind; - \Minify::setCache( - isset($min_cachePath) ? $min_cachePath : '' - ,$min_cacheFileLocking - ); - - // required to work well :( - $_SERVER['DOCUMENT_ROOT'] = __DIR__ . '/../../../../www/'; - \Minify::$isDocRootSet = true; - - $min_serveOptions['minifierOptions']['text/css']['symlinks'] = $min_symlinks; - // auto-add targets to allowDirs - foreach ($min_symlinks as $uri => $target) { - $min_serveOptions['minApp']['allowDirs'][] = $target; - } - - if (null !== $request->query->get('g')) { - // well need groups config - $min_serveOptions['minApp']['groups'] = require __DIR__ . '/../../../conf.d/minifyGroupsConfig.php'; - } - - if (null === $request->query->get('f') && null === $request->query->get('g')) { - throw new HttpException(400, 'Please provide an argument'); - } - - $ret = \Minify::serve(new \Minify_Controller_MinApp(), $min_serveOptions); - - if (!$ret['success']) { - throw new HttpException(500, 'Unable to generate data'); - } - - $response = new Response($ret['content'], $ret['statusCode']); - $response->setMaxAge($min_serveOptions['maxAge']); - - foreach ($ret['headers'] as $key => $value) { - $response->headers->set($key, $value); - } - - return $response; - })->bind('minifier'); + $controllers->get('/', 'controller.minifier:minifyAction')->bind('minifier'); return $controllers; } From f122e0eafd140c09e463c5dee98ea592d75e99e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Mon, 30 Mar 2015 15:14:39 +0200 Subject: [PATCH 13/26] Setup Controller --- lib/Alchemy/Phrasea/Application.php | 5 +- .../Phrasea/Controller/SetupController.php | 212 ++++++++++++++++++ .../Phrasea/ControllerProvider/Setup.php | 185 ++------------- .../Setup/RequirementCollectionInterface.php | 2 +- 4 files changed, 229 insertions(+), 175 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/SetupController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 0e2342dd3e..2629ba8214 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -60,7 +60,6 @@ use Alchemy\Phrasea\ControllerProvider\Root\Login; use Alchemy\Phrasea\ControllerProvider\Root\Root; use Alchemy\Phrasea\ControllerProvider\Root\RSSFeeds; use Alchemy\Phrasea\ControllerProvider\Root\Session; -use Alchemy\Phrasea\ControllerProvider\Setup as SetupController; use Alchemy\Phrasea\ControllerProvider\Thesaurus\Thesaurus; use Alchemy\Phrasea\ControllerProvider\Thesaurus\Xmlhttp as ThesaurusXMLHttp; use Alchemy\Phrasea\ControllerProvider\User\Notifications; @@ -318,6 +317,7 @@ class Application extends SilexApplication 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], 'Alchemy\Phrasea\ControllerProvider\Permalink' => [], + 'Alchemy\Phrasea\ControllerProvider\Setup' => [], ]; foreach ($providers as $class => $values) { $this->register(new $class, $values); @@ -667,8 +667,6 @@ class Application extends SilexApplication $this->mount('/download/', new DoDownload()); $this->mount('/session/', new Session()); - $this->mount('/setup', new SetupController()); - $this->mount('/report/', new ReportRoot()); $this->mount('/report/activity', new ReportActivity()); $this->mount('/report/informations', new ReportInformations()); @@ -681,6 +679,7 @@ class Application extends SilexApplication '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', + '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', ]; foreach ($providers as $prefix => $class) { $this->mount($prefix, new $class); diff --git a/lib/Alchemy/Phrasea/Controller/SetupController.php b/lib/Alchemy/Phrasea/Controller/SetupController.php new file mode 100644 index 0000000000..c8c8f15216 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/SetupController.php @@ -0,0 +1,212 @@ +app = $app; + } + + /** + * @param string $template + * @param array $parameters + * @return string + */ + private function render($template, array $parameters = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render($template, $parameters); + } + + public function rootInstaller(Request $request) + { + $requirementsCollection = $this->getRequirementsCollection(); + + return $this->render('/setup/index.html.twig', [ + 'locale' => $this->app['locale'], + 'available_locales' => Application::getAvailableLanguages(), + 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/', + 'requirementsCollection' => $requirementsCollection, + ]); + } + + /** + * @return RequirementCollectionInterface[] + */ + private function getRequirementsCollection() + { + return [ + new BinariesRequirements(), + new FilesystemRequirements(), + new LocalesRequirements(), + new PhpRequirements(), + new SystemRequirements(), + ]; + } + + public function displayUpgradeInstructions() + { + return $this->render('/setup/upgrade-instructions.html.twig', [ + 'locale' => $this->app['locale'], + 'available_locales' => Application::getAvailableLanguages(), + ]); + } + + public function getInstallForm(Request $request) + { + $warnings = []; + + $requirementsCollection = $this->getRequirementsCollection(); + foreach ($requirementsCollection as $requirements) { + foreach ($requirements->getRequirements() as $requirement) { + if (!$requirement->isFulfilled() && !$requirement->isOptional()) { + $warnings[] = $requirement->getTestMessage(); + } + } + } + + if ($request->getScheme() == 'http') { + $warnings[] = $this->app->trans('It is not recommended to install Phraseanet without HTTPS support'); + } + + return $this->render('/setup/step2.html.twig', [ + 'locale' => $this->app['locale'], + 'available_locales' => Application::getAvailableLanguages(), + 'available_templates' => ['en', 'fr'], + 'warnings' => $warnings, + 'error' => $request->query->get('error'), + 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/', + 'discovered_binaries' => \setup::discover_binaries(), + 'rootpath' => realpath(__DIR__ . '/../../../../'), + ]); + } + + public function doInstall(Request $request) + { + set_time_limit(360); + + $servername = $request->getScheme() . '://' . $request->getHttpHost() . '/'; + + $dbConn = null; + + $database_host = $request->request->get('hostname'); + $database_port = $request->request->get('port'); + $database_user = $request->request->get('user'); + $database_password = $request->request->get('db_password'); + + $appbox_name = $request->request->get('ab_name'); + $databox_name = $request->request->get('db_name'); + + try { + $abInfo = [ + 'host' => $database_host, + 'port' => $database_port, + 'user' => $database_user, + 'password' => $database_password, + 'dbname' => $appbox_name, + ]; + + /** @var Connection $abConn */ + $abConn = $this->app['dbal.provider']($abInfo); + $abConn->connect(); + } catch (\Exception $e) { + return $this->app->redirectPath('install_step2', [ + 'error' => $this->app->trans('Appbox is unreachable'), + ]); + } + + try { + if ($databox_name) { + $dbInfo = [ + 'host' => $database_host, + 'port' => $database_port, + 'user' => $database_user, + 'password' => $database_password, + 'dbname' => $databox_name, + ]; + + /** @var Connection $dbConn */ + $dbConn = $this->app['dbal.provider']($dbInfo); + $dbConn->connect(); + } + } catch (\Exception $e) { + return $this->app->redirectPath('install_step2', [ + 'error' => $this->app->trans('Databox is unreachable'), + ]); + } + + $this->app['dbs.options'] = array_merge( + $this->app['db.options.from_info']($dbInfo), + $this->app['db.options.from_info']($abInfo), + $this->app['dbs.options'] + ); + $this->app['orm.ems.options'] = array_merge( + $this->app['orm.em.options.from_info']($dbInfo), + $this->app['orm.em.options.from_info']($abInfo), + $this->app['orm.ems.options'] + ); + + $email = $request->request->get('email'); + $password = $request->request->get('password'); + $template = $request->request->get('db_template'); + $dataPath = $request->request->get('datapath_noweb'); + + try { + $installer = $this->app['phraseanet.installer']; + $installer->setPhraseaIndexerPath($request->request->get('binary_phraseanet_indexer')); + + $binaryData = []; + foreach ([ + 'php_binary' => $request->request->get('binary_php'), + 'swf_extract_binary' => $request->request->get('binary_swfextract'), + 'pdf2swf_binary' => $request->request->get('binary_pdf2swf'), + 'swf_render_binary' => $request->request->get('binary_swfrender'), + 'unoconv_binary' => $request->request->get('binary_unoconv'), + 'ffmpeg_binary' => $request->request->get('binary_ffmpeg'), + 'mp4box_binary' => $request->request->get('binary_MP4Box'), + 'pdftotext_binary' => $request->request->get('binary_xpdf'), + 'recess_binary' => $request->request->get('binary_recess'), + ] as $key => $path) { + $binaryData[$key] = $path; + } + + $user = $installer->install($email, $password, $abConn, $servername, $dataPath, $dbConn, $template, $binaryData); + + $this->app['authentication']->openAccount($user); + + return $this->app->redirectPath('admin', [ + 'section' => 'taskmanager', + 'notice' => 'install_success', + ]); + } catch (\Exception $e) { + return $this->app->redirectPath('install_step2', [ + 'error' => $this->app->trans('an error occured : %message%', ['%message%' => $e->getMessage()]), + ]); + } + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php index 0d102b78a1..da2b81993b 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Setup.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php @@ -12,23 +12,29 @@ namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Controller\SetupController; use Alchemy\Phrasea\Helper\DatabaseHelper; use Alchemy\Phrasea\Helper\PathHelper; -use Alchemy\Phrasea\Setup\Requirements\BinariesRequirements; -use Alchemy\Phrasea\Setup\Requirements\FilesystemRequirements; -use Alchemy\Phrasea\Setup\Requirements\LocalesRequirements; -use Alchemy\Phrasea\Setup\Requirements\PhpRequirements; -use Alchemy\Phrasea\Setup\Requirements\SystemRequirements; use Silex\ControllerProviderInterface; use Silex\Application as SilexApplication; +use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Request; -class Setup implements ControllerProviderInterface +class Setup implements ControllerProviderInterface, ServiceProviderInterface { + public function register(SilexApplication $app) + { + $app['controller.setup'] = $app->share(function ($application) { + return new SetupController($application); + }); + } + + public function boot(SilexApplication $app) + { + } + public function connect(SilexApplication $app) { - $app['controller.setup'] = $this; - $controllers = $app['controllers_factory']; $controllers->get('/', function (Application $app) { @@ -67,167 +73,4 @@ class Setup implements ControllerProviderInterface return $controllers; } - - public function rootInstaller(Application $app, Request $request) - { - $requirementsCollection = $this->getRequirementsCollection(); - - return $app['twig']->render('/setup/index.html.twig', [ - 'locale' => $app['locale'], - 'available_locales' => Application::getAvailableLanguages(), - 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/', - 'requirementsCollection' => $requirementsCollection, - ]); - } - - private function getRequirementsCollection() - { - return [ - new BinariesRequirements(), - new FilesystemRequirements(), - new LocalesRequirements(), - new PhpRequirements(), - new SystemRequirements(), - ]; - } - - public function displayUpgradeInstructions(Application $app, Request $request) - { - return $app['twig']->render('/setup/upgrade-instructions.html.twig', [ - 'locale' => $app['locale'], - 'available_locales' => Application::getAvailableLanguages(), - ]); - } - - public function getInstallForm(Application $app, Request $request) - { - $warnings = []; - - $requirementsCollection = $this->getRequirementsCollection(); - - foreach ($requirementsCollection as $requirements) { - foreach ($requirements->getRequirements() as $requirement) { - if (!$requirement->isFulfilled() && !$requirement->isOptional()) { - $warnings[] = $requirement->getTestMessage(); - } - } - } - - if ($request->getScheme() == 'http') { - $warnings[] = $app->trans('It is not recommended to install Phraseanet without HTTPS support'); - } - - return $app['twig']->render('/setup/step2.html.twig', [ - 'locale' => $app['locale'], - 'available_locales' => Application::getAvailableLanguages(), - 'available_templates' => ['en', 'fr'], - 'warnings' => $warnings, - 'error' => $request->query->get('error'), - 'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/', - 'discovered_binaries' => \setup::discover_binaries(), - 'rootpath' => realpath(__DIR__ . '/../../../../'), - ]); - } - - public function doInstall(Application $app, Request $request) - { - set_time_limit(360); - - $servername = $request->getScheme() . '://' . $request->getHttpHost() . '/'; - - $abConn = $dbConn = null; - - $database_host = $request->request->get('hostname'); - $database_port = $request->request->get('port'); - $database_user = $request->request->get('user'); - $database_password = $request->request->get('db_password'); - - $appbox_name = $request->request->get('ab_name'); - $databox_name = $request->request->get('db_name'); - - try { - $abInfo = [ - 'host' => $database_host, - 'port' => $database_port, - 'user' => $database_user, - 'password' => $database_password, - 'dbname' => $appbox_name, - ]; - - $abConn = $app['dbal.provider']($abInfo); - $abConn->connect(); - } catch (\Exception $e) { - return $app->redirectPath('install_step2', [ - 'error' => $app->trans('Appbox is unreachable'), - ]); - } - - try { - if ($databox_name) { - $dbInfo = [ - 'host' => $database_host, - 'port' => $database_port, - 'user' => $database_user, - 'password' => $database_password, - 'dbname' => $databox_name, - ]; - - $dbConn = $app['dbal.provider']($dbInfo); - $dbConn->connect(); - } - } catch (\Exception $e) { - return $app->redirectPath('install_step2', [ - 'error' => $app->trans('Databox is unreachable'), - ]); - } - - $app['dbs.options'] = array_merge( - $app['db.options.from_info']($dbInfo), - $app['db.options.from_info']($abInfo), - $app['dbs.options'] - ); - $app['orm.ems.options'] = array_merge( - $app['orm.em.options.from_info']($dbInfo), - $app['orm.em.options.from_info']($abInfo), - $app['orm.ems.options'] - ); - - $email = $request->request->get('email'); - $password = $request->request->get('password'); - $template = $request->request->get('db_template'); - $dataPath = $request->request->get('datapath_noweb'); - - try { - $installer = $app['phraseanet.installer']; - $installer->setPhraseaIndexerPath($request->request->get('binary_phraseanet_indexer')); - - $binaryData = []; - foreach ([ - 'php_binary' => $request->request->get('binary_php'), - 'swf_extract_binary' => $request->request->get('binary_swfextract'), - 'pdf2swf_binary' => $request->request->get('binary_pdf2swf'), - 'swf_render_binary' => $request->request->get('binary_swfrender'), - 'unoconv_binary' => $request->request->get('binary_unoconv'), - 'ffmpeg_binary' => $request->request->get('binary_ffmpeg'), - 'mp4box_binary' => $request->request->get('binary_MP4Box'), - 'pdftotext_binary' => $request->request->get('binary_xpdf'), - 'recess_binary' => $request->request->get('binary_recess'), - ] as $key => $path) { - $binaryData[$key] = $path; - } - - $user = $installer->install($email, $password, $abConn, $servername, $dataPath, $dbConn, $template, $binaryData); - - $app['authentication']->openAccount($user); - - return $app->redirectPath('admin', [ - 'section' => 'taskmanager', - 'notice' => 'install_success', - ]); - } catch (\Exception $e) { - return $app->redirectPath('install_step2', [ - 'error' => $app->trans('an error occured : %message%', ['%message%' => $e->getMessage()]), - ]); - } - } } diff --git a/lib/Alchemy/Phrasea/Setup/RequirementCollectionInterface.php b/lib/Alchemy/Phrasea/Setup/RequirementCollectionInterface.php index b59f2109ba..84d8a3702f 100644 --- a/lib/Alchemy/Phrasea/Setup/RequirementCollectionInterface.php +++ b/lib/Alchemy/Phrasea/Setup/RequirementCollectionInterface.php @@ -114,7 +114,7 @@ interface RequirementCollectionInterface extends \IteratorAggregate /** * Returns all mandatory requirements. * - * @return array Array of Requirement instances + * @return RequirementInterface[] Array of Requirement instances */ public function getRequirements(); From 26e6b9180482d72898e86df753c99b6b502ee152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Mon, 30 Mar 2015 17:25:14 +0200 Subject: [PATCH 14/26] Admin Collection Controller --- lib/Alchemy/Phrasea/Application.php | 14 +- .../Phrasea/Authentication/Authenticator.php | 7 + .../Controller/Admin/CollectionController.php | 968 ++++++++++++++++++ .../ControllerProvider/Admin/Collection.php | 891 +--------------- 4 files changed, 996 insertions(+), 884 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 2629ba8214..2c7bfac4fc 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea; use Alchemy\Geonames\GeonamesServiceProvider; -use Alchemy\Phrasea\ControllerProvider\Admin\Collection; use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; use Alchemy\Phrasea\ControllerProvider\Admin\Dashboard; use Alchemy\Phrasea\ControllerProvider\Admin\Databox; @@ -313,6 +312,7 @@ class Application extends SilexApplication }); $providers = [ + 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], @@ -622,7 +622,6 @@ class Application extends SilexApplication $this->mount('/admin/', new AdminRoot()); $this->mount('/admin/dashboard', new Dashboard()); - $this->mount('/admin/collection', new Collection()); $this->mount('/admin/databox', new Databox()); $this->mount('/admin/databoxes', new Databoxes()); $this->mount('/admin/setup', new Setup()); @@ -675,11 +674,12 @@ class Application extends SilexApplication $this->mount('/xmlhttp', new ThesaurusXMLHttp()); $providers = [ - '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', - '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', - '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', - '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', - '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', + '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', + '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', + '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', + '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', + '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', + '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', ]; foreach ($providers as $prefix => $class) { $this->mount($prefix, new $class); diff --git a/lib/Alchemy/Phrasea/Authentication/Authenticator.php b/lib/Alchemy/Phrasea/Authentication/Authenticator.php index 92f092a4be..518a9c56f3 100644 --- a/lib/Alchemy/Phrasea/Authentication/Authenticator.php +++ b/lib/Alchemy/Phrasea/Authentication/Authenticator.php @@ -38,11 +38,18 @@ class Authenticator $this->reinitUser(); } + /** + * @return User|null + */ public function getUser() { return $this->user; } + /** + * @param User|null $user + * @return $this + */ public function setUser(User $user = null) { $this->user = $user; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php new file mode 100644 index 0000000000..c432d8c6a0 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php @@ -0,0 +1,968 @@ +app = $app; + } + + /** + * @return User|null + */ + private function getAuthenticatedUser() + { + /** @var Authenticator $authenticator */ + $authenticator = $this->app['authentication']; + return $authenticator->getUser(); + } + + /** + * @return \ACL + */ + private function getAuthenticatedUserAcl() + { + /** @var ACLProvider $acl */ + $acl = $this->app['acl']; + return $acl->get($this->getAuthenticatedUser()); + } + + /** + * @param string $template + * @param array $parameters + * @return string + */ + private function render($template, array $parameters = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + + return $twig->render($template, $parameters); + } + + /** + * Display collection information page + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function getCollection(Request $request, $bas_id) + { + $collection = \collection::get_from_base_id($this->app, $bas_id); + + $admins = []; + + if ($this->getAuthenticatedUserAcl()->has_right_on_base($bas_id, 'manage')) { + /** @var \User_Query $query */ + $query = $this->app['phraseanet.user-query']; + $admins = $query->on_base_ids([$bas_id]) + ->who_have_right(['order_master']) + ->execute() + ->get_results(); + } + + switch ($errorMsg = $request->query->get('error')) { + case 'file-error': + $errorMsg = $this->app->trans('Error while sending the file'); + break; + case 'file-invalid': + $errorMsg = $this->app->trans('Invalid file format'); + break; + case 'file-file-too-big': + $errorMsg = $this->app->trans('The file is too big'); + break; + case 'collection-not-empty': + $errorMsg = $this->app->trans('Empty the collection before removing'); + break; + } + + return $this->render('admin/collection/collection.html.twig', [ + 'collection' => $collection, + 'admins' => $admins, + 'errorMsg' => $errorMsg, + 'reloadTree' => $request->query->get('reload-tree') === '1' + ]); + } + + /** + * Set new admin to handle orders + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + * @throws \Doctrine\DBAL\ConnectionException + * @throws \Exception + */ + public function setOrderAdmins(Request $request, $bas_id) + { + $admins = array_values($request->request->get('admins', [])); + + if (count($admins) === 0) { + $this->app->abort(400, 'No admins provided.'); + } + if (!is_array($admins)) { + $this->app->abort(400, 'Admins must be an array.'); + } + + /** @var UserRepository $userRepository */ + $userRepository = $this->app['repo.users']; + $users = $userRepository->findBy(['id' => $admins]); + $userIds = array_map(function (User $user) { + return $user->getId(); + }, $users); + $missingAdmins = array_diff($admins, $userIds); + if (!empty($missingAdmins)) { + throw new RuntimeException(sprintf('Invalid usrId %s provided.', reset($missingAdmins))); + } + $admins = $users; + + /** @var Connection $conn */ + $conn = $this->app['phraseanet.appbox']->get_connection(); + $conn->beginTransaction(); + + try { + /** @var \User_Query $userQuery */ + $userQuery = $this->app['phraseanet.user-query']; + + $result = $userQuery->on_base_ids([$bas_id]) + ->who_have_right(['order_master']) + ->execute()->get_results(); + + /** @var ACLProvider $acl */ + $acl = $this->app['acl']; + foreach ($result as $user) { + $acl->get($user)->update_rights_to_base($bas_id, ['order_master' => false]); + } + + foreach ($admins as $admin) { + $acl->get($admin)->update_rights_to_base($bas_id, ['order_master' => true]); + } + $conn->commit(); + } catch (\Exception $e) { + $conn->rollBack(); + throw $e; + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 1, + ]); + } + + /** + * Empty a collection + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function emptyCollection(Request $request, $bas_id) + { + $success = false; + $msg = $this->app->trans('An error occurred'); + + $collection = \collection::get_from_base_id($this->app, $bas_id); + try { + if ($collection->get_record_amount() <= 500) { + $collection->empty_collection(500); + $msg = $this->app->trans('Collection empty successful'); + } else { + $this->app['manipulator.task']->createEmptyCollectionJob($collection); + $msg = $this->app->trans('A task has been creted, please run it to complete empty collection'); + } + + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $msg, + 'bas_id' => $collection->get_base_id() + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + ]); + } + + /** + * Delete the collection stamp + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function deleteStamp(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + null, + \collection::PIC_STAMP + ); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful removal') : $this->app->trans('An error occured'), + 'bas_id' => $collection->get_base_id() + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + ]); + } + + /** + * Delete the collection watermark + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function deleteWatermark(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + null, + \collection::PIC_WM + ); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful removal') : $this->app->trans('An error occured'), + 'bas_id' => $collection->get_base_id(), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + ]); + } + + /** + * Delete the current collection logo + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function deleteLogo(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->update_logo(null); + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + null, + \collection::PIC_LOGO + ); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful removal') : $this->app->trans('An error occured'), + 'bas_id' => $collection->get_base_id(), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + ]); + } + + /** + * Set a collection stamp + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function setStamp(Request $request, $bas_id) + { + if (null === $file = $request->files->get('newStamp')) { + $this->app->abort(400); + } + + if ($file->getClientSize() > 1024 * 1024) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + ]); + } + + if (!$file->isValid()) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + ]); + } + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + $file, + \collection::PIC_STAMP + ); + + $this->app['filesystem']->remove($file->getPathname()); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 1, + ]); + } + + /** + * Set a collection watermark + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function setWatermark(Request $request, $bas_id) + { + if (null === $file = $request->files->get('newWm')) { + $this->app->abort(400); + } + + if ($file->getClientSize() > 65535) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + ]); + } + + if (!$file->isValid()) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + ]); + } + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + $file, + \collection::PIC_WM + ); + $this->app['filesystem']->remove($file->getPathname()); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 1, + ]); + } + + /** + * Set collection minilogo + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function setMiniLogo(Request $request, $bas_id) + { + if (null === $file = $request->files->get('newLogo')) { + $this->app->abort(400); + } + + if ($file->getClientSize() > 65535) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-too-big', + ]); + } + + if (!$file->isValid()) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-invalid', + ]); + } + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $this->app['phraseanet.appbox']->write_collection_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $collection, + $file, + \collection::PIC_LOGO); + $this->app['filesystem']->remove($file->getPathname()); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 0, + 'error' => 'file-error', + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $bas_id, + 'success' => 1, + ]); + } + + /** + * Delete a Collection + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function delete(Request $request, $bas_id) + { + $success = false; + $msg = $this->app->trans('An error occured'); + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + if ($collection->get_record_amount() > 0) { + $msg = $this->app->trans('Empty the collection before removing'); + } else { + $collection->unmount_collection($this->app); + $collection->delete(); + $success = true; + $msg = $this->app->trans('Successful removal'); + } + } catch (\Exception $e) { + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $msg + ]); + } + + if ($collection->get_record_amount() > 0) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => 0, + 'error' => 'collection-not-empty', + ]); + } + + if ($success) { + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1, + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => 0, + ]); + } + + /** + * Unmount a collection from application box + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function unmount(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->unmount_collection($this->app); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + $msg = $success + ? $this->app->trans('The publication has been stopped') + : $this->app->trans('An error occured'); + return $this->app->json([ + 'success' => $success, + 'msg' => $msg, + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + ]); + } + + /** + * Rename a collection + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function rename(Request $request, $bas_id) + { + if (trim($name = $request->request->get('name')) === '') { + $this->app->abort(400, $this->app->trans('Missing name parameter')); + } + + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->set_name($name); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $this->app['request']->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + 'reload-tree' => 1, + ]); + } + + public function labels(Request $request, $bas_id) + { + if (null === $labels = $request->request->get('labels')) { + $this->app->abort(400, $this->app->trans('Missing labels parameter')); + } + if (false === is_array($labels)) { + $this->app->abort(400, $this->app->trans('Invalid labels parameter')); + } + + $collection = \collection::get_from_base_id($this->app, $bas_id); + $success = true; + + try { + foreach ($this->app['locales.available'] as $code => $language) { + if (!isset($labels[$code])) { + continue; + } + $value = $labels[$code] ?: null; + $collection->set_label($code, $value); + } + } catch (\Exception $e) { + $success = false; + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => (int) $success, + 'reload-tree' => 1, + ]); + } + + /** + * Set public presentation watermark + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function setPublicationDisplay(Request $request, $bas_id) + { + if (null === $watermark = $request->request->get('pub_wm')) { + $this->app->abort(400, 'Missing public watermark setting'); + } + + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->set_public_presentation($watermark); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + ]); + } + + /** + * Enable a collection + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function enable(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->enable($this->app['phraseanet.appbox']); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + ]); + } + + /** + * Disable a collection + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function disabled(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + + try { + $collection->disable($this->app['phraseanet.appbox']); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + ]); + } + + /** + * Display suggested values + * + * @param integer $bas_id The collection base_id + * @return string + */ + public function getSuggestedValues($bas_id) + { + /** @var \databox $databox */ + $databox = $this->app['phraseanet.appbox']->get_databox(\phrasea::sbasFromBas($this->app, $bas_id)); + $collection = \collection::get_from_base_id($this->app, $bas_id); + $structFields = $suggestedValues = $basePrefs = []; + + /** @var \databox_field $meta */ + foreach ($databox->get_meta_structure() as $meta) { + if ($meta->is_readonly()) { + continue; + } + + $structFields[$meta->get_name()] = $meta; + } + + if ($sxe = simplexml_load_string($collection->get_prefs())) { + $z = $sxe->xpath('/baseprefs/sugestedValues'); + if ($z && is_array($z)) { + $f = 0; + foreach ($z[0] as $ki => $vi) { + if ($vi && isset($structFields[$ki])) { + foreach ($vi->value as $oneValue) { + $suggestedValues[] = [ + 'key' => $ki, + 'value' => $f, + 'name' => (string) $oneValue + ]; + $f++; + } + } + } + } + + $z = $sxe->xpath('/baseprefs'); + if ($z && is_array($z)) { + /** + * @var string $ki + * @var \SimpleXMLElement $vi + */ + foreach ($z[0] as $ki => $vi) { + $pref = ['status' => null, 'xml' => null]; + + if ($ki == 'status') { + $pref['status'] = $vi; + } elseif ($ki != 'sugestedValues') { + $pref['xml'] = $vi->asXML(); + } + + $basePrefs[] = $pref; + } + } + } + + return $this->render('admin/collection/suggested_value.html.twig', [ + 'collection' => $collection, + 'databox' => $databox, + 'suggestedValues' => $suggestedValues, + 'structFields' => $structFields, + 'basePrefs' => $basePrefs, + ]); + } + + /** + * Register suggested values + * + * @param Request $request The current request + * @param integer $bas_id The collection base_id + * @return Response + */ + public function submitSuggestedValues(Request $request, $bas_id) + { + $success = false; + + $collection = \collection::get_from_base_id($this->app, $bas_id); + $prefs = $request->request->get('str'); + + try { + if ('' !== trim($prefs)) { + $domdoc = new \DOMDocument(); + if (true === @$domdoc->loadXML($prefs)) { + $collection->set_prefs($domdoc); + $success = true; + } + } + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'bas_id' => $collection->get_base_id(), + ]); + } + + return $this->app->redirectPath('admin_collection_display_suggested_values', [ + 'bas_id' => $collection->get_sbas_id(), + 'success' => (int) $success, + ]); + } + + /** + * Get document details in the requested collection + * + * @param integer $bas_id The collection base_id + * @return Response + */ + public function getDetails($bas_id) + { + $collection = \collection::get_from_base_id($this->app, $bas_id); + + $out = ['total' => ['totobj' => 0, 'totsiz' => 0, 'mega' => '0', 'giga' => '0'], 'result' => []]; + + foreach ($collection->get_record_details() as $vrow) { + + $last_k1 = $last_k2 = null; + $outRow = ['midobj' => 0, 'midsiz' => 0]; + + if ($vrow['amount'] > 0 || $last_k1 !== $vrow['coll_id']) { + if (extension_loaded('bcmath')) { + $outRow['midsiz'] = bcadd($outRow['midsiz'], $vrow['size'], 0); + } else { + $outRow['midsiz'] += $vrow['size']; + } + + if ($last_k2 !== $vrow['name']) { + $outRow['name'] = $vrow['name']; + $last_k2 = $vrow['name']; + } + + if (extension_loaded('bcmath')) { + $mega = bcdiv($vrow['size'], 1024 * 1024, 5); + } else { + $mega = $vrow['size'] / (1024 * 1024); + } + + if (extension_loaded('bcmath')) { + $giga = bcdiv($vrow['size'], 1024 * 1024 * 1024, 5); + } else { + $giga = $vrow['size'] / (1024 * 1024 * 1024); + } + + $outRow['mega'] = sprintf('%.2f', $mega); + $outRow['giga'] = sprintf('%.2f', $giga); + $outRow['amount'] = $vrow['amount']; + } + + $out['total']['totobj'] += $outRow['amount']; + + if (extension_loaded('bcmath')) { + $out['total']['totsiz'] = bcadd($out['total']['totsiz'], $outRow['midsiz'], 0); + } else { + $out['total']['totsiz'] += $outRow['midsiz']; + } + + if (extension_loaded('bcmath')) { + $mega = bcdiv($outRow['midsiz'], 1024 * 1024, 5); + } else { + $mega = $outRow['midsiz'] / (1024 * 1024); + } + + if (extension_loaded('bcmath')) { + $giga = bcdiv($outRow['midsiz'], 1024 * 1024 * 1024, 5); + } else { + $giga = $outRow['midsiz'] / (1024 * 1024 * 1024); + } + + $outRow['mega_mid_size'] = sprintf('%.2f', $mega); + $outRow['giga_mid_size'] = sprintf('%.2f', $giga); + + $out['result'][] = $outRow; + } + + if (extension_loaded('bcmath')) { + $out['total']['mega'] = bcdiv($out['total']['totsiz'], 1024 * 1024, 5); + } else { + $out['total']['mega'] = $out['total']['totsiz'] / (1024 * 1024); + } + + if (extension_loaded('bcmath')) { + $out['total']['giga'] = bcdiv($out['total']['totsiz'], 1024 * 1024 * 1024, 5); + } else { + $out['total']['giga'] = $out['total']['totsiz'] / (1024 * 1024 * 1024); + } + + return $this->render('admin/collection/details.html.twig', [ + 'collection' => $collection, + 'table' => $out, + ]); + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php index ac64c19ea5..c5f72e1854 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php @@ -11,21 +11,27 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Phrasea\Exception\RuntimeException; +use Alchemy\Phrasea\Controller\Admin\CollectionController; use Silex\Application; use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Silex\ServiceProviderInterface; -class Collection implements ControllerProviderInterface +class Collection implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.collection'] = $app->share(function () use ($app) { + return new CollectionController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.collection'] = $this; - /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; @@ -113,873 +119,4 @@ class Collection implements ControllerProviderInterface return $controllers; } - - /** - * Display collection information page - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return Response - */ - public function getCollection(Application $app, Request $request, $bas_id) - { - $collection = \collection::get_from_base_id($app, $bas_id); - - $admins = []; - - if ($app['acl']->get($app['authentication']->getUser())->has_right_on_base($bas_id, 'manage')) { - $query = $app['phraseanet.user-query']; - $admins = $query->on_base_ids([$bas_id]) - ->who_have_right(['order_master']) - ->execute() - ->get_results(); - } - - switch ($errorMsg = $request->query->get('error')) { - case 'file-error': - $errorMsg = $app->trans('Error while sending the file'); - break; - case 'file-invalid': - $errorMsg = $app->trans('Invalid file format'); - break; - case 'file-file-too-big': - $errorMsg = $app->trans('The file is too big'); - break; - case 'collection-not-empty': - $errorMsg = $app->trans('Empty the collection before removing'); - break; - } - - return $app['twig']->render('admin/collection/collection.html.twig', [ - 'collection' => $collection, - 'admins' => $admins, - 'errorMsg' => $errorMsg, - 'reloadTree' => $request->query->get('reload-tree') === '1' - ]); - } - - /** - * Set new admin to handle orders - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return RedirectResponse - */ - public function setOrderAdmins(Application $app, Request $request, $bas_id) - { - $success = false; - $admins = array_values($request->request->get('admins', [])); - - if (count($admins) === 0) { - $app->abort(400, 'No admins provided.'); - } - if (!is_array($admins)) { - $app->abort(400, 'Admins must be an array.'); - } - - $admins = array_map(function ($usrId) use ($app) { - if (null === $user = $app['repo.users']->find($usrId)) { - throw new RuntimeException(sprintf('Invalid usrId %s provided.', $usrId)); - } - - return $user; - }, $admins); - - $conn = $app['phraseanet.appbox']->get_connection(); - $conn->beginTransaction(); - - try { - $userQuery = $app['phraseanet.user-query']; - - $result = $userQuery->on_base_ids([$bas_id]) - ->who_have_right(['order_master']) - ->execute()->get_results(); - - foreach ($result as $user) { - $app['acl']->get($user)->update_rights_to_base($bas_id, ['order_master' => false]); - } - - foreach ($admins as $admin) { - $app['acl']->get($admin)->update_rights_to_base($bas_id, ['order_master' => true]); - } - $conn->commit(); - $success = true; - } catch (\Exception $e) { - $conn->rollBack(); - throw $e; - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => (int) $success, - ]); - } - - /** - * Empty a collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function emptyCollection(Application $app, Request $request, $bas_id) - { - $success = false; - $msg = $app->trans('An error occurred'); - - $collection = \collection::get_from_base_id($app, $bas_id); - try { - - if ($collection->get_record_amount() <= 500) { - $collection->empty_collection(500); - $msg = $app->trans('Collection empty successful'); - } else { - $app['manipulator.task']->createEmptyCollectionJob($collection); - $msg = $app->trans('A task has been creted, please run it to complete empty collection'); - } - - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $msg, - 'bas_id' => $collection->get_base_id() - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - ]); - } - - /** - * Delete the collection stamp - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function deleteStamp(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, null, \collection::PIC_STAMP); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), - 'bas_id' => $collection->get_base_id() - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - ]); - } - - /** - * Delete the collection watermark - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function deleteWatermark(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, null, \collection::PIC_WM); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), - 'bas_id' => $collection->get_base_id() - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - ]); - } - - /** - * Delete the current collection logo - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function deleteLogo(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->update_logo(null); - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, null, \collection::PIC_LOGO); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), - 'bas_id' => $collection->get_base_id() - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - ]); - } - - /** - * Set a collection stamp - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return RedirectResponse - */ - public function setStamp(Application $app, Request $request, $bas_id) - { - if (null === $file = $request->files->get('newStamp')) { - $app->abort(400); - } - - if ($file->getClientSize() > 1024 * 1024) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-too-big', - ]); - } - - if (!$file->isValid()) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-invalid', - ]); - } - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, $file, \collection::PIC_STAMP); - - $app['filesystem']->remove($file->getPathname()); - } catch (\Exception $e) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-error', - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 1, - ]); - } - - /** - * Set a collection watermark - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return RedirectResponse - */ - public function setWatermark(Application $app, Request $request, $bas_id) - { - if (null === $file = $request->files->get('newWm')) { - $app->abort(400); - } - - if ($file->getClientSize() > 65535) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-too-big', - ]); - } - - if (!$file->isValid()) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-invalid', - ]); - } - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $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->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-error', - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 1, - ]); - } - - /** - * Set collection minilogo - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return RedirectResponse - */ - public function setMiniLogo(Application $app, Request $request, $bas_id) - { - if (null === $file = $request->files->get('newLogo')) { - $app->abort(400); - } - - if ($file->getClientSize() > 65535) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-too-big', - ]); - } - - if (!$file->isValid()) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-invalid', - ]); - } - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $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->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-error', - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $bas_id, - 'success' => 1, - ]); - } - - /** - * Delete a Collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function delete(Application $app, Request $request, $bas_id) - { - $success = false; - $msg = $app->trans('An error occured'); - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - if ($collection->get_record_amount() > 0) { - $msg = $app->trans('Empty the collection before removing'); - } else { - $collection->unmount_collection($app); - $collection->delete(); - $success = true; - $msg = $app->trans('Successful removal'); - } - } catch (\Exception $e) { - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $msg - ]); - } - - if ($collection->get_record_amount() > 0) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => 0, - 'error' => 'collection-not-empty', - ]); - } - - if ($success) { - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => 1, - 'reload-tree' => 1, - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => 0, - ]); - } - - /** - * Unmount a collection from application box - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function unmount(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->unmount_collection($app); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('The publication has been stopped') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => (int) $success, - ]); - } - - /** - * Rename a collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function rename(Application $app, Request $request, $bas_id) - { - if (trim($name = $request->request->get('name')) === '') { - $app->abort(400, $app->trans('Missing name parameter')); - } - - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->set_name($name); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - 'reload-tree' => 1, - ]); - } - - public function labels(Application $app, Request $request, $bas_id) - { - if (null === $labels = $request->request->get('labels')) { - $app->abort(400, $app->trans('Missing labels parameter')); - } - if (false === is_array($labels)) { - $app->abort(400, $app->trans('Invalid labels parameter')); - } - - $collection = \collection::get_from_base_id($app, $bas_id); - $success = true; - - try { - foreach ($app['locales.available'] as $code => $language) { - if (!isset($labels[$code])) { - continue; - } - $value = $labels[$code] ?: null; - $collection->set_label($code, $value); - } - } catch (\Exception $e) { - $success = false; - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - 'reload-tree' => 1, - ]); - } - - /** - * Set public presentation watermark - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function setPublicationDisplay(Application $app, Request $request, $bas_id) - { - if (null === $watermark = $request->request->get('pub_wm')) { - $app->abort(400, 'Missing public watermark setting'); - } - - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->set_public_presentation($watermark); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => (int) $success, - ]); - } - - /** - * Enable a collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function enable(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->enable($app['phraseanet.appbox']); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => (int) $success, - ]); - } - - /** - * Disable a collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function disabled(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $collection->disable($app['phraseanet.appbox']); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirectPath('admin_display_collection', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => (int) $success, - ]); - } - - /** - * Display suggested values - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - */ - public function getSuggestedValues(Application $app, Request $request, $bas_id) - { - $databox = $app['phraseanet.appbox']->get_databox(\phrasea::sbasFromBas($app, $bas_id)); - $collection = \collection::get_from_base_id($app, $bas_id); - $structFields = $suggestedValues = $basePrefs = []; - - foreach ($databox->get_meta_structure() as $meta) { - if ($meta->is_readonly()) { - continue; - } - - $structFields[$meta->get_name()] = $meta; - } - - if ($sxe = simplexml_load_string($collection->get_prefs())) { - $z = $sxe->xpath('/baseprefs/sugestedValues'); - if ($z && is_array($z)) { - $f = 0; - foreach ($z[0] as $ki => $vi) { - if ($vi && isset($structFields[$ki])) { - foreach ($vi->value as $oneValue) { - $suggestedValues[] = [ - 'key' => $ki, 'value' => $f, 'name' => (string) $oneValue - ]; - $f++; - } - } - } - } - - $z = $sxe->xpath('/baseprefs'); - if ($z && is_array($z)) { - foreach ($z[0] as $ki => $vi) { - $pref = ['status' => null, 'xml' => null]; - - if ($ki == 'status') { - $pref['status'] = $vi; - } elseif ($ki != 'sugestedValues') { - $pref['xml'] = $vi->asXML(); - } - - $basePrefs[] = $pref; - } - } - } - - return $app['twig']->render('admin/collection/suggested_value.html.twig', [ - 'collection' => $collection, - 'databox' => $databox, - 'suggestedValues' => $suggestedValues, - 'structFields' => $structFields, - 'basePrefs' => $basePrefs, - ]); - } - - /** - * Register suggested values - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function submitSuggestedValues(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - $prefs = $request->request->get('str'); - - try { - if ('' !== trim($prefs)) { - $domdoc = new \DOMDocument(); - if (true === @$domdoc->loadXML($prefs)) { - $collection->set_prefs($domdoc); - $success = true; - } - } - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'bas_id' => $collection->get_base_id() - ]); - } - - return $app->redirectPath('admin_collection_display_suggested_values', [ - 'bas_id' => $collection->get_sbas_id(), - 'success' => (int) $success, - ]); - } - - /** - * Get document details in the requested collection - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return Response - */ - public function getDetails(Application $app, Request $request, $bas_id) - { - $collection = \collection::get_from_base_id($app, $bas_id); - - $out = ['total' => ['totobj' => 0, 'totsiz' => 0, 'mega' => '0', 'giga' => '0'], 'result' => []]; - - foreach ($collection->get_record_details() as $vrow) { - - $last_k1 = $last_k2 = null; - $outRow = ['midobj' => 0, 'midsiz' => 0]; - - if ($vrow['amount'] > 0 || $last_k1 !== $vrow['coll_id']) { - - if (extension_loaded('bcmath')) { - $outRow['midsiz'] = bcadd($outRow['midsiz'], $vrow['size'], 0); - } else { - $outRow['midsiz'] += $vrow['size']; - } - - if ($last_k2 !== $vrow['name']) { - $outRow['name'] = $vrow['name']; - $last_k2 = $vrow['name']; - } - - if (extension_loaded('bcmath')) { - $mega = bcdiv($vrow['size'], 1024 * 1024, 5); - } else { - $mega = $vrow['size'] / (1024 * 1024); - } - - if (extension_loaded('bcmath')) { - $giga = bcdiv($vrow['size'], 1024 * 1024 * 1024, 5); - } else { - $giga = $vrow['size'] / (1024 * 1024 * 1024); - } - - $outRow['mega'] = sprintf('%.2f', $mega); - $outRow['giga'] = sprintf('%.2f', $giga); - $outRow['amount'] = $vrow['amount']; - } - - $out['total']['totobj'] += $outRow['amount']; - - if (extension_loaded('bcmath')) { - $out['total']['totsiz'] = bcadd($out['total']['totsiz'], $outRow['midsiz'], 0); - } else { - $out['total']['totsiz'] += $outRow['midsiz']; - } - - if (extension_loaded('bcmath')) { - $mega = bcdiv($outRow['midsiz'], 1024 * 1024, 5); - } else { - $mega = $outRow['midsiz'] / (1024 * 1024); - } - - if (extension_loaded('bcmath')) { - $giga = bcdiv($outRow['midsiz'], 1024 * 1024 * 1024, 5); - } else { - $giga = $outRow['midsiz'] / (1024 * 1024 * 1024); - } - - $outRow['mega_mid_size'] = sprintf('%.2f', $mega); - $outRow['giga_mid_size'] = sprintf('%.2f', $giga); - - $out['result'][] = $outRow; - } - - if (extension_loaded('bcmath')) { - $out['total']['mega'] = bcdiv($out['total']['totsiz'], 1024 * 1024, 5); - } else { - $out['total']['mega'] = $out['total']['totsiz'] / (1024 * 1024); - } - - if (extension_loaded('bcmath')) { - $out['total']['giga'] = bcdiv($out['total']['totsiz'], 1024 * 1024 * 1024, 5); - } else { - $out['total']['giga'] = $out['total']['totsiz'] / (1024 * 1024 * 1024); - } - - return $app['twig']->render('admin/collection/details.html.twig', [ - 'collection' => $collection, - 'table' => $out, - ]); - } } From 9c7af310805ff5d57ea976faafe3e6b4457cd741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Mon, 30 Mar 2015 20:11:51 +0200 Subject: [PATCH 15/26] Admin Connected Users --- lib/Alchemy/Phrasea/Application.php | 19 ++- .../Admin/ConnectedUsersController.php | 129 +++++++++++++++++ .../Admin/ConnectedUsers.php | 130 ++++-------------- .../Controller/Admin/ConnectedUserTest.php | 13 -- .../Admin/ConnectedUsersControllerTest.php | 77 +++++++++++ 5 files changed, 241 insertions(+), 127 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php create mode 100644 tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUsersControllerTest.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 2c7bfac4fc..13e698b595 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea; use Alchemy\Geonames\GeonamesServiceProvider; -use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; use Alchemy\Phrasea\ControllerProvider\Admin\Dashboard; use Alchemy\Phrasea\ControllerProvider\Admin\Databox; use Alchemy\Phrasea\ControllerProvider\Admin\Databoxes; @@ -313,6 +312,7 @@ class Application extends SilexApplication $providers = [ 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], @@ -443,9 +443,6 @@ class Application extends SilexApplication $twig->addFilter('count', new \Twig_Filter_Function('count')); $twig->addFilter('formatOctets', new \Twig_Filter_Function('p4string::format_octets')); $twig->addFilter('base_from_coll', new \Twig_Filter_Function('phrasea::baseFromColl')); - $twig->addFilter(new \Twig_SimpleFilter('AppName', function ($value) use ($app) { - return ConnectedUsers::appName($app['translator'], $value); - })); $twig->addFilter(new \Twig_SimpleFilter('escapeSimpleQuote', function ($value) { return str_replace("'", "\\'", $value); })); @@ -626,7 +623,6 @@ class Application extends SilexApplication $this->mount('/admin/databoxes', new Databoxes()); $this->mount('/admin/setup', new Setup()); $this->mount('/admin/search-engine', new SearchEngine()); - $this->mount('/admin/connected-users', new ConnectedUsers()); $this->mount('/admin/publications', new Publications()); $this->mount('/admin/users', new Users()); $this->mount('/admin/fields', new Fields()); @@ -674,12 +670,13 @@ class Application extends SilexApplication $this->mount('/xmlhttp', new ThesaurusXMLHttp()); $providers = [ - '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', - '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', - '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', - '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', - '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', - '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', + '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', + '/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers', + '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', + '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', + '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', + '/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink', + '/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup', ]; foreach ($providers as $prefix => $class) { $this->mount($prefix, new $class); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php new file mode 100644 index 0000000000..b39f2dfbfa --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php @@ -0,0 +1,129 @@ +app = $app; + $this->translator = $app['translator']; + $this->logger = $app['monolog']; + } + + public function listConnectedUsers(Request $request) + { + $dql = 'SELECT s FROM Phraseanet:Session s WHERE s.updated > :date ORDER BY s.updated DESC'; + $date = new \DateTime('-2 hours'); + + /** @var EntityManager $manager */ + $manager = $this->app['orm.em']; + + $query = $manager->createQuery($dql); + $query->setParameter('date', $date->format('Y-m-d h:i:s')); + /** @var Session[] $sessions */ + $sessions = $query->getResult(); + + $result = []; + + foreach ($sessions as $session) { + $info = ''; + try { + /** @var Geoname $geoname */ + $geoname = $this->app['geonames.connector']->ip($session->getIpAddress()); + $country = $geoname->get('country'); + $city = $geoname->get('city'); + $region = $geoname->get('region'); + + $countryName = isset($country['name']) ? $country['name'] : null; + $regionName = isset($region['name']) ? $region['name'] : null; + + if (null !== $city) { + $info = $city . ($countryName ? ' (' . $countryName . ')' : null); + } elseif (null !== $regionName) { + $info = $regionName . ($countryName ? ' (' . $countryName . ')' : null); + } elseif (null !== $countryName) { + $info = $countryName; + } else { + $info = ''; + } + } catch (ExceptionInterface $e) { + $this->logger->error( + sprintf("Unable to get IP information for %s", $session->getIpAddress()), + ['exception' => $e] + ); + } + + $result[] = [ + 'session' => $session, + 'info' => $info, + ]; + } + + $ret = [ + 'sessions' => $result, + 'applications' => array_fill(0, 9, 0), + ]; + + foreach ($result as $session) { + foreach ($session['session']->getModules() as $module) { + if (isset($ret['applications'][$module->getModuleId()])) { + $ret['applications'][$module->getModuleId()]++; + } + } + } + + return $this->app['twig']->render('admin/connected-users.html.twig', ['data' => $ret]); + } + + /** + * Return module name according to its ID + * + * @param integer $appId + * @return string + */ + public function getModuleNameFromId($appId) + { + if (null === $this->moduleNames) { + $translator = $this->translator; + $this->moduleNames = [ + '0' => $translator->trans('admin::monitor: module inconnu'), + '1' => $translator->trans('admin::monitor: module production'), + '2' => $translator->trans('admin::monitor: module client'), + '3' => $translator->trans('admin::monitor: module admin'), + '4' => $translator->trans('admin::monitor: module report'), + '5' => $translator->trans('admin::monitor: module thesaurus'), + '6' => $translator->trans('admin::monitor: module comparateur'), + '7' => $translator->trans('admin::monitor: module validation'), + '8' => $translator->trans('admin::monitor: module upload'), + ]; + } + + return isset($this->moduleNames[$appId]) ? $this->moduleNames[$appId] : null; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php index a881a6fee8..122116a22a 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php @@ -11,23 +11,43 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Geonames\Exception\ExceptionInterface as GeonamesExceptionInterface; +use Alchemy\Phrasea\Controller\Admin\ConnectedUsersController; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Translation\TranslatorInterface; +use Silex\ServiceProviderInterface; -class ConnectedUsers implements ControllerProviderInterface +class ConnectedUsers implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.connected-users'] = $app->share(function () use ($app) { + return new ConnectedUsersController($app); + }); + + $app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twig, Application $app) { + $twig->addFilter(new \Twig_SimpleFilter('AppName', function ($value) use ($app) { + /** @var ConnectedUsersController $controller */ + $controller = $app['controller.admin.connected-users']; + return $controller->getModuleNameFromId($value); + })); + + return $twig; + })); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.connected-users'] = $this; - + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; $app['firewall']->addMandatoryAuthentication($controllers); - $controllers->before(function (Request $request) use ($app) { + $controllers->before(function () use ($app) { $app['firewall']->requireAccessToModule('Admin'); }); @@ -36,100 +56,4 @@ class ConnectedUsers implements ControllerProviderInterface return $controllers; } - - public function listConnectedUsers(Application $app, Request $request) - { - $dql = 'SELECT s FROM Phraseanet:Session s - WHERE - s.updated > :date - ORDER BY s.updated DESC'; - - $date = new \DateTime('-2 hours'); - $params = ['date' => $date->format('Y-m-d h:i:s')]; - - $query = $app['orm.em']->createQuery($dql); - $query->setParameters($params); - $sessions = $query->getResult(); - - $result = []; - - foreach ($sessions as $session) { - $info = ''; - try { - $geoname = $app['geonames.connector']->ip($session->getIpAddress()); - $country = $geoname->get('country'); - $city = $geoname->get('city'); - $region = $geoname->get('region'); - - $countryName = isset($country['name']) ? $country['name'] : null; - $regionName = isset($region['name']) ? $region['name'] : null; - - if (null !== $city) { - $info = $city . ($countryName ? ' (' . $countryName . ')' : null); - } elseif (null !== $regionName) { - $info = $regionName . ($countryName ? ' (' . $countryName . ')' : null); - } elseif (null !== $countryName) { - $info = $countryName; - } else { - $info = ''; - } - } catch (GeonamesExceptionInterface $e) { - $app['monolog']->error(sprintf("Unable to get IP information for %s", $session->getIpAddress()), ['exception' => $e]); - } - - $result[] = [ - 'session' => $session, - 'info' => $info, - ]; - } - - $ret = [ - 'sessions' => $result, - 'applications' => [ - '0' => 0, - '1' => 0, - '2' => 0, - '3' => 0, - '4' => 0, - '5' => 0, - '6' => 0, - '7' => 0, - '8' => 0, - ] - ]; - - foreach ($result as $session) { - foreach ($session['session']->getModules() as $module) { - if (isset($ret['applications'][$module->getModuleId()])) { - $ret['applications'][$module->getModuleId()]++; - } - } - } - - return $app['twig']->render('admin/connected-users.html.twig', ['data' => $ret]); - } - - /** - * Return module name according to its ID - * - * @param integer $appId - * @return string - * @return null - */ - public static function appName(TranslatorInterface $translator, $appId) - { - $appRef = [ - '0' => $translator->trans('admin::monitor: module inconnu'), - '1' => $translator->trans('admin::monitor: module production'), - '2' => $translator->trans('admin::monitor: module client'), - '3' => $translator->trans('admin::monitor: module admin'), - '4' => $translator->trans('admin::monitor: module report'), - '5' => $translator->trans('admin::monitor: module thesaurus'), - '6' => $translator->trans('admin::monitor: module comparateur'), - '7' => $translator->trans('admin::monitor: module validation'), - '8' => $translator->trans('admin::monitor: module upload'), - ]; - - return isset($appRef[$appId]) ? $appRef[$appId] : null; - } } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php index 7007879dab..e9e8b7e9f5 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php @@ -2,8 +2,6 @@ namespace Alchemy\Tests\Phrasea\Controller\Admin; -use Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers; - class ConnectedUserTest extends \PhraseanetAuthenticatedWebTestCase { protected $client; @@ -16,15 +14,4 @@ class ConnectedUserTest extends \PhraseanetAuthenticatedWebTestCase self::$DI['client']->request('GET', '/admin/connected-users/'); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); } - - /** - * @covers \Alchemy\Phrasea\Controller\Admin\ConnectedUsers::appName - */ - public function testAppName() - { - $appNameResult = ConnectedUsers::appName(self::$DI['app']['translator'], 1000); - $this->assertNull($appNameResult); - $appNameResult = ConnectedUsers::appName(self::$DI['app']['translator'], 0); - $this->assertTrue(is_string($appNameResult)); - } } diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUsersControllerTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUsersControllerTest.php new file mode 100644 index 0000000000..3aadb732b6 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUsersControllerTest.php @@ -0,0 +1,77 @@ +getMock(TranslatorInterface::class); + $translator + ->expects($this->exactly(9)) + ->method('trans') + ->willReturnMap([ + ['admin::monitor: module inconnu', [], null, null, 'module0'], + ['admin::monitor: module production', [], null, null, 'module1'], + ['admin::monitor: module client', [], null, null, 'module2'], + ['admin::monitor: module admin', [], null, null, 'module3'], + ['admin::monitor: module report', [], null, null, 'module4'], + ['admin::monitor: module thesaurus', [], null, null, 'module5'], + ['admin::monitor: module comparateur', [], null, null, 'module6'], + ['admin::monitor: module validation', [], null, null, 'module7'], + ['admin::monitor: module upload', [], null, null, 'module8'], + [null, [], null, null, null], + ]); + + $app = $this->getMockBuilder(Application::class) + ->disableOriginalConstructor() + ->getMock() + ; + $app->expects($this->any()) + ->method('offsetGet') + ->willReturnMap([ + ['translator', $translator], + ['monolog', $this->getMock(LoggerInterface::class)], + ]); + + $controller = new ConnectedUsersController($app); + + $this->assertSame($expected, $controller->getModuleNameFromId($id)); + // Calling twig should not duplicate translator calls + $this->assertSame($expected, $controller->getModuleNameFromId($id)); + } + + public function provideModuleNames() + { + return [ + ['0', 'module0'], + ['1', 'module1'], + ['2', 'module2'], + ['3', 'module3'], + ['4', 'module4'], + ['5', 'module5'], + ['6', 'module6'], + ['7', 'module7'], + ['8', 'module8'], + ['9', null], + ]; + } +} From feddae6ac7f247cfbc0f0d895399e4e3dfd58fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Tue, 31 Mar 2015 19:57:14 +0200 Subject: [PATCH 16/26] UserController refactor --- lib/Alchemy/Phrasea/Application.php | 4 +- .../Controller/Admin/UserController.php | 1076 +++++++++++++++++ .../ControllerProvider/Admin/Users.php | 940 +------------- lib/Alchemy/Phrasea/Helper/User/Manage.php | 3 + .../Phrasea/Model/Entities/Registration.php | 3 +- .../Repositories/RegistrationRepository.php | 3 +- lib/classes/ACL.php | 2 +- lib/classes/User/Query.php | 2 +- 8 files changed, 1142 insertions(+), 891 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/UserController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 13e698b595..29ed265713 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -22,7 +22,6 @@ use Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine; use Alchemy\Phrasea\ControllerProvider\Admin\Setup; use Alchemy\Phrasea\ControllerProvider\Admin\Subdefs; use Alchemy\Phrasea\ControllerProvider\Admin\TaskManager; -use Alchemy\Phrasea\ControllerProvider\Admin\Users; use Alchemy\Phrasea\ControllerProvider\Client\Root as ClientRoot; use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; @@ -313,6 +312,7 @@ class Application extends SilexApplication $providers = [ 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], @@ -624,7 +624,6 @@ class Application extends SilexApplication $this->mount('/admin/setup', new Setup()); $this->mount('/admin/search-engine', new SearchEngine()); $this->mount('/admin/publications', new Publications()); - $this->mount('/admin/users', new Users()); $this->mount('/admin/fields', new Fields()); $this->mount('/admin/task-manager', new TaskManager()); $this->mount('/admin/subdefs', new Subdefs()); @@ -672,6 +671,7 @@ class Application extends SilexApplication $providers = [ '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', '/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers', + '/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users', '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', '/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox', diff --git a/lib/Alchemy/Phrasea/Controller/Admin/UserController.php b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php new file mode 100644 index 0000000000..d8c44a5503 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php @@ -0,0 +1,1076 @@ +app = $app; + } + + public function editRightsAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + return $this->render('admin/editusers.html.twig', $rights->get_users_rights()); + } + + public function resetRightsAction(Request $request) + { + try { + $data = ['error' => false]; + + $helper = $this->getUserEditHelper($request); + $helper->resetRights(); + } catch (\Exception $e) { + $data['error'] = true; + $data['message'] = $e->getMessage(); + } + + return $this->app->json($data); + } + + public function deleteUserAction(Request $request) + { + $module = $this->getUserEditHelper($request); + $module->delete_users(); + + return $this->app->redirectPath('admin_users_search'); + } + + public function applyRightsAction(Request $request) + { + $data = ['error' => true]; + + try { + $rights = $this->getUserEditHelper($request); + + $resetBeforeApply = (bool) $request->request->get('reset_before_apply', false); + if (!$resetBeforeApply) { + $rights->apply_rights(); + } + + if ($request->request->get('template')) { + if ($resetBeforeApply) { + $rights->resetRights(); + } + $rights->apply_template(); + } + + $rights->apply_infos(); + + $data = ['error' => false]; + } catch (\Exception $e) { + $data['message'] = $e->getMessage(); + } + + return $this->app->json($data); + } + + public function editQuotasRightsAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + return $this->render('admin/editusers_quotas.html.twig', $rights->get_quotas()); + } + + public function applyQuotasAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + $rights->apply_quotas(); + + return $this->app->json(['message' => '', 'error' => false]); + } + + public function editTimeLimitAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + + return $this->render('admin/editusers_timelimit.html.twig', $rights->get_time()); + } + + public function editTimeLimitSbasAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + + return $this->render('admin/editusers_timelimit_sbas.html.twig', $rights->get_time_sbas()); + } + + public function applyTimeAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + $rights->apply_time(); + + return $this->app->json(['message' => '', 'error' => false]); + } + + public function editMasksAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + + return $this->render('admin/editusers_masks.html.twig', $rights->get_masks()); + } + + public function applyMasksAction(Request $request) + { + $rights = $this->getUserEditHelper($request); + $rights->apply_masks(); + + return $this->app->json(['message' => '', 'error' => false]); + } + + public function searchAction(Request $request) + { + return $this->render('admin/users.html.twig', $this->getUserManageHelper($request)->search()); + } + + public function searchExportAction(Request $request) + { + $users = $this->getUserManageHelper($request); + $userTable = [ + [ + 'ID', + 'Login', + 'Last Name', + 'First Name', + 'E-Mail', + 'Created', + 'Updated', + 'Address', + 'City', + 'Zip', + 'Country', + 'Phone', + 'Fax', + 'Job', + 'Company', + 'Position' + ] + ]; + + foreach ($users->export() as $user) { + $userTable[] = [ + $user->getId(), + $user->getLogin(), + $user->getLastName(), + $user->getFirstName(), + $user->getEmail(), + $user->getCreated()->format(DATE_ATOM), + $user->getUpdated()->format(DATE_ATOM), + $user->getAddress(), + $user->getCity(), + $user->getZipCode(), + $user->getCountry(), + $user->getPhone(), + $user->getFax(), + $user->getJob(), + $user->getCompany(), + $user->getActivity() + ]; + } + + $filename = sprintf('user_export_%s.csv', date('Ymd')); + $exporter = $this->getCsvExporter(); + + return new CSVFileResponse($filename, function () use ($exporter, $userTable) { + $exporter->export('php://output', $userTable); + }); + } + + public function applyTemplateAction(Request $request) + { + $users = $this->getUserEditHelper($request); + if ($request->request->get('reset_before_apply')) { + $users->resetRights(); + } + $users->apply_template(); + + return $this->app->redirectPath('admin_users_search'); + } + + public function typeAheadSearchAction(Request $request) + { + $user_query = $this->createUserQuery(); + + $like_value = $request->query->get('term'); + $rights = $request->query->get('filter_rights') ? : []; + $have_right = $request->query->get('have_right') ? : []; + $have_not_right = $request->query->get('have_not_right') ? : []; + $on_base = $request->query->get('on_base') ? : []; + + $eligible_users = $user_query + ->on_sbas_where_i_am($this->getAclForConnectedUser(), $rights) + ->like(\User_Query::LIKE_EMAIL, $like_value) + ->like(\User_Query::LIKE_FIRSTNAME, $like_value) + ->like(\User_Query::LIKE_LASTNAME, $like_value) + ->like(\User_Query::LIKE_LOGIN, $like_value) + ->like_match(\User_Query::LIKE_MATCH_OR) + ->who_have_right($have_right) + ->who_have_not_right($have_not_right) + ->on_base_ids($on_base) + ->execute() + ->get_results(); + + $data = []; + foreach ($eligible_users as $user) { + $data[] = [ + 'email' => $user->getEmail() ? : '', + 'login' => $user->getLogin() ? : '', + 'name' => $user->getDisplayName(), + 'id' => $user->getId(), + ]; + } + + return $this->app->json($data); + } + + public function createAction(Request $request) + { + $data = ['error' => false, 'message' => '', 'data' => null]; + try { + $module = $this->getUserManageHelper($request); + if ($request->request->get('template') == '1') { + $user = $module->create_template(); + } else { + $user = $module->create_newuser(); + } + if (!$user instanceof User) { + throw new \Exception('Unknown error'); + } + + $data['data'] = $user->getId(); + } catch (\Exception $e) { + $data['error'] = true; + if ($request->request->get('template') == '1') { + $data['message'] = $this->app->trans('Unable to create template, the name is already used.'); + } else { + $data['message'] = $this->app->trans('Unable to create the user.'); + } + } + + return $this->app->json($data); + } + + public function exportAction(Request $request) + { + $user_query = $this->createUserQuery(); + + $like_value = $request->request->get('like_value'); + $like_field = $request->request->get('like_field'); + $on_base = $request->request->get('base_id') ? : null; + $on_sbas = $request->request->get('sbas_id') ? : null; + + $eligible_users = $user_query->on_bases_where_i_am($this->getAclForConnectedUser(), ['canadmin']) + ->like($like_field, $like_value) + ->on_base_ids($on_base) + ->on_sbas_ids($on_sbas); + + $offset = 0; + $buffer = []; + $buffer[] = [ + 'ID', + 'Login', + $this->app->trans('admin::compte-utilisateur nom'), + $this->app->trans('admin::compte-utilisateur prenom'), + $this->app->trans('admin::compte-utilisateur email'), + 'CreationDate', + 'ModificationDate', + $this->app->trans('admin::compte-utilisateur adresse'), + $this->app->trans('admin::compte-utilisateur ville'), + $this->app->trans('admin::compte-utilisateur code postal'), + $this->app->trans('admin::compte-utilisateur pays'), + $this->app->trans('admin::compte-utilisateur telephone'), + $this->app->trans('admin::compte-utilisateur fax'), + $this->app->trans('admin::compte-utilisateur poste'), + $this->app->trans('admin::compte-utilisateur societe'), + $this->app->trans('admin::compte-utilisateur activite'), + ]; + do { + $eligible_users->limit($offset, 20); + $offset += 20; + + $results = $eligible_users->execute()->get_results(); + + foreach ($results as $user) { + $buffer[] = [ + $user->getId(), + $user->getLogin(), + $user->getLastName(), + $user->getFirstName(), + $user->getEmail(), + $this->app['date-formatter']->format_mysql($user->getCreated()), + $this->app['date-formatter']->format_mysql($user->getUpdated()), + $user->getAddress(), + $user->getCity(), + $user->getZipCode(), + $user->getCountry(), + $user->getPhone(), + $user->getFax(), + $user->getJob(), + $user->getCompany(), + $user->getActivity(), + ]; + } + } while (count($results) > 0); + + $filename = sprintf('user_export_%s.csv', date('Ymd')); + $exporter = $this->getCsvExporter(); + return new CSVFileResponse($filename, function () use ($exporter, $buffer) { + $exporter->export('php://output', $buffer); + }); + } + + public function displayRegistrationsAction() + { + $this->getRegistrationManipulator()->deleteOldRegistrations(); + + /** @var UserRepository $userRepository */ + $userRepository = $this->app['repo.users']; + $authenticatedUser = $this->getAuthenticatedUser(); + $models = $userRepository->findTemplateOwner($authenticatedUser); + + $userRegistrations = []; + /** @var RegistrationRepository $registrationRepository */ + $registrationRepository = $this->app['repo.registrations']; + foreach ( + $registrationRepository->getUserRegistrations( + $authenticatedUser, + $this->getAclForConnectedUser()->get_granted_base(['canadmin']) + ) as $registration) { + $user = $registration->getUser(); + $userRegistrations[$user->getId()]['user'] = $user; + $userRegistrations[$user->getId()]['registrations'][$registration->getBaseid()] = $registration; + } + + return $this->render('admin/user/registrations.html.twig', [ + 'user_registrations' => $userRegistrations, + 'models' => $models, + ]); + } + + public function submitRegistrationAction(Request $request) + { + $templates = $this->normalizeTemplateArray($request->request->get('template', [])); + $deny = $this->normalizeDenyArray($request->request->get('deny', []), $templates); + + $accepts = $request->request->get('accept', []); + $accept = $options = []; + foreach ($accepts as $acc) { + $acc = explode('_', $acc); + if (count($acc) == 2 && !isset($templates[$acc[0]])) { + $accept[$acc[0]][$acc[1]] = $acc[1]; + $options[$acc[0]][$acc[1]] = ['HD' => false, 'WM' => false]; + } + } + + foreach ($request->request->get('accept_hd', []) as $accHD) { + $accHD = explode('_', $accHD); + if (count($accHD) == 2 && isset($accept[$accHD[0]]) && isset($options[$accHD[0]][$accHD[1]])) { + $options[$accHD[0]][$accHD[1]]['HD'] = true; + } + } + + foreach ($request->request->get('watermark', []) as $wm) { + $wm = explode('_', $wm); + if (count($wm) == 2 && isset($accept[$wm[0]]) && isset($options[$wm[0]][$wm[1]])) { + $options[$wm[0]][$wm[1]]['WM'] = true; + } + } + + $registrationManipulator = $this->getRegistrationManipulator(); + if (count($templates) > 0 || count($deny) > 0 || count($accept) > 0) { + $cacheToUpdate = $done = []; + + /** @var UserRepository $userRepository */ + $userRepository = $this->app['repo.users']; + $searchedUserIds = array_unique(array_merge( + array_keys($templates), + array_keys($deny), + array_keys($accept) + )); + // Load all user entities needed afterwards + $userRepository->findBy(['id' => $searchedUserIds]); + foreach ($templates as $usr => $template_id) { + /** @var User $user */ + $user = $userRepository->find($usr); + if (null === $user) { + $this->app->abort(400, sprintf("User with id % in provided in 'template' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; + + /** @var User $user_template */ + $user_template = $userRepository->find($template_id); + $collections = $this->getAclForUser($user_template)->get_granted_base(); + $baseIds = array_keys($collections); + + $this->getAclForUser($user)->apply_model($user_template, $baseIds); + + foreach ($collections as $collection) { + $done[$usr][$collection->get_base_id()] = true; + } + + $registrationManipulator->deleteUserRegistrations($user, $collections); + } + + /** @var RegistrationRepository $registrationRepository */ + $registrationRepository = $this->app['repo.registrations']; + foreach ($deny as $usr => $bases) { + /** @var User $user */ + $user = $userRepository->find($usr); + if (null === $user) { + $this->app->abort(400, sprintf("User with id % in provided in 'deny' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; + foreach ( + $registrationRepository->getUserRegistrations( + $user, + array_map(function ($baseId) { + return \collection::get_from_base_id($this->app, $baseId); + }, $bases) + ) as $registration) { + $registrationManipulator->rejectRegistration($registration); + $done[$usr][$registration->getBaseId()] = false; + } + } + + foreach ($accept as $usr => $bases) { + /** @var User $user */ + $user = $userRepository->find($usr); + if (null === $user) { + $this->app->abort(400, sprintf("User with id % in provided in 'accept' request variable could not be found", $usr)); + } + $cacheToUpdate[$usr] = $user; + foreach ($registrationRepository->getUserRegistrations( + $user, + array_map(function ($baseId) { + return \collection::get_from_base_id($this->app, $baseId); + }, $bases) + ) as $registration) { + $done[$usr][$registration->getBaseId()] = true; + $registrationManipulator->acceptRegistration( + $registration, + $options[$usr][$registration->getBaseId()]['HD'], + $options[$usr][$registration->getBaseId()]['WM'] + ); + } + } + + array_walk($cacheToUpdate, function (User $user) { + $this->getAclForUser($user)->delete_data_from_cache(); + }); + unset ($cacheToUpdate); + + foreach ($done as $usr => $bases) { + $user = $userRepository->find($usr); + $acceptColl = $denyColl = []; + + foreach ($bases as $bas => $isok) { + $collection = \collection::get_from_base_id($this->app, $bas); + + if ($isok) { + $acceptColl[] = $collection->get_label($this->app['locale']); + continue; + } + + $denyColl[] = $collection->get_label($this->app['locale']); + } + + if (0 !== count($acceptColl) || 0 !== count($denyColl)) { + $message = ''; + if (0 !== count($acceptColl)) { + $message .= "\n" . $this->app->trans('login::register:email: Vous avez ete accepte sur les collections suivantes : ') . implode(', ', $acceptColl). "\n"; + } + if (0 !== count($denyColl)) { + $message .= "\n" . $this->app->trans('login::register:email: Vous avez ete refuse sur les collections suivantes : ') . implode(', ', $denyColl) . "\n"; + } + + $receiver = new Receiver(null, $user->getEmail()); + $mail = MailSuccessEmailUpdate::create($this->app, $receiver, null, $message); + + /** @var Deliverer $deliverer */ + $deliverer = $this->app['notification.deliverer']; + $deliverer->deliver($mail); + } + } + } + + return $this->app->redirectPath('users_display_registrations', ['success' => 1]); + } + + public function displayImportFileAction() + { + return $this->render('admin/user/import/file.html.twig'); + } + + public function submitImportFileAction(Request $request) + { + if ((null === $file = $request->files->get('files')) || !$file->isValid()) { + return $this->app->redirectPath('users_display_import_file', ['error' => 'file-invalid']); + } + + $equivalenceToMysqlField = $this->getEquivalenceToMysqlField(); + $loginDefined = $pwdDefined = $mailDefined = false; + $loginNew = []; + $out = [ + 'ignored_row' => [], + 'errors' => [] + ]; + $nbUsrToAdd = 0; + + $lines = []; + /** @var Interpreter $interpreter */ + $interpreter = $this->app['csv.interpreter']; + $interpreter->addObserver(function (array $row) use (&$lines) { + $lines[] = $row; + }); + $this->app['csv.lexer']->parse($file->getPathname(), $interpreter); + + $roughColumns = array_shift($lines); + + $columnsSanitized = array_map(function ($columnName) { + return trim(mb_strtolower($columnName)); + }, $roughColumns); + + $columns = array_filter($columnsSanitized, function ($columnName) use (&$out, $equivalenceToMysqlField) { + if (!isset($equivalenceToMysqlField[$columnName])) { + $out['ignored_row'][] = $columnName; + + return false; + } + + return true; + }); + + foreach ($columns as $columnName) { + if ($equivalenceToMysqlField[$columnName] === 'usr_login') { + $loginDefined = true; + } + + if (($equivalenceToMysqlField[$columnName]) === 'usr_password') { + $pwdDefined = true; + } + + if (($equivalenceToMysqlField[$columnName]) === 'usr_mail') { + $mailDefined = true; + } + } + + if (!$loginDefined) { + return $this->app->redirectPath('users_display_import_file', ['error' => 'row-login']); + } + + if (!$pwdDefined) { + return $this->app->redirectPath('users_display_import_file', ['error' => 'row-pwd']); + } + + if (!$mailDefined) { + return $this->app->redirectPath('users_display_import_file', ['error' => 'row-mail']); + } + + /** @var UserRepository $userRepository */ + $userRepository = $this->app['repo.users']; + foreach ($lines as $nbLine => $line) { + $loginValid = false; + $pwdValid = false; + $mailValid = false; + + foreach ($columns as $nbCol => $colName) { + if (!isset($equivalenceToMysqlField[$colName])) { + unset($lines[$nbCol]); + continue; + } + + $sqlField = $equivalenceToMysqlField[$colName]; + $value = $line[$nbCol]; + + if ($sqlField === 'usr_login') { + $loginToAdd = $value; + if ($loginToAdd === "") { + $out['errors'][] = $this->app->trans("Login line %line% is empty", ['%line%' => $nbLine + 1]); + } elseif (in_array($loginToAdd, $loginNew)) { + $out['errors'][] = $this->app->trans( + "Login %login% is already defined in the file at line %line%", + ['%login%' => $loginToAdd, '%line%' => $nbLine] + ); + } else { + if (null !== $userRepository->findByLogin($loginToAdd)) { + $out['errors'][] = $this->app->trans( + "Login %login% already exists in database", + ['%login%' => $loginToAdd] + ); + } else { + $loginValid = true; + } + } + } + + if ($loginValid && $sqlField === 'usr_mail') { + $mailToAdd = $value; + + if ($mailToAdd === "") { + $out['errors'][] = $this->app->trans("Mail line %line% is empty", ['%line%' => $nbLine + 1]); + } elseif (null !== $userRepository->findByEmail($mailToAdd)) { + $out['errors'][] = $this->app->trans( + "Email '%email%' for login '%login%' already exists in database", + ['%email%' => $mailToAdd, '%login%' => $loginToAdd] + ); + } else { + $mailValid = true; + } + } + + if ($sqlField === 'usr_password') { + $passwordToVerif = $value; + + if ($passwordToVerif === "") { + $out['errors'][] = $this->app->trans("Password is empty at line %line%", ['%line%' => $nbLine]); + } else { + $pwdValid = true; + } + } + } + + if ($loginValid && $pwdValid && $mailValid) { + $loginNew[] = $loginToAdd; + $nbUsrToAdd++; + } + } + + if (count($out['errors']) > 0 && $nbUsrToAdd === 0) { + return $this->render('admin/user/import/file.html.twig', [ + 'errors' => $out['errors'] + ]); + } + + if ($nbUsrToAdd === 0) { + return $this->app->redirectPath('users_display_import_file', [ + 'error' => 'no-user' + ]); + } + + $basList = array_keys($this->getAclForConnectedUser()->get_granted_base(['manage'])); + /** @var NativeQueryProvider $query */ + $query = $this->app['orm.em.native-query']; + $models = $query->getModelForUser($this->getAuthenticatedUser(), $basList); + + return $this->render('/admin/user/import/view.html.twig', [ + 'nb_user_to_add' => $nbUsrToAdd, + 'models' => $models, + 'lines_serialized' => serialize($lines), + 'columns_serialized' => serialize($columns), + 'errors' => $out['errors'] + ]); + } + + public function submitImportAction(Request $request) + { + $nbCreation = 0; + + if ((null === $serializedColumns = $request->request->get('sr_columns')) || ('' === $serializedColumns)) { + $this->app->abort(400); + } + + if ((null === $serializedLines = $request->request->get('sr_lines')) || ('' === $serializedLines)) { + $this->app->abort(400); + } + + if (null === $model = $request->request->get("modelToApply")) { + $this->app->abort(400); + } + + $lines = unserialize($serializedLines); + $columns = unserialize($serializedColumns); + + $equivalenceToMysqlField = $this->getEquivalenceToMysqlField(); + + foreach ($lines as $nbLine => $line) { + $curUser = []; + foreach ($columns as $nbCol => $colName) { + if (!isset($equivalenceToMysqlField[$colName]) || !isset($line[$nbCol])) { + continue; + } + + $sqlField = $equivalenceToMysqlField[$colName]; + $value = trim($line[$nbCol]); + + if ($sqlField === "usr_sexe") { + switch ($value) { + case "Mlle": + case "Mlle.": + case "mlle": + case "Miss": + case "miss": + case "0": + $curUser[$sqlField] = 0; + break; + + case "Mme": + case "Madame": + case "Ms": + case "Ms.": + case "1": + $curUser[$sqlField] = 1; + break; + + case "M": + case "M.": + case "Mr": + case "Mr.": + case "Monsieur": + case "Mister": + case "2": + $curUser[$sqlField] = 2; + break; + } + } else { + $curUser[$sqlField] = $value; + } + } + + /** @var UserRepository $userRepository */ + $userRepository = $this->app['repo.users']; + /** @var UserManipulator $userManipulator */ + $userManipulator = $this->app['manipulator.user']; + if (isset($curUser['usr_login']) && trim($curUser['usr_login']) !== '' + && isset($curUser['usr_password']) && trim($curUser['usr_password']) !== '' + && isset($curUser['usr_mail']) && trim($curUser['usr_mail']) !== '') { + if (null === $userRepository->findByLogin($curUser['usr_login']) + && false === $userRepository->findByEmail($curUser['usr_mail'])) { + + $newUser = $userManipulator + ->createUser($curUser['usr_login'], $curUser['usr_password'], $curUser['usr_mail']); + + $ftpCredential = new FtpCredential(); + $ftpCredential->setUser($newUser); + + if (isset($curUser['activeFTP'])) { + $ftpCredential->setActive((int) $curUser['activeFTP']); + } + if (isset($curUser['addrFTP'])) { + $ftpCredential->setAddress((string) $curUser['addrFTP']); + } + if (isset($curUser['passifFTP'])) { + $ftpCredential->setPassive((int) $curUser['passifFTP']); + } + if (isset($curUser['destFTP'])) { + $ftpCredential->setReceptionFolder($curUser['destFTP']); + } + if (isset($curUser['prefixFTPfolder'])) { + $ftpCredential->setRepositoryPrefixName($curUser['prefixFTPfolder']); + } + if (isset($curUser['usr_prenom'])) { + $newUser->setFirstName($curUser['usr_prenom']); + } + if (isset($curUser['usr_nom'])) { + $newUser->setLastName($curUser['usr_nom']); + } + if (isset($curUser['adresse'])) { + $newUser->setAddress($curUser['adresse']); + } + if (isset($curUser['cpostal'])) { + $newUser->setZipCode($curUser['cpostal']); + } + if (isset($curUser['usr_sexe'])) { + $newUser->setGender((int) ($curUser['usr_sexe'])); + } + if (isset($curUser['tel'])) { + $newUser->setPhone($curUser['tel']); + } + if (isset($curUser['fax'])) { + $newUser->setFax($curUser['fax']); + } + if (isset($curUser['activite'])) { + $newUser->setJob($curUser['activite']); + } + if (isset($curUser['fonction'])) { + $newUser->setPosition($curUser['fonction']); + } + if (isset($curUser['societe'])) { + $newUser->setCompany($curUser['societe']); + } + + $this->getAclForUser($newUser)->apply_model( + $userRepository->find($model), + array_keys($this->getAclForConnectedUser()->get_granted_base(['manage'])) + ); + + $nbCreation++; + } + } + } + + return $this->app->redirectPath('admin_users_search', ['user-updated' => $nbCreation]); + } + + public function importCsvExampleAction() + { + $filename = $this->app['root.path'] . '/resources/examples/example_import_users.csv'; + $contentType = 'text/csv'; + return $this->returnExampleFile($filename, $contentType); + } + + public function importRtfExampleAction() + { + $filename = $this->app['root.path'] . '/resources/examples/fields.rtf'; + $contentType = 'text/rtf'; + return $this->returnExampleFile($filename, $contentType); + } + + public function getEquivalenceToMysqlField() + { + return [ + 'civilite' => 'usr_sexe', + 'gender' => 'usr_sexe', + 'usr_sexe' => 'usr_sexe', + 'nom' => 'usr_nom', + 'name' => 'usr_nom', + 'last name' => 'usr_nom', + 'last_name' => 'usr_nom', + 'usr_nom' => 'usr_nom', + 'first name' => 'usr_prenom', + 'first_name' => 'usr_prenom', + 'prenom' => 'usr_prenom', + 'usr_prenom' => 'usr_prenom', + 'identifiant' => 'usr_login', + 'login' => 'usr_login', + 'usr_login' => 'usr_login', + 'usr_password' => 'usr_password', + 'password' => 'usr_password', + 'mot de passe' => 'usr_password', + 'usr_mail' => 'usr_mail', + 'email' => 'usr_mail', + 'mail' => 'usr_mail', + 'adresse' => 'adresse', + 'adress' => 'adresse', + 'address' => 'adresse', + 'ville' => 'ville', + 'city' => 'ville', + 'zip' => 'cpostal', + 'zipcode' => 'cpostal', + 'zip_code' => 'cpostal', + 'cpostal' => 'cpostal', + 'cp' => 'cpostal', + 'code_postal' => 'cpostal', + 'tel' => 'tel', + 'telephone' => 'tel', + 'phone' => 'tel', + 'fax' => 'fax', + 'job' => 'fonction', + 'fonction' => 'fonction', + 'function' => 'fonction', + 'societe' => 'societe', + 'company' => 'societe', + 'activity' => 'activite', + 'activite' => 'activite', + 'pays' => 'pays', + 'country' => 'pays', + 'ftp_active' => 'activeFTP', + 'compte_ftp_actif' => 'activeFTP', + 'ftpactive' => 'activeFTP', + 'activeftp' => 'activeFTP', + 'ftp_adress' => 'addrFTP', + 'adresse_du_serveur_ftp' => 'addrFTP', + 'addrftp' => 'addrFTP', + 'ftpaddr' => 'addrFTP', + 'loginftp' => 'loginFTP', + 'ftplogin' => 'loginFTP', + 'ftppwd' => 'pwdFTP', + 'pwdftp' => 'pwdFTP', + 'destftp' => 'destFTP', + 'destination_folder' => 'destFTP', + 'dossier_de_destination' => 'destFTP', + 'passive_mode' => 'passifFTP', + 'mode_passif' => 'passifFTP', + 'passifftp' => 'passifFTP', + 'retry' => 'retryFTP', + 'nombre_de_tentative' => 'retryFTP', + 'retryftp' => 'retryFTP', + 'by_default__send' => 'defaultftpdatasent', + 'by_default_send' => 'defaultftpdatasent', + 'envoi_par_defaut' => 'defaultftpdatasent', + 'defaultftpdatasent' => 'defaultftpdatasent', + 'prefix_creation_folder' => 'prefixFTPfolder', + 'prefix_de_creation_de_dossier' => 'prefixFTPfolder', + 'prefixFTPfolder' => 'prefixFTPfolder', + ]; + } + + /** + * @param string $name + * @param array $context + * @return string + */ + private function render($name, array $context = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + + return $twig->render($name, $context); + } + + /** + * @param Request $request + * @return UserHelper\Edit + */ + private function getUserEditHelper(Request $request) + { + return new UserHelper\Edit($this->app, $request); + } + + /** + * @param Request $request + * @return UserHelper\Manage + */ + private function getUserManageHelper(Request $request) + { + return new UserHelper\Manage($this->app, $request); + } + + /** + * @return \ACL + */ + private function getAclForConnectedUser() + { + return $this->getAclForUser($this->getAuthenticatedUser()); + + } + + /** + * @return \User_Query + */ + private function createUserQuery() + { + return $this->app['phraseanet.user-query']; + } + + /** + * @return ExporterInterface + */ + private function getCsvExporter() + { + /** @var ExporterInterface $exporter */ + $exporter = $this->app['csv.exporter']; + return $exporter; + } + + /** + * @return User|null + */ + private function getAuthenticatedUser() + { + /** @var Authenticator $authenticator */ + $authenticator = $this->app['authentication']; + return $authenticator->getUser(); + } + + /** + * @param array $template + * @return array + */ + private function normalizeTemplateArray(array $template) + { + $templates = []; + foreach ($template as $tmp) { + if ('' === trim($tmp)) { + continue; + } + + $tmp = explode('_', $tmp); + + if (count($tmp) == 2) { + $templates[$tmp[0]] = $tmp[1]; + } + } + return $templates; + } + + /** + * @param array $denials + * @param array $templates + * @return array + */ + private function normalizeDenyArray(array $denials, array $templates) + { + $deny = []; + foreach ($denials as $den) { + $den = explode('_', $den); + if (count($den) == 2 && !isset($templates[$den[0]])) { + $deny[$den[0]][$den[1]] = $den[1]; + } + } + return $deny; + } + + /** + * @param User $user + * @return \ACL + */ + private function getAclForUser(User $user) + { + /** @var ACLProvider $aclProvider */ + $aclProvider = $this->app['acl']; + return $aclProvider->get($user); + } + + /** + * @return RegistrationManipulator + */ + private function getRegistrationManipulator() + { + return $this->app['manipulator.registration']; + } + + /** + * @param $filename + * @param $contentType + * @return Response + */ + public function returnExampleFile($filename, $contentType) + { + $file = new \SplFileInfo($filename); + + if (!$file->isFile()) { + $this->app->abort(400); + } + + $response = new Response(); + $response->setStatusCode(200); + $response->headers->set('Pragma', 'public'); + $response->headers->set('Content-Disposition', 'attachment; filename=' . $file->getFilename()); + $response->headers->set('Content-Length', $file->getSize()); + $response->headers->set('Content-Type', $contentType); + $response->setContent(file_get_contents($file->getPathname())); + + return $response; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php index 2d68b30422..30f1a2f89c 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php @@ -11,906 +11,76 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Phrasea\Core\Response\CSVFileResponse; -use Alchemy\Phrasea\Helper\User as UserHelper; -use Alchemy\Phrasea\Model\Entities\FtpCredential; -use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Controller\Admin\UserController; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Alchemy\Phrasea\Notification\Receiver; -use Alchemy\Phrasea\Notification\Mail\MailSuccessEmailUpdate; +use Silex\ServiceProviderInterface; -class Users implements ControllerProviderInterface +class Users implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.users'] = $app->share(function () use ($app) { + return new UserController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.users'] = $this; - + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; $app['firewall']->addMandatoryAuthentication($controllers); - $controllers->before(function (Request $request) use ($app) { + $controllers->before(function () use ($app) { $app['firewall']->requireAccessToModule('admin') ->requireRight('manageusers'); }); - $controllers->post('/rights/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers.html.twig', $rights->get_users_rights()); - }); - - $controllers->get('/rights/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers.html.twig', $rights->get_users_rights()); - }); - - $controllers->post('/rights/reset/', function (Application $app, Request $request) { - try { - $datas = ['error' => false]; - - $helper = new UserHelper\Edit($app, $request); - $helper->resetRights(); - } catch (\Exception $e) { - $datas['error'] = true; - $datas['message'] = $e->getMessage(); - } - - 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->redirectPath('admin_users_search'); - }); - - $controllers->post('/rights/apply/', function (Application $app) { - $datas = ['error' => true]; - - try { - $rights = new UserHelper\Edit($app, $app['request']); - - if (!$app['request']->request->get('reset_before_apply')) { - $rights->apply_rights(); - } - - if ($app['request']->request->get('template')) { - if ($app['request']->request->get('reset_before_apply')) { - $rights->resetRights(); - } - $rights->apply_template(); - } - - $rights->apply_infos(); - - $datas = ['error' => false]; - } catch (\Exception $e) { - $datas['message'] = $e->getMessage(); - } - - return $app->json($datas); - })->bind('admin_users_rights_apply'); - - $controllers->post('/rights/quotas/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers_quotas.html.twig', $rights->get_quotas()); - }); - - $controllers->post('/rights/quotas/apply/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - $rights->apply_quotas(); - - return $app->json(['message' => '', 'error' => false]); - }); - - $controllers->post('/rights/time/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers_timelimit.html.twig', $rights->get_time()); - }); - - $controllers->post('/rights/time/sbas/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers_timelimit_sbas.html.twig', $rights->get_time_sbas()); - }); - - $controllers->post('/rights/time/apply/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - $rights->apply_time(); - - return $app->json(['message' => '', 'error' => false]); - }); - - $controllers->post('/rights/masks/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - - return $app['twig']->render('admin/editusers_masks.html.twig', $rights->get_masks()); - }); - - $controllers->post('/rights/masks/apply/', function (Application $app) { - $rights = new UserHelper\Edit($app, $app['request']); - $rights->apply_masks(); - - return $app->json(['message' => '', 'error' => false]); - }); - - $controllers->match('/search/', function (Application $app) { - $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) { - $users = new UserHelper\Manage($app, $app['request']); - - $userTable = [ - [ - 'ID', - 'Login', - 'Last Name', - 'First Name', - 'E-Mail', - 'Created', - 'Updated', - 'Address', - 'City', - 'Zip', - 'Country', - 'Phone', - 'Fax', - 'Job', - 'Company', - 'Position' - ] - ]; - - foreach ($users->export() as $user) { - $userTable[] = [ - $user->getId(), - $user->getLogin(), - $user->getLastName(), - $user->getFirstName(), - $user->getEmail(), - $user->getCreated()->format(DATE_ATOM), - $user->getUpdated()->format(DATE_ATOM), - $user->getAddress(), - $user->getCity(), - $user->getZipCode(), - $user->getCountry(), - $user->getPhone(), - $user->getFax(), - $user->getJob(), - $user->getCompany(), - $user->getActivity() - ]; - } - - $filename = sprintf('user_export_%s.csv', date('Ymd')); - $response = new CSVFileResponse($filename, function () use ($app, $userTable) { - $app['csv.exporter']->export('php://output', $userTable); - }); - - return $response; - })->bind('admin_users_search_export'); - - $controllers->post('/apply_template/', function () use ($app) { - $users = new UserHelper\Edit($app, $app['request']); - - if ($app['request']->request->get('reset_before_apply')) { - $users->resetRights(); - } - $users->apply_template(); - - return $app->redirectPath('admin_users_search'); - })->bind('admin_users_apply_template'); - - $controllers->get('/typeahead/search/', function (Application $app) { - $request = $app['request']; - - $user_query = $app['phraseanet.user-query']; - $like_value = $request->query->get('term'); - $rights = $request->query->get('filter_rights') ? : []; - $have_right = $request->query->get('have_right') ? : []; - $have_not_right = $request->query->get('have_not_right') ? : []; - $on_base = $request->query->get('on_base') ? : []; - - $eligible_users = $user_query - ->on_sbas_where_i_am($app['acl']->get($app['authentication']->getUser()), $rights) - ->like(\User_Query::LIKE_EMAIL, $like_value) - ->like(\User_Query::LIKE_FIRSTNAME, $like_value) - ->like(\User_Query::LIKE_LASTNAME, $like_value) - ->like(\User_Query::LIKE_LOGIN, $like_value) - ->like_match(\User_Query::LIKE_MATCH_OR) - ->who_have_right($have_right) - ->who_have_not_right($have_not_right) - ->on_base_ids($on_base) - ->execute() - ->get_results(); - - $datas = []; - - foreach ($eligible_users as $user) { - $datas[] = [ - 'email' => $user->getEmail() ? : '', - 'login' => $user->getLogin() ? : '', - 'name' => $user->getDisplayName(), - 'id' => $user->getId(), - ]; - } - - return $app->json($datas); - }); - - $controllers->post('/create/', function (Application $app) { - $datas = ['error' => false, 'message' => '', 'data' => null]; - try { - $request = $app['request']; - $module = new UserHelper\Manage($app, $app['request']); - if ($request->request->get('template') == '1') { - $user = $module->create_template(); - } else { - $user = $module->create_newuser(); - } - if (!$user instanceof User) { - throw new \Exception('Unknown error'); - } - - $datas['data'] = $user->getId(); - } catch (\Exception $e) { - $datas['error'] = true; - if ($request->request->get('template') == '1') { - $datas['message'] = $app->trans('Unable to create template, the name is already used.'); - } else { - $datas['message'] = $app->trans('Unable to create the user.'); - } - } - - return $app->json($datas); - }); - - $controllers->post('/export/csv/', function (Application $app) { - $request = $app['request']; - $user_query = $app['phraseanet.user-query']; - - $like_value = $request->request->get('like_value'); - $like_field = $request->request->get('like_field'); - $on_base = $request->request->get('base_id') ? : null; - $on_sbas = $request->request->get('sbas_id') ? : null; - - $eligible_users = $user_query->on_bases_where_i_am($app['acl']->get($app['authentication']->getUser()), ['canadmin']) - ->like($like_field, $like_value) - ->on_base_ids($on_base) - ->on_sbas_ids($on_sbas); - - $offset = 0; - $buffer = []; - - $buffer[] = [ - 'ID', - 'Login', - $app->trans('admin::compte-utilisateur nom'), - $app->trans('admin::compte-utilisateur prenom'), - $app->trans('admin::compte-utilisateur email'), - 'CreationDate', - 'ModificationDate', - $app->trans('admin::compte-utilisateur adresse'), - $app->trans('admin::compte-utilisateur ville'), - $app->trans('admin::compte-utilisateur code postal'), - $app->trans('admin::compte-utilisateur pays'), - $app->trans('admin::compte-utilisateur telephone'), - $app->trans('admin::compte-utilisateur fax'), - $app->trans('admin::compte-utilisateur poste'), - $app->trans('admin::compte-utilisateur societe'), - $app->trans('admin::compte-utilisateur activite'), - ]; - do { - $eligible_users->limit($offset, 20); - $offset += 20; - - $results = $eligible_users->execute()->get_results(); - - foreach ($results as $user) { - $buffer[] = [ - $user->getId(), - $user->getLogin(), - $user->getLastName(), - $user->getFirstName(), - $user->getEmail(), - $app['date-formatter']->format_mysql($user->getCreated()), - $app['date-formatter']->format_mysql($user->getUpdated()), - $user->getAddress(), - $user->getCity(), - $user->getZipCode(), - $user->getCountry(), - $user->getPhone(), - $user->getFax(), - $user->getJob(), - $user->getCompany(), - $user->getActivity(), - ]; - } - } while (count($results) > 0); - - $filename = sprintf('user_export_%s.csv', date('Ymd')); - $response = new CSVFileResponse($filename, function () use ($app, $buffer) { - $app['csv.exporter']->export('php://output', $buffer); - }); - - return $response; - })->bind('admin_users_export_csv'); - - $controllers->get('/registrations/', function (Application $app) { - $app['manipulator.registration']->deleteOldRegistrations(); - - $models = $app['repo.users']->findTemplateOwner($app['authentication']->getUser()); - - $userRegistrations = []; - foreach ($app['repo.registrations']->getUserRegistrations( - $app['authentication']->getUser(), - $app['acl']->get($app['authentication']->getUser())->get_granted_base(['canadmin']) - ) as $registration) { - $user = $registration->getUser(); - $userRegistrations[$user->getId()]['user'] = $user; - $userRegistrations[$user->getId()]['registrations'][$registration->getBaseid()] = $registration; - } - - return $app['twig']->render('admin/user/registrations.html.twig', [ - 'user_registrations' => $userRegistrations, - 'models' => $models, - ]); - })->bind('users_display_registrations'); - - $controllers->post('/registrations/', function (Application $app, Request $request) { - $templates = $deny = $accept = $options = []; - - foreach ($request->request->get('template', []) as $tmp) { - if ('' === trim($tmp)) { - continue; - } - - $tmp = explode('_', $tmp); - - if (count($tmp) == 2) { - $templates[$tmp[0]] = $tmp[1]; - } - } - - foreach ($request->request->get('deny', []) as $den) { - $den = explode('_', $den); - if (count($den) == 2 && !isset($templates[$den[0]])) { - $deny[$den[0]][$den[1]] = $den[1]; - } - } - - foreach ($request->request->get('accept', []) as $acc) { - $acc = explode('_', $acc); - if (count($acc) == 2 && !isset($templates[$acc[0]])) { - $accept[$acc[0]][$acc[1]] = $acc[1]; - $options[$acc[0]][$acc[1]] = ['HD' => false, 'WM' => false]; - } - } - - foreach ($request->request->get('accept_hd', []) as $accHD) { - $accHD = explode('_', $accHD); - if (count($accHD) == 2 && isset($accept[$accHD[0]]) && isset($options[$accHD[0]][$accHD[1]])) { - $options[$accHD[0]][$accHD[1]]['HD'] = true; - } - } - - foreach ($request->request->get('watermark', []) as $wm) { - $wm = explode('_', $wm); - if (count($wm) == 2 && isset($accept[$wm[0]]) && isset($options[$wm[0]][$wm[1]])) { - $options[$wm[0]][$wm[1]]['WM'] = true; - } - } - - if (count($templates) > 0 || count($deny) > 0 || count($accept) > 0) { - $cacheToUpdate = $done = []; - - foreach ($templates as $usr => $template_id) { - if (null === $user = $app['repo.users']->find($usr)) { - $app->abort(400, srpintf("User with id % in provided in 'template' request variable could not be found", $usr)); - } - $cacheToUpdate[$usr] = $user; - - $user_template = $app['repo.users']->find($template_id); - $collections = $app['acl']->get($user_template)->get_granted_base(); - $baseIds = array_keys($collections); - - $app['acl']->get($user)->apply_model($user_template, $baseIds); - - foreach ($collections as $collection) { - $done[$usr][$collection->get_base_id()] = true; - } - - $app['manipulator.registration']->deleteUserRegistrations($user, $collections); - } - - foreach ($deny as $usr => $bases) { - if (null === $user = $app['repo.users']->find($usr)) { - $app->abort(400, srpintf("User with id % in provided in 'deny' request variable could not be found", $usr)); - } - $cacheToUpdate[$usr] = $user; - foreach ($app['repo.registrations']->getUserRegistrations( - $user, - array_map(function ($baseId) use ($app) { - return \collection::get_from_base_id($app, $baseId); - }, $bases) - ) as $registration) { - $app['manipulator.registration']->rejectRegistration($registration); - $done[$usr][$registration->getBaseId()] = false; - } - } - - foreach ($accept as $usr => $bases) { - if (null === $user = $app['repo.users']->find($usr)) { - $app->abort(400, srpintf("User with id % in provided in 'accept' request variable could not be found", $usr)); - } - $cacheToUpdate[$usr] = $user; - foreach ($app['repo.registrations']->getUserRegistrations( - $user, - array_map(function ($baseId) use ($app) { - return \collection::get_from_base_id($app, $baseId); - }, $bases) - ) as $registration) { - $done[$usr][$registration->getBaseId()] = true; - $app['manipulator.registration']->acceptRegistration( - $registration, - $options[$usr][$registration->getBaseId()]['HD'], - $options[$usr][$registration->getBaseId()]['WM'] - ); - } - } - - array_walk($cacheToUpdate, function (User $user) use ($app) { - $app['acl']->get($user)->delete_data_from_cache(); - }); - unset ($cacheToUpdate); - - foreach ($done as $usr => $bases) { - $user = $app['repo.users']->find($usr); - $acceptColl = $denyColl = []; - - foreach ($bases as $bas => $isok) { - $collection = \collection::get_from_base_id($app, $bas); - - if ($isok) { - $acceptColl[] = $collection->get_label($app['locale']); - continue; - } - - $denyColl[] = $collection->get_label($app['locale']); - } - - if (0 !== count($acceptColl) || 0 !== count($denyColl)) { - $message = ''; - if (0 !== count($acceptColl)) { - $message .= "\n" . $app->trans('login::register:email: Vous avez ete accepte sur les collections suivantes : ') . implode(', ', $acceptColl). "\n"; - } - if (0 !== count($denyColl)) { - $message .= "\n" . $app->trans('login::register:email: Vous avez ete refuse sur les collections suivantes : ') . implode(', ', $denyColl) . "\n"; - } - - $receiver = new Receiver(null, $user->getEmail()); - $mail = MailSuccessEmailUpdate::create($app, $receiver, null, $message); - - $app['notification.deliverer']->deliver($mail); - } - } - } - - return $app->redirectPath('users_display_registrations', ['success' => 1]); - })->bind('users_submit_registrations'); - - $controllers->get('/import/file/', function (Application $app, Request $request) { - return $app['twig']->render('admin/user/import/file.html.twig'); - })->bind('users_display_import_file'); - - $controllers->post('/import/file/', function (Application $app, Request $request) { - - if ((null === $file = $request->files->get('files')) || !$file->isValid()) { - return $app->redirectPath('users_display_import_file', ['error' => 'file-invalid']); - } - - $equivalenceToMysqlField = Users::getEquivalenceToMysqlField(); - $loginDefined = $pwdDefined = $mailDefined = false; - $loginNew = []; - $out = [ - 'ignored_row' => [], - 'errors' => [] - ]; - $nbUsrToAdd = 0; - - $lines = []; - $app['csv.interpreter']->addObserver(function (array $row) use (&$lines) { - $lines[] = $row; - }); - $app['csv.lexer']->parse($file->getPathname(), $app['csv.interpreter']); - - $roughColumns = array_shift($lines); - - $columnsSanitized = array_map(function ($columnName) { - return trim(mb_strtolower($columnName)); - }, $roughColumns); - - $columns = array_filter($columnsSanitized, function ($columnName) use (&$out, $equivalenceToMysqlField) { - if (!isset($equivalenceToMysqlField[$columnName])) { - $out['ignored_row'][] = $columnName; - - return false; - } - - return true; - }); - - foreach ($columns as $columnName) { - if ($equivalenceToMysqlField[$columnName] === 'usr_login') { - $loginDefined = true; - } - - if (($equivalenceToMysqlField[$columnName]) === 'usr_password') { - $pwdDefined = true; - } - - if (($equivalenceToMysqlField[$columnName]) === 'usr_mail') { - $mailDefined = true; - } - } - - if (!$loginDefined) { - return $app->redirectPath('users_display_import_file', ['error' => 'row-login']); - } - - if (!$pwdDefined) { - return $app->redirectPath('users_display_import_file', ['error' => 'row-pwd']); - } - - if (!$mailDefined) { - return $app->redirectPath('users_display_import_file', ['error' => 'row-mail']); - } - - foreach ($lines as $nbLine => $line) { - $loginValid = false; - $pwdValid = false; - $mailValid = false; - - foreach ($columns as $nbCol => $colName) { - if (!isset($equivalenceToMysqlField[$colName])) { - unset($lines[$nbCol]); - continue; - } - - $sqlField = $equivalenceToMysqlField[$colName]; - $value = $line[$nbCol]; - - if ($sqlField === 'usr_login') { - $loginToAdd = $value; - if ($loginToAdd === "") { - $out['errors'][] = $app->trans("Login line %line% is empty", ['%line%' => $nbLine + 1]); - } elseif (in_array($loginToAdd, $loginNew)) { - $out['errors'][] = $app->trans("Login %login% is already defined in the file at line %line%", ['%login%' => $loginToAdd, '%line%' => $nbLine]); - } else { - if (null !== $app['repo.users']->findByLogin($loginToAdd)) { - $out['errors'][] = $app->trans("Login %login% already exists in database", ['%login%' => $loginToAdd]); - } else { - $loginValid = true; - } - } - } - - if ($loginValid && $sqlField === 'usr_mail') { - $mailToAdd = $value; - - if ($mailToAdd === "") { - $out['errors'][] = $app->trans("Mail line %line% is empty", ['%line%' => $nbLine + 1]); - } elseif (null !== $app['repo.users']->findByEmail($mailToAdd)) { - $out['errors'][] = $app->trans("Email '%email%' for login '%login%' already exists in database", ['%email%' => $mailToAdd, '%login%' => $loginToAdd]); - } else { - $mailValid = true; - } - } - - if ($sqlField === 'usr_password') { - $passwordToVerif = $value; - - if ($passwordToVerif === "") { - $out['errors'][] = $app->trans("Password is empty at line %line%", ['%line%' => $nbLine]); - } else { - $pwdValid = true; - } - } - } - - if ($loginValid && $pwdValid && $mailValid) { - $loginNew[] = $loginToAdd; - $nbUsrToAdd++; - } - } - - if (count($out['errors']) > 0 && $nbUsrToAdd === 0) { - return $app['twig']->render('admin/user/import/file.html.twig', [ - 'errors' => $out['errors'] - ]); - } - - if ($nbUsrToAdd === 0) { - return $app->redirectPath('users_display_import_file', [ - 'error' => 'no-user' - ]); - } - - $basList = array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['manage'])); - $models = $app['orm.em.native-query']->getModelForUser($app['authentication']->getUser(), $basList); - - return $app['twig']->render('/admin/user/import/view.html.twig', [ - 'nb_user_to_add' => $nbUsrToAdd, - 'models' => $models, - 'lines_serialized' => serialize($lines), - 'columns_serialized' => serialize($columns), - 'errors' => $out['errors'] - ]); - })->bind('users_submit_import_file'); - - $controllers->post('/import/', function (Application $app, Request $request) { - $nbCreation = 0; - - if ((null === $serializedColumns = $request->request->get('sr_columns')) || ('' === $serializedColumns)) { - $app->abort(400); - } - - if ((null === $serializedLines = $request->request->get('sr_lines')) || ('' === $serializedLines)) { - $app->abort(400); - } - - if (null === $model = $request->request->get("modelToApply")) { - $app->abort(400); - } - - $lines = unserialize($serializedLines); - $columns = unserialize($serializedColumns); - - $equivalenceToMysqlField = Users::getEquivalenceToMysqlField(); - - foreach ($lines as $nbLine => $line) { - $curUser = []; - foreach ($columns as $nbCol => $colName) { - if (!isset($equivalenceToMysqlField[$colName]) || !isset($line[$nbCol])) { - continue; - } - - $sqlField = $equivalenceToMysqlField[$colName]; - $value = trim($line[$nbCol]); - - if ($sqlField === "usr_sexe") { - switch ($value) { - case "Mlle": - case "Mlle.": - case "mlle": - case "Miss": - case "miss": - case "0": - $curUser[$sqlField] = 0; - break; - - case "Mme": - case "Madame": - case "Ms": - case "Ms.": - case "1": - $curUser[$sqlField] = 1; - break; - - case "M": - case "M.": - case "Mr": - case "Mr.": - case "Monsieur": - case "Mister": - case "2": - $curUser[$sqlField] = 2; - break; - } - } else { - $curUser[$sqlField] = $value; - } - } - - if (isset($curUser['usr_login']) && trim($curUser['usr_login']) !== '' - && isset($curUser['usr_password']) && trim($curUser['usr_password']) !== '' - && isset($curUser['usr_mail']) && trim($curUser['usr_mail']) !== '') { - if (null === $app['repo.users']->findByLogin($curUser['usr_login']) - && false === $app['repo.users']->findByEmail($curUser['usr_mail'])) { - - $newUser = $app['manipulator.user']->createUser($curUser['usr_login'], $curUser['usr_password'], $curUser['usr_mail']); - - $ftpCredential = new FtpCredential(); - $ftpCredential->setUser($newUser); - - if (isset($curUser['activeFTP'])) { - $ftpCredential->setActive((int) $curUser['activeFTP']); - } - if (isset($curUser['addrFTP'])) { - $ftpCredential->setAddress((string) $curUser['addrFTP']); - } - if (isset($curUser['passifFTP'])) { - $ftpCredential->setPassive((int) $curUser['passifFTP']); - } - if (isset($curUser['destFTP'])) { - $ftpCredential->setReceptionFolder($curUser['destFTP']); - } - if (isset($curUser['prefixFTPfolder'])) { - $ftpCredential->setRepositoryPrefixName($curUser['prefixFTPfolder']); - } - if (isset($curUser['usr_prenom'])) { - $newUser->setFirstName($curUser['usr_prenom']); - } - if (isset($curUser['usr_nom'])) { - $newUser->setLastName($curUser['usr_nom']); - } - if (isset($curUser['adresse'])) { - $newUser->setAdress($curUser['adresse']); - } - if (isset($curUser['cpostal'])) { - $newUser->setZipCode($curUser['cpostal']); - } - if (isset($curUser['usr_sexe'])) { - $newUser->setGender((int) ($curUser['usr_sexe'])); - } - if (isset($curUser['tel'])) { - $newUser->setPhone($curUser['tel']); - } - if (isset($curUser['fax'])) { - $newUser->setFax($curUser['fax']); - } - if (isset($curUser['activite'])) { - $newUser->setJob($curUser['activite']); - } - if (isset($curUser['fonction'])) { - $newUser->setPosition($curUser['fonction']); - } - if (isset($curUser['societe'])) { - $newUser->setCompany($curUser['societe']); - } - - $app['acl']->get($newUser)->apply_model( - $app['repo.users']->find($model), array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_base(['manage'])) - ); - - $nbCreation++; - } - } - } - - return $app->redirectPath('admin_users_search', ['user-updated' => $nbCreation]); - })->bind('users_submit_import'); - - $controllers->get('/import/example/csv/', function (Application $app) { - - $file = new \SplFileInfo($app['root.path'] . '/resources/examples/example_import_users.csv'); - - if (!$file->isFile()) { - $app->abort(400); - } - - $response = new Response(); - $response->setStatusCode(200); - $response->headers->set('Pragma', 'public'); - $response->headers->set('Content-Disposition', 'attachment; filename=' . $file->getFilename()); - $response->headers->set('Content-Length', $file->getSize()); - $response->headers->set('Content-Type', 'text/csv'); - $response->setContent(file_get_contents($file->getPathname())); - - return $response; - })->bind('users_import_csv'); - - $controllers->get('/import/example/rtf/', function (Application $app) { - - $file = new \SplFileInfo($app['root.path'] . '/resources/examples/fields.rtf'); - - if (!$file->isFile()) { - $app->abort(400); - } - - $response = new Response(); - $response->setStatusCode(200); - $response->headers->set('Pragma', 'public'); - $response->headers->set('Content-Disposition', 'attachment; filename=' . $file->getFilename()); - $response->headers->set('Content-Length', $file->getSize()); - $response->headers->set('Content-Type', 'text/rtf'); - $response->setContent(file_get_contents($file->getPathname())); - - return $response; - })->bind('users_import_rtf'); + $controllers->match('/rights/', 'controller.admin.users:editRightsAction') + ->method('GET|POST'); + $controllers->post('/rights/reset/', 'controller.admin.users:resetRightsAction') + ->bind('admin_users_rights_reset'); + $controllers->post('/delete/', 'controller.admin.users:deleteUserAction'); + $controllers->post('/rights/apply/', 'controller.admin.users:applyRightsAction') + ->bind('admin_users_rights_apply'); + $controllers->post('/rights/quotas/', 'controller.admin.users:editQuotasRightsAction'); + $controllers->post('/rights/quotas/apply/', 'controller.admin.users:applyQuotasAction'); + $controllers->post('/rights/time/', 'controller.admin.users:editTimeLimitAction'); + $controllers->post('/rights/time/sbas/', 'controller.admin.users:editTimeLimitSbasAction'); + $controllers->post('/rights/time/apply/', 'controller.admin.users:applyTimeAction'); + $controllers->post('/rights/masks/', 'controller.admin.users:editMasksAction'); + $controllers->post('/rights/masks/apply/', 'controller.admin.users:applyMasksAction'); + $controllers->match('/search/', 'controller.admin.users:searchAction') + ->bind('admin_users_search'); + $controllers->post('/search/export/', 'controller.admin.users:searchExportAction') + ->bind('admin_users_search_export'); + $controllers->post('/apply_template/', 'controller.admin.users:applyTemplateAction') + ->bind('admin_users_apply_template'); + $controllers->get('/typeahead/search/', 'controller.admin.users:typeAheadSearchAction'); + $controllers->post('/create/', 'controller.admin.users:createAction'); + $controllers->post('/export/csv/', 'controller.admin.users:exportAction') + ->bind('admin_users_export_csv'); + $controllers->get('/registrations/', 'controller.admin.users:displayRegistrationsAction') + ->bind('users_display_registrations'); + $controllers->post('/registrations/', 'controller.admin.users:submitRegistrationAction') + ->bind('users_submit_registrations'); + $controllers->get('/import/file/', 'controller.admin.users:displayImportFileAction') + ->bind('users_display_import_file'); + $controllers->post('/import/file/', 'controller.admin.users:submitImportFileAction') + ->bind('users_submit_import_file'); + $controllers->post('/import/', 'controller.admin.users:submitImportAction') + ->bind('users_submit_import'); + $controllers->get('/import/example/csv/', 'controller.admin.users:importCsvExampleAction') + ->bind('users_import_csv'); + $controllers->get('/import/example/rtf/', 'controller.admin.users:importRtfExampleAction') + ->bind('users_import_rtf'); return $controllers; } - - public static function getEquivalenceToMysqlField() - { - $equivalenceToMysqlField = []; - - $equivalenceToMysqlField['civilite'] = 'usr_sexe'; - $equivalenceToMysqlField['gender'] = 'usr_sexe'; - $equivalenceToMysqlField['usr_sexe'] = 'usr_sexe'; - $equivalenceToMysqlField['nom'] = 'usr_nom'; - $equivalenceToMysqlField['name'] = 'usr_nom'; - $equivalenceToMysqlField['last name'] = 'usr_nom'; - $equivalenceToMysqlField['last_name'] = 'usr_nom'; - $equivalenceToMysqlField['usr_nom'] = 'usr_nom'; - $equivalenceToMysqlField['first name'] = 'usr_prenom'; - $equivalenceToMysqlField['first_name'] = 'usr_prenom'; - $equivalenceToMysqlField['prenom'] = 'usr_prenom'; - $equivalenceToMysqlField['usr_prenom'] = 'usr_prenom'; - $equivalenceToMysqlField['identifiant'] = 'usr_login'; - $equivalenceToMysqlField['login'] = 'usr_login'; - $equivalenceToMysqlField['usr_login'] = 'usr_login'; - $equivalenceToMysqlField['usr_password'] = 'usr_password'; - $equivalenceToMysqlField['password'] = 'usr_password'; - $equivalenceToMysqlField['mot de passe'] = 'usr_password'; - $equivalenceToMysqlField['usr_mail'] = 'usr_mail'; - $equivalenceToMysqlField['email'] = 'usr_mail'; - $equivalenceToMysqlField['mail'] = 'usr_mail'; - $equivalenceToMysqlField['adresse'] = 'adresse'; - $equivalenceToMysqlField['adress'] = 'adresse'; - $equivalenceToMysqlField['address'] = 'adresse'; - $equivalenceToMysqlField['ville'] = 'ville'; - $equivalenceToMysqlField['city'] = 'ville'; - $equivalenceToMysqlField['zip'] = 'cpostal'; - $equivalenceToMysqlField['zipcode'] = 'cpostal'; - $equivalenceToMysqlField['zip_code'] = 'cpostal'; - $equivalenceToMysqlField['cpostal'] = 'cpostal'; - $equivalenceToMysqlField['cp'] = 'cpostal'; - $equivalenceToMysqlField['code_postal'] = 'cpostal'; - $equivalenceToMysqlField['tel'] = 'tel'; - $equivalenceToMysqlField['telephone'] = 'tel'; - $equivalenceToMysqlField['phone'] = 'tel'; - $equivalenceToMysqlField['fax'] = 'fax'; - $equivalenceToMysqlField['job'] = 'fonction'; - $equivalenceToMysqlField['fonction'] = 'fonction'; - $equivalenceToMysqlField['function'] = 'fonction'; - $equivalenceToMysqlField['societe'] = 'societe'; - $equivalenceToMysqlField['company'] = 'societe'; - $equivalenceToMysqlField['activity'] = 'activite'; - $equivalenceToMysqlField['activite'] = 'activite'; - $equivalenceToMysqlField['pays'] = 'pays'; - $equivalenceToMysqlField['country'] = 'pays'; - $equivalenceToMysqlField['ftp_active'] = 'activeFTP'; - $equivalenceToMysqlField['compte_ftp_actif'] = 'activeFTP'; - $equivalenceToMysqlField['ftpactive'] = 'activeFTP'; - $equivalenceToMysqlField['activeftp'] = 'activeFTP'; - $equivalenceToMysqlField['ftp_adress'] = 'addrFTP'; - $equivalenceToMysqlField['adresse_du_serveur_ftp'] = 'addrFTP'; - $equivalenceToMysqlField['addrftp'] = 'addrFTP'; - $equivalenceToMysqlField['ftpaddr'] = 'addrFTP'; - $equivalenceToMysqlField['loginftp'] = 'loginFTP'; - $equivalenceToMysqlField['ftplogin'] = 'loginFTP'; - $equivalenceToMysqlField['ftppwd'] = 'pwdFTP'; - $equivalenceToMysqlField['pwdftp'] = 'pwdFTP'; - $equivalenceToMysqlField['destftp'] = 'destFTP'; - $equivalenceToMysqlField['destination_folder'] = 'destFTP'; - $equivalenceToMysqlField['dossier_de_destination'] = 'destFTP'; - $equivalenceToMysqlField['passive_mode'] = 'passifFTP'; - $equivalenceToMysqlField['mode_passif'] = 'passifFTP'; - $equivalenceToMysqlField['passifftp'] = 'passifFTP'; - $equivalenceToMysqlField['retry'] = 'retryFTP'; - $equivalenceToMysqlField['nombre_de_tentative'] = 'retryFTP'; - $equivalenceToMysqlField['retryftp'] = 'retryFTP'; - $equivalenceToMysqlField['by_default__send'] = 'defaultftpdatasent'; - $equivalenceToMysqlField['by_default_send'] = 'defaultftpdatasent'; - $equivalenceToMysqlField['envoi_par_defaut'] = 'defaultftpdatasent'; - $equivalenceToMysqlField['defaultftpdatasent'] = 'defaultftpdatasent'; - $equivalenceToMysqlField['prefix_creation_folder'] = 'prefixFTPfolder'; - $equivalenceToMysqlField['prefix_de_creation_de_dossier'] = 'prefixFTPfolder'; - $equivalenceToMysqlField['prefixFTPfolder'] = 'prefixFTPfolder'; - - return $equivalenceToMysqlField; - } } diff --git a/lib/Alchemy/Phrasea/Helper/User/Manage.php b/lib/Alchemy/Phrasea/Helper/User/Manage.php index 26bd94a098..e24b691242 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Manage.php +++ b/lib/Alchemy/Phrasea/Helper/User/Manage.php @@ -38,6 +38,9 @@ class Manage extends Helper */ protected $usr_id; + /** + * @return User[] + */ public function export() { $request = $this->request; diff --git a/lib/Alchemy/Phrasea/Model/Entities/Registration.php b/lib/Alchemy/Phrasea/Model/Entities/Registration.php index 304a2bca65..e00b82455f 100644 --- a/lib/Alchemy/Phrasea/Model/Entities/Registration.php +++ b/lib/Alchemy/Phrasea/Model/Entities/Registration.php @@ -116,6 +116,7 @@ class Registration } /** + * @param User $user * @return Registration */ public function setUser(User $user) @@ -126,7 +127,7 @@ class Registration } /** - * @return integer + * @return User */ public function getUser() { diff --git a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php index a91d1e25aa..66b761da85 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/RegistrationRepository.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\Model\Repositories; +use Alchemy\Phrasea\Model\Entities\Registration; use Doctrine\ORM\EntityRepository; use Alchemy\Phrasea\Model\Entities\User; @@ -28,7 +29,7 @@ class RegistrationRepository extends EntityRepository * @param User $user * @param \collection[] $collections * - * @return array + * @return Registration[] */ public function getUserRegistrations(User $user, array $collections) { diff --git a/lib/classes/ACL.php b/lib/classes/ACL.php index d0efb37db0..52a70740db 100644 --- a/lib/classes/ACL.php +++ b/lib/classes/ACL.php @@ -661,7 +661,7 @@ class ACL implements cache_cacheableInterface * * @param array $rights * @param array|null $sbas_ids Optionnal sbas_id to restrict the query on - * @return array An array of collection + * @return collection[] An array of collection */ public function get_granted_base(Array $rights = [], array $sbas_ids = null) { diff --git a/lib/classes/User/Query.php b/lib/classes/User/Query.php index 66a922f36a..cdbc3bc2e6 100644 --- a/lib/classes/User/Query.php +++ b/lib/classes/User/Query.php @@ -79,7 +79,7 @@ class User_Query implements User_QueryInterface /** * Return query results * - * @return array + * @return User[] */ public function get_results() { From 08500947de3171d329fb37b20e1e070693f2ccbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Wed, 1 Apr 2015 10:30:04 +0200 Subject: [PATCH 17/26] Add max packet to mariadb conf in tests bootstrap --- tests/bootstrap.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/bootstrap.sh b/tests/bootstrap.sh index b324a84001..e46c4ee95e 100755 --- a/tests/bootstrap.sh +++ b/tests/bootstrap.sh @@ -21,8 +21,12 @@ shift VERBOSITY=$@ set -x -mysql -uroot -ptoor -e 'SET @@global.sql_mode=STRICT_ALL_TABLES;' -mysql -uroot -ptoor -e 'CREATE SCHEMA IF NOT EXISTS ab_test;CREATE SCHEMA IF NOT EXISTS db_test;' +mysql -uroot -ptoor -e ' +SET @@global.sql_mode= STRICT_ALL_TABLES; +SET @@global.max_allowed_packet= 33554432; +SET @@global.wait_timeout= 999999; +CREATE SCHEMA IF NOT EXISTS ab_test;CREATE SCHEMA IF NOT EXISTS db_test; +' if ! ./bin/developer system:uninstall > /dev/null 2>&1 then rm -f config/configuration.yml config/configuration-compiled.php From 52001b583ceef31432d41051134013e6fc0f492a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Wed, 1 Apr 2015 18:47:26 +0200 Subject: [PATCH 18/26] rename admin_dashboard route --- .../Phrasea/ControllerProvider/Admin/Dashboard.php | 14 +++++++------- templates/web/admin/tree.html.twig | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php index b5fa997ff3..9c9e6e5d4e 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php @@ -34,7 +34,7 @@ class Dashboard implements ControllerProviderInterface }); $controllers->get('/', 'controller.admin.dashboard:slash') - ->bind('admin_dashbord'); + ->bind('admin_dashboard'); $controllers->post('/flush-cache/', 'controller.admin.dashboard:flush') ->bind('admin_dashboard_flush_cache'); @@ -88,10 +88,10 @@ class Dashboard implements ControllerProviderInterface public function flush(Application $app, Request $request) { if ($app['phraseanet.cache-service']->flushAll()) { - return $app->redirectPath('admin_dashbord', ['flush_cache' => 'ok']); + return $app->redirectPath('admin_dashboard', ['flush_cache' => 'ok']); } - return $app->redirectPath('admin_dashbord', ['flush_cache' => 'ko']); + return $app->redirectPath('admin_dashboard', ['flush_cache' => 'ko']); } /** @@ -114,7 +114,7 @@ class Dashboard implements ControllerProviderInterface try { $receiver = new Receiver(null, $mail); } catch (InvalidArgumentException $e) { - return $app->redirectPath('admin_dashbord', ['email' => 'not-sent']); + return $app->redirectPath('admin_dashboard', ['email' => 'not-sent']); } $mail = MailTest::create($app, $receiver); @@ -122,7 +122,7 @@ class Dashboard implements ControllerProviderInterface $app['notification.deliverer']->deliver($mail); $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); - return $app->redirectPath('admin_dashbord', ['email' => 'sent']); + return $app->redirectPath('admin_dashboard', ['email' => 'sent']); } /** @@ -136,7 +136,7 @@ class Dashboard implements ControllerProviderInterface { $app['manipulator.acl']->resetAdminRights($app['repo.users']->findAdmins()); - return $app->redirectPath('admin_dashbord'); + return $app->redirectPath('admin_dashboard'); } /** @@ -167,6 +167,6 @@ class Dashboard implements ControllerProviderInterface $app['manipulator.user']->promote($admins); $app['manipulator.acl']->resetAdminRights($admins); - return $app->redirectPath('admin_dashbord'); + return $app->redirectPath('admin_dashboard'); } } diff --git a/templates/web/admin/tree.html.twig b/templates/web/admin/tree.html.twig index 597819ac10..228cb2919e 100644 --- a/templates/web/admin/tree.html.twig +++ b/templates/web/admin/tree.html.twig @@ -4,7 +4,7 @@ {% if app['acl'].get(app['authentication'].getUser()).is_admin() %}
  • - + {{ 'Tableau de bord' | trans }} From c19b1559c95ace136a124733acd11384d764610e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Wed, 1 Apr 2015 19:24:24 +0200 Subject: [PATCH 19/26] DashboardController Refactoring --- lib/Alchemy/Phrasea/Application.php | 3 +- .../Controller/Admin/DashboardController.php | 183 ++++++++++++++++++ .../ControllerProvider/Admin/Dashboard.php | 147 ++------------ 3 files changed, 202 insertions(+), 131 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 29ed265713..e1517fe2bf 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -312,6 +312,7 @@ class Application extends SilexApplication $providers = [ 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], @@ -618,7 +619,6 @@ class Application extends SilexApplication $this->mount('/developers/', new Developers()); $this->mount('/admin/', new AdminRoot()); - $this->mount('/admin/dashboard', new Dashboard()); $this->mount('/admin/databox', new Databox()); $this->mount('/admin/databoxes', new Databoxes()); $this->mount('/admin/setup', new Setup()); @@ -671,6 +671,7 @@ class Application extends SilexApplication $providers = [ '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', '/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers', + '/admin/dashboard' => 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard', '/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users', '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php new file mode 100644 index 0000000000..e1c889b46b --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php @@ -0,0 +1,183 @@ +app = $app; + } + + /** + * Display admin dashboard page + * + * @param Request $request + * @return string + */ + public function slash(Request $request) + { + switch ($emailStatus = $request->query->get('email')) { + case 'sent'; + $emailStatus = $this->app->trans('Mail sent'); + break; + case 'error': + $emailStatus = $this->app->trans('Could not send email'); + break; + } + + return $this->render('admin/dashboard.html.twig', [ + 'cache_flushed' => $request->query->get('flush_cache') === 'ok', + 'admins' => $this->getUserRepository()->findAdmins(), + 'email_status' => $emailStatus, + ]); + } + + /** + * Flush all cache services + * + * @return RedirectResponse + */ + public function flush() + { + /** @var Cache $cache */ + $cache = $this->app['phraseanet.cache-service']; + $flushOK = $cache->flushAll() ? 'ok' : 'ko'; + + return $this->app->redirectPath('admin_dashboard', ['flush_cache' => $flushOK]); + } + + /** + * Test a mail address + * + * @param Request $request + * @return RedirectResponse + */ + public function sendMail(Request $request) + { + if (null === $mail = $request->request->get('email')) { + $this->app->abort(400, 'Bad request missing email parameter'); + }; + + if (!\Swift_Validate::email($mail)) { + $this->app->abort(400, 'Bad request missing email parameter'); + }; + + try { + $receiver = new Receiver(null, $mail); + } catch (InvalidArgumentException $e) { + return $this->app->redirectPath('admin_dashboard', ['email' => 'not-sent']); + } + + $mail = MailTest::create($this->app, $receiver); + + /** @var Deliverer $deliverer */ + $deliverer = $this->app['notification.deliverer']; + $deliverer->deliver($mail); + + /** @var \Swift_SpoolTransport $spoolTransport */ + $spoolTransport = $this->app['swiftmailer.spooltransport']; + /** @var \Swift_Transport $transport */ + $transport = $this->app['swiftmailer.transport']; + $spoolTransport->getSpool()->flushQueue($transport); + + return $this->app->redirectPath('admin_dashboard', ['email' => 'sent']); + } + + /** + * Reset admin rights + * + * @return RedirectResponse + */ + public function resetAdminRights() + { + /** @var ACLManipulator $aclManipulator */ + $aclManipulator = $this->app['manipulator.acl']; + $aclManipulator->resetAdminRights($this->getUserRepository()->findAdmins()); + + return $this->app->redirectPath('admin_dashboard'); + } + + /** + * Grant to an user admin rights + * + * @param Request $request + * @return RedirectResponse + */ + public function addAdmins(Request $request) + { + $admins = $request->request->get('admins', []); + if (!is_array($admins) || count($admins) === 0) { + $this->app->abort(400, '"admins" parameter must contains at least one value.'); + } + /** @var Authenticator $authenticator */ + $authenticator = $this->app['authentication']; + if (!in_array($authenticator->getUser()->getId(), $admins)) { + $admins[] = $authenticator->getUser()->getId(); + } + + $userRepository = $this->getUserRepository(); + $userRepository->findBy(['id' => $admins]); + $admins = array_map(function ($usrId) use ($userRepository) { + if (null === $user = $userRepository->find($usrId)) { + throw new RuntimeException(sprintf('Invalid usrId %s provided.', $usrId)); + } + + return $user; + }, $admins); + + /** @var UserManipulator $userManipulator */ + $userManipulator = $this->app['manipulator.user']; + $userManipulator->promote($admins); + /** @var ACLManipulator $aclManipulator */ + $aclManipulator = $this->app['manipulator.acl']; + $aclManipulator->resetAdminRights($admins); + + return $this->app->redirectPath('admin_dashboard'); + } + + /** + * @param string $name + * @param array $context + * @return string + */ + public function render($name, array $context = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render($name, $context); + } + + /** + * @return UserRepository + */ + public function getUserRepository() + { + return $this->app['repo.users']; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php index 9c9e6e5d4e..d637949d46 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php @@ -11,25 +11,31 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Phrasea\Controller\Admin\RedirectResponse; -use Alchemy\Phrasea\Notification\Receiver; -use Alchemy\Phrasea\Notification\Mail\MailTest; -use Alchemy\Phrasea\Exception\InvalidArgumentException; -use Alchemy\Phrasea\Exception\RuntimeException; +use Alchemy\Phrasea\Controller\Admin\DashboardController; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Silex\ServiceProviderInterface; -class Dashboard implements ControllerProviderInterface +class Dashboard implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.dashboard'] = $app->share(function () use ($app) { + return new DashboardController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.dashboard'] = $this; - + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; - $controllers->before(function (Request $request) use ($app) { + $controllers->before(function () use ($app) { $app['firewall']->requireAdmin(); }); @@ -50,123 +56,4 @@ class Dashboard implements ControllerProviderInterface return $controllers; } - - /** - * Display admin dashboard page - * - * @param Application $app - * @param Request $request - * @return Response - */ - public function slash(Application $app, Request $request) - { - switch ($emailStatus = $request->query->get('email')) { - case 'sent'; - $emailStatus = $app->trans('Mail sent'); - break; - case 'error': - $emailStatus = $app->trans('Could not send email'); - break; - } - - $parameters = [ - 'cache_flushed' => $request->query->get('flush_cache') === 'ok', - 'admins' => $app['repo.users']->findAdmins(), - 'email_status' => $emailStatus, - ]; - - return $app['twig']->render('admin/dashboard.html.twig', $parameters); - } - - /** - * Flush all cash services - * - * @param Application $app - * @param Request $request - * @return RedirectResponse - */ - public function flush(Application $app, Request $request) - { - if ($app['phraseanet.cache-service']->flushAll()) { - return $app->redirectPath('admin_dashboard', ['flush_cache' => 'ok']); - } - - return $app->redirectPath('admin_dashboard', ['flush_cache' => 'ko']); - } - - /** - * Test a mail address - * - * @param Application $app - * @param Request $request - * @return RedirectResponse - */ - public function sendMail(Application $app, Request $request) - { - if (null === $mail = $request->request->get('email')) { - $app->abort(400, 'Bad request missing email parameter'); - }; - - if (!\Swift_Validate::email($request->request->get('email'))) { - $app->abort(400, 'Bad request missing email parameter'); - }; - - try { - $receiver = new Receiver(null, $mail); - } catch (InvalidArgumentException $e) { - return $app->redirectPath('admin_dashboard', ['email' => 'not-sent']); - } - - $mail = MailTest::create($app, $receiver); - - $app['notification.deliverer']->deliver($mail); - $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); - - return $app->redirectPath('admin_dashboard', ['email' => 'sent']); - } - - /** - * Reset admin rights - * - * @param Application $app - * @param Request $request - * @return RedirectResponse - */ - public function resetAdminRights(Application $app, Request $request) - { - $app['manipulator.acl']->resetAdminRights($app['repo.users']->findAdmins()); - - return $app->redirectPath('admin_dashboard'); - } - - /** - * Grant to an user admin rights - * - * @param Application $app - * @param Request $request - * @return RedirectResponse - */ - public function addAdmins(Application $app, Request $request) - { - $admins = $request->request->get('admins', []); - if (count($admins) === 0 || !is_array($admins)) { - $app->abort(400, '"admins" parameter must contains at least one value.'); - } - if (!in_array($app['authentication']->getUser()->getId(), $admins)) { - $admins[] = $app['authentication']->getUser()->getId(); - } - - $admins = array_map(function ($usrId) use ($app) { - if (null === $user = $app['repo.users']->find($usrId)) { - throw new RuntimeException(sprintf('Invalid usrId %s provided.', $usrId)); - } - - return $user; - }, $admins); - - $app['manipulator.user']->promote($admins); - $app['manipulator.acl']->resetAdminRights($admins); - - return $app->redirectPath('admin_dashboard'); - } } From e069d335ad472fb8c938a39695ab4df7e535c764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Wed, 1 Apr 2015 20:17:53 +0200 Subject: [PATCH 20/26] Partial DataboxController Refactor --- .../Controller/Admin/DataboxController.php | 750 +++++++++++++++ .../ControllerProvider/Admin/Databox.php | 858 ++---------------- 2 files changed, 824 insertions(+), 784 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php new file mode 100644 index 0000000000..7f0827adc9 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php @@ -0,0 +1,750 @@ +app = $app; + } + + /** + * @param Request $request + * @param integer $databox_id + * @return Response + */ + public function getDatabase(Request $request, $databox_id) + { + $databox = $this->findDataboxById($databox_id); + + switch ($errorMsg = $request->query->get('error')) { + case 'file-error': + $errorMsg = $this->app->trans('Error while sending the file'); + break; + case 'file-invalid': + $errorMsg = $this->app->trans('Invalid file format'); + break; + case 'file-too-big': + $errorMsg = $this->app->trans('The file is too big'); + break; + } + + return $this->render('admin/databox/databox.html.twig', [ + 'databox' => $databox, + 'showDetail' => (int)$request->query->get("sta") < 1, + 'errorMsg' => $errorMsg, + 'reloadTree' => $request->query->get('reload-tree') === '1' + ]); + } + + /** + * Get databox CGU's + * + * @param integer $databox_id The requested databox + * @return Response + */ + public function getDatabaseCGU($databox_id) + { + return $this->render('admin/databox/cgus.html.twig', [ + 'languages' => $this->app['locales.available'], + 'cgus' => $this->findDataboxById($databox_id)->get_cgus(), + 'current_locale' => $this->app['locale'], + ]); + } + + /** + * Delete a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function deleteBase(Application $app, Request $request, $databox_id) + { + $success = false; + $msg = $app->trans('An error occured'); + try { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + + if ($databox->get_record_amount() > 0) { + $msg = $app->trans('admin::base: vider la base avant de la supprimer'); + } else { + $databox->unmount_databox(); + $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, null, \databox::PIC_PDF); + $databox->delete(); + $success = true; + $msg = $app->trans('Successful removal'); + } + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $msg, + 'sbas_id' => $databox->get_sbas_id() + ]); + } + + $params = [ + '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); + } + + public function setLabels(Application $app, Request $request, $databox_id) + { + if (null === $labels = $request->request->get('labels')) { + $app->abort(400, $app->trans('Missing labels parameter')); + } + if (false === is_array($labels)) { + $app->abort(400, $app->trans('Invalid labels parameter')); + } + + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $success = true; + + try { + foreach ($app['locales.available'] as $code => $language) { + if (!isset($labels[$code])) { + continue; + } + $value = $labels[$code] ?: null; + $databox->set_label($code, $value); + } + } catch (\Exception $e) { + $success = false; + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') + ]); + } + + return $app->redirect('/admin/databox/' . $databox->get_sbas_id() . '/?success=' . (int) $success . '&reload-tree=1'); + } + + /** + * Reindex databox content + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function reindex(Application $app, Request $request, $databox_id) + { + $success = false; + + try { + $app['phraseanet.appbox']->get_databox($databox_id)->reindex(); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Make a databox indexable + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function setIndexable(Application $app, Request $request, $databox_id) + { + $success = false; + + try { + $app['phraseanet.appbox']->set_databox_indexable($app['phraseanet.appbox']->get_databox($databox_id), !!$request->request->get('indexable', false)); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Update databox CGU's + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return RedirectResponse + */ + public function updateDatabaseCGU(Application $app, Request $request, $databox_id) + { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + + try { + foreach ($request->request->get('TOU', []) as $loc => $terms) { + $databox->update_cgus($loc, $terms, !!$request->request->get('valid', false)); + } + } catch (\Exception $e) { + return $app->redirectPath('admin_database_display_cgus', [ + 'databox_id' => $databox_id, + 'success' => 0, + ]); + } + + return $app->redirectPath('admin_database_display_cgus', [ + 'databox_id' => $databox_id, + 'success' => 1, + ]); + } + + /** + * Mount a collection on a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @param integer $collection_id The requested collection id + * @return RedirectResponse + */ + public function mountCollection(Application $app, Request $request, $databox_id, $collection_id) + { + $app['phraseanet.appbox']->get_connection()->beginTransaction(); + try { + $baseId = \collection::mount_collection($app, $app['phraseanet.appbox']->get_databox($databox_id), $collection_id, $app['authentication']->getUser()); + + $othCollSel = (int) $request->request->get("othcollsel") ?: null; + + if (null !== $othCollSel) { + $query = $app['phraseanet.user-query']; + $n = 0; + + while ($n < $query->on_base_ids([$othCollSel])->get_total()) { + $results = $query->limit($n, 50)->execute()->get_results(); + + foreach ($results as $user) { + $app['acl']->get($user)->duplicate_right_from_bas($othCollSel, $baseId); + } + + $n += 50; + } + } + + $app['phraseanet.appbox']->get_connection()->commit(); + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'mount' => 'ok', + ]); + } catch (\Exception $e) { + $app['phraseanet.appbox']->get_connection()->rollBack(); + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'mount' => 'ko', + ]); + } + } + + /** + * Set a new logo for a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return RedirectResponse + */ + public function sendLogoPdf(Application $app, Request $request, $databox_id) + { + try { + if (null !== ($file = $request->files->get('newLogoPdf')) && $file->isValid()) { + + if ($file->getClientSize() < 65536) { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, $file, \databox::PIC_PDF); + unlink($file->getPathname()); + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '1', + ]); + } else { + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-too-big', + ]); + } + } else { + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-invalid', + ]); + } + } catch (\Exception $e) { + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-error', + ]); + } + } + + /** + * Delete an existing logo for a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function deleteLogoPdf(Application $app, Request $request, $databox_id) + { + $success = false; + + try { + $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $app['phraseanet.appbox']->get_databox($databox_id), null, \databox::PIC_PDF); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Clear databox logs + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function clearLogs(Application $app, Request $request, $databox_id) + { + $success = false; + + try { + $app['phraseanet.appbox']->get_databox($databox_id)->clear_logs(); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Change the name of a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function changeViewName(Application $app, Request $request, $databox_id) + { + if (null === $viewName = $request->request->get('viewname')) { + $app->abort(400, $app->trans('Missing view name parameter')); + } + + $success = false; + + try { + $app['phraseanet.appbox']->get_databox($databox_id)->set_viewname($viewName); + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Unmount a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function unmountDatabase(Application $app, Request $request, $databox_id) + { + $success = false; + + try { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox->unmount_databox(); + + $success = true; + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('The publication has been stopped') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_databases', [ + 'reload-tree' => 1, + ]); + } + + /** + * Empty a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function emptyDatabase(Application $app, Request $request, $databox_id) + { + $msg = $app->trans('An error occurred'); + $success = false; + $taskCreated = false; + + try { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + + foreach ($databox->get_collections() as $collection) { + if ($collection->get_record_amount() <= 500) { + $collection->empty_collection(500); + } else { + $app['manipulator.task']->createEmptyCollectionJob($collection); + } + } + + $msg = $app->trans('Base empty successful'); + $success = true; + + if ($taskCreated) { + $msg = $app->trans('A task has been created, please run it to complete empty collection'); + } + } catch (\Exception $e) { + + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $msg, + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Get number of indexed items for a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse + */ + public function progressBarInfos(Application $app, Request $request, $databox_id) + { + if (!$app['request']->isXmlHttpRequest() || 'json' !== $app['request']->getRequestFormat()) { + $app->abort(400, $app->trans('Bad request format, only JSON is allowed')); + } + + $app['phraseanet.appbox'] = $app['phraseanet.appbox']; + + $ret = [ + 'success' => false, + 'msg' => $app->trans('An error occured'), + 'sbas_id' => null, + 'indexable' => false, + 'records' => 0, + 'xml_indexed' => 0, + 'thesaurus_indexed' => 0, + 'viewname' => null, + 'printLogoURL' => null + ]; + + try { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $datas = $databox->get_indexed_record_amount(); + + $ret['indexable'] = $app['phraseanet.appbox']->is_databox_indexable($databox); + $ret['viewname'] = (($databox->get_dbname() == $databox->get_viewname()) ? $app->trans('admin::base: aucun alias') : $databox->get_viewname()); + $ret['records'] = $databox->get_record_amount(); + $ret['sbas_id'] = $databox_id; + $ret['xml_indexed'] = $datas['xml_indexed']; + $ret['thesaurus_indexed'] = $datas['thesaurus_indexed']; + $ret['jeton_subdef'] = $datas['jeton_subdef']; + if ($app['filesystem']->exists($app['root.path'] . '/config/minilogos/logopdf_' . $databox_id . '.jpg')) { + $ret['printLogoURL'] = '/custom/minilogos/logopdf_' . $databox_id . '.jpg'; + } + + $ret['success'] = true; + $ret['msg'] = $app->trans('Successful update'); + } catch (\Exception $e) { + + } + + return $app->json($ret); + } + + /** + * Display page for reaorder collections on a databox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function getReorder(Application $app, Request $request, $databox_id) + { + return $app['twig']->render('admin/collection/reorder.html.twig', [ + 'collections' => $app['acl']->get($app['authentication']->getUser())->get_granted_base([], [$databox_id]), + ]); + } + + /** + * Apply collection reorder changes + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function setReorder(Application $app, Request $request, $databox_id) + { + try { + foreach ($request->request->get('order', []) as $data) { + $collection = \collection::get_from_base_id($app, $data['id']); + $collection->set_ord($data['offset']); + } + $success = true; + } catch (\Exception $e) { + $success = false; + } + + if ('json' === $app['request']->getRequestFormat()) { + return $app->json([ + 'success' => $success, + 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), + 'sbas_id' => $databox_id + ]); + } + + return $app->redirectPath('admin_database_display_collections_order', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Display page to create a new collection + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function getNewCollection(Application $app, Request $request, $databox_id) + { + return $app['twig']->render('admin/collection/create.html.twig'); + } + + /** + * Create a new collection + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function createCollection(Application $app, Request $request, $databox_id) + { + if (($name = trim($request->request->get('name', ''))) === '') { + return $app->redirectPath('admin_database_display_new_collection_form', [ + 'databox_id' => $databox_id, + 'error' => 'name', + ]); + } + + try { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $collection = \collection::create($app, $databox, $app['phraseanet.appbox'], $name, $app['authentication']->getUser()); + + if (($request->request->get('ccusrothercoll') === "on") + && (null !== $othcollsel = $request->request->get('othcollsel'))) { + $query = $app['phraseanet.user-query']; + $total = $query->on_base_ids([$othcollsel])->get_total(); + $n = 0; + while ($n < $total) { + $results = $query->limit($n, 20)->execute()->get_results(); + foreach ($results as $user) { + $app['acl']->get($user)->duplicate_right_from_bas($othcollsel, $collection->get_base_id()); + } + $n += 20; + } + } + + return $app->redirectPath('admin_display_collection', ['bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1]); + } catch (\Exception $e) { + return $app->redirectPath('admin_database_submit_collection', ['databox_id' => $databox_id, 'error' => 'error']); + } + } + + /** + * Display page to get some details on a appbox + * + * @param Application $app The silex application + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function getDetails(Application $app, Request $request, $databox_id) + { + $databox = $app['phraseanet.appbox']->get_databox($databox_id); + + $details = []; + $total = ['total_subdefs' => 0, 'total_size' => 0]; + + foreach ($databox->get_record_details($request->query->get('sort')) as $collName => $colDetails) { + $details[$collName] = [ + 'total_subdefs' => 0, + 'total_size' => 0, + 'medias' => [] + ]; + + foreach ($colDetails as $subdefName => $subdefDetails) { + $details[$collName]['total_subdefs'] += $subdefDetails['n']; + $total['total_subdefs'] += $subdefDetails['n']; + $details[$collName]['total_size'] += $subdefDetails['siz']; + $total['total_size'] += $subdefDetails['siz']; + + $details[$collName]['medias'][] = [ + 'subdef_name' => $subdefName, + 'total_subdefs' => $subdefDetails['n'], + 'total_size' => $subdefDetails['siz'], + ]; + } + } + + return $app['twig']->render('admin/databox/details.html.twig', [ + 'databox' => $databox, + 'table' => $details, + 'total' => $total + ]); + } + + /** + * @param int $id + * @return \databox + */ + private function findDataboxById($id) + { + /** @var \appbox $appbox */ + $appbox = $this->app['phraseanet.appbox']; + return $appbox->get_databox($id); + } + + /** + * @param $name + * @param array $context + * @return string + */ + private function render($name, array $context = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render( + $name, + $context + ); + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php index d439998719..8938c8e1db 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php @@ -11,851 +11,141 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Phrasea\Controller\Admin\JsonResponse; -use Alchemy\Phrasea\Controller\Admin\RedirectResponse; +use Alchemy\Phrasea\Controller\Admin\DataboxController; +use Alchemy\Phrasea\Security\Firewall; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; +use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -class Databox implements ControllerProviderInterface +class Databox implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.databox'] = $app->share(function () use ($app) { + return new DataboxController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.databox'] = $this; - + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; $app['firewall']->addMandatoryAuthentication($controllers); - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('admin') - ->requireAccessToSbas($request->attributes->get('databox_id')); - }); + $controllers + ->before(function (Request $request) use ($app) { + $app['firewall']->requireAccessToModule('admin') + ->requireAccessToSbas($request->attributes->get('databox_id')); + }) + ->assert('databox_id', '\d+') + ; $controllers->get('/{databox_id}/', 'controller.admin.databox:getDatabase') - ->assert('databox_id', '\d+') ->bind('admin_database'); $controllers->post('/{databox_id}/delete/', 'controller.admin.databox:deleteBase') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_delete'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_delete'); $controllers->post('/{databox_id}/unmount/', 'controller.admin.databox:unmountDatabase') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_unmount'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_unmount'); $controllers->post('/{databox_id}/empty/', 'controller.admin.databox:emptyDatabase') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_empty'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_empty'); $controllers->get('/{databox_id}/collections/order/', 'controller.admin.databox:getReorder') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_display_collections_order'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_collections_order'); $controllers->post('/{databox_id}/collections/order/', 'controller.admin.databox:setReorder') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_submit_collections_order'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_submit_collections_order'); $controllers->post('/{databox_id}/collection/', 'controller.admin.databox:createCollection') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - }) + ->before([$this, 'requireManageRightOnSbas']) ->bind('admin_database_submit_collection'); $controllers->get('/{databox_id}/cgus/', 'controller.admin.databox:getDatabaseCGU') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_modify_struct'); - })->bind('admin_database_display_cgus'); + ->before([$this, 'requireChangeSbasStructureRight']) + ->bind('admin_database_display_cgus'); $controllers->post('/{databox_id}/labels/', 'controller.admin.databox:setLabels') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_databox_labels'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_databox_labels'); $controllers->post('/{databox_id}/cgus/', 'controller.admin.databox:updateDatabaseCGU') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_modify_struct'); - })->bind('admin_database_submit_cgus'); + ->before([$this, 'requireChangeSbasStructureRight']) + ->bind('admin_database_submit_cgus'); $controllers->get('/{databox_id}/informations/documents/', 'controller.admin.databox:progressBarInfos') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_display_document_information'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_document_information'); $controllers->get('/{databox_id}/informations/details/', 'controller.admin.databox:getDetails') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_display_document_details'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_document_details'); $controllers->post('/{databox_id}/collection/{collection_id}/mount/', 'controller.admin.databox:mountCollection') - ->assert('databox_id', '\d+') ->assert('collection_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_mount_collection'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_mount_collection'); $controllers->get('/{databox_id}/collection/', 'controller.admin.databox:getNewCollection') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_display_new_collection_form'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_new_collection_form'); $controllers->post('/{databox_id}/logo/', 'controller.admin.databox:sendLogoPdf') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_submit_logo'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_submit_logo'); $controllers->post('/{databox_id}/logo/delete/', 'controller.admin.databox:deleteLogoPdf') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_delete_logo'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_delete_logo'); $controllers->post('/{databox_id}/clear-logs/', 'controller.admin.databox:clearLogs') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_clear_logs'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_clear_logs'); $controllers->post('/{databox_id}/reindex/', 'controller.admin.databox:reindex') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_reindex'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_reindex'); $controllers->post('/{databox_id}/indexable/', 'controller.admin.databox:setIndexable') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_set_indexable'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_set_indexable'); $controllers->post('/{databox_id}/view-name/', 'controller.admin.databox:changeViewName') - ->assert('databox_id', '\d+') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); - })->bind('admin_database_rename'); + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_rename'); return $controllers; } + public function requireManageRightOnSbas(Request $request, Application $app) + { + $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_manage'); + } + + public function requireChangeSbasStructureRight(Request $request, Application $app) + { + $this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_modify_struct'); + } + /** - * * @param Application $app - * @param Request $request - * @param integer $databox_id - * - * @return Response + * @return Firewall */ - public function getDatabase(Application $app, Request $request, $databox_id) + private function getFirewall(Application $app) { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - - switch ($errorMsg = $request->query->get('error')) { - case 'file-error': - $errorMsg = $app->trans('Error while sending the file'); - break; - case 'file-invalid': - $errorMsg = $app->trans('Invalid file format'); - break; - case 'file-too-big': - $errorMsg = $app->trans('The file is too big'); - break; - } - - return $app['twig']->render('admin/databox/databox.html.twig', [ - 'databox' => $databox, - 'showDetail' => (int) $request->query->get("sta") < 1, - 'errorMsg' => $errorMsg, - 'reloadTree' => $request->query->get('reload-tree') === '1' - ]); - } - - /** - * Get databox CGU's - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return Response - */ - public function getDatabaseCGU(Application $app, Request $request, $databox_id) - { - return $app['twig']->render('admin/databox/cgus.html.twig', [ - 'languages' => $app['locales.available'], - 'cgus' => $app['phraseanet.appbox']->get_databox($databox_id)->get_cgus(), - 'current_locale' => $app['locale'] - ]); - } - - /** - * Delete a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function deleteBase(Application $app, Request $request, $databox_id) - { - $success = false; - $msg = $app->trans('An error occured'); - try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - - if ($databox->get_record_amount() > 0) { - $msg = $app->trans('admin::base: vider la base avant de la supprimer'); - } else { - $databox->unmount_databox(); - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, null, \databox::PIC_PDF); - $databox->delete(); - $success = true; - $msg = $app->trans('Successful removal'); - } - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $msg, - 'sbas_id' => $databox->get_sbas_id() - ]); - } - - $params = [ - '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); - } - - public function setLabels(Application $app, Request $request, $databox_id) - { - if (null === $labels = $request->request->get('labels')) { - $app->abort(400, $app->trans('Missing labels parameter')); - } - if (false === is_array($labels)) { - $app->abort(400, $app->trans('Invalid labels parameter')); - } - - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $success = true; - - try { - foreach ($app['locales.available'] as $code => $language) { - if (!isset($labels[$code])) { - continue; - } - $value = $labels[$code] ?: null; - $databox->set_label($code, $value); - } - } catch (\Exception $e) { - $success = false; - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') - ]); - } - - return $app->redirect('/admin/databox/' . $databox->get_sbas_id() . '/?success=' . (int) $success . '&reload-tree=1'); - } - - /** - * Reindex databox content - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function reindex(Application $app, Request $request, $databox_id) - { - $success = false; - - try { - $app['phraseanet.appbox']->get_databox($databox_id)->reindex(); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => (int) $success, - ]); - } - - /** - * Make a databox indexable - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function setIndexable(Application $app, Request $request, $databox_id) - { - $success = false; - - try { - $app['phraseanet.appbox']->set_databox_indexable($app['phraseanet.appbox']->get_databox($databox_id), !!$request->request->get('indexable', false)); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => (int) $success, - ]); - } - - /** - * Update databox CGU's - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return RedirectResponse - */ - public function updateDatabaseCGU(Application $app, Request $request, $databox_id) - { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - - try { - foreach ($request->request->get('TOU', []) as $loc => $terms) { - $databox->update_cgus($loc, $terms, !!$request->request->get('valid', false)); - } - } catch (\Exception $e) { - return $app->redirectPath('admin_database_display_cgus', [ - 'databox_id' => $databox_id, - 'success' => 0, - ]); - } - - return $app->redirectPath('admin_database_display_cgus', [ - 'databox_id' => $databox_id, - 'success' => 1, - ]); - } - - /** - * Mount a collection on a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @param integer $collection_id The requested collection id - * @return RedirectResponse - */ - public function mountCollection(Application $app, Request $request, $databox_id, $collection_id) - { - $app['phraseanet.appbox']->get_connection()->beginTransaction(); - try { - $baseId = \collection::mount_collection($app, $app['phraseanet.appbox']->get_databox($databox_id), $collection_id, $app['authentication']->getUser()); - - $othCollSel = (int) $request->request->get("othcollsel") ?: null; - - if (null !== $othCollSel) { - $query = $app['phraseanet.user-query']; - $n = 0; - - while ($n < $query->on_base_ids([$othCollSel])->get_total()) { - $results = $query->limit($n, 50)->execute()->get_results(); - - foreach ($results as $user) { - $app['acl']->get($user)->duplicate_right_from_bas($othCollSel, $baseId); - } - - $n += 50; - } - } - - $app['phraseanet.appbox']->get_connection()->commit(); - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'mount' => 'ok', - ]); - } catch (\Exception $e) { - $app['phraseanet.appbox']->get_connection()->rollBack(); - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'mount' => 'ko', - ]); - } - } - - /** - * Set a new logo for a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return RedirectResponse - */ - public function sendLogoPdf(Application $app, Request $request, $databox_id) - { - try { - if (null !== ($file = $request->files->get('newLogoPdf')) && $file->isValid()) { - - if ($file->getClientSize() < 65536) { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, $file, \databox::PIC_PDF); - unlink($file->getPathname()); - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => '1', - ]); - } else { - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => '0', - 'error' => 'file-too-big', - ]); - } - } else { - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => '0', - 'error' => 'file-invalid', - ]); - } - } catch (\Exception $e) { - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'success' => '0', - 'error' => 'file-error', - ]); - } - } - - /** - * Delete an existing logo for a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function deleteLogoPdf(Application $app, Request $request, $databox_id) - { - $success = false; - - try { - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $app['phraseanet.appbox']->get_databox($databox_id), null, \databox::PIC_PDF); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'error' => 'file-too-big', - ]); - } - - /** - * Clear databox logs - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function clearLogs(Application $app, Request $request, $databox_id) - { - $success = false; - - try { - $app['phraseanet.appbox']->get_databox($databox_id)->clear_logs(); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'error' => 'file-too-big', - ]); - } - - /** - * Change the name of a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function changeViewName(Application $app, Request $request, $databox_id) - { - if (null === $viewName = $request->request->get('viewname')) { - $app->abort(400, $app->trans('Missing view name parameter')); - } - - $success = false; - - try { - $app['phraseanet.appbox']->get_databox($databox_id)->set_viewname($viewName); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'error' => 'file-too-big', - ]); - } - - /** - * Unmount a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function unmountDatabase(Application $app, Request $request, $databox_id) - { - $success = false; - - try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $databox->unmount_databox(); - - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('The publication has been stopped') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_databases', [ - 'reload-tree' => 1, - ]); - } - - /** - * Empty a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function emptyDatabase(Application $app, Request $request, $databox_id) - { - $msg = $app->trans('An error occurred'); - $success = false; - $taskCreated = false; - - try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - - foreach ($databox->get_collections() as $collection) { - if ($collection->get_record_amount() <= 500) { - $collection->empty_collection(500); - } else { - $app['manipulator.task']->createEmptyCollectionJob($collection); - } - } - - $msg = $app->trans('Base empty successful'); - $success = true; - - if ($taskCreated) { - $msg = $app->trans('A task has been created, please run it to complete empty collection'); - } - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $msg, - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database', [ - 'databox_id' => $databox_id, - 'error' => 'file-too-big', - ]); - } - - /** - * Get number of indexed items for a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse - */ - public function progressBarInfos(Application $app, Request $request, $databox_id) - { - if (!$app['request']->isXmlHttpRequest() || 'json' !== $app['request']->getRequestFormat()) { - $app->abort(400, $app->trans('Bad request format, only JSON is allowed')); - } - - $app['phraseanet.appbox'] = $app['phraseanet.appbox']; - - $ret = [ - 'success' => false, - 'msg' => $app->trans('An error occured'), - 'sbas_id' => null, - 'indexable' => false, - 'records' => 0, - 'xml_indexed' => 0, - 'thesaurus_indexed' => 0, - 'viewname' => null, - 'printLogoURL' => null - ]; - - try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $datas = $databox->get_indexed_record_amount(); - - $ret['indexable'] = $app['phraseanet.appbox']->is_databox_indexable($databox); - $ret['viewname'] = (($databox->get_dbname() == $databox->get_viewname()) ? $app->trans('admin::base: aucun alias') : $databox->get_viewname()); - $ret['records'] = $databox->get_record_amount(); - $ret['sbas_id'] = $databox_id; - $ret['xml_indexed'] = $datas['xml_indexed']; - $ret['thesaurus_indexed'] = $datas['thesaurus_indexed']; - $ret['jeton_subdef'] = $datas['jeton_subdef']; - if ($app['filesystem']->exists($app['root.path'] . '/config/minilogos/logopdf_' . $databox_id . '.jpg')) { - $ret['printLogoURL'] = '/custom/minilogos/logopdf_' . $databox_id . '.jpg'; - } - - $ret['success'] = true; - $ret['msg'] = $app->trans('Successful update'); - } catch (\Exception $e) { - - } - - return $app->json($ret); - } - - /** - * Display page for reaorder collections on a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return Response - */ - public function getReorder(Application $app, Request $request, $databox_id) - { - return $app['twig']->render('admin/collection/reorder.html.twig', [ - 'collections' => $app['acl']->get($app['authentication']->getUser())->get_granted_base([], [$databox_id]), - ]); - } - - /** - * Apply collection reorder changes - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return JsonResponse|RedirectResponse - */ - public function setReorder(Application $app, Request $request, $databox_id) - { - try { - foreach ($request->request->get('order', []) as $data) { - $collection = \collection::get_from_base_id($app, $data['id']); - $collection->set_ord($data['offset']); - } - $success = true; - } catch (\Exception $e) { - $success = false; - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ - 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id - ]); - } - - return $app->redirectPath('admin_database_display_collections_order', [ - 'databox_id' => $databox_id, - 'success' => (int) $success, - ]); - } - - /** - * Display page to create a new collection - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return Response - */ - public function getNewCollection(Application $app, Request $request, $databox_id) - { - return $app['twig']->render('admin/collection/create.html.twig'); - } - - /** - * Create a new collection - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return Response - */ - public function createCollection(Application $app, Request $request, $databox_id) - { - if (($name = trim($request->request->get('name', ''))) === '') { - return $app->redirectPath('admin_database_display_new_collection_form', [ - 'databox_id' => $databox_id, - 'error' => 'name', - ]); - } - - try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $collection = \collection::create($app, $databox, $app['phraseanet.appbox'], $name, $app['authentication']->getUser()); - - if (($request->request->get('ccusrothercoll') === "on") - && (null !== $othcollsel = $request->request->get('othcollsel'))) { - $query = $app['phraseanet.user-query']; - $total = $query->on_base_ids([$othcollsel])->get_total(); - $n = 0; - while ($n < $total) { - $results = $query->limit($n, 20)->execute()->get_results(); - foreach ($results as $user) { - $app['acl']->get($user)->duplicate_right_from_bas($othcollsel, $collection->get_base_id()); - } - $n += 20; - } - } - - return $app->redirectPath('admin_display_collection', ['bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1]); - } catch (\Exception $e) { - return $app->redirectPath('admin_database_submit_collection', ['databox_id' => $databox_id, 'error' => 'error']); - } - } - - /** - * Display page to get some details on a appbox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @return Response - */ - public function getDetails(Application $app, Request $request, $databox_id) - { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - - $details = []; - $total = ['total_subdefs' => 0, 'total_size' => 0]; - - foreach ($databox->get_record_details($request->query->get('sort')) as $collName => $colDetails) { - $details[$collName] = [ - 'total_subdefs' => 0, - 'total_size' => 0, - 'medias' => [] - ]; - - foreach ($colDetails as $subdefName => $subdefDetails) { - $details[$collName]['total_subdefs'] += $subdefDetails['n']; - $total['total_subdefs'] += $subdefDetails['n']; - $details[$collName]['total_size'] += $subdefDetails['siz']; - $total['total_size'] += $subdefDetails['siz']; - - $details[$collName]['medias'][] = [ - 'subdef_name' => $subdefName, - 'total_subdefs' => $subdefDetails['n'], - 'total_size' => $subdefDetails['siz'], - ]; - } - } - - return $app['twig']->render('admin/databox/details.html.twig', [ - 'databox' => $databox, - 'table' => $details, - 'total' => $total - ]); + return $app['firewall']; } } From 5c2fab88a0da44c555d5c2d4106b7e9ded4a23c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 00:55:33 +0200 Subject: [PATCH 21/26] Finish Admin Databox refactoring --- lib/Alchemy/Phrasea/Application.php | 5 +- .../Controller/Admin/DataboxController.php | 453 +++++++++++------- lib/classes/databox.php | 3 + 3 files changed, 276 insertions(+), 185 deletions(-) diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index e1517fe2bf..9ae01f5e55 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -12,8 +12,6 @@ namespace Alchemy\Phrasea; use Alchemy\Geonames\GeonamesServiceProvider; -use Alchemy\Phrasea\ControllerProvider\Admin\Dashboard; -use Alchemy\Phrasea\ControllerProvider\Admin\Databox; use Alchemy\Phrasea\ControllerProvider\Admin\Databoxes; use Alchemy\Phrasea\ControllerProvider\Admin\Fields; use Alchemy\Phrasea\ControllerProvider\Admin\Publications; @@ -313,6 +311,7 @@ class Application extends SilexApplication 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\Databox' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], @@ -619,7 +618,6 @@ class Application extends SilexApplication $this->mount('/developers/', new Developers()); $this->mount('/admin/', new AdminRoot()); - $this->mount('/admin/databox', new Databox()); $this->mount('/admin/databoxes', new Databoxes()); $this->mount('/admin/setup', new Setup()); $this->mount('/admin/search-engine', new SearchEngine()); @@ -672,6 +670,7 @@ class Application extends SilexApplication '/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection', '/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers', '/admin/dashboard' => 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard', + '/admin/databox' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databox', '/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users', '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php index 7f0827adc9..0bbda3609d 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php @@ -11,6 +11,12 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Authentication\ACLProvider; +use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Model\Manipulator\TaskManipulator; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -71,33 +77,42 @@ class DataboxController /** * Delete a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function deleteBase(Application $app, Request $request, $databox_id) + public function deleteBase(Request $request, $databox_id) { + $databox = null; $success = false; - $msg = $app->trans('An error occured'); + $msg = $this->app->trans('An error occured'); try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); if ($databox->get_record_amount() > 0) { - $msg = $app->trans('admin::base: vider la base avant de la supprimer'); + $msg = $this->app->trans('admin::base: vider la base avant de la supprimer'); } else { $databox->unmount_databox(); - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, null, \databox::PIC_PDF); + $this->getApplicationBox()->write_databox_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $databox, + null, + \databox::PIC_PDF + ); $databox->delete(); $success = true; - $msg = $app->trans('Successful removal'); + $msg = $this->app->trans('Successful removal'); } } catch (\Exception $e) { } + if (!$databox) { + $this->app->abort(404, $this->app->trans('admin::base: databox not found', ['databox_id' => $databox_id])); + } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, 'msg' => $msg, 'sbas_id' => $databox->get_sbas_id() @@ -113,23 +128,23 @@ class DataboxController $params['error'] = 'databox-not-empty'; } - return $app->redirectPath('admin_database', $params); + return $this->app->redirectPath('admin_database', $params); } - public function setLabels(Application $app, Request $request, $databox_id) + public function setLabels(Request $request, $databox_id) { if (null === $labels = $request->request->get('labels')) { - $app->abort(400, $app->trans('Missing labels parameter')); + $this->app->abort(400, $this->app->trans('Missing labels parameter')); } if (false === is_array($labels)) { - $app->abort(400, $app->trans('Invalid labels parameter')); + $this->app->abort(400, $this->app->trans('Invalid labels parameter')); } - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); $success = true; try { - foreach ($app['locales.available'] as $code => $language) { + foreach ($this->app['locales.available'] as $code => $language) { if (!isset($labels[$code])) { continue; } @@ -140,44 +155,47 @@ class DataboxController $success = false; } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured') + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), ]); } - return $app->redirect('/admin/databox/' . $databox->get_sbas_id() . '/?success=' . (int) $success . '&reload-tree=1'); + return $this->app->redirect(sprintf( + '/admin/databox/%d/?success=%d&reload-tree=1', + $databox->get_sbas_id(), + (int) $success + )); } /** * Reindex databox content * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function reindex(Application $app, Request $request, $databox_id) + public function reindex(Request $request, $databox_id) { $success = false; try { - $app['phraseanet.appbox']->get_databox($databox_id)->reindex(); + $this->findDataboxById($databox_id)->reindex(); $success = true; } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => (int) $success, ]); @@ -186,31 +204,32 @@ class DataboxController /** * Make a databox indexable * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function setIndexable(Application $app, Request $request, $databox_id) + public function setIndexable(Request $request, $databox_id) { $success = false; try { - $app['phraseanet.appbox']->set_databox_indexable($app['phraseanet.appbox']->get_databox($databox_id), !!$request->request->get('indexable', false)); + $databox = $this->findDataboxById($databox_id); + $indexable = !!$request->request->get('indexable', false); + $this->getApplicationBox()->set_databox_indexable($databox, $indexable); $success = true; } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => (int) $success, ]); @@ -219,27 +238,26 @@ class DataboxController /** * Update databox CGU's * - * @param Application $app The silex application * @param Request $request The current HTTP request * @param integer $databox_id The requested databox * @return RedirectResponse */ - public function updateDatabaseCGU(Application $app, Request $request, $databox_id) + public function updateDatabaseCGU(Request $request, $databox_id) { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); try { foreach ($request->request->get('TOU', []) as $loc => $terms) { $databox->update_cgus($loc, $terms, !!$request->request->get('valid', false)); } } catch (\Exception $e) { - return $app->redirectPath('admin_database_display_cgus', [ + return $this->app->redirectPath('admin_database_display_cgus', [ 'databox_id' => $databox_id, 'success' => 0, ]); } - return $app->redirectPath('admin_database_display_cgus', [ + return $this->app->redirectPath('admin_database_display_cgus', [ 'databox_id' => $databox_id, 'success' => 1, ]); @@ -248,45 +266,55 @@ class DataboxController /** * Mount a collection on a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox - * @param integer $collection_id The requested collection id + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @param integer $collection_id The requested collection id * @return RedirectResponse */ - public function mountCollection(Application $app, Request $request, $databox_id, $collection_id) + public function mountCollection(Request $request, $databox_id, $collection_id) { - $app['phraseanet.appbox']->get_connection()->beginTransaction(); + $connection = $this->getApplicationBox()->get_connection(); + $connection->beginTransaction(); try { - $baseId = \collection::mount_collection($app, $app['phraseanet.appbox']->get_databox($databox_id), $collection_id, $app['authentication']->getUser()); + /** @var Authenticator $authenticator */ + $authenticator = $this->app['authentication']; + $baseId = \collection::mount_collection( + $this->app, + $this->findDataboxById($databox_id), + $collection_id, + $authenticator->getUser() + ); $othCollSel = (int) $request->request->get("othcollsel") ?: null; if (null !== $othCollSel) { - $query = $app['phraseanet.user-query']; + /** @var \User_Query $query */ + $query = $this->app['phraseanet.user-query']; $n = 0; + /** @var ACLProvider $aclProvider */ + $aclProvider = $this->app['acl']; while ($n < $query->on_base_ids([$othCollSel])->get_total()) { $results = $query->limit($n, 50)->execute()->get_results(); foreach ($results as $user) { - $app['acl']->get($user)->duplicate_right_from_bas($othCollSel, $baseId); + $aclProvider->get($user)->duplicate_right_from_bas($othCollSel, $baseId); } $n += 50; } } - $app['phraseanet.appbox']->get_connection()->commit(); + $connection->commit(); - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'mount' => 'ok', ]); } catch (\Exception $e) { - $app['phraseanet.appbox']->get_connection()->rollBack(); + $connection->rollBack(); - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'mount' => 'ko', ]); @@ -296,41 +324,46 @@ class DataboxController /** * Set a new logo for a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return RedirectResponse */ - public function sendLogoPdf(Application $app, Request $request, $databox_id) + public function sendLogoPdf(Request $request, $databox_id) { try { if (null !== ($file = $request->files->get('newLogoPdf')) && $file->isValid()) { if ($file->getClientSize() < 65536) { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $databox, $file, \databox::PIC_PDF); + $databox = $this->findDataboxById($databox_id); + $this->getApplicationBox()->write_databox_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $databox, + $file, + \databox::PIC_PDF + ); unlink($file->getPathname()); - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => '1', ]); } else { - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => '0', 'error' => 'file-too-big', ]); } } else { - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => '0', 'error' => 'file-invalid', ]); } } catch (\Exception $e) { - return $app->redirectPath('admin_database', [ + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'success' => '0', 'error' => 'file-error', @@ -341,31 +374,37 @@ class DataboxController /** * Delete an existing logo for a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function deleteLogoPdf(Application $app, Request $request, $databox_id) + public function deleteLogoPdf(Request $request, $databox_id) { $success = false; try { - $app['phraseanet.appbox']->write_databox_pic($app['media-alchemyst'], $app['filesystem'], $app['phraseanet.appbox']->get_databox($databox_id), null, \databox::PIC_PDF); + $this->getApplicationBox()->write_databox_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $this->findDataboxById($databox_id), + null, + \databox::PIC_PDF + ); $success = true; } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful removal') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful removal') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'error' => 'file-too-big', ]); @@ -374,31 +413,31 @@ class DataboxController /** * Clear databox logs * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function clearLogs(Application $app, Request $request, $databox_id) + public function clearLogs(Request $request, $databox_id) { $success = false; try { - $app['phraseanet.appbox']->get_databox($databox_id)->clear_logs(); + $this->findDataboxById($databox_id)->clear_logs(); $success = true; } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'error' => 'file-too-big', ]); @@ -407,35 +446,35 @@ class DataboxController /** * Change the name of a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function changeViewName(Application $app, Request $request, $databox_id) + public function changeViewName(Request $request, $databox_id) { if (null === $viewName = $request->request->get('viewname')) { - $app->abort(400, $app->trans('Missing view name parameter')); + $this->app->abort(400, $this->app->trans('Missing view name parameter')); } $success = false; try { - $app['phraseanet.appbox']->get_databox($databox_id)->set_viewname($viewName); + $this->findDataboxById($databox_id)->set_viewname($viewName); $success = true; } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'error' => 'file-too-big', ]); @@ -444,17 +483,16 @@ class DataboxController /** * Unmount a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function unmountDatabase(Application $app, Request $request, $databox_id) + public function unmountDatabase(Request $request, $databox_id) { $success = false; try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); $databox->unmount_databox(); $success = true; @@ -462,15 +500,18 @@ class DataboxController } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + $msg = $success + ? $this->app->trans('The publication has been stopped') + : $this->app->trans('An error occured'); + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('The publication has been stopped') : $app->trans('An error occured'), + 'msg' => $msg, 'sbas_id' => $databox_id ]); } - return $app->redirectPath('admin_databases', [ + return $this->app->redirectPath('admin_databases', [ 'reload-tree' => 1, ]); } @@ -478,47 +519,49 @@ class DataboxController /** * Empty a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function emptyDatabase(Application $app, Request $request, $databox_id) + public function emptyDatabase(Request $request, $databox_id) { - $msg = $app->trans('An error occurred'); + $msg = $this->app->trans('An error occurred'); $success = false; $taskCreated = false; try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); foreach ($databox->get_collections() as $collection) { if ($collection->get_record_amount() <= 500) { $collection->empty_collection(500); } else { - $app['manipulator.task']->createEmptyCollectionJob($collection); + /** @var TaskManipulator $taskManipulator */ + $taskManipulator = $this->app['manipulator.task']; + $taskManipulator->createEmptyCollectionJob($collection); } } - $msg = $app->trans('Base empty successful'); + $msg = $this->app->trans('Base empty successful'); $success = true; if ($taskCreated) { - $msg = $app->trans('A task has been created, please run it to complete empty collection'); + $msg = $this->app->trans('A task has been created, please run it to complete empty collection'); } } catch (\Exception $e) { } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, 'msg' => $msg, - 'sbas_id' => $databox_id + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database', [ + // TODO: Can this method be called as HTML? + return $this->app->redirectPath('admin_database', [ 'databox_id' => $databox_id, 'error' => 'file-too-big', ]); @@ -527,83 +570,83 @@ class DataboxController /** * Get number of indexed items for a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse */ - public function progressBarInfos(Application $app, Request $request, $databox_id) + public function progressBarInfos(Request $request, $databox_id) { - if (!$app['request']->isXmlHttpRequest() || 'json' !== $app['request']->getRequestFormat()) { - $app->abort(400, $app->trans('Bad request format, only JSON is allowed')); + if (!$request->isXmlHttpRequest() || 'json' !== $request->getRequestFormat()) { + $this->app->abort(400, $this->app->trans('Bad request format, only JSON is allowed')); } - $app['phraseanet.appbox'] = $app['phraseanet.appbox']; + $appbox = $this->getApplicationBox(); $ret = [ 'success' => false, - 'msg' => $app->trans('An error occured'), + 'msg' => $this->app->trans('An error occured'), 'sbas_id' => null, 'indexable' => false, 'records' => 0, 'xml_indexed' => 0, 'thesaurus_indexed' => 0, 'viewname' => null, - 'printLogoURL' => null + 'printLogoURL' => null, ]; try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $datas = $databox->get_indexed_record_amount(); + $databox = $this->findDataboxById($databox_id); + $data = $databox->get_indexed_record_amount(); - $ret['indexable'] = $app['phraseanet.appbox']->is_databox_indexable($databox); - $ret['viewname'] = (($databox->get_dbname() == $databox->get_viewname()) ? $app->trans('admin::base: aucun alias') : $databox->get_viewname()); + $ret['indexable'] = $appbox->is_databox_indexable($databox); + $ret['viewname'] = (($databox->get_dbname() == $databox->get_viewname()) + ? $this->app->trans('admin::base: aucun alias') + : $databox->get_viewname()); $ret['records'] = $databox->get_record_amount(); $ret['sbas_id'] = $databox_id; - $ret['xml_indexed'] = $datas['xml_indexed']; - $ret['thesaurus_indexed'] = $datas['thesaurus_indexed']; - $ret['jeton_subdef'] = $datas['jeton_subdef']; - if ($app['filesystem']->exists($app['root.path'] . '/config/minilogos/logopdf_' . $databox_id . '.jpg')) { + $ret['xml_indexed'] = $data['xml_indexed']; + $ret['thesaurus_indexed'] = $data['thesaurus_indexed']; + $ret['jeton_subdef'] = $data['jeton_subdef']; + if ($this->app['filesystem']->exists($this->app['root.path'] . '/config/minilogos/logopdf_' . $databox_id . '.jpg')) { $ret['printLogoURL'] = '/custom/minilogos/logopdf_' . $databox_id . '.jpg'; } $ret['success'] = true; - $ret['msg'] = $app->trans('Successful update'); + $ret['msg'] = $this->app->trans('Successful update'); } catch (\Exception $e) { } - return $app->json($ret); + return $this->app->json($ret); } /** - * Display page for reaorder collections on a databox + * Display page for reorder collections on a databox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param integer $databox_id The requested databox * @return Response */ - public function getReorder(Application $app, Request $request, $databox_id) + public function getReorder($databox_id) { - return $app['twig']->render('admin/collection/reorder.html.twig', [ - 'collections' => $app['acl']->get($app['authentication']->getUser())->get_granted_base([], [$databox_id]), + $acl = $this->getAclForUser(); + + return $this->render('admin/collection/reorder.html.twig', [ + 'collections' => $acl->get_granted_base([], [$databox_id]), ]); } /** * Apply collection reorder changes * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return JsonResponse|RedirectResponse */ - public function setReorder(Application $app, Request $request, $databox_id) + public function setReorder(Request $request, $databox_id) { try { foreach ($request->request->get('order', []) as $data) { - $collection = \collection::get_from_base_id($app, $data['id']); + $collection = \collection::get_from_base_id($this->app, $data['id']); $collection->set_ord($data['offset']); } $success = true; @@ -611,15 +654,15 @@ class DataboxController $success = false; } - if ('json' === $app['request']->getRequestFormat()) { - return $app->json([ + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ 'success' => $success, - 'msg' => $success ? $app->trans('Successful update') : $app->trans('An error occured'), - 'sbas_id' => $databox_id + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, ]); } - return $app->redirectPath('admin_database_display_collections_order', [ + return $this->app->redirectPath('admin_database_display_collections_order', [ 'databox_id' => $databox_id, 'success' => (int) $success, ]); @@ -628,68 +671,76 @@ class DataboxController /** * Display page to create a new collection * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox * @return Response */ - public function getNewCollection(Application $app, Request $request, $databox_id) + public function getNewCollection() { - return $app['twig']->render('admin/collection/create.html.twig'); + return $this->render('admin/collection/create.html.twig'); } /** * Create a new collection * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return Response */ - public function createCollection(Application $app, Request $request, $databox_id) + public function createCollection(Request $request, $databox_id) { if (($name = trim($request->request->get('name', ''))) === '') { - return $app->redirectPath('admin_database_display_new_collection_form', [ + return $this->app->redirectPath('admin_database_display_new_collection_form', [ 'databox_id' => $databox_id, 'error' => 'name', ]); } try { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); - $collection = \collection::create($app, $databox, $app['phraseanet.appbox'], $name, $app['authentication']->getUser()); + $databox = $this->findDataboxById($databox_id); + $collection = \collection::create( + $this->app, $databox, + $this->getApplicationBox(), + $name, + $this->getAuthenticator()->getUser() + ); if (($request->request->get('ccusrothercoll') === "on") && (null !== $othcollsel = $request->request->get('othcollsel'))) { - $query = $app['phraseanet.user-query']; + /** @var \User_Query $query */ + $query = $this->app['phraseanet.user-query']; $total = $query->on_base_ids([$othcollsel])->get_total(); $n = 0; while ($n < $total) { $results = $query->limit($n, 20)->execute()->get_results(); foreach ($results as $user) { - $app['acl']->get($user)->duplicate_right_from_bas($othcollsel, $collection->get_base_id()); + $this->getAclForUser($user)->duplicate_right_from_bas($othcollsel, $collection->get_base_id()); } $n += 20; } } - return $app->redirectPath('admin_display_collection', ['bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1]); + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => 1, + 'reload-tree' => 1, + ]); } catch (\Exception $e) { - return $app->redirectPath('admin_database_submit_collection', ['databox_id' => $databox_id, 'error' => 'error']); + return $this->app->redirectPath('admin_database_submit_collection', [ + 'databox_id' => $databox_id, + 'error' => 'error', + ]); } } /** * Display page to get some details on a appbox * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @param integer $databox_id The requested databox + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox * @return Response */ - public function getDetails(Application $app, Request $request, $databox_id) + public function getDetails(Request $request, $databox_id) { - $databox = $app['phraseanet.appbox']->get_databox($databox_id); + $databox = $this->findDataboxById($databox_id); $details = []; $total = ['total_subdefs' => 0, 'total_size' => 0]; @@ -715,21 +766,29 @@ class DataboxController } } - return $app['twig']->render('admin/databox/details.html.twig', [ + return $this->render('admin/databox/details.html.twig', [ 'databox' => $databox, 'table' => $details, 'total' => $total ]); } + /** + * @return \appbox + */ + private function getApplicationBox() + { + return $this->app['phraseanet.appbox']; + } + /** * @param int $id * @return \databox */ private function findDataboxById($id) { - /** @var \appbox $appbox */ - $appbox = $this->app['phraseanet.appbox']; + $appbox = $this->getApplicationBox(); + return $appbox->get_databox($id); } @@ -747,4 +806,34 @@ class DataboxController $context ); } + + /** + * @return ACLProvider + */ + private function getAclProvider() + { + return $this->app['acl']; + } + + /** + * @return Authenticator + */ + private function getAuthenticator() + { + return $this->app['authentication']; + } + + /** + * @param User|null $user + * @return \ACL + */ + private function getAclForUser(User $user = null) + { + $aclProvider = $this->getAclProvider(); + if (null === $user) { + $user = $this->getAuthenticator()->getUser(); + } + + return $aclProvider->get($user); + } } diff --git a/lib/classes/databox.php b/lib/classes/databox.php index ffd0f467f8..9508eb7376 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -211,6 +211,9 @@ class databox extends base return $this->app['phraseanet.appbox']; } + /** + * @return collection[] + */ public function get_collections() { $ret = []; From 10a655e2942d71bc6ef55d9eac5240b4941a3297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 10:49:40 +0200 Subject: [PATCH 22/26] DataboxesController Refactor, CS fixup --- lib/Alchemy/Phrasea/Application.php | 4 +- .../Controller/Admin/DataboxesController.php | 340 ++++++++++++++++++ .../ControllerProvider/Admin/Collection.php | 3 +- .../Admin/ConnectedUsers.php | 3 +- .../ControllerProvider/Admin/Dashboard.php | 3 +- .../ControllerProvider/Admin/Databox.php | 3 +- .../ControllerProvider/Admin/Databoxes.php | 266 ++------------ .../Phrasea/ControllerProvider/Datafiles.php | 3 +- .../Phrasea/ControllerProvider/Lightbox.php | 2 +- .../Phrasea/ControllerProvider/Minifier.php | 4 +- .../Phrasea/ControllerProvider/Permalink.php | 48 +-- .../Phrasea/ControllerProvider/Setup.php | 22 +- lib/classes/databox.php | 7 + 13 files changed, 417 insertions(+), 291 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 9ae01f5e55..35f195d037 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea; use Alchemy\Geonames\GeonamesServiceProvider; -use Alchemy\Phrasea\ControllerProvider\Admin\Databoxes; use Alchemy\Phrasea\ControllerProvider\Admin\Fields; use Alchemy\Phrasea\ControllerProvider\Admin\Publications; use Alchemy\Phrasea\ControllerProvider\Admin\Root as AdminRoot; @@ -312,6 +311,7 @@ class Application extends SilexApplication 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Databox' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], @@ -618,7 +618,6 @@ class Application extends SilexApplication $this->mount('/developers/', new Developers()); $this->mount('/admin/', new AdminRoot()); - $this->mount('/admin/databoxes', new Databoxes()); $this->mount('/admin/setup', new Setup()); $this->mount('/admin/search-engine', new SearchEngine()); $this->mount('/admin/publications', new Publications()); @@ -671,6 +670,7 @@ class Application extends SilexApplication '/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers', '/admin/dashboard' => 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard', '/admin/databox' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databox', + '/admin/databoxes' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes', '/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users', '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php new file mode 100644 index 0000000000..f897ed59c4 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php @@ -0,0 +1,340 @@ +app = $app; + } + + /** + * Get Databases control panel + * + * @param Request $request + * @return Response + */ + public function getDatabases(Request $request) + { + $acl = $this->getAclForUser(); + $sbasIds = array_merge( + array_keys($acl->get_granted_sbas(['bas_manage'])), + array_keys($acl->get_granted_sbas(['bas_modify_struct'])) + ); + + $sbas = []; + foreach ($sbasIds as $sbasId) { + $sbas[$sbasId] = [ + 'version' => 'unknown', + 'image' => '/skins/icons/db-remove.png', + 'server_info' => '', + 'name' => $this->app->trans('Unreachable server') + ]; + + try { + $databox = $this->findDataboxById($sbasId); + + /** @var \PDO $pdoConnection */ + $pdoConnection = $databox->get_connection()->getWrappedConnection(); + $sbas[$sbasId] = [ + 'version' => $databox->get_version(), + 'image' => '/skins/icons/foldph20close_0.gif', + 'server_info' => $pdoConnection->getAttribute(\PDO::ATTR_SERVER_VERSION), + 'name' => \phrasea::sbas_labels($sbasId, $this->app) + ]; + } catch (\Exception $e) { + + } + } + + switch ($errorMsg = $request->query->get('error')) { + case 'scheduler-started' : + $errorMsg = $this->app->trans('Veuillez arreter le planificateur avant la mise a jour'); + break; + case 'already-started' : + $errorMsg = $this->app->trans('The upgrade is already started'); + break; + case 'unknow' : + $errorMsg = $this->app->trans('An error occured'); + break; + case 'bad-email' : + $errorMsg = $this->app->trans('Please fix the database before starting'); + break; + case 'special-chars' : + $errorMsg = $this->app->trans('Database name can not contains special characters'); + break; + case 'base-failed' : + $errorMsg = $this->app->trans('Base could not be created'); + break; + case 'database-failed' : + $errorMsg = $this->app->trans('Database does not exists or can not be accessed'); + break; + case 'no-empty' : + $errorMsg = $this->app->trans('Database can not be empty'); + break; + case 'mount-failed' : + $errorMsg = $this->app->trans('Database could not be mounted'); + break; + case 'innodb-support' : + $errorMsg = _('Database server does not support InnoDB storage engine'); + break; + } + + return $this->render('admin/databases.html.twig', [ + 'files' => new \DirectoryIterator($this->app['root.path'] . '/lib/conf.d/data_templates'), + 'sbas' => $sbas, + 'error_msg' => $errorMsg, + 'advices' => $request->query->get('advices', []), + 'reloadTree' => (Boolean) $request->query->get('reload-tree'), + ]); + } + + /** + * Create a new databox + * + * @param Request $request The current HTTP request + * @return RedirectResponse + */ + public function createDatabase(Request $request) + { + if ('' === $dbName = $request->request->get('new_dbname', '')) { + return $this->app->redirectPath('admin_databases', ['error' => 'no-empty']); + } + + if (\p4string::hasAccent($dbName)) { + return $this->app->redirectPath('admin_databases', ['error' => 'special-chars']); + } + + if ((null === $request->request->get('new_settings')) && (null !== $dataTemplate = $request->request->get('new_data_template'))) { + $connexion = $this->app['conf']->get(['main', 'database']); + + $hostname = $connexion['host']; + $port = $connexion['port']; + $user = $connexion['user']; + $password = $connexion['password']; + + $dataTemplate = new \SplFileInfo($this->app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); + + try { + /** @var Connection $connection */ + $connection = $this->app['dbal.provider']([ + 'host' => $hostname, + 'port' => $port, + 'user' => $user, + 'password' => $password, + 'dbname' => $dbName, + ]); + $connection->connect(); + } catch (DBALException $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']); + } + + try { + $base = \databox::create($this->app, $connection, $dataTemplate); + $base->registerAdmin($this->getAuthenticator()->getUser()); + $this->getAclForUser()->delete_data_from_cache(); + + $connection->close(); + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $base->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1 + ]); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); + } + } + + if (null !== $request->request->get('new_settings') + && (null !== $hostname = $request->request->get('new_hostname')) + && (null !== $port = $request->request->get('new_port')) + && (null !== $userDb = $request->request->get('new_user')) + && (null !== $passwordDb = $request->request->get('new_password')) + && (null !== $dataTemplate = $request->request->get('new_data_template')) + ) { + try { + $data_template = new \SplFileInfo($this->app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); + /** @var Connection $connection */ + $connection = $this->app['db.provider']([ + 'host' => $hostname, + 'port' => $port, + 'user' => $userDb, + 'password' => $passwordDb, + 'dbname' => $dbName, + ]); + $connection->connect(); + try { + $base = \databox::create($this->app, $connection, $data_template); + $base->registerAdmin($this->getAuthenticator()->getUser()); + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $base->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1, + ]); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); + } + } catch (\Exception $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']); + } + } + + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); + } + + /** + * Mount a databox + * + * @param Request $request The current HTTP request + * @return RedirectResponse + */ + public function databaseMount(Request $request) + { + if ('' === $dbName = trim($request->request->get('new_dbname', ''))) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'no-empty']); + } + + if (\p4string::hasAccent($dbName)) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'special-chars']); + } + + if ((null === $request->request->get('new_settings'))) { + try { + $connexion = $this->app['conf']->get(['main', 'database']); + + $hostname = $connexion['host']; + $port = $connexion['port']; + $user = $connexion['user']; + $password = $connexion['password']; + + $this->app['phraseanet.appbox']->get_connection()->beginTransaction(); + $base = \databox::mount($this->app, $hostname, $port, $user, $password, $dbName); + $base->registerAdmin($this->app['authentication']->getUser()); + $this->app['phraseanet.appbox']->get_connection()->commit(); + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $base->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1, + ]); + } catch (\Exception $e) { + $this->app['phraseanet.appbox']->get_connection()->rollBack(); + + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); + } + } + + if (null !== $request->request->get('new_settings') + && (null !== $hostname = $request->request->get('new_hostname')) + && (null !== $port = $request->request->get('new_port')) + && (null !== $userDb = $request->request->get('new_user')) + && (null !== $passwordDb = $request->request->get('new_password')) + ) { + $connection = $this->getApplicationBox()->get_connection(); + try { + $connection->beginTransaction(); + $base = \databox::mount($this->app, $hostname, $port, $userDb, $passwordDb, $dbName); + $base->registerAdmin($this->getAuthenticator()->getUser()); + $connection->commit(); + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $base->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1 + ]); + } catch (\Exception $e) { + $connection->rollBack(); + + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); + } + } + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); + } + + /** + * @return \appbox + */ + private function getApplicationBox() + { + return $this->app['phraseanet.appbox']; + } + + /** + * @param int $id + * @return \databox + */ + private function findDataboxById($id) + { + $appbox = $this->getApplicationBox(); + + return $appbox->get_databox($id); + } + + /** + * @param $name + * @param array $context + * @return string + */ + private function render($name, array $context = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render( + $name, + $context + ); + } + + /** + * @return ACLProvider + */ + private function getAclProvider() + { + return $this->app['acl']; + } + + /** + * @return Authenticator + */ + private function getAuthenticator() + { + return $this->app['authentication']; + } + + /** + * @param User|null $user + * @return \ACL + */ + private function getAclForUser(User $user = null) + { + $aclProvider = $this->getAclProvider(); + if (null === $user) { + $user = $this->getAuthenticator()->getUser(); + } + + return $aclProvider->get($user); + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php index c5f72e1854..d6fd6f8110 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\Admin\CollectionController; use Silex\Application; use Silex\ControllerCollection; @@ -21,7 +22,7 @@ class Collection implements ControllerProviderInterface, ServiceProviderInterfac { public function register(Application $app) { - $app['controller.admin.collection'] = $app->share(function () use ($app) { + $app['controller.admin.collection'] = $app->share(function (PhraseaApplication $app) { return new CollectionController($app); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php index 122116a22a..e30460e433 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\Admin\ConnectedUsersController; use Silex\Application; use Silex\ControllerCollection; @@ -21,7 +22,7 @@ class ConnectedUsers implements ControllerProviderInterface, ServiceProviderInte { public function register(Application $app) { - $app['controller.admin.connected-users'] = $app->share(function () use ($app) { + $app['controller.admin.connected-users'] = $app->share(function (PhraseaApplication $app) { return new ConnectedUsersController($app); }); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php index d637949d46..700a4833b5 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\Admin\DashboardController; use Silex\Application; use Silex\ControllerCollection; @@ -21,7 +22,7 @@ class Dashboard implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.admin.dashboard'] = $app->share(function () use ($app) { + $app['controller.admin.dashboard'] = $app->share(function (PhraseaApplication $app) { return new DashboardController($app); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php index 8938c8e1db..91301a1732 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\Admin\DataboxController; use Alchemy\Phrasea\Security\Firewall; use Silex\Application; @@ -23,7 +24,7 @@ class Databox implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.admin.databox'] = $app->share(function () use ($app) { + $app['controller.admin.databox'] = $app->share(function (PhraseaApplication $app) { return new DataboxController($app); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php index 0e08f4b0c2..b99d79ecb0 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php @@ -11,25 +11,38 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Doctrine\DBAL\DBALException; +use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\Controller\Admin\DataboxesController; +use Alchemy\Phrasea\Security\Firewall; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Silex\ServiceProviderInterface; -class Databoxes implements ControllerProviderInterface +class Databoxes implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.databoxes'] = $app->share(function (PhraseaApplication $app) { + return new DataboxesController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { - $app['controller.admin.databoxes'] = $this; - + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; - $app['firewall']->addMandatoryAuthentication($controllers); + /** @var Firewall $firewall */ + $firewall = $app['firewall']; + $firewall->addMandatoryAuthentication($controllers); - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('admin'); + $controllers->before(function () use ($firewall) { + $firewall->requireAccessToModule('admin'); }); $controllers->get('/', 'controller.admin.databoxes:getDatabases') @@ -37,241 +50,16 @@ class Databoxes implements ControllerProviderInterface $controllers->post('/', 'controller.admin.databoxes:createDatabase') ->bind('admin_database_new') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireAdmin(); + ->before(function () use ($firewall) { + $firewall->requireAdmin(); }); $controllers->post('/mount/', 'controller.admin.databoxes:databaseMount') ->bind('admin_database_mount') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireAdmin(); + ->before(function () use ($firewall) { + $firewall->requireAdmin(); }); return $controllers; } - - /** - * Get Databases control panel - * - * @param $app Application $app - * @param $request Request $request - * @return Response - */ - public function getDatabases(Application $app, Request $request) - { - $sbasIds = array_merge( - array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_sbas(['bas_manage'])) - , array_keys($app['acl']->get($app['authentication']->getUser())->get_granted_sbas(['bas_modify_struct'])) - ); - - $sbas = []; - foreach ($sbasIds as $sbasId) { - $sbas[$sbasId] = [ - 'version' => 'unknown', - 'image' => '/skins/icons/db-remove.png', - 'server_info' => '', - 'name' => $app->trans('Unreachable server') - ]; - - try { - $databox = $app['phraseanet.appbox']->get_databox($sbasId); - - $sbas[$sbasId] = [ - 'version' => $databox->get_version(), - 'image' => '/skins/icons/foldph20close_0.gif', - 'server_info' => $databox->get_connection()->getWrappedConnection()->getAttribute(\PDO::ATTR_SERVER_VERSION), - 'name' => \phrasea::sbas_labels($sbasId, $app) - ]; - } catch (\Exception $e) { - - } - } - - switch ($errorMsg = $request->query->get('error')) { - case 'scheduler-started' : - $errorMsg = $app->trans('Veuillez arreter le planificateur avant la mise a jour'); - break; - case 'already-started' : - $errorMsg = $app->trans('The upgrade is already started'); - break; - case 'unknow' : - $errorMsg = $app->trans('An error occured'); - break; - case 'bad-email' : - $errorMsg = $app->trans('Please fix the database before starting'); - break; - case 'special-chars' : - $errorMsg = $app->trans('Database name can not contains special characters'); - break; - case 'base-failed' : - $errorMsg = $app->trans('Base could not be created'); - break; - case 'database-failed' : - $errorMsg = $app->trans('Database does not exists or can not be accessed'); - break; - case 'no-empty' : - $errorMsg = $app->trans('Database can not be empty'); - break; - case 'mount-failed' : - $errorMsg = $app->trans('Database could not be mounted'); - break; - case 'innodb-support' : - $errorMsg = _('Database server does not support InnoDB storage engine'); - break; - } - - return $app['twig']->render('admin/databases.html.twig', [ - 'files' => new \DirectoryIterator($app['root.path'] . '/lib/conf.d/data_templates'), - 'sbas' => $sbas, - 'error_msg' => $errorMsg, - 'advices' => $request->query->get('advices', []), - 'reloadTree' => (Boolean) $request->query->get('reload-tree'), - ]); - } - - /** - * Create a new databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * - * @return RedirectResponse - */ - public function createDatabase(Application $app, Request $request) - { - if ('' === $dbName = $request->request->get('new_dbname', '')) { - return $app->redirectPath('admin_databases', ['error' => 'no-empty']); - } - - if (\p4string::hasAccent($dbName)) { - return $app->redirectPath('admin_databases', ['error' => 'special-chars']); - } - - if ((null === $request->request->get('new_settings')) && (null !== $dataTemplate = $request->request->get('new_data_template'))) { - $connexion = $app['conf']->get(['main', 'database']); - - $hostname = $connexion['host']; - $port = $connexion['port']; - $user = $connexion['user']; - $password = $connexion['password']; - - $dataTemplate = new \SplFileInfo($app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); - - try { - $connbas = $app['dbal.provider']([ - 'host' => $hostname, - 'port' => $port, - 'user' => $user, - 'password' => $password, - 'dbname' => $dbName, - ]); - $connbas->connect(); - } catch (DBALException $e) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']); - } - - try { - $base = \databox::create($app, $connbas, $dataTemplate); - $base->registerAdmin($app['authentication']->getUser()); - $app['acl']->get($app['authentication']->getUser())->delete_data_from_cache(); - - $connbas->close(); - return $app->redirectPath('admin_database', ['databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1]); - } catch (\Exception $e) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); - } - } - - if ( - null !== $request->request->get('new_settings') - && (null !== $hostname = $request->request->get('new_hostname')) - && (null !== $port = $request->request->get('new_port')) - && (null !== $userDb = $request->request->get('new_user')) - && (null !== $passwordDb = $request->request->get('new_password')) - && (null !== $dataTemplate = $request->request->get('new_data_template'))) { - - try { - $data_template = new \SplFileInfo($app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); - $connbas = $app['db.provider']([ - 'host' => $hostname, - 'port' => $port, - 'user' => $userDb, - 'password' => $passwordDb, - 'dbname' => $dbName, - ]); - $connbas->connect(); - try { - $base = \databox::create($app, $connbas, $data_template); - $base->registerAdmin($app['authentication']->getUser()); - - return $app->redirectPath('admin_database', ['databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1]); - } catch (\Exception $e) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); - } - } catch (\Exception $e) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']); - } - } - } - - /** - * Mount a databox - * - * @param Application $app The silex application - * @param Request $request The current HTTP request - * @return RedirectResponse - */ - public function databaseMount(Application $app, Request $request) - { - if ('' === $dbName = trim($request->request->get('new_dbname', ''))) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'no-empty']); - } - - if (\p4string::hasAccent($dbName)) { - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'special-chars']); - } - - if ((null === $request->request->get('new_settings'))) { - try { - $connexion = $app['conf']->get(['main', 'database']); - - $hostname = $connexion['host']; - $port = $connexion['port']; - $user = $connexion['user']; - $password = $connexion['password']; - - $app['phraseanet.appbox']->get_connection()->beginTransaction(); - $base = \databox::mount($app, $hostname, $port, $user, $password, $dbName); - $base->registerAdmin($app['authentication']->getUser()); - $app['phraseanet.appbox']->get_connection()->commit(); - - return $app->redirectPath('admin_database', ['databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1]); - } catch (\Exception $e) { - $app['phraseanet.appbox']->get_connection()->rollBack(); - - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); - } - } - - if ( - null !== $request->request->get('new_settings') - && (null !== $hostname = $request->request->get('new_hostname')) - && (null !== $port = $request->request->get('new_port')) - && (null !== $userDb = $request->request->get('new_user')) - && (null !== $passwordDb = $request->request->get('new_password'))) { - - try { - $app['phraseanet.appbox']->get_connection()->beginTransaction(); - $base = \databox::mount($app, $hostname, $port, $userDb, $passwordDb, $dbName); - $base->registerAdmin($app['authentication']->getUser()); - $app['phraseanet.appbox']->get_connection()->commit(); - - return $app->redirectPath('admin_database', ['databox_id' => $base->get_sbas_id(), 'success' => 1, 'reload-tree' => 1]); - } catch (\Exception $e) { - $app['phraseanet.appbox']->get_connection()->rollBack(); - - return $app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); - } - } - } } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php index 2d30735360..bb30898ef3 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\ControllerProvider; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\DatafileController; use Silex\Application; use Silex\ControllerProviderInterface; @@ -21,7 +22,7 @@ class Datafiles implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.datafiles'] = $app->share(function () use ($app) { + $app['controller.datafiles'] = $app->share(function (PhraseaApplication $app) { return new DatafileController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php index a608c0e164..a4b9d3b894 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php @@ -25,7 +25,7 @@ class Lightbox implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.lightbox'] = $app->share(function () use ($app) { + $app['controller.lightbox'] = $app->share(function (PhraseaApplication $app) { return new LightboxController($app); }); } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php index 11a47e0abf..1265e0fdf3 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Controller\MinifierController; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; use Silex\Application; use Silex\ServiceProviderInterface; @@ -21,7 +22,7 @@ class Minifier implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.minifier'] = $app->share(function ($app) { + $app['controller.minifier'] = $app->share(function (Application $app) { $cachePath = $app['cache.path'] . '/minify'; /** @var Filesystem $fs */ $fs = $app['filesystem']; @@ -38,6 +39,7 @@ class Minifier implements ControllerProviderInterface, ServiceProviderInterface public function connect(Application $app) { + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; $controllers->get('/', 'controller.minifier:minifyAction')->bind('minifier'); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php index 6c59c324ab..6bc9817e4a 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php @@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\ControllerProvider; use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\PermalinkController; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; use Silex\ServiceProviderInterface; @@ -21,7 +22,7 @@ class Permalink implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) { - $app['controller.permalink'] = $app->share(function () use ($app) { + $app['controller.permalink'] = $app->share(function (PhraseaApplication $app) { return new PermalinkController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); }); } @@ -32,61 +33,42 @@ class Permalink implements ControllerProviderInterface, ServiceProviderInterface public function connect(Application $app) { + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; - $controllers->get('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:deliverCaption') + $controllers ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ->bind('permalinks_caption') - ; + ->assert('record_id', '\d+'); + + $controllers->get('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:deliverCaption') + ->bind('permalinks_caption'); $controllers->match('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:getOptionsResponse') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ->method('OPTIONS') - ; + ->method('OPTIONS'); $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:deliverPermaview') - ->bind('permalinks_permaview') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->bind('permalinks_permaview'); $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:getOptionsResponse') - ->method('OPTIONS') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->method('OPTIONS'); $controllers->get( '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/view/', 'controller.permalink:deliverPermaviewOldWay' ) - ->bind('permalinks_permaview_old') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->bind('permalinks_permaview_old'); $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:deliverPermalink') - ->bind('permalinks_permalink') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->bind('permalinks_permalink'); $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:getOptionsResponse') - ->method('OPTIONS') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->method('OPTIONS'); $controllers->get( '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/', 'controller.permalink:deliverPermalinkOldWay' ) - ->bind('permalinks_permalink_old') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+') - ; + ->bind('permalinks_permalink_old'); return $controllers; } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php index da2b81993b..7d24b304b7 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Setup.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php @@ -11,33 +11,35 @@ namespace Alchemy\Phrasea\ControllerProvider; -use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Controller\SetupController; use Alchemy\Phrasea\Helper\DatabaseHelper; use Alchemy\Phrasea\Helper\PathHelper; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Silex\Application as SilexApplication; +use Silex\Application; use Silex\ServiceProviderInterface; use Symfony\Component\HttpFoundation\Request; class Setup implements ControllerProviderInterface, ServiceProviderInterface { - public function register(SilexApplication $app) + public function register(Application $app) { - $app['controller.setup'] = $app->share(function ($application) { + $app['controller.setup'] = $app->share(function (PhraseaApplication $application) { return new SetupController($application); }); } - public function boot(SilexApplication $app) + public function boot(Application $app) { } - public function connect(SilexApplication $app) + public function connect(Application $app) { + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; - $controllers->get('/', function (Application $app) { + $controllers->get('/', function (PhraseaApplication $app) { return $app->redirectPath('install_root'); })->bind('setup'); @@ -53,19 +55,19 @@ class Setup implements ControllerProviderInterface, ServiceProviderInterface $controllers->post('/installer/install/', 'controller.setup:doInstall') ->bind('install_do_install'); - $controllers->get('/connection_test/mysql/', function (Application $app, Request $request) { + $controllers->get('/connection_test/mysql/', function (PhraseaApplication $app, Request $request) { $dbHelper = new DatabaseHelper($app, $request); return $app->json($dbHelper->checkConnection()); }); - $controllers->get('/test/path/', function (Application $app, Request $request) { + $controllers->get('/test/path/', function (PhraseaApplication $app, Request $request) { $pathHelper = new PathHelper($app, $request); return $app->json($pathHelper->checkPath()); }); - $controllers->get('/test/url/', function (Application $app, Request $request) { + $controllers->get('/test/url/', function (PhraseaApplication $app, Request $request) { $pathHelper = new PathHelper($app, $request); return $app->json($pathHelper->checkUrl()); diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 9508eb7376..af7ed71359 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -516,6 +516,13 @@ class databox extends base return; } + /** + * @param Application $app + * @param Connection $connection + * @param SplFileInfo $data_template + * @return databox + * @throws \Doctrine\DBAL\DBALException + */ public static function create(Application $app, Connection $connection, \SplFileInfo $data_template) { if ( ! file_exists($data_template->getRealPath())) { From 57736782a9930a5e6585126eac08e12a3f81c599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 13:03:03 +0200 Subject: [PATCH 23/26] Add BaseController with helper methods --- lib/Alchemy/Phrasea/Controller/Controller.php | 113 ++++++++++++ .../Phrasea/Controller/ControllerTest.php | 174 ++++++++++++++++++ 2 files changed, 287 insertions(+) create mode 100644 lib/Alchemy/Phrasea/Controller/Controller.php create mode 100644 tests/Alchemy/Tests/Phrasea/Controller/ControllerTest.php diff --git a/lib/Alchemy/Phrasea/Controller/Controller.php b/lib/Alchemy/Phrasea/Controller/Controller.php new file mode 100644 index 0000000000..20485505bc --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Controller.php @@ -0,0 +1,113 @@ +app = $app; + } + + + /** + * @return \appbox + */ + public function getApplicationBox() + { + return $this->app['phraseanet.appbox']; + } + + /** + * @param int $id + * @return \databox + */ + public function findDataboxById($id) + { + $appbox = $this->getApplicationBox(); + + return $appbox->get_databox($id); + } + + /** + * @param string $name + * @param array $context + * @return string + */ + public function render($name, array $context = []) + { + /** @var \Twig_Environment $twig */ + $twig = $this->app['twig']; + return $twig->render( + $name, + $context + ); + } + + /** + * @param string $name + * @param array $context + * @param int $status + * @param array $headers + * @return Response + */ + public function renderResponse($name, array $context = [], $status = 200, array $headers = []) + { + return new Response($this->render($name, $context), $status, $headers); + } + + /** + * @return ACLProvider + */ + public function getAclProvider() + { + return $this->app['acl']; + } + + /** + * @return Authenticator + */ + public function getAuthenticator() + { + return $this->app['authentication']; + } + + /** + * @param User|null $user + * @return \ACL + */ + public function getAclForUser(User $user = null) + { + $aclProvider = $this->getAclProvider(); + if (null === $user) { + $user = $this->getAuthenticatedUser(); + } + + return $aclProvider->get($user); + } + + /** + * @return User|null + */ + public function getAuthenticatedUser() + { + return $this->getAuthenticator()->getUser(); + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/ControllerTest.php b/tests/Alchemy/Tests/Phrasea/Controller/ControllerTest.php new file mode 100644 index 0000000000..e2acc37eec --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Controller/ControllerTest.php @@ -0,0 +1,174 @@ +appbox = $this->getMockBuilder(\appbox::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->twig = $this->getMockBuilder(\Twig_Environment::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->aclProvider = $this->getMockBuilder(ACLProvider::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->authenticator = $this->getMockBuilder(Authenticator::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->app = $this->getMockBuilder(Application::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->app->expects($this->any()) + ->method('offsetGet') + ->willReturnMap([ + ['phraseanet.appbox', $this->appbox], + ['twig', $this->twig], + ['authentication', $this->authenticator], + ['acl', $this->aclProvider], + ]); + + $this->sut = new Controller($this->app); + } + + public function testItCanFetchApplicationBox() + { + $this->assertInstanceOf(\appbox::class, $this->sut->getApplicationBox()); + } + + public function testItCanFetchDataboxById() + { + $databox = $this->getMockBuilder(\databox::class) + ->disableOriginalConstructor() + ->getMock(); + $this->appbox->expects($this->once()) + ->method('get_databox') + ->with(42) + ->willReturn($databox); + + $this->assertSame($databox, $this->sut->findDataboxById(42)); + } + + public function testItCanRenderTwigTemplate() + { + $name = 'template_name'; + $context = ['foo' => 'bar']; + $this->twig->expects($this->once()) + ->method('render') + ->with($name, $context) + ->willReturn('foo content'); + + $this->assertSame('foo content', $this->sut->render($name, $context)); + } + + public function testItCanWrapATwigTemplateIntoAResponse() + { + $name = 'template_name'; + $context = ['foo' => 'bar']; + $status = 400; + $headers = [ 'baz' => 'bim']; + $this->twig->expects($this->once()) + ->method('render') + ->with($name, $context) + ->willReturn('foo content'); + + $response = $this->sut->renderResponse($name, $context, $status, $headers); + + $this->assertInstanceOf(Response::class, $response); + $this->assertSame(400, $response->getStatusCode()); + $this->assertSame('foo content', $response->getContent()); + $this->assertTrue($response->headers->contains('baz', 'bim')); + } + + public function testItCanRetrieveAclProvider() + { + $this->assertSame($this->aclProvider, $this->sut->getAclProvider()); + } + + public function testItCanRetrieveAuthenticator() + { + $this->assertSame($this->authenticator, $this->sut->getAuthenticator()); + } + + public function testItCanRetrieveAuthenticatedUser() + { + $user = new User(); + $this->authenticator->expects($this->once()) + ->method('getUser') + ->willReturn($user); + + $this->assertSame($user, $this->sut->getAuthenticatedUser()); + } + + public function testItCanCreateAclForAGivenUser() + { + $user = new User(); + $acl = $this->getMockBuilder(\ACL::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->authenticator->expects($this->never()) + ->method('getUser'); + + $this->aclProvider->expects($this->once()) + ->method('get') + ->with($user) + ->willReturn($acl); + + $this->assertSame($acl, $this->sut->getAclForUser($user)); + } + + public function testItCanCreateAclForCurrentlyLoggedUser() + { + $user = new User(); + $acl = $this->getMockBuilder(\ACL::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->authenticator->expects($this->once()) + ->method('getUser') + ->willReturn($user); + + $this->aclProvider->expects($this->once()) + ->method('get') + ->with($user) + ->willReturn($acl); + + $this->assertSame($acl, $this->sut->getAclForUser()); + } +} From 447029bc6a81bbb05d28f2ebf269e0d5216de373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 13:34:30 +0200 Subject: [PATCH 24/26] FieldsController Split --- lib/Alchemy/Phrasea/Application.php | 4 +- .../Controller/Admin/FieldsController.php | 339 ++++++++++++++++ .../ControllerProvider/Admin/Fields.php | 373 ++---------------- 3 files changed, 378 insertions(+), 338 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 35f195d037..d2387763e9 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea; use Alchemy\Geonames\GeonamesServiceProvider; -use Alchemy\Phrasea\ControllerProvider\Admin\Fields; use Alchemy\Phrasea\ControllerProvider\Admin\Publications; use Alchemy\Phrasea\ControllerProvider\Admin\Root as AdminRoot; use Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine; @@ -312,6 +311,7 @@ class Application extends SilexApplication 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Databox' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\Fields' => [], 'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [], 'Alchemy\Phrasea\ControllerProvider\Datafiles' => [], 'Alchemy\Phrasea\ControllerProvider\Lightbox' => [], @@ -621,7 +621,6 @@ class Application extends SilexApplication $this->mount('/admin/setup', new Setup()); $this->mount('/admin/search-engine', new SearchEngine()); $this->mount('/admin/publications', new Publications()); - $this->mount('/admin/fields', new Fields()); $this->mount('/admin/task-manager', new TaskManager()); $this->mount('/admin/subdefs', new Subdefs()); @@ -671,6 +670,7 @@ class Application extends SilexApplication '/admin/dashboard' => 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard', '/admin/databox' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databox', '/admin/databoxes' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes', + '/admin/fields' => 'Alchemy\Phrasea\ControllerProvider\Admin\Fields', '/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users', '/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles', '/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier', diff --git a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php new file mode 100644 index 0000000000..5cd730520a --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php @@ -0,0 +1,339 @@ +app = $app; + } + + public function updateFields(Application $app, Request $request, $sbas_id) + { + $fields = []; + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $metaStructure = $databox->get_meta_structure(); + $connection = $databox->get_connection(); + $data = $this->getFieldsJsonFromRequest($app, $request); + + $connection->beginTransaction(); + + foreach ($data as $jsonField) { + try { + $field = \databox_field::get_instance($app, $databox, $jsonField['id']); + + if ($field->get_name() !== $jsonField['name']) { + $this->validateNameField($metaStructure, $jsonField); + } + + $this->validateTagField($jsonField); + + $this->updateFieldWithData($app, $field, $jsonField); + $field->save(); + $fields[] = $field->toArray(); + } catch (\Exception $e) { + $connection->rollback(); + $app->abort(500, $app->trans('Field %name% could not be saved, please try again or contact an admin.', ['%name%' => $jsonField['name']])); + break; + } + } + + $connection->commit(); + + return $app->json($fields); + } + + public function getLanguage(Application $app, Request $request) + { + return $app->json([ + 'something_wrong' => $app->trans('Something wrong happened, please try again or contact an admin.'), + 'created_success' => $app->trans('%s field has been created with success.'), + 'deleted_success' => $app->trans('%s field has been deleted with success.'), + 'are_you_sure_delete' => $app->trans('Do you really want to delete the field %s ?'), + 'validation_blank' => $app->trans('Field can not be blank.'), + 'validation_name_exists' => $app->trans('Field name already exists.'), + 'validation_name_invalid' => $app->trans('Field name is not valid.'), + 'validation_tag_invalid' => $app->trans('Field source is not valid.'), + 'field_error' => $app->trans('Field %s contains errors.'), + 'fields_save' => $app->trans('Your configuration has been successfuly saved.'), + ]); + } + + public function displayApp(Application $app, Request $request, $sbas_id) + { + $languages = []; + + foreach ($app['locales.available'] as $code => $language) { + $data = explode('_', $code); + $languages[$data[0]] = $language; + } + + return $app['twig']->render('/admin/fields/index.html.twig', [ + 'sbas_id' => $sbas_id, + 'languages' => $languages, + ]); + } + + public function listDcFields(Application $app, Request $request) + { + $data = $app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json'); + + return new Response($data, 200, ['content-type' => 'application/json']); + } + + public function listVocabularies(Application $app, Request $request) + { + $vocabularies = VocabularyController::getAvailable($app); + + return $app->json(array_map(function ($vocabulary) { + return [ + 'type' => $vocabulary->getType(), + 'name' => $vocabulary->getName(), + ]; + }, $vocabularies)); + } + + public function getVocabulary(Application $app, Request $request, $type) + { + $vocabulary = VocabularyController::get($app, $type); + + return $app->json([ + 'type' => $vocabulary->getType(), + 'name' => $vocabulary->getName(), + ]); + } + + public function searchTag(Application $app, Request $request) + { + $term = trim(strtolower($request->query->get('term'))); + $res = []; + + if ($term) { + $provider = new TagProvider(); + + foreach ($provider->getLookupTable() as $namespace => $tags) { + $ns = strpos($namespace, $term); + + foreach ($tags as $tagname => $datas) { + if ($ns === false && strpos($tagname, $term) === false) { + continue; + } + + $res[] = [ + 'id' => $namespace . '/' . $tagname, + /** @Ignore */ + 'label' => $datas['namespace'] . ' / ' . $datas['tagname'], + 'value' => $datas['namespace'] . ':' . $datas['tagname'], + ]; + } + } + } + + return $app->json($res); + } + + public function getTag(Application $app, Request $request, $tagname) + { + $tag = \databox_field::loadClassFromTagName($tagname); + $json = $app['serializer']->serialize($tag, 'json'); + + return new Response($json, 200, ['Content-Type' => 'application/json']); + } + + public function createField(Application $app, Request $request, $sbas_id) + { + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $data = $this->getFieldJsonFromRequest($app, $request); + + $metaStructure = $databox->get_meta_structure(); + $this->validateNameField($metaStructure, $data); + $this->validateTagField($data); + + try { + $field = \databox_field::create($app, $databox, $data['name'], $data['multi']); + $this->updateFieldWithData($app, $field, $data); + $field->save(); + } catch (\Exception $e) { + $app->abort(500, $app->trans('Field %name% could not be created, please try again or contact an admin.', ['%name%' => $data['name']])); + } + + return $app->json($field->toArray(), 201, [ + 'location' => $app->path('admin_fields_show_field', [ + 'sbas_id' => $sbas_id, + 'id' => $field->get_id() + ])]); + } + + public function listFields(Application $app, $sbas_id) + { + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + + return $app->json($databox->get_meta_structure()->toArray()); + } + + public function getField(Application $app, $sbas_id, $id) + { + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $field = \databox_field::get_instance($app, $databox, $id); + + return $app->json($field->toArray()); + } + + public function updateField(Application $app, Request $request, $sbas_id, $id) + { + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $field = \databox_field::get_instance($app, $databox, $id); + $data = $this->getFieldJsonFromRequest($app, $request); + + $this->validateTagField($data); + + if ($field->get_name() !== $data['name']) { + $metaStructure = $databox->get_meta_structure(); + $this->validateNameField($metaStructure, $data); + } + + $this->updateFieldWithData($app, $field, $data); + $field->save(); + + return $app->json($field->toArray()); + } + + public function deleteField(Application $app, $sbas_id, $id) + { + $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + \databox_field::get_instance($app, $databox, $id)->delete(); + + return new Response('', 204); + } + + private function getFieldJsonFromRequest(Application $app, Request $request) + { + $data = $this->requestBodyToJson($request); + $required = $this->getMandatoryFieldProperties(); + + foreach ($required as $key) { + if (false === array_key_exists($key, $data)) { + $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + } + } + + return $data; + } + + private function getFieldsJsonFromRequest(Application $app, Request $request) + { + $data = $this->requestBodyToJson($request); + $required = $this->getMandatoryFieldProperties(); + + foreach ($data as $field) { + foreach ($required as $key) { + if (false === array_key_exists($key, $field)) { + $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + } + } + } + + return $data; + } + + private function updateFieldWithData(Application $app, \databox_field $field, array $data) + { + $field + ->set_name($data['name']) + ->set_thumbtitle($data['thumbtitle']) + ->set_tag(\databox_field::loadClassFromTagName($data['tag'])) + ->set_business($data['business']) + ->set_aggregable($data['aggregable']) + ->set_indexable($data['indexable']) + ->set_required($data['required']) + ->set_separator($data['separator']) + ->set_readonly($data['readonly']) + ->set_type($data['type']) + ->set_tbranch($data['tbranch']) + ->set_report($data['report']) + ->setVocabularyControl(null) + ->setVocabularyRestricted(false); + + foreach ($data['labels'] as $code => $label) { + $field->set_label($code, $label); + } + + if (isset($data['sorter'])) { + $field->set_position($data['sorter']); + } + + try { + $vocabulary = VocabularyController::get($app, $data['vocabulary-type']); + $field->setVocabularyControl($vocabulary); + $field->setVocabularyRestricted($data['vocabulary-restricted']); + } catch (\InvalidArgumentException $e) { + + } + + if ('' !== $dcesElement = (string) $data['dces-element']) { + $class = sprintf('\databox_Field_DCES_%s', $dcesElement); + + if (!class_exists($class)) { + throw new BadRequestHttpException(sprintf('DCES element %s does not exist.', $dcesElement)); + } + + $field->set_dces_element(new $class()); + } + } + + private function getMandatoryFieldProperties() + { + return [ + 'name', 'multi', 'thumbtitle', 'tag', 'business', 'indexable', 'aggregable', + 'required', 'separator', 'readonly', 'type', 'tbranch', 'report', + 'vocabulary-type', 'vocabulary-restricted', 'dces-element', 'labels' + ]; + } + + private function validateNameField(\databox_descriptionStructure $metaStructure, array $field) + { + if (null !== $metaStructure->get_element_by_name($field['name'])) { + throw new BadRequestHttpException(sprintf('Field %s already exists.', $field['name'])); + } + } + + private function validateTagField(array $field) + { + try { + \databox_field::loadClassFromTagName($field['tag'], true); + } catch (\Exception_Databox_metadataDescriptionNotFound $e) { + throw new BadRequestHttpException(sprintf('Provided tag %s is unknown.', $field['tag'])); + } + } + + private function requestBodyToJson(Request $request) + { + $body = $request->getContent(); + $data = @json_decode($body, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + throw new BadRequestHttpException('Body must contain a valid JSON payload.'); + } + + return $data; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php index a6cf25f42f..8dae2e0cad 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php @@ -11,393 +11,94 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin; -use Alchemy\Phrasea\Metadata\TagProvider; -use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController; -use JMS\TranslationBundle\Annotation\Ignore; +use Alchemy\Phrasea\Application as PhraseaApplication; +use Alchemy\Phrasea\Controller\Admin\FieldsController; +use Alchemy\Phrasea\Security\Firewall; use Silex\Application; +use Silex\ControllerCollection; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Silex\ServiceProviderInterface; -class Fields implements ControllerProviderInterface +class Fields implements ControllerProviderInterface, ServiceProviderInterface { + public function register(Application $app) + { + $app['controller.admin.fields'] = $app->share(function (PhraseaApplication $app) { + return new FieldsController($app); + }); + } + + public function boot(Application $app) + { + } + public function connect(Application $app) { + /** @var ControllerCollection $controllers */ $controllers = $app['controllers_factory']; - $app['admin.fields.controller'] = $this; + /** @var Firewall $firewall */ + $firewall = $app['firewall']; + $firewall->addMandatoryAuthentication($controllers); - $app['firewall']->addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall'] + $controllers->before(function () use ($firewall) { + $firewall ->requireAccessToModule('admin') ->requireRight('bas_modify_struct'); }); - $controllers->get('/language.json', 'admin.fields.controller:getLanguage') + $controllers->get('/language.json', 'controller.admin.fields:getLanguage') ->bind('admin_fields_language'); - $controllers->get('/{sbas_id}', 'admin.fields.controller:displayApp') + $controllers->get('/{sbas_id}', 'controller.admin.fields:displayApp') ->assert('sbas_id', '\d+') ->bind('admin_fields'); - $controllers->put('/{sbas_id}/fields', 'admin.fields.controller:updateFields') + $controllers->put('/{sbas_id}/fields', 'controller.admin.fields:updateFields') ->assert('sbas_id', '\d+') ->bind('admin_fields_register'); - $controllers->get('/{sbas_id}/fields', 'admin.fields.controller:listFields') + $controllers->get('/{sbas_id}/fields', 'controller.admin.fields:listFields') ->assert('sbas_id', '\d+') ->bind('admin_fields_list'); - $controllers->post('/{sbas_id}/fields', 'admin.fields.controller:createField') + $controllers->post('/{sbas_id}/fields', 'controller.admin.fields:createField') ->assert('sbas_id', '\d+') ->bind('admin_fields_create_field'); - $controllers->get('/{sbas_id}/fields/{id}', 'admin.fields.controller:getField') + $controllers->get('/{sbas_id}/fields/{id}', 'controller.admin.fields:getField') ->assert('id', '\d+') ->assert('sbas_id', '\d+') ->bind('admin_fields_show_field'); - $controllers->put('/{sbas_id}/fields/{id}', 'admin.fields.controller:updateField') + $controllers->put('/{sbas_id}/fields/{id}', 'controller.admin.fields:updateField') ->assert('id', '\d+') ->assert('sbas_id', '\d+') ->bind('admin_fields_update_field'); - $controllers->delete('/{sbas_id}/fields/{id}', 'admin.fields.controller:deleteField') + $controllers->delete('/{sbas_id}/fields/{id}', 'controller.admin.fields:deleteField') ->assert('id', '\d+') ->assert('sbas_id', '\d+') ->bind('admin_fields_delete_field'); - $controllers->get('/tags/search', 'admin.fields.controller:searchTag') + $controllers->get('/tags/search', 'controller.admin.fields:searchTag') ->bind('admin_fields_search_tag'); - $controllers->get('/tags/{tagname}', 'admin.fields.controller:getTag') + $controllers->get('/tags/{tagname}', 'controller.admin.fields:getTag') ->bind('admin_fields_show_tag'); - $controllers->get('/vocabularies', 'admin.fields.controller:listVocabularies') + $controllers->get('/vocabularies', 'controller.admin.fields:listVocabularies') ->bind('admin_fields_list_vocabularies'); - $controllers->get('/vocabularies/{type}', 'admin.fields.controller:getVocabulary') + $controllers->get('/vocabularies/{type}', 'controller.admin.fields:getVocabulary') ->bind('admin_fields_show_vocabulary'); - $controllers->get('/dc-fields', 'admin.fields.controller:listDcFields') + $controllers->get('/dc-fields', 'controller.admin.fields:listDcFields') ->bind('admin_fields_list_dc_fields'); - $controllers->get('/dc-fields/{name}', 'admin.fields.controller:getDcFields') + $controllers->get('/dc-fields/{name}', 'controller.admin.fields:getDcFields') ->bind('admin_fields_get_dc_fields'); return $controllers; } - - public function updateFields(Application $app, Request $request, $sbas_id) - { - $fields = []; - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $metaStructure = $databox->get_meta_structure(); - $connection = $databox->get_connection(); - $data = $this->getFieldsJsonFromRequest($app, $request); - - $connection->beginTransaction(); - - foreach ($data as $jsonField) { - try { - $field = \databox_field::get_instance($app, $databox, $jsonField['id']); - - if ($field->get_name() !== $jsonField['name']) { - $this->validateNameField($metaStructure, $jsonField); - } - - $this->validateTagField($jsonField); - - $this->updateFieldWithData($app, $field, $jsonField); - $field->save(); - $fields[] = $field->toArray(); - } catch (\Exception $e) { - $connection->rollback(); - $app->abort(500, $app->trans('Field %name% could not be saved, please try again or contact an admin.', ['%name%' => $jsonField['name']])); - break; - } - } - - $connection->commit(); - - return $app->json($fields); - } - - public function getLanguage(Application $app, Request $request) - { - return $app->json([ - 'something_wrong' => $app->trans('Something wrong happened, please try again or contact an admin.'), - 'created_success' => $app->trans('%s field has been created with success.'), - 'deleted_success' => $app->trans('%s field has been deleted with success.'), - 'are_you_sure_delete' => $app->trans('Do you really want to delete the field %s ?'), - 'validation_blank' => $app->trans('Field can not be blank.'), - 'validation_name_exists' => $app->trans('Field name already exists.'), - 'validation_name_invalid' => $app->trans('Field name is not valid.'), - 'validation_tag_invalid' => $app->trans('Field source is not valid.'), - 'field_error' => $app->trans('Field %s contains errors.'), - 'fields_save' => $app->trans('Your configuration has been successfuly saved.'), - ]); - } - - public function displayApp(Application $app, Request $request, $sbas_id) - { - $languages = []; - - foreach ($app['locales.available'] as $code => $language) { - $data = explode('_', $code); - $languages[$data[0]] = $language; - } - - return $app['twig']->render('/admin/fields/index.html.twig', [ - 'sbas_id' => $sbas_id, - 'languages' => $languages, - ]); - } - - public function listDcFields(Application $app, Request $request) - { - $data = $app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json'); - - return new Response($data, 200, ['content-type' => 'application/json']); - } - - public function listVocabularies(Application $app, Request $request) - { - $vocabularies = VocabularyController::getAvailable($app); - - return $app->json(array_map(function ($vocabulary) { - return [ - 'type' => $vocabulary->getType(), - 'name' => $vocabulary->getName(), - ]; - }, $vocabularies)); - } - - public function getVocabulary(Application $app, Request $request, $type) - { - $vocabulary = VocabularyController::get($app, $type); - - return $app->json([ - 'type' => $vocabulary->getType(), - 'name' => $vocabulary->getName(), - ]); - } - - public function searchTag(Application $app, Request $request) - { - $term = trim(strtolower($request->query->get('term'))); - $res = []; - - if ($term) { - $provider = new TagProvider(); - - foreach ($provider->getLookupTable() as $namespace => $tags) { - $ns = strpos($namespace, $term); - - foreach ($tags as $tagname => $datas) { - if ($ns === false && strpos($tagname, $term) === false) { - continue; - } - - $res[] = [ - 'id' => $namespace . '/' . $tagname, - /** @Ignore */ - 'label' => $datas['namespace'] . ' / ' . $datas['tagname'], - 'value' => $datas['namespace'] . ':' . $datas['tagname'], - ]; - } - } - } - - return $app->json($res); - } - - public function getTag(Application $app, Request $request, $tagname) - { - $tag = \databox_field::loadClassFromTagName($tagname); - $json = $app['serializer']->serialize($tag, 'json'); - - return new Response($json, 200, ['Content-Type' => 'application/json']); - } - - public function createField(Application $app, Request $request, $sbas_id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $data = $this->getFieldJsonFromRequest($app, $request); - - $metaStructure = $databox->get_meta_structure(); - $this->validateNameField($metaStructure, $data); - $this->validateTagField($data); - - try { - $field = \databox_field::create($app, $databox, $data['name'], $data['multi']); - $this->updateFieldWithData($app, $field, $data); - $field->save(); - } catch (\Exception $e) { - $app->abort(500, $app->trans('Field %name% could not be created, please try again or contact an admin.', ['%name%' => $data['name']])); - } - - return $app->json($field->toArray(), 201, [ - 'location' => $app->path('admin_fields_show_field', [ - 'sbas_id' => $sbas_id, - 'id' => $field->get_id() - ])]); - } - - public function listFields(Application $app, $sbas_id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - - return $app->json($databox->get_meta_structure()->toArray()); - } - - public function getField(Application $app, $sbas_id, $id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $field = \databox_field::get_instance($app, $databox, $id); - - return $app->json($field->toArray()); - } - - public function updateField(Application $app, Request $request, $sbas_id, $id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $field = \databox_field::get_instance($app, $databox, $id); - $data = $this->getFieldJsonFromRequest($app, $request); - - $this->validateTagField($data); - - if ($field->get_name() !== $data['name']) { - $metaStructure = $databox->get_meta_structure(); - $this->validateNameField($metaStructure, $data); - } - - $this->updateFieldWithData($app, $field, $data); - $field->save(); - - return $app->json($field->toArray()); - } - - public function deleteField(Application $app, $sbas_id, $id) - { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - \databox_field::get_instance($app, $databox, $id)->delete(); - - return new Response('', 204); - } - - private function getFieldJsonFromRequest(Application $app, Request $request) - { - $data = $this->requestBodyToJson($request); - $required = $this->getMandatoryFieldProperties(); - - foreach ($required as $key) { - if (false === array_key_exists($key, $data)) { - $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); - } - } - - return $data; - } - - private function getFieldsJsonFromRequest(Application $app, Request $request) - { - $data = $this->requestBodyToJson($request); - $required = $this->getMandatoryFieldProperties(); - - foreach ($data as $field) { - foreach ($required as $key) { - if (false === array_key_exists($key, $field)) { - $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); - } - } - } - - return $data; - } - - private function updateFieldWithData(Application $app, \databox_field $field, array $data) - { - $field - ->set_name($data['name']) - ->set_thumbtitle($data['thumbtitle']) - ->set_tag(\databox_field::loadClassFromTagName($data['tag'])) - ->set_business($data['business']) - ->set_aggregable($data['aggregable']) - ->set_indexable($data['indexable']) - ->set_required($data['required']) - ->set_separator($data['separator']) - ->set_readonly($data['readonly']) - ->set_type($data['type']) - ->set_tbranch($data['tbranch']) - ->set_report($data['report']) - ->setVocabularyControl(null) - ->setVocabularyRestricted(false); - - foreach ($data['labels'] as $code => $label) { - $field->set_label($code, $label); - } - - if (isset($data['sorter'])) { - $field->set_position($data['sorter']); - } - - try { - $vocabulary = VocabularyController::get($app, $data['vocabulary-type']); - $field->setVocabularyControl($vocabulary); - $field->setVocabularyRestricted($data['vocabulary-restricted']); - } catch (\InvalidArgumentException $e) { - - } - - if ('' !== $dcesElement = (string) $data['dces-element']) { - $class = sprintf('\databox_Field_DCES_%s', $dcesElement); - - if (!class_exists($class)) { - throw new BadRequestHttpException(sprintf('DCES element %s does not exist.', $dcesElement)); - } - - $field->set_dces_element(new $class()); - } - } - - private function getMandatoryFieldProperties() - { - return [ - 'name', 'multi', 'thumbtitle', 'tag', 'business', 'indexable', 'aggregable', - 'required', 'separator', 'readonly', 'type', 'tbranch', 'report', - 'vocabulary-type', 'vocabulary-restricted', 'dces-element', 'labels' - ]; - } - - private function validateNameField(\databox_descriptionStructure $metaStructure, array $field) - { - if (null !== $metaStructure->get_element_by_name($field['name'])) { - throw new BadRequestHttpException(sprintf('Field %s already exists.', $field['name'])); - } - } - - private function validateTagField(array $field) - { - try { - \databox_field::loadClassFromTagName($field['tag'], true); - } catch (\Exception_Databox_metadataDescriptionNotFound $e) { - throw new BadRequestHttpException(sprintf('Provided tag %s is unknown.', $field['tag'])); - } - } - - private function requestBodyToJson(Request $request) - { - $body = $request->getContent(); - $data = @json_decode($body, true); - - if (JSON_ERROR_NONE !== json_last_error()) { - throw new BadRequestHttpException('Body must contain a valid JSON payload.'); - } - - return $data; - } } From 5f8dab86fd32db1c5681c5d23af9ac57b4548262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 13:35:44 +0200 Subject: [PATCH 25/26] Use BaseController --- .../Controller/Admin/CollectionController.php | 46 +---------- .../Admin/ConnectedUsersController.php | 7 +- .../Controller/Admin/DashboardController.php | 23 +----- .../Controller/Admin/DataboxController.php | 76 +----------------- .../Controller/Admin/DataboxesController.php | 78 +------------------ .../Controller/Admin/FieldsController.php | 11 +-- .../Controller/Admin/UserController.php | 45 +---------- .../Phrasea/Controller/LightboxController.php | 42 +--------- .../Phrasea/Controller/SetupController.php | 22 +----- 9 files changed, 18 insertions(+), 332 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php index c432d8c6a0..f3edbce86d 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php @@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\ACLProvider; use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Exception\RuntimeException; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Repositories\UserRepository; @@ -20,49 +21,8 @@ use Doctrine\DBAL\Connection; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class CollectionController +class CollectionController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - - /** - * @return User|null - */ - private function getAuthenticatedUser() - { - /** @var Authenticator $authenticator */ - $authenticator = $this->app['authentication']; - return $authenticator->getUser(); - } - - /** - * @return \ACL - */ - private function getAuthenticatedUserAcl() - { - /** @var ACLProvider $acl */ - $acl = $this->app['acl']; - return $acl->get($this->getAuthenticatedUser()); - } - - /** - * @param string $template - * @param array $parameters - * @return string - */ - private function render($template, array $parameters = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - - return $twig->render($template, $parameters); - } - /** * Display collection information page * @@ -76,7 +36,7 @@ class CollectionController $admins = []; - if ($this->getAuthenticatedUserAcl()->has_right_on_base($bas_id, 'manage')) { + if ($this->getAclForUser()->has_right_on_base($bas_id, 'manage')) { /** @var \User_Query $query */ $query = $this->app['phraseanet.user-query']; $admins = $query->on_base_ids([$bas_id]) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php index b39f2dfbfa..8b3b013cc8 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php @@ -13,16 +13,15 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Geonames\Exception\ExceptionInterface; use Alchemy\Geonames\Geoname; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Model\Entities\Session; use Doctrine\ORM\EntityManager; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Translation\TranslatorInterface; -class ConnectedUsersController +class ConnectedUsersController extends Controller { - /** @var Application */ - private $app; /** @var TranslatorInterface */ private $translator; protected $moduleNames; @@ -31,7 +30,7 @@ class ConnectedUsersController public function __construct(Application $app) { - $this->app = $app; + parent::__construct($app); $this->translator = $app['translator']; $this->logger = $app['monolog']; } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php index e1c889b46b..325f76a3ac 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php @@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\Authenticator; use Alchemy\Phrasea\Cache\Cache; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Exception\RuntimeException; use Alchemy\Phrasea\Model\Manipulator\ACLManipulator; @@ -24,16 +25,8 @@ use Alchemy\Phrasea\Notification\Receiver; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -class DashboardController +class DashboardController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - /** * Display admin dashboard page * @@ -161,18 +154,6 @@ class DashboardController return $this->app->redirectPath('admin_dashboard'); } - /** - * @param string $name - * @param array $context - * @return string - */ - public function render($name, array $context = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - return $twig->render($name, $context); - } - /** * @return UserRepository */ diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php index 0bbda3609d..ae6fb27860 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php @@ -13,23 +13,15 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\ACLProvider; use Alchemy\Phrasea\Authentication\Authenticator; -use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Model\Manipulator\TaskManipulator; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class DataboxController +class DataboxController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - /** * @param Request $request * @param integer $databox_id @@ -772,68 +764,4 @@ class DataboxController 'total' => $total ]); } - - /** - * @return \appbox - */ - private function getApplicationBox() - { - return $this->app['phraseanet.appbox']; - } - - /** - * @param int $id - * @return \databox - */ - private function findDataboxById($id) - { - $appbox = $this->getApplicationBox(); - - return $appbox->get_databox($id); - } - - /** - * @param $name - * @param array $context - * @return string - */ - private function render($name, array $context = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - return $twig->render( - $name, - $context - ); - } - - /** - * @return ACLProvider - */ - private function getAclProvider() - { - return $this->app['acl']; - } - - /** - * @return Authenticator - */ - private function getAuthenticator() - { - return $this->app['authentication']; - } - - /** - * @param User|null $user - * @return \ACL - */ - private function getAclForUser(User $user = null) - { - $aclProvider = $this->getAclProvider(); - if (null === $user) { - $user = $this->getAuthenticator()->getUser(); - } - - return $aclProvider->get($user); - } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php index f897ed59c4..a13a62197d 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php @@ -11,25 +11,15 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; -use Alchemy\Phrasea\Authentication\ACLProvider; -use Alchemy\Phrasea\Authentication\Authenticator; -use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Controller\Controller; use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class DataboxesController +class DataboxesController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - /** * Get Databases control panel * @@ -273,68 +263,4 @@ class DataboxesController } return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'mount-failed']); } - - /** - * @return \appbox - */ - private function getApplicationBox() - { - return $this->app['phraseanet.appbox']; - } - - /** - * @param int $id - * @return \databox - */ - private function findDataboxById($id) - { - $appbox = $this->getApplicationBox(); - - return $appbox->get_databox($id); - } - - /** - * @param $name - * @param array $context - * @return string - */ - private function render($name, array $context = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - return $twig->render( - $name, - $context - ); - } - - /** - * @return ACLProvider - */ - private function getAclProvider() - { - return $this->app['acl']; - } - - /** - * @return Authenticator - */ - private function getAuthenticator() - { - return $this->app['authentication']; - } - - /** - * @param User|null $user - * @return \ACL - */ - private function getAclForUser(User $user = null) - { - $aclProvider = $this->getAclProvider(); - if (null === $user) { - $user = $this->getAuthenticator()->getUser(); - } - - return $aclProvider->get($user); - } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php index 5cd730520a..bcbf8c4b21 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php @@ -11,22 +11,15 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Metadata\TagProvider; use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -class FieldsController +class FieldsController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - public function updateFields(Application $app, Request $request, $sbas_id) { $fields = []; diff --git a/lib/Alchemy/Phrasea/Controller/Admin/UserController.php b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php index d8c44a5503..7dfc23f3e6 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/UserController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php @@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\ACLProvider; use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Core\Response\CSVFileResponse; use Alchemy\Phrasea\Helper\User as UserHelper; use Alchemy\Phrasea\Model\Entities\FtpCredential; @@ -30,16 +31,8 @@ use Goodby\CSV\Import\Standard\Interpreter; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class UserController +class UserController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - public function editRightsAction(Request $request) { $rights = $this->getUserEditHelper($request); @@ -925,19 +918,6 @@ class UserController ]; } - /** - * @param string $name - * @param array $context - * @return string - */ - private function render($name, array $context = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - - return $twig->render($name, $context); - } - /** * @param Request $request * @return UserHelper\Edit @@ -983,16 +963,6 @@ class UserController return $exporter; } - /** - * @return User|null - */ - private function getAuthenticatedUser() - { - /** @var Authenticator $authenticator */ - $authenticator = $this->app['authentication']; - return $authenticator->getUser(); - } - /** * @param array $template * @return array @@ -1031,17 +1001,6 @@ class UserController return $deny; } - /** - * @param User $user - * @return \ACL - */ - private function getAclForUser(User $user) - { - /** @var ACLProvider $aclProvider */ - $aclProvider = $this->app['acl']; - return $aclProvider->get($user); - } - /** * @return RegistrationManipulator */ diff --git a/lib/Alchemy/Phrasea/Controller/LightboxController.php b/lib/Alchemy/Phrasea/Controller/LightboxController.php index 3d27e80964..d30eb147de 100644 --- a/lib/Alchemy/Phrasea/Controller/LightboxController.php +++ b/lib/Alchemy/Phrasea/Controller/LightboxController.php @@ -24,16 +24,8 @@ use Alchemy\Phrasea\Model\Repositories\BasketRepository; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -class LightboxController +class LightboxController extends Controller { - /** @var Application */ - protected $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - public function rootAction() { try { @@ -60,28 +52,6 @@ class LightboxController ]); } - /** - * @param string $template - * @param array $parameters - * @return Response - */ - private function renderResponse($template, array $parameters = []) - { - return new Response($this->render($template, $parameters)); - } - - /** - * @param string $template - * @param array $parameters - * @return string - */ - private function render($template, array $parameters = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - return $twig->render($template, $parameters); - } - /** * @param int $sselcont_id * @return Response @@ -444,16 +414,6 @@ class LightboxController return $this->app->json($ret); } - /** - * @return mixed - */ - private function getAuthenticatedUser() - { - /** @var Authenticator $authentication */ - $authentication = $this->app['authentication']; - return $authentication->getUser(); - } - /** * @param Basket $basket * @return Response diff --git a/lib/Alchemy/Phrasea/Controller/SetupController.php b/lib/Alchemy/Phrasea/Controller/SetupController.php index c8c8f15216..937db64b10 100644 --- a/lib/Alchemy/Phrasea/Controller/SetupController.php +++ b/lib/Alchemy/Phrasea/Controller/SetupController.php @@ -21,28 +21,8 @@ use Doctrine\DBAL\Connection; use Silex\Application as SilexApplication; use Symfony\Component\HttpFoundation\Request; -class SetupController +class SetupController extends Controller { - /** @var Application */ - private $app; - - public function __construct(Application $app) - { - $this->app = $app; - } - - /** - * @param string $template - * @param array $parameters - * @return string - */ - private function render($template, array $parameters = []) - { - /** @var \Twig_Environment $twig */ - $twig = $this->app['twig']; - return $twig->render($template, $parameters); - } - public function rootInstaller(Request $request) { $requirementsCollection = $this->getRequirementsCollection(); From bdec67aac79bc578d720c968bf036e91dcb075fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 2 Apr 2015 14:33:12 +0200 Subject: [PATCH 26/26] FieldsController refactor --- .../Controller/Admin/FieldsController.php | 135 +++++++++--------- lib/classes/databox/field.php | 90 +----------- 2 files changed, 76 insertions(+), 149 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php index bcbf8c4b21..d0b14b2d8f 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php @@ -14,25 +14,27 @@ use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Metadata\TagProvider; use Alchemy\Phrasea\Vocabulary\Controller as VocabularyController; +use Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\HttpException; class FieldsController extends Controller { - public function updateFields(Application $app, Request $request, $sbas_id) + public function updateFields(Request $request, $sbas_id) { $fields = []; - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $databox = $this->findDataboxById((int) $sbas_id); $metaStructure = $databox->get_meta_structure(); $connection = $databox->get_connection(); - $data = $this->getFieldsJsonFromRequest($app, $request); + $data = $this->getFieldsJsonFromRequest($request); $connection->beginTransaction(); foreach ($data as $jsonField) { try { - $field = \databox_field::get_instance($app, $databox, $jsonField['id']); + $field = \databox_field::get_instance($this->app, $databox, $jsonField['id']); if ($field->get_name() !== $jsonField['name']) { $this->validateNameField($metaStructure, $jsonField); @@ -40,64 +42,64 @@ class FieldsController extends Controller $this->validateTagField($jsonField); - $this->updateFieldWithData($app, $field, $jsonField); + $this->updateFieldWithData($field, $jsonField); $field->save(); $fields[] = $field->toArray(); } catch (\Exception $e) { $connection->rollback(); - $app->abort(500, $app->trans('Field %name% could not be saved, please try again or contact an admin.', ['%name%' => $jsonField['name']])); + $this->app->abort(500, $this->app->trans('Field %name% could not be saved, please try again or contact an admin.', ['%name%' => $jsonField['name']])); break; } } $connection->commit(); - return $app->json($fields); + return $this->app->json($fields); } - public function getLanguage(Application $app, Request $request) + public function getLanguage() { - return $app->json([ - 'something_wrong' => $app->trans('Something wrong happened, please try again or contact an admin.'), - 'created_success' => $app->trans('%s field has been created with success.'), - 'deleted_success' => $app->trans('%s field has been deleted with success.'), - 'are_you_sure_delete' => $app->trans('Do you really want to delete the field %s ?'), - 'validation_blank' => $app->trans('Field can not be blank.'), - 'validation_name_exists' => $app->trans('Field name already exists.'), - 'validation_name_invalid' => $app->trans('Field name is not valid.'), - 'validation_tag_invalid' => $app->trans('Field source is not valid.'), - 'field_error' => $app->trans('Field %s contains errors.'), - 'fields_save' => $app->trans('Your configuration has been successfuly saved.'), + return $this->app->json([ + 'something_wrong' => $this->app->trans('Something wrong happened, please try again or contact an admin.'), + 'created_success' => $this->app->trans('%s field has been created with success.'), + 'deleted_success' => $this->app->trans('%s field has been deleted with success.'), + 'are_you_sure_delete' => $this->app->trans('Do you really want to delete the field %s ?'), + 'validation_blank' => $this->app->trans('Field can not be blank.'), + 'validation_name_exists' => $this->app->trans('Field name already exists.'), + 'validation_name_invalid' => $this->app->trans('Field name is not valid.'), + 'validation_tag_invalid' => $this->app->trans('Field source is not valid.'), + 'field_error' => $this->app->trans('Field %s contains errors.'), + 'fields_save' => $this->app->trans('Your configuration has been successfuly saved.'), ]); } - public function displayApp(Application $app, Request $request, $sbas_id) + public function displayApp($sbas_id) { $languages = []; - foreach ($app['locales.available'] as $code => $language) { + foreach ($this->app['locales.available'] as $code => $language) { $data = explode('_', $code); $languages[$data[0]] = $language; } - return $app['twig']->render('/admin/fields/index.html.twig', [ + return $this->render('/admin/fields/index.html.twig', [ 'sbas_id' => $sbas_id, 'languages' => $languages, ]); } - public function listDcFields(Application $app, Request $request) + public function listDcFields() { - $data = $app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json'); + $data = $this->app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json'); return new Response($data, 200, ['content-type' => 'application/json']); } - public function listVocabularies(Application $app, Request $request) + public function listVocabularies() { - $vocabularies = VocabularyController::getAvailable($app); + $vocabularies = VocabularyController::getAvailable($this->app); - return $app->json(array_map(function ($vocabulary) { + return $this->app->json(array_map(function (ControlProviderInterface $vocabulary) { return [ 'type' => $vocabulary->getType(), 'name' => $vocabulary->getName(), @@ -105,17 +107,17 @@ class FieldsController extends Controller }, $vocabularies)); } - public function getVocabulary(Application $app, Request $request, $type) + public function getVocabulary($type) { - $vocabulary = VocabularyController::get($app, $type); + $vocabulary = VocabularyController::get($this->app, $type); - return $app->json([ + return $this->app->json([ 'type' => $vocabulary->getType(), 'name' => $vocabulary->getName(), ]); } - public function searchTag(Application $app, Request $request) + public function searchTag(Request $request) { $term = trim(strtolower($request->query->get('term'))); $res = []; @@ -141,61 +143,64 @@ class FieldsController extends Controller } } - return $app->json($res); + return $this->app->json($res); } - public function getTag(Application $app, Request $request, $tagname) + public function getTag($tagname) { $tag = \databox_field::loadClassFromTagName($tagname); - $json = $app['serializer']->serialize($tag, 'json'); + $json = $this->app['serializer']->serialize($tag, 'json'); return new Response($json, 200, ['Content-Type' => 'application/json']); } - public function createField(Application $app, Request $request, $sbas_id) + public function createField(Request $request, $sbas_id) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $data = $this->getFieldJsonFromRequest($app, $request); + $databox = $this->findDataboxById((int) $sbas_id); + $data = $this->getFieldJsonFromRequest($request); $metaStructure = $databox->get_meta_structure(); $this->validateNameField($metaStructure, $data); $this->validateTagField($data); try { - $field = \databox_field::create($app, $databox, $data['name'], $data['multi']); - $this->updateFieldWithData($app, $field, $data); + $field = \databox_field::create($this->app, $databox, $data['name'], $data['multi']); + $this->updateFieldWithData($field, $data); $field->save(); } catch (\Exception $e) { - $app->abort(500, $app->trans('Field %name% could not be created, please try again or contact an admin.', ['%name%' => $data['name']])); + throw new HttpException(500, $this->app->trans( + 'Field %name% could not be created, please try again or contact an admin.', + ['%name%' => $data['name']] + )); } - return $app->json($field->toArray(), 201, [ - 'location' => $app->path('admin_fields_show_field', [ + return $this->app->json($field->toArray(), 201, [ + 'location' => $this->app->path('admin_fields_show_field', [ 'sbas_id' => $sbas_id, - 'id' => $field->get_id() + 'id' => $field->get_id(), ])]); } - public function listFields(Application $app, $sbas_id) + public function listFields($sbas_id) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); + $databox = $this->findDataboxById((int) $sbas_id); - return $app->json($databox->get_meta_structure()->toArray()); + return $this->app->json($databox->get_meta_structure()->toArray()); } - public function getField(Application $app, $sbas_id, $id) + public function getField($sbas_id, $id) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $field = \databox_field::get_instance($app, $databox, $id); + $databox = $this->findDataboxById((int) $sbas_id); + $field = \databox_field::get_instance($this->app, $databox, $id); - return $app->json($field->toArray()); + return $this->app->json($field->toArray()); } - public function updateField(Application $app, Request $request, $sbas_id, $id) + public function updateField(Request $request, $sbas_id, $id) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - $field = \databox_field::get_instance($app, $databox, $id); - $data = $this->getFieldJsonFromRequest($app, $request); + $databox = $this->findDataboxById((int) $sbas_id); + $field = \databox_field::get_instance($this->app, $databox, $id); + $data = $this->getFieldJsonFromRequest($request); $this->validateTagField($data); @@ -204,35 +209,35 @@ class FieldsController extends Controller $this->validateNameField($metaStructure, $data); } - $this->updateFieldWithData($app, $field, $data); + $this->updateFieldWithData($field, $data); $field->save(); - return $app->json($field->toArray()); + return $this->app->json($field->toArray()); } - public function deleteField(Application $app, $sbas_id, $id) + public function deleteField($sbas_id, $id) { - $databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id); - \databox_field::get_instance($app, $databox, $id)->delete(); + $databox = $this->findDataboxById((int) $sbas_id); + \databox_field::get_instance($this->app, $databox, $id)->delete(); return new Response('', 204); } - private function getFieldJsonFromRequest(Application $app, Request $request) + private function getFieldJsonFromRequest(Request $request) { $data = $this->requestBodyToJson($request); $required = $this->getMandatoryFieldProperties(); foreach ($required as $key) { if (false === array_key_exists($key, $data)) { - $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + $this->app->abort(400, sprintf('The entity must contain a key `%s`', $key)); } } return $data; } - private function getFieldsJsonFromRequest(Application $app, Request $request) + private function getFieldsJsonFromRequest(Request $request) { $data = $this->requestBodyToJson($request); $required = $this->getMandatoryFieldProperties(); @@ -240,7 +245,7 @@ class FieldsController extends Controller foreach ($data as $field) { foreach ($required as $key) { if (false === array_key_exists($key, $field)) { - $app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + $this->app->abort(400, sprintf('The entity must contain a key `%s`', $key)); } } } @@ -248,7 +253,7 @@ class FieldsController extends Controller return $data; } - private function updateFieldWithData(Application $app, \databox_field $field, array $data) + private function updateFieldWithData(\databox_field $field, array $data) { $field ->set_name($data['name']) @@ -275,7 +280,7 @@ class FieldsController extends Controller } try { - $vocabulary = VocabularyController::get($app, $data['vocabulary-type']); + $vocabulary = VocabularyController::get($this->app, $data['vocabulary-type']); $field->setVocabularyControl($vocabulary); $field->setVocabularyRestricted($data['vocabulary-restricted']); } catch (\InvalidArgumentException $e) { diff --git a/lib/classes/databox/field.php b/lib/classes/databox/field.php index 7386db6d3b..6b849b9aca 100644 --- a/lib/classes/databox/field.php +++ b/lib/classes/databox/field.php @@ -26,98 +26,36 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class databox_field implements cache_cacheableInterface { - /** - * - * @var - */ protected $id; /** - * * @var databox */ protected $databox; /** - * - * @var \PHPExiftool\Driver\Tag + * @var TagInterface */ protected $tag; - /** - * - * @var - */ protected $name; - - /** - * - * @var - */ protected $indexable; - - /** - * - * @var - */ protected $readonly; - - /** - * - * @var - */ protected $position; - - /** - * - * @var - */ protected $required; - - /** - * - * @var - */ protected $multi; - - /** - * - * @var - */ protected $report; - - /** - * - * @var - */ protected $type; - - /** - * - * @var - */ protected $tbranch; - - /** - * - * @var - */ protected $separator; - - /** - * - * @var - */ protected $thumbtitle; /** - * * @var array */ protected $labels = []; /** - * * @var boolean */ protected $Business; @@ -125,15 +63,6 @@ class databox_field implements cache_cacheableInterface protected $renamed = false; /** - * - * - * To implement : change multi - * Change vocab Id - * - */ - - /** - * * @var int */ protected $sbas_id; @@ -173,7 +102,7 @@ class databox_field implements cache_cacheableInterface /** * * @param databox $databox - * @param $id + * @param int $id * @return databox_field */ protected function __construct(Application $app, databox $databox, $id) @@ -242,7 +171,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @return type \Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface */ public function getVocabularyControl() @@ -251,7 +179,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @return boolean */ public function isVocabularyRestricted() @@ -260,7 +187,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @return boolean */ public function isBusiness() @@ -274,7 +200,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @param Application $app * @param \databox $databox * @param int $id @@ -306,7 +231,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @param databox $databox */ public function set_databox(databox $databox) @@ -315,7 +239,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @return Connection */ public function get_connection() @@ -329,7 +252,6 @@ class databox_field implements cache_cacheableInterface } /** - * * @return databox */ public function get_databox() @@ -548,8 +470,8 @@ class databox_field implements cache_cacheableInterface /** * Get a PHPExiftool Tag from tagName * - * @param type $tagName - * @return \PHPExiftool\Driver\Tag + * @param string $tagName + * @return \PHPExiftool\Driver\TagInterface * @throws Exception_Databox_metadataDescriptionNotFound */ public static function loadClassFromTagName($tagName, $throwException = true) @@ -592,7 +514,7 @@ class databox_field implements cache_cacheableInterface return $tag; } - public function set_tag(TagInterface $tag = null) + public function set_tag($tag = null) { if ($tag === null) { $tag = new Nosource(); @@ -989,7 +911,7 @@ class databox_field implements cache_cacheableInterface * @param type $name * @param type $multi * - * @return databox_field + * @return self * * @throws \Exception_InvalidArgument */