mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-17 23:13:15 +00:00
Merge branch 'master' into PHRAS-2739-incorporate-subdefwebhook
This commit is contained in:
@@ -14,6 +14,8 @@ namespace Alchemy\Phrasea\Border;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Border\Checker\CheckerInterface;
|
||||
use Alchemy\Phrasea\Border\Attribute\AttributeInterface;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
||||
use Alchemy\Phrasea\Metadata\Tag\TfArchivedate;
|
||||
use Alchemy\Phrasea\Metadata\Tag\TfQuarantine;
|
||||
@@ -333,7 +335,7 @@ class Manager
|
||||
$this->app['phraseanet.metadata-setter']->replaceMetadata($newMetadata, $element);
|
||||
|
||||
if(!$nosubdef) {
|
||||
$element->rebuild_subdefs();
|
||||
$this->app['dispatcher']->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($element, true));
|
||||
}
|
||||
|
||||
return $element;
|
||||
|
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class PublishCollectionCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('collection:publish');
|
||||
|
||||
$this->setDescription('Publish collection in Phraseanet')
|
||||
->addOption('collection_id', null, InputOption::VALUE_REQUIRED, 'The base_id of the collection to publish but keep with existing right into present in application box.')
|
||||
->setHelp('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
|
||||
$collection = \collection::getByBaseId($this->container,(int)$input->getOption('collection_id'));
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question> Do you want really publish this collection? (y/N)</question>', 'N'));
|
||||
} while ( ! in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('Aborting !');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$collection->enable($this->container->getApplicationBox());
|
||||
$output->writeln('<info>Publish collection successful</info>');
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Publish collection failed : '.$e->getMessage().'</error>');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class UnPublishCollectionCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('collection:unpublish');
|
||||
|
||||
$this->setDescription('Unpublish collection in Phraseanet')
|
||||
->addOption('collection_id', null, InputOption::VALUE_REQUIRED, 'The base_id of the collection to unpublish, the base_id is the same id used in API.')
|
||||
->setHelp('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
|
||||
$collection = \collection::getByBaseId($this->container,(int)$input->getOption('collection_id'));
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, sprintf("<question> Do you want really unpublish the collection %s? (y/N)</question>", $collection->get_name()), 'N'));
|
||||
} while ( ! in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('<info>Aborting !</>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$collection->disable($this->container->getApplicationBox());
|
||||
$output->writeln('<info>Unpublish collection successful</info>');
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Unpublish collection failed : '.$e->getMessage().'</error>');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@@ -1,7 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2020 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\Databox;
|
||||
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionSettings;
|
||||
use Alchemy\Phrasea\Databox\DataboxService;
|
||||
@@ -13,42 +22,84 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class MountDataboxCommand extends Command
|
||||
{
|
||||
|
||||
protected function configure()
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
$this->setName('databox:mount')
|
||||
->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);
|
||||
parent::__construct('databox:mount');
|
||||
|
||||
$this->setDescription('Mount databox')
|
||||
->addArgument('databox', InputArgument::REQUIRED, 'Database name in Mysql', null)
|
||||
->addArgument('user_id', InputArgument::REQUIRED, 'The Id of user owner (this account became full admin on this databox)', null)
|
||||
->addOption('db-host', null, InputOption::VALUE_OPTIONAL, 'MySQL server host')
|
||||
->addOption('db-port', null, InputOption::VALUE_OPTIONAL, 'MySQL server port')
|
||||
->addOption('db-user', null, InputOption::VALUE_OPTIONAL, 'MySQL server user')
|
||||
->addOption('db-password', null, InputOption::VALUE_OPTIONAL, 'MySQL server password')
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
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')
|
||||
);
|
||||
try {
|
||||
|
||||
/** @var UserRepository $userRepository */
|
||||
$userRepository = $this->container['repo.users'];
|
||||
/** @var DataboxService $databoxService */
|
||||
$databoxService = $this->container['databox.service'];
|
||||
/** @var UserRepository $userRepository */
|
||||
$userRepository = $this->container['repo.users'];
|
||||
|
||||
$owner = $userRepository->findByEmail($input->getArgument('owner'));
|
||||
$owner = $userRepository->find($input->getArgument('user_id'));
|
||||
|
||||
$databoxService->mountDatabox(
|
||||
$databoxName,
|
||||
$owner,
|
||||
$connectionSettings
|
||||
);
|
||||
if (empty($owner)) {
|
||||
$output->writeln('<error>User not found ! </error>');
|
||||
|
||||
$output->writeln('Databox mounted');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($owner->isGuest() || !$this->container->getAclForUser($owner)->is_admin()) {
|
||||
$output->writeln('<error>Admin role is required for the owner ! </error>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$databoxName = $input->getArgument('databox');
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
$connectionSettings = new DataboxConnectionSettings(
|
||||
$input->getOption('db-host')?:$this->container['conf']->get(['main', 'database', 'host']),
|
||||
$input->getOption('db-port')?:$this->container['conf']->get(['main', 'database', 'port']),
|
||||
$input->getOption('db-user')?:$this->container['conf']->get(['main', 'database', 'user']),
|
||||
$input->getOption('db-password')?:$this->container['conf']->get(['main', 'database', 'password'])
|
||||
);
|
||||
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question> Do you want really mount this databox? (y/N)</question>', 'N'));
|
||||
}
|
||||
while ( ! in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('Aborting !');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var DataboxService $databoxService */
|
||||
$databoxService = $this->container['databox.service'];
|
||||
|
||||
\phrasea::clear_sbas_params($this->container);
|
||||
|
||||
$databox = $databoxService->mountDatabox(
|
||||
$databoxName,
|
||||
$owner,
|
||||
$connectionSettings
|
||||
);
|
||||
|
||||
$output->writeln("\n\t<info>Data-Box ID ".$databox->get_sbas_id()." mounted successful !</info>\n");
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Mount databox failed :'.$e->getMessage().'</error>');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\Databox;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class UnMountDataboxCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('databox:unmount');
|
||||
|
||||
$this->setDescription('Unmount databox')
|
||||
->addArgument('databox_id', InputArgument::REQUIRED, 'The id of the databox to unmount', null)
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
$databox = $this->container->findDataboxById($input->getArgument('databox_id'));
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question> Do you want really unmount this databox? (y/N)</question>', 'N'));
|
||||
} while ( ! in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('Aborting !');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$databox->unmount_databox();
|
||||
$output->writeln('<info>Unmount databox successful</info>');
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Unmount databox failed : '.$e->getMessage().'</error>');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@@ -15,6 +15,21 @@ use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
function normalizePath($path) {
|
||||
return array_reduce(explode('/', $path), function ($a, $b) {
|
||||
if($a === 0)
|
||||
$a = '/';
|
||||
|
||||
if($b === '' || $b === '.')
|
||||
return $a;
|
||||
|
||||
if($b === '..')
|
||||
return dirname($a);
|
||||
|
||||
return preg_replace('/\/+/', '/', "$a/$b");
|
||||
}, 0);
|
||||
}
|
||||
|
||||
abstract class AbstractPluginCommand extends Command
|
||||
{
|
||||
protected function validatePlugins(InputInterface $input, OutputInterface $output)
|
||||
@@ -54,33 +69,42 @@ abstract class AbstractPluginCommand extends Command
|
||||
|
||||
protected function doInstallPlugin($source, InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$temporaryDir = $this->container['temporary-filesystem']->createTemporaryDirectory();
|
||||
|
||||
$output->write("Importing <info>$source</info>...");
|
||||
$this->container['plugins.importer']->import($source, $temporaryDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
|
||||
$output->write("Validating plugin...");
|
||||
$manifest = $this->container['plugins.plugins-validator']->validatePlugin($temporaryDir);
|
||||
$manifest = $this->container['plugins.plugins-validator']->validatePlugin($source);
|
||||
$output->writeln(" <comment>OK</comment> found <info>".$manifest->getName()."</info>");
|
||||
|
||||
$targetDir = $this->container['plugin.path'] . DIRECTORY_SEPARATOR . $manifest->getName();
|
||||
if (normalizePath($targetDir) !== normalizePath($source)) {
|
||||
$temporaryDir = $this->container['temporary-filesystem']->createTemporaryDirectory();
|
||||
$output->write("Importing <info>$source</info>...");
|
||||
$this->container['plugins.importer']->import($source, $temporaryDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
$workingDir = $temporaryDir;
|
||||
} else {
|
||||
$workingDir = $targetDir;
|
||||
}
|
||||
|
||||
$output->write("Setting up composer...");
|
||||
$this->container['plugins.composer-installer']->install($temporaryDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
if (!is_dir($workingDir.'/vendor')) {
|
||||
$output->write("Setting up composer...");
|
||||
$this->container['plugins.composer-installer']->install($workingDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
}
|
||||
|
||||
$output->write("Installing plugin <info>".$manifest->getName()."</info>...");
|
||||
$this->container['filesystem']->mirror($temporaryDir, $targetDir);
|
||||
if (isset($temporaryDir)) {
|
||||
$this->container['filesystem']->mirror($temporaryDir, $targetDir);
|
||||
}
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
|
||||
$output->write("Copying public files <info>".$manifest->getName()."</info>...");
|
||||
$this->container['plugins.assets-manager']->update($manifest);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
|
||||
$output->write("Removing temporary directory...");
|
||||
$this->container['filesystem']->remove($temporaryDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
if (isset($temporaryDir)) {
|
||||
$output->write("Removing temporary directory...");
|
||||
$this->container['filesystem']->remove($temporaryDir);
|
||||
$output->writeln(" <comment>OK</comment>");
|
||||
}
|
||||
|
||||
$output->write("Activating plugin...");
|
||||
$this->container['conf']->set(['plugins', $manifest->getName(), 'enabled'], true);
|
||||
|
329
lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php
Normal file
329
lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php
Normal file
@@ -0,0 +1,329 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2020 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\User;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Alchemy\Phrasea\ControllerProvider\Api\V2;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Notification\Mail\MailRequestPasswordSetup;
|
||||
use Alchemy\Phrasea\Notification\Mail\MailRequestEmailConfirmation;
|
||||
use Alchemy\Phrasea\Notification\Receiver;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class UserApplicationsCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('user:applications');
|
||||
|
||||
$this->setDescription('List, Create, Edit, Delete application in Phraseanet <comment>(experimental)</>')
|
||||
->addOption('list', null, InputOption::VALUE_NONE, 'List all applications or user applications if --user_id is set')
|
||||
->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet')
|
||||
->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id is set')
|
||||
->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, require an app_id')
|
||||
->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The Id of user owner of application (user_id), required to Create, Edit and Delete.')
|
||||
->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID, required for Edit and Delete')
|
||||
->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application, required for Create and Edit.')
|
||||
->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The kind of application, Desktop or Web.',ApiApplication::WEB_TYPE)
|
||||
->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application.')
|
||||
->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url, eg: -w "https://www.alchemy.fr".')
|
||||
->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind eg: -c "https://www.alchemy.fr/callback"')
|
||||
->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url')
|
||||
->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate the app, values true or false', 'true')
|
||||
->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate the access token')
|
||||
->addOption('password_oauth2_gt', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false')
|
||||
->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')
|
||||
|
||||
->setHelp('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$userId = $input->getOption('user_id');
|
||||
$appId = $input->getOption('app_id');
|
||||
$name = $input->getOption('name');
|
||||
$type = $input->getOption('type');
|
||||
$description = $input->getOption('description');
|
||||
$website = $input->getOption('website');
|
||||
$urlCallback = $input->getOption('callback');
|
||||
$webhookUrl = $input->getOption('webhook_url');
|
||||
$active = $input->getOption('active');
|
||||
$generateToken = $input->getOption('generate_token');
|
||||
$passwordOauth2Gt = $input->getOption('password_oauth2_gt');
|
||||
$create = $input->getOption('create');
|
||||
$edit = $input->getOption('edit');
|
||||
$delete = $input->getOption('delete');
|
||||
$list = $input->getOption('list');
|
||||
$jsonformat = $input->getOption('jsonformat');
|
||||
|
||||
$applicationManipulator = $this->container['manipulator.api-application'];
|
||||
$apiOauthTokenManipulator = $this->container['manipulator.api-oauth-token'];
|
||||
$accountRepository = $this->container['repo.api-accounts'];
|
||||
$apiApllicationConverter = $this->container['converter.api-application'];
|
||||
$userRepository = $this->container['repo.users'];
|
||||
$apiOauthRepository = $this->container['repo.api-oauth-tokens'];
|
||||
|
||||
if ($create) {
|
||||
if (null === $user = $userRepository->find($userId)) {
|
||||
$output->writeln('<error>User not found</error>');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
$output->writeln('<error>Name of application must be provide with option --name.</error>');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$description) {
|
||||
$output->writeln('<error>Desciption of application must be provide.</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
$application = $applicationManipulator
|
||||
->create(
|
||||
$name,
|
||||
$type,
|
||||
$description,
|
||||
$website,
|
||||
$user,
|
||||
$urlCallback
|
||||
);
|
||||
|
||||
$apiAccountManipulator = $this->container['manipulator.api-account'];
|
||||
$apiAccountManipulator->create($application, $user, V2::VERSION);
|
||||
|
||||
$account = $accountRepository->findByUserAndApplication($user, $application);
|
||||
|
||||
if ($generateToken) {
|
||||
$apiOauthTokenManipulator->create($account);
|
||||
}
|
||||
|
||||
if ($passwordOauth2Gt) {
|
||||
if (in_array($passwordOauth2Gt, ['true', 'false'])) {
|
||||
$application->setGrantPassword(($passwordOauth2Gt == 'true') ? true : false);
|
||||
$applicationManipulator->update($application);
|
||||
} else {
|
||||
$output->writeln('<error> Value of option --password_oauth2_gt should be "true" or "false"</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($webhookUrl) {
|
||||
$applicationManipulator->setWebhookUrl($application, $webhookUrl);
|
||||
$applicationManipulator->update($application);
|
||||
}
|
||||
|
||||
if ($active) {
|
||||
if (in_array($active, ['true', 'false'])) {
|
||||
$application->setActivated(($active == 'true') ? true : false);
|
||||
$applicationManipulator->update($application);
|
||||
} else {
|
||||
$output->writeln('<error>Value of option --active should be "true" or "false"</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
$application->setActivated(true);
|
||||
$applicationManipulator->update($application);
|
||||
}
|
||||
|
||||
$this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output);
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Create an application for user failed : '.$e->getMessage().'</error>');
|
||||
}
|
||||
} elseif ($edit) {
|
||||
if (!$appId) {
|
||||
$output->writeln('<error>ID of the application must be provided with option --app_id to edit the application.</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$application = $apiApllicationConverter->convert($appId);
|
||||
$account = $accountRepository->findByUserAndApplication($application->getCreator(), $application);
|
||||
|
||||
if (!$account) {
|
||||
$output->writeln('<error>ApiAccount not found!</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($name) {
|
||||
$application->setName($name);
|
||||
}
|
||||
if ($type) {
|
||||
$applicationManipulator->setType($application, $type);
|
||||
if ($type == ApiApplication::DESKTOP_TYPE) {
|
||||
$applicationManipulator->setRedirectUri($application, ApiApplication::NATIVE_APP_REDIRECT_URI);
|
||||
}
|
||||
}
|
||||
if ($description) {
|
||||
$application->setDescription($description);
|
||||
}
|
||||
if ($website) {
|
||||
$applicationManipulator->setWebsiteUrl($application, $website);
|
||||
}
|
||||
if ($urlCallback) {
|
||||
$applicationManipulator->setRedirectUri($application, $urlCallback);
|
||||
}
|
||||
if ($generateToken) {
|
||||
if (null !== $devToken = $apiOauthRepository->findDeveloperToken($account)) {
|
||||
$apiOauthTokenManipulator->renew($devToken);
|
||||
} else {
|
||||
$apiOauthTokenManipulator->create($account);
|
||||
}
|
||||
}
|
||||
if ($passwordOauth2Gt) {
|
||||
if (in_array($passwordOauth2Gt, ['true', 'false'])) {
|
||||
$application->setGrantPassword(($passwordOauth2Gt == 'true') ? true : false);
|
||||
} else {
|
||||
$output->writeln('<error> Value of option --password_oauth2_gt should be "true" or "false"</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ($webhookUrl) {
|
||||
$applicationManipulator->setWebhookUrl($application, $webhookUrl);
|
||||
}
|
||||
|
||||
if ($active) {
|
||||
if (in_array($active, ['true', 'false'])) {
|
||||
$application->setActivated(($active == 'true') ? true : false);
|
||||
} else {
|
||||
$output->writeln('<error>Value of option --active should be "true" or "false"</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$applicationManipulator->update($application);
|
||||
|
||||
$this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output);
|
||||
} elseif ($list) {
|
||||
if ($userId) {
|
||||
if (null === $user = $userRepository->find($userId)) {
|
||||
$output->writeln('<error>User not found</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$accounts = $accountRepository->findByUser($user);
|
||||
} else {
|
||||
$accounts = $accountRepository->findAll();
|
||||
}
|
||||
|
||||
$applicationList = [];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$application = $account->getApplication();
|
||||
$token = $apiOauthRepository->findDeveloperToken($account);
|
||||
|
||||
$applicationList[] = [
|
||||
$application->getId(),
|
||||
$account->getUser()->getId(),
|
||||
$application->getName(),
|
||||
$application->getClientId(),
|
||||
$application->getClientSecret(),
|
||||
$application->getRedirectUri(),
|
||||
($token) ? $token->getOauthToken() : '-',
|
||||
$application->isPasswordGranted() ? "true": "false"
|
||||
];
|
||||
}
|
||||
|
||||
$applicationTable = $this->getHelperSet()->get('table');
|
||||
$headers = ['app_id', 'user_id', 'name', 'client_id', 'client_secret', 'callback_url', 'generated token', 'grant_password status'];
|
||||
|
||||
if ($jsonformat ) {
|
||||
foreach ($applicationList as $appList) {
|
||||
$appInfo[] = array_combine($headers, $appList);
|
||||
}
|
||||
|
||||
echo json_encode($appInfo);
|
||||
} else {
|
||||
$applicationTable = $this->getHelperSet()->get('table');
|
||||
$applicationTable
|
||||
->setHeaders($headers)
|
||||
->setRows($applicationList)
|
||||
->render($output)
|
||||
;
|
||||
}
|
||||
} elseif ($delete) {
|
||||
if (!$appId) {
|
||||
$output->writeln('<error>ID of the application must be provided with option --app_id to delete the app.</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$application = $apiApllicationConverter->convert($appId);
|
||||
|
||||
if (is_null($application->getCreator())) {
|
||||
/** @var DialogHelper $dialog */
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
$continue = $dialog->askConfirmation($output, "<question>It's a special phraseanet application, do you want really to delete it? (N/y)</>", false);
|
||||
|
||||
if (!$continue) {
|
||||
$output->writeln("<info>See you later !</>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$applicationManipulator->delete($application);
|
||||
|
||||
$output->writeln("<info>Application ID $appId deleted successfully !</info>");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function showApllicationInformation($apiOauthRepository, ApiAccount $account, ApiApplication $application, $jsonformat, $output)
|
||||
{
|
||||
$token = $account ? $apiOauthRepository->findDeveloperToken($account) : null;
|
||||
|
||||
$applicationCreated = [
|
||||
$application->getClientSecret(),
|
||||
$application->getClientId(),
|
||||
$this->container["conf"]->get("servername") . "api/oauthv2/authorize",
|
||||
$this->container["conf"]->get("servername") . "api/oauthv2/token",
|
||||
($token) ? $token->getOauthToken() : '-',
|
||||
$application->isPasswordGranted() ? "true": "false"
|
||||
];
|
||||
|
||||
$headers = ['client_secret', 'client_id', 'Authorize endpoint url', 'Access endpoint', 'generated token', 'grant_password status'];
|
||||
if ($jsonformat ) {
|
||||
$createdAppInfo = array_combine($headers, $applicationCreated);
|
||||
echo json_encode($createdAppInfo);
|
||||
} else {
|
||||
$table = $this->getHelperSet()->get('table');
|
||||
$table
|
||||
->setHeaders($headers)
|
||||
->setRows([$applicationCreated])
|
||||
->render($output)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,8 +30,8 @@ class UserListCommand extends Command
|
||||
{
|
||||
parent::__construct('user:list');
|
||||
|
||||
$this->setDescription('List of all user (experimental)')
|
||||
->addOption('user_id', null, InputOption::VALUE_OPTIONAL, ' The id of user export only info this user ')
|
||||
$this->setDescription('List of all user <comment>(experimental)</>')
|
||||
->addOption('user_id', null, InputOption::VALUE_OPTIONAL, 'The id of user export only info this user ')
|
||||
->addOption('user_email', null, InputOption::VALUE_OPTIONAL, 'The mail of user export only info this user .')
|
||||
->addOption('database_id', null, InputOption::VALUE_OPTIONAL, 'Id of database.')
|
||||
->addOption('collection_id', null, InputOption::VALUE_OPTIONAL, 'Id of the collection.')
|
||||
@@ -39,7 +39,6 @@ class UserListCommand extends Command
|
||||
->addOption('guest', null, InputOption::VALUE_NONE, 'Only guest user')
|
||||
->addOption('created', null, InputOption::VALUE_OPTIONAL, 'Created at with operator,aaaa-mm-jj hh:mm:ss.')
|
||||
->addOption('updated', null, InputOption::VALUE_OPTIONAL, 'Update at with operator,aaaa-mm-jj hh:mm:ss.')
|
||||
->addOption('application', null, InputOption::VALUE_NONE, 'List application of user work only if --user_id is set')
|
||||
->addOption('right', null, InputOption::VALUE_NONE, 'Show right information')
|
||||
->addOption('adress', null, InputOption::VALUE_NONE, 'Show adress information')
|
||||
->addOption('models', null, InputOption::VALUE_NONE, "Show only defined models, if --user_id is set with --models it's the template owner")
|
||||
@@ -58,7 +57,6 @@ class UserListCommand extends Command
|
||||
$collectionId = $input->getOption('collection_id');
|
||||
$lockStatus = $input->getOption('mail_lock_status');
|
||||
$guest = $input->getOption('guest');
|
||||
$application = $input->getOption('application');
|
||||
$withAdress = $input->getOption('adress');
|
||||
$created = $input->getOption('created');
|
||||
$updated = $input->getOption('updated');
|
||||
@@ -77,11 +75,6 @@ class UserListCommand extends Command
|
||||
if($lockStatus && !$models) $query->addSqlFilter('Users.mail_locked = 1');
|
||||
if($guest && !$models) $query->include_invite(true)->addSqlFilter('Users.guest = 1');
|
||||
|
||||
if ($application and !$userId) {
|
||||
$output->writeln('<error>You must provide --user_id when using --application option</error>');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @var UserRepository $userRepository */
|
||||
$userRepository = $this->container['repo.users'];
|
||||
|
||||
@@ -94,11 +87,7 @@ class UserListCommand extends Command
|
||||
}
|
||||
|
||||
$userList = [];
|
||||
$showApplication = false;
|
||||
foreach ($users as $key => $user) {
|
||||
if ($userId and $application) {
|
||||
$showApplication = true;
|
||||
}
|
||||
$userList[] = $this->listUser($user, $withAdress, $withRight);
|
||||
|
||||
$userListRaw[] = array_combine($this->headerTable($withAdress, $withRight), $this->listUser($user, $withAdress, $withRight));
|
||||
@@ -113,15 +102,6 @@ class UserListCommand extends Command
|
||||
->setRows($userList)
|
||||
->render($output);
|
||||
;
|
||||
|
||||
|
||||
if ($showApplication) {
|
||||
$applicationTable = $this->getHelperSet()->get('table');
|
||||
$applicationTable->setHeaders(array(
|
||||
array(new TableCell('Applications', array('colspan' => 5))),
|
||||
['name','callback','client_secret','client_id','token'],
|
||||
))->setRows($this->getApplicationOfUser($users[0]))->render($output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -215,37 +195,6 @@ class UserListCommand extends Command
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return array
|
||||
*/
|
||||
private function getApplicationOfUser(User $user)
|
||||
{
|
||||
$apiRepository = $this->container['repo.api-applications'];
|
||||
$applications = $apiRepository->findByUser($user);
|
||||
|
||||
if (empty($applications)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$accountRepository = $this->container['repo.api-accounts'];
|
||||
$apiOauthRepository = $this->container['repo.api-oauth-tokens'];
|
||||
$usersApplication = [];
|
||||
foreach ($applications as $application) {
|
||||
$account = $accountRepository->findByUserAndApplication($user, $application);
|
||||
$token = $account ? $apiOauthRepository->findDeveloperToken($account) : null;
|
||||
$usersApplication[] = [
|
||||
$application->getName(),
|
||||
$application->getRedirectUri(),
|
||||
$application->getClientSecret(),
|
||||
$application->getClientId(),
|
||||
($token) ? $token->getOauthToken() : '-'
|
||||
];
|
||||
}
|
||||
|
||||
return $usersApplication;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $withAdress
|
||||
* @param $withRight
|
||||
|
178
lib/Alchemy/Phrasea/Command/User/UserPasswordCommand.php
Normal file
178
lib/Alchemy/Phrasea/Command/User/UserPasswordCommand.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\User;
|
||||
|
||||
use Alchemy\Phrasea\Application\Helper\NotifierAware;
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Notification\Receiver;
|
||||
use Alchemy\Phrasea\Notification\Mail\MailRequestPasswordUpdate;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class UserPasswordCommand extends Command
|
||||
{
|
||||
use NotifierAware;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('user:password');
|
||||
|
||||
$this->setDescription('Set user password in Phraseanet <comment>(experimental)</>')
|
||||
->addOption('user_id', null, InputOption::VALUE_REQUIRED, 'The id of user.')
|
||||
->addOption('generate', null, InputOption::VALUE_NONE, 'Generate and set with a random value')
|
||||
->addOption('password', null, InputOption::VALUE_OPTIONAL, 'Set the user password to the input value')
|
||||
->addOption('send_renewal_email', null, InputOption::VALUE_NONE, 'Send email link to user for password renewing, work only if --password or --generate are not define')
|
||||
->addOption('password_hash', null, InputOption::VALUE_OPTIONAL, 'Define a password hashed, work only with password_nonce')
|
||||
->addOption('password_nonce', null, InputOption::VALUE_OPTIONAL, 'Define a password nonce, work only with password_hash')
|
||||
->addOption('dump', null, InputOption::VALUE_NONE, 'Return the password hashed and nonce')
|
||||
->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')
|
||||
->addOption('yes', 'y', InputOption::VALUE_NONE, 'Answer yes to all questions')
|
||||
|
||||
->setHelp('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$userRepository = $this->container['repo.users'];
|
||||
$userManipulator = $this->container['manipulator.user'];
|
||||
|
||||
$user = $userRepository->find($input->getOption('user_id'));
|
||||
$password = $input->getOption('password');
|
||||
$generate = $input->getOption('generate');
|
||||
$sendRenewalEmail = $input->getOption('send_renewal_email');
|
||||
$dump = $input->getOption('dump');
|
||||
$passwordHash = $input->getOption('password_hash');
|
||||
$passwordNonce = $input->getOption('password_nonce');
|
||||
$jsonformat = $input->getOption('jsonformat');
|
||||
$yes = $input->getOption('yes');
|
||||
|
||||
|
||||
if ($user === null) {
|
||||
$output->writeln('<info>Not found User.</info>');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($passwordHash && $passwordNonce) {
|
||||
$user->setNonce($passwordNonce);
|
||||
$user->setPassword($passwordHash);
|
||||
$userManipulator->updateUser($user);
|
||||
|
||||
$output->writeln('<info>password set with hashed pass</info>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($dump) {
|
||||
$oldHash = $user->getPassword();
|
||||
$oldNonce = $user->getNonce();
|
||||
}
|
||||
|
||||
if ($generate) {
|
||||
$oldHash = $user->getPassword();
|
||||
$oldNonce = $user->getNonce();
|
||||
|
||||
$password = $this->container['random.medium']->generateString(64);
|
||||
} else {
|
||||
if (!$password && $sendRenewalEmail) {
|
||||
$this->sendPasswordSetupMail($user);
|
||||
$output->writeln('<info>email link sended for password renewing!</info>');
|
||||
|
||||
return 0;
|
||||
} elseif (!$password && !$sendRenewalEmail && ! $dump) {
|
||||
$output->writeln('<error>choose one option to set a password!</error>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($password) {
|
||||
if (!$yes) {
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question>Do you want really set password to this user? (y/N)</question>', 'N'));
|
||||
} while (!in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('Aborting !');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
$oldHash = $user->getPassword();
|
||||
$oldNonce = $user->getNonce();
|
||||
|
||||
$userManipulator->setPassword($user,$password);
|
||||
}
|
||||
|
||||
if ($dump) {
|
||||
if ($jsonformat) {
|
||||
$hash['password_hash'] = $oldHash;
|
||||
$hash['nonce'] = $oldNonce;
|
||||
|
||||
echo json_encode($hash);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
$output->writeln('<info>password_hash :</info>' . $oldHash);
|
||||
$output->writeln('<info>nonce :</info>' . $oldNonce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (($password || $generate)) {
|
||||
if ($jsonformat) {
|
||||
$hash['new_password'] = $password;
|
||||
$hash['previous_password_hash'] = $oldHash;
|
||||
$hash['previous_nonce'] = $oldNonce;
|
||||
|
||||
echo json_encode($hash);
|
||||
} else {
|
||||
$output->writeln('<info>new_password :</info>' . $password);
|
||||
$output->writeln('<info>previous_password_hash :</info>' . $oldHash);
|
||||
$output->writeln('<info>previous_nonce :</info>' . $oldNonce);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send mail for renew password
|
||||
* @param User $user
|
||||
*/
|
||||
private function sendPasswordSetupMail(User $user)
|
||||
{
|
||||
$this->setDelivererLocator(new LazyLocator($this->container, 'notification.deliverer'));
|
||||
$receiver = Receiver::fromUser($user);
|
||||
|
||||
$token = $this->container['manipulator.token']->createResetPasswordToken($user);
|
||||
|
||||
$url = $this->container['url_generator']->generate('login_renew_password', [ 'token' => $token->getValue() ], true);
|
||||
$mail = MailRequestPasswordUpdate::create($this->container, $receiver);
|
||||
$servername = $this->container['conf']->get('servername');
|
||||
$mail->setButtonUrl($url);
|
||||
$mail->setLogin($user->getLogin());
|
||||
$mail->setExpiration(new \DateTime('+1 day'));
|
||||
|
||||
$this->deliver($mail);
|
||||
}
|
||||
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\User;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
|
||||
class UserSetPasswordCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($name = null)
|
||||
{
|
||||
parent::__construct('user:set-password');
|
||||
|
||||
$this->setDescription('Set user password in Phraseanet')
|
||||
->addOption('user_id', null, InputOption::VALUE_REQUIRED, 'The id of user.')
|
||||
->addOption('generate', null, InputOption::VALUE_NONE, 'Generate the password')
|
||||
->addOption('password', null, InputOption::VALUE_OPTIONAL, 'The password')
|
||||
->setHelp('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$userRepository = $this->container['repo.users'];
|
||||
$userManipulator = $this->container['manipulator.user'];
|
||||
$user = $userRepository->find($input->getOption('user_id'));
|
||||
$password = $input->getOption('password');
|
||||
$generate = $input->getOption('generate');
|
||||
|
||||
if ($user === null) {
|
||||
$output->writeln('<info>Not found User.</info>');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($generate) {
|
||||
$password = $this->container['random.medium']->generateString(64);
|
||||
} else {
|
||||
if (!$password) {
|
||||
$output->writeln('<error>--password option not specified</error>');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question>Do you want really set password to this user? (y/N)</question>', 'N'));
|
||||
} while (!in_array($continue, ['y', 'n']));
|
||||
|
||||
if ($continue !== 'y') {
|
||||
$output->writeln('Aborting !');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$userManipulator->setPassword($user,$password);
|
||||
$output->writeln('New password: <info>' . $password . '</info>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@@ -1573,9 +1573,9 @@ class V1Controller extends Controller
|
||||
$options->setFirstResult((int)($request->get('offset_start') ?: 0));
|
||||
$options->setMaxResults((int)$request->get('per_page') ?: 10);
|
||||
|
||||
$this->getSearchEngine()->resetCache();
|
||||
$searchEngine = $this->getSearchEngine();
|
||||
|
||||
$search_result = $this->getSearchEngine()->query((string)$request->get('query'), $options);
|
||||
$search_result = $searchEngine->query((string)$request->get('query'), $options);
|
||||
|
||||
$this->getUserManipulator()->logQuery($this->getAuthenticatedUser(), $search_result->getQueryText());
|
||||
|
||||
@@ -1583,12 +1583,12 @@ class V1Controller extends Controller
|
||||
$collectionsReferencesByDatabox = $options->getCollectionsReferencesByDatabox();
|
||||
foreach ($collectionsReferencesByDatabox as $sbid => $references) {
|
||||
$databox = $this->findDataboxById($sbid);
|
||||
$collectionsIds = array_map(function(CollectionReference $ref){return $ref->getCollectionId();}, $references);
|
||||
$collectionsIds = array_map(function (CollectionReference $ref) {
|
||||
return $ref->getCollectionId();
|
||||
}, $references);
|
||||
$this->getSearchEngineLogger()->log($databox, $search_result->getQueryText(), $search_result->getTotal(), $collectionsIds);
|
||||
}
|
||||
|
||||
$this->getSearchEngine()->clearCache();
|
||||
|
||||
return $search_result;
|
||||
}
|
||||
|
||||
|
@@ -450,6 +450,51 @@ class LightboxController extends Controller
|
||||
return $this->app->json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Basket $basket
|
||||
* @return Response
|
||||
*/
|
||||
public function ajaxGetElementsAction(Basket $basket)
|
||||
{
|
||||
$ret = [
|
||||
'error' => false,
|
||||
'datas' => [
|
||||
'counts' => [
|
||||
'yes' => 0,
|
||||
'no' => 0,
|
||||
'nul' => 0,
|
||||
'total' => 0
|
||||
]
|
||||
]
|
||||
];
|
||||
try {
|
||||
if (!$basket->getValidation()) {
|
||||
throw new Exception('There is no validation session attached to this basket');
|
||||
}
|
||||
foreach ($basket->getElements() as $element) {
|
||||
$vd = $element->getUserValidationDatas($this->getAuthenticatedUser());
|
||||
if($vd->getAgreement() === true) {
|
||||
$ret['datas']['counts']['yes']++;
|
||||
}
|
||||
elseif($vd->getAgreement() === false) {
|
||||
$ret['datas']['counts']['no']++;
|
||||
}
|
||||
elseif($vd->getAgreement() === null) {
|
||||
$ret['datas']['counts']['nul']++;
|
||||
}
|
||||
$ret['datas']['counts']['total']++;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$ret = [
|
||||
'error' => true,
|
||||
'datas' => $e->getMessage()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Basket $basket
|
||||
* @throws Exception
|
||||
|
@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Application\Helper\FilesystemAware;
|
||||
use Alchemy\Phrasea\Application\Helper\NotifierAware;
|
||||
use Alchemy\Phrasea\Controller\Controller;
|
||||
use Alchemy\Phrasea\Core\Event\ExportFailureEvent;
|
||||
use Alchemy\Phrasea\Core\Event\ExportMailEvent;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
@@ -193,42 +194,26 @@ class ExportController extends Controller
|
||||
$token = $this->getTokenManipulator()->createEmailExportToken(serialize($list));
|
||||
|
||||
if (count($destMails) > 0) {
|
||||
//zip documents
|
||||
\set_export::build_zip(
|
||||
$this->app,
|
||||
$token,
|
||||
$list,
|
||||
$this->app['tmp.download.path'].'/'. $token->getValue() . '.zip'
|
||||
);
|
||||
$emitterId = $this->getAuthenticatedUser()->getId();
|
||||
|
||||
$remaingEmails = $destMails;
|
||||
$tokenValue = $token->getValue();
|
||||
|
||||
$url = $this->app->url('prepare_download', ['token' => $token->getValue(), 'anonymous' => false, 'type' => \Session_Logger::EVENT_EXPORTMAIL]);
|
||||
|
||||
$user = $this->getAuthenticatedUser();
|
||||
$emitter = new Emitter($user->getDisplayName(), $user->getEmail());
|
||||
$params = [
|
||||
'url' => $url,
|
||||
'textmail' => $request->request->get('textmail'),
|
||||
'reading_confirm' => !!$request->request->get('reading_confirm', false),
|
||||
'ssttid' => $ssttid = $request->request->get('ssttid', ''),
|
||||
'lst' => $lst = $request->request->get('lst', ''),
|
||||
];
|
||||
|
||||
foreach ($destMails as $key => $mail) {
|
||||
try {
|
||||
$receiver = new Receiver(null, trim($mail));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mail = MailRecordsExport::create($this->app, $receiver, $emitter, $request->request->get('textmail'));
|
||||
$mail->setButtonUrl($url);
|
||||
$mail->setExpiration($token->getExpiration());
|
||||
|
||||
$this->deliver($mail, !!$request->request->get('reading_confirm', false));
|
||||
unset($remaingEmails[$key]);
|
||||
}
|
||||
|
||||
//some mails failed
|
||||
if (count($remaingEmails) > 0) {
|
||||
foreach ($remaingEmails as $mail) {
|
||||
$this->dispatch(PhraseaEvents::EXPORT_MAIL_FAILURE, new ExportFailureEvent($this->getAuthenticatedUser(), $ssttid, $lst, \eventsmanager_notify_downloadmailfail::MAIL_FAIL, $mail));
|
||||
}
|
||||
}
|
||||
$this->dispatch(PhraseaEvents::EXPORT_MAIL_CREATE, new ExportMailEvent(
|
||||
$emitterId,
|
||||
$tokenValue,
|
||||
$destMails,
|
||||
$params
|
||||
));
|
||||
}
|
||||
|
||||
return $this->app->json([
|
||||
|
@@ -98,7 +98,7 @@ class PushController extends Controller
|
||||
$Basket->setUser($user_receiver);
|
||||
$Basket->setPusher($this->getAuthenticatedUser());
|
||||
$Basket->markUnread();
|
||||
|
||||
|
||||
$manager->persist($Basket);
|
||||
|
||||
foreach ($pusher->get_elements() as $element) {
|
||||
@@ -600,6 +600,38 @@ class PushController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
public function updateExpirationAction(Request $request)
|
||||
{
|
||||
$ret = [
|
||||
'success' => false,
|
||||
'message' => $this->app->trans('Unable to save the expiration date')
|
||||
];
|
||||
if (is_null($request->request->get('date'))) {
|
||||
$ret['message'] = $this->app->trans('The provided date is null!');
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
$repository = $this->app['repo.baskets'];
|
||||
$manager = $this->getEntityManager();
|
||||
$manager->beginTransaction();
|
||||
try {
|
||||
$basket = $repository->findUserBasket($request->request->get('basket_id'), $this->app->getAuthenticatedUser(), true);
|
||||
$date = new \DateTime($request->request->get('date') . " 23:59:59");
|
||||
$validation = $basket->getValidation();
|
||||
if (is_null($validation)) {
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
$validation->setExpires($date);
|
||||
$manager->persist($validation);
|
||||
$manager->flush();
|
||||
$manager->commit();
|
||||
$ret['message'] = $this->app->trans('Expiration date successfully updated!');
|
||||
} catch (\Exception $e) {
|
||||
$ret['message'] = $e->getMessage();
|
||||
$manager->rollback();
|
||||
}
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
private function formatUser(User $user)
|
||||
{
|
||||
$subtitle = array_filter([$user->getJob(), $user->getCompany()]);
|
||||
@@ -734,4 +766,5 @@ class PushController extends Controller
|
||||
{
|
||||
return $this->app['random.medium'];
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ use Alchemy\Phrasea\Application\Helper\EntityManagerAware;
|
||||
use Alchemy\Phrasea\Application\Helper\SearchEngineAware;
|
||||
use Alchemy\Phrasea\Controller\Controller;
|
||||
use Alchemy\Phrasea\Controller\RecordsRequest;
|
||||
use Alchemy\Phrasea\Core\Event\Record\DeleteEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\RecordEdit;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Model\Entities\BasketElement;
|
||||
@@ -234,7 +236,7 @@ class RecordController extends Controller
|
||||
if($trashCollectionsBySbasId[$sbasId] !== null) {
|
||||
if($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
|
||||
// record is already in trash so delete it
|
||||
$record->delete();
|
||||
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
|
||||
} else {
|
||||
// move to trash collection
|
||||
$record->move_to_collection($trashCollectionsBySbasId[$sbasId], $this->getApplicationBox());
|
||||
@@ -247,7 +249,7 @@ class RecordController extends Controller
|
||||
}
|
||||
} else {
|
||||
// no trash collection, delete
|
||||
$record->delete();
|
||||
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ use Alchemy\Phrasea\Application\Helper\EntityManagerAware;
|
||||
use Alchemy\Phrasea\Controller\Controller;
|
||||
use Alchemy\Phrasea\Controller\RecordsRequest;
|
||||
use Alchemy\Phrasea\Controller\Exception as ControllerException;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Core\Event\RecordEdit;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Model\Entities\StoryWZ;
|
||||
@@ -68,7 +70,9 @@ class StoryController extends Controller
|
||||
break;
|
||||
}
|
||||
|
||||
$story->set_metadatas($metadatas)->rebuild_subdefs();
|
||||
$recordAdapter = $story->set_metadatas($metadatas);
|
||||
// tell phraseanet to rebuild subdef
|
||||
$this->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($recordAdapter));
|
||||
|
||||
$storyWZ = new StoryWZ();
|
||||
$storyWZ->setUser($this->getAuthenticatedUser());
|
||||
|
@@ -16,6 +16,7 @@ use Alchemy\Phrasea\Application\Helper\SubDefinitionSubstituerAware;
|
||||
use Alchemy\Phrasea\Controller\Controller;
|
||||
use Alchemy\Phrasea\Controller\RecordsRequest;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
||||
use Alchemy\Phrasea\Metadata\PhraseanetMetadataReader;
|
||||
use Alchemy\Phrasea\Metadata\PhraseanetMetadataSetter;
|
||||
@@ -156,7 +157,7 @@ class ToolsController extends Controller
|
||||
}
|
||||
|
||||
if (!$substituted || $force) {
|
||||
$record->rebuild_subdefs();
|
||||
$this->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($record));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -105,6 +105,11 @@ class Lightbox implements ControllerProviderInterface, ServiceProviderInterface
|
||||
->assert('basket', '\d+')
|
||||
;
|
||||
|
||||
$controllers->get('/ajax/GET_ELEMENTS/{basket}/', 'controller.lightbox:ajaxGetElementsAction')
|
||||
->bind('lightbox_ajax_get_elements')
|
||||
->assert('basket', '\d+')
|
||||
;
|
||||
|
||||
return $controllers;
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,9 @@ class Push implements ControllerProviderInterface, ServiceProviderInterface
|
||||
$controllers->post('/validate/', 'controller.prod.push:validateAction')
|
||||
->bind('prod_push_validate');
|
||||
|
||||
$controllers->post('/update-expiration/', 'controller.prod.push:updateExpirationAction')
|
||||
->bind('prod_push_do_update_expiration');
|
||||
|
||||
$controllers->get('/user/{usr_id}/', 'controller.prod.push:getUserAction')
|
||||
->assert('usr_id', '\d+');
|
||||
|
||||
|
53
lib/Alchemy/Phrasea/Core/Event/ExportMailEvent.php
Normal file
53
lib/Alchemy/Phrasea/Core/Event/ExportMailEvent.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2019 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\Event as SfEvent;
|
||||
|
||||
class ExportMailEvent extends SfEvent
|
||||
{
|
||||
private $emitterUserId;
|
||||
private $tokenValue;
|
||||
/** @var array */
|
||||
private $destinationMails;
|
||||
/** @var array */
|
||||
private $params;
|
||||
|
||||
|
||||
public function __construct($emitterUserId, $tokenValue, array $destMails, array $params)
|
||||
{
|
||||
$this->emitterUserId = $emitterUserId;
|
||||
$this->tokenValue = $tokenValue;
|
||||
$this->destinationMails = $destMails;
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
public function getTokenValue()
|
||||
{
|
||||
return $this->tokenValue;
|
||||
}
|
||||
|
||||
public function getDestinationMails()
|
||||
{
|
||||
return $this->destinationMails;
|
||||
}
|
||||
|
||||
public function getEmitterUserId()
|
||||
{
|
||||
return $this->emitterUserId;
|
||||
}
|
||||
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
}
|
7
lib/Alchemy/Phrasea/Core/Event/Record/DeleteEvent.php
Normal file
7
lib/Alchemy/Phrasea/Core/Event/Record/DeleteEvent.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event\Record;
|
||||
|
||||
class DeleteEvent extends RecordEvent
|
||||
{
|
||||
}
|
@@ -13,8 +13,10 @@ namespace Alchemy\Phrasea\Core\Event\Record;
|
||||
|
||||
final class RecordEvents
|
||||
{
|
||||
const CREATED = 'record.created';
|
||||
const DELETED = 'record.deleted';
|
||||
const CREATED = 'record.created';
|
||||
const DELETED = 'record.deleted';
|
||||
const DELETE = 'record.delete';
|
||||
|
||||
// Change
|
||||
const COLLECTION_CHANGED = 'record.collection_changed';
|
||||
const METADATA_CHANGED = 'record.metadata_changed';
|
||||
@@ -29,6 +31,8 @@ final class RecordEvents
|
||||
const SUB_DEFINITIONS_CREATED = 'record.sub_definitions_created';
|
||||
const SUB_DEFINITION_CREATION_FAILED = 'record.sub_definition_creation_failed';
|
||||
|
||||
const SUBDEFINITION_CREATE = 'record.subdefinition_create';
|
||||
|
||||
const MEDIA_SUBSTITUTED = 'record.media_substituted';
|
||||
|
||||
const STORY_COVER_CHANGED = 'record.story_cover_changed';
|
||||
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event\Record;
|
||||
|
||||
use Alchemy\Phrasea\Model\RecordInterface;
|
||||
|
||||
class SubdefinitionCreateEvent extends RecordEvent
|
||||
{
|
||||
private $isNewRecord;
|
||||
|
||||
public function __construct(RecordInterface $record, $isNewRecord = false)
|
||||
{
|
||||
parent::__construct($record);
|
||||
|
||||
$this->isNewRecord = $isNewRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNewRecord()
|
||||
{
|
||||
return $this->isNewRecord;
|
||||
}
|
||||
}
|
@@ -12,7 +12,15 @@
|
||||
namespace Alchemy\Phrasea\Core\Event\Subscriber;
|
||||
|
||||
use Alchemy\Phrasea\Core\Event\ExportFailureEvent;
|
||||
use Alchemy\Phrasea\Core\Event\ExportMailEvent;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\Token;
|
||||
use Alchemy\Phrasea\Model\Repositories\TokenRepository;
|
||||
use Alchemy\Phrasea\Model\Repositories\UserRepository;
|
||||
use Alchemy\Phrasea\Notification\Emitter;
|
||||
use Alchemy\Phrasea\Notification\Mail\MailRecordsExport;
|
||||
use Alchemy\Phrasea\Notification\Receiver;
|
||||
|
||||
class ExportSubscriber extends AbstractNotificationSubscriber
|
||||
{
|
||||
@@ -39,10 +47,65 @@ class ExportSubscriber extends AbstractNotificationSubscriber
|
||||
$this->app['event-manager']->notify($params['usr_id'], 'eventsmanager_notify_downloadmailfail', $datas, $mailed);
|
||||
}
|
||||
|
||||
public function onCreateExportMail(ExportMailEvent $event)
|
||||
{
|
||||
$destMails = $event->getDestinationMails();
|
||||
|
||||
$params = $event->getParams();
|
||||
|
||||
/** @var UserRepository $userRepository */
|
||||
$userRepository = $this->app['repo.users'];
|
||||
|
||||
$user = $userRepository->find($event->getEmitterUserId());
|
||||
|
||||
/** @var TokenRepository $tokenRepository */
|
||||
$tokenRepository = $this->app['repo.tokens'];
|
||||
|
||||
/** @var Token $token */
|
||||
$token = $tokenRepository->findValidToken($event->getTokenValue());
|
||||
|
||||
$list = unserialize($token->getData());
|
||||
|
||||
//zip documents
|
||||
\set_export::build_zip(
|
||||
$this->app,
|
||||
$token,
|
||||
$list,
|
||||
$this->app['tmp.download.path'].'/'. $token->getValue() . '.zip'
|
||||
);
|
||||
|
||||
$remaingEmails = $destMails;
|
||||
|
||||
$emitter = new Emitter($user->getDisplayName(), $user->getEmail());
|
||||
|
||||
foreach ($destMails as $key => $mail) {
|
||||
try {
|
||||
$receiver = new Receiver(null, trim($mail));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mail = MailRecordsExport::create($this->app, $receiver, $emitter, $params['textmail']);
|
||||
$mail->setButtonUrl($params['url']);
|
||||
$mail->setExpiration($token->getExpiration());
|
||||
|
||||
$this->deliver($mail, $params['reading_confirm']);
|
||||
unset($remaingEmails[$key]);
|
||||
}
|
||||
|
||||
//some mails failed
|
||||
if (count($remaingEmails) > 0) {
|
||||
foreach ($remaingEmails as $mail) {
|
||||
$this->app['dispatcher']->dispatch(PhraseaEvents::EXPORT_MAIL_FAILURE, new ExportFailureEvent($user, $params['ssttid'], $params['lst'], \eventsmanager_notify_downloadmailfail::MAIL_FAIL, $mail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
PhraseaEvents::EXPORT_MAIL_FAILURE => 'onMailExportFailure'
|
||||
PhraseaEvents::EXPORT_MAIL_FAILURE => 'onMailExportFailure',
|
||||
PhraseaEvents::EXPORT_MAIL_CREATE => 'onCreateExportMail',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -11,8 +11,10 @@
|
||||
namespace Alchemy\Phrasea\Core\Event\Subscriber;
|
||||
|
||||
use Alchemy\Phrasea\Core\Event\Record\CollectionChangedEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\DeleteEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Core\Event\RecordEdit;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Metadata\Tag\TfEditdate;
|
||||
@@ -26,10 +28,12 @@ class RecordEditSubscriber implements EventSubscriberInterface
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
PhraseaEvents::RECORD_EDIT => 'onEdit',
|
||||
PhraseaEvents::RECORD_UPLOAD => 'onEdit',
|
||||
RecordEvents::ROTATE => 'onRecordChange',
|
||||
RecordEvents::COLLECTION_CHANGED => 'onCollectionChanged',
|
||||
PhraseaEvents::RECORD_EDIT => 'onEdit',
|
||||
PhraseaEvents::RECORD_UPLOAD => 'onEdit',
|
||||
RecordEvents::ROTATE => 'onRecordChange',
|
||||
RecordEvents::COLLECTION_CHANGED => 'onCollectionChanged',
|
||||
RecordEvents::SUBDEFINITION_CREATE => 'onSubdefinitionCreate',
|
||||
RecordEvents::DELETE => 'onDelete',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,6 +53,18 @@ class RecordEditSubscriber implements EventSubscriberInterface
|
||||
$recordAdapter->clearStampCache();
|
||||
}
|
||||
|
||||
public function onSubdefinitionCreate(SubdefinitionCreateEvent $event)
|
||||
{
|
||||
$recordAdapter = $this->convertToRecordAdapter($event->getRecord());
|
||||
$recordAdapter->rebuild_subdefs();
|
||||
}
|
||||
|
||||
public function onDelete(DeleteEvent $event)
|
||||
{
|
||||
$recordAdapter = $this->convertToRecordAdapter($event->getRecord());
|
||||
$recordAdapter->delete();
|
||||
}
|
||||
|
||||
public function onEdit(RecordEdit $event)
|
||||
{
|
||||
static $into = false;
|
||||
|
@@ -84,10 +84,14 @@ class DatabaseMetaProvider implements ServiceProviderInterface
|
||||
$service = $app['phraseanet.cache-service'];
|
||||
|
||||
$config->setMetadataCacheImpl(
|
||||
$service->factory('ORM_metadata', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
$app['orm.cache.factory.filesystem'](array(
|
||||
'path' => $app['cache.path'].'/doctrine/metadata',
|
||||
))
|
||||
);
|
||||
$config->setQueryCacheImpl(
|
||||
$service->factory('ORM_query', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
$app['orm.cache.factory.filesystem'](array(
|
||||
'path' => $app['cache.path'].'/doctrine/query',
|
||||
))
|
||||
);
|
||||
$config->setResultCacheImpl(
|
||||
$service->factory('ORM_result', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
|
@@ -48,7 +48,8 @@ final class PhraseaEvents
|
||||
const BRIDGE_UPLOAD_FAILURE = 'bridge.upload-failure';
|
||||
|
||||
const EXPORT_MAIL_FAILURE = 'export.mail-failure';
|
||||
const EXPORT_CREATE = 'export.create';
|
||||
const EXPORT_CREATE = 'export.create';
|
||||
const EXPORT_MAIL_CREATE = 'export.mail-create';
|
||||
|
||||
const RECORD_EDIT = 'record.edit';
|
||||
const RECORD_UPLOAD = 'record.upload';
|
||||
|
@@ -32,11 +32,12 @@ class WorkerConfigurationServiceProvider implements ServiceProviderInterface
|
||||
$app['alchemy_queues.queues'] = $app->share(function (Application $app) {
|
||||
$defaultConfiguration = [
|
||||
'worker-queue' => [
|
||||
'registry' => 'alchemy_worker.queue_registry',
|
||||
'host' => 'localhost',
|
||||
'port' => 5672,
|
||||
'user' => 'guest',
|
||||
'vhost' => '/'
|
||||
'registry' => 'alchemy_worker.queue_registry',
|
||||
'host' => 'localhost',
|
||||
'port' => 5672,
|
||||
'user' => 'guest',
|
||||
'password' => 'guest',
|
||||
'vhost' => '/'
|
||||
]
|
||||
];
|
||||
|
||||
@@ -46,19 +47,22 @@ class WorkerConfigurationServiceProvider implements ServiceProviderInterface
|
||||
|
||||
$queueConfigurations = $configuration->get(['workers', 'queue'], $defaultConfiguration);
|
||||
|
||||
$queueConfiguration = reset($queueConfigurations);
|
||||
$queueKey = key($queueConfigurations);
|
||||
$config = [];
|
||||
|
||||
if (! isset($queueConfiguration['name'])) {
|
||||
if (! is_string($queueKey)) {
|
||||
throw new \RuntimeException('Invalid queue configuration: configuration has no key or name.');
|
||||
foreach($queueConfigurations as $name => $queueConfiguration) {
|
||||
$queueKey = $name;
|
||||
|
||||
if (! isset($queueConfiguration['name'])) {
|
||||
if (! is_string($queueKey)) {
|
||||
throw new \RuntimeException('Invalid queue configuration: configuration has no key or name.');
|
||||
}
|
||||
|
||||
$queueConfiguration['name'] = $queueKey;
|
||||
}
|
||||
|
||||
$queueConfiguration['name'] = $queueKey;
|
||||
$config[$queueConfiguration['name']] = $queueConfiguration ;
|
||||
}
|
||||
|
||||
$config = [ $queueConfiguration['name'] => $queueConfiguration ];
|
||||
|
||||
return $config;
|
||||
}
|
||||
catch (RuntimeException $exception) {
|
||||
|
@@ -17,7 +17,7 @@ class Version
|
||||
* @var string
|
||||
*/
|
||||
|
||||
private $number = '4.1.0-alpha.23a';
|
||||
private $number = '4.1.0-alpha.25a';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
@@ -18,6 +18,7 @@ use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionsCreationEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubDefinitionCreationFailedEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository;
|
||||
use Alchemy\Phrasea\Filesystem\FilesystemService;
|
||||
use Alchemy\Phrasea\Media\Subdef\Specification\PdfSpecification;
|
||||
use MediaAlchemyst\Alchemyst;
|
||||
@@ -170,13 +171,53 @@ class SubdefGenerator
|
||||
unset($this->tmpFilePath);
|
||||
}
|
||||
|
||||
$this->dispatch(
|
||||
RecordEvents::SUB_DEFINITIONS_CREATED,
|
||||
new SubDefinitionsCreatedEvent(
|
||||
$record,
|
||||
$mediaCreated
|
||||
)
|
||||
);
|
||||
// if we created subdef one by one
|
||||
if (count($wanted_subdefs) == 1) {
|
||||
$mediaSubdefRepository = $this->getMediaSubdefRepository($record->getDataboxId());
|
||||
$mediaSubdefs = $mediaSubdefRepository->findByRecordIdsAndNames([$record->getRecordId()]);
|
||||
$medias = [];
|
||||
foreach ($mediaSubdefs as $subdef) {
|
||||
try {
|
||||
$medias[$subdef->get_name()] = $this->mediavorus->guess($subdef->getRealPath());
|
||||
} catch (MediaVorusFileNotFoundException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatch(
|
||||
RecordEvents::SUB_DEFINITIONS_CREATED,
|
||||
new SubDefinitionsCreatedEvent(
|
||||
$record,
|
||||
$medias
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->dispatch(
|
||||
RecordEvents::SUB_DEFINITIONS_CREATED,
|
||||
new SubDefinitionsCreatedEvent(
|
||||
$record,
|
||||
$mediaCreated
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set a logger to use
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* to get the logger
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
private function generateSubdef(\record_adapter $record, \databox_subdef $subdef_class, $pathdest)
|
||||
@@ -276,4 +317,14 @@ class SubdefGenerator
|
||||
$i = floor(log($bytes, 1024));
|
||||
return round($bytes / pow(1024, $i), [0,0,2,2,3][$i]).['B','kB','MB','GB'][$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $databoxId
|
||||
*
|
||||
* @return MediaSubdefRepository|Object
|
||||
*/
|
||||
private function getMediaSubdefRepository($databoxId)
|
||||
{
|
||||
return $this->app['provider.repo.media_subdef']->getRepositoryForDatabox($databoxId);
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Media;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Event\Record\MediaSubstitutedEvent;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Filesystem\FilesystemService;
|
||||
use MediaAlchemyst\Alchemyst;
|
||||
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
|
||||
@@ -79,7 +80,7 @@ class SubdefSubstituer
|
||||
$record->write_metas();
|
||||
|
||||
if ($shouldSubdefsBeRebuilt) {
|
||||
$record->rebuild_subdefs();
|
||||
$this->dispatcher->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($record));
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(RecordEvents::MEDIA_SUBSTITUTED, new MediaSubstitutedEvent($record));
|
||||
|
@@ -12,7 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\WebhookEvent;
|
||||
use Alchemy\Phrasea\Webhook\WebhookPublisher;
|
||||
use Alchemy\Phrasea\Webhook\WebhookPublisherInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
@@ -29,11 +29,11 @@ class WebhookEventManipulator implements ManipulatorInterface
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var WebhookPublisher
|
||||
* @var WebhookPublisherInterface
|
||||
*/
|
||||
private $publisher;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, WebhookPublisher $publisher)
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, WebhookPublisherInterface $publisher)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
|
@@ -12,6 +12,8 @@
|
||||
namespace Alchemy\Phrasea\TaskManager\Job;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
|
||||
use Alchemy\Phrasea\Core\Event\Record\SubdefinitionCreateEvent;
|
||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
||||
use Alchemy\Phrasea\Border\File;
|
||||
use Alchemy\Phrasea\Border\Manager as borderManager;
|
||||
@@ -1001,7 +1003,7 @@ class ArchiveJob extends AbstractJob
|
||||
{
|
||||
// quick fix to reconnect if mysql is lost
|
||||
$app->getApplicationBox()->get_connection();
|
||||
$databox->get_connection();
|
||||
$collection->get_connection();
|
||||
|
||||
$status = \databox_status::operation_or($stat0, $stat1);
|
||||
|
||||
@@ -1032,7 +1034,8 @@ class ArchiveJob extends AbstractJob
|
||||
}
|
||||
|
||||
$story->setStatus(\databox_status::operation_or($stat0, $stat1));
|
||||
$story->rebuild_subdefs();
|
||||
|
||||
$app['dispatcher']->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($story));
|
||||
|
||||
unset($media);
|
||||
|
||||
|
@@ -19,7 +19,7 @@ use Alchemy\Queue\MessageQueueRegistry;
|
||||
* Class WebhookPublisher publishes webhook event notifications in message queues
|
||||
* @package Alchemy\Phrasea\Webhook
|
||||
*/
|
||||
class WebhookPublisher
|
||||
class WebhookPublisher implements WebhookPublisherInterface
|
||||
{
|
||||
/**
|
||||
* @var MessageQueueRegistry
|
||||
|
10
lib/Alchemy/Phrasea/Webhook/WebhookPublisherInterface.php
Normal file
10
lib/Alchemy/Phrasea/Webhook/WebhookPublisherInterface.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Webhook;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\WebhookEvent;
|
||||
|
||||
interface WebhookPublisherInterface
|
||||
{
|
||||
public function publishWebhookEvent(WebhookEvent $event);
|
||||
}
|
Reference in New Issue
Block a user