PHRAS-1248 Merge branch '4.0'

Conflicts:
	Makefile
	composer.json
	composer.lock
	lib/Alchemy/Phrasea/Collection/CollectionService.php
	lib/Alchemy/Phrasea/Controller/Thesaurus/ThesaurusXmlHttpController.php
	lib/Alchemy/Phrasea/Core/Event/Subscriber/RecordEditSubscriber.php
	lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php
	lib/Alchemy/Phrasea/Model/Manipulator/LazaretManipulator.php
	lib/classes/record/adapter.php
	resources/ansible/roles/app/tasks/main.yml
	resources/www/prod/js/jquery.Edit.js
	resources/www/prod/js/jquery.main-prod.js
	resources/www/prod/skins/ui-components/_answers-tools.scss
	templates/web/common/dialog_export.html.twig
	templates/web/prod/thesaurus.js.twig
This commit is contained in:
Thibaud Fabre
2016-09-28 19:52:15 +02:00
43 changed files with 1046 additions and 402 deletions

View File

@@ -1,16 +1,23 @@
install: install:
make install_composer make install_composer
make clean_assets
make install_asset_dependencies
make install_assets make install_assets
install_composer: install_composer:
composer install composer install
install_asset_dependencies:
npm install
./node_modules/.bin/gulp build
install_assets: install_assets:
./node_modules/.bin/gulp install-assets
clean_assets:
rm -rf ./node_modules rm -rf ./node_modules
rm -rf ./www/assets rm -rf ./www/assets
rm -rf ./www/bower_components rm -rf ./www/bower_components
npm install
./node_modules/bin/gulp build
config: config:
@php bin/console compile:configuration @php bin/console compile:configuration

10
Vagrantfile vendored
View File

@@ -26,12 +26,10 @@ def config_net(config)
"dev." + $hostname + ".vb" "dev." + $hostname + ".vb"
] ]
#config.vm.network :public_network, type: "dhcp", bridge: "en0: Ethernet"
# Assign static IP if present in network config # Assign static IP if present in network config
if File.file?($root + "/.network.conf") if File.file?($root + "/.network.conf")
ipAddress = File.read($root + "/.network.conf") ipAddress = File.read($root + "/.network.conf")
config.vm.network :private_network, ip: ipAddress #config.vm.network :private_network, ip: ipAddress
else else
# vboxnet0 can be changed to use a specific private_network # vboxnet0 can be changed to use a specific private_network
config.vm.network :private_network, type: "dhcp" config.vm.network :private_network, type: "dhcp"
@@ -48,6 +46,7 @@ end
# By default, the name of the VM is the project's directory name # By default, the name of the VM is the project's directory name
$hostname = File.basename($root).downcase $hostname = File.basename($root).downcase
$hostIps = `ip addr show | grep inet | grep -v inet6 | cut -d' ' -f6 | cut -d'/' -f1`.split("\n");
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
@@ -80,9 +79,10 @@ Vagrant.configure("2") do |config|
config.vm.provision "ansible" do |ansible| config.vm.provision "ansible" do |ansible|
ansible.playbook = "resources/ansible/playbook.yml" ansible.playbook = "resources/ansible/playbook.yml"
ansible.limit = 'all' ansible.limit = 'all'
ansible.verbose = 'v' ansible.verbose = 'vvv'
ansible.extra_vars = { ansible.extra_vars = {
hostname: $hostname, hostname: $hostname,
host_addresses: $hostIps,
postfix: { postfix: {
postfix_domain: $hostname + ".vb" postfix_domain: $hostname + ".vb"
} }
@@ -92,7 +92,9 @@ Vagrant.configure("2") do |config|
config.vm.provision "ansible", run: "always" do |ansible| config.vm.provision "ansible", run: "always" do |ansible|
ansible.playbook = "resources/ansible/playbook-always.yml" ansible.playbook = "resources/ansible/playbook-always.yml"
ansible.limit = 'all' ansible.limit = 'all'
ansible.verbose = 'vvv'
ansible.extra_vars = { ansible.extra_vars = {
host_addresses: $hostIps,
hostname: $hostname hostname: $hostname
} }
end end

View File

@@ -11,6 +11,7 @@
namespace KonsoleKommander; namespace KonsoleKommander;
use Alchemy\Phrasea\Command\Setup\ConfigurationEditor;
use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Core\Version;
use Alchemy\Phrasea\Command\UpgradeDBDatas; use Alchemy\Phrasea\Command\UpgradeDBDatas;
use Alchemy\Phrasea\Command\Setup\Install; use Alchemy\Phrasea\Command\Setup\Install;
@@ -24,6 +25,7 @@ use Alchemy\Phrasea\Command\Plugin\DisablePlugin;
use Alchemy\Phrasea\CLI; use Alchemy\Phrasea\CLI;
use Alchemy\Phrasea\Command\Setup\CheckEnvironment; use Alchemy\Phrasea\Command\Setup\CheckEnvironment;
use Alchemy\Phrasea\Core\CLIProvider\DoctrineMigrationServiceProvider; use Alchemy\Phrasea\Core\CLIProvider\DoctrineMigrationServiceProvider;
use Alchemy\Phrasea\Setup\ConfigurationTester;
require_once __DIR__ . '/../vendor/autoload.php'; require_once __DIR__ . '/../vendor/autoload.php';
@@ -53,16 +55,16 @@ $app->register(new DoctrineMigrationServiceProvider());
$app->command(new \module_console_aboutAuthors('about:authors')); $app->command(new \module_console_aboutAuthors('about:authors'));
$app->command(new \module_console_aboutLicense('about:license')); $app->command(new \module_console_aboutLicense('about:license'));
if( /** @var ConfigurationTester $configurationTester */
$app['phraseanet.configuration-tester']->isMigrable() $configurationTester = $app['phraseanet.configuration-tester'];
|| $app['phraseanet.configuration-tester']->isUpgradable()
|| $app['phraseanet.configuration-tester']->isInstalled() if($configurationTester->isMigrable() || $configurationTester->isUpgradable() || $configurationTester->isInstalled()) {
) {
$app->command(new \module_console_systemUpgrade('system:upgrade')); $app->command(new \module_console_systemUpgrade('system:upgrade'));
} }
if ($app['phraseanet.configuration-tester']->isInstalled()) { if ($configurationTester->isInstalled()) {
$app->command(new UpgradeDBDatas('system:upgrade-datas')); $app->command(new UpgradeDBDatas('system:upgrade-datas'));
$app->command(new ConfigurationEditor('system:config'));
} }
$app->command(new AddPlugin()); $app->command(new AddPlugin());

707
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@ main:
languages: [] languages: []
key: '' key: ''
api_require_ssl: true api_require_ssl: true
api_disabled: true
database: database:
host: 127.0.0.1 host: 127.0.0.1
port: 3306 port: 3306
@@ -191,6 +192,7 @@ api_cors:
expose_headers: [] expose_headers: []
max_age: 0 max_age: 0
hosts: [] hosts: []
api_cors_paths: []
session: session:
idle: 0 idle: 0
lifetime: 604800 # 1 week lifetime: 604800 # 1 week

View File

@@ -11,9 +11,12 @@
namespace Alchemy\Phrasea\Collection; namespace Alchemy\Phrasea\Collection;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Authentication\ACLProvider;
use Alchemy\Phrasea\Collection\Reference\CollectionReference; use Alchemy\Phrasea\Collection\Reference\CollectionReference;
use Alchemy\Phrasea\Databox\DataboxConnectionProvider; use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
class CollectionService class CollectionService
@@ -23,15 +26,31 @@ class CollectionService
*/ */
private $app; private $app;
/**
* @var Connection
*/
private $connection; private $connection;
/**
* @var DataboxConnectionProvider
*/
private $connectionProvider; private $connectionProvider;
public function __construct(Application $application, Connection $connection, DataboxConnectionProvider $connectionProvider) /**
{ * @var callable
*/
private $userQueryFactory;
public function __construct(
Application $application,
Connection $connection,
DataboxConnectionProvider $connectionProvider,
callable $userQueryFactory
) {
$this->app = $application; $this->app = $application;
$this->connection = $connection; $this->connection = $connection;
$this->connectionProvider = $connectionProvider; $this->connectionProvider = $connectionProvider;
$this->userQueryFactory = $userQueryFactory;
} }
/** /**
@@ -270,4 +289,53 @@ class CollectionService
$this->app->getAclForUser($user)->update_rights_to_base($reference->getBaseId(), $rights); $this->app->getAclForUser($user)->update_rights_to_base($reference->getBaseId(), $rights);
} }
public function setOrderMasters(CollectionReference $reference, array $userIds)
{
/** @var UserRepository $userRepository */
$userRepository = $this->app['repo.users'];
$users = $userRepository->findBy(['id' => $userIds]);
$missingAdmins = array_diff($userIds, array_map(function (User $user) {
return $user->getId();
}, $users));
if (! empty($missingAdmins)) {
throw new RuntimeException(sprintf('Invalid usrIds provided [%s].', implode(',', $missingAdmins)));
}
$admins = $users;
/** @var Connection $conn */
$conn = $this->app->getApplicationBox()->get_connection();
$conn->beginTransaction();
try {
$factory = $this->userQueryFactory;
/** @var \User_Query $userQuery */
$userQuery = $factory();
$result = $userQuery->on_base_ids([ $reference->getBaseId()] )
->who_have_right(['order_master'])
->execute()->get_results();
/** @var ACLProvider $acl */
$acl = $this->app['acl'];
foreach ($result as $user) {
$acl->get($user)->update_rights_to_base($reference->getBaseId(), ['order_master' => false]);
}
foreach ($admins as $admin) {
$acl->get($admin)->update_rights_to_base($reference->getBaseId(), ['order_master' => true]);
}
$conn->commit();
} catch (\Exception $e) {
$conn->rollBack();
throw $e;
}
}
} }

