PHRAS-3918_subdef-substituable-setting (#4381)

* add checkbox "substituable" to admin/subdef ; bump to 4.1.8-rc7 and bump production-client ; migrate and remove conf 'registry/modules/thumb-substitution'

* bump production-client to 94

* fix test ; add test ; move "substituable" node to all subdefs (attribute)

* fix test

* fix test

* set "flatten layers"=true for new subdefs (PHRAS-3852 fix it)
This commit is contained in:
jygaulier
2023-10-31 15:52:45 +01:00
committed by GitHub
parent 23bb538246
commit 65732343ee
19 changed files with 408 additions and 241 deletions

2
.env
View File

@@ -134,7 +134,7 @@ PHRASEANET_DOCKER_REGISTRY=local
# Docker images tag. # Docker images tag.
# @run # @run
PHRASEANET_DOCKER_TAG=4.1.8-rc6 PHRASEANET_DOCKER_TAG=4.1.8-rc7
# Stack Name # Stack Name
# An optionnal Name for the stack # An optionnal Name for the stack

View File

@@ -62775,6 +62775,7 @@ var recordToolsModal = function recordToolsModal(services, datas) {
(0, _jquery2.default)('.iframe_submiter', $scope).bind('click', function () { (0, _jquery2.default)('.iframe_submiter', $scope).bind('click', function () {
var form = (0, _jquery2.default)(this).closest('form'); var form = (0, _jquery2.default)(this).closest('form');
form.submit(); form.submit();
form.find('.resultAction').empty();
form.find('.load').empty().html(localeService.t('loading') + ' ...'); form.find('.load').empty().html(localeService.t('loading') + ' ...');
(0, _jquery2.default)('#uploadHdsub').contents().find('.content').empty(); (0, _jquery2.default)('#uploadHdsub').contents().find('.content').empty();
(0, _jquery2.default)('#uploadHdsub').load(function () { (0, _jquery2.default)('#uploadHdsub').load(function () {

View File

@@ -62775,6 +62775,7 @@ var recordToolsModal = function recordToolsModal(services, datas) {
(0, _jquery2.default)('.iframe_submiter', $scope).bind('click', function () { (0, _jquery2.default)('.iframe_submiter', $scope).bind('click', function () {
var form = (0, _jquery2.default)(this).closest('form'); var form = (0, _jquery2.default)(this).closest('form');
form.submit(); form.submit();
form.find('.resultAction').empty();
form.find('.load').empty().html(localeService.t('loading') + ' ...'); form.find('.load').empty().html(localeService.t('loading') + ' ...');
(0, _jquery2.default)('#uploadHdsub').contents().find('.content').empty(); (0, _jquery2.default)('#uploadHdsub').contents().find('.content').empty();
(0, _jquery2.default)('#uploadHdsub').load(function () { (0, _jquery2.default)('#uploadHdsub').load(function () {

View File

@@ -51,6 +51,7 @@ const recordToolsModal = (services, datas, activeTab = false) => {
$('.iframe_submiter', $scope).bind('click', function () { $('.iframe_submiter', $scope).bind('click', function () {
var form = $(this).closest('form'); var form = $(this).closest('form');
form.submit(); form.submit();
form.find('.resultAction').empty();
form.find('.load').empty().html(localeService.t('loading') + ' ...'); form.find('.load').empty().html(localeService.t('loading') + ' ...');
$('#uploadHdsub').contents().find('.content').empty(); $('#uploadHdsub').contents().find('.content').empty();
$('#uploadHdsub').load(function () { $('#uploadHdsub').load(function () {

0
cache/.gitkeep vendored Normal file → Executable file
View File

View File

@@ -14,12 +14,14 @@ use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Databox\SubdefGroup; use Alchemy\Phrasea\Databox\SubdefGroup;
use Alchemy\Phrasea\Media\Subdef\Subdef; use Alchemy\Phrasea\Media\Subdef\Subdef;
use Alchemy\Phrasea\Media\Type\Type; use Alchemy\Phrasea\Media\Type\Type;
use Exception;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Alchemy\Phrasea\Media\Subdef\Image; use Alchemy\Phrasea\Media\Subdef\Image;
use Alchemy\Phrasea\Media\Subdef\Video; use Alchemy\Phrasea\Media\Subdef\Video;
use Alchemy\Phrasea\Media\Subdef\Audio; use Alchemy\Phrasea\Media\Subdef\Audio;
use Alchemy\Phrasea\Media\Subdef\Gif; use Alchemy\Phrasea\Media\Subdef\Gif;
use unicode;
class SubdefsController extends Controller class SubdefsController extends Controller
{ {
@@ -44,7 +46,7 @@ class SubdefsController extends Controller
* @param Request $request * @param Request $request
* @param int $sbas_id * @param int $sbas_id
* @return Response * @return Response
* @throws \Exception * @throws Exception
*/ */
function changeSubdefsAction(Request $request, $sbas_id) { function changeSubdefsAction(Request $request, $sbas_id) {
$delete_subdef = $request->request->get('delete_subdef'); $delete_subdef = $request->request->get('delete_subdef');
@@ -84,7 +86,7 @@ class SubdefsController extends Controller
$subdefs = $databox->get_subdef_structure(); $subdefs = $databox->get_subdef_structure();
$group = $add_subdef['group']; $group = $add_subdef['group'];
/** @var \unicode $unicode */ /** @var unicode $unicode */
$unicode = $this->app['unicode']; $unicode = $this->app['unicode'];
$name = $unicode->remove_nonazAZ09($add_subdef['name'], false); $name = $unicode->remove_nonazAZ09($add_subdef['name'], false);
$class = $add_subdef['class']; $class = $add_subdef['class'];
@@ -111,6 +113,7 @@ class SubdefsController extends Controller
$options[Image::OPTION_FLATTEN] = $config["image"]["definitions"][$preset][Image::OPTION_FLATTEN]; $options[Image::OPTION_FLATTEN] = $config["image"]["definitions"][$preset][Image::OPTION_FLATTEN];
$options[Image::OPTION_QUALITY] = $config["image"]["definitions"][$preset][Image::OPTION_QUALITY]; $options[Image::OPTION_QUALITY] = $config["image"]["definitions"][$preset][Image::OPTION_QUALITY];
$options[Image::OPTION_ICODEC] = $config["image"]["definitions"][$preset][Image::OPTION_ICODEC]; $options[Image::OPTION_ICODEC] = $config["image"]["definitions"][$preset][Image::OPTION_ICODEC];
$options[Image::OPTION_BACKGROUNDCOLOR] = $config["image"]["definitions"][$preset][Image::OPTION_BACKGROUNDCOLOR];
foreach ($config["image"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) { foreach ($config["image"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) {
$options[Subdef::OPTION_DEVICE][] = $devices; $options[Subdef::OPTION_DEVICE][] = $devices;
} }
@@ -182,6 +185,7 @@ class SubdefsController extends Controller
$class = $request->request->get($post_sub . '_class'); $class = $request->request->get($post_sub . '_class');
$downloadable = $request->request->get($post_sub . '_downloadable'); $downloadable = $request->request->get($post_sub . '_downloadable');
$orderable = $request->request->get($post_sub . '_orderable'); $orderable = $request->request->get($post_sub . '_orderable');
$substituable = $request->request->get($post_sub . '_substituable');
$toBuild = $request->request->get($post_sub . '_tobuild'); $toBuild = $request->request->get($post_sub . '_tobuild');
$defaults = ['path', 'meta', 'mediatype']; $defaults = ['path', 'meta', 'mediatype'];
@@ -208,7 +212,7 @@ class SubdefsController extends Controller
} }
$labels = $request->request->get($post_sub . '_label', []); $labels = $request->request->get($post_sub . '_label', []);
$subdefs->set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable, $preset, $toBuild); $subdefs->set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable, $preset, $toBuild, $substituable);
} }
} }

View File

@@ -44,14 +44,14 @@ class ToolsController extends Controller
$metadatas = false; $metadatas = false;
$record = null; $record = null;
$recordAccessibleSubdefs = array(); $recordAccessibleSubdefs = [];
$listsubdef= null; $listsubdef = null;
if (count($records) == 1) { if (count($records) == 1) {
/** @var record_adapter $record */ /** @var record_adapter $record */
$record = $records->first(); $record = $records->first();
/**Array list of subdefs**/ /**Array list of subdefs**/
$listsubdef = array_keys($record-> get_subdefs()); $listsubdef = array_keys($record->get_subdefs());
// fetch subdef list: // fetch subdef list:
$subdefs = $record->get_subdefs(); $subdefs = $record->get_subdefs();
@@ -73,18 +73,19 @@ class ToolsController extends Controller
continue; continue;
} }
$label = $this->app->trans('prod::tools: document'); $label = $this->app->trans('prod::tools: document');
} elseif ($databoxSubdefs !== null && $databoxSubdefs->hasSubdef($subdefName)) { }
elseif ($databoxSubdefs !== null && $databoxSubdefs->hasSubdef($subdefName)) {
if (!$acl->has_access_to_subdef($record, $subdefName)) { if (!$acl->has_access_to_subdef($record, $subdefName)) {
continue; continue;
} }
$label = $databoxSubdefs->getSubdef($subdefName)->get_label($this->app['locale']); $label = $databoxSubdefs->getSubdef($subdefName)->get_label($this->app['locale']);
} }
$recordAccessibleSubdefs[] = array( $recordAccessibleSubdefs[] = [
'name' => $subdef->get_name(), 'name' => $subdef->get_name(),
'state' => $permalink->get_is_activated(), 'state' => $permalink->get_is_activated(),
'label' => $label, 'label' => $label,
); ];
} }
} }
if (!$record->isStory()) { if (!$record->isStory()) {
@@ -95,8 +96,13 @@ class ToolsController extends Controller
$availableSubdefLabel = []; $availableSubdefLabel = [];
$countSubdefTodo = []; $countSubdefTodo = [];
$substituables = [];
if ($this->getConf()->get(['registry', 'modules', 'doc-substitution'])) {
$substituables[] = 'document';
}
/** @var record_adapter $rec */ /** @var record_adapter $rec */
foreach ($records as $rec) { foreach ($records as $rec) {
$databoxSubdefs = $rec->getDatabox()->get_subdef_structure()->getSubdefGroup($rec->getType()); $databoxSubdefs = $rec->getDatabox()->get_subdef_structure()->getSubdefGroup($rec->getType());
if ($databoxSubdefs !== null) { if ($databoxSubdefs !== null) {
foreach ($databoxSubdefs as $sub) { foreach ($databoxSubdefs as $sub) {
@@ -104,29 +110,38 @@ class ToolsController extends Controller
$label = trim($sub->get_label($this->app['locale'])); $label = trim($sub->get_label($this->app['locale']));
$availableSubdefLabel[] = $label; $availableSubdefLabel[] = $label;
if (isset($countSubdefTodo[$label])) { if (isset($countSubdefTodo[$label])) {
$countSubdefTodo[$label] ++; $countSubdefTodo[$label]++;
} else { }
else {
$countSubdefTodo[$label] = 1; $countSubdefTodo[$label] = 1;
} }
} }
if ($sub->isSubstituable()) {
$substituables[] = $sub->get_name();
}
} }
} }
} }
if (count($records) > 1) {
$substituables = [];
}
$this->setSessionFormToken('prodToolsSubdef'); $this->setSessionFormToken('prodToolsSubdef');
$this->setSessionFormToken('prodToolsRotate'); $this->setSessionFormToken('prodToolsRotate');
$this->setSessionFormToken('prodToolsHDSubstitution'); $this->setSessionFormToken('prodToolsHDSubstitution');
$this->setSessionFormToken('prodToolsThumbSubstitution'); $this->setSessionFormToken('prodToolsThumbSubstitution');
return $this->render('prod/actions/Tools/index.html.twig', [ return $this->render('prod/actions/Tools/index.html.twig', [
'records' => $records, 'records' => $records,
'record' => $record, 'record' => $record,
'recordSubdefs' => $recordAccessibleSubdefs, 'recordSubdefs' => $recordAccessibleSubdefs,
'metadatas' => $metadatas, 'metadatas' => $metadatas,
'listsubdef' => $listsubdef, 'listsubdef' => $listsubdef,
'availableSubdefLabel' => array_unique($availableSubdefLabel), 'availableSubdefLabel' => array_unique($availableSubdefLabel),
'nbRecords' => count($records), 'nbRecords' => count($records),
'countSubdefTodo' => $countSubdefTodo 'countSubdefTodo' => $countSubdefTodo,
'substituables' => $substituables,
]); ]);
} }
@@ -161,7 +176,8 @@ class ToolsController extends Controller
try { try {
$subdef->rotate($rotation, $this->getMediaAlchemyst(), $this->getMediaVorus()); $subdef->rotate($rotation, $this->getMediaAlchemyst(), $this->getMediaVorus());
} catch (\Exception $e) { }
catch (\Exception $e) {
// ignore exception // ignore exception
} }
} }
@@ -256,31 +272,34 @@ class ToolsController extends Controller
$this->getSubDefinitionSubstituer()->substituteDocument($record, $media); $this->getSubDefinitionSubstituer()->substituteDocument($record, $media);
$record->insertTechnicalDatas($this->getMediaVorus()); $record->insertTechnicalDatas($this->getMediaVorus());
$this->getMetadataSetter()->replaceMetadata($this->getMetadataReader() ->read($media), $record); $this->getMetadataSetter()->replaceMetadata($this->getMetadataReader()->read($media), $record);
$this->getDataboxLogger($record->getDatabox()) $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, 'HD', '' ); ->log($record, \Session_Logger::EVENT_SUBSTITUTE, 'HD', '');
if ((int) $request->request->get('ccfilename') === 1) { if ((int)$request->request->get('ccfilename') === 1) {
$record->set_original_name($fileName); $record->set_original_name($fileName);
} }
unlink($tempoFile); unlink($tempoFile);
rmdir($tempoDir); rmdir($tempoDir);
$success = true; $success = true;
$message = $this->app->trans('Document has been successfully substitued'); $message = $this->app->trans('Document has been successfully substitued');
} catch (\Exception $e) { }
catch (\Exception $e) {
$message = $this->app->trans('file is not valid'); $message = $this->app->trans('file is not valid');
} }
} else { }
else {
$message = $this->app->trans('file is not valid'); $message = $this->app->trans('file is not valid');
} }
} else { }
else {
$this->app->abort(400, 'Missing file parameter'); $this->app->abort(400, 'Missing file parameter');
} }
return $this->render('prod/actions/Tools/iframeUpload.html.twig', [ return $this->render('prod/actions/Tools/iframeUpload.html.twig', [
'success' => $success, 'success' => $success,
'message' => $message, 'message' => $message,
]); ]);
} }
@@ -296,10 +315,10 @@ class ToolsController extends Controller
$this->app->abort(400, 'Missing file parameter'); $this->app->abort(400, 'Missing file parameter');
} }
if (! $file->isValid()) { if (!$file->isValid()) {
return $this->render('prod/actions/Tools/iframeUpload.html.twig', [ return $this->render('prod/actions/Tools/iframeUpload.html.twig', [
'success' => false, 'success' => false,
'message' => $this->app->trans('file is not valid'), 'message' => $this->app->trans('file is not valid'),
]); ]);
} }
@@ -318,22 +337,28 @@ class ToolsController extends Controller
$media = $this->app->getMediaFromUri($tempoFile); $media = $this->app->getMediaFromUri($tempoFile);
$this->getSubDefinitionSubstituer()->substituteSubdef($record, 'thumbnail', $media); // no BC break before PHRAS-3918 when only "thumbnail" was substituable
if(($subdef = $request->get('subdef')) === null) {
$subdef = 'thumbnail';
}
$this->getSubDefinitionSubstituer()->substituteSubdef($record, $subdef, $media);
$this->getDataboxLogger($record->getDatabox()) $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, 'thumbnail', ''); ->log($record, \Session_Logger::EVENT_SUBSTITUTE, $subdef, '');
unlink($tempoFile); unlink($tempoFile);
rmdir($tempoDir); rmdir($tempoDir);
$success = true; $success = true;
$message = $this->app->trans('Thumbnail has been successfully substitued'); $message = sprintf($this->app->trans('Subdef "%s" has been successfully substitued'), $subdef);
} catch (\Exception $e) { }
catch (\Exception $e) {
$success = false; $success = false;
$message = $this->app->trans('file is not valid'); $message = $this->app->trans('file is not valid');
} }
return $this->render('prod/actions/Tools/iframeUpload.html.twig', [ return $this->render('prod/actions/Tools/iframeUpload.html.twig', [
'success' => $success, 'success' => $success,
'message' => $message, 'message' => $message,
]); ]);
} }
@@ -344,14 +369,15 @@ class ToolsController extends Controller
try { try {
$record = new record_adapter($this->app, $request->request->get('sbas_id'), $request->request->get('record_id')); $record = new record_adapter($this->app, $request->request->get('sbas_id'), $request->request->get('record_id'));
$var = [ $var = [
'video_title' => $record->get_title(['encode'=> record_adapter::ENCODE_NONE]), 'video_title' => $record->get_title(['encode' => record_adapter::ENCODE_NONE]),
'image' => $request->request->get('image', ''), 'image' => $request->request->get('image', ''),
]; ];
$return = [ $return = [
'error' => false, 'error' => false,
'datas' => $this->render($template, $var), 'datas' => $this->render($template, $var),
]; ];
} catch (\Exception $e) { }
catch (\Exception $e) {
$return = [ $return = [
'error' => true, 'error' => true,
'datas' => $this->app->trans('an error occured'), 'datas' => $this->app->trans('an error occured'),
@@ -378,7 +404,8 @@ class ToolsController extends Controller
} }
$return = ['success' => true, 'message' => '']; $return = ['success' => true, 'message' => ''];
} catch (\Exception $e) { }
catch (\Exception $e) {
$return = ['success' => false, 'message' => $e->getMessage()]; $return = ['success' => false, 'message' => $e->getMessage()];
} }
@@ -418,7 +445,8 @@ class ToolsController extends Controller
try { try {
$permalink->set_is_activated($state); $permalink->set_is_activated($state);
$return = ['success' => true, 'state' => $permalink->get_is_activated()]; $return = ['success' => true, 'state' => $permalink->get_is_activated()];
} catch (\Exception $e) { }
catch (\Exception $e) {
$return = ['success' => false, 'state' => $permalink->get_is_activated()]; $return = ['success' => false, 'state' => $permalink->get_is_activated()];
} }
@@ -474,13 +502,14 @@ class ToolsController extends Controller
$media = $this->app->getMediaFromUri($fileName); $media = $this->app->getMediaFromUri($fileName);
if($subDefName == 'document') { if ($subDefName == 'document') {
$this->getSubDefinitionSubstituer()->substituteDocument($record, $media); $this->getSubDefinitionSubstituer()->substituteDocument($record, $media);
} else { }
else {
$this->getSubDefinitionSubstituer()->substituteSubdef($record, $subDefName, $media); $this->getSubDefinitionSubstituer()->substituteSubdef($record, $subDefName, $media);
} }
$this->getDataboxLogger($record->getDatabox()) $this->getDataboxLogger($record->getDatabox())
->log($record, \Session_Logger::EVENT_SUBSTITUTE, $subDefName, ''); ->log($record, \Session_Logger::EVENT_SUBSTITUTE, $subDefName, '');
unset($media); unset($media);
$this->getFilesystem()->remove($fileName); $this->getFilesystem()->remove($fileName);
@@ -574,7 +603,7 @@ class ToolsController extends Controller
'_value' => $record->getCaption([$meta->get_name()]), '_value' => $record->getCaption([$meta->get_name()]),
]; ];
if (preg_match('/^VideoTextTrack(.*)$/iu', $meta->get_name(), $matches) && !empty($matches[1]) && strlen($matches[1]) == 2 ) { if (preg_match('/^VideoTextTrack(.*)$/iu', $meta->get_name(), $matches) && !empty($matches[1]) && strlen($matches[1]) == 2) {
$field['label'] = $matches[1]; $field['label'] = $matches[1];
$field['meta_struct_id'] = $meta->get_id(); $field['meta_struct_id'] = $meta->get_id();
$field['value'] = ''; $field['value'] = '';
@@ -595,12 +624,12 @@ class ToolsController extends Controller
$conf = $this->getConf(); $conf = $this->getConf();
return $this->render('prod/actions/Tools/videoEditor.html.twig', [ return $this->render('prod/actions/Tools/videoEditor.html.twig', [
'records' => $records, 'records' => $records,
'record' => $record, 'record' => $record,
'videoEditorConfig' => $conf->get(['video-editor']), 'videoEditorConfig' => $conf->get(['video-editor']),
'metadatas' => $metadatas, 'metadatas' => $metadatas,
'JSonFields' => json_encode($JSFields), 'JSonFields' => json_encode($JSFields),
'videoTextTrackFields' => $videoTextTrackFields 'videoTextTrackFields' => $videoTextTrackFields
]); ]);
} }
@@ -608,7 +637,8 @@ class ToolsController extends Controller
{ {
try { try {
return $record->get_subdef($subdefName)->is_physically_present(); return $record->get_subdef($subdefName)->is_physically_present();
} catch (\Exception $e) { }
catch (\Exception $e) {
unset($e); unset($e);
} }

View File

@@ -44,10 +44,12 @@ class Subdefs implements ControllerProviderInterface, ServiceProviderInterface
->requireRightOnSbas($request->attributes->get('sbas_id'), \ACL::BAS_MODIFY_STRUCT); ->requireRightOnSbas($request->attributes->get('sbas_id'), \ACL::BAS_MODIFY_STRUCT);
}); });
/** @uses SubdefsController::indexAction */
$controllers->get('/{sbas_id}/', 'controller.admin.subdefs:indexAction') $controllers->get('/{sbas_id}/', 'controller.admin.subdefs:indexAction')
->bind('admin_subdefs_subdef') ->bind('admin_subdefs_subdef')
->assert('sbas_id', '\d+'); ->assert('sbas_id', '\d+');
/** @uses SubdefsController::changeSubdefsAction */
$controllers->post('/{sbas_id}/', 'controller.admin.subdefs:changeSubdefsAction') $controllers->post('/{sbas_id}/', 'controller.admin.subdefs:changeSubdefsAction')
->bind('admin_subdefs_subdef_update') ->bind('admin_subdefs_subdef_update')
->assert('sbas_id', '\d+'); ->assert('sbas_id', '\d+');

