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 && diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index b208509542..d2387763e9 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -11,92 +11,80 @@ 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\Geonames\GeonamesServiceProvider; +use Alchemy\Phrasea\ControllerProvider\Admin\Publications; +use Alchemy\Phrasea\ControllerProvider\Admin\Root as AdminRoot; +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\Client\Root as ClientRoot; +use Alchemy\Phrasea\ControllerProvider\Prod\BasketController; +use Alchemy\Phrasea\ControllerProvider\Prod\Bridge; +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; +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\Property; +use Alchemy\Phrasea\ControllerProvider\Prod\Push; +use Alchemy\Phrasea\ControllerProvider\Prod\Query; +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\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; 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 +93,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 +110,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 +304,24 @@ class Application extends SilexApplication return $handler; }); + + $providers = [ + 'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [], + 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [], + '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' => [], + 'Alchemy\Phrasea\ControllerProvider\Minifier' => [], + 'Alchemy\Phrasea\ControllerProvider\Permalink' => [], + 'Alchemy\Phrasea\ControllerProvider\Setup' => [], + ]; + 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'; @@ -440,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); })); @@ -617,19 +617,10 @@ 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()); - $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()); - $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()); $this->mount('/admin/task-manager', new TaskManager()); $this->mount('/admin/subdefs', new Subdefs()); @@ -666,8 +657,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()); @@ -675,10 +664,23 @@ class Application extends SilexApplication $this->mount('/thesaurus', new Thesaurus()); $this->mount('/xmlhttp', new ThesaurusXMLHttp()); - $this->mount('/include/minify/', new Minifier()); - $this->mount('/permalink/', new Permalink()); - - $this->mount('/lightbox/', new Lightbox()); + $providers = [ + '/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/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', + '/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/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index 268bdac5a3..b1d6b04425 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; @@ -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/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/AbstractDelivery.php b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php index b2dcf1ea25..9847117929 100644 --- a/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php +++ b/lib/Alchemy/Phrasea/Controller/AbstractDelivery.php @@ -13,37 +13,47 @@ namespace Alchemy\Phrasea\Controller; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Http\DeliverDataInterface; -use Silex\ControllerProviderInterface; +use Session_Logger; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; -abstract class AbstractDelivery implements ControllerProviderInterface +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($record, $request); } elseif ($subdef !== 'thumbnail') { try { if ($file->getDataboxSubdef()->get_class() != \databox_subdef::CLASS_THUMBNAIL) { $response->setPrivate(); - $this->logView($app, $record, $request); + $this->logView($record, $request); } } catch (\Exception $e) { - + // Ignore exception } } @@ -52,14 +62,20 @@ abstract class AbstractDelivery implements ControllerProviderInterface 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/Admin/Collection.php b/lib/Alchemy/Phrasea/Controller/Admin/Collection.php deleted file mode 100644 index 0d1d5ad807..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php +++ /dev/null @@ -1,983 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('admin') - ->requireRightOnBase($app['request']->attributes->get('bas_id'), 'canadmin'); - }); - - $controllers->get('/{bas_id}/', 'controller.admin.collection:getCollection') - ->assert('bas_id', '\d+') - ->bind('admin_display_collection'); - - $controllers->get('/{bas_id}/suggested-values/', 'controller.admin.collection:getSuggestedValues') - ->assert('bas_id', '\d+') - ->bind('admin_collection_display_suggested_values'); - - $controllers->post('/{bas_id}/suggested-values/', 'controller.admin.collection:submitSuggestedValues') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_suggested_values'); - - $controllers->post('/{bas_id}/delete/', 'controller.admin.collection:delete') - ->assert('bas_id', '\d+') - ->bind('admin_collection_delete'); - - $controllers->post('/{bas_id}/enable/', 'controller.admin.collection:enable') - ->assert('bas_id', '\d+') - ->bind('admin_collection_enable'); - - $controllers->post('/{bas_id}/disabled/', 'controller.admin.collection:disabled') - ->assert('bas_id', '\d+') - ->bind('admin_collection_disable'); - - $controllers->post('/{bas_id}/order/admins/', 'controller.admin.collection:setOrderAdmins') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_order_admins'); - - $controllers->post('/{bas_id}/publication/display/', 'controller.admin.collection:setPublicationDisplay') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_publication'); - - $controllers->post('/{bas_id}/rename/', 'controller.admin.collection:rename') - ->assert('bas_id', '\d+') - ->bind('admin_collection_rename'); - - $controllers->post('/{bas_id}/labels/', 'controller.admin.collection:labels') - ->assert('bas_id', '\d+') - ->bind('admin_collection_labels'); - - $controllers->post('/{bas_id}/empty/', 'controller.admin.collection:emptyCollection') - ->assert('bas_id', '\d+') - ->bind('admin_collection_empty'); - - $controllers->post('/{bas_id}/unmount/', 'controller.admin.collection:unmount') - ->assert('bas_id', '\d+') - ->bind('admin_collection_unmount'); - - $controllers->post('/{bas_id}/picture/mini-logo/', 'controller.admin.collection:setMiniLogo') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_logo'); - - $controllers->post('/{bas_id}/picture/mini-logo/delete/', 'controller.admin.collection:deleteLogo') - ->assert('bas_id', '\d+') - ->bind('admin_collection_delete_logo'); - - $controllers->post('/{bas_id}/picture/watermark/', 'controller.admin.collection:setWatermark') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_watermark'); - - $controllers->post('/{bas_id}/picture/watermark/delete/', 'controller.admin.collection:deleteWatermark') - ->assert('bas_id', '\d+') - ->bind('admin_collection_delete_watermark'); - - $controllers->post('/{bas_id}/picture/stamp-logo/', 'controller.admin.collection:setStamp') - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_stamp'); - - $controllers->post('/{bas_id}/picture/stamp-logo/delete/', 'controller.admin.collection:deleteStamp') - ->assert('bas_id', '\d+') - ->bind('admin_collection_delete_stamp'); - $controllers->get('/{bas_id}/informations/details/', 'controller.admin.collection:getDetails') - ->assert('bas_id', '\d+') - ->bind('admin_collection_display_document_details'); - - 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, - ]); - } -} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php new file mode 100644 index 0000000000..f3edbce86d --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/CollectionController.php @@ -0,0 +1,928 @@ +app, $bas_id); + + $admins = []; + + 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]) + ->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/Controller/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php deleted file mode 100644 index 6ed8fe1b67..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsers.php +++ /dev/null @@ -1,135 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('Admin'); - }); - - $controllers->get('/', 'controller.admin.connected-users:listConnectedUsers') - ->bind('admin_connected_users'); - - 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/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php new file mode 100644 index 0000000000..8b3b013cc8 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/ConnectedUsersController.php @@ -0,0 +1,128 @@ +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/Controller/Admin/Dashboard.php b/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php deleted file mode 100644 index 4f21177602..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Dashboard.php +++ /dev/null @@ -1,171 +0,0 @@ -before(function (Request $request) use ($app) { - $app['firewall']->requireAdmin(); - }); - - $controllers->get('/', 'controller.admin.dashboard:slash') - ->bind('admin_dashbord'); - - $controllers->post('/flush-cache/', 'controller.admin.dashboard:flush') - ->bind('admin_dashboard_flush_cache'); - - $controllers->post('/send-mail-test/', 'controller.admin.dashboard:sendMail') - ->bind('admin_dashboard_test_mail'); - - $controllers->post('/reset-admin-rights/', 'controller.admin.dashboard:resetAdminRights') - ->bind('admin_dashboard_reset_admin_rights'); - - $controllers->post('/add-admins/', 'controller.admin.dashboard:addAdmins') - ->bind('admin_dashboard_add_admins'); - - 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_dashbord', ['flush_cache' => 'ok']); - } - - return $app->redirectPath('admin_dashbord', ['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_dashbord', ['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_dashbord', ['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_dashbord'); - } - - /** - * 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_dashbord'); - } -} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php new file mode 100644 index 0000000000..325f76a3ac --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DashboardController.php @@ -0,0 +1,164 @@ +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'); + } + + /** + * @return UserRepository + */ + public function getUserRepository() + { + return $this->app['repo.users']; + } +} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php b/lib/Alchemy/Phrasea/Controller/Admin/Databox.php deleted file mode 100644 index ee3fc77f34..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php +++ /dev/null @@ -1,859 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('admin') - ->requireAccessToSbas($request->attributes->get('databox_id')); - }); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - }) - ->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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - $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'); - - return $controllers; - } - - /** - * - * @param Application $app - * @param Request $request - * @param integer $databox_id - * - * @return Response - */ - public function getDatabase(Application $app, Request $request, $databox_id) - { - $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 - ]); - } -} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php new file mode 100644 index 0000000000..ae6fb27860 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxController.php @@ -0,0 +1,767 @@ +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 Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function deleteBase(Request $request, $databox_id) + { + $databox = null; + $success = false; + $msg = $this->app->trans('An error occured'); + try { + $databox = $this->findDataboxById($databox_id); + + if ($databox->get_record_amount() > 0) { + $msg = $this->app->trans('admin::base: vider la base avant de la supprimer'); + } else { + $databox->unmount_databox(); + $this->getApplicationBox()->write_databox_pic( + $this->app['media-alchemyst'], + $this->app['filesystem'], + $databox, + null, + \databox::PIC_PDF + ); + $databox->delete(); + $success = true; + $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' === $request->getRequestFormat()) { + return $this->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 $this->app->redirectPath('admin_database', $params); + } + + public function setLabels(Request $request, $databox_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')); + } + + $databox = $this->findDataboxById($databox_id); + $success = true; + + try { + foreach ($this->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' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + ]); + } + + return $this->app->redirect(sprintf( + '/admin/databox/%d/?success=%d&reload-tree=1', + $databox->get_sbas_id(), + (int) $success + )); + } + + /** + * Reindex databox content + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function reindex(Request $request, $databox_id) + { + $success = false; + + try { + $this->findDataboxById($databox_id)->reindex(); + $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'), + 'sbas_id' => $databox_id, + ]); + } + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Make a databox indexable + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function setIndexable(Request $request, $databox_id) + { + $success = false; + + try { + $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' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful update') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, + ]); + } + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Update databox CGU's + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return RedirectResponse + */ + public function updateDatabaseCGU(Request $request, $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 $this->app->redirectPath('admin_database_display_cgus', [ + 'databox_id' => $databox_id, + 'success' => 0, + ]); + } + + return $this->app->redirectPath('admin_database_display_cgus', [ + 'databox_id' => $databox_id, + 'success' => 1, + ]); + } + + /** + * Mount a collection on a databox + * + * @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(Request $request, $databox_id, $collection_id) + { + $connection = $this->getApplicationBox()->get_connection(); + $connection->beginTransaction(); + try { + /** @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) { + /** @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) { + $aclProvider->get($user)->duplicate_right_from_bas($othCollSel, $baseId); + } + + $n += 50; + } + } + + $connection->commit(); + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'mount' => 'ok', + ]); + } catch (\Exception $e) { + $connection->rollBack(); + + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'mount' => 'ko', + ]); + } + } + + /** + * Set a new logo for a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return RedirectResponse + */ + public function sendLogoPdf(Request $request, $databox_id) + { + try { + if (null !== ($file = $request->files->get('newLogoPdf')) && $file->isValid()) { + + if ($file->getClientSize() < 65536) { + $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 $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '1', + ]); + } else { + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-too-big', + ]); + } + } else { + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-invalid', + ]); + } + } catch (\Exception $e) { + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'success' => '0', + 'error' => 'file-error', + ]); + } + } + + /** + * Delete an existing logo for a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function deleteLogoPdf(Request $request, $databox_id) + { + $success = false; + + try { + $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' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $success ? $this->app->trans('Successful removal') : $this->app->trans('An error occured'), + 'sbas_id' => $databox_id, + ]); + } + + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Clear databox logs + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function clearLogs(Request $request, $databox_id) + { + $success = false; + + try { + $this->findDataboxById($databox_id)->clear_logs(); + $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'), + 'sbas_id' => $databox_id, + ]); + } + + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Change the name of a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function changeViewName(Request $request, $databox_id) + { + if (null === $viewName = $request->request->get('viewname')) { + $this->app->abort(400, $this->app->trans('Missing view name parameter')); + } + + $success = false; + + try { + $this->findDataboxById($databox_id)->set_viewname($viewName); + $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'), + 'sbas_id' => $databox_id, + ]); + } + + // TODO: Check whether html call is still valid + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Unmount a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function unmountDatabase(Request $request, $databox_id) + { + $success = false; + + try { + $databox = $this->findDataboxById($databox_id); + $databox->unmount_databox(); + + $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, + 'sbas_id' => $databox_id + ]); + } + + return $this->app->redirectPath('admin_databases', [ + 'reload-tree' => 1, + ]); + } + + /** + * Empty a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function emptyDatabase(Request $request, $databox_id) + { + $msg = $this->app->trans('An error occurred'); + $success = false; + $taskCreated = false; + + try { + $databox = $this->findDataboxById($databox_id); + + foreach ($databox->get_collections() as $collection) { + if ($collection->get_record_amount() <= 500) { + $collection->empty_collection(500); + } else { + /** @var TaskManipulator $taskManipulator */ + $taskManipulator = $this->app['manipulator.task']; + $taskManipulator->createEmptyCollectionJob($collection); + } + } + + $msg = $this->app->trans('Base empty successful'); + $success = true; + + if ($taskCreated) { + $msg = $this->app->trans('A task has been created, please run it to complete empty collection'); + } + } catch (\Exception $e) { + + } + + if ('json' === $request->getRequestFormat()) { + return $this->app->json([ + 'success' => $success, + 'msg' => $msg, + 'sbas_id' => $databox_id, + ]); + } + + // TODO: Can this method be called as HTML? + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox_id, + 'error' => 'file-too-big', + ]); + } + + /** + * Get number of indexed items for a databox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse + */ + public function progressBarInfos(Request $request, $databox_id) + { + if (!$request->isXmlHttpRequest() || 'json' !== $request->getRequestFormat()) { + $this->app->abort(400, $this->app->trans('Bad request format, only JSON is allowed')); + } + + $appbox = $this->getApplicationBox(); + + $ret = [ + 'success' => false, + 'msg' => $this->app->trans('An error occured'), + 'sbas_id' => null, + 'indexable' => false, + 'records' => 0, + 'xml_indexed' => 0, + 'thesaurus_indexed' => 0, + 'viewname' => null, + 'printLogoURL' => null, + ]; + + try { + $databox = $this->findDataboxById($databox_id); + $data = $databox->get_indexed_record_amount(); + + $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'] = $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'] = $this->app->trans('Successful update'); + } catch (\Exception $e) { + + } + + return $this->app->json($ret); + } + + /** + * Display page for reorder collections on a databox + * + * @param integer $databox_id The requested databox + * @return Response + */ + public function getReorder($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 Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return JsonResponse|RedirectResponse + */ + public function setReorder(Request $request, $databox_id) + { + try { + foreach ($request->request->get('order', []) as $data) { + $collection = \collection::get_from_base_id($this->app, $data['id']); + $collection->set_ord($data['offset']); + } + $success = true; + } 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'), + 'sbas_id' => $databox_id, + ]); + } + + return $this->app->redirectPath('admin_database_display_collections_order', [ + 'databox_id' => $databox_id, + 'success' => (int) $success, + ]); + } + + /** + * Display page to create a new collection + * + * @return Response + */ + public function getNewCollection() + { + return $this->render('admin/collection/create.html.twig'); + } + + /** + * Create a new collection + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function createCollection(Request $request, $databox_id) + { + if (($name = trim($request->request->get('name', ''))) === '') { + return $this->app->redirectPath('admin_database_display_new_collection_form', [ + 'databox_id' => $databox_id, + 'error' => 'name', + ]); + } + + try { + $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'))) { + /** @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) { + $this->getAclForUser($user)->duplicate_right_from_bas($othcollsel, $collection->get_base_id()); + } + $n += 20; + } + } + + return $this->app->redirectPath('admin_display_collection', [ + 'bas_id' => $collection->get_base_id(), + 'success' => 1, + 'reload-tree' => 1, + ]); + } catch (\Exception $e) { + return $this->app->redirectPath('admin_database_submit_collection', [ + 'databox_id' => $databox_id, + 'error' => 'error', + ]); + } + } + + /** + * Display page to get some details on a appbox + * + * @param Request $request The current HTTP request + * @param integer $databox_id The requested databox + * @return Response + */ + public function getDetails(Request $request, $databox_id) + { + $databox = $this->findDataboxById($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 $this->render('admin/databox/details.html.twig', [ + 'databox' => $databox, + 'table' => $details, + 'total' => $total + ]); + } +} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php b/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php deleted file mode 100644 index b2f78f8cd4..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php +++ /dev/null @@ -1,277 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall']->requireAccessToModule('admin'); - }); - - $controllers->get('/', 'controller.admin.databoxes:getDatabases') - ->bind('admin_databases'); - - $controllers->post('/', 'controller.admin.databoxes:createDatabase') - ->bind('admin_database_new') - ->before(function (Request $request) use ($app) { - $app['firewall']->requireAdmin(); - }); - - $controllers->post('/mount/', 'controller.admin.databoxes:databaseMount') - ->bind('admin_database_mount') - ->before(function (Request $request) use ($app) { - $app['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/Controller/Admin/DataboxesController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php new file mode 100644 index 0000000000..a13a62197d --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php @@ -0,0 +1,266 @@ +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']); + } +} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Fields.php b/lib/Alchemy/Phrasea/Controller/Admin/Fields.php deleted file mode 100644 index bbbbf967fb..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Fields.php +++ /dev/null @@ -1,403 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) use ($app) { - $app['firewall'] - ->requireAccessToModule('admin') - ->requireRight('bas_modify_struct'); - }); - - $controllers->get('/language.json', 'admin.fields.controller:getLanguage') - ->bind('admin_fields_language'); - - $controllers->get('/{sbas_id}', 'admin.fields.controller:displayApp') - ->assert('sbas_id', '\d+') - ->bind('admin_fields'); - - $controllers->put('/{sbas_id}/fields', 'admin.fields.controller:updateFields') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_register'); - - $controllers->get('/{sbas_id}/fields', 'admin.fields.controller:listFields') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_list'); - - $controllers->post('/{sbas_id}/fields', 'admin.fields.controller:createField') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_create_field'); - - $controllers->get('/{sbas_id}/fields/{id}', 'admin.fields.controller:getField') - ->assert('id', '\d+') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_show_field'); - - $controllers->put('/{sbas_id}/fields/{id}', 'admin.fields.controller:updateField') - ->assert('id', '\d+') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_update_field'); - - $controllers->delete('/{sbas_id}/fields/{id}', 'admin.fields.controller:deleteField') - ->assert('id', '\d+') - ->assert('sbas_id', '\d+') - ->bind('admin_fields_delete_field'); - - $controllers->get('/tags/search', 'admin.fields.controller:searchTag') - ->bind('admin_fields_search_tag'); - - $controllers->get('/tags/{tagname}', 'admin.fields.controller:getTag') - ->bind('admin_fields_show_tag'); - - $controllers->get('/vocabularies', 'admin.fields.controller:listVocabularies') - ->bind('admin_fields_list_vocabularies'); - - $controllers->get('/vocabularies/{type}', 'admin.fields.controller:getVocabulary') - ->bind('admin_fields_show_vocabulary'); - - $controllers->get('/dc-fields', 'admin.fields.controller:listDcFields') - ->bind('admin_fields_list_dc_fields'); - - $controllers->get('/dc-fields/{name}', 'admin.fields.controller: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; - } -} diff --git a/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php new file mode 100644 index 0000000000..d0b14b2d8f --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/FieldsController.php @@ -0,0 +1,337 @@ +findDataboxById((int) $sbas_id); + $metaStructure = $databox->get_meta_structure(); + $connection = $databox->get_connection(); + $data = $this->getFieldsJsonFromRequest($request); + + $connection->beginTransaction(); + + foreach ($data as $jsonField) { + try { + $field = \databox_field::get_instance($this->app, $databox, $jsonField['id']); + + if ($field->get_name() !== $jsonField['name']) { + $this->validateNameField($metaStructure, $jsonField); + } + + $this->validateTagField($jsonField); + + $this->updateFieldWithData($field, $jsonField); + $field->save(); + $fields[] = $field->toArray(); + } catch (\Exception $e) { + $connection->rollback(); + $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 $this->app->json($fields); + } + + public function getLanguage() + { + 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($sbas_id) + { + $languages = []; + + foreach ($this->app['locales.available'] as $code => $language) { + $data = explode('_', $code); + $languages[$data[0]] = $language; + } + + return $this->render('/admin/fields/index.html.twig', [ + 'sbas_id' => $sbas_id, + 'languages' => $languages, + ]); + } + + public function listDcFields() + { + $data = $this->app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json'); + + return new Response($data, 200, ['content-type' => 'application/json']); + } + + public function listVocabularies() + { + $vocabularies = VocabularyController::getAvailable($this->app); + + return $this->app->json(array_map(function (ControlProviderInterface $vocabulary) { + return [ + 'type' => $vocabulary->getType(), + 'name' => $vocabulary->getName(), + ]; + }, $vocabularies)); + } + + public function getVocabulary($type) + { + $vocabulary = VocabularyController::get($this->app, $type); + + return $this->app->json([ + 'type' => $vocabulary->getType(), + 'name' => $vocabulary->getName(), + ]); + } + + public function searchTag(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 $this->app->json($res); + } + + public function getTag($tagname) + { + $tag = \databox_field::loadClassFromTagName($tagname); + $json = $this->app['serializer']->serialize($tag, 'json'); + + return new Response($json, 200, ['Content-Type' => 'application/json']); + } + + public function createField(Request $request, $sbas_id) + { + $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($this->app, $databox, $data['name'], $data['multi']); + $this->updateFieldWithData($field, $data); + $field->save(); + } catch (\Exception $e) { + throw new HttpException(500, $this->app->trans( + 'Field %name% could not be created, please try again or contact an admin.', + ['%name%' => $data['name']] + )); + } + + return $this->app->json($field->toArray(), 201, [ + 'location' => $this->app->path('admin_fields_show_field', [ + 'sbas_id' => $sbas_id, + 'id' => $field->get_id(), + ])]); + } + + public function listFields($sbas_id) + { + $databox = $this->findDataboxById((int) $sbas_id); + + return $this->app->json($databox->get_meta_structure()->toArray()); + } + + public function getField($sbas_id, $id) + { + $databox = $this->findDataboxById((int) $sbas_id); + $field = \databox_field::get_instance($this->app, $databox, $id); + + return $this->app->json($field->toArray()); + } + + public function updateField(Request $request, $sbas_id, $id) + { + $databox = $this->findDataboxById((int) $sbas_id); + $field = \databox_field::get_instance($this->app, $databox, $id); + $data = $this->getFieldJsonFromRequest($request); + + $this->validateTagField($data); + + if ($field->get_name() !== $data['name']) { + $metaStructure = $databox->get_meta_structure(); + $this->validateNameField($metaStructure, $data); + } + + $this->updateFieldWithData($field, $data); + $field->save(); + + return $this->app->json($field->toArray()); + } + + public function deleteField($sbas_id, $id) + { + $databox = $this->findDataboxById((int) $sbas_id); + \databox_field::get_instance($this->app, $databox, $id)->delete(); + + return new Response('', 204); + } + + private function getFieldJsonFromRequest(Request $request) + { + $data = $this->requestBodyToJson($request); + $required = $this->getMandatoryFieldProperties(); + + foreach ($required as $key) { + if (false === array_key_exists($key, $data)) { + $this->app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + } + } + + return $data; + } + + private function getFieldsJsonFromRequest(Request $request) + { + $data = $this->requestBodyToJson($request); + $required = $this->getMandatoryFieldProperties(); + + foreach ($data as $field) { + foreach ($required as $key) { + if (false === array_key_exists($key, $field)) { + $this->app->abort(400, sprintf('The entity must contain a key `%s`', $key)); + } + } + } + + return $data; + } + + private function updateFieldWithData(\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($this->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/Controller/Admin/UserController.php b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php new file mode 100644 index 0000000000..7dfc23f3e6 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Admin/UserController.php @@ -0,0 +1,1035 @@ +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 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; + } + + /** + * @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; + } + + /** + * @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/Controller/Admin/Users.php b/lib/Alchemy/Phrasea/Controller/Admin/Users.php deleted file mode 100644 index 70702c73ec..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Admin/Users.php +++ /dev/null @@ -1,916 +0,0 @@ -addMandatoryAuthentication($controllers); - - $controllers->before(function (Request $request) 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'); - - 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/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/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/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/Datafiles.php b/lib/Alchemy/Phrasea/Controller/Datafiles.php deleted file mode 100644 index a7a03906a7..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Datafiles.php +++ /dev/null @@ -1,108 +0,0 @@ -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); - }) - ->bind('datafile') - ->assert('sbas_id', '\d+') - ->assert('record_id', '\d+'); - - return $controllers; - } -} diff --git a/lib/Alchemy/Phrasea/Controller/Lightbox.php b/lib/Alchemy/Phrasea/Controller/Lightbox.php deleted file mode 100644 index 9434052482..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Lightbox.php +++ /dev/null @@ -1,486 +0,0 @@ -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; - } - }); - - $app['firewall']->addMandatoryAuthentication($controllers); - - $controllers - // Silex\Route::convert is not used as this should be done prior the before middleware - ->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'); - } - - $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); - }) - ->bind('lightbox_ajax_note_form') - ->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); - } - }) - ->bind('lightbox_ajax_load_basketelement') - ->assert('sselcont_id', '\d+'); - - $controllers->get('/ajax/LOAD_FEED_ITEM/{entry_id}/{item_id}/', function (SilexApplication $app, $entry_id, $item_id) { - - $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); - } - }) - ->bind('lightbox_ajax_load_feeditem') - ->assert('entry_id', '\d+') - ->assert('item_id', '\d+'); - - $controllers->get('/validate/{basket}/', function (SilexApplication $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; - }) - ->bind('lightbox_validation') - ->assert('basket', '\d+'); - - $controllers->get('/compare/{basket}/', function (SilexApplication $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; - }) - ->bind('lightbox_compare') - ->assert('basket', '\d+'); - - $controllers->get('/feeds/entry/{entry_id}/', function (SilexApplication $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; - }) - ->bind('lightbox_feed_entry') - ->assert('entry_id', '\d+'); - - $controllers->get('/ajax/LOAD_REPORT/{basket}/', function (SilexApplication $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) { - $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); - }) - ->bind('lightbox_ajax_set_note') - ->assert('sselcont_id', '\d+'); - - $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) { - $request = $app['request']; - $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); - }) - ->bind('lightbox_ajax_set_element_agreement') - ->assert('sselcont_id', '\d+'); - - $controllers->post('/ajax/SET_RELEASE/{basket}/', function (SilexApplication $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); - }) - ->bind('lightbox_ajax_set_release') - ->assert('basket', '\d+'); - - return $controllers; - } -} diff --git a/lib/Alchemy/Phrasea/Controller/LightboxController.php b/lib/Alchemy/Phrasea/Controller/LightboxController.php new file mode 100644 index 0000000000..d30eb147de --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/LightboxController.php @@ -0,0 +1,470 @@ +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->getAuthenticatedUser()), + $repository->findActiveValidationByUser($this->getAuthenticatedUser()) + ); + + $template = $this->isBrowserNewGenerationOrMobile() + ? 'lightbox/index.html.twig' + : 'lightbox/IE6/index.html.twig'; + + return $this->renderResponse($template, [ + 'baskets_collection' => $basket_collection, + 'module_name' => 'Lightbox', + 'module' => 'lightbox', + ]); + } + + /** + * @param int $sselcont_id + * @return Response + */ + 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->getAuthenticatedUser()); + + 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->getAuthenticatedUser()); + + if ($this->app['browser']->isMobile()) { + return $this->renderResponse('lightbox/basket_element.html.twig', [ + 'basket_element' => $basketElement, + 'module_name' => $basketElement->getRecord($this->app)->get_title() + ]); + } + + $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'] = $this->render( + 'common/preview.html.twig', + ['record' => $basketElement->getRecord($this->app), 'not_wrapped' => true] + ); + $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'] = $this->render( + $isNewGenerationBrowser ? 'lightbox/agreement_box.html.twig' : 'lightbox/IE6/agreement_box.html.twig', + ['basket' => $basket, 'basket_element' => $basketElement] + ); + $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); + } + + /** + * @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/Controller/Minifier.php b/lib/Alchemy/Phrasea/Controller/Minifier.php deleted file mode 100644 index fe471634c1..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Minifier.php +++ /dev/null @@ -1,150 +0,0 @@ -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'); - - return $controllers; - } -} 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/Controller/Permalink.php b/lib/Alchemy/Phrasea/Controller/Permalink.php deleted file mode 100644 index f86a45196b..0000000000 --- a/lib/Alchemy/Phrasea/Controller/Permalink.php +++ /dev/null @@ -1,197 +0,0 @@ -get('/v1/{sbas_id}/{record_id}/caption/', 'controller.permalink:deliverCaption') - ->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'); - - $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:deliverPermaview') - ->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+'); - - $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+'); - - $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:getOptionsResponse') - ->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+'); - - 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; - } -} diff --git a/lib/Alchemy/Phrasea/Controller/PermalinkController.php b/lib/Alchemy/Phrasea/Controller/PermalinkController.php new file mode 100644 index 0000000000..37fd8a5cd6 --- /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($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($sbas_id, $record_id, $request->query->get('token'), $subdef); + } + + public function deliverPermaviewOldWay($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) + { + 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/Controller/Setup.php b/lib/Alchemy/Phrasea/Controller/SetupController.php similarity index 59% rename from lib/Alchemy/Phrasea/Controller/Setup.php rename to lib/Alchemy/Phrasea/Controller/SetupController.php index 7dc349f001..937db64b10 100644 --- a/lib/Alchemy/Phrasea/Controller/Setup.php +++ b/lib/Alchemy/Phrasea/Controller/SetupController.php @@ -1,5 +1,4 @@ get('/', function (Application $app) { - return $app->redirectPath('install_root'); - })->bind('setup'); - - $controllers->get('/installer/', 'controller.setup:rootInstaller') - ->bind('install_root'); - - $controllers->get('/upgrade-instructions/', 'controller.setup:displayUpgradeInstructions') - ->bind('setup_upgrade_instructions'); - - $controllers->get('/installer/step2/', 'controller.setup:getInstallForm') - ->bind('install_step2'); - - $controllers->post('/installer/install/', 'controller.setup:doInstall') - ->bind('install_do_install'); - - $controllers->get('/connection_test/mysql/', function (Application $app, Request $request) { - $dbHelper = new DatabaseHelper($app, $request); - - return $app->json($dbHelper->checkConnection()); - }); - - $controllers->get('/test/path/', function (Application $app, Request $request) { - $pathHelper = new PathHelper($app, $request); - - return $app->json($pathHelper->checkPath()); - }); - - $controllers->get('/test/url/', function (Application $app, Request $request) { - $pathHelper = new PathHelper($app, $request); - - return $app->json($pathHelper->checkUrl()); - }); - - return $controllers; - } - - public function rootInstaller(Application $app, Request $request) + public function rootInstaller(Request $request) { $requirementsCollection = $this->getRequirementsCollection(); - return $app['twig']->render('/setup/index.html.twig', [ - 'locale' => $app['locale'], + 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 [ @@ -91,20 +49,19 @@ class Setup implements ControllerProviderInterface ]; } - public function displayUpgradeInstructions(Application $app, Request $request) + public function displayUpgradeInstructions() { - return $app['twig']->render('/setup/upgrade-instructions.html.twig', [ - 'locale' => $app['locale'], + return $this->render('/setup/upgrade-instructions.html.twig', [ + 'locale' => $this->app['locale'], 'available_locales' => Application::getAvailableLanguages(), ]); } - public function getInstallForm(Application $app, Request $request) + public function getInstallForm(Request $request) { $warnings = []; $requirementsCollection = $this->getRequirementsCollection(); - foreach ($requirementsCollection as $requirements) { foreach ($requirements->getRequirements() as $requirement) { if (!$requirement->isFulfilled() && !$requirement->isOptional()) { @@ -114,11 +71,11 @@ class Setup implements ControllerProviderInterface } if ($request->getScheme() == 'http') { - $warnings[] = $app->trans('It is not recommended to install Phraseanet without HTTPS support'); + $warnings[] = $this->app->trans('It is not recommended to install Phraseanet without HTTPS support'); } - return $app['twig']->render('/setup/step2.html.twig', [ - 'locale' => $app['locale'], + return $this->render('/setup/step2.html.twig', [ + 'locale' => $this->app['locale'], 'available_locales' => Application::getAvailableLanguages(), 'available_templates' => ['en', 'fr'], 'warnings' => $warnings, @@ -129,13 +86,13 @@ class Setup implements ControllerProviderInterface ]); } - public function doInstall(Application $app, Request $request) + public function doInstall(Request $request) { set_time_limit(360); $servername = $request->getScheme() . '://' . $request->getHttpHost() . '/'; - $abConn = $dbConn = null; + $dbConn = null; $database_host = $request->request->get('hostname'); $database_port = $request->request->get('port'); @@ -154,11 +111,12 @@ class Setup implements ControllerProviderInterface 'dbname' => $appbox_name, ]; - $abConn = $app['dbal.provider']($abInfo); + /** @var Connection $abConn */ + $abConn = $this->app['dbal.provider']($abInfo); $abConn->connect(); } catch (\Exception $e) { - return $app->redirectPath('install_step2', [ - 'error' => $app->trans('Appbox is unreachable'), + return $this->app->redirectPath('install_step2', [ + 'error' => $this->app->trans('Appbox is unreachable'), ]); } @@ -172,24 +130,25 @@ class Setup implements ControllerProviderInterface 'dbname' => $databox_name, ]; - $dbConn = $app['dbal.provider']($dbInfo); + /** @var Connection $dbConn */ + $dbConn = $this->app['dbal.provider']($dbInfo); $dbConn->connect(); } } catch (\Exception $e) { - return $app->redirectPath('install_step2', [ - 'error' => $app->trans('Databox is unreachable'), + return $this->app->redirectPath('install_step2', [ + 'error' => $this->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'] + $this->app['dbs.options'] = array_merge( + $this->app['db.options.from_info']($dbInfo), + $this->app['db.options.from_info']($abInfo), + $this->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'] + $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'); @@ -198,7 +157,7 @@ class Setup implements ControllerProviderInterface $dataPath = $request->request->get('datapath_noweb'); try { - $installer = $app['phraseanet.installer']; + $installer = $this->app['phraseanet.installer']; $installer->setPhraseaIndexerPath($request->request->get('binary_phraseanet_indexer')); $binaryData = []; @@ -212,21 +171,21 @@ class Setup implements ControllerProviderInterface 'mp4box_binary' => $request->request->get('binary_MP4Box'), 'pdftotext_binary' => $request->request->get('binary_xpdf'), 'recess_binary' => $request->request->get('binary_recess'), - ] as $key => $path) { + ] as $key => $path) { $binaryData[$key] = $path; } $user = $installer->install($email, $password, $abConn, $servername, $dataPath, $dbConn, $template, $binaryData); - $app['authentication']->openAccount($user); + $this->app['authentication']->openAccount($user); - return $app->redirectPath('admin', [ + return $this->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()]), + return $this->app->redirectPath('install_step2', [ + 'error' => $this->app->trans('an error occured : %message%', ['%message%' => $e->getMessage()]), ]); } } diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php new file mode 100644 index 0000000000..d6fd6f8110 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Collection.php @@ -0,0 +1,123 @@ +share(function (PhraseaApplication $app) { + return new CollectionController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $app['firewall']->addMandatoryAuthentication($controllers); + + $controllers->before(function () use ($app) { + $app['firewall']->requireAccessToModule('admin') + ->requireRightOnBase($app['request']->attributes->get('bas_id'), 'canadmin'); + }); + + $controllers->get('/{bas_id}/', 'controller.admin.collection:getCollection') + ->assert('bas_id', '\d+') + ->bind('admin_display_collection'); + + $controllers->get('/{bas_id}/suggested-values/', 'controller.admin.collection:getSuggestedValues') + ->assert('bas_id', '\d+') + ->bind('admin_collection_display_suggested_values'); + + $controllers->post('/{bas_id}/suggested-values/', 'controller.admin.collection:submitSuggestedValues') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_suggested_values'); + + $controllers->post('/{bas_id}/delete/', 'controller.admin.collection:delete') + ->assert('bas_id', '\d+') + ->bind('admin_collection_delete'); + + $controllers->post('/{bas_id}/enable/', 'controller.admin.collection:enable') + ->assert('bas_id', '\d+') + ->bind('admin_collection_enable'); + + $controllers->post('/{bas_id}/disabled/', 'controller.admin.collection:disabled') + ->assert('bas_id', '\d+') + ->bind('admin_collection_disable'); + + $controllers->post('/{bas_id}/order/admins/', 'controller.admin.collection:setOrderAdmins') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_order_admins'); + + $controllers->post('/{bas_id}/publication/display/', 'controller.admin.collection:setPublicationDisplay') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_publication'); + + $controllers->post('/{bas_id}/rename/', 'controller.admin.collection:rename') + ->assert('bas_id', '\d+') + ->bind('admin_collection_rename'); + + $controllers->post('/{bas_id}/labels/', 'controller.admin.collection:labels') + ->assert('bas_id', '\d+') + ->bind('admin_collection_labels'); + + $controllers->post('/{bas_id}/empty/', 'controller.admin.collection:emptyCollection') + ->assert('bas_id', '\d+') + ->bind('admin_collection_empty'); + + $controllers->post('/{bas_id}/unmount/', 'controller.admin.collection:unmount') + ->assert('bas_id', '\d+') + ->bind('admin_collection_unmount'); + + $controllers->post('/{bas_id}/picture/mini-logo/', 'controller.admin.collection:setMiniLogo') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_logo'); + + $controllers->post('/{bas_id}/picture/mini-logo/delete/', 'controller.admin.collection:deleteLogo') + ->assert('bas_id', '\d+') + ->bind('admin_collection_delete_logo'); + + $controllers->post('/{bas_id}/picture/watermark/', 'controller.admin.collection:setWatermark') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_watermark'); + + $controllers->post('/{bas_id}/picture/watermark/delete/', 'controller.admin.collection:deleteWatermark') + ->assert('bas_id', '\d+') + ->bind('admin_collection_delete_watermark'); + + $controllers->post('/{bas_id}/picture/stamp-logo/', 'controller.admin.collection:setStamp') + ->assert('bas_id', '\d+') + ->bind('admin_collection_submit_stamp'); + + $controllers->post('/{bas_id}/picture/stamp-logo/delete/', 'controller.admin.collection:deleteStamp') + ->assert('bas_id', '\d+') + ->bind('admin_collection_delete_stamp'); + $controllers->get('/{bas_id}/informations/details/', 'controller.admin.collection:getDetails') + ->assert('bas_id', '\d+') + ->bind('admin_collection_display_document_details'); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php new file mode 100644 index 0000000000..e30460e433 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/ConnectedUsers.php @@ -0,0 +1,60 @@ +share(function (PhraseaApplication $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) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $app['firewall']->addMandatoryAuthentication($controllers); + + $controllers->before(function () use ($app) { + $app['firewall']->requireAccessToModule('Admin'); + }); + + $controllers->get('/', 'controller.admin.connected-users:listConnectedUsers') + ->bind('admin_connected_users'); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php new file mode 100644 index 0000000000..700a4833b5 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Dashboard.php @@ -0,0 +1,60 @@ +share(function (PhraseaApplication $app) { + return new DashboardController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $controllers->before(function () use ($app) { + $app['firewall']->requireAdmin(); + }); + + $controllers->get('/', 'controller.admin.dashboard:slash') + ->bind('admin_dashboard'); + + $controllers->post('/flush-cache/', 'controller.admin.dashboard:flush') + ->bind('admin_dashboard_flush_cache'); + + $controllers->post('/send-mail-test/', 'controller.admin.dashboard:sendMail') + ->bind('admin_dashboard_test_mail'); + + $controllers->post('/reset-admin-rights/', 'controller.admin.dashboard:resetAdminRights') + ->bind('admin_dashboard_reset_admin_rights'); + + $controllers->post('/add-admins/', 'controller.admin.dashboard:addAdmins') + ->bind('admin_dashboard_add_admins'); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php new file mode 100644 index 0000000000..91301a1732 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databox.php @@ -0,0 +1,152 @@ +share(function (PhraseaApplication $app) { + return new DataboxController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @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')); + }) + ->assert('databox_id', '\d+') + ; + + $controllers->get('/{databox_id}/', 'controller.admin.databox:getDatabase') + ->bind('admin_database'); + + $controllers->post('/{databox_id}/delete/', 'controller.admin.databox:deleteBase') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_delete'); + + $controllers->post('/{databox_id}/unmount/', 'controller.admin.databox:unmountDatabase') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_unmount'); + + $controllers->post('/{databox_id}/empty/', 'controller.admin.databox:emptyDatabase') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_empty'); + + $controllers->get('/{databox_id}/collections/order/', 'controller.admin.databox:getReorder') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_collections_order'); + + $controllers->post('/{databox_id}/collections/order/', 'controller.admin.databox:setReorder') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_submit_collections_order'); + + $controllers->post('/{databox_id}/collection/', 'controller.admin.databox:createCollection') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_submit_collection'); + + $controllers->get('/{databox_id}/cgus/', 'controller.admin.databox:getDatabaseCGU') + ->before([$this, 'requireChangeSbasStructureRight']) + ->bind('admin_database_display_cgus'); + + $controllers->post('/{databox_id}/labels/', 'controller.admin.databox:setLabels') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_databox_labels'); + + $controllers->post('/{databox_id}/cgus/', 'controller.admin.databox:updateDatabaseCGU') + ->before([$this, 'requireChangeSbasStructureRight']) + ->bind('admin_database_submit_cgus'); + + $controllers->get('/{databox_id}/informations/documents/', 'controller.admin.databox:progressBarInfos') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_document_information'); + + $controllers->get('/{databox_id}/informations/details/', 'controller.admin.databox:getDetails') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_document_details'); + + $controllers->post('/{databox_id}/collection/{collection_id}/mount/', 'controller.admin.databox:mountCollection') + ->assert('collection_id', '\d+') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_mount_collection'); + + $controllers->get('/{databox_id}/collection/', 'controller.admin.databox:getNewCollection') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_display_new_collection_form'); + + $controllers->post('/{databox_id}/logo/', 'controller.admin.databox:sendLogoPdf') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_submit_logo'); + + $controllers->post('/{databox_id}/logo/delete/', 'controller.admin.databox:deleteLogoPdf') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_delete_logo'); + + $controllers->post('/{databox_id}/clear-logs/', 'controller.admin.databox:clearLogs') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_clear_logs'); + + $controllers->post('/{databox_id}/reindex/', 'controller.admin.databox:reindex') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_reindex'); + + $controllers->post('/{databox_id}/indexable/', 'controller.admin.databox:setIndexable') + ->before([$this, 'requireManageRightOnSbas']) + ->bind('admin_database_set_indexable'); + + $controllers->post('/{databox_id}/view-name/', 'controller.admin.databox:changeViewName') + ->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 + * @return Firewall + */ + private function getFirewall(Application $app) + { + return $app['firewall']; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php new file mode 100644 index 0000000000..b99d79ecb0 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Databoxes.php @@ -0,0 +1,65 @@ +share(function (PhraseaApplication $app) { + return new DataboxesController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + /** @var Firewall $firewall */ + $firewall = $app['firewall']; + $firewall->addMandatoryAuthentication($controllers); + + $controllers->before(function () use ($firewall) { + $firewall->requireAccessToModule('admin'); + }); + + $controllers->get('/', 'controller.admin.databoxes:getDatabases') + ->bind('admin_databases'); + + $controllers->post('/', 'controller.admin.databoxes:createDatabase') + ->bind('admin_database_new') + ->before(function () use ($firewall) { + $firewall->requireAdmin(); + }); + + $controllers->post('/mount/', 'controller.admin.databoxes:databaseMount') + ->bind('admin_database_mount') + ->before(function () use ($firewall) { + $firewall->requireAdmin(); + }); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php new file mode 100644 index 0000000000..8dae2e0cad --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Fields.php @@ -0,0 +1,104 @@ +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']; + + /** @var Firewall $firewall */ + $firewall = $app['firewall']; + $firewall->addMandatoryAuthentication($controllers); + + $controllers->before(function () use ($firewall) { + $firewall + ->requireAccessToModule('admin') + ->requireRight('bas_modify_struct'); + }); + + $controllers->get('/language.json', 'controller.admin.fields:getLanguage') + ->bind('admin_fields_language'); + + $controllers->get('/{sbas_id}', 'controller.admin.fields:displayApp') + ->assert('sbas_id', '\d+') + ->bind('admin_fields'); + + $controllers->put('/{sbas_id}/fields', 'controller.admin.fields:updateFields') + ->assert('sbas_id', '\d+') + ->bind('admin_fields_register'); + + $controllers->get('/{sbas_id}/fields', 'controller.admin.fields:listFields') + ->assert('sbas_id', '\d+') + ->bind('admin_fields_list'); + + $controllers->post('/{sbas_id}/fields', 'controller.admin.fields:createField') + ->assert('sbas_id', '\d+') + ->bind('admin_fields_create_field'); + + $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}', 'controller.admin.fields:updateField') + ->assert('id', '\d+') + ->assert('sbas_id', '\d+') + ->bind('admin_fields_update_field'); + + $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', 'controller.admin.fields:searchTag') + ->bind('admin_fields_search_tag'); + + $controllers->get('/tags/{tagname}', 'controller.admin.fields:getTag') + ->bind('admin_fields_show_tag'); + + $controllers->get('/vocabularies', 'controller.admin.fields:listVocabularies') + ->bind('admin_fields_list_vocabularies'); + + $controllers->get('/vocabularies/{type}', 'controller.admin.fields:getVocabulary') + ->bind('admin_fields_show_vocabulary'); + + $controllers->get('/dc-fields', 'controller.admin.fields:listDcFields') + ->bind('admin_fields_list_dc_fields'); + + $controllers->get('/dc-fields/{name}', 'controller.admin.fields:getDcFields') + ->bind('admin_fields_get_dc_fields'); + + return $controllers; + } +} 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/ControllerProvider/Admin/Users.php b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php new file mode 100644 index 0000000000..30f1a2f89c --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Admin/Users.php @@ -0,0 +1,86 @@ +share(function () use ($app) { + return new UserController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $app['firewall']->addMandatoryAuthentication($controllers); + + $controllers->before(function () use ($app) { + $app['firewall']->requireAccessToModule('admin') + ->requireRight('manageusers'); + }); + + $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; + } +} 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/ControllerProvider/Datafiles.php b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php new file mode 100644 index 0000000000..bb30898ef3 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Datafiles.php @@ -0,0 +1,51 @@ +share(function (PhraseaApplication $app) { + return new DatafileController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + $controllers = $app['controllers_factory']; + + $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}/', 'controller.datafiles:getAction') + ->bind('datafile') + ->assert('sbas_id', '\d+') + ->assert('record_id', '\d+'); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php new file mode 100644 index 0000000000..a4b9d3b894 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Lightbox.php @@ -0,0 +1,141 @@ +share(function (PhraseaApplication $app) { + return new LightboxController($app); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + $controllers = $app['controllers_factory']; + + $controllers->before([$this, 'redirectOnLogRequests']); + + $app['firewall']->addMandatoryAuthentication($controllers); + + $controllers + // Silex\Route::convert is not used as this should be done prior the before middleware + ->before($app['middleware.basket.converter']) + ->before($app['middleware.basket.user-access']); + + $controllers->get('/', 'controller.lightbox:rootAction') + ->bind('lightbox') + ; + + $controllers->get('/ajax/NOTE_FORM/{sselcont_id}/', 'controller.lightbox:ajaxNoteFormAction') + ->bind('lightbox_ajax_note_form') + ->assert('sselcont_id', '\d+') + ; + + $controllers->get('/ajax/LOAD_BASKET_ELEMENT/{sselcont_id}/', 'controller.lightbox:ajaxLoadBasketElementAction') + ->bind('lightbox_ajax_load_basketelement') + ->assert('sselcont_id', '\d+') + ; + + $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+') + ; + + $controllers->get('/validate/{basket}/', 'controller.lightbox:validationAction') + ->bind('lightbox_validation') + ->assert('basket', '\d+') + ; + + $controllers->get('/compare/{basket}/', 'controller.lightbox:compareAction') + ->bind('lightbox_compare') + ->assert('basket', '\d+'); + + $controllers->get('/feeds/entry/{entry_id}/', 'controller.lightbox:getFeedEntryAction') + ->bind('lightbox_feed_entry') + ->assert('entry_id', '\d+') + ; + + $controllers->get('/ajax/LOAD_REPORT/{basket}/', 'controller.lightbox:ajaxReportAction') + ->bind('lightbox_ajax_report') + ->assert('basket', '\d+') + ; + + $controllers->post('/ajax/SET_NOTE/{sselcont_id}/', 'controller.lightbox:ajaxSetNoteAction') + ->bind('lightbox_ajax_set_note') + ->assert('sselcont_id', '\d+') + ; + + $controllers->post('/ajax/SET_ELEMENT_AGREEMENT/{sselcont_id}/', 'controller.lightbox:ajaxSetElementAgreementAction') + ->bind('lightbox_ajax_set_element_agreement') + ->assert('sselcont_id', '\d+') + ; + + $controllers->post('/ajax/SET_RELEASE/{basket}/', 'controller.lightbox:ajaxSetReleaseAction') + ->bind('lightbox_ajax_set_release') + ->assert('basket', '\d+') + ; + + 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/ControllerProvider/Minifier.php b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php new file mode 100644 index 0000000000..1265e0fdf3 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Minifier.php @@ -0,0 +1,49 @@ +share(function (Application $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) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $controllers->get('/', 'controller.minifier:minifyAction')->bind('minifier'); + + return $controllers; + } +} diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php new file mode 100644 index 0000000000..6bc9817e4a --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Permalink.php @@ -0,0 +1,75 @@ +share(function (PhraseaApplication $app) { + return new PermalinkController($app, $app['phraseanet.appbox'], $app['acl'], $app['authentication']); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $controllers + ->assert('sbas_id', '\d+') + ->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') + ->method('OPTIONS'); + + $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:deliverPermaview') + ->bind('permalinks_permaview'); + + $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/', 'controller.permalink:getOptionsResponse') + ->method('OPTIONS'); + + $controllers->get( + '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/view/', + 'controller.permalink:deliverPermaviewOldWay' + ) + ->bind('permalinks_permaview_old'); + + $controllers->get('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:deliverPermalink') + ->bind('permalinks_permalink'); + + $controllers->match('/v1/{sbas_id}/{record_id}/{subdef}/{label}', 'controller.permalink:getOptionsResponse') + ->method('OPTIONS'); + + $controllers->get( + '/v1/{label}/{sbas_id}/{record_id}/{token}/{subdef}/', + 'controller.permalink:deliverPermalinkOldWay' + ) + ->bind('permalinks_permalink_old'); + + return $controllers; + } +} 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/ControllerProvider/Setup.php b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php new file mode 100644 index 0000000000..7d24b304b7 --- /dev/null +++ b/lib/Alchemy/Phrasea/ControllerProvider/Setup.php @@ -0,0 +1,78 @@ +share(function (PhraseaApplication $application) { + return new SetupController($application); + }); + } + + public function boot(Application $app) + { + } + + public function connect(Application $app) + { + /** @var ControllerCollection $controllers */ + $controllers = $app['controllers_factory']; + + $controllers->get('/', function (PhraseaApplication $app) { + return $app->redirectPath('install_root'); + })->bind('setup'); + + $controllers->get('/installer/', 'controller.setup:rootInstaller') + ->bind('install_root'); + + $controllers->get('/upgrade-instructions/', 'controller.setup:displayUpgradeInstructions') + ->bind('setup_upgrade_instructions'); + + $controllers->get('/installer/step2/', 'controller.setup:getInstallForm') + ->bind('install_step2'); + + $controllers->post('/installer/install/', 'controller.setup:doInstall') + ->bind('install_do_install'); + + $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 (PhraseaApplication $app, Request $request) { + $pathHelper = new PathHelper($app, $request); + + return $app->json($pathHelper->checkPath()); + }); + + $controllers->get('/test/url/', function (PhraseaApplication $app, Request $request) { + $pathHelper = new PathHelper($app, $request); + + return $app->json($pathHelper->checkUrl()); + }); + + return $controllers; + } +} 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/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/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/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/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/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/Manipulator/ApiAccountManipulator.php b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php index d00d8855f6..86fdd4a7a2 100644 --- a/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php +++ b/lib/Alchemy/Phrasea/Model/Manipulator/ApiAccountManipulator.php @@ -11,23 +11,19 @@ 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; 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/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php index d2a65b80ed..3422629d40 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) { @@ -270,8 +270,8 @@ class BasketRepository extends EntityRepository * Return all actives validation where current user is involved and user basket * * @param User $user - * @param type $sort - * @return Array + * @param string $sort + * @return Basket[] */ public function findActiveValidationAndBasketByUser(User $user, $sort = null) { 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/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(); 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() { diff --git a/lib/classes/databox.php b/lib/classes/databox.php index ffd0f467f8..af7ed71359 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 = []; @@ -513,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())) { 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 */ 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 }} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/ConnectedUserTest.php index 5bee91e76c..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\Controller\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], + ]; + } +} 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/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()); + } +} 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/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' ) ); diff --git a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php index 5a0cd3203b..c21a870a2c 100644 --- a/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Model/Manipulator/ApiAccountManipulatorTest.php @@ -2,16 +2,25 @@ 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 { + /** @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()); } } 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