Add create databox console command

This commit is contained in:
Thibaud Fabre
2016-10-14 14:30:33 +02:00
parent a040dc2aea
commit efc5842e06
11 changed files with 348 additions and 82 deletions

View File

@@ -26,6 +26,7 @@ use Alchemy\Phrasea\Command\WebsocketServer;
use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Core\Version;
use Alchemy\Phrasea\Command\BuildMissingSubdefs; use Alchemy\Phrasea\Command\BuildMissingSubdefs;
use Alchemy\Phrasea\Command\CreateCollection; use Alchemy\Phrasea\Command\CreateCollection;
use Alchemy\Phrasea\Command\CreateDataboxCommand;
use Alchemy\Phrasea\Command\MailTest; use Alchemy\Phrasea\Command\MailTest;
use Alchemy\Phrasea\Command\Compile\Configuration; use Alchemy\Phrasea\Command\Compile\Configuration;
use Alchemy\Phrasea\Command\RecordAdd; 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 \module_console_fieldsMerge('fields:merge'));
$cli->command(new CreateCollection('collection:create')); $cli->command(new CreateCollection('collection:create'));
$cli->command(new CreateDataboxCommand('databox:create'));
$cli->command(new RecordAdd('records:add')); $cli->command(new RecordAdd('records:add'));
$cli->command(new RescanTechnicalDatas('records:rescan-technical-datas')); $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas'));

View File

@@ -48,6 +48,7 @@ use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider; use Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider;
use Alchemy\Phrasea\Core\Provider\CSVServiceProvider; use Alchemy\Phrasea\Core\Provider\CSVServiceProvider;
use Alchemy\Phrasea\Core\Provider\DataboxServiceProvider;
use Alchemy\Phrasea\Core\Provider\FeedServiceProvider; use Alchemy\Phrasea\Core\Provider\FeedServiceProvider;
use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider; use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider;
use Alchemy\Phrasea\Core\Provider\FtpServiceProvider; use Alchemy\Phrasea\Core\Provider\FtpServiceProvider;
@@ -241,6 +242,7 @@ class Application extends SilexApplication
$this->setupEventDispatcher(); $this->setupEventDispatcher();
$this->register(new DataboxServiceProvider());
$this->register(new OrderServiceProvider()); $this->register(new OrderServiceProvider());
$this->register(new WebhookServiceProvider()); $this->register(new WebhookServiceProvider());

View File

@@ -0,0 +1,61 @@
<?php
namespace Alchemy\Phrasea\Command;
use Alchemy\Phrasea\Databox\DataboxConnectionSettings;
use Alchemy\Phrasea\Databox\DataboxService;
use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CreateDataboxCommand extends Command
{
protected function configure()
{
$this->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');
}
}

View File

@@ -22,12 +22,12 @@ class IndexCreateCommand extends Command
{ {
$this $this
->setName('searchengine:index:create') ->setName('searchengine:index:create')
->setDescription('Creates search index') ->setDescription('Creates search index');
;
} }
protected function doExecute(InputInterface $input, OutputInterface $output) protected function doExecute(InputInterface $input, OutputInterface $output)
{ {
/** @var Indexer $indexer */
$indexer = $this->container['elasticsearch.indexer']; $indexer = $this->container['elasticsearch.indexer'];
if ($indexer->indexExists()) { if ($indexer->indexExists()) {

View File

@@ -11,6 +11,8 @@
namespace Alchemy\Phrasea\Controller\Admin; namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Databox\DataboxConnectionSettings;
use Alchemy\Phrasea\Databox\DataboxService;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -116,82 +118,37 @@ class DataboxesController extends Controller
return $this->app->redirectPath('admin_databases', ['error' => 'special-chars']); return $this->app->redirectPath('admin_databases', ['error' => 'special-chars']);
} }
if ((null === $request->request->get('new_settings')) && (null !== $dataTemplate = $request->request->get('new_data_template'))) { /** @var DataboxService $databoxService */
$connexion = $this->app['conf']->get(['main', 'database']); $databoxService = $this->app['databox.service'];
$dataTemplate = $request->request->get('new_data_template');
$hostname = $connexion['host']; $connectionSettings = $request->request->get('new_settings') == false ? null : new DataboxConnectionSettings(
$port = $connexion['port']; $request->request->get('new_hostname'),
$user = $connexion['user']; $request->request->get('new_port'),
$password = $connexion['password']; $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 { return $this->app->redirectPath('admin_database', [
/** @var Connection $connection */ 'databox_id' => $databox->get_sbas_id(),
$connection = $this->app['dbal.provider']([ 'success' => 1,
'host' => $hostname, 'reload-tree' => 1
'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']);
}
} }
catch (DBALException $e) {
if (null !== $request->request->get('new_settings') return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'database-failed']);
&& (null !== $hostname = $request->request->get('new_hostname')) }
&& (null !== $port = $request->request->get('new_port')) catch (\Exception $e) {
&& (null !== $userDb = $request->request->get('new_user')) return $this->app->redirectPath('admin_databases', ['success' => 0, 'error' => 'base-failed']);
&& (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']);
} }
/** /**

View File

@@ -96,6 +96,7 @@ class Controller
public function getAclForUser(User $user = null) public function getAclForUser(User $user = null)
{ {
$aclProvider = $this->getAclProvider(); $aclProvider = $this->getAclProvider();
if (null === $user) { if (null === $user) {
$user = $this->getAuthenticatedUser(); $user = $this->getAuthenticatedUser();
} }

View File

@@ -0,0 +1,29 @@
<?php
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Databox\DataboxService;
use Silex\Application;
use Silex\ServiceProviderInterface;
class DataboxServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['databox.service'] = $app->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.
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Alchemy\Phrasea\Databox;
class DataboxConnectionSettings
{
/**
* @param array $configuration
* @return DataboxConnectionSettings
*/
public static function fromArray(array $configuration)
{
return new self(
$configuration['host'],
$configuration['port'],
$configuration['user'],
$configuration['password']
);
}
/**
* @var string
*/
private $host;
/**
* @var int
*/
private $port;
/**
* @var string
*/
private $user;
/**
* @var string
*/
private $password;
/**
* @param string $host
* @param int $port
* @param string $user
* @param string $password
*/
public function __construct($host, $port, $user, $password)
{
$this->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;
}
}

View File

@@ -14,10 +14,14 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class DataboxFactory class DataboxFactory
{ {
/** @var Application */ /**
* @var Application
*/
private $app; private $app;
/** @var DataboxRepository */ /**
* @var DataboxRepository
*/
private $databoxRepository; private $databoxRepository;
/** /**

View File

@@ -0,0 +1,111 @@
<?php
namespace Alchemy\Phrasea\Databox;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\Model\Entities\User;
use Doctrine\DBAL\Connection;
/**
* Class DataboxService
* @package Alchemy\Phrasea\Databox
*/
class DataboxService
{
/**
* @var Application
*/
private $app;
/**
* @var PropertyAccess
*/
private $configuration;
/**
* @var callable
*/
private $connectionFactory;
/**
* @var DataboxRepository
*/
private $databoxRepository;
/**
* @var string
*/
private $rootPath;
/**
* @param Application $application
* @param callable $connectionFactory
* @param DataboxRepository $databoxRepository
* @param PropertyAccess $defaultDbConfiguration
* @param string $rootPath
*/
public function __construct(
Application $application,
callable $connectionFactory,
DataboxRepository $databoxRepository,
PropertyAccess $defaultDbConfiguration,
$rootPath
) {
$this->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'])
);
}
}

View File

@@ -1152,17 +1152,30 @@ class databox extends base implements ThumbnailedElement
$stmt->closeCursor(); $stmt->closeCursor();
$this->app->getAclForUser($user)->give_access_to_base($base_ids); $this->app->getAclForUser($user)->give_access_to_base($base_ids);
foreach ($base_ids as $base_id) { foreach ($base_ids as $base_id) {
$this->app->getAclForUser($user)->update_rights_to_base($base_id, [ $this->app->getAclForUser($user)->update_rights_to_base($base_id, [
'canpush' => 1, 'cancmd' => 1 'canpush' => 1,
, 'canputinalbum' => 1, 'candwnldhd' => 1, 'candwnldpreview' => 1, 'canadmin' => 1 'cancmd' => 1,
, 'actif' => 1, 'canreport' => 1, 'canaddrecord' => 1, 'canmodifrecord' => 1 'canputinalbum' => 1,
, 'candeleterecord' => 1, 'chgstatus' => 1, 'imgtools' => 1, 'manage' => 1 'candwnldhd' => 1,
, 'modify_struct' => 1, 'nowatermark' => 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; return $this;
} }