View File

@@ -57,9 +57,11 @@ class Tools implements ControllerProviderInterface, ServiceProviderInterface
$controllers->post('/image/', 'controller.prod.tools:imageAction') $controllers->post('/image/', 'controller.prod.tools:imageAction')
->bind('prod_tools_image'); ->bind('prod_tools_image');
/** @uses \Alchemy\Phrasea\Controller\Prod\ToolsController::hddocAction */
$controllers->post('/hddoc/', 'controller.prod.tools:hddocAction') $controllers->post('/hddoc/', 'controller.prod.tools:hddocAction')
->bind('prod_tools_hd_substitution'); ->bind('prod_tools_hd_substitution');
/** @uses \Alchemy\Phrasea\Controller\Prod\ToolsController::changeThumbnailAction */
$controllers->post('/chgthumb/', 'controller.prod.tools:changeThumbnailAction') $controllers->post('/chgthumb/', 'controller.prod.tools:changeThumbnailAction')
->bind('prod_tools_thumbnail_substitution'); ->bind('prod_tools_thumbnail_substitution');

View File

@@ -17,7 +17,7 @@ class Version
* @var string * @var string
*/ */
private $number = '4.1.8-rc6'; private $number = '4.1.8-rc7';
/** /**
* @var string * @var string

View File

@@ -36,7 +36,7 @@ class Image extends Provider
$this->registerOption(new OptionType\Range($this->translator->trans('Dimension'), self::OPTION_SIZE, 20, 5000, 800)); $this->registerOption(new OptionType\Range($this->translator->trans('Dimension'), self::OPTION_SIZE, 20, 5000, 800));
$this->registerOption(new OptionType\Range($this->translator->trans('Resolution'), self::OPTION_RESOLUTION, 50, 1000, 72)); $this->registerOption(new OptionType\Range($this->translator->trans('Resolution'), self::OPTION_RESOLUTION, 50, 1000, 72));
$this->registerOption(new OptionType\Boolean($this->translator->trans('Remove ICC Profile'), self::OPTION_STRIP, false)); $this->registerOption(new OptionType\Boolean($this->translator->trans('Remove ICC Profile'), self::OPTION_STRIP, false));
$this->registerOption(new OptionType\Boolean($this->translator->trans('Flatten layers'), self::OPTION_FLATTEN, false)); $this->registerOption(new OptionType\Boolean($this->translator->trans('Flatten layers'), self::OPTION_FLATTEN, true));
$this->registerOption(new OptionType\Range($this->translator->trans('Quality'), self::OPTION_QUALITY, 0, 100, 75)); $this->registerOption(new OptionType\Range($this->translator->trans('Quality'), self::OPTION_QUALITY, 0, 100, 75));
$this->registerOption(new OptionType\Enum('Image Codec', self::OPTION_ICODEC, array('jpeg', 'png', 'tiff'), 'jpeg')); $this->registerOption(new OptionType\Enum('Image Codec', self::OPTION_ICODEC, array('jpeg', 'png', 'tiff'), 'jpeg'));
$this->registerOption(new OptionType\EnumButton($this->translator->trans('Watermark'), self::OPTION_WATERMARK, array('no' => 'no', 'yes' => 'yes'), 'no')); $this->registerOption(new OptionType\EnumButton($this->translator->trans('Watermark'), self::OPTION_WATERMARK, array('no' => 'no', 'yes' => 'yes'), 'no'));

View File

@@ -43,6 +43,8 @@ class databox_subdef
*/ */
private $requiresMetadataUpdate; private $requiresMetadataUpdate;
protected $downloadable; protected $downloadable;
protected $orderable;
protected $substituable;
protected $tobuild; protected $tobuild;
protected $translator; protected $translator;
protected static $mediaTypeToSubdefTypes = [ protected static $mediaTypeToSubdefTypes = [
@@ -67,8 +69,8 @@ class databox_subdef
* *
* @param SubdefType $type * @param SubdefType $type
* @param SimpleXMLElement $sd * @param SimpleXMLElement $sd
* * @param TranslatorInterface $translator
* @return databox_subdef * @param databox|null $databox
*/ */
public function __construct(SubdefType $type, SimpleXMLElement $sd, TranslatorInterface $translator, databox $databox = null) public function __construct(SubdefType $type, SimpleXMLElement $sd, TranslatorInterface $translator, databox $databox = null)
{ {
@@ -81,8 +83,9 @@ class databox_subdef
} }
$this->name = strtolower($sd->attributes()->name); $this->name = strtolower($sd->attributes()->name);
$this->downloadable = p4field::isyes($sd->attributes()->downloadable); $this->downloadable = p4field::isyes($sd->attributes()->downloadable);
$this->orderable = isset($sd->attributes()->orderable) ? p4field::isyes($sd->attributes()->orderable) : true; $this->substituable = isset($sd->attributes()->substituable) && p4field::isyes($sd->attributes()->substituable);
$this->tobuild = isset($sd->attributes()->tobuild) ? p4field::isyes($sd->attributes()->tobuild) : true; $this->orderable = !isset($sd->attributes()->orderable) || p4field::isyes($sd->attributes()->orderable);
$this->tobuild = !isset($sd->attributes()->tobuild) || p4field::isyes($sd->attributes()->tobuild);
$this->path = trim($sd->path) !== '' ? p4string::addEndSlash(trim($sd->path)) : ''; $this->path = trim($sd->path) !== '' ? p4string::addEndSlash(trim($sd->path)) : '';
$this->preset = $sd->attributes()->presets; $this->preset = $sd->attributes()->presets;
$this->requiresMetadataUpdate = p4field::isyes((string)$sd->meta); $this->requiresMetadataUpdate = p4field::isyes((string)$sd->meta);
@@ -368,8 +371,6 @@ class databox_subdef
} }
/** /**
* boolean
*
* @return bool * @return bool
*/ */
public function isTobuild() public function isTobuild()
@@ -377,6 +378,14 @@ class databox_subdef
return $this->tobuild; return $this->tobuild;
} }
/**
* @return bool
*/
public function isSubstituable()
{
return $this->substituable;
}
/** /**
* Get an array of Alchemy\Phrasea\Media\Subdef\Subdef available for the current Media Type * Get an array of Alchemy\Phrasea\Media\Subdef\Subdef available for the current Media Type
* *

View File

@@ -246,7 +246,7 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
* @return databox_subdefsStructure * @return databox_subdefsStructure
* @throws Exception * @throws Exception
*/ */
public function set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable = true, $preset = "Custom", $toBuild = true) public function set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable = true, $preset = "Custom", $toBuild = true, $substituable = false)
{ {
$dom_struct = $this->databox->get_dom_structure(); $dom_struct = $this->databox->get_dom_structure();
@@ -256,6 +256,7 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
$subdef->setAttribute('downloadable', ($downloadable ? 'true' : 'false')); $subdef->setAttribute('downloadable', ($downloadable ? 'true' : 'false'));
$subdef->setAttribute('orderable', ($orderable ? 'true' : 'false')); $subdef->setAttribute('orderable', ($orderable ? 'true' : 'false'));
$subdef->setAttribute('tobuild', ($toBuild ? 'true' : 'false')); $subdef->setAttribute('tobuild', ($toBuild ? 'true' : 'false'));
$subdef->setAttribute('substituable', ($substituable ? 'true' : 'false'));
$subdef->setAttribute('presets', $preset); $subdef->setAttribute('presets', $preset);
foreach ($labels as $code => $label) { foreach ($labels as $code => $label) {

View File

@@ -0,0 +1,92 @@
<?php
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class patch_418RC7 implements patchInterface
{
/** @var string */
private $release = '4.1.8-rc7';
/** @var array */
private $concern = [base::DATA_BOX];
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function getDoctrineMigrations()
{
return [];
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function apply(base $base, Application $app)
{
if ($base->get_base_type() === base::DATA_BOX) {
$this->patch_databox($base, $app);
}
elseif ($base->get_base_type() === base::APPLICATION_BOX) {
$this->patch_appbox($base, $app);
}
return true;
}
private $thumbSubstitution = null;
public function patch_databox(databox $databox, Application $app)
{
/** @var PropertyAccess $conf */
$conf = $app['conf'];
if ($this->thumbSubstitution === null) {
// first db
$this->thumbSubstitution = $conf->get(['registry', 'modules', 'thumb-substitution']);
$conf->remove(['registry', 'modules', 'thumb-substitution']);
}
if ($this->thumbSubstitution) {
$dom_struct = $databox->get_dom_structure();
$dom_xp = $databox->get_xpath_structure();
$nodes = $dom_xp->query('//record/subdefs/subdefgroup/subdef[@name="thumbnail"]');
for ($i = 0; $i < $nodes->length; $i++) {
/** @var \DOMElement $node */
$node = $nodes->item($i);
$node->setAttribute('substituable', 'true');
}
$databox->saveStructure($dom_struct);
}
}
private function patch_appbox(base $appbox, Application $app)
{
}
}

0
logs/.gitkeep Normal file → Executable file
View File

View File

@@ -456,6 +456,13 @@
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>{{ 'subdef.substituable' | trans }}</td>
<td><input type="checkbox" name="{{ subdefgroup }}_{{ subdefname }}_substituable"
{% if subdef.isSubstituable() %}checked="checked"{% endif %} value="1"/>
</td>
<td></td>
</tr>
<tr> <tr>
<td> <td>
{{ 'classe' | trans }} {{ 'classe' | trans }}

View File

@@ -4,23 +4,23 @@
{% set nbSubdefSubstitute = 0 %} {% set nbSubdefSubstitute = 0 %}
{% for record in records %} {% for record in records %}
{% set subdefs = record.get_subdefs() %} {% set subdefs = record.get_subdefs() %}
{% if subdefs|length > 0 %} {% if subdefs|length > 0 %}
{% for key, subdef in subdefs if subdef.is_substituted() %} {% for key, subdef in subdefs if subdef.is_substituted() %}
{% if key == 'document' %} {% if key == 'document' %}
{% set nbHdSubstitute = nbHdSubstitute + 1 %} {% set nbHdSubstitute = nbHdSubstitute + 1 %}
{% else %} {% else %}
{% set nbSubdefSubstitute = nbSubdefSubstitute + 1 %} {% set nbSubdefSubstitute = nbSubdefSubstitute + 1 %}
{% endif%} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<div id='prod-tool-box' class="PNB10"> <div id='prod-tool-box' class="PNB10">
{# jquery Tabs #} {# jquery Tabs #}
<div id="tool-tabs" class="tabs tool-modal-wrapper"> <div id="tool-tabs" class="tabs tool-modal-wrapper">
{# jquery menu #} {# jquery menu #}
<div> <div>
<ul> <ul>
@@ -34,7 +34,7 @@
{{ "image tool" | trans }} {{ "image tool" | trans }}
</a> </a>
</li> </li>
{% if selectionLength == 1 and (app['conf'].get(['registry', 'modules', 'doc-substitution']) or app['conf'].get(['registry', 'modules', 'thumb-substitution'])) %} {% if substituables|length > 0 %}
<li> <li>
<a href="#substitution"> <a href="#substitution">
{{ "substitution" | trans }} {{ "substitution" | trans }}
@@ -48,7 +48,7 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if selectionLength == 1%} {% if selectionLength == 1 %}
{% if recordSubdefs %} {% if recordSubdefs %}
<li> <li>
<a href="#tools-sharing"> <a href="#tools-sharing">
@@ -63,13 +63,14 @@
<div id="subdefs" class="tabBox"> <div id="subdefs" class="tabBox">
<form id="new-img-form" action="{{ path('prod_tools_image') }}" method="post" name="prodToolsSubdef"> <form id="new-img-form" action="{{ path('prod_tools_image') }}" method="post" name="prodToolsSubdef">
<fieldset style='border:1px solid #999; padding:20px;'> <fieldset style='border:1px solid #999; padding:20px;'>
<legend style="margin-bottom: 0px;">&nbsp;<b>{{ "Reconstruire les sous definitions" | trans }}</b>&nbsp;</legend> <legend style="margin-bottom: 0px;">&nbsp;<b>{{ "Reconstruire les sous definitions" | trans }}</b>&nbsp;
</legend>
{% if nbSubdefSubstitute > 0 %} {% if nbSubdefSubstitute > 0 %}
<div style="color:#A00;"> <div style="color:#FF0000;">
{{ "Attention, certain documents ont des sous-definitions substituees" | trans }} {{ "Attention, certain documents ont des sous-definitions substituees" | trans }}
</div> </div>
<label for="FTS" class="checkbox"> <label for="FTS" class="checkbox">
<input type="checkbox" name="force_substitution" value="1" id="FTS" /> <input type="checkbox" name="force_substitution" value="1" id="FTS"/>
{{ "Forcer la reconstruction sur les enregistrements ayant des thumbnails substituees" | trans }} {{ "Forcer la reconstruction sur les enregistrements ayant des thumbnails substituees" | trans }}
</label> </label>
<br/> <br/>
@@ -79,14 +80,16 @@
<div class="well-small"> <div class="well-small">
<label for="recreate_all" class="checkbox"> <label for="recreate_all" class="checkbox">
<input class="subdefTodo" id="recreate_all" type="checkbox" value="0"> {{ 'All' | trans }} <input class="subdefTodo" id="recreate_all" type="checkbox" value="0"> {{ 'All' | trans }}
</label> </label>
</div> </div>
{% for subdefLabel in availableSubdefLabel %} {% for subdefLabel in availableSubdefLabel %}
<div class="well-small"> <div class="well-small">
<label for="recreate_{{ subdefLabel | replace({' ':'_'}) }}" class="checkbox"> <label for="recreate_{{ subdefLabel | replace({' ':'_'}) }}" class="checkbox">
<input class="subdefTodo" type="checkbox" id="recreate_{{ subdefLabel | replace({' ':'_'}) }}" name="subdefsLabel[]" value="{{ subdefLabel }}" /> <input class="subdefTodo" type="checkbox"
id="recreate_{{ subdefLabel | replace({' ':'_'}) }}" name="subdefsLabel[]"
value="{{ subdefLabel }}"/>
{{ subdefLabel }} {{ countSubdefTodo[subdefLabel] }} / {{ nbRecords }} {{ subdefLabel }} {{ countSubdefTodo[subdefLabel] }} / {{ nbRecords }}
</label> </label>
</div> </div>
@@ -97,8 +100,8 @@
{{ 'Are you sure you want to rebuild the sub-definitions of selected records?' | trans }} {{ 'Are you sure you want to rebuild the sub-definitions of selected records?' | trans }}
</p> </p>
</div> </div>
<input type="hidden" name="ACT" value="SEND" /> <input type="hidden" name="ACT" value="SEND"/>
<input type="hidden" name="lst" value="{{records.serializedList()}}" /> <input type="hidden" name="lst" value="{{ records.serializedList() }}"/>
</fieldset> </fieldset>
<div style='text-align:right;padding-top:10px;'> <div style='text-align:right;padding-top:10px;'>
<button class="action_submiter btn btn-inverse" type="button">{{ "validate" | trans }}</button> <button class="action_submiter btn btn-inverse" type="button">{{ "validate" | trans }}</button>
@@ -113,126 +116,108 @@
</form> </form>
</div> </div>
<div id="image" class="tabBox"> <div id="image" class="tabBox">
<div class="text-info"> <div class="text-info">
<i class="fa fa-info-circle" aria-hidden="true"></i> {% trans %}Changes for rotation will be applied only on <i class="fa fa-info-circle"
the sub-definitions of "image" type.{% endtrans %} aria-hidden="true"></i> {% trans %}Changes for rotation will be applied only on
</div> the sub-definitions of "image" type.{% endtrans %}
<form name="formpushdoc" action="{{ path('prod_tools_rotate') }}" method="post"> </div>
<fieldset style='border:1px solid #999;padding:20px;'> <form name="formpushdoc" action="{{ path('prod_tools_rotate') }}" method="post">
<legend>&nbsp;<b>{{ "image rotation" | trans }}</b>&nbsp;</legend> <fieldset style='border:1px solid #999;padding:20px;'>
<label for="ROTA_90" class="radio"> <legend>&nbsp;<b>{{ "image rotation" | trans }}</b>&nbsp;</legend>
<input type="radio" name="rotation" id="ROTA_90" value="90" checked="checked"> <label for="ROTA_90" class="radio">
{{ "rotation 90 degres horaire" | trans }} <input type="radio" name="rotation" id="ROTA_90" value="90" checked="checked">
</label> {{ "rotation 90 degres horaire" | trans }}
<br /> </label>
<label for="ROTA_C90" class="radio"> <br/>
<input type="radio" name="rotation" id="ROTA_C90" value="-90"> <label for="ROTA_C90" class="radio">
{{ "rotation 90 degres anti-horaires" | trans }} <input type="radio" name="rotation" id="ROTA_C90" value="-90">
</label> {{ "rotation 90 degres anti-horaires" | trans }}
<input type="hidden" name="lst" value="{{records.serializedList()}}" /> </label>
<input type="hidden" name="element" value="" /> <input type="hidden" name="lst" value="{{ records.serializedList() }}"/>
<input type="hidden" name="cchd" value="" /> <input type="hidden" name="element" value=""/>
</fieldset> <input type="hidden" name="cchd" value=""/>
<div style='text-align:right;padding-top:10px;'> </fieldset>
<button class="action_submiter btn btn-inverse">{{ "validate"|trans }}</button> <div style='text-align:right;padding-top:10px;'>
<button class="action_cancel btn btn-inverse">{{ "cancel"|trans }}</button> <button class="action_submiter btn btn-inverse">{{ "validate"|trans }}</button>
</div> <button class="action_cancel btn btn-inverse">{{ "cancel"|trans }}</button>
<input type="hidden" name="prodToolsRotate_token" value="{{ app['session'].get('prodToolsRotate_token') }}"> </div>
<input type="hidden" name="prodToolsRotate_token" value="{{ app['session'].get('prodToolsRotate_token') }}">
</form> </form>
</div>
{# hd sub section #}
{% if selectionLength == 1 and (app['conf'].get(['registry', 'modules', 'doc-substitution']) or app['conf'].get(['registry', 'modules', 'thumb-substitution'])) %}
{% for record in records %}
<div id="substitution" class="tabBox">
{% if "unknown" == record.get_type() %}
<i class="fa fa-exclamation-triangle icon-white"
aria-hidden="true"></i>{{ "Substitution is not possible for this kind of record" | trans }}
{% else %}
{% if app['conf'].get(['registry', 'modules', 'doc-substitution']) %}
<div id="substitution-hd">
<form
name ="formchgHD"
action="{{ path('prod_tools_hd_substitution') }}"
enctype="multipart/form-data"
method="post"
target="uploadHdsub">
<fieldset style='border:1px solid #999;padding:20px;'>
<legend>&nbsp;<b>{{ "substitution HD" | trans }}</b>&nbsp;</legend>
<div>
<input id='new-hd-file' name="newHD" type="file"/>
<br />
<label for="CCFNALP" class="checkbox">
<input type="checkbox" name="ccfilename" id="CCFNALP" value="1">
{{ "mettre a jour le nom original de fichier apres substitution" | trans }}
</label>
<input type="hidden" name="ACT" value="SEND" />
<input type="hidden" name="sbas_id" value="{{record.get_sbas_id()}}"/>
<input type="hidden" name="record_id" value="{{record.get_record_id()}}" />
<div class="load"></div>
</div>
</fieldset>
<div style='text-align:right;padding-top:10px;'>
<button class="iframe_submiter btn btn-inverse">{{ "validate" | trans }}</button>
<button class="action_cancel btn btn-inverse">{{ "cancel" | trans }}</button>
</div>
<input type="hidden" name="prodToolsHDSubstitution_token" value="{{ app['session'].get('prodToolsHDSubstitution_token') }}">
</form>
<div class='resultAction'></div>
</div>
{% endif %}
{% if app['conf'].get(['registry', 'modules', 'thumb-substitution']) %}
<div id="substitution-sd">
<form
name="formchgHD"
action="{{ path('prod_tools_thumbnail_substitution') }}"
enctype="multipart/form-data"
method="post"
target="uploadHdsub">
<fieldset style='border:1px solid #999;padding:20px;'>
<legend>&nbsp;<b>{{ "substitution SD" | trans }}</b>&nbsp;</legend>
<div>
<input id='new-sd-file' name="newThumb" type="file" />
<input type="hidden" name="sbas_id" value="{{record.get_sbas_id()}}" />
<input type="hidden" name="record_id" value="{{record.get_record_id()}}" />
<div class="load"></div>
</div>
</fieldset>
<div style='text-align:right;padding-top:10px;'>
<button class="iframe_submiter btn btn-inverse">{{ "validate" | trans }}</button>
<button class="action_cancel btn btn-inverse">{{ "cancel" | trans }}</button>
</div>
<input type="hidden" name="prodToolsThumbSubstitution_token" value="{{ app['session'].get('prodToolsThumbSubstitution_token') }}">
</form>
<div class='resultAction'></div>
</div>
{% endif %}
{% endif %}
</div> </div>
{% endfor %}
{% endif %}
{# exiftool section #} {# substitution section #}
{% if metadatas %} {% if substituables|length > 0 %} {# substituables is empty if multiple records #}
<div id="exiftool" class="tabBox"> {% for record in records %}
<div class="metadatas-top-block"> <div id="substitution" class="tabBox">
<select id="select-meta-subdef" name="metaSubdef" class="input-medium check-filters">
<option value="" disabled >{{"prod::tool:select subdef" | trans}}</option> {% if "unknown" == record.get_type() %}
{% if listsubdef is defined and listsubdef is not null %} <i class="fa fa-exclamation-triangle icon-white"
{% for subdef in listsubdef %} aria-hidden="true"></i>{{ "Substitution is not possible for this kind of record" | trans }}
<option value= "{{ subdef }}" {{ subdef== 'document'? 'selected' : 'false' }}>{{ subdef }}</option> {% else %}
{% for substituable in substituables %}
{% set d = (substituable == "document") ? true : false %}
<div id="substitution-hd">
<form
name="formchgHD"
action="{{ path(d ? 'prod_tools_hd_substitution' : 'prod_tools_thumbnail_substitution') }}"
enctype="multipart/form-data"
method="post"
target="uploadHdsub">
<fieldset style='border:1px solid #999;padding:20px;'>
<legend>&nbsp;
<b>{% trans with {'%sd%' : substituable} %}substitution of %sd%{% endtrans %}</b>&nbsp
</legend>
<div>
{% if d %}
<input id='new-hd-file' name="newHD" type="file"/>
<br/>
<label for="CCFNALP" class="checkbox">
<input type="checkbox" name="ccfilename" id="CCFNALP" value="1">
{{ "mettre a jour le nom original de fichier apres substitution" | trans }}
</label>
<input type="hidden" name="prodToolsHDSubstitution_token" value="{{ app['session'].get('prodToolsHDSubstitution_token') }}">
{% else %}
<input id='new-sd-file' name="newThumb" type="file"/>
<input type="hidden" name="prodToolsThumbSubstitution_token" value="{{ app['session'].get('prodToolsThumbSubstitution_token') }}">
{% endif %}
<input type="hidden" name="subdef" value="{{ substituable|e }}"/>
<input type="hidden" name="sbas_id" value="{{ record.get_sbas_id() }}"/>
<input type="hidden" name="record_id" value="{{ record.get_record_id() }}"/>
<div class="load"></div>
<div class='resultAction'></div>
</div>
</fieldset>
<div style='text-align:right;padding-top:10px;'>
<button class="iframe_submiter btn btn-inverse">{{ "validate" | trans }}</button>
<button class="action_cancel btn btn-inverse">{{ "cancel" | trans }}</button>
</div>
</form>
</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</select> </div>
{% endfor %}
{% endif %}
{# exiftool section #}
{% if metadatas %}
<div id="exiftool" class="tabBox">
<div class="metadatas-top-block">
<select id="select-meta-subdef" name="metaSubdef" class="input-medium check-filters">
<option value="" disabled>{{ "prod::tool:select subdef" | trans }}</option>
{% if listsubdef is defined and listsubdef is not null %}
{% for subdef in listsubdef %}
<option value="{{ subdef }}" {{ subdef== 'document'? 'selected' : 'false' }}>{{ subdef }}</option>
{% endfor %}
{% endif %}
</select>
</div>
<div id="metadata-load" style="height: 100%"></div>
<div id="metadata-content"></div>
</div> </div>
<div id="metadata-load" style="height: 100%"></div> {% endif %}
<div id="metadata-content"></div>
</div>
{% endif %}
{% if selectionLength == 1 and recordSubdefs is not empty %} {% if selectionLength == 1 and recordSubdefs is not empty %}
<div id="tools-sharing" class="tabBox"> <div id="tools-sharing" class="tabBox">
<div class="well-large"> <div class="well-large">
@@ -242,44 +227,45 @@
<span class="status-marker {{ subdef.state ? 'status-active' : 'status-inactive' }}"></span>{{ subdef.label }} <span class="status-marker {{ subdef.state ? 'status-active' : 'status-inactive' }}"></span>{{ subdef.label }}
</div> </div>
<div class="span6 text-right"> <div class="span6 text-right">
<button type="button" class="tools-sharing-btn stateChange_button btn btn-inverse text-right" <button type="button"
data-name="{{ subdef.name }}" data-state="{{ subdef.state }}"> class="tools-sharing-btn stateChange_button btn btn-inverse text-right"
{% if subdef.state %} data-name="{{ subdef.name }}" data-state="{{ subdef.state }}">
{{- "Disable document type sharing"|trans -}} {% if subdef.state %}
{% else %} {{- "Disable document type sharing"|trans -}}
{{- "Enable document type sharing"|trans -}} {% else %}
{% endif %} {{- "Enable document type sharing"|trans -}}
</button> {% endif %}
</button>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
{# hidden iframe to handle upload #} {# hidden iframe to handle upload #}
<iframe <iframe
id="uploadHdsub" id="uploadHdsub"
name="uploadHdsub" name="uploadHdsub"
height="0" height="0"
width="0" width="0"
border="0" border="0"
> >
</iframe> </iframe>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var toolsConfig = { var toolsConfig = {
selectionLength: {{ selectionLength }}, selectionLength: {{ selectionLength }},
databaseId: {% if selectionLength == 1%}{{record.get_base_id}}{% else %}0{% endif %}, databaseId: {% if selectionLength == 1 %}{{ record.get_base_id }}{% else %}0{% endif %},
translations: { translations: {
alertTitle: '{{ "alert" | trans }}', alertTitle: '{{ "alert" | trans }}',
noImgSelected: '{{ "no image selected" | trans }}', noImgSelected: '{{ "no image selected" | trans }}',
processing: '{{ "processing" | trans }}', processing: '{{ "processing" | trans }}',
thumbnailTitle: '{{ 'thumbnail validation' | trans }}', thumbnailTitle: '{{ 'thumbnail validation' | trans }}',
}, },
records: [ records: [
{% for record in records %} {% for record in records %}
{ {
@@ -297,9 +283,9 @@
{% set height = technical_info[dataH].value %} {% set height = technical_info[dataH].value %}
{% if width and height %} {% if width and height %}
{% set ratio = (width / height)|number_format(2, '.') %} {% set ratio = (width / height)|number_format(2, '.') %}
{% else %} {% else %}
{% set ratio = '' %} {% set ratio = '' %}
{% endif %} {% endif %}
sources: [ sources: [
@@ -307,8 +293,8 @@
{ {
ratio: '{{ ratio }}', ratio: '{{ ratio }}',
framerate: {{ record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] | round(2) }}, framerate: {{ record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] | round(2) }},
type: "{{ subdef.get_mime() }}", type: "{{ subdef.get_mime() }}",
src: "{{ subdef.get_url() }}" src: "{{ subdef.get_url() }}"
}{% if not loop.last %},{% endif %} }{% if not loop.last %},{% endif %}
{% endfor %} {% endfor %}
] ]
@@ -321,38 +307,38 @@
}; };
function loadMetadataTab (url) { function loadMetadataTab(url) {
$.ajax({ $.ajax({
"url": url, "url": url,
"type": "GET", "type": "GET",
beforeSend: function () { beforeSend: function () {
$('#metadata-content').empty(); $('#metadata-content').empty();
$('#metadata-load').removeClass('hidden').addClass('loading'); $('#metadata-load').removeClass('hidden').addClass('loading');
}, },
success: function (data) { success: function (data) {
$('#metadata-load').removeClass('loading').addClass('hidden'); $('#metadata-load').removeClass('loading').addClass('hidden');
$('#metadata-content').append(data); $('#metadata-content').append(data);
} }
}); });
} }
$(document).ready(function(){ $(document).ready(function () {
{% if record is not null %} {% if record is not null %}
/**load default Subdef info **/ /**load default Subdef info **/
loadMetadataTab( '{{ path('prod_subdefs_metadata', {'databox_id': record.get_sbas_id(), 'record_id': record.get_record_id, 'subdef_name': 'document' }) }}'); loadMetadataTab('{{ path('prod_subdefs_metadata', {'databox_id': record.get_sbas_id(), 'record_id': record.get_record_id, 'subdef_name': 'document' }) }}');
/**load selected Subdef info **/ /**load selected Subdef info **/
$('#select-meta-subdef').on('change', function (e) { $('#select-meta-subdef').on('change', function (e) {
var selectedSubdef = $(this).children('option:selected'); var selectedSubdef = $(this).children('option:selected');
if (selectedSubdef.val() !== "") { if (selectedSubdef.val() !== "") {
var url = '{{ path('prod_subdefs_metadata', {'databox_id': record.get_sbas_id(), 'record_id': record.get_record_id, 'subdef_name': 'subdefName' }) }}'; var url = '{{ path('prod_subdefs_metadata', {'databox_id': record.get_sbas_id(), 'record_id': record.get_record_id, 'subdef_name': 'subdefName' }) }}';
url = url.replace("subdefName", selectedSubdef.val() ); url = url.replace("subdefName", selectedSubdef.val());
loadMetadataTab(url); loadMetadataTab(url);
} }
}); });
{% endif %} {% endif %}
$('.tool-modal-wrapper .tabBox').height($('#prod-tool-box').height() - 61 ); $('.tool-modal-wrapper .tabBox').height($('#prod-tool-box').height() - 61);
$('#exiftool').height($('#prod-tool-box').height() - 55 ); $('#exiftool').height($('#prod-tool-box').height() - 55);
}); });

View File

@@ -73,6 +73,6 @@ class ToolsTest extends \PhraseanetAuthenticatedWebTestCase
$response = self::$DI['client']->getResponse(); $response = self::$DI['client']->getResponse();
$message = trim($crawler->filterXPath('//div')->text()); $message = trim($crawler->filterXPath('//div')->text());
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(self::$DI['app']['translator']->trans('Thumbnail has been successfully substitued'), $message); $this->assertEquals(sprintf(self::$DI['app']['translator']->trans('Subdef "%s" has been successfully substitued'), 'thumbnail'), $message);
} }
} }

View File

@@ -249,6 +249,37 @@ EOF;
]; ];
} }
/**
* @param bool $expected
* @param null|string $configValue
* @dataProvider providesSubstituableStatuses
*/
public function testSubstituableStatus($expected, $configValue, $message)
{
$xmlTemplate = <<<'EOF'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<subdef class="thumbnail" name="gifou" downloadable="false" %s>
<path>/home/datas/noweb/db_alch_phrasea/video/</path>
<mediatype>image</mediatype>
</subdef>
EOF;
$xml = sprintf($xmlTemplate, $configValue ?: '');
$sut = new databox_subdef(new Type\Image(), simplexml_load_string($xml), $this->translator);
$this->assertSame($expected, $sut->isSubstituable(), $message);
}
public function providesSubstituableStatuses()
{
return [
[false, '', 'No substituable Status set should defaults to true'],
[false, 'substituable="false"', 'substituable should default to false'],
[true, 'substituable="true"', 'substituable should be true'],
];
}
/** /**
* @return PHPUnit_Framework_MockObject_MockObject|TranslatorInterface * @return PHPUnit_Framework_MockObject_MockObject|TranslatorInterface
*/ */