diff --git a/bin/console b/bin/console index 0fe46b128c..aebb0ead0b 100755 --- a/bin/console +++ b/bin/console @@ -26,6 +26,7 @@ use Alchemy\Phrasea\Command\WebsocketServer; use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Command\BuildMissingSubdefs; use Alchemy\Phrasea\Command\CreateCollection; +use Alchemy\Phrasea\Command\CreateDataboxCommand; use Alchemy\Phrasea\Command\MailTest; use Alchemy\Phrasea\Command\Compile\Configuration; use Alchemy\Phrasea\Command\RecordAdd; @@ -107,6 +108,7 @@ $cli->command(new \module_console_fieldsRename('fields:rename')); $cli->command(new \module_console_fieldsMerge('fields:merge')); $cli->command(new CreateCollection('collection:create')); +$cli->command(new CreateDataboxCommand('databox:create')); $cli->command(new RecordAdd('records:add')); $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas')); diff --git a/lib/Alchemy/Phrasea/Application.php b/lib/Alchemy/Phrasea/Application.php index 846c0dc99d..4970f6052a 100644 --- a/lib/Alchemy/Phrasea/Application.php +++ b/lib/Alchemy/Phrasea/Application.php @@ -48,6 +48,7 @@ use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider; use Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider; use Alchemy\Phrasea\Core\Provider\CSVServiceProvider; +use Alchemy\Phrasea\Core\Provider\DataboxServiceProvider; use Alchemy\Phrasea\Core\Provider\FeedServiceProvider; use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider; use Alchemy\Phrasea\Core\Provider\FtpServiceProvider; @@ -241,6 +242,7 @@ class Application extends SilexApplication $this->setupEventDispatcher(); + $this->register(new DataboxServiceProvider()); $this->register(new OrderServiceProvider()); $this->register(new WebhookServiceProvider()); diff --git a/lib/Alchemy/Phrasea/Command/CreateDataboxCommand.php b/lib/Alchemy/Phrasea/Command/CreateDataboxCommand.php new file mode 100644 index 0000000000..068ae5a674 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/CreateDataboxCommand.php @@ -0,0 +1,61 @@ +setName('databox:create') + ->addArgument('databox', InputArgument::REQUIRED, 'Database name for the databox', null) + ->addArgument('owner', InputArgument::REQUIRED, 'Email of the databox admin user', null) + ->addOption('connection', 'c', InputOption::VALUE_NONE, 'Flag to set new database settings') + ->addOption('db-host', null, InputOption::VALUE_OPTIONAL, 'MySQL server host', 'localhost') + ->addOption('db-port', null, InputOption::VALUE_OPTIONAL, 'MySQL server port', 3306) + ->addOption('db-user', null, InputOption::VALUE_OPTIONAL, 'MySQL server user', 'phrasea') + ->addOption('db-password', null, InputOption::VALUE_OPTIONAL, 'MySQL server password', null) + ->addOption( + 'db-template', + null, + InputOption::VALUE_OPTIONAL, + 'Metadata structure language template (available are fr (french) and en (english))', + 'fr' + ); + } + + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $databoxName = $input->getArgument('databox'); + $connectionSettings = $input->getOption('connection') == false ? null : new DataboxConnectionSettings( + $input->getOption('db-host'), + $input->getOption('db-port'), + $input->getOption('db-user'), + $input->getOption('db-password') + ); + + /** @var UserRepository $userRepository */ + $userRepository = $this->container['repo.users']; + /** @var DataboxService $databoxService */ + $databoxService = $this->container['databox.service']; + + $owner = $userRepository->findByEmail($input->getArgument('owner')); + + $databoxService->createDatabox( + $databoxName, + $input->getOption('db-template') . '-simple', + $owner, + $connectionSettings + ); + + $output->writeln('Databox created'); + } +} diff --git a/lib/Alchemy/Phrasea/Command/SearchEngine/IndexCreateCommand.php b/lib/Alchemy/Phrasea/Command/SearchEngine/IndexCreateCommand.php index 6247962b08..d4d84c15ea 100644 --- a/lib/Alchemy/Phrasea/Command/SearchEngine/IndexCreateCommand.php +++ b/lib/Alchemy/Phrasea/Command/SearchEngine/IndexCreateCommand.php @@ -22,12 +22,12 @@ class IndexCreateCommand extends Command { $this ->setName('searchengine:index:create') - ->setDescription('Creates search index') - ; + ->setDescription('Creates search index'); } protected function doExecute(InputInterface $input, OutputInterface $output) { + /** @var Indexer $indexer */ $indexer = $this->container['elasticsearch.indexer']; if ($indexer->indexExists()) { diff --git a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php index 942fb9a48e..93ad9a59a8 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/DataboxesController.php @@ -11,6 +11,8 @@ namespace Alchemy\Phrasea\Controller\Admin; use Alchemy\Phrasea\Controller\Controller; +use Alchemy\Phrasea\Databox\DataboxConnectionSettings; +use Alchemy\Phrasea\Databox\DataboxService; use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -116,82 +118,37 @@ class DataboxesController extends Controller 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']); + /** @var DataboxService $databoxService */ + $databoxService = $this->app['databox.service']; + $dataTemplate = $request->request->get('new_data_template'); - $hostname = $connexion['host']; - $port = $connexion['port']; - $user = $connexion['user']; - $password = $connexion['password']; + $connectionSettings = $request->request->get('new_settings') == false ? null : new DataboxConnectionSettings( + $request->request->get('new_hostname'), + $request->request->get('new_port'), + $request->request->get('new_user'), + $request->request->get('new_password') + ); - $dataTemplate = new \SplFileInfo($this->app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); + try { + $databox = $databoxService->createDatabox( + $dbName, + $dataTemplate, + $this->getAuthenticatedUser(), + $connectionSettings + ); - 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']); - } + return $this->app->redirectPath('admin_database', [ + 'databox_id' => $databox->get_sbas_id(), + 'success' => 1, + 'reload-tree' => 1 + ]); } - - 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']); - } + catch (DBALException $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']); + } + catch (\Exception $e) { + return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); } - - return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']); } /** diff --git a/lib/Alchemy/Phrasea/Controller/Controller.php b/lib/Alchemy/Phrasea/Controller/Controller.php index 4f477ff8de..79890b3501 100644 --- a/lib/Alchemy/Phrasea/Controller/Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Controller.php @@ -96,6 +96,7 @@ class Controller public function getAclForUser(User $user = null) { $aclProvider = $this->getAclProvider(); + if (null === $user) { $user = $this->getAuthenticatedUser(); } diff --git a/lib/Alchemy/Phrasea/Core/Provider/DataboxServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/DataboxServiceProvider.php new file mode 100644 index 0000000000..5272c1ca47 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Provider/DataboxServiceProvider.php @@ -0,0 +1,29 @@ +share(function (Application $app) { + return new DataboxService( + $app, + $app['dbal.provider'], + $app['repo.databoxes'], + $app['conf'], + $app['root.path'] + ); + }); + } + + public function boot(Application $app) + { + // TODO: Implement boot() method. + } +} diff --git a/lib/Alchemy/Phrasea/Databox/DataboxConnectionSettings.php b/lib/Alchemy/Phrasea/Databox/DataboxConnectionSettings.php new file mode 100644 index 0000000000..6b1883d0db --- /dev/null +++ b/lib/Alchemy/Phrasea/Databox/DataboxConnectionSettings.php @@ -0,0 +1,86 @@ +host = $host; + $this->port = $port; + $this->user = $user; + $this->password = $password; + } + + /** + * @return string + */ + public function getHost() + { + return $this->host; + } + + /** + * @return int + */ + public function getPort() + { + return $this->port; + } + + /** + * @return string + */ + public function getUser() + { + return $this->user; + } + + /** + * @return string + */ + public function getPassword() + { + return $this->password; + } +} diff --git a/lib/Alchemy/Phrasea/Databox/DataboxFactory.php b/lib/Alchemy/Phrasea/Databox/DataboxFactory.php index 522dd989f7..85bbf5500f 100644 --- a/lib/Alchemy/Phrasea/Databox/DataboxFactory.php +++ b/lib/Alchemy/Phrasea/Databox/DataboxFactory.php @@ -14,10 +14,14 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class DataboxFactory { - /** @var Application */ + /** + * @var Application + */ private $app; - /** @var DataboxRepository */ + /** + * @var DataboxRepository + */ private $databoxRepository; /** diff --git a/lib/Alchemy/Phrasea/Databox/DataboxService.php b/lib/Alchemy/Phrasea/Databox/DataboxService.php new file mode 100644 index 0000000000..7d45969936 --- /dev/null +++ b/lib/Alchemy/Phrasea/Databox/DataboxService.php @@ -0,0 +1,111 @@ +app = $application; + $this->connectionFactory = $connectionFactory; + $this->databoxRepository = $databoxRepository; + $this->configuration = $defaultDbConfiguration; + $this->rootPath = $rootPath; + } + + /** + * @param User $owner + * @param string $databaseName + * @param string $dataTemplate + * @param DataboxConnectionSettings|null $connectionSettings + * @return \databox + */ + public function createDatabox( + $databaseName, + $dataTemplate, + User $owner, + DataboxConnectionSettings $connectionSettings = null + ) { + $dataTemplate = new \SplFileInfo($this->rootPath . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); + $connectionSettings = $connectionSettings ?: DataboxConnectionSettings::fromArray( + $this->configuration->get(['main', 'database']) + ); + + $factory = $this->connectionFactory; + /** @var Connection $connection */ + $connection = $factory([ + 'host' => $connectionSettings->getHost(), + 'port' => $connectionSettings->getPort(), + 'user' => $connectionSettings->getUser(), + 'password' => $connectionSettings->getPassword(), + 'dbname' => $databaseName + ]); + + $connection->connect(); + + $databox = \databox::create($this->app, $connection, $dataTemplate); + $databox->registerAdmin($owner); + + $connection->close(); + + return $databox; + } + + /** + * @param $databaseName + * @param DataboxConnectionSettings $connectionSettings + * @return \databox + */ + public function mountDatabox($databaseName, DataboxConnectionSettings $connectionSettings = null) + { + $connectionSettings = $connectionSettings ?: DataboxConnectionSettings::fromArray( + $this->configuration->get(['main', 'database']) + ); + } +} diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 4346a3da04..9e8c32ad33 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -1152,17 +1152,30 @@ class databox extends base implements ThumbnailedElement $stmt->closeCursor(); $this->app->getAclForUser($user)->give_access_to_base($base_ids); + foreach ($base_ids as $base_id) { $this->app->getAclForUser($user)->update_rights_to_base($base_id, [ - 'canpush' => 1, 'cancmd' => 1 - , 'canputinalbum' => 1, 'candwnldhd' => 1, 'candwnldpreview' => 1, 'canadmin' => 1 - , 'actif' => 1, 'canreport' => 1, 'canaddrecord' => 1, 'canmodifrecord' => 1 - , 'candeleterecord' => 1, 'chgstatus' => 1, 'imgtools' => 1, 'manage' => 1 - , 'modify_struct' => 1, 'nowatermark' => 1 - ] - ); + 'canpush' => 1, + 'cancmd' => 1, + 'canputinalbum' => 1, + 'candwnldhd' => 1, + 'candwnldpreview' => 1, + 'canadmin' => 1, + 'actif' => 1, + 'canreport' => 1, + 'canaddrecord' => 1, + 'canmodifrecord' => 1, + 'candeleterecord' => 1, + 'chgstatus' => 1, + 'imgtools' => 1, + 'manage' => 1, + 'modify_struct' => 1, + 'nowatermark' => 1 + ]); } + $this->app->getAclForUser($user)->delete_data_from_cache(); + return $this; }