View File

@@ -0,0 +1,178 @@
<?php
namespace Alchemy\Phrasea\Command\Setup;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Core\Configuration\Configuration;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Yaml;
class ConfigurationEditor extends Command
{
public function __construct($name)
{
parent::__construct($name);
}
protected function configure()
{
$this->addArgument(
'operation',
InputArgument::REQUIRED,
'The operation to execute (get, set, or add)'
);
$this->addArgument(
'parameter',
InputArgument::REQUIRED,
'The name of the configuration parameter to get or set'
);
$this->addArgument(
'value',
InputArgument::OPTIONAL,
'The value to set when operation is "set" or "add", in YAML syntax'
);
}
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$command = $input->getArgument('operation');
$parameter = $input->getArgument('parameter');
$parameterNodes = explode('.', $parameter);
if ($command == 'get') {
$this->readConfigurationValue($output, $parameter, $parameterNodes);
}
elseif ($command == 'set') {
$this->writeConfigurationValue($output, $parameter, $parameterNodes, $input->getArgument('value'));
}
elseif ($command == 'add') {
$this->appendConfigurationValue($output, $parameter, $parameterNodes, $input->getArgument('value'));
}
}
private function readConfigurationValue(OutputInterface $output, $parameter, array $parameterNodes)
{
$app = $this->getContainer();
/** @var Configuration $config */
$config = $app['configuration.store'];
$values = $config->getConfig();
$current = $values;
foreach ($parameterNodes as $paramName) {
$current = $current[$paramName];
}
$output->writeln('<info>Getting configuration entry</info> ' . $parameter);
$this->printConfigurationValue($output, $parameter, $current);
}
private function writeConfigurationValue(OutputInterface $output, $parameter, array $parameterNodes, $value)
{
$app = $this->getContainer();
/** @var Configuration $configurationStore */
$configurationStore = $app['configuration.store'];
$lastParameter = end($parameterNodes);
$configurationRoot = $configurationStore->getConfig();
$configurationCurrent = & $configurationRoot;
$output->writeln('<info>Writing value to configuration entry</info> ' . $parameter);
foreach ($parameterNodes as $paramName) {
if (! isset($configurationCurrent[$paramName])) {
$configurationCurrent[$paramName] = array();
}
if ($lastParameter == $paramName) {
$configurationCurrent[$paramName] = Yaml::parse($value);
}
else {
$configurationCurrent = & $configurationCurrent[$paramName];
}
}
$configurationStore->setConfig($configurationRoot);
$configurationStore->compileAndWrite();
$output->writeln('<comment>Reading updated configuration value</comment>');
$this->readConfigurationValue($output, $parameter, $parameterNodes);
}
private function appendConfigurationValue(OutputInterface $output, $parameter, array $parameterNodes, $value)
{
$app = $this->getContainer();
/** @var Configuration $configurationStore */
$configurationStore = $app['configuration.store'];
$lastParameter = end($parameterNodes);
$configurationRoot = $configurationStore->getConfig();
$configurationCurrent = & $configurationRoot;
$output->writeln('<info>Appending value to configuration entry</info> ' . $parameter);
foreach ($parameterNodes as $paramName) {
if (! isset($configurationCurrent[$paramName])) {
$configurationCurrent[$paramName] = array();
}
if ($lastParameter == $paramName) {
if (! is_array($configurationCurrent[$paramName])) {
$configurationCurrent[$paramName] = array($configurationCurrent[$paramName]);
}
$parsedValue = Yaml::parse($value);
if (! is_array($parsedValue)) {
$parsedValue = [ $parsedValue ];
}
$configurationCurrent[$paramName] = array_merge($configurationCurrent[$paramName], $parsedValue);
$configurationCurrent[$paramName] = array_unique($configurationCurrent[$paramName]);
}
else {
$configurationCurrent = & $configurationCurrent[$paramName];
}
}
$configurationStore->setConfig($configurationRoot);
$configurationStore->compileAndWrite();
$output->writeln('<comment>Reading updated configuration value</comment>');
$this->readConfigurationValue($output, $parameter, $parameterNodes);
}
private function printConfigurationValue(OutputInterface $output, $name, $value, $indent = 0)
{
if ($indent > 0) {
$output->write(PHP_EOL);
}
$output->write(str_repeat(' ', $indent * 4) . (is_numeric($name) ? '- ' : $name . ': '));
if (is_array($value)) {
if (empty($value)) {
$output->write('[]');
}
foreach ($value as $valueName => $valueItem) {
$this->printConfigurationValue($output, $valueName, $valueItem, $indent + 1);
}
}
else {
$output->write(var_export($value));
}
if ($indent == 0) {
$output->write(PHP_EOL);
}
}
}

View File

@@ -10,13 +10,10 @@
namespace Alchemy\Phrasea\Controller\Admin; namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Application\Helper\UserQueryAware; use Alchemy\Phrasea\Application\Helper\UserQueryAware;
use Alchemy\Phrasea\Authentication\ACLProvider; use Alchemy\Phrasea\Collection\CollectionService;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
@@ -24,6 +21,18 @@ class CollectionController extends Controller
{ {
use UserQueryAware; use UserQueryAware;
/**
* @var CollectionService
*/
private $collectionService;
public function __construct(Application $application, CollectionService $collectionService)
{
parent::__construct($application);
$this->collectionService = $collectionService;
}
/** /**
* Display collection information page * Display collection information page
* *
@@ -79,52 +88,23 @@ class CollectionController extends Controller
*/ */
public function setOrderAdmins(Request $request, $bas_id) public function setOrderAdmins(Request $request, $bas_id)
{ {
$admins = array_values($request->request->get('admins', [])); $admins = array_filter(
array_values($request->request->get('admins', [])),
function ($value) { return $value != false; }
);
if (count($admins) === 0) { if (false && count($admins) === 0) {
$this->app->abort(400, 'No admins provided.'); $this->app->abort(400, 'No admins provided.');
} }
if (!is_array($admins)) { if (!is_array($admins)) {
$this->app->abort(400, 'Admins must be an array.'); $this->app->abort(400, 'Admins must be an array.');
} }
/** @var UserRepository $userRepository */ $collection = $this->getApplicationBox()->get_collection($bas_id);
$userRepository = $this->app['repo.users']; $collectionReference = $collection->getReference();
$users = $userRepository->findBy(['id' => $admins]);
$userIds = array_map(function (User $user) {
return $user->getId();
}, $users);
$missingAdmins = array_diff($admins, $userIds);
if (!empty($missingAdmins)) {
throw new RuntimeException(sprintf('Invalid usrId %s provided.', reset($missingAdmins)));
}
$admins = $users;
/** @var Connection $conn */ $this->collectionService->setOrderMasters($collectionReference, $admins);
$conn = $this->app->getApplicationBox()->get_connection();
$conn->beginTransaction();
try {
$userQuery = $this->createUserQuery();
$result = $userQuery->on_base_ids([$bas_id])
->who_have_right(['order_master'])
->execute()->get_results();
/** @var ACLProvider $acl */
$acl = $this->app['acl'];
foreach ($result as $user) {
$acl->get($user)->update_rights_to_base($bas_id, ['order_master' => false]);
}
foreach ($admins as $admin) {
$acl->get($admin)->update_rights_to_base($bas_id, ['order_master' => true]);
}
$conn->commit();
} catch (\Exception $e) {
$conn->rollBack();
throw $e;
}
return $this->app->redirectPath('admin_display_collection', [ return $this->app->redirectPath('admin_display_collection', [
'bas_id' => $bas_id, 'bas_id' => $bas_id,

View File

@@ -484,6 +484,16 @@ class V1Controller extends Controller
private function listCollection(\collection $collection) private function listCollection(\collection $collection)
{ {
$userQuery = new \User_Query($this->app);
$orderMasters = $userQuery->on_base_ids([ $collection->get_base_id() ] )
->who_have_right(['order_master'])
->execute()
->get_results()
->map(function (User $user) {
return $user->getEmail();
})
->toArray();
return [ return [
'base_id' => $collection->get_base_id(), 'base_id' => $collection->get_base_id(),
'databox_id' => $collection->get_sbas_id(), 'databox_id' => $collection->get_sbas_id(),
@@ -496,6 +506,7 @@ class V1Controller extends Controller
'nl' => $collection->get_label('nl'), 'nl' => $collection->get_label('nl'),
], ],
'record_amount' => $collection->get_record_amount(), 'record_amount' => $collection->get_record_amount(),
'order_managers' => $orderMasters
]; ];
} }
@@ -1103,6 +1114,7 @@ class V1Controller extends Controller
'results.stories' => $storyTransformer, 'results.stories' => $storyTransformer,
'results.stories.thumbnail' => $subdefTransformer, 'results.stories.thumbnail' => $subdefTransformer,
'results.stories.metadatas' => new CallbackTransformer(), 'results.stories.metadatas' => new CallbackTransformer(),
'results.stories.caption' => new CallbackTransformer(),
'results.stories.records' => $recordTransformer, 'results.stories.records' => $recordTransformer,
'results.stories.records.thumbnail' => $subdefTransformer, 'results.stories.records.thumbnail' => $subdefTransformer,
'results.stories.records.technical_informations' => $technicalDataTransformer, 'results.stories.records.technical_informations' => $technicalDataTransformer,
@@ -1118,6 +1130,7 @@ class V1Controller extends Controller
'results.records.status' => new CallbackTransformer(), 'results.records.status' => new CallbackTransformer(),
'results.records.caption' => new CallbackTransformer(), 'results.records.caption' => new CallbackTransformer(),
]); ]);
$includeResolver = new IncludeResolver($transformerResolver); $includeResolver = new IncludeResolver($transformerResolver);
$fractal = new \League\Fractal\Manager(); $fractal = new \League\Fractal\Manager();
@@ -1244,7 +1257,8 @@ class V1Controller extends Controller
} }
} }
if (in_array('results.stories.metadatas', $includes, true)) { if (in_array('results.stories.metadatas', $includes, true) ||
in_array('results.stories.caption', $includes, true)) {
$captions = $this->app['service.caption']->findByReferenceCollection($stories); $captions = $this->app['service.caption']->findByReferenceCollection($stories);
$canSeeBusiness = $this->retrieveSeeBusinessPerDatabox($stories); $canSeeBusiness = $this->retrieveSeeBusinessPerDatabox($stories);
@@ -1407,20 +1421,32 @@ class V1Controller extends Controller
*/ */
private function resolveSearchIncludes(Request $request) private function resolveSearchIncludes(Request $request)
{ {
$includes = [
'results.stories.records'
];
if ($request->attributes->get('_extended', false)) { if ($request->attributes->get('_extended', false)) {
return [ if ($request->get('search_type') != SearchEngineOptions::RECORD_STORY) {
$includes = array_merge($includes, [
'results.stories.records.subdefs', 'results.stories.records.subdefs',
'results.stories.records.metadata', 'results.stories.records.metadata',
'results.stories.records.caption', 'results.stories.records.caption',
'results.stories.records.status', 'results.stories.records.status'
]);
}
else {
$includes = [ 'results.stories.caption' ];
}
$includes = array_merge($includes, [
'results.records.subdefs', 'results.records.subdefs',
'results.records.metadata', 'results.records.metadata',
'results.records.caption', 'results.records.caption',
'results.records.status', 'results.records.status'
]; ]);
} }
return []; return $includes;
} }
/** /**
@@ -1436,7 +1462,7 @@ class V1Controller extends Controller
'results.subdefs', 'results.subdefs',
'results.metadata', 'results.metadata',
'results.caption', 'results.caption',
'results.status', 'results.status'
]; ];
} }

View File

@@ -27,7 +27,6 @@ class Controller
$this->app = $app; $this->app = $app;
} }
/** /**
* @return \appbox * @return \appbox
*/ */

View File

@@ -9,24 +9,12 @@
*/ */
namespace Alchemy\Phrasea\Controller; namespace Alchemy\Phrasea\Controller;
class LazyLocator /**
{ * Class LazyLocator
/** @var \Pimple */ * @package Alchemy\Phrasea\Controller
private $pimple; * @deprecated Use Alchemy\Phrasea\Core\LazyLocator
private $serviceId;
/**
* @param \Pimple $pimple
* @param string $serviceId
*/ */
public function __construct(\Pimple $pimple, $serviceId) class LazyLocator extends \Alchemy\Phrasea\Core\LazyLocator
{ {
$this->pimple = $pimple; // Stub left for BC
$this->serviceId = $serviceId;
}
public function __invoke()
{
return $this->pimple->offsetGet($this->serviceId);
}
} }

View File

@@ -42,6 +42,7 @@ class DoDownloadController extends Controller
if (false === $list = @unserialize($token->getData())) { if (false === $list = @unserialize($token->getData())) {
$this->app->abort(500, 'Invalid datas'); $this->app->abort(500, 'Invalid datas');
} }
if (!is_array($list)) { if (!is_array($list)) {
$this->app->abort(500, 'Invalid datas'); $this->app->abort(500, 'Invalid datas');
} }

View File

@@ -14,6 +14,8 @@ use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Application\Helper\SubDefinitionSubstituerAware; use Alchemy\Phrasea\Application\Helper\SubDefinitionSubstituerAware;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Controller\RecordsRequest; use Alchemy\Phrasea\Controller\RecordsRequest;
use Alchemy\Phrasea\Core\Event\Record\RecordEvents;
use Alchemy\Phrasea\Core\Event\Record\StoryCoverChangedEvent;
use Alchemy\Phrasea\Core\Event\RecordEdit; use Alchemy\Phrasea\Core\Event\RecordEdit;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Model\Entities\Preset; use Alchemy\Phrasea\Model\Entities\Preset;
@@ -295,6 +297,7 @@ class EditController extends Controller
$newsubdef_reg = new \record_adapter($this->app, $reg_record->getDataboxId(), $request->request->get('newrepresent')); $newsubdef_reg = new \record_adapter($this->app, $reg_record->getDataboxId(), $request->request->get('newrepresent'));
$subdefChanged = false;
foreach ($newsubdef_reg->get_subdefs() as $name => $value) { foreach ($newsubdef_reg->get_subdefs() as $name => $value) {
if (!in_array($name, ['thumbnail', 'preview'])) { if (!in_array($name, ['thumbnail', 'preview'])) {
continue; continue;
@@ -304,14 +307,18 @@ class EditController extends Controller
} }
$media = $this->app->getMediaFromUri($value->getRealPath()); $media = $this->app->getMediaFromUri($value->getRealPath());
$this->getSubDefinitionSubstituer()->substitute($reg_record, $name, $media); $this->getSubDefinitionSubstituer()->substituteSubdef($reg_record, $name, $media);
$this->getDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($reg_record));
$this->getDataboxLogger($reg_record->getDatabox())->log( $this->getDataboxLogger($reg_record->getDatabox())->log(
$reg_record, $reg_record,
\Session_Logger::EVENT_SUBSTITUTE, \Session_Logger::EVENT_SUBSTITUTE,
$name == 'document' ? 'HD' : $name, $name,
'' ''
); );
$subdefChanged = true;
}
if($subdefChanged) {
$this->dispatch(RecordEvents::STORY_COVER_CHANGED, new StoryCoverChangedEvent($reg_record, $newsubdef_reg));
$this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($reg_record));
} }
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -348,7 +355,7 @@ class EditController extends Controller
if (isset($rec['metadatas']) && is_array($rec['metadatas'])) { if (isset($rec['metadatas']) && is_array($rec['metadatas'])) {
$record->set_metadatas($rec['metadatas']); $record->set_metadatas($rec['metadatas']);
$this->getDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record)); $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record));
} }
$newstat = $record->getStatus(); $newstat = $record->getStatus();

View File

@@ -1834,7 +1834,7 @@ class ThesaurusController extends Controller
$this->renumerate($newte, $ct->getAttribute("id") . "." . $teid, $chgids); $this->renumerate($newte, $ct->getAttribute("id") . "." . $teid, $chgids);
$databox->saveThesaurus($domth); $databox->saveCterms($domct);
$this->dispatch( $this->dispatch(
ThesaurusEvents::CONCEPT_TRASHED, ThesaurusEvents::CONCEPT_TRASHED,
@@ -1843,7 +1843,7 @@ class ThesaurusController extends Controller
$thnode_parent->removeChild($thnode); $thnode_parent->removeChild($thnode);
$databox->saveCterms($domct); $databox->saveThesaurus($domth);
$r = $refresh_list->appendChild($ret->createElement("refresh")); $r = $refresh_list->appendChild($ret->createElement("refresh"));
$r->setAttribute("id", $pid); $r->setAttribute("id", $pid);

View File

@@ -1463,7 +1463,12 @@ class ThesaurusXmlHttpController extends Controller
public function searchTermJson(Request $request) public function searchTermJson(Request $request)
{ {
$lng = $request->get('lng'); if (null === $lng = $request->get('lng')) {
$data = explode('_', $this->app['locale']);
if (count($data) > 0) {
$lng = $data[0];
}
}
$html = ''; $html = '';
$sbid = (int) $request->get('sbid'); $sbid = (int) $request->get('sbid');
@@ -1507,9 +1512,8 @@ class ThesaurusXmlHttpController extends Controller
if ($t[1]) { if ($t[1]) {
$q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[1])) . '\')'; $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($unicode->remove_indexer_chars($t[1])) . '\')';
} }
if($lng !== null) {
$q2 .= ' and @lng=\'' . \thesaurus::xquery_escape($lng) . '\''; $q2 .= ' and @lng=\'' . \thesaurus::xquery_escape($lng) . '\'';
}
$q .= ('//sy[' . $q2 . ']'); $q .= ('//sy[' . $q2 . ']');
$nodes = $xpath->query($q); $nodes = $xpath->query($q);

View File

@@ -27,7 +27,7 @@ class Collection implements ControllerProviderInterface, ServiceProviderInterfac
public function register(Application $app) public function register(Application $app)
{ {
$app['controller.admin.collection'] = $app->share(function (PhraseaApplication $app) { $app['controller.admin.collection'] = $app->share(function (PhraseaApplication $app) {
return (new CollectionController($app)) return (new CollectionController($app, $app->getApplicationBox()->getCollectionService()))
->setUserQueryFactory(new LazyLocator($app, 'phraseanet.user-query')) ->setUserQueryFactory(new LazyLocator($app, 'phraseanet.user-query'))
; ;
}); });

View File

@@ -85,7 +85,7 @@ class DatabaseMaintenanceService
$ref_engine = strtolower($foundTable['Engine']); $ref_engine = strtolower($foundTable['Engine']);
if ($engine != $ref_engine && in_array($engine, ['innodb', 'myisam'])) { if ($engine != $ref_engine && in_array($engine, ['innodb', 'myisam'])) {
$recommends = $this->alterTableEngine($tableName, $engine, $recommends); $this->alterTableEngine($tableName, $engine, $recommends);
} }
$ret = $this->upgradeTable($allTables[$tableName]); $ret = $this->upgradeTable($allTables[$tableName]);

View File

@@ -30,4 +30,6 @@ final class RecordEvents
const SUB_DEFINITION_CREATION_FAILED = 'record.sub_definition_creation_failed'; const SUB_DEFINITION_CREATION_FAILED = 'record.sub_definition_creation_failed';
const MEDIA_SUBSTITUTED = 'record.media_substituted'; const MEDIA_SUBSTITUTED = 'record.media_substituted';
const STORY_COVER_CHANGED = 'record.story_cover_changed';
} }

View File

@@ -0,0 +1,45 @@
<?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\Core\Event\Record;
use record_adapter;
use Symfony\Component\EventDispatcher\Event;
class StoryCoverChangedEvent extends Event
{
/** @var record_adapter $record */
private $story_record;
/** @var record_adapter $record */
private $cover_record;
public function __construct(record_adapter $story_record, record_adapter $cover_record)
{
$this->story_record = $story_record;
$this->cover_record = $cover_record;
}
/**
* @return record_adapter
*/
public function getStoryRecord()
{
return $this->story_record;
}
/**
* @return record_adapter
*/
public function getCoverRecord()
{
return $this->cover_record;
}
}

View File

@@ -0,0 +1,41 @@
<?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\Core;
class LazyLocator
{
/**
* @var \Pimple
*/
private $pimple;
/**
* @var string
*/
private $serviceId;
/**
* @param \Pimple $pimple
* @param string $serviceId
*/
public function __construct(\Pimple $pimple, $serviceId)
{
$this->pimple = $pimple;
$this->serviceId = $serviceId;
}
/**
* @return mixed
*/
public function __invoke()
{
return $this->pimple->offsetGet($this->serviceId);
}
}

View File

@@ -91,6 +91,12 @@ class HttpStackMetaProvider implements ServiceProviderInterface
unset($config['enabled']); unset($config['enabled']);
$paths['/api/v\d+/'] = $config; $paths['/api/v\d+/'] = $config;
$paths['/download/'] = $config;
}
if (isset($app['phraseanet.configuration']['api_cors_paths'])) {
foreach ($app['phraseanet.configuration']['api_cors_paths'] as $path) {
$paths[$path] = $config;
}
} }
} }

View File

@@ -54,7 +54,6 @@ class IncludeResolver
private function figureOutWhichIncludes(ResourceTransformerAccessibleScope $scope) private function figureOutWhichIncludes(ResourceTransformerAccessibleScope $scope)
{ {
$transformer = $scope->getResourceTransformer(); $transformer = $scope->getResourceTransformer();
$includes = $transformer->getDefaultIncludes(); $includes = $transformer->getDefaultIncludes();
foreach ($transformer->getAvailableIncludes() as $include) { foreach ($transformer->getAvailableIncludes() as $include) {

View File

@@ -28,9 +28,10 @@ class TokenRepository extends EntityRepository
WHERE t.type = :type WHERE t.type = :type
AND t.user = :user AND t.user = :user
AND t.data = :basket_id AND t.data = :basket_id
AND (t.expiration > CURRENT_TIMESTAMP() OR t.expiration IS NULL)'; AND (t.expiration > CURRENT_TIMESTAMP() OR t.expiration IS NULL) ORDER BY t.created DESC';
$query = $this->_em->createQuery($dql); $query = $this->_em->createQuery($dql);
$query->setMaxResults(1);
$query->setParameters([ $query->setParameters([
':type' => TokenManipulator::TYPE_VALIDATE, ':type' => TokenManipulator::TYPE_VALIDATE,
':user' => $user, ':user' => $user,
@@ -49,9 +50,10 @@ class TokenRepository extends EntityRepository
{ {
$dql = 'SELECT t FROM Phraseanet:Token t $dql = 'SELECT t FROM Phraseanet:Token t
WHERE t.value = :value WHERE t.value = :value
AND (t.expiration IS NULL OR t.expiration >= CURRENT_TIMESTAMP())'; AND (t.expiration IS NULL OR t.expiration >= CURRENT_TIMESTAMP()) ORDER BY t.created DESC';
$query = $this->_em->createQuery($dql); $query = $this->_em->createQuery($dql);
$query->setMaxResults(1);
$query->setParameters([':value' => $value]); $query->setParameters([':value' => $value]);
return $query->getOneOrNullResult(); return $query->getOneOrNullResult();

View File

@@ -15,6 +15,7 @@ use League\Fractal\TransformerAbstract;
class RecordTransformer extends TransformerAbstract class RecordTransformer extends TransformerAbstract
{ {
protected $availableIncludes = ['thumbnail', 'technical_informations', 'subdefs', 'metadata', 'status', 'caption']; protected $availableIncludes = ['thumbnail', 'technical_informations', 'subdefs', 'metadata', 'status', 'caption'];
protected $defaultIncludes = ['thumbnail', 'technical_informations']; protected $defaultIncludes = ['thumbnail', 'technical_informations'];
/** /**

View File

@@ -15,8 +15,15 @@ use League\Fractal\TransformerAbstract;
class StoryTransformer extends TransformerAbstract class StoryTransformer extends TransformerAbstract
{ {
protected $availableIncludes = ['thumbnail', 'metadatas', 'records']; /**
protected $defaultIncludes = ['thumbnail', 'metadatas', 'records']; * @var array
*/
protected $availableIncludes = ['thumbnail', 'metadatas', 'records', 'caption'];
/**
* @var array
*/
protected $defaultIncludes = ['thumbnail', 'metadatas'];
/** /**
* @var SubdefTransformer * @var SubdefTransformer
@@ -51,6 +58,7 @@ class StoryTransformer extends TransformerAbstract
'collection_id' => $story->getCollectionId(), 'collection_id' => $story->getCollectionId(),
'base_id' => $story->getBaseId(), 'base_id' => $story->getBaseId(),
'uuid' => $story->getUuid(), 'uuid' => $story->getUuid(),
'record_count' => count($storyView->getChildren())
]; ];
} }
@@ -61,7 +69,7 @@ class StoryTransformer extends TransformerAbstract
public function includeMetadatas(StoryView $storyView) public function includeMetadatas(StoryView $storyView)
{ {
return $this->item($storyView->getCaption(), $this->getCaptionTransformer()); return $this->item($storyView->getCaption(), $this->getCaptionDCFieldTransformer());
} }
public function includeRecords(StoryView $storyView) public function includeRecords(StoryView $storyView)
@@ -69,10 +77,29 @@ class StoryTransformer extends TransformerAbstract
return $this->collection($storyView->getChildren(), $this->recordTransformer); return $this->collection($storyView->getChildren(), $this->recordTransformer);
} }
public function includeCaption(StoryView $storyView)
{
return $this->collection($storyView->getCaption()->getFields(), $this->getCaptionFieldTransformer());
}
/** /**
* @return \Closure * @return \Closure
*/ */
private function getCaptionTransformer() private function getCaptionFieldTransformer()
{
return function (\caption_field $captionField) {
return [
'meta_structure_id' => $captionField->get_meta_struct_id(),
'name' => $captionField->get_name(),
'value' => $captionField->get_serialized_values(';')
];
};
}
/**
* @return \Closure
*/
private function getCaptionDCFieldTransformer()
{ {
/** /**
* @param \caption_field[] $fields * @param \caption_field[] $fields

View File

@@ -31,7 +31,6 @@ class StoryView
*/ */
public function __construct(\record_adapter $story) public function __construct(\record_adapter $story)
{ {
$this->story = $story; $this->story = $story;
} }

View File

@@ -14,13 +14,21 @@ use League\Fractal\TransformerAbstract;
class V1SearchCompositeResultTransformer extends TransformerAbstract class V1SearchCompositeResultTransformer extends TransformerAbstract
{ {
/**
* @var string[]
*/
protected $availableIncludes = ['stories', 'records']; protected $availableIncludes = ['stories', 'records'];
/**
* @var string[]
*/
protected $defaultIncludes = ['stories', 'records']; protected $defaultIncludes = ['stories', 'records'];
/** /**
* @var RecordTransformer * @var RecordTransformer
*/ */
private $recordTransformer; private $recordTransformer;
/** /**
* @var StoryTransformer * @var StoryTransformer
*/ */

View File

@@ -24,6 +24,7 @@ class SearchEngineOptions
{ {
const RECORD_RECORD = 0; const RECORD_RECORD = 0;
const RECORD_GROUPING = 1; const RECORD_GROUPING = 1;
const RECORD_STORY = 2;
const TYPE_IMAGE = 'image'; const TYPE_IMAGE = 'image';
const TYPE_VIDEO = 'video'; const TYPE_VIDEO = 'video';
const TYPE_AUDIO = 'audio'; const TYPE_AUDIO = 'audio';
@@ -296,6 +297,7 @@ class SearchEngineOptions
$this->search_type = self::RECORD_RECORD; $this->search_type = self::RECORD_RECORD;
break; break;
case self::RECORD_GROUPING: case self::RECORD_GROUPING:
case self::RECORD_STORY:
$this->search_type = self::RECORD_GROUPING; $this->search_type = self::RECORD_GROUPING;
break; break;
} }

View File

@@ -13,6 +13,7 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Collection\CollectionService; use Alchemy\Phrasea\Collection\CollectionService;
use Alchemy\Phrasea\Core\Configuration\AccessRestriction; use Alchemy\Phrasea\Core\Configuration\AccessRestriction;
use Alchemy\Phrasea\Core\Connection\ConnectionSettings; use Alchemy\Phrasea\Core\Connection\ConnectionSettings;
use Alchemy\Phrasea\Core\LazyLocator;
use Alchemy\Phrasea\Core\Version\AppboxVersionRepository; use Alchemy\Phrasea\Core\Version\AppboxVersionRepository;
use Alchemy\Phrasea\Databox\DataboxConnectionProvider; use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
use Alchemy\Phrasea\Databox\DataboxRepository; use Alchemy\Phrasea\Databox\DataboxRepository;
@@ -325,7 +326,8 @@ class appbox extends base
$this->collectionService = new CollectionService( $this->collectionService = new CollectionService(
$this->app, $this->app,
$this->connection, $this->connection,
new DataboxConnectionProvider($this) new DataboxConnectionProvider($this),
new LazyLocator($this->app, 'phraseanet.user-query')
); );
} }

View File

@@ -1310,6 +1310,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
@unlink(\p4string::addEndSlash($row['path']) . 'stamp_' . $row['file']); @unlink(\p4string::addEndSlash($row['path']) . 'stamp_' . $row['file']);
} }
$stmt->closeCursor(); $stmt->closeCursor();
return $this; return $this;

View File

@@ -399,16 +399,11 @@ SQL;
throw new Exception('No subdefs given'); throw new Exception('No subdefs given');
} }
$includeBusinessFields = !!$includeBusinessFields; $includeBusinessFields = (bool) $includeBusinessFields;
$files = []; $files = [];
$n_files = 0; $n_files = 0;
$file_names = []; $file_names = [];
$size = 0; $size = 0;
$unicode = new \unicode(); $unicode = new \unicode();
/** @var record_exportElement $download_element */ /** @var record_exportElement $download_element */
@@ -433,7 +428,7 @@ SQL;
$files[$id]['original_name'] = $files[$id]['original_name'] =
$files[$id]['export_name'] = $files[$id]['export_name'] =
$download_element->get_original_name(true); $download_element->get_original_name(false);
$files[$id]['original_name'] = $files[$id]['original_name'] =
trim($files[$id]['original_name']) != '' ? trim($files[$id]['original_name']) != '' ?
@@ -441,16 +436,20 @@ SQL;
$infos = pathinfo($files[$id]['original_name']); $infos = pathinfo($files[$id]['original_name']);
$extension = isset($infos['extension']) ? $infos['extension'] : ''; $extension = isset($infos['extension']) ? $infos['extension'] :
substr($files[$id]['original_name'], 0 - strrpos($files[$id]['original_name'], '.'));
if ($rename_title) { if ($rename_title) {
$title = strip_tags($download_element->get_title(null, null, true)); $title = strip_tags($download_element->get_title(null, null, true));
$files[$id]['export_name'] = $unicode->remove_nonazAZ09($title, true, true, true); $files[$id]['export_name'] = $unicode->remove_nonazAZ09($title, true, true, true);
} else { } else {
$files[$id]["export_name"] = $infos['filename']; $files[$id]["export_name"] = $infos['filename'];
} }
if (substr(strrev($files[$id]['export_name']), 0, strlen($extension)) != strrev($extension)) {
$files[$id]['export_name'] .= '.' . $extension;
}
$sizeMaxAjout = 0; $sizeMaxAjout = 0;
$sizeMaxExt = 0; $sizeMaxExt = 0;
@@ -713,7 +712,7 @@ SQL;
$name = $obj["folder"] $name = $obj["folder"]
. $record["export_name"] . $record["export_name"]
. $obj["ajout"] . $obj["ajout"]
. '.' . $obj["exportExt"]; . (isset($obj["exportExt"]) && trim($obj["exportExt"]) != '' ? '.' . $obj["exportExt"] : '');
$archiveFiles[$app['unicode']->remove_diacritics($name)] = $path; $archiveFiles[$app['unicode']->remove_diacritics($name)] = $path;
if ($o == 'caption') { if ($o == 'caption') {

View File

@@ -6,6 +6,7 @@ main:
maintenance: false maintenance: false
key: '' key: ''
api_require_ssl: true api_require_ssl: true
api_disabled: true
database: database:
host: 'sql-host' host: 'sql-host'
port: 3306 port: 3306

View File

@@ -5,7 +5,7 @@
become_user: vagrant become_user: vagrant
shell: export NVM_DIR="$HOME/.nvm" &&. "$NVM_DIR/nvm.sh" && npm install -g bower recess shell: export NVM_DIR="$HOME/.nvm" &&. "$NVM_DIR/nvm.sh" && npm install -g bower recess
- name: Initialize application dependencies - name: Install Composer dependencies
shell: make install_composer shell: make install_composer
become: yes become: yes
become_user: vagrant become_user: vagrant
@@ -13,7 +13,15 @@
args: args:
chdir: /vagrant/ chdir: /vagrant/
- name: Initialize and build application assets - name: Install assets dependencies
shell: export NVM_DIR="$HOME/.nvm" &&. "$NVM_DIR/nvm.sh" && make install_asset_dependencies
become: yes
become_user: vagrant
ignore_errors: yes
args:
chdir: /vagrant/
- name: Install assets
shell: export NVM_DIR="$HOME/.nvm" &&. "$NVM_DIR/nvm.sh" && make install_assets shell: export NVM_DIR="$HOME/.nvm" &&. "$NVM_DIR/nvm.sh" && make install_assets
become: yes become: yes
become_user: vagrant become_user: vagrant
@@ -21,9 +29,30 @@
args: args:
chdir: /vagrant/ chdir: /vagrant/
- name: Initialize application configuration - name: Run application setup
become: yes become: yes
become_user: vagrant become_user: vagrant
shell: 'bin/setup system:install --email=admin@{{ hostname }}.vb --password=admin --db-host=127.0.0.1 --db-port=3306 --db-user={{ mariadb.user }} --db-password={{ mariadb.password }} --db-template=fr --appbox={{ mariadb.database }} --databox={{ mariadb.databox_db }} --server-name=www.{{ hostname }}.vb --data-path=/vagrant/datas -y' shell: 'bin/setup system:install --email=admin@{{ hostname }}.vb --password=admin --db-host=127.0.0.1 --db-port=3306 --db-user={{ mariadb.user }} --db-password={{ mariadb.password }} --db-template=fr --appbox={{ mariadb.database }} --databox={{ mariadb.databox_db }} --server-name=www.{{ hostname }}.vb --data-path=/vagrant/datas -y'
args: args:
chdir: /vagrant/ chdir: /vagrant/
- name: Enable debugger for host IP addresses
shell: bin/setup system:config add debugger.allowed-ips "{{ item}}"
with_items: '{{ host_addresses }}'
args:
chdir: /vagrant/
- name: Disable API SSL requirement
shell: bin/setup system:config set main.api_require_ssl false
args:
chdir: /vagrant/
- name: Enable API routes
shell: bin/setup system:config set main.api_disabled false
args:
chdir: /vagrant/
- name: Create ElasticSearch indexes
shell: bin/console s:i:c
args:
chdir: /vagrant/

View File

@@ -17,19 +17,21 @@
- name: Install Dependencies - name: Install Dependencies
apt: pkg=oracle-java8-installer state=latest apt: pkg=oracle-java8-installer state=latest
- name: Download - name: Remove temporary debian package
shell: rm -f /tmp/elasticsearch-{{ elasticsearch.version }}.deb
when: not is_installed
- name: Download debian package
get_url: > get_url: >
url={{ elasticsearch_url }} url={{ elasticsearch_url }}
dest=/tmp/elasticsearch-{{ elasticsearch.version }}.deb dest=/tmp/elasticsearch-{{ elasticsearch.version }}.deb
when: not is_installed when: not is_installed
- name: Install - name: Install debian package
apt: deb=/tmp/elasticsearch-{{ elasticsearch.version }}.deb apt: deb=/tmp/elasticsearch-{{ elasticsearch.version }}.deb
when: not is_installed when: not is_installed
- name: Install plugins - name: Install plugins
become: yes
become_user: elasticsearch
shell: /usr/share/elasticsearch/bin/plugin install {{ item.name }}/{{ item.version }} shell: /usr/share/elasticsearch/bin/plugin install {{ item.name }}/{{ item.version }}
when: not is_installed when: not is_installed
with_items: "{{ elasticsearch.plugins }}" with_items: "{{ elasticsearch.plugins }}"

View File

@@ -1567,11 +1567,6 @@
<target state="translated">meine E-Mail Adresse verändern</target> <target state="translated">meine E-Mail Adresse verändern</target>
<jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file> <jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="04d0ff716d072a61412e969b78fe694be13d049f" resname="Changes for rotation will be applied only on the sub-definitions of &quot;image&quot; type.">
<source>Changes for rotation will be applied only on the sub-definitions of "image" type.</source>
<target state="new">Changes for rotation will be applied only on the sub-definitions of "image" type.</target>
<jms:reference-file line="180">actions/Tools/index.html.twig</jms:reference-file>
</trans-unit>
<trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes"> <trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes">
<source>Channels</source> <source>Channels</source>
<target state="translated">Kanäle</target> <target state="translated">Kanäle</target>

View File

@@ -1567,11 +1567,6 @@
<target state="translated">Change my e-mail address</target> <target state="translated">Change my e-mail address</target>
<jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file> <jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="04d0ff716d072a61412e969b78fe694be13d049f" resname="Changes for rotation will be applied only on the sub-definitions of &quot;image&quot; type." approved="yes">
<source>Changes for rotation will be applied only on the sub-definitions of "image" type.</source>
<target state="translated">Rotations are applied only on subviews of "image" type documents.</target>
<jms:reference-file line="180">actions/Tools/index.html.twig</jms:reference-file>
</trans-unit>
<trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes"> <trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes">
<source>Channels</source> <source>Channels</source>
<target state="translated">Channels</target> <target state="translated">Channels</target>

View File

@@ -1567,11 +1567,6 @@
<target state="translated">Changer mon adresse e-mail</target> <target state="translated">Changer mon adresse e-mail</target>
<jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file> <jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="04d0ff716d072a61412e969b78fe694be13d049f" resname="Changes for rotation will be applied only on the sub-definitions of &quot;image&quot; type." approved="yes">
<source>Changes for rotation will be applied only on the sub-definitions of "image" type.</source>
<target state="translated">Les rotations ne sont appliquées qu'aux sous-définitions des documents de type image.</target>
<jms:reference-file line="180">actions/Tools/index.html.twig</jms:reference-file>
</trans-unit>
<trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes"> <trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes">
<source>Channels</source> <source>Channels</source>
<target state="translated">Canaux</target> <target state="translated">Canaux</target>

View File

@@ -1570,11 +1570,6 @@
<target state="translated">Mijn email adres wijzigen</target> <target state="translated">Mijn email adres wijzigen</target>
<jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file> <jms:reference-file line="6">web/account/reset-email.html.twig</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="04d0ff716d072a61412e969b78fe694be13d049f" resname="Changes for rotation will be applied only on the sub-definitions of &quot;image&quot; type.">
<source>Changes for rotation will be applied only on the sub-definitions of "image" type.</source>
<target state="new">Changes for rotation will be applied only on the sub-definitions of "image" type.</target>
<jms:reference-file line="180">actions/Tools/index.html.twig</jms:reference-file>
</trans-unit>
<trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes"> <trans-unit id="18e03e2a37ba37df713f9665ef752fb8b40fc1e8" resname="Channels" approved="yes">
<source>Channels</source> <source>Channels</source>
<target state="translated">Kanalen</target> <target state="translated">Kanalen</target>

View File

@@ -25,6 +25,18 @@
{% if width is not none and height is not none %} {% if width is not none and height is not none %}
{{ width ~ " x " ~ height }} {{ width ~ " x " ~ height }}
{% endif %}</dd> {% endif %}</dd>
{% set document = record.get_subdef('document') %}
{% if document and document.get_width() and document.get_height() %}
<dt>&nbsp;</dt>
<dd>{% if record.get_type() == 'image' and document.get_width() and document.get_height() %}
{% set size_w = (document.get_width() * (254/100) / 300) %}
{% set size_h = (document.get_height() * (254/100) / 300) %}
{{ size_w|round(1) }} x {{ size_h|round(1) }} cm (300dpi)
{% set size_w = (document.get_width() * (254/100) / 72) %}<br/>
{% set size_h = (document.get_height() * (254/100) / 72) %}
{{ size_w|round(1) }} x {{ size_h|round(1) }} cm (72dpi)
{% endif %}</dd>
{% endif %}
{% endblock %} {% endblock %}
</dl> </dl>
<hr/> <hr/>

View File

@@ -210,9 +210,6 @@
{% endif %} {% endif %}
<div id="image" class="tabBox"> <div id="image" class="tabBox">
<div class="text-info">
<i class=" icon-info-sign"></i> {% trans %}Changes for rotation will be applied only on the sub-definitions of "image" type.{% endtrans %}
</div>
<form name="formpushdoc" action="{{ path('prod_tools_rotate') }}" method="post"> <form name="formpushdoc" action="{{ path('prod_tools_rotate') }}" method="post">
<fieldset style='border:1px solid #999;padding:20px;'> <fieldset style='border:1px solid #999;padding:20px;'>
<legend>&nbsp;<b>{{ "image rotation" | trans }}</b>&nbsp;</legend> <legend>&nbsp;<b>{{ "image rotation" | trans }}</b>&nbsp;</legend>

View File

@@ -358,7 +358,7 @@
<div id="ADVSRCH_SB_ZONE"> <div id="ADVSRCH_SB_ZONE">
{% if search_status|length > 0 %} {% if search_status|length > 0 %}
<hr /> <hr />
<span>{{ 'Status des documents a rechercher' | trans }}</span> <span class="status-section-title">{{ 'Status des documents a rechercher' | trans }}</span>
{% for databox_id, databox in search_status %} {% for databox_id, databox in search_status %}
{% if databox.status|length > 0 %} {% if databox.status|length > 0 %}
<table style="width: 100%;" id="ADVSRCH_SB_ZONE_{{databox_id}}" class="field_{{databox_id}}"> <table style="width: 100%;" id="ADVSRCH_SB_ZONE_{{databox_id}}" class="field_{{databox_id}}">

View File

@@ -131,11 +131,7 @@
alert("{{ 'phraseanet::erreur: Votre session est fermee, veuillez vous re-authentifier' | trans }}"); alert("{{ 'phraseanet::erreur: Votre session est fermee, veuillez vous re-authentifier' | trans }}");
self.location.replace(self.location.href); self.location.replace(self.location.href);
} }
//if(manageSession(data)) window.setTimeout("pollNotifications();", 10000);
var t = 5000; // 120000;
if(data.apps && parseInt(data.apps)>1)
t = Math.round((Math.sqrt(parseInt(data.apps)-1) * 1.3 * 120000));
window.setTimeout("pollNotifications();", t);
return; return;
} }
@@ -460,13 +456,8 @@
// alert(url); // alert(url);
ret = loadXMLDoc(url, null, true); ret = loadXMLDoc(url, null, true);
// alert(ret);
allhits = ret.getElementsByTagName("allhits").item(0).firstChild.nodeValue;
if(allhits==0)
msg = "{{ 'thesaurus:: Supprimer cette branche ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation)' | trans }}"; msg = "{{ 'thesaurus:: Supprimer cette branche ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation)' | trans }}";
else
msg = "{{ 'thesaurus:: Des reponses sont retournees par cette branche. &#10;Supprimer quand meme ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation)' | trans }}";
if(confirm(msg)) if(confirm(msg))
{ {
@@ -1027,6 +1018,7 @@
if(confirm("{{ 'thesaurus:: deplacer le terme dans la corbeille ?' | trans | e('js') }}"+"\n\n"+fullpath+"\n\n")) if(confirm("{{ 'thesaurus:: deplacer le terme dans la corbeille ?' | trans | e('js') }}"+"\n\n"+fullpath+"\n\n"))
{ {
console.log(url);
// xmlhttp/delts.x.php?bid=15&id=T1.629&debug=1 // xmlhttp/delts.x.php?bid=15&id=T1.629&debug=1
// alert(url+"?"+parms); // alert(url+"?"+parms);
ret = loadXMLDoc(url, parms, true); ret = loadXMLDoc(url, parms, true);

View File

@@ -28,9 +28,11 @@ SET @@global.wait_timeout= 999999;
DROP SCHEMA IF EXISTS ab_test;DROP SCHEMA IF EXISTS db_test; DROP SCHEMA IF EXISTS ab_test;DROP SCHEMA IF EXISTS db_test;
CREATE SCHEMA IF NOT EXISTS ab_test;CREATE SCHEMA IF NOT EXISTS db_test; CREATE SCHEMA IF NOT EXISTS ab_test;CREATE SCHEMA IF NOT EXISTS db_test;
' '
if ! ./bin/developer system:uninstall > /dev/null 2>&1 if ! ./bin/developer system:uninstall > /dev/null 2>&1
then then
rm -f config/configuration.yml config/configuration-compiled.php mv config/configuration.yml{,.backup}
rm -f config/configuration-compiled.php
fi fi
./bin/setup system:install --email=test@phraseanet.com --password=test --db-user=root --db-template=en --db-password=toor --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y $VERBOSITY ./bin/setup system:install --email=test@phraseanet.com --password=test --db-user=root --db-template=en --db-password=toor --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y $VERBOSITY
case "$INSTALL_MODE" in case "$INSTALL_MODE" in