Merge remote-tracking branch 'alchemy/master' into PHRAS-1734_PORT_PHRAS-1589

# Conflicts:
#	resources/locales/messages.de.xlf
#	resources/locales/messages.en.xlf
#	resources/locales/messages.fr.xlf
#	resources/locales/messages.nl.xlf
#	resources/locales/validators.de.xlf
#	resources/locales/validators.en.xlf
#	resources/locales/validators.fr.xlf
#	resources/locales/validators.nl.xlf
This commit is contained in:
Mike Ng
2018-01-09 09:50:27 +04:00
78 changed files with 4604 additions and 2183 deletions

View File

@@ -1,3 +1,3 @@
{
"directory" : "www/bower_components"
"directory": "www/bower_components"
}

View File

@@ -28,7 +28,8 @@
"jquery.lazyload": "~1.9.7",
"jquery-treeview": "~1.4.2",
"alchemy-embed-medias": "~0.3.4",
"html5shiv": "^3.7.3"
"html5shiv": "^3.7.3",
"jquery-simplecolorpicker": "^0.3.1"
},
"devDependencies": {
"mocha": "latest",

0
cache/.gitkeep vendored
View File

View File

@@ -176,6 +176,7 @@ class Install extends Command
private function getDBConn(InputInterface $input, OutputInterface $output, Connection $abConn, DialogHelper $dialog)
{
$dbConn = $template = $info = null;
$templates = $this->container['phraseanet.structure-template']->getAvailable();
if (!$input->getOption('databox')) {
do {
$retry = false;
@@ -196,8 +197,9 @@ class Install extends Command
$output->writeln("\n\t<info>Data-Box : Connection successful !</info>\n");
do {
$template = $dialog->ask($output, 'Choose a language template for metadata structure, available are fr (french) and en (english) (en) : ', 'en');
} while (!in_array($template, ['en', 'fr']));
$template = $dialog->ask($output, "Choose a language template for metadata structure, available are {$templates->__toString()} : ", 'en');
}
while (!in_array($template, array_keys($templates->getTemplates())));
$output->writeln("\n\tLanguage selected is <info>'$template'</info>\n");
} catch (\Exception $e) {

View File

@@ -38,7 +38,12 @@ class SetupController extends Controller
public function submitGlobalsAction(Request $request)
{
$form = $this->registryFormManipulator->createForm();
if (null !== $this->configuration->get('registry')) {
$form = $this->registryFormManipulator->createForm($this->configuration);
}
else {
$form = $this->registryFormManipulator->createForm();
}
if ('POST' === $request->getMethod()) {
$form->submit($request->request->all());

View File

@@ -12,8 +12,14 @@ namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Databox\SubdefGroup;
use Alchemy\Phrasea\Media\Subdef\Subdef;
use Alchemy\Phrasea\Media\Type\Type;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Alchemy\Phrasea\Media\Subdef\Image;
use Alchemy\Phrasea\Media\Subdef\Video;
use Alchemy\Phrasea\Media\Subdef\Audio;
use Alchemy\Phrasea\Media\Subdef\Gif;
class SubdefsController extends Controller
{
@@ -23,10 +29,14 @@ class SubdefsController extends Controller
*/
function indexAction($sbas_id) {
$databox = $this->findDataboxById((int) $sbas_id);
$config = $this->getConfiguration();
$subviews_mapping = $this->getSubviewsMapping();
return $this->render('admin/subdefs.html.twig', [
'databox' => $databox,
'subdefs' => $databox->get_subdef_structure(),
'databox' => $databox,
'subdefs' => $databox->get_subdef_structure(),
'config' => $config,
'subviews_mapping' => $subviews_mapping
]);
}
@@ -43,7 +53,7 @@ class SubdefsController extends Controller
$databox = $this->findDataboxById((int) $sbas_id);
$add_subdef = ['class' => null, 'name' => null, 'group' => null];
$add_subdef = ['class' => null, 'name' => null, 'group' => null, 'mediaType' => null, 'presets' => null];
foreach ($add_subdef as $k => $v) {
if (!isset($toadd_subdef[$k]) || trim($toadd_subdef[$k]) === '') {
unset($add_subdef[$k]);
@@ -58,7 +68,8 @@ class SubdefsController extends Controller
$name = $delete_subef[1];
$subdefs = $databox->get_subdef_structure();
$subdefs->delete_subdef($group, $name);
} elseif (count($add_subdef) === 3) {
}
elseif (count($add_subdef) === 5) {
$subdefs = $databox->get_subdef_structure();
$group = $add_subdef['group'];
@@ -66,13 +77,85 @@ class SubdefsController extends Controller
$unicode = $this->app['unicode'];
$name = $unicode->remove_nonazAZ09($add_subdef['name'], false);
$class = $add_subdef['class'];
$preset = $add_subdef['presets'];
$mediatype = $add_subdef['mediaType'];
$subdefs->add_subdef($group, $name, $class, $mediatype, $preset);
if ($preset !== "Choose") {
$options = [];
$config = $this->getConfiguration();
//On applique directement les valeurs du preset à la sous def
switch ($mediatype) {
case Subdef::TYPE_IMAGE :
$options["path"] = "";
$options["meta"] = true;
$options["mediatype"] = $mediatype;
$options[Image::OPTION_SIZE] = $config["image"]["definitions"][$preset][Image::OPTION_SIZE];
$options["dpi"] = $config["image"]["definitions"][$preset][Image::OPTION_RESOLUTION];
$options[Image::OPTION_STRIP] = $config["image"]["definitions"][$preset][Image::OPTION_STRIP];
$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_ICODEC] = $config["image"]["definitions"][$preset][Image::OPTION_ICODEC];
foreach ($config["image"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) {
$options[Subdef::OPTION_DEVICE][] = $devices;
}
break;
case Subdef::TYPE_VIDEO :
$options["path"] = "";
$options["meta"] = true;
$options["mediatype"] = $mediatype;
$options[Video::OPTION_AUDIOBITRATE] = $config["video"]["definitions"][$preset][Video::OPTION_AUDIOBITRATE];
$options[Video::OPTION_AUDIOSAMPLERATE] = $config["video"]["definitions"][$preset][Video::OPTION_AUDIOSAMPLERATE];
$options[Video::OPTION_BITRATE] = $config["video"]["definitions"][$preset][Video::OPTION_BITRATE];
$options[Video::OPTION_GOPSIZE] = $config["video"]["definitions"][$preset][Video::OPTION_GOPSIZE];
$options[Video::OPTION_SIZE] = $config["video"]["definitions"][$preset][Video::OPTION_SIZE];
$options[Video::OPTION_FRAMERATE] = $config["video"]["definitions"][$preset][Video::OPTION_FRAMERATE];
$options[Video::OPTION_VCODEC] = $config["video"]["definitions"][$preset][Video::OPTION_VCODEC];
$options[Video::OPTION_ACODEC] = $config["video"]["definitions"][$preset][Video::OPTION_ACODEC];
foreach ($config["video"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) {
$options[Subdef::OPTION_DEVICE][] = $devices;
}
break;
case Subdef::TYPE_FLEXPAPER :
$options["path"] = "";
$options["meta"] = true;
$options["mediatype"] = $mediatype;
foreach ($config["document"]["definitions"][$preset]["devices"] as $devices) {
$options["devices"][] = $devices;
}
break;
case Subdef::TYPE_ANIMATION :
$options["path"] = "";
$options["meta"] = true;
$options["mediatype"] = $mediatype;
$options[Gif::OPTION_SIZE] = $config["gif"]["definitions"][$preset][Gif::OPTION_SIZE];
$options[Gif::OPTION_DELAY] = $config["gif"]["definitions"][$preset][Gif::OPTION_DELAY];
foreach ($config["gif"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) {
$options[Subdef::OPTION_DEVICE][] = $devices;
}
break;
case Subdef::TYPE_AUDIO :
$options["path"] = "";
$options["meta"] = true;
$options["mediatype"] = $mediatype;
$options[Audio::OPTION_AUDIOBITRATE] = $config["audio"]["definitions"][$preset][Audio::OPTION_AUDIOBITRATE];
$options[Audio::OPTION_AUDIOSAMPLERATE] = $config["audio"]["definitions"][$preset][Audio::OPTION_AUDIOSAMPLERATE];
$options[Audio::OPTION_ACODEC] = $config["audio"]["definitions"][$preset][Audio::OPTION_ACODEC];
foreach ($config["audio"]["definitions"][$preset][Subdef::OPTION_DEVICE] as $devices) {
$options[Subdef::OPTION_DEVICE][] = $devices;
}
break;
}
$subdefs->set_subdef($group, $name, $class, false, $options, [], true, $preset);
}
$subdefs->add_subdef($group, $name, $class);
} else {
$subdefs = $databox->get_subdef_structure();
$this->updateSubdefGroups($subdefs, $request);
foreach ($Parmsubdefs as $post_sub) {
$options = [];
@@ -81,6 +164,7 @@ class SubdefsController extends Controller
$group = $post_sub_ex[0];
$name = $post_sub_ex[1];
$preset = $request->request->get($post_sub . '_presets');
$class = $request->request->get($post_sub . '_class');
$downloadable = $request->request->get($post_sub . '_downloadable');
$orderable = $request->request->get($post_sub . '_orderable');
@@ -96,7 +180,6 @@ class SubdefsController extends Controller
$options[$def] = $parm_loc;
}
$mediatype = $request->request->get($post_sub . '_mediatype');
$media = $request->request->get($post_sub . '_' . $mediatype, []);
@@ -110,8 +193,7 @@ class SubdefsController extends Controller
}
$labels = $request->request->get($post_sub . '_label', []);
$subdefs->set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable);
$subdefs->set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable, $preset);
}
}
@@ -121,35 +203,359 @@ class SubdefsController extends Controller
}
/**
* Update Databox subdefsStructure DOM according to defined groups.
*
* @param \databox_subdefsStructure $subdefs
* @param Request $request
* @return array
*/
private function updateSubdefGroups(\databox_subdefsStructure $subdefs, Request $request)
protected function getSubviewsMapping()
{
$subdefsGroups = $request->request->get('subdefsgroups', []);
$changedGroups = [];
$mapping = [
Type::TYPE_IMAGE => [Subdef::TYPE_IMAGE],
Type::TYPE_VIDEO => [Subdef::TYPE_IMAGE, Subdef::TYPE_VIDEO, Subdef::TYPE_ANIMATION],
Type::TYPE_AUDIO => [Subdef::TYPE_IMAGE, Subdef::TYPE_AUDIO],
Type::TYPE_DOCUMENT => [Subdef::TYPE_IMAGE, Subdef::TYPE_FLEXPAPER],
Type::TYPE_FLASH => [Subdef::TYPE_IMAGE]
];
/** @var SubdefGroup $subdefsGroup */
foreach ($subdefs as $groupName => $subdefsGroup) {
$documentOrderable = isset($subdefsGroups[$groupName]['document_orderable'])
? \p4field::isyes($subdefsGroups[$groupName]['document_orderable'])
: false;
return $mapping;
}
if ($subdefsGroup->isDocumentOrderable() !== $documentOrderable) {
if ($documentOrderable) {
$subdefsGroup->allowDocumentOrdering();
} else {
$subdefsGroup->disallowDocumentOrdering();
}
/**
* @return array
*/
protected function getConfiguration()
{
$config = [
Subdef::TYPE_IMAGE => [
"definitions" => [
"JPG" => null,
"160px JPG" => [
Image::OPTION_SIZE => "160",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "jpeg",
Subdef::OPTION_DEVICE => ["all"]
],
"320 px JPG (thumbnail Phraseanet)" => [
Image::OPTION_SIZE => "320",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "jpeg",
Subdef::OPTION_DEVICE => ["all"]
],
"640px JPG" => [
Image::OPTION_SIZE => "640",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "jpeg",
Subdef::OPTION_DEVICE => ["all"]
],
"1280px JPG (preview Phraseanet)" => [
Image::OPTION_SIZE => "1280",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "jpeg",
Subdef::OPTION_DEVICE => ["all"]
],
"2560px JPG" => [
Image::OPTION_SIZE => "2560",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "jpeg",
Subdef::OPTION_DEVICE => ["all"]
],
"PNG" => null,
"160px PNG 8 bits" => [
Image::OPTION_SIZE => "160",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "png",
Subdef::OPTION_DEVICE => ["all"]
],
"320px PNG 8 bits" => [
Image::OPTION_SIZE => "320",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "png",
Subdef::OPTION_DEVICE => ["all"]
],
"640px PNG 8 bits" => [
Image::OPTION_SIZE => "640",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "png",
Subdef::OPTION_DEVICE => ["all"]
],
"1280px PNG 8 bits" => [
Image::OPTION_SIZE => "1280",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "png",
Subdef::OPTION_DEVICE => ["all"]
],
"2560px PNG 8 bits" => [
Image::OPTION_SIZE => "2560",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "png",
Subdef::OPTION_DEVICE => ["all"]
],
"TIFF" => null,
"1280 TIFF" => [
Image::OPTION_SIZE => "1280",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "tiff",
Subdef::OPTION_DEVICE => ["all"]
],
"2560px TIFF" => [
Image::OPTION_SIZE => "2560",
Image::OPTION_RESOLUTION => "75",
Image::OPTION_STRIP => "yes",
Image::OPTION_FLATTEN => "yes",
Image::OPTION_QUALITY => "75",
Image::OPTION_ICODEC => "tiff",
Subdef::OPTION_DEVICE => ["all"]
],
],
"form" => [
Image::OPTION_SIZE => "slide",
Image::OPTION_RESOLUTION => "slide",
Image::OPTION_STRIP => "radio",
Image::OPTION_FLATTEN => "radio",
Image::OPTION_QUALITY => "slide",
Image::OPTION_ICODEC => "select",
Subdef::OPTION_DEVICE => "checkbox",
],
],
Subdef::TYPE_VIDEO => [
"definitions" => [
"video codec H264" => null,
"144P H264 128 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "128",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "256",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libx264",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"240P H264 256 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "256",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "426",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libx264",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"360P H264 576 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "576",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "480",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libtheora",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"480P H264 750 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "750",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "854",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libx264",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"720P H264 1492 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "1492",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "1280",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libx264",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"1080P H264 2420 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "2420",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "1920",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libx264",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"video codec libvpx" => null,
"144P webm 128 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "128",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "256",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"240P webm 256 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "256",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "426",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"360P webm 576 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "576",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "480",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"480P webm 750 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "750",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "854",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"720P webm 1492 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "1492",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "1280",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
"1080P webm 2420 kbps ACC 128kbps" => [
Video::OPTION_AUDIOBITRATE => "128",
Video::OPTION_AUDIOSAMPLERATE => "44100",
Video::OPTION_BITRATE => "2420",
Video::OPTION_GOPSIZE => "25",
Video::OPTION_SIZE => "1920",
Video::OPTION_FRAMERATE => "25",
Video::OPTION_VCODEC => "libvpx",
Video::OPTION_ACODEC => "libfaac",
Subdef::OPTION_DEVICE => ["all"]
],
],
"form" => [
Video::OPTION_AUDIOBITRATE => "slide",
Video::OPTION_AUDIOSAMPLERATE => "select",
Video::OPTION_BITRATE => "slide",
Video::OPTION_GOPSIZE => "slide",
Video::OPTION_SIZE => "slide",
Video::OPTION_FRAMERATE => "slide",
Video::OPTION_VCODEC => "select",
Video::OPTION_ACODEC => "select",
Subdef::OPTION_DEVICE => "checkbox",
],
],
Subdef::TYPE_ANIMATION => [
"definitions" => [
"256 px fast 200 ms" => [
Gif::OPTION_SIZE => "256",
Gif::OPTION_DELAY => "200",
Subdef::OPTION_DEVICE => ["all"]
],
"256 px very fast 120 ms" => [
Gif::OPTION_SIZE => "256",
Gif::OPTION_DELAY => "120",
Subdef::OPTION_DEVICE => ["all"]
],
"320 px fast 200 ms" => [
Gif::OPTION_SIZE => "320",
Gif::OPTION_DELAY => "200",
Subdef::OPTION_DEVICE => ["all"]
],
],
"form" => [
Gif::OPTION_SIZE => "slide",
Gif::OPTION_DELAY => "slide",
Subdef::OPTION_DEVICE => "checkbox",
],
],
Subdef::TYPE_AUDIO => [
"definitions" => [
"Low AAC 96 kbit/s" => [
Audio::OPTION_AUDIOBITRATE => "100",
Audio::OPTION_AUDIOSAMPLERATE => "8000",
Audio::OPTION_ACODEC => "libmp3lame",
Subdef::OPTION_DEVICE => ["all"]
],
"Normal AAC 128 kbit/s" => [
Audio::OPTION_AUDIOBITRATE => "180",
Audio::OPTION_AUDIOSAMPLERATE => "44100",
Audio::OPTION_ACODEC => "libmp3lame",
Subdef::OPTION_DEVICE => ["all"]
],
"High AAC 320 kbit/s" => [
Audio::OPTION_AUDIOBITRATE => "230",
Audio::OPTION_AUDIOSAMPLERATE => "50000",
Audio::OPTION_ACODEC => "libmp3lame",
Subdef::OPTION_DEVICE => ["all"]
],
],
"form" => [
Audio::OPTION_AUDIOBITRATE => "slide",
Audio::OPTION_AUDIOSAMPLERATE => "select",
Audio::OPTION_ACODEC => "select",
Subdef::OPTION_DEVICE => "checkbox",
],
],
Subdef::TYPE_FLEXPAPER => [
"definitions" => [
],
"form" => [],
],
];
$changedGroups[] = $subdefsGroup;
}
}
if ($changedGroups) {
$subdefs->updateSubdefGroups($changedGroups);
}
return $config;
}
}

View File

@@ -376,6 +376,7 @@ class V1Controller extends Controller
'password' => $conf->get(['registry', 'email', 'smtp-password']),
],
],
'custom-links' => $conf->get(['registry', 'custom-links']),
'ftp' => [
'active' => $conf->get(['registry', 'ftp', 'ftp-enabled']),
'activeForUser' => $conf->get(['registry', 'ftp', 'ftp-user-access']),

View File

@@ -36,6 +36,32 @@ class MoveCollectionController extends Controller
} else {
// is able to move:
$success = true;
/** @var DisplaySettingService $settings */
$settings = $this->app['settings'];
$userOrderSetting = $settings->getUserSetting($this->app->getAuthenticatedUser(), 'order_collection_by');
// a temporary array to sort the collections
$aName = [];
list($ukey, $uorder) = ["order", SORT_ASC]; // default ORDER_BY_ADMIN
switch ($userOrderSetting) {
case $settings::ORDER_ALPHA_ASC :
list($ukey, $uorder) = ["name", SORT_ASC];
break;
case $settings::ORDER_ALPHA_DESC :
list($ukey, $uorder) = ["name", SORT_DESC];
break;
}
foreach ($collections as $key => $row) {
if ($ukey == "order") {
$aName[$key] = $row->get_ord();
}
else {
$aName[$key] = $row->get_name();
}
}
// sort the collections
array_multisort($aName, $uorder, SORT_REGULAR, $collections);
$parameters = [
'records' => $records,
'message' => '',

View File

@@ -23,44 +23,71 @@ class ShareController extends Controller
*/
public function shareRecord($base_id, $record_id)
{
$outputVars = [
'isAvailable' => false,
'preview' => [
'permalinkUrl' => '',
'permaviewUrl' => '',
'embedUrl' => '',
'width' => '',
'height' => ''
]
];
$record = new \record_adapter($this->app, \phrasea::sbasFromBas($this->app, $base_id), $record_id);
if (!$this->getAclForUser()->has_access_to_subdef($record, 'preview')) {
$this->app->abort(403);
}
//get list of subdefs
$subdefs = $record->get_subdefs();
$preview = $record->get_preview();
$databoxSubdefs = $record->getDatabox()->get_subdef_structure()->getSubdefGroup($record->getType());
$acl = $this->getAclForUser();
$subdefList = [];
$defaultKey = null;
foreach ($subdefs as $subdef) {
$subdefName = $subdef->get_name();
if ($subdefName == 'document') {
if (!$acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDHD)) {
continue;
}
$label = $this->app->trans('prod::tools: document');
}
elseif ($databoxSubdefs->hasSubdef($subdefName)) {
if (!$acl->has_access_to_subdef($record, $subdefName)) {
continue;
}
$label = $databoxSubdefs->getSubdef($subdefName)->get_label($this->app['locale']);
}
else {
// this subdef does no exists anymore in databox structure ?
continue; // don't publish it
}
$value = $subdef->get_name();
$preview = $record->get_subdef($value);
$defaultKey = $value; // will set a default option if neither preview,thumbnail or document is present
if (null !== $previewLink = $preview->get_permalink()) {
$permalinkUrl = $previewLink->get_url();
$permaviewUrl = $previewLink->get_page();
$previewWidth = $preview->get_width();
$previewHeight = $preview->get_height();
$embedUrl = $this->app->url('alchemy_embed_view', ['url' => (string)$permalinkUrl]);
$outputVars = [
'isAvailable' => true,
'preview' => [
if (($previewLink = $preview->get_permalink()) !== null) {
$permalinkUrl = $previewLink->get_url()->__toString();
$permaviewUrl = $previewLink->get_page();
$previewWidth = $preview->get_width();
$previewHeight = $preview->get_height();
$embedUrl = $this->app->url('alchemy_embed_view', ['url' => (string)$permalinkUrl]);
$previewData = [
'label' => $label,
'permalinkUrl' => $permalinkUrl,
'permaviewUrl' => $permaviewUrl,
'embedUrl' => $embedUrl,
'width' => $previewWidth,
'height' => $previewHeight
]
];
'embedUrl' => $embedUrl,
'width' => $previewWidth,
'height' => $previewHeight
];
$subdefList[$value] = $previewData;
}
}
// candidates as best default selected option
foreach (["preview", "thumbnail", "document"] as $k) {
if (array_key_exists($k, $subdefList)) {
$defaultKey = $k;
break;
}
}
// if no subdef was sharable, subdefList is empty and defaultKey is null
// the twig MUST handle that
$outputVars = [
'isAvailable' => !empty($subdefList),
'subdefList' => $subdefList,
'defaultKey' => $defaultKey
];
return $this->renderResponse('prod/Share/record.html.twig', $outputVars);
}
}

View File

@@ -243,20 +243,45 @@ class UploadController extends Controller
{
$collections = [];
foreach ($acl->get_granted_base([\ACL::CANADDRECORD]) as $collection) {
$databox = $collection->get_databox();
if ( ! isset($collections[$databox->get_sbas_id()])) {
$collections[$databox->get_sbas_id()] = [
'databox' => $databox,
'databox_collections' => []
];
foreach ($acl->get_granted_sbas() as $databox) {
$sbasId = $databox->get_sbas_id();
foreach ($acl->get_granted_base([\ACL::CANADDRECORD], [$sbasId]) as $collection) {
$databox = $collection->get_databox();
if (!isset($collections[$sbasId])) {
$collections[$databox->get_sbas_id()] = [
'databox' => $databox,
'databox_collections' => []
];
}
$collections[$databox->get_sbas_id()]['databox_collections'][] = $collection;
/** @var DisplaySettingService $settings */
$settings = $this->app['settings'];
$userOrderSetting = $settings->getUserSetting($this->app->getAuthenticatedUser(), 'order_collection_by');
// a temporary array to sort the collections
$aName = [];
list($ukey, $uorder) = ["order", SORT_ASC]; // default ORDER_BY_ADMIN
switch ($userOrderSetting) {
case $settings::ORDER_ALPHA_ASC :
list($ukey, $uorder) = ["name", SORT_ASC];
break;
case $settings::ORDER_ALPHA_DESC :
list($ukey, $uorder) = ["name", SORT_DESC];
break;
}
foreach ($collections[$databox->get_sbas_id()]['databox_collections'] as $key => $row) {
if ($ukey == "order") {
$aName[$key] = $row->get_ord();
}
else {
$aName[$key] = $row->get_name();
}
}
// sort the collections
array_multisort($aName, $uorder, SORT_REGULAR, $collections[$databox->get_sbas_id()]['databox_collections']);
}
$collections[$databox->get_sbas_id()]['databox_collections'][] = $collection;
}
return $collections;
}
/**

View File

@@ -77,7 +77,7 @@ class SetupController extends Controller
return $this->render('/setup/step2.html.twig', [
'locale' => $this->app['locale'],
'available_locales' => Application::getAvailableLanguages(),
'available_templates' => ['en', 'fr'],
'available_templates' => $this->app['phraseanet.structure-template']->getAvailable()->getTemplates(),
'warnings' => $warnings,
'error' => $request->query->get('error'),
'current_servername' => $request->getScheme() . '://' . $request->getHttpHost() . '/',

View File

@@ -47,10 +47,22 @@ class Share implements ControllerProviderInterface, ServiceProviderInterface
$controllers->get('/record/{base_id}/{record_id}/', 'controller.prod.share:shareRecord')
->before(function (Request $request) use ($app, $firewall) {
$firewall->requireRightOnSbas(
\phrasea::sbasFromBas($app, $request->attributes->get('base_id')),
\ACL::BAS_CHUPUB
);
$socialTools = $app['conf']->get(['registry', 'actions', 'social-tools']);
if ($socialTools === "all") {
return;
}
elseif ($socialTools === "none") {
$app->abort(403, 'social tools disabled');
}
elseif ($socialTools === "publishers") {
$firewall->requireRightOnSbas(
\phrasea::sbasFromBas($app, $request->attributes->get('base_id')),
\ACL::BAS_CHUPUB
);
}
else {
throw new \Exception("bad value \"" . $socialTools . "\" for social tools");
}
})
->bind('share_record');

View File

@@ -15,6 +15,10 @@ use Alchemy\Phrasea\Model\Entities\User;
class DisplaySettingService
{
const ORDER_ALPHA_ASC = "ORDER_ALPHA_ASC";
const ORDER_ALPHA_DESC = "ORDER_ALPHA_DESC";
const ORDER_BY_ADMIN = "ORDER_BY_ADMIN";
/**
* The default user settings.
*
@@ -34,6 +38,7 @@ class DisplaySettingService
'client_basket_status' => '1',
'css' => '000000',
'start_page_query' => '',
'order_collection_by' => self::ORDER_BY_ADMIN,
'start_page' => 'QUERY',
'rollover_thumbnail' => 'caption',
'technical_display' => '1',

View File

@@ -147,7 +147,7 @@ class RegistryFormManipulator
'recaptcha-public-key' => '',
'recaptcha-private-key' => '',
],
'executables' => [
'executables' => [
'h264-streaming-enabled' => false,
'auth-token-directory' => null,
'auth-token-directory-path' => null,
@@ -162,7 +162,7 @@ class RegistryFormManipulator
'default-query' => '',
'default-query-type' => 0,
],
'email' => [
'email' => [
'emitter-email' => 'phraseanet@example.com',
'prefix' => null,
'smtp-enabled' => false,
@@ -173,6 +173,22 @@ class RegistryFormManipulator
'smtp-user' => null,
'smtp-password' => isset($config['email']['smtp-password']) ? $config['email']['smtp-password'] : null,
],
'custom-links' => [
[
'linkName' => 'Phraseanet store',
'linkLanguage' => 'fr',
'linkUrl' => 'https://alchemy.odoo.com/shop',
'linkLocation' => 'help-menu',
'linkOrder' => '1',
],
[
'linkName' => 'Phraseanet store',
'linkLanguage' => 'en',
'linkUrl' => 'https://alchemy.odoo.com/en_US/shop',
'linkLocation' => 'help-menu',
'linkOrder' => '1',
],
]
];
}
}

View File

@@ -0,0 +1,109 @@
<?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\Configuration;
use Alchemy\Phrasea\Application;
/**
* Class StructureTemplate
* @package Alchemy\Phrasea\Core\Configuration
*/
class StructureTemplate
{
const TEMPLATE_EXTENSION = 'xml';
private $templates;
public function __construct(Application $app)
{
$this->app = $app;
}
/**
* @return $this
* @throws \Exception
*/
public function getAvailable()
{
$templateList = new \DirectoryIterator($this->app['root.path'] . '/lib/conf.d/data_templates');
if (empty($templateList)) {
throw new \Exception('No available structure template');
}
$templates = [];
$abbreviationLength = 2;
foreach ($templateList as $template) {
if ($template->isDot()
|| !$template->isFile()
|| $template->getExtension() !== self::TEMPLATE_EXTENSION
) {
continue;
}
$name = $template->getFilename();
$abbreviation = strtolower(substr($name, 0, $abbreviationLength));
if (array_key_exists($abbreviation, $templates)) {
$abbreviation = strtolower(substr($name, 0, ++$abbreviationLength));
}
$templates[$abbreviation] = $template->getBasename('.' . self::TEMPLATE_EXTENSION);
}
$this->templates = $templates;
return $this;
}
/**
* @return string
*/
public function __toString()
{
if (!$this->templates) {
return '';
}
$templateToString = '';
$cpt = 1;
$templateLength = count($this->templates);
foreach ($this->templates as $key => $value) {
if (($templateLength - 1) == $cpt) {
$separator = ' and ';
}
elseif (end($this->templates) == $value) {
$separator = '';
}
else {
$separator = ', ';
}
$templateToString .= $key . ' (' . $value . ')' . $separator;
$cpt++;
}
return $templateToString;
}
/**
* @param $template
* @return mixed
* @throws \Exception
*/
public function getTemplateName($template = 'en')
{
if (!array_key_exists($template, $this->templates)) {
throw new \Exception('Not found template : ' . $template);
}
return $this->templates[$template];
}
/**
* @return mixed
*/
public function getTemplates()
{
return $this->templates;
}
}

View File

@@ -11,6 +11,8 @@
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\StructureTemplate;
use Alchemy\Phrasea\Core\Configuration\AccessRestriction;
use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\DisplaySettingService;
@@ -71,6 +73,10 @@ class ConfigurationServiceProvider implements ServiceProviderInterface
$app['conf.restrictions'] = $app->share(function (SilexApplication $app) {
return new AccessRestriction($app['conf'], $app->getApplicationBox(), $app['monolog']);
});
$app['phraseanet.structure-template'] = $app->share(function (Application $app) {
return new StructureTemplate($app);
});
}
/**

View File

@@ -0,0 +1,49 @@
<?php
namespace Alchemy\Phrasea\Databox\Subdef;
class SubdefPreset
{
/**
* @var string
*/
private $mediaType;
/**
* @var string
*/
private $label;
/**
* @var array
*/
private $definitions;
/**
* @param string $mediaType
* @param array $definitions
*/
public function __construct($mediaType, array $definitions)
{
foreach ($definitions as $definition) {
if (!$definition instanceof Subdef) {
}
}
$this->mediaType = (string)$mediaType;
$this->definitions = $definitions;
}
/**
* @return string
*/
public function getMediaType()
{
return $this->label;
}
/**
* @return array
*/
public function getDefinitions()
{
return $this->definitions;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Alchemy\Phrasea\Databox\Subdef;
class SubdefPresetProvider
{
private $presets = [];
/**
* @param string $type Type of media for which to get presets
* @return SubdefPreset[]
*/
public function getPresets($type)
{
if (!isset($this->presets[$type])) {
throw new \InvalidArgumentException('Invalid type');
}
return $this->presets[$type];
}
}

View File

@@ -0,0 +1,94 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Configuration;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class CustomLinkFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('linkName', 'text', [
'label' => false,
'attr' => [
'placeholder' => 'setup::custom-link:name-link',
'required' => true,
'maxlength' => "30"
]
]);
$builder->add('linkLanguage', 'choice', [
'label' => false,
'attr' => [
'required' => true
],
'choices' => [
'' => 'setup::custom-link:select-language',
'all' => 'All',
'fr' => 'FR',
'en' => 'EN',
'es' => 'ES',
'ar' => 'AR',
'de' => 'DE',
'du' => 'DU'
]
]);
$builder->add('linkUrl', 'url', [
'label' => false,
'attr' => [
'placeholder' => 'setup::custom-link:placeholder-link-url',
'required' => true
]
]);
$builder->add('linkLocation', 'choice', [
'label' => false,
'attr' => [
'required' => true
],
'choices' => [
'' => 'setup::custom-link:location',
'help-menu' => 'setup::custom-link:help-menu',
'navigation-bar' => 'setup::custom-link:navigation-bar',
]
]);
$builder->add('linkOrder', 'integer', [
'label' => false,
]);
$builder->add('linkBold', 'checkbox', [
'label' => false,
]);
$builder->add('linkColor', 'choice', [
'label' => false,
'choices' => [
'' => '#ad0800',
'#ad0800' => '#ad0800',
'#f06006' => '#f06006',
'#f5842b' => '#f5842b',
'#ffc322' => '#ffc322',
'#f4ea5b' => '#f4ea5b',
'#b8d84e' => '#b8d84e',
'#5aa53b' => '#5aa53b',
'#a1d0d0' => '#a1d0d0',
'#4497d5' => '#4497d5',
'#3567c6' => '#3567c6',
'#b151ee' => '#b151ee',
'#c875ea' => '#c875ea',
'#e46990' => '#e46990',
'#ffccd7' => '#ffccd7'
]
]);
}
public function getName()
{
return null;
}
}

View File

@@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class MainConfigurationFormType extends AbstractType
{
@@ -62,12 +63,19 @@ class MainConfigurationFormType extends AbstractType
$builder->add('email', new EmailFormType(), [
'label' => 'Emails',
]);
$builder->add('custom-links', CollectionType::class, [
'entry_type' => CustomLinkFormType::class,
'entry_options' => ['label' => false],
'allow_add' => true,
'allow_delete' => true,
]);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'required' => false,
'required' => false,
'allow_extra_fields' => true
]);
}

View File

@@ -46,10 +46,34 @@ class Prod extends Helper
$selected = $saveSettings ? ((isset($searchSet['bases']) && isset($searchSet['bases'][$sbasId])) ? (in_array($coll->get_base_id(), $searchSet['bases'][$sbasId])) : true) : true;
$bases[$sbasId]['collections'][] = array(
'selected' => $selected,
'base_id' => $coll->get_base_id()
'base_id' => $coll->get_base_id(),
'name' => $coll->get_name(),
'order' => $coll->get_ord()
);
}
/** @var DisplaySettingService $settings */
$settings = $this->app['settings'];
$userOrderSetting = $settings->getUserSetting($this->app->getAuthenticatedUser(), 'order_collection_by');
// a temporary array to sort the collections
$aName = [];
list($ukey, $uorder) = ["order", SORT_ASC]; // default ORDER_BY_ADMIN
switch ($userOrderSetting) {
case $settings::ORDER_ALPHA_ASC :
list($ukey, $uorder) = ["name", SORT_ASC];
break;
case $settings::ORDER_ALPHA_DESC :
list($ukey, $uorder) = ["name", SORT_DESC];
break;
}
foreach ($bases[$sbasId]['collections'] as $key => $row) {
$aName[$key] = $row[$ukey];
}
// sort the collections
array_multisort($aName, $uorder, SORT_REGULAR, $bases[$sbasId]['collections']);
foreach ($databox->get_meta_structure() as $fieldMeta) {
if (!$fieldMeta->is_indexable()) {
continue;

View File

@@ -15,6 +15,8 @@ use MediaAlchemyst\Specification\SpecificationInterface;
interface Subdef
{
const OPTION_DEVICE = 'devices';
const TYPE_IMAGE = 'image';
const TYPE_ANIMATION = 'gif';
const TYPE_VIDEO = 'video';

View File

@@ -53,7 +53,7 @@ class Installer
private function createDB(Connection $dbConn = null, $template, User $admin)
{
$template = new \SplFileInfo(__DIR__ . '/../../../conf.d/data_templates/' . $template . '-simple.xml');
$template = new \SplFileInfo(__DIR__ . '/../../../conf.d/data_templates/' . $this->app['phraseanet.structure-template']->getAvailable()->getTemplateName($template) . '.xml');
$databox = \databox::create($this->app, $dbConn, $template);
$this->app->getAclForUser($admin)

View File

@@ -7,40 +7,18 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Media\Subdef\Image;
use Alchemy\Phrasea\Media\Subdef\Audio;
use Alchemy\Phrasea\Media\Subdef\Video;
use Alchemy\Phrasea\Media\Subdef\FlexPaper;
use Alchemy\Phrasea\Media\Subdef\Gif;
use Alchemy\Phrasea\Media\Subdef\Image;
use Alchemy\Phrasea\Media\Subdef\Unknown;
use Alchemy\Phrasea\Media\Subdef\Subdef as SubdefSpecs;
use Alchemy\Phrasea\Media\Subdef\Video;
use Alchemy\Phrasea\Media\Type\Type as SubdefType;
use MediaAlchemyst\Specification\SpecificationInterface;
use Symfony\Component\Translation\TranslatorInterface;
class databox_subdef
{
const CLASS_THUMBNAIL = 'thumbnail';
const CLASS_PREVIEW = 'preview';
const CLASS_DOCUMENT = 'document';
const DEVICE_ALL = 'all';
const DEVICE_HANDHELD = 'handheld';
const DEVICE_PRINT = 'print';
const DEVICE_PROJECTION = 'projection';
const DEVICE_SCREEN = 'screen';
const DEVICE_TV = 'tv';
protected static $mediaTypeToSubdefTypes = [
SubdefType::TYPE_AUDIO => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_AUDIO],
SubdefType::TYPE_DOCUMENT => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_FLEXPAPER],
SubdefType::TYPE_FLASH => [SubdefSpecs::TYPE_IMAGE],
SubdefType::TYPE_IMAGE => [SubdefSpecs::TYPE_IMAGE],
SubdefType::TYPE_VIDEO => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_VIDEO, SubdefSpecs::TYPE_ANIMATION],
SubdefType::TYPE_UNKNOWN => [SubdefSpecs::TYPE_IMAGE]
];
/**
* The class type of the subdef
* Is null or one of the CLASS_* constants
@@ -51,52 +29,61 @@ class databox_subdef
protected $devices = [];
protected $name;
protected $path;
protected $preset;
protected $subdef_group;
protected $labels = [];
protected $downloadable;
protected $translator;
/**
* @var bool
*/
private $requiresMetadataUpdate;
protected $downloadable;
protected $translator;
protected static $mediaTypeToSubdefTypes = [
SubdefType::TYPE_AUDIO => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_AUDIO],
SubdefType::TYPE_DOCUMENT => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_FLEXPAPER],
SubdefType::TYPE_FLASH => [SubdefSpecs::TYPE_IMAGE],
SubdefType::TYPE_IMAGE => [SubdefSpecs::TYPE_IMAGE],
SubdefType::TYPE_VIDEO => [SubdefSpecs::TYPE_IMAGE, SubdefSpecs::TYPE_VIDEO, SubdefSpecs::TYPE_ANIMATION],
SubdefType::TYPE_UNKNOWN => [SubdefSpecs::TYPE_IMAGE],
];
const CLASS_THUMBNAIL = 'thumbnail';
const CLASS_PREVIEW = 'preview';
const CLASS_DOCUMENT = 'document';
const DEVICE_ALL = 'all';
const DEVICE_HANDHELD = 'handheld';
const DEVICE_PRINT = 'print';
const DEVICE_PROJECTION = 'projection';
const DEVICE_SCREEN = 'screen';
const DEVICE_TV = 'tv';
/**
* @var bool
*/
private $orderable;
/**
*
* @param SubdefType $type
* @param SimpleXMLElement $sd
* @param TranslatorInterface $translator
*
* @return databox_subdef
*/
public function __construct(SubdefType $type, SimpleXMLElement $sd, TranslatorInterface $translator)
{
$this->subdef_group = $type;
$this->class = (string) $sd->attributes()->class;
$this->class = (string)$sd->attributes()->class;
$this->translator = $translator;
foreach ($sd->devices as $device) {
$this->devices[] = (string) $device;
$this->devices[] = (string)$device;
}
$this->name = strtolower($sd->attributes()->name);
$this->downloadable = p4field::isyes($sd->attributes()->downloadable);
$this->orderable = isset($sd->attributes()->orderable) ? p4field::isyes($sd->attributes()->orderable) : true;
$this->path = trim($sd->path) !== '' ? p4string::addEndSlash(trim($sd->path)) : '';
$this->requiresMetadataUpdate = p4field::isyes((string) $sd->meta);
$this->preset = $sd->attributes()->presets;
$this->requiresMetadataUpdate = p4field::isyes((string)$sd->meta);
foreach ($sd->label as $label) {
$lang = trim((string) $label->attributes()->lang);
$lang = trim((string)$label->attributes()->lang);
if ($lang) {
$this->labels[$lang] = (string) $label;
$this->labels[$lang] = (string)$label;
}
}
switch ((string) $sd->mediatype) {
switch ((string)$sd->mediatype) {
default:
case SubdefSpecs::TYPE_IMAGE:
$this->subdef_type = $this->buildImageSubdef($sd);
@@ -118,7 +105,6 @@ class databox_subdef
break;
}
}
/**
* Build Image Subdef object depending the SimpleXMLElement
*
@@ -128,7 +114,6 @@ class databox_subdef
protected function buildImageSubdef(SimpleXMLElement $sd)
{
$image = new Image($this->translator);
if ($sd->icodec) {
$image->setOptionValue(Image::OPTION_ICODEC, (string) $sd->icodec);
}
@@ -147,10 +132,8 @@ class databox_subdef
if ($sd->flatten) {
$image->setOptionValue(Image::OPTION_FLATTEN, p4field::isyes($sd->flatten));
}
return $image;
}
/**
* Build Audio Subdef object depending the SimpleXMLElement
*
@@ -160,7 +143,6 @@ class databox_subdef
protected function buildAudioSubdef(SimpleXMLElement $sd)
{
$audio = new Audio($this->translator);
if ($sd->acodec) {
$audio->setOptionValue(Audio::OPTION_ACODEC, (string) $sd->acodec);
}
@@ -170,10 +152,8 @@ class databox_subdef
if ($sd->audiosamplerate) {
$audio->setOptionValue(Audio::OPTION_AUDIOSAMPLERATE, (int) $sd->audiosamplerate);
}
return $audio;
}
/**
* Build Video Subdef object depending the SimpleXMLElement
*
@@ -183,7 +163,6 @@ class databox_subdef
protected function buildVideoSubdef(SimpleXMLElement $sd)
{
$video = new Video($this->translator);
if ($sd->size) {
$video->setOptionValue(Video::OPTION_SIZE, (int) $sd->size);
}
@@ -208,10 +187,8 @@ class databox_subdef
if ($sd->GOPsize) {
$video->setOptionValue(Video::OPTION_GOPSIZE, (int) $sd->GOPsize);
}
return $video;
}
/**
* Build GIF Subdef object depending the SimpleXMLElement
*
@@ -221,17 +198,14 @@ class databox_subdef
protected function buildGifSubdef(SimpleXMLElement $sd)
{
$gif = new Gif($this->translator);
if ($sd->size) {
$gif->setOptionValue(Gif::OPTION_SIZE, (int) $sd->size);
}
if ($sd->delay) {
$gif->setOptionValue(Gif::OPTION_DELAY, (int) $sd->delay);
}
return $gif;
}
/**
* Build Flexpaper Subdef object depending the SimpleXMLElement
*
@@ -242,8 +216,8 @@ class databox_subdef
{
return new FlexPaper($this->translator);
}
/**
*
* @return string
*/
public function get_class()
@@ -252,6 +226,16 @@ class databox_subdef
}
/**
*
* @return string
*/
public function get_preset()
{
return $this->preset;
}
/**
*
* @return string
*/
public function get_path()
@@ -262,7 +246,7 @@ class databox_subdef
/**
* The devices matching this subdefinition
*
* @return array
* @return Array
*/
public function getDevices()
{
@@ -272,7 +256,7 @@ class databox_subdef
/**
* The current SubdefType the subdef converts documents
*
* @return \Alchemy\Phrasea\Media\Subdef\Subdef
* @return Alchemy\Phrasea\Media\Subdef\Subdef
*/
public function getSubdefType()
{
@@ -292,7 +276,7 @@ class databox_subdef
/**
* An associative label ; keys are i18n languages
*
* @return array
* @return Array
*/
public function get_labels()
{
@@ -306,21 +290,12 @@ class databox_subdef
} elseif (isset($this->labels[$code])) {
return $this->labels[$code];
}
return null;
}
/**
* The name of the subdef
* boolean
*
* @return string
*/
public function get_name()
{
return $this->name;
}
/**
* @return bool
*/
public function isDownloadable()
@@ -344,7 +319,6 @@ class databox_subdef
public function getAvailableSubdefTypes()
{
$subdefTypes = [];
$availableDevices = [
self::DEVICE_ALL,
self::DEVICE_HANDHELD,
@@ -353,11 +327,8 @@ class databox_subdef
self::DEVICE_SCREEN,
self::DEVICE_TV,
];
if (isset(self::$mediaTypeToSubdefTypes[$this->subdef_group->getType()])) {
foreach (self::$mediaTypeToSubdefTypes[$this->subdef_group->getType()] as $subdefType) {
if ($subdefType == $this->subdef_type->getType()) {
$mediatype_obj = $this->subdef_type;
} else {
@@ -385,13 +356,11 @@ class databox_subdef
break;
}
}
$mediatype_obj->registerOption(new \Alchemy\Phrasea\Media\Subdef\OptionType\Multi($this->translator->trans('Target Device'), 'devices', $availableDevices, $this->devices));
$mediatype_obj->registerOption(new \Alchemy\Phrasea\Media\Subdef\OptionType\Multi($this->translator->trans('Target Device'),
'devices', $availableDevices, $this->devices));
$subdefTypes[] = $mediatype_obj;
}
}
return $subdefTypes;
}
@@ -405,6 +374,16 @@ class databox_subdef
return $this->requiresMetadataUpdate;
}
/**
* The name of the subdef
*
* @return string
*/
public function get_name()
{
return $this->name;
}
/**
* Get the MediaAlchemyst specs for the current subdef
*

View File

@@ -9,8 +9,8 @@
*/
use Alchemy\Phrasea\Databox\SubdefGroup;
use Alchemy\Phrasea\Media\MediaTypeFactory;
use Assert\Assertion;
use Alchemy\Phrasea\Media\MediaTypeFactory;
use Symfony\Component\Translation\TranslatorInterface;
class databox_subdefsStructure implements IteratorAggregate, Countable
@@ -185,15 +185,19 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
* @param string $groupname
* @param string $name
* @param string $class
* @param string $mediatype
* @param string $preset
* @return databox_subdefsStructure
*/
public function add_subdef($groupname, $name, $class)
public function add_subdef($groupname, $name, $class, $mediatype, $preset)
{
$dom_struct = $this->databox->get_dom_structure();
$subdef = $dom_struct->createElement('subdef');
$subdef->setAttribute('class', $class);
$subdef->setAttribute('name', mb_strtolower($name));
$subdef->setAttribute('presets', $preset);
$subdef->setAttribute('mediaType', $mediatype);
$dom_xp = $this->databox->get_xpath_structure();
$query = '//record/subdefs/subdefgroup[@name="' . $groupname . '"]';
@@ -216,25 +220,6 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
return $this;
}
/**
* @param SubdefGroup[] $groups
*/
public function updateSubdefGroups($groups)
{
Assertion::allIsInstanceOf($groups, SubdefGroup::class);
$dom_xp = $this->databox->get_xpath_structure();
foreach ($groups as $group) {
$nodes = $dom_xp->query('//record/subdefs/subdefgroup[@name="' . $group->getName() . '"]');
/** @var DOMElement $node */
foreach ($nodes as $node) {
$node->setAttribute('document_orderable', ($group->isDocumentOrderable() ? 'true' : 'false'));
}
}
}
/**
* @param string $group
* @param string $name
@@ -242,11 +227,12 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
* @param boolean $downloadable
* @param array $options
* @param array $labels
* @param bool $orderable
* @param boolean $orderable
* @param string $preset
* @return databox_subdefsStructure
* @throws Exception
*/
public function set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable = true)
public function set_subdef($group, $name, $class, $downloadable, $options, $labels, $orderable = true, $preset = "Custom")
{
$dom_struct = $this->databox->get_dom_structure();
@@ -255,6 +241,7 @@ class databox_subdefsStructure implements IteratorAggregate, Countable
$subdef->setAttribute('name', mb_strtolower($name));
$subdef->setAttribute('downloadable', ($downloadable ? 'true' : 'false'));
$subdef->setAttribute('orderable', ($orderable ? 'true' : 'false'));
$subdef->setAttribute('presets', $preset);
foreach ($labels as $code => $label) {
$child = $dom_struct->createElement('label');

View File

@@ -431,6 +431,7 @@ class record_preview extends record_adapter
$nbDays--; // because 0 is included
for ($d=$nbDays; $d>=0; $d--) {
$datetime = new DateTime('-' . $d . ' days');
$datetime->modify('+1 day');
$date = date_format($datetime, 'Y-m-d');
if($d == $nbDays) {
$this->statistics['from'] = $date;

View File

@@ -12,7 +12,7 @@ main:
port: 3306
user: '{{ mariadb.user }}'
password: '{{ mariadb.password }}'
dbname: '{{ mariadb.appbox_db }}'
dbname: '{{ mariadb.appbox_db }}'
driver: pdo_mysql
charset: UTF8
database-test:

View File

@@ -21,6 +21,6 @@
when: php.pecl_packages is defined
- name: Enable extension
shell: php5enmod {{ item.name }}
shell: phpenmod {{ item.name }}
with_items: '{{ php.pecl_packages }}'
when: php.pecl_packages is defined

View File

@@ -48,5 +48,7 @@ gulp.task('build-vendors', [
'build-requirejs',
'build-jquery-treeview',
'build-jquery-lazyload',
'build-jquery-test-paths'
], function() {});
'build-jquery-test-paths',
'build-simple-colorpicker'
], function () {
});

View File

@@ -0,0 +1,12 @@
var gulp = require('gulp');
var config = require('../../config.js');
var utils = require('../../utils.js');
gulp.task('build-simple-colorpicker', function () {
gulp.start('copy-simple-colorpicker');
});
gulp.task('copy-simple-colorpicker', function () {
return gulp.src(config.paths.vendors + 'jquery-simplecolorpicker/*')
.pipe(gulp.dest(config.paths.build + 'vendors/jquery-simplecolorpicker'));
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2017-12-22T11:45:35Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<file date="2018-01-09T05:47:20Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2017-12-22T11:46:20Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<file date="2018-01-09T05:47:59Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2017-12-22T11:47:12Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<file date="2018-01-09T05:48:46Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2017-12-22T11:48:10Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<file date="2018-01-09T05:49:38Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

View File

@@ -336,6 +336,200 @@ div.switch_right.unchecked {
margin-top: 5px;
}
.alert .close {
text-decoration: none;
}
.subdefs [id^="box"] {
display: none;
}
.subdefs .subviews-submit {
position: fixed;
top: 75px;
right: 40px;
z-index: 1;
}
h2.subdefName {
display: inline-block;
margin-right: 1.5rem;
}
.reload, .loader, .status {
display: inline-block;
}
.langTab {
display: inline-block;
vertical-align: top;
}
.langTab h3 {
font-weight: 700;
font-size: 13px;
margin: 4px 0;
line-height: 11px;
text-align: center;
}
.toggle {
display: block;
margin: 15px 0;
color: #08c;
cursor: pointer;
}
.subdefTab input, .langTab input {
margin: 0;
}
label[for="elasticsearch_settings_highlight"] {
display: inline-block;
margin-left: 0.5rem;
margin-bottom: 1rem;
}
input[id="elasticsearch_settings_highlight"] {
float: left;
}
#downbutton {
margin: 1rem 0;
}
#upbutton {
width: 100%;
text-align: left;
}
#upbutton i {
position: relative;
left: -5px;
}
#downbutton i {
position: relative;
left: -5px;
}
.form-horizontal .controls + div {
margin-left: 180px;
font-style: italic;
}
.ui-dialog .ui-dialog-content {
position: relative;
border: 0;
padding: .5em 1em;
background: none;
margin-bottom: 7rem;
overflow: visible;
}
/******* SETUP *******************************************************************/
#custom-link-table {
width: 100%;
thead {
th {
text-align: left;
font-weight: bold;
}
}
td {
height: 30px;
width: 19%;
input {
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 30px;
}
select {
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 30px;
}
.simplecolorpicker {
width: 21px;
height: 21px;
background-repeat: no-repeat;
background-size: contain !important;
background-position: center center;
border: none;
margin-right: 3px;
}
button {
height: 30px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
}
td:nth-of-type(5) {
width: 14%;
}
td:nth-of-type(6) {
width: 3%;
}
td:nth-of-type(7) {
width: 3%;
}
td:last-child {
width: 8%;
}
}
span.simplecolorpicker.picker {
min-width: 0px;
width: 22px;
margin-top: -360px;
border-radius: 0px;
margin-left: 4px;
padding: 0;
span {
width: 20px;
margin: 0px;
}
}
#add-row {
margin-top: 10px;
margin-bottom: 20px;
float: right;
}
.link_check_box:before {
content: "";
display: inline-block;
width: 30px;
height: 30px;
background: url(/assets/common/images/icons/Bouton-Bold.png) #fff;
background-repeat: no-repeat;
background-size: 75%;
background-position: center center;
}
.link_check_box:checked:before {
content: "";
display: inline-block;
width: 30px;
height: 30px;
background: url(/assets/common/images/icons/Bouton-bold-active.png) #fff;
background-repeat: no-repeat;
background-size: 75%;
background-position: center center;
}
@media screen and (max-width: 1150px) {
.langTab {
display: block;
}
}
@import './databases';
@import './fields';
@import './tables';

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 B

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

View File

@@ -31,10 +31,14 @@ var commonModule = (function ($, p4) {
$(this).removeClass('context-menu-item-hover');
});
$('#help-trigger').contextMenu('#mainMenu .helpcontextmenu', {openEvt: 'click', dropDown: true, theme: 'vista', dropDown: true,
showTransition: 'slideDown',
hideTransition: 'hide',
shadow: false
// $('#help-trigger').contextMenu('#mainMenu .helpcontextmenu', {openEvt: 'click', dropDown: true, theme: 'vista', dropDown: true,
// showTransition: 'slideDown',
// hideTransition: 'hide',
// shadow: false
// });
$('body').on('click', '.infoDialog', function (event) {
infoDialog($(this));
});
});
@@ -89,6 +93,26 @@ var commonModule = (function ($, p4) {
$('#' + div).hide().remove();
}
function infoDialog(el) {
$("#DIALOG").attr('title', '')
.empty()
.append(el.attr('infos'))
.dialog({
autoOpen: false,
closeOnEscape: true,
resizable: false,
draggable: false,
width: 600,
height: 400,
modal: true,
overlay: {
backgroundColor: '#000',
opacity: 0.7
}
}).dialog('open').css({'overflow-x': 'auto', 'overflow-y': 'auto'});
}
// @deprecated
function manageSession(data, showMessages) {

View File

@@ -3,6 +3,10 @@
{% extends "common/index_bootstrap.html.twig" %}
{% block icon %}
<link rel="shortcut icon" type="image/x-icon" href="/assets/account/images/favicon.ico">
{% endblock %}
{% block stylesheet %}
<link type="text/css" rel="stylesheet" href="/assets/account/css/account{% if not app.debug %}.min{% endif %}.css">
<style type="text/css">

View File

@@ -0,0 +1,14 @@
<tr>
<td>{{ form_widget(form.linkName) }}</td>
<td>{{ form_widget(form.linkLanguage) }}</td>
<td>{{ form_widget(form.linkUrl) }}</td>
<td>{{ form_widget(form.linkLocation) }}</td>
<td>{{ form_widget(form.linkOrder) }}</td>
<td>{{ form_widget(form.linkBold, { 'attr': {'style' : 'margin-top:0', 'class': 'link_check_box'} }) }}</td>
<td>{{ form_widget(form.linkColor, { 'attr': {'class': 'link-color'} }) }}</td>
<td>
<button class="btn btn-default close-row">
<span class="ui-button-icon-primary ui-icon ui-icon-closethick"></span>
</button>
</td>
</tr>

View File

@@ -8,6 +8,7 @@
{% endblock %}
{% block stylesheet %}
<link rel="stylesheet" href="/bower_components/jquery-simplecolorpicker/jquery.simplecolorpicker.css">
<link type="text/css" rel="stylesheet" href="/assets/admin/css/admin{% if not app.debug %}.min{% endif %}.css" />
{% endblock %}

View File

@@ -34,23 +34,36 @@
{{ form_start(form, {'method': 'POST', 'action' : path('setup_display_globals'), 'attr': {'class' : 'form-horizontal'}}) }}
{{ form_errors(form) }}
{% for daform in form %}
<fieldset>
<legend>{{ daform.vars['label'] }}</legend>
{% for formdata in daform %}
<div class="control-group">
{{ form_errors(formdata) }}
{{ form_label(formdata, null, { 'label_attr': {'class' : 'control-label'} } ) }}
<div class="controls">
{{ form_widget(formdata, {'attr': {'class': 'input-xxlarge'}}) }}
</div>
{% if daform.vars['label'] != null %}
<fieldset>
<legend>{{ daform.vars['label'] }}</legend>
{% for formdata in daform %}
<div class="control-group">
{{ form_errors(formdata) }}
{{ form_label(formdata, null, { 'label_attr': {'class' : 'control-label'} } ) }}
<div class="controls">
{{ form_widget(formdata, {'attr': {'class': 'input-xxlarge'}}) }}
</div>
<div>{{ formdata.vars['help_message'] }}</div>
{{ form_rest(formdata) }}
</div>
{% endfor %}
{{ form_rest(daform) }}
</fieldset>
<div>{{ formdata.vars['help_message'] }}</div>
{{ form_rest(formdata) }}
</div>
{% endfor %}
{{ form_rest(daform) }}
</fieldset>
{% endif %}
{% endfor %}
<legend>{{ "setup::custom-link:title-custom-link" | trans }}</legend>
<table class="links" id="custom-link-table"
data-prototype="{% filter escape %}{% include 'admin/custom_links.html.twig' with {'form': form['custom-links'].vars.prototype} %}{% endfilter %}">
<tbody>
{% for links in form['custom-links'] %}
{% include 'admin/custom_links.html.twig' with {'form': links} %}
{% endfor %}
</tbody>
</table>
<button id="add-row" class="btn btn-success">{{ "setup::custom-link:add-link" | trans }}</button>
<div style="clear: both;"></div>
<div class="well well-large">
<div style="max-width: 400px;margin: 0 auto 10px;">
<input type="submit" class="btn btn-primary btn-block btn-large" value="{{ 'boutton::valider' | trans }}"/>
@@ -58,12 +71,26 @@
</div>
{{ form_end(form) }}
<script type="text/javascript" src="/assets/vendors/jquery-simplecolorpicker/jquery.simplecolorpicker.js"></script>
<script type='text/javascript'>
{% autoescape false %}
$(document).ready(function() {
// use html5 fallback validation if browser do not support required attribute
var form = $("#GV_form");
var inputs = form.find("input, select, textarea");
var header = "<thead>" +
"<th>{{ "setup::custom-link:name-link" | trans }}</th>" +
"<th>{{ "setup::custom-link:language-link" | trans }}</th>" +
"<th>{{ "setup::custom-link:link-url" | trans }}</th>" +
"<th>{{ "setup::custom-link:location-link" | trans }}</th>" +
"<th>{{ "setup::custom-link:order-link" | trans }}</th>" +
"<th></th>" +
"<th></th>" +
"<th></th>" +
"</thead>";
// if required not supported, emulate it
if (!Modernizr.input.required) {
form.bind("submit", function (event) {
@@ -95,6 +122,73 @@
}
});
}
// Get the ul that holds the collection of links
$collectionHolder = $('table.links');
$collectionHolder.data('index', $collectionHolder.find(':input').length);
if ($collectionHolder.find('tbody tr').length > 0) {
$("#custom-link-table").append(header);
}
$('select.link-color').simplecolorpicker({picker: true});
_.each($('select.link-color'), function (element) {
updateSelectColor($(element).siblings(), $(element).val());
updateInputNameColor($(element).parent().siblings(':first').find("input"), $(element).val());
});
$("#add-row").click(function (e) {
e.preventDefault();
if ($collectionHolder.find('tbody tr').length == 0) {
$("#custom-link-table").append(header);
}
addTagForm($collectionHolder);
});
function addTagForm($collectionHolder) {
// Get the data-prototype
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
var newForm = prototype;
newForm = newForm.replace(/__name__/g, index);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
$collectionHolder.append(newForm);
$('select.link-color').simplecolorpicker({picker: true});
_.each($('select.link-color'), function (element) {
updateSelectColor($(element).siblings(), $(element).val());
updateInputNameColor($(element).parent().siblings(':first').find("input"), $(element).val());
});
}
$("#custom-link-table").on('click', '.close-row', function () {
$(this).closest('tr').remove();
var rowCount = $('#custom-link-table tr').length;
//remove header if no more rows
if (rowCount <= 1) {
$("#custom-link-table").empty();
}
return false;
});
$("#custom-link-table").on('change', 'select.link-color', function () {
var element = $(this).parent().siblings(':first').find("input");
updateSelectColor($(this).siblings(), $(this).val());
updateInputNameColor(element, $(this).val());
});
function updateSelectColor(element, color) {
element.css("border", "none");
if (color === "") {
element.css("background", "url(/assets/common/images/icons/Bouton-couleur.png)");
} else {
element.css("background", color);
}
}
function updateInputNameColor(element, color) {
element.css("background-color", color);
if (color === "") {
element.css("color", "#555");
} else {
element.css("color", "#FFFFFF");
}
}
});
{% endautoescape %}
</script>

View File

@@ -15,372 +15,583 @@
{#<script type="text/javascript" src="/assets/vendors/jquery/jquery{% if not app.debug %}.min{% endif %}.js"></script>
<script type="text/javascript" src="/assets/vendors/jquery-ui/jquery-ui{% if not app.debug %}.min{% endif %}.js"></script>
<script type="text/javascript" src="/assets/vendors/jquery-test-paths/jquery.test-paths{% if not app.debug %}.min{% endif %}.js"></script>#}
<script type="text/javascript">
$(document).ready(function(){
$('.path_testable').path_file_test();
$('.url_testable').url_test();
$('.tabs').tabs({
beforeActivate:function(event, ui){
$('.path_testable:visible, .url_testable:visible').trigger('keyup');
}
});
});
<script type="text/javascript">
$(document).ready(function () {
$('.path_testable').path_file_test();
$('.url_testable').url_test();
$('.tabs').tabs({
beforeActivate: function (event, ui) {
$('.path_testable:visible, .url_testable:visible').trigger('keyup');
}
});
function select_mediatype(name, selector)
{
$('.'+name).hide();
$('#box'+name+$(selector).val()).show();
}
$(function() {
// a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
$( "#dialog:ui-dialog" ).dialog( "destroy" );
$(".toggle").on("click", function () {
var box = $(this).data("toggle");
$(box).toggle("500");
});
var name = $( "#name" ), accessclass = $( "#accessclass" ),
allFields = $( [] ).add( name ).add(accessclass),
tips = $( ".validateTips" );
function updateTips( t ) {
tips
.text( t )
.addClass( "ui-state-highlight" );
setTimeout(function() {
tips.removeClass( "ui-state-highlight", 1500 );
}, 500 );
}
function checkLength( o, n, min, max ) {
if ( o.val().length > max || o.val().length < min ) {
o.addClass( "ui-state-error" );
updateTips( "Length of " + n + " must be between " +
min + " and " + max + "." );
return false;
} else {
return true;
}
}
function get_current_group()
{
return $('.ui-tabs-nav .ui-state-active a').html();
}
function checkPresence( o ) {
var el = $('input[name="subdefs[]"][value="'+get_current_group()+'_'+o.val()+'"]');
if ( el.length !== 0 ) {
o.addClass( "ui-state-error" );
updateTips( "SubdefName should be unique per group" );
return false;
} else {
return true;
}
}
function checkSpecialChar( o )
{
var ok = true;
var reg = new RegExp("[A-Za-z0-9-]+","g");
if(o.val().match(reg)[0].length !== o.val().length)
{
ok = false;
o.addClass( "ui-state-error" );
updateTips( "Special characters (except minus) or espaces are not authorized" );
}
return ok;
}
$( "#dialog-form" ).dialog({
autoOpen: false,
height: 250,
width: 350,
modal: true,
buttons: {
"Create a Subdef": function() {
var bValid = true;
allFields.removeClass( "ui-state-error" );
bValid = bValid && checkLength( name, "subdef name", 3, 16 );
bValid = bValid && checkSpecialChar( name );
bValid = bValid && checkPresence( name );
if ( bValid ) {
$('input[name="add_subdef[group]"]').val(get_current_group());
$('input[name="add_subdef[name]"]').val(name.val());
$('input[name="add_subdef[class]"]').val(accessclass.val());
$( this ).dialog( "close" );
$('form.subdefs').submit();
}
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
close: function() {
allFields.val( "" ).removeClass( "ui-state-error" );
}
});
$( "#create-subdef" )
// .button()
.click(function() {
$( "#dialog-form" ).dialog( "open" );
});
$('.subdef_deleter')
// .button()
.click(function(){
delete_subdef($(this).next('input[name="subdef"]').val());
return false;
});
function delete_subdef(name)
{
$( "#dialog-delete-subdef" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Delete subdef": function() {
$('#delete_subdef').val(name);
$( this ).dialog( "destroy" );
$('form.subdefs').submit();
},
Cancel: function() {
$( this ).dialog( "destroy" );
}
}
$("input, select").one("change", activeSubmit);
});
}
});
function activeSubmit() {
$(".subviews-submit").removeAttr("disabled");
$("input, select").off("change", activeSubmit);
}
function fillCheckbox(section, name, defType, fieldname, values) {
$("[name='" + section + "_" + name + "_" + defType + "[" + fieldname + "][]']").each(function () {
$(this).removeAttr("checked");
for (var key in values) {
if ($(this).val() == values[key])
$(this).prop("checked", "true");
}
});
}
function fillRadio(section, name, defType, fieldname, value) {
$("[name='" + section + "_" + name + "_" + defType + "[" + fieldname + "]'][value='" + value + "']").prop("checked", true);
}
function fillSelect(section, name, defType, fieldname, value) {
$("[name='" + section + "_" + name + "_" + defType + "[" + fieldname + "]']").val(value)
}
function fillSlide(section, name, defType, fieldname, value) {
$("#slider" + section + name + defType + fieldname).slider({value: value});
$("#slidervalue" + section + name + defType + fieldname).val(value);
}
function populate_values(section, name) {
var config = JSON.parse('{{ config |json_encode|raw }}'),
i = 0,
defType = $('[name="' + section + '_' + name + '_mediatype"]').val(),
preset = $('[name="' + section + '_' + name + '_presets"]').val(),
optionValue = $('[name="' + section + '_' + name + '_presets"] option:selected').attr("value");
if (typeof optionValue === 'undefined') {
return;
}
for (var input in config[defType].form) {
if (config[defType].form[input] == "slide") {
fillSlide(section, name, defType, input, config[defType].definitions[preset][input]);
}
if (config[defType].form[input] == "radio") {
fillRadio(section, name, defType, input, config[defType].definitions[preset][input]);
}
if (config[defType].form[input] == "select") {
fillSelect(section, name, defType, input, config[defType].definitions[preset][input]);
}
if (config[defType].form[input] == "checkbox") {
fillCheckbox(section, name, defType, input, config[defType].definitions[preset][input]);
}
i++;
}
}
function select_mediatype(type, name, selector) {
var config = JSON.parse('{{ config |json_encode|raw }}'),
inputPresets = '[name="' + type + '_' + name + '_presets"]',
defType = $(selector).val();
$('.' + type + name).hide();
$('[data-toggle^="#box' + type + name + '"]').hide();
$('[data-toggle="#box' + type + name + defType + '"]').show();
$('#box' + type + name + $(selector).val()).show();
if (defType == 'flexpaper') {
$(inputPresets).closest("tr").hide();
return;
} else {
$(inputPresets).closest("tr").show();
}
$(inputPresets)
.find('option')
.remove()
.end()
.append($("<option value='custom'></option>").text('{{ 'Custom' | trans }}'));
if (typeof config[defType] === 'undefined') {
return;
}
for (var key in config[defType].definitions) {
if (config[defType].definitions[key] == null) {
$(inputPresets).append($("<option></option>")
.attr("disabled", "disabled")
.text(key)
);
} else {
$(inputPresets).append($("<option></option>")
.attr("value", key)
.text(key)
);
}
}
}
function subview_type(selector) {
var mapping = JSON.parse('{{ subviews_mapping |json_encode|raw }}'),
subviewType = $(selector).val();
$("#mediaType")
.find('option')
.remove()
.end()
.append($("<option></option>").text('{{ 'Choisir' | trans }}'));
for (var key in mapping[subviewType]) {
$("#mediaType").append($('<option></option>')
.attr("value", mapping[subviewType][key])
.text(mapping[subviewType][key])
);
}
}
function media_type(selector) {
var config = JSON.parse('{{ config |json_encode|raw }}'),
defType = $(selector).val();
$("#presets")
.find('option')
.remove()
.end()
.append($("<option></option>").text('{{ 'Choisir' | trans }}'));
if (typeof config[defType] === 'undefined') {
return;
}
for (var key in config[defType].definitions) {
if (config[defType].definitions[key] == null) {
$("#presets").append($("<option></option>")
.attr("disabled", "disabled")
.text(key)
);
} else {
$("#presets").append($('<option></option>')
.attr("value", key)
.text(key)
);
}
}
}
$(function () {
// a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
$("#dialog:ui-dialog").dialog("destroy");
var name = $("#name"), accessclass = $("#accessclass"), subviewType = $("#subviewType"),
mediaType = $("#mediaType"), presets = $("#presets"),
allFields = $([]).add(name).add(accessclass).add(subviewType).add(mediaType).add(presets),
tips = $(".validateTips");
function updateTips(t) {
tips
.text(t)
.addClass("ui-state-highlight");
setTimeout(function () {
tips.removeClass("ui-state-highlight", 1500);
}, 500);
}
function checkLength(o, n, min, max) {
if (o.val().length > max || o.val().length < min) {
o.addClass("ui-state-error");
updateTips("Length of " + n + " must be between " +
min + " and " + max + ".");
return false;
} else {
return true;
}
}
function checkPresence(mediaType, o) {
var el = $('input[name="subdefs[]"][value="' + mediaType + '_' + o.val() + '"]');
if (el.length !== 0) {
o.addClass("ui-state-error");
updateTips("SubdefName should be unique per group");
return false;
} else {
return true;
}
}
function checkSpecialChar(o) {
var ok = true;
var reg = new RegExp("[A-Za-z0-9-]+", "g");
if (o.val().match(reg)[0].length !== o.val().length) {
ok = false;
o.addClass("ui-state-error");
updateTips("Special characters (except minus) or espaces are not authorized");
}
return ok;
}
$("#dialog-form").dialog({
autoOpen: false,
height: 420,
width: 300,
modal: true,
buttons: {
"Create a Subdef": function () {
var bValid = true;
allFields.removeClass("ui-state-error");
bValid = bValid && checkLength(name, "subdef name", 3, 16);
bValid = bValid && checkSpecialChar(name);
bValid = bValid && checkPresence(subviewType.val(), name);
if (bValid) {
$('input[name="add_subdef[group]"]').val(subviewType.val());
$('input[name="add_subdef[name]"]').val(name.val());
$('input[name="add_subdef[mediaType]"]').val(mediaType.val());
$('input[name="add_subdef[class]"]').val(accessclass.val());
$('input[name="add_subdef[presets]"]').val(presets.val());
$(this).dialog("close");
$('form.subdefs').submit();
}
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
}
});
$("#create-subdef")
// .button()
.click(function () {
$("#dialog-form").dialog("open");
});
$('.subdef_deleter')
// .button()
.click(function () {
delete_subdef($(this).next('input[name="subdef"]').val());
return false;
});
function delete_subdef(name) {
$("#dialog-delete-subdef").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
"Delete subdef": function () {
$('#delete_subdef').val(name);
$(this).dialog("destroy");
$('form.subdefs').submit();
},
Cancel: function () {
$(this).dialog("destroy");
}
}
});
}
});
</script>
{% endblock %}
{% block content %}
<p>
<button id="create-subdef" class="btn btn-success">{{ 'Create new subdef' | trans }}</button>
</p>
<div id="dialog-delete-subdef" title="{{ 'Delete the subdef ?' | trans }}" style="display:none;">
<p>
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
{{ 'These subdef will be permanently deleted and cannot be recovered. Are you sure?' | trans }}
<button id="create-subdef" class="btn btn-success">{{ 'Create new subdef' | trans }}</button>
</p>
</div>
<div id="dialog-delete-subdef" title="{{ 'Delete the subdef ?' | trans }}" style="display:none;">
<p>
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
{{ 'These subdef will be permanently deleted and cannot be recovered. Are you sure?' | trans }}
</p>
</div>
<div id="dialog-form" title="Create new subdef">
<p class="validateTips"></p>
<form>
<fieldset>
<label for="name">{{ 'Subdef name' | trans }}</label>
<input type="text" name="name" id="name" class="text ui-widget-content ui-corner-all" value=""/><br/>
<label for="accessclass">{{ 'classe d\'acces' | trans }}</label>
<select name="accessclass" id="accessclass">
<option value="document">{{ 'document' | trans }}</option>
<option value="preview" selected="selected">{{ 'preview' | trans }}</option>
<option value="thumbnail">{{ 'tout le monde' | trans }}</option>
</select>
</fieldset>
</form>
</div>
<div id="dialog-form" title="Create new subdef">
<p class="validateTips"></p>
<form>
<fieldset>
<label for="name">{{ 'Subdef name' | trans }}</label>
<input type="text" name="name" id="name" class="text ui-widget-content ui-corner-all" value=""/><br/>
<label for="accessclass">{{ 'classe d\'acces' | trans }}</label>
<select name="accessclass" id="accessclass">
<option value="document">{{ 'document' | trans }}</option>
<option value="preview" selected="selected">{{ 'preview' | trans }}</option>
<option value="thumbnail">{{ 'tout le monde' | trans }}</option>
</select>
<label for="subviewType">{{ 'subviewType' | trans }}</label>
<select name="subviewType" id="subviewType" onchange="subview_type(this)">
<option>{{ 'Choisir' | trans }}</option>
<option value="image">{{ 'image' | trans }}</option>
<option value="video">{{ 'video' | trans }}</option>
<option value="audio">{{ 'audio' | trans }}</option>
<option value="document">{{ 'document' | trans }}</option>
<option value="flash">{{ 'flash' | trans }}</option>
</select>
<label for="mediaType">{{ 'mediatype' | trans }}</label>
<select name="mediaType" id="mediaType" onchange="media_type(this)">
<option>{{ 'Choisir' | trans }}</option>
</select>
<label for="presets">{{ 'Presets' | trans }}</label>
<select name="presets" id="presets">
<option>{{ 'Choisir' | trans }}</option>
</select>
</fieldset>
</form>
</div>
<form method="post" action="{{ path('admin_subdefs_subdef_update', { 'sbas_id' : databox.get_sbas_id }) }}" target="_self" class="subdefs">
<div class="tabs">
<ul>
{% for subdefgroup, subdeflist in subdefs %}
<li><a class="no-ajax" href="#{{subdefgroup}}">{{subdefgroup}}</a></li>
{% endfor %}
</ul>
{% for subdefgroup, subdeflist in subdefs %}
<div id="{{subdefgroup}}">
<div>
<table cellspacing="0" cellpading="0" border="0" style="width:500px;">
<tbody>
<tr>
<td style="width:120px;">
<h2>{{ 'subdef.document' | trans }}</h2>
</td>
<td style="width:250px;"></td>
<td></td>
</tr>
<tr>
<td>{{ 'subdef.orderable' | trans }}</td>
<td><input type="checkbox" name="subdefsgroups[{{ subdefgroup }}][document_orderable]" {% if subdeflist.isDocumentOrderable() %}checked="checked" {% endif %}value="1"/></td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% for subdefname , subdef in subdeflist %}
<div>
<input type="hidden" name="subdefs[]" value="{{subdefgroup}}_{{subdefname}}"/>
<table cellspacing="0" cellpading="0" border="0" style="width:500px;">
<tbody>
<tr>
<td style="width:120px;">
<h2>{{subdefname}}</h2><button class="subdef_deleter btn btn-danger btn-mini">{{ 'boutton::supprimer' | trans }}</button>
<input type="hidden" name="subdef" value="{{subdefgroup}}_{{subdefname}}"/>
</td>
<td style="width:250px;"></td>
<td></td>
</tr>
{% for code, language in app['locales.available'] %}
<tr>
<td>{{ language }}</td>
<td><input type="text" name="{{subdefgroup}}_{{subdefname}}_label[{{ code }}]" value="{{ subdef.get_label(code, false) }}" /></td>
<td></td>
</tr>
{% endfor %}
<tr>
<td>{{ 'Telechargeable' | trans }}</td>
<td><input type="checkbox" name="{{subdefgroup}}_{{subdefname}}_downloadable" {% if subdef.isDownloadable() %}checked="checked"{% endif %} value="1" /></td>
<td></td>
</tr>
<tr>
<td>{{ 'subdef.orderable' | trans }}</td>
<td><input type="checkbox" name="{{subdefgroup}}_{{subdefname}}_orderable" {% if subdef.isOrderable() %}checked="checked"{% endif %} value="1" /></td>
<td></td>
</tr>
<tr>
<td>
{{ 'classe' | trans }}
</td>
<td>
<select name="{{subdefgroup}}_{{subdefname}}_class">
<option>{{ 'classe' | trans }}</option>
<option value="document" {% if subdef.get_class() == "document" %}selected="selected"{% endif %}>{{ 'document' | trans }}</option>
<option value="preview" {% if subdef.get_class() == "preview" %}selected="selected"{% endif %}>{{ 'preview' | trans }}</option>
<option value="thumbnail" {% if subdef.get_class() == "thumbnail" %}selected="selected"{% endif %}>{{ 'tout le monde' | trans }}</option>
</select>
</td>
<td></td>
</tr>
<tr>
<td>
Path
</td>
<td>
<input class="path_testable test_writeable" type="text" value="{{subdef.get_path()}}" name="{{subdefgroup}}_{{subdefname}}_path"/>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'Write Metas' | trans }}
</td>
<td>
<input type="checkbox" value="yes" {% if subdef.isMetadataUpdateRequired() %}checked="checked"{% endif %} name="{{subdefgroup}}_{{subdefname}}_meta"/>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'mediatype' | trans }}
</td>
<td>
<select onchange="select_mediatype('{{subdefgroup}}{{subdefname}}', this);" name="{{subdefgroup}}_{{subdefname}}_mediatype">
<option>{{ 'Choisir' | trans }}</option>
{% for subdefType in subdef.getAvailableSubdefTypes() %}
<option value="{{ subdefType.getType() }}" {% if subdef.getSubdefType.getType() == subdefType.getType() %}selected="selected"{% endif %}>{{ subdefType.getType() }}</option>
{% endfor %}
</select>
</td>
<td></td>
</tr>
</tbody>
</table>
{% for subdefType in subdef.getAvailableSubdefTypes() %}
<div id="box{{subdefgroup}}{{subdefname}}{{ subdefType.getType() }}" class="{{subdefgroup}}{{subdefname}}" {% if subdef.getSubdefType.getType() != subdefType.getType() %}style="display:none;"{% endif %}>
<table cellspacing="0" cellpading="0" border="0" style="width:500px;">
{% for option in subdefType.getOptions() %}
{% set varname = subdefgroup~'_'~subdefname~'_'~subdefType.getType()~'['~ option.getName() ~']' %}
<tr>
<td style="width:120px;">
{{option.getDisplayName()}}
</td>
<td style="width:250px;">
{% set extradata = '' %}
{% if option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_RANGE') %}
<div style="width:250px;" id="slider{{subdefgroup}}{{subdefname}}{{subdefType.getType()}}{{ option.getName() }}"></div>
<script type="text/javascript">
$('#slider{{subdefgroup}}{{subdefname}}{{subdefType.getType()}}{{ option.getName() }}')
.slider({
value:{{ option.getValue }},
min: {{ option.getMinValue() }},
max: {{ option.getMaxValue() }},
{% if option.getStep() is not empty %}step : {{ option.getStep() }},{% endif %}
slide: function( event, ui ) {
$( "#slidervalue{{subdefgroup}}{{subdefname}}{{ subdefType.getType() }}{{ option.getName() }}" ).val( ui.value );
},
create: function (event, ui) {
{# add no-ajax class to slider link to prevent page load in IE7 #}
$("a.ui-slider-handle", event.target).addClass("no-ajax");
}
});
$('#slidervalue{{subdefgroup}}{{subdefname}}{{subdefType.getType()}}{{ option.getName() }}').on('change', function(){
var $this = $(this);
$('#slider{{subdefgroup}}{{subdefname}}{{subdefType.getType()}}{{ option.getName() }}').slider( "option", "value", $this.val() );
})
</script>
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_ENUM') %}
<select name="{{varname}}">
<option value="">{{ 'Choisir' | trans }}</option>
{% for pot_value in option.getAvailableValues() %}
<option value="{{ pot_value }}" {% if pot_value == option.getValue() %}selected="selected"{% endif %}>{{ pot_value }}</option>
{% endfor %}
</select>
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_BOOLEAN') %}
<input name="{{varname}}" type="radio" value="yes" {% if option.getValue() %}checked="checked"{% endif %} /> {{ 'yes' | trans }}
<input name="{{varname}}" type="radio" value="no" {% if option.getValue() is empty %}checked="checked"{% endif %}/> {{ 'no' | trans }}
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_MULTI') %}
{% for pot_value, selected in option.Value(true) %}
<label class="checkbox inline">
<input type="checkbox" name="{{varname}}[]" value="{{ pot_value }}" {% if selected %}checked="checked"{% endif %}/>{{ pot_value }}
</label>
{% endfor %}
{% endif %}
</td>
<td>
{% if option.type == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_RANGE') %}
<input style="width:35px;" value="{{option.value}}" id="slidervalue{{subdefgroup}}{{subdefname}}{{subdefType.getType()}}{{ option.getName() }}" name="{{varname}}" />
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
<form method="post" action="{{ path('admin_subdefs_subdef_update', { 'sbas_id' : databox.get_sbas_id }) }}"
target="_self" class="subdefs">
<div class="tabs">
<ul>
{% for subdefgroup, subdeflist in subdefs %}
<li><a class="no-ajax" href="#{{ subdefgroup }}">{{ subdefgroup }}</a></li>
{% endfor %}
</div>
</ul>
<button type="submit" disabled="disabled"
class="btn btn-primary subviews-submit">{{ 'boutton::valider' | trans }}</button>
{% for subdefgroup, subdeflist in subdefs %}
<div id="{{ subdefgroup }}">
{% for subdefname , subdef in subdeflist %}
<div>
<input type="hidden" name="subdefs[]" value="{{ subdefgroup }}_{{ subdefname }}"/>
<h2 class="subdefName">{{ subdefname }}</h2>
<button class="subdef_deleter btn btn-danger btn-mini">{{ 'boutton::supprimer' | trans }}</button>
<input type="hidden" name="subdef" value="{{ subdefgroup }}_{{ subdefname }}"/>
<br/>
<table class="subdefTab" cellspacing="0" cellpading="0" border="0"
style="display:inline-block;">
<tbody>
<tr>
<td style="width:100px;line-height: 0.9rem;">{{ 'Telechargeable' | trans }}</td>
<td style="width:300px;"><input type="checkbox"
name="{{ subdefgroup }}_{{ subdefname }}_downloadable"
{% if subdef.isDownloadable() %}checked="checked"{% endif %}
value="1"/></td>
<td></td>
</tr>
<tr>
<td>{{ 'subdef.orderable' | trans }}</td>
<td><input type="checkbox" name="{{ subdefgroup }}_{{ subdefname }}_orderable"
{% if subdef.isOrderable() %}checked="checked"{% endif %} value="1"/>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'classe' | trans }}
</td>
<td>
<select name="{{ subdefgroup }}_{{ subdefname }}_class">
<option>{{ 'classe' | trans }}</option>
<option value="document"
{% if subdef.get_class() == "document" %}selected="selected"{% endif %}>{{ 'document' | trans }}</option>
<option value="preview"
{% if subdef.get_class() == "preview" %}selected="selected"{% endif %}>{{ 'preview' | trans }}</option>
<option value="thumbnail"
{% if subdef.get_class() == "thumbnail" %}selected="selected"{% endif %}>{{ 'tout le monde' | trans }}</option>
</select>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'mediatype' | trans }}
</td>
<td>
<select onchange="select_mediatype('{{ subdefgroup }}', '{{ subdefname }}', this);"
name="{{ subdefgroup }}_{{ subdefname }}_mediatype">
<option>{{ 'Choisir' | trans }}</option>
{% for subdefType in subdef.getAvailableSubdefTypes() %}
<option value="{{ subdefType.getType() }}"
{% if subdef.getSubdefType.getType() == subdefType.getType() %}selected="selected"{% endif %}>{{ subdefType.getType() }}</option>
{% endfor %}
</select>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'Presets' | trans }}
</td>
<td>
<select onchange="populate_values('{{ subdefgroup }}', '{{ subdefname }}');"
name="{{ subdefgroup }}_{{ subdefname }}_presets">
<option value="custom">{{ 'Custom' | trans }}</option>
{% set defType = subdef.getSubdefType.getType() %}
{% for key, pressets in config[defType].definitions %}
{% if pressets == null %}
<option disabled="disabled">{{ key }}</option>
{% else %}
<option value="{{ key }}"
{% if subdef.get_preset() == key %}selected="selected"{% endif %}>{{ key }}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td></td>
</tr>
<tr>
<td>
Path
</td>
<td>
<input class="path_testable test_writeable" type="text"
value="{{ subdef.get_path() }}"
name="{{ subdefgroup }}_{{ subdefname }}_path"/>
</td>
<td></td>
</tr>
<tr>
<td>
{{ 'Write Metas' | trans }}
</td>
<td>
<input type="checkbox" value="yes"
{% if subdef.isMetadataUpdateRequired() %}checked="checked"{% endif %}
name="{{ subdefgroup }}_{{ subdefname }}_meta"/>
</td>
<td></td>
</tr>
</tbody>
</table>
<table cellspacing="0" class="langTab" cellpading="0" border="0">
<tr>
<td colspan="2"><h3>Labels</h3></td>
</tr>
{% for code, language in app['locales.available'] %}
<tr>
<td style="width:100px;">{{ language }}</td>
<td style="width:300px;"><input type="text"
name="{{ subdefgroup }}_{{ subdefname }}_label[{{ code }}]"
value="{{ subdef.get_label(code, false) }}"/>
</td>
</tr>
{% endfor %}
</table>
{% for subdefType in subdef.getAvailableSubdefTypes() %}
<span class="toggle"
data-toggle="#box{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}"
{% if subdef.getSubdefType.getType() != subdefType.getType() %}style="display:none;"{% endif %}>
{{ 'Advanced settings' | trans }}
</span>
<div id="box{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}"
class="{{ subdefgroup }}{{ subdefname }}"
{% if subdef.getSubdefType.getType() != subdefType.getType() %}style="display:none;"{% endif %}>
<table cellspacing="0" cellpading="0" border="0" style="width:500px;">
{% for option in subdefType.getOptions() %}
{% set varname = subdefgroup~'_'~subdefname~'_'~subdefType.getType()~'['~ option.getName() ~']' %}
<tr>
<td style="width:120px;">
{{ option.getDisplayName() }}
</td>
<td style="width:250px;">
{% set extradata = '' %}
{% if option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_RANGE') %}
<div style="width:250px;"
id="slider{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}"></div>
<script type="text/javascript">
$('#slider{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}')
.slider({
value:{{ option.getValue }},
min: {{ option.getMinValue() }},
max: {{ option.getMaxValue() }},
{% if option.getStep() is not empty %}step: {{ option.getStep() }},{% endif %}
slide: function (event, ui) {
$("#slidervalue{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}").val(ui.value);
jQuery('[name={{ subdefgroup }}_{{ subdefname }}_presets]').val("custom");
if (jQuery(".subviews-submit").attr("disabled"))
activeSubmit();
},
create: function (event, ui) {
{# add no-ajax class to slider link to prevent page load in IE7 #}
$("a.ui-slider-handle", event.target).addClass("no-ajax");
}
});
$('#slidervalue{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}').on('change', function () {
var $this = $(this);
$('#slider{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}').slider("option", "value", $this.val());
})
</script>
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_ENUM') %}
<select name="{{ varname }}">
<option value="">{{ 'Choisir' | trans }}</option>
{% for pot_value in option.getAvailableValues() %}
<option value="{{ pot_value }}"
{% if pot_value == option.getValue() %}selected="selected"{% endif %}>{{ pot_value }}</option>
{% endfor %}
</select>
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_BOOLEAN') %}
<input name="{{ varname }}" type="radio" value="yes"
{% if option.getValue() %}checked="checked"{% endif %} /> {{ 'yes' | trans }}
<input name="{{ varname }}" type="radio" value="no"
{% if option.getValue() is empty %}checked="checked"{% endif %}/> {{ 'no' | trans }}
{% elseif option.getType() == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_MULTI') %}
{% for pot_value, selected in option.Value(true) %}
<label class="checkbox inline">
<input type="checkbox" name="{{ varname }}[]"
value="{{ pot_value }}"
{% if selected %}checked="checked"{% endif %}/>{{ pot_value }}
</label>
{% endfor %}
{% endif %}
</td>
<td>
{% if option.type == constant('\\Alchemy\\Phrasea\\Media\\Subdef\\OptionType\\OptionType::TYPE_RANGE') %}
<input style="width:35px;" value="{{ option.value }}"
id="slidervalue{{ subdefgroup }}{{ subdefname }}{{ subdefType.getType() }}{{ option.getName() }}"
name="{{ varname }}"/>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
</div>
<script>
{% set defType = subdef.getSubdefType.getType() %}
jQuery('#box{{ subdefgroup }}{{ subdefname }}{{ defType }} input, #box{{ subdefgroup }}{{ subdefname }}{{ defType }} select').change(function () {
jQuery('[name={{ subdefgroup }}_{{ subdefname }}_presets]').val("custom");
});
</script>
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
<input type="hidden" name="delete_subdef" id="delete_subdef" value=""/>
<input type="hidden" name="add_subdef[group]" value=""/>
<input type="hidden" name="add_subdef[name]" value=""/>
<input type="hidden" name="add_subdef[class]" value=""/>
<div class="form-actions">
<button type="submit" class="btn btn-primary">{{ 'boutton::valider' | trans }}</button>
</div>
</form>
<input type="hidden" name="delete_subdef" id="delete_subdef" value=""/>
<input type="hidden" name="add_subdef[group]" value=""/>
<input type="hidden" name="add_subdef[name]" value=""/>
<input type="hidden" name="add_subdef[mediaType]" value=""/>
<input type="hidden" name="add_subdef[class]" value=""/>
<input type="hidden" name="add_subdef[presets]" value=""/>
</form>
<div style="display:none;">
<div id="image_template">
<div style="display:none;">
<div id="image_template">
</div>
</div>
</div>
{% endblock %}

View File

@@ -68,11 +68,10 @@
<tr>
<td class="menu">
<div class="btn-group dropdown">
<a class="btn btn-mini dropdown-toggle disabled" data-toggle="dropdown" href="#">
<a class="btn btn-mini dropdown-toggle" data-toggle="dropdown" href="#">
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% if app['phraseanet.configuration']['main']['task-manager']['enabled'] %}
<li>
<a href="{{ path('admin_tasks_task_show', {"task" : task["id"] }) }}">
{{ 'Edit' | trans }}
@@ -93,7 +92,6 @@
{{ 'Delete' | trans }}
</a>
</li>
{% endif %}
<li>
<a href="{{ path('admin_tasks_task_log', {"task" : task["id"] }) }}">
{{ 'Logs' | trans }}

View File

@@ -25,6 +25,8 @@
<script type="text/javascript">
google.charts.load('42', {packages: ['corechart']});
</script>
<script type="text/javascript"
src="/assets/vendors/underscore/underscore{% if not app.debug %}.min{% endif %}.js"></script>
{% block rss %}{% endblock %}
{% block javascript %}{% endblock %}
</head>

View File

@@ -1,5 +1,6 @@
<div id="mainMenu" class="">
<div class="PNB" style="right:auto;overflow:hidden;">
{% set configuration = app['conf'].get(['registry', 'custom-links']) %}
<div class="PNB menu-bar" style="right:auto;overflow:hidden;">
<ol>
<li>
<span class="title">
@@ -137,7 +138,8 @@
<a target="_blank" href="https://docs.phraseanet.com/4.0/">
<span>
{{ 'phraseanet:: aide' | trans }}
<span style="display:inline-block;cursor:pointer;padding:0;border:none;" id="help-trigger"> <i class="icon-caret-down"></i></span>
<span style="display:inline-block;cursor:pointer;padding:0;border:none;padding-right:4px;padding-left:4px;"
id="help-trigger"> <i class="icon-caret-down"></i></span>
</span>
</a>
<table cellspacing="0" cellpadding="0" style="display:none;" class="contextMenu helpcontextmenu">
@@ -153,7 +155,7 @@
</div>
{% endif %}
<div title="" class="context-menu-item menu3-custom-item">
<div style="" class="context-menu-item-inner infoDialog" infos="<div><span style='font-size:18px;'>PHRASEANET</span> {{ app['phraseanet.version'].getName() }} (V{{ app['phraseanet.version'].getNumber() }})</div><div></div><br/><div><a href='http://www.gnu.org/licenses/gpl.html' target='_blank'><img src='http://www.gnu.org/graphics/gplv3-88x31.png' style='vertical-align:middle;'/><span>License GNU GPL v3</span></a></div><br/><div><a href='http://www.phraseanet.com/' target='_blank'> &copy; Copyright Alchemy 2005-{{ "now"|date("Y") }}</a></div>">{{ 'phraseanet:: a propos' | trans }}</div>
<div style="" class="context-menu-item-inner infoDialog" infos="<div><span style='font-size:18px;'>PHRASEANET</span> {{ app['phraseanet.version'].getName() }} (V{{ app['phraseanet.version'].getNumber() }})</div><div></div><br/><div><a href='http://www.gnu.org/licenses/gpl.html' target='_blank'><img src='http://www.gnu.org/graphics/gplv3-88x31.png' style='vertical-align:middle;'/><span>License GNU GPL v3</span></a></div><br/><div><a href='http://www.phraseanet.com/' target='_blank'> &copy; Copyright Alchemy 2005-{{ "now"|date("Y") }}</a><p style='margin-top: 10px' ><a href='../../gitlog.txt' target='_blank'>gitlog</a></p></div>">{{ 'phraseanet:: a propos' | trans }}</div>
</div>
</div>
</td>
@@ -180,3 +182,50 @@
{% include 'prod/notifications.html.twig' %}
</div>
{% endif %}
<script type="text/javascript">
$(document).ready(function () {
// var key = 'help';
var configurationSettingLinks = {{ configuration|json_encode|raw }};
//seperate array based on location of link
var seperatedLinksByLocation = _.groupBy(configurationSettingLinks, "linkLocation");
for (key in seperatedLinksByLocation) {
if (key === 'navigation-bar') {
var sortedCustomLinks = _.sortBy(seperatedLinksByLocation[key], 'linkOrder');
_.each(sortedCustomLinks, function (linksData) {
if (linksData.linkLanguage == 'all' || linksData.linkLanguage === '{{ app['locale'] }}') {
var styleAttr = "";
styleAttr += linksData.linkColor ? "color: " + linksData.linkColor + ";" : "";
styleAttr += linksData.linkBold == true ? "font-weight: bold;" : "";
var spanElement = $('<span />').attr('style', styleAttr).html(linksData.linkName);
var links = '<li><a target="_blank" href="' + linksData.linkUrl + '">' +
spanElement.prop("outerHTML") + '</a></li>';
$('#mainMenu .menu-bar ol').append(links);
}
});
} else if (key === 'help-menu') {
var sortedCustomLinks = _.sortBy(seperatedLinksByLocation[key], 'linkOrder');
_.each(sortedCustomLinks, function (linksData) {
if (linksData.linkLanguage == 'all' || linksData.linkLanguage === '{{ app['locale'] }}') {
var styleAttr = "";
styleAttr += linksData.linkColor ? "color: " + linksData.linkColor + ";" : "";
styleAttr += linksData.linkBold == true ? "font-weight: bold;" : "";
var spanElement = $('<span />').attr('style', styleAttr).html(linksData.linkName);
var links = '<div title="" class="context-menu-item menu3-custom-item">' +
'<div style="" class="context-menu-item-inner">' +
'<a target="_blank" href="' + linksData.linkUrl + '">' +
spanElement.prop("outerHTML") + '</a></div></div>';
$('.helpcontextmenu .context-menu-theme-vista').append(links);
}
});
}
}
});
</script>

View File

@@ -7,6 +7,8 @@
<option value="">{{ 'Choisir' | trans }}</option>
<option value="default">{{ 'Re-initialiser' | trans }}</option>
<option value="title">{{ 'Titre' | trans }}</option>
<option value="date_created">{{ 'Date de création' | trans }}</option>
<option value="date_updated">{{ 'Date de modification' | trans }}</option>
</select>
<button type="button" class="autoorder btn btn-inverse">{{ 'Re-ordonner' | trans }}</button>
<button type="button" class="reverseorder btn btn-inverse">{{ 'Inverser' | trans }}</button>
@@ -22,13 +24,17 @@
{% for element in basket.getElements() %}
<div id="ORDER_{{ element.getId() }}" class="CHIM diapo" style="height:130px;overflow:hidden;">
<div class="title" title="{{ element.getRecord(app).get_title() }}" style="position:relative;z-index:1200;height:30px;overflow:hidden;text-align:center;text-overflow: ellipsis; line-height: 15px;">
{{ element.getRecord(app).get_title() }} {{ element.getRecord(app).get_title() }}{{ element.getRecord(app).get_title() }}
{{ element.getRecord(app).get_title() }}
</div>
{{ thumbnail.format(element.getRecord(app).get_thumbnail(), 80, 80, '', false, false) }}
<form style="display:none;">
<input type="hidden" name="id" value="{{ element.getId() }}"/>
<input type="hidden" name="title" value="{{ element.getRecord(app).get_title() }}"/>
<input type="hidden" name="default" value="{{ element.getOrd() }}"/>
<input type="hidden" name="date_created"
value="{{ element.getRecord(app).getCreated() | date('Y-m-dTH:i:s') }}"/>
<input type="hidden" name="date_updated"
value="{{ element.getRecord(app).getUpdated() | date('Y-m-dTH:i:s') }}"/>
</form>
</div>
{% endfor %}

View File

@@ -1,58 +1,136 @@
{% if not isAvailable %}
<p>{{ 'No permalink available.' | trans }}</p>
{% else %}
{% if preview.permalinkUrl is not empty %}
{% if subdefList is not empty %}
{% set defKey = defaultKey %}
<div id="share">
<div id="tweet" class="well-large">
<p>
<a href="http://www.twitter.com/home/?status={{ preview.permaviewUrl }}" target="_blank">
<img src="/assets/common/images/icons/twitter.png" title="share this on twitter" style="width:25px;vertical-align:middle;padding:0 5px;"/>
{% trans %}Send to Twitter{% endtrans %}
</a>
</p>
<p>
<a href="http://www.facebook.com/sharer.php?u={{ preview.permaviewUrl }}" target="_blank">
<img src="/assets/common/images/icons/facebook.png" title="share on facebook" style="width:25px;vertical-align:middle;padding:0 5px;"/>
{% trans %}Send to Facebook{% endtrans %}
</a>
</p>
<form action="#">
<div class="form-group clearfix">
<label>{% trans %}Resource URL{% endtrans %}</label>
<input class="input-block-level" readonly="readonly" type="text" value="{{ preview.permalinkUrl }}"
id="permalinkUrl"/>
<p class="pull-right">
<a href="{{ preview.permalinkUrl }}" target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="permalinkUrlCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
<div class="form-group clearfix">
<label>{% trans %}Detailed view URL{% endtrans %}</label>
<input class="input-block-level" readonly="readonly" type="text" value="{{ preview.permaviewUrl }}" id="permaviewUrl"/>
<p class="pull-right">
<a href="{{ preview.permaviewUrl }}" target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="permaviewUrlCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
<div class="form-group clearfix">
{#{% if type == 'image' %}#}
<label>{% trans %}Embed code{% endtrans %}</label>
{% spaceless %}
<textarea class="input-block-level" rows="4" readonly="true" id="embedRecordUrl">
<iframe width="{{ preview.width }}" height="{{ preview.height }}" src="{{ preview.embedUrl }}" frameborder="0" allowfullscreen></iframe>
</textarea>
{% endspaceless %}
<p class="pull-right">
<a href="{{ preview.embedUrl }}" target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="embedCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
{#{% endif %}#}
</form>
<div id="tweet" class="well-large">
<p>
<a href="#" id="advance-share">{{ 'share::share-record: advance' | trans }}</a>
<span id="shared-def">
{{ 'share::share-record: select-shared-def' | trans }}
<select name="resource_type" id="resource_type_sel" class="input-small">
{% for key,value in subdefList %}
<option value={{ key }} {% if key == defKey %}selected{% endif %}>{{ value.label }}</option>
{% endfor %}
</select>
</span>
</p>
<p>
<a id="twitter-link" href="http://www.twitter.com/home/?status={{ subdefList[defKey].permaviewUrl }}"
target="_blank">
<img src="/assets/common/images/icons/twitter.png" title="share this on twitter"
style="width:25px;vertical-align:middle;padding:0 5px;"/>
{% trans %}Send to Twitter{% endtrans %}
</a>
</p>
<p>
<a id="facebook-link" href="http://www.facebook.com/sharer.php?u={{ subdefList[defKey].permaviewUrl }}"
target="_blank">
<img src="/assets/common/images/icons/facebook.png" title="share on facebook"
style="width:25px;vertical-align:middle;padding:0 5px;"/>
{% trans %}Send to Facebook{% endtrans %}
</a>
</p>
<form action="#">
<div class="form-group clearfix">
<label style="display:inline-block;">{% trans %}Resource URL{% endtrans %}</label>
<input class="input-block-level" readonly="readonly" type="text"
value="{{ subdefList[defKey].permalinkUrl }}"
id="permalinkUrl"/>
<p class="pull-right">
<a id="permalinkUrl-link" href="{{ subdefList[defKey].permalinkUrl }}"
target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="permalinkUrlCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
<div class="form-group clearfix">
<label>{% trans %}Detailed view URL{% endtrans %}</label>
<input class="input-block-level" readonly="readonly" type="text"
value="{{ subdefList[defKey].permaviewUrl }}" id="permaviewUrl"/>
<p class="pull-right">
<a id="permaviewUrl-link" href="{{ subdefList[defKey].permaviewUrl }}"
target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="permaviewUrlCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
<div class="form-group clearfix">
{#{% if type == 'image' %}#}
<label>{% trans %}Embed code{% endtrans %}</label>
{% spaceless %}
<textarea class="input-block-level" rows="4" readonly="true" id="embedRecordUrl">
<iframe width="{{ subdefList[defKey].width }}" height="{{ subdefList[defKey].height }}"
src="{{ subdefList[defKey].embedUrl }}" frameborder="0"
allowfullscreen></iframe>
</textarea>
{% endspaceless %}
<p class="pull-right">
<a id="embedRecordUrl-link" href="{{ subdefList[defKey].embedUrl }}"
target="_blank">{{ 'previewLinkLabel' | trans }}</a> &nbsp;&nbsp;
<a href="#" class="" id="embedCopy">{{ 'copyClipboardLabel' | trans }}</a>
</p>
</div>
{#{% endif %}#}
</form>
</div>
<script language="javascript">
// var subdefListObj = JSON.parse(subdefList); // to convert json into a javascript object
$(document).ready(function () {
var subdefList = JSON.parse('{{ subdefList | json_encode | escape('js') }}');
$('#resource_type_sel').on('change', function () {
assignPermalinks(this.value);
});
$('input.ui-state-default').hover(
function () {
$(this).addClass('ui-state-hover');
},
function () {
$(this).removeClass('ui-state-hover');
}
);
$('#permalinkUrlCopy').on('click', function (event) {
event.preventDefault();
return copyElContentClipboard('permalinkUrl');
});
$('#permaviewUrlCopy').on('click', function (event) {
event.preventDefault();
return copyElContentClipboard('permaviewUrl');
});
$('#embedCopy').on('click', function (event) {
event.preventDefault();
return copyElContentClipboard('embedRecordUrl');
});
$('#advance-share').on('click', function () {
$('#shared-def').show();
});
var copyElContentClipboard = function (elId) {
var copyEl = document.getElementById(elId);
copyEl.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('unable to copy');
}
}
var assignPermalinks = function (resourceType) {
$('#twitter-link').attr('href', 'http://www.twitter.com/home/?status=' + subdefList[resourceType].permaviewUrl);
$('#facebook-link').attr('href', 'http://www.facebook.com/sharer.php?u=' + subdefList[resourceType].permaviewUrl);
$('#permalinkUrl').val(subdefList[resourceType].permalinkUrl);
$('#permalinkUrl-link').attr('href', subdefList[resourceType].permalinkUrl);
$('#permaviewUrl').val(subdefList[resourceType].permaviewUrl);
$('#permaviewUrl-link').attr('href', subdefList[resourceType].permaviewUrl);
var html = '<iframe width="' + subdefList[resourceType].width
+ '" height="' + subdefList[resourceType].height + '" src="' + subdefList[resourceType].embedUrl + '" frameborder="0" allowfullscreen></iframe>';
$('#embedRecordUrl').val(html);
$('#embedRecordUrl-link').attr('href', subdefList[resourceType].embedUrl);
}
});
</script>
{% else %}
<div>{{ 'No URL available' | trans }}</div>
{% endif %}

View File

@@ -1,34 +1,39 @@
{% import 'common/thumbnail.html.twig' as thumbnail %}
<div id="reorder_options" class="PNB" style="height:30px;bottom:auto;">
<form id="reorder_options" class="form-inline" style="display:inline-block;">
<div id="reorder_options" class="row-fluid" style="height:30px;bottom:auto;">
<form id="reorder_options" class="form-inline span10">
<span>{{ 'Reordonner automatiquement' | trans }}</span>
<select id="auto_order">
<option value="">{{ 'Choisir' | trans }}</option>
<option value="default">{{ 'Re-initialiser' | trans }}</option>
<option value="title">{{ 'Titre' | trans }}</option>
<option value="date_created">{{ 'Date de création' | trans }}</option>
<option value="date_updated">{{ 'Date de modification' | trans }}</option>
</select>
<button type="button" class="autoorder">{{ 'Re-ordonner' | trans }}</button>
<button type="button" class="reverseorder">{{ 'Inverser' | trans }}</button>
<button type="button" class="autoorder btn btn-inverse">{{ 'Re-ordonner' | trans }}</button>
<button type="button" class="reverseorder btn btn-inverse">{{ 'Inverser' | trans }}</button>
</form>
<form style="display:inline-block;" class="form-inline" name="reorder" method="POST" action="{{ path('prod_stories_story_reorder', { 'sbas_id' : story.get_sbas_id(), 'record_id' : story.get_record_id() }) }}">
<form class="form-inline span2" name="reorder" method="POST"
action="{{ path('prod_stories_story_reorder', { 'sbas_id' : story.get_sbas_id(), 'record_id' : story.get_record_id() }) }}">
{% for element in story.get_children() %}
<input type="hidden" name="element[{{ element.get_record_id() }}]" value="{{ element.getNumber() }}"/>
{% endfor %}
<button>{{ 'boutton::valider' | trans }}</button>
<input type="submit" class="btn btn-inverse" value="{{ 'boutton::valider' | trans }}"/>
</form>
</div>
<div style="top:45px;overflow:auto;" id="reorder_box" class="PNB">
<div style="top:45px;overflow:auto;" id="reorder_box" class="row-fluid">
<div class="elements">
{% for element in story.get_children() %}
<div id="ORDER_{{ element.get_record_id() }}" class="CHIM diapo" style="height:130px;overflow:hidden;">
<div class="title" title="{{ element.get_title() }}" style="position:relative;z-index:1200;height:30px;overflow:hidden;text-align:center;text-overflow: ellipsis; line-height: 15px;">
{{ element.get_title() }} {{ element.get_title() }} {{ element.get_title() }}
{{ element.get_title() }}
</div>
{{ thumbnail.format(element.get_thumbnail(), 80, 80, '', false, false) }}
<form style="display:none;">
<input type="hidden" name="id" value="{{ element.get_record_id() }}"/>
<input type="hidden" name="title" value="{{ element.get_title() }}"/>
<input type="hidden" name="default" value="{{ element.getNumber() }}"/>
<input type="hidden" name="date_created" value="{{ element.getCreated() | date('Y-m-dTH:i:s') }}"/>
<input type="hidden" name="date_updated" value="{{ element.getUpdated() | date('Y-m-dTH:i:s') }}"/>
</form>
</div>
{% endfor %}

View File

@@ -41,9 +41,9 @@
</button>
{% endif %}
{% if app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::BAS_CHUPUB')) %}
<button class="ui-corner-all TOOL_bridge_btn basket_window" title="{{ 'action : bridge' | trans }}" data-href="{{ path("prod_bridge_manager") }}">
<img src="/assets/common/images/icons/door.png"/>
</button>
{#<button class="ui-corner-all TOOL_bridge_btn basket_window" title="{{ 'action : bridge' | trans }}" data-href="{{ path("prod_bridge_manager") }}">#}
{#<img src="/assets/common/images/icons/door.png"/>#}
{#</button>#}
<button class="ui-corner-all TOOL_publish_btn basket_window" title="{{ 'action : publier' | trans }}" data-selection-source="basket">
<img src="/assets/common/images/icons/rss16.png"/>
</button>

View File

@@ -41,9 +41,9 @@
</button>
{% endif %}
{% if app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::BAS_CHUPUB')) %}
<button class="ui-corner-all TOOL_bridge_btn story_window" title="{{ 'action : bridge' | trans }}" data-href="{{ path("prod_bridge_manager") }}" data-selection-source="story">
<img src="/assets/common/images/icons/door.png"/>
</button>
{#<button class="ui-corner-all TOOL_bridge_btn story_window" title="{{ 'action : bridge' | trans }}" data-href="{{ path("prod_bridge_manager") }}" data-selection-source="story">#}
{#<img src="/assets/common/images/icons/door.png"/>#}
{#</button>#}
<button class="ui-corner-all TOOL_publish_btn story_window" title="{{ 'action : publier' | trans }}" data-selection-source="story">
<img src="/assets/common/images/icons/rss16.png"/>
</button>

View File

@@ -200,39 +200,53 @@
<li class="context-menu-item">
<div class="context-menu-item-inner">
<a title="{{ 'action:: nouveau panier' | trans }}" class="basket-create-action" href="#">
<img style="cursor:pointer;" src="/assets/common/images/icons/mtadd_0.gif" title="{{ 'action:: nouveau panier' | trans }}" />
{{ 'action:: nouveau panier' | trans }}
<img style="cursor:pointer;" src="/assets/common/images/icons/new_basket.png"
title="{{ 'action:: nouveau panier' | trans }}"/>
<span>{{ 'action:: nouveau panier' | trans }}</span>
</a>
</div>
<div class="context-menu-item-inner">
<a title="{{ 'Browse Baskets' | trans }}" class="basket-browse-action" href="#">
{{ 'Browse Baskets' | trans }}
<img style="cursor:pointer;" src="/assets/common/images/icons/browse_basket.png"
title="{{ 'Browse Baskets' | trans }}"/>
<span>{{ 'Browse Baskets' | trans }}</span>
</a>
</div>
{% if app['conf'].get(['registry', 'modules', 'stories']) and app.getAclForUser(app.getAuthenticatedUser()).has_right(constant('\\ACL::CANADDRECORD')) %}
<div class="context-menu-item-inner">
<div class="context-menu-item-inner" style="line-height: 34px;">
<div class="divider"></div>
<a title="{{ 'action:: nouveau reportage' | trans }}" class="story-create-action" href="#">
<img style="cursor:pointer;" src="/assets/common/images/icons/mtadd_0.gif" title="{{ 'action:: nouveau reportage' | trans }}" />
{{ 'action:: nouveau reportage' | trans }}
<img style="cursor:pointer;" src="/assets/common/images/icons/new_report.png"
title="{{ 'action:: nouveau reportage' | trans }}"/>
<span>{{ 'action:: nouveau reportage' | trans }}</span>
</a>
<div class="divider"></div>
</div>
{% endif %}
</li>
<li class="context-menu-item">
<div class="context-menu-item-inner basket-filter-action" data-sort="date">
<img style="cursor:pointer;" src="/assets/common/images/icons/cal.png" title="{{ 'phraseanet:: tri par date' | trans }}" />
{{ 'phraseanet:: tri par date' | trans }}
<a title="{{ 'phraseanet:: tri par date' | trans }} " href="#">
<img style="cursor:pointer;" src="/assets/common/images/icons/sort_date.png"
title="{{ 'phraseanet:: tri par date' | trans }}"/>
<span>{{ 'phraseanet:: tri par date' | trans }}</span>
</a>
</div>
</li>
<li class="context-menu-item">
<div class="context-menu-item-inner basket-filter-action" data-sort="name">
<img style="cursor:pointer;" src="/assets/common/images/icons/alpha.png" title="{{ 'phraseanet:: tri par nom' | trans }}" />
{{ 'phraseanet:: tri par nom' | trans }}
<a title="{{ 'phraseanet:: tri par nom' | trans }} " href="#">
<img style="cursor:pointer;" src="/assets/common/images/icons/sort_alpha.png"
title="{{ 'phraseanet:: tri par nom' | trans }}"/>
<span>{{ 'phraseanet:: tri par nom' | trans }}</span>
</a>
</div>
</li>
<li class="context-menu-item">
<div class="context-menu-item-inner basket-preferences-action">
{{ 'Preferences' | trans }}
<a title="{{ 'Preferences' | trans }} " href="#">
<span>{{ 'Preferences' | trans }}</span>
</a>
</div>
</li>
</ul>
@@ -288,6 +302,13 @@
<table style="width:100%; table-layout:fixed;">
<tr>
<td style="width:50%; vertical-align:top;">
{% set useTruncation = app['settings'].getUserSetting(app.getAuthenticatedUser(), 'use_truncation') %}
<label class="checkbox inline" for="ADVSRCH_USE_TRUNCATION">
<input id="ADVSRCH_USE_TRUNCATION" type="checkbox"
class="checkbox preferences-options-use-truncation" name="truncation"
{% if useTruncation == '1' or useTruncation == NULL %}checked="checked"{% endif %}>
{{ 'index:advanced-preferences:: use truncation' | trans }}
</label>
<div id="ADVSRCH_SBAS_ZONE" class="sbasglob">
<div class="btn-toolbar">
<input class="btn btn-inverse toggle-database" type="button"
@@ -664,6 +685,22 @@
</form>
</div>
</div>
<div class="box">
<h1>{{ 'Collection order' | trans }}</h1>
<form class="form-inline">
{% set order_collection_by = app['settings'].getUserSetting(app.getAuthenticatedUser(), 'order_collection_by') %}
<label class="select" for="orderByName">
<select class="preferences-options-collection-order" name="orderByName">
<option {% if order_collection_by == constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_BY_ADMIN') %} selected="selected" {% endif %}
value="{{ constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_BY_ADMIN') }}">{{ 'Defined by admin' | trans }}</option>
<option {% if order_collection_by == constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_ALPHA_ASC') %} selected="selected" {% endif %}
value="{{ constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_ALPHA_ASC') }}">{{ 'Alphabetic asc' | trans }}</option>
<option {% if order_collection_by == constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_ALPHA_DESC') %} selected="selected" {% endif %}
value="{{ constant('Alchemy\\Phrasea\\Core\\Configuration\\DisplaySettingService::ORDER_ALPHA_DESC') }}">{{ 'Alphabetic desc' | trans }}</option>
</select>
</label>
</form>
</div>
<div class="box">
<h1>{{ 'index::advance_search: facet' | trans }}</h1>
{% set facetFilter = app['settings'].getUserSetting(app.getAuthenticatedUser(), 'facet') %}

View File

@@ -139,13 +139,13 @@
{{ 'Feedback' | trans }}
</a>
</li>
<li class="divider"></li>
<li>
<a class="TOOL_bridge_btn results_window" href="{{ path("prod_bridge_manager") }}" data-selection-source="search-result">
<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/>
{{ 'action : bridge' | trans }}
</a>
</li>
{#<li class="divider"></li>#}
{#<li>#}
{#<a class="TOOL_bridge_btn results_window" href="{{ path("prod_bridge_manager") }}" data-selection-source="search-result">#}
{#<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/>#}
{#{{ 'action : bridge' | trans }}#}
{#</a>#}
{#</li>#}
<li class="divider"></li>
<li>
<a class="TOOL_publish_btn results_window" data-selection-source="search-result">
@@ -211,36 +211,37 @@
{% elseif acl.has_right(constant('\\ACL::BAS_CHUPUB')) %}
<span class="dropdownButton">
<div class="btn-group">
<button class="TOOL_pushdoc_btn default_action results_window btn btn-inverse" data-selection-source="search-result">
<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/> {{ 'action : bridge' | trans }}
{#<button class="TOOL_pushdoc_btn default_action results_window btn btn-inverse" data-selection-source="search-result">#}
{#<img src="/assets/common/images/icons/door.png" height="16" width="16" class="btn-image"/> {{ 'action : bridge' | trans }}#}
{#</button>#}
<button class="TOOL_publish_btn results_window btn btn-inverse">
<img src="/assets/common/images/icons/rss16.png" height="16" width="16" class="btn-image"/>
{{ 'action : publier' | trans }}
</button>
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
class="caret"></span></button>
<ul class="submenu dropdown-menu">
<li>
<a class="TOOL_publish_btn results_window" data-selection-source="search-result">
<img src="/assets/common/images/icons/rss16.png" height="16" width="16" class="btn-image"/>
{{ 'action : publier' | trans }}
</a>
</li>
{% if plugins.actionbar is not empty %}
{% for plugin in plugins.actionbar %}
<li class="divider"></li>
{% for key, action in plugin.getActionBar().push|default([]) %}
{% if plugins.actionbar is not empty %}
<button class="trigger btn btn-inverse dropdown-toggle" data-toggle="dropdown"><span
class="caret"></span></button>
<ul class="submenu dropdown-menu">
{% for plugin in plugins.actionbar %}
<li class="divider"></li>
{% for key, action in plugin.getActionBar().push|default([]) %}
<li>
<a class="results_window {{ action.classes|default('') }}" data-selection-source="search-result">
{% if action.icon %}
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}" height="16" width="16" class="btn-image"/>
{% endif %}
<a class="results_window {{ action.classes|default('') }}">
{% if action.icon %}
<img src="{{ plugin_asset(plugin.PluginName, action.icon) }}"
height="16" width="16" class="btn-image"/>
{% endif %}
{% set label = action.label %}
{% trans from plugin.PluginLocale %}label{% endtrans %}
</a>
</li>
{% set label = action.label %}
{% trans from plugin.PluginLocale %}label{% endtrans %}
</a>
</li>
{% endfor %}
{% endfor %}
{% endif %}
</ul>
{% endfor %}
</ul>
{% endif %}
</div>
</span>
{% elseif plugins.actionbar is not empty %}

View File

@@ -33,20 +33,21 @@
({% trans with {'%maxFileSizeReadable%' : maxFileSizeReadable} %}maximum : %maxFileSizeReadable%{% endtrans %})
</span>
</td>
<td class='uploader-icon'>
<img src='/assets/common/images/icons/logo-flash.png' width="32px" heigh="32px" title="{{ 'You are using the Flash uploader.' | trans }}"/>
</td>
<td class='uploader-info'>
<p>
{{ 'You are using the Flash uploader.' | trans }}
{% if not app['browser'].supportFileAPI() %}
{{ 'This version does not allow you to access all the features offered by the HTML5 uploader' | trans }}
{% endif %}
</p>
{% if app['browser'].supportFileAPI() %}
<a id="UPLOAD_HTML5_LINK" href="{{ path('upload_html5_form') }}" class="dialog full-dialog">{{ 'Use the HTML5 uploader' | trans }}</a>
{% endif %}
</td>
{#<td class='uploader-icon'>#}
{#<img src='/assets/common/images/icons/logo-flash.png' width="32px" heigh="32px" title="{{ 'You are using the Flash uploader.' | trans }}"/>#}
{#</td>#}
{#<td class='uploader-info'>#}
{#<p>#}
{#{{ 'You are using the Flash uploader.' | trans }}#}
{#{% if not app['browser'].supportFileAPI() %}#}
{#{{ 'This version does not allow you to access all the features offered by the HTML5 uploader' | trans }}#}
{#{% endif %}#}
{#</p>#}
{#{% if app['browser'].supportFileAPI() %}#}
<a style="display: none" id="UPLOAD_HTML5_LINK" href="{{ path('upload_html5_form') }}"
class="dialog full-dialog">{{ 'Use the HTML5 uploader' | trans }}</a>
{#{% endif %}#}
{#</td>#}
</tr>
</table>
{# settings box #}
@@ -54,11 +55,14 @@
<h5>{{ 'upload:: Destination (collection) :' | trans }} :</h5>
{# collections list #}
{% if collections|length > 0 %}
<select name="base_id" class="span3" style="margin-left: 10px;">
{% set last_used_collection = app['settings'].getUserSetting(app.getAuthenticatedUser(), 'upload_last_used_collection') %}
<select name="base_id" class="span3 upload-options-collection" style="margin-left: 10px;">
{% for sbasId, availableCollections in collections %}
<optgroup label="{{ availableCollections['databox'].get_label(app['locale']) }}" class="select-label">
{% for collection in availableCollections['databox_collections'] %}
<option value="{{ collection.get_base_id() }}" class="select-row">{{ collection.get_label(app['locale']) }}</option>
<option {% if last_used_collection == collection.get_base_id() %} selected="selected" {% endif %}
value="{{ collection.get_base_id() }}"
class="select-row">{{ collection.get_label(app['locale']) }}</option>
{% endfor %}
</optgroup>
{% endfor %}
@@ -66,7 +70,8 @@
{# collections status #}
{% for availableCollections in collections %}
{% for collection in availableCollections['databox_collections'] %}
<div id="status-{{ collection.get_base_id() }}" class='collection-status' style='{{ loop.parent.loop.first and loop.first ? "display:block" :"display:none" }}'>
<div id="status-{{ collection.get_base_id() }}" class='collection-status'
style='{{ last_used_collection == collection.get_base_id() ? "display:block" :"display:none" }}'>
<h5>{{ 'upload:: Status :' | trans }} :</h5>
<table class="status-tab">
<tbody>
@@ -121,6 +126,12 @@
</div>
</form>
<div>
<select name="upload_type" id="upload_type" class="input-large" style="width: 200px; float:right">
<option value="html">{{ 'Use the HTML5 uploader' | trans }}</option>
<option value="flash" selected>{{ 'Use the Flash uploader' | trans }}</option>
</select>
</div>
</div>
</div>
</div>

View File

@@ -36,18 +36,19 @@
({% trans with {'%maxFileSizeReadable%' : maxFileSizeReadable} %}maximum : %maxFileSizeReadable%{% endtrans %})
</span>
</td>
<td class='uploader-icon'>
<img src='/assets/common/images/icons/html5-logo.png' width="32px" heigh="32px" title="{{ 'You are using the HTML5 uploader.' | trans }}"/>
</td>
<td class="uploader-infmaxFileSizeo">
<p>
{{ 'You are using the HTML5 uploader.' | trans }}
{% if not app['browser'].supportFileAPI() %}
{{ 'Your browser does not support all HTML5 features properly.' | trans }}
{% endif %}
</p>
<a id="UPLOAD_FLASH_LINK" href="{{ path('upload_flash_form') }}" class="dialog full-dialog">{{ 'Use the Flash uploader' | trans }}</a>
</td>
{#<td class='uploader-icon'>#}
{#<img src='/assets/common/images/icons/html5-logo.png' width="32px" heigh="32px" title="{{ 'You are using the HTML5 uploader.' | trans }}"/>#}
{#</td>#}
{#<td class="uploader-infmaxFileSizeo">#}
{#<p>#}
{#{{ 'You are using the HTML5 uploader.' | trans }}#}
{#{% if not app['browser'].supportFileAPI() %}#}
{#{{ 'Your browser does not support all HTML5 features properly.' | trans }}#}
{#{% endif %}#}
{#</p>#}
<a style="display: none" id="UPLOAD_FLASH_LINK" href="{{ path('upload_flash_form') }}"
class="dialog full-dialog">{{ 'Use the Flash uploader' | trans }}</a>
{#</td>#}
</tr>
</table>
@@ -55,19 +56,24 @@
<div class='settings-box'>
<h5>{{ 'upload:: Destination (collection) :' | trans }} :</h5>
{# collections list #}
<select name="base_id" class="span3" style="margin-left: 10px;">
{% for sbasId, availableCollections in collections %}
<optgroup label="{{ availableCollections['databox'].get_label(app['locale']) }}" class="select-label">
{% for collection in availableCollections['databox_collections'] %}
<option value="{{ collection.get_base_id() }}" class="select-row">{{ collection.get_label(app['locale']) }}</option>
{% set last_used_collection = app['settings'].getUserSetting(app.getAuthenticatedUser(), 'upload_last_used_collection') %}
<select name="base_id" class="span3 upload-options-collection" style="margin-left: 10px;">
{% for sbasId, availableCollections in collections %}
<optgroup label="{{ availableCollections['databox'].get_label(app['locale']) }}"
class="select-label">
{% for collection in availableCollections['databox_collections'] %}
<option {% if last_used_collection == collection.get_base_id() %} selected="selected" {% endif %}
value="{{ collection.get_base_id() }}"
class="select-row">{{ collection.get_label(app['locale']) }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</optgroup>
{% endfor %}
</select>
{# collections status #}
{% for availableCollections in collections %}
{% for collection in availableCollections['databox_collections'] %}
<div id="status-{{ collection.get_base_id() }}" class='collection-status' style='{{ loop.parent.loop.first and loop.first ? "display:block" :"display:none" }}'>
<div id="status-{{ collection.get_base_id() }}" class='collection-status'
style='{{ last_used_collection == collection.get_base_id() ? "display:block" :"display:none" }}'>
<h5>{{ 'upload:: Status :' | trans }} :</h5>
<table class="status-tab">
<tbody>
@@ -131,6 +137,12 @@
</div>
</form>
<div>
<select name="upload_type" id="upload_type" class="input-large" style="width: 200px; float:right">
<option value="html" selected>{{ 'Use the HTML5 uploader' | trans }}</option>
<option value="flash">{{ 'Use the Flash uploader' | trans }}</option>
</select>
</div>
{% else %}
{{ 'You can not upload files' | trans }}
{% endif %}

View File

@@ -738,8 +738,8 @@
<td><label>{{ 'Modele de donnees' | trans }}</label></td>
<td>
<select name="db_template" class="databox_creation_input">
{% for template in available_templates %}
<option value="{{ template }}">{{ template }}</option>
{% for key,template in available_templates %}
<option value="{{ key }}">{{ template }}</option>
{% endfor %}
</select>
</td>

View File

@@ -39,6 +39,14 @@
self.location.replace("thesaurus.php?piv={{ piv }}&bid={{ bid }}") ;
}
function inputChanged() {
if ($("[name=term]").val().length > 0) {
$("[name=term]").css('border-color', '');
} else {
$("[name=term]").css('border-color', '#F00');
}
}
function test(div)
{
t = document.getElementById(div).innerHTML;
@@ -262,7 +270,8 @@
<tr>
<td style="text-align:right; width:80px;"><span class="label"></span> :&nbsp;</td>
<td></td>
<td><input type="text" style="width:250px;" name="term"></td>
<td><input type="text" style="width:250px;" name="term"
onkeyup="inputChanged();return(false);"></td>
</tr>
<tr>
<td style="text-align:right">{{ 'thesaurus:: contexte' | trans }} : </td>
@@ -976,6 +985,10 @@
var myObj = { "win":window };
var t = zdialog.find("[name=term]").val();
if (t.length == 0) {
zdialog.find("[name=term]").css('border-color', '#F00');
return;
}
var k = zdialog.find("[name=context]").val();
if(k != "") {
t += " (" + k + ")";

View File

@@ -3,7 +3,6 @@
namespace Alchemy\Tests\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Media\Subdef\Image;
/**
* @group functional
* @group legacy
@@ -13,9 +12,7 @@ use Alchemy\Phrasea\Media\Subdef\Image;
class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
{
protected $client;
protected $databox_id;
public function setUp()
{
parent::setUp();
@@ -24,12 +21,10 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
$databox = array_shift($databoxes);
$this->databox_id = $databox->get_sbas_id();
}
public function getSubdefName()
{
return 'testname' . time() . mt_rand(10000, 99999);
}
/**
* Default route test
*/
@@ -38,73 +33,63 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['client']->request("GET", "/admin/subdefs/" . $this->databox_id . "/");
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
}
public function testPostRouteAddSubdef()
{
$name = $this->getSubdefName();
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/", ['add_subdef' => [
'class' => 'thumbnail',
'name' => $name,
'group' => 'image'
]]);
'class' => 'thumbnail',
'name' => $name,
'group' => 'image'
]]);
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
$app = $this->getApplication();
$subdefs = new \databox_subdefsStructure($app->findDataboxById($this->databox_id), $app['translator']);
$subdefs->delete_subdef('image', $name);
}
public function testPostRouteDeleteSubdef()
{
$subdefs = $this->getApplication()->findDataboxById($this->databox_id)->get_subdef_structure();
$name = $this->getSubdefName();
$subdefs->add_subdef("image", $name, "thumbnail");
$subdefs->add_subdef("image", $name, "thumbnail", "image", "1280px JPG (preview Phraseanet)");
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/", ['delete_subdef' => 'image_' . $name]);
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
try {
$subdefs->get_subdef("image", $name);
$this->fail("should raise an exception");
} catch (\Exception $e) {
}
}
public function testPostRouteAddSubdefWithNoParams()
{
$subdefs = $this->getApplication()->findDataboxById($this->databox_id)->get_subdef_structure();
$name = $this->getSubdefName();
$subdefs->add_subdef("image", $name, "thumbnail");
$subdefs->add_subdef("image", $name, "thumbnail", "image", "1280px JPG (preview Phraseanet)");
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/"
, ['subdefs' => [
, ['subdefs' => [
'image_' . $name
]
, 'image_' . $name . '_class' => 'thumbnail'
, 'image_' . $name . '_downloadable' => 0
, 'image_' . $name . '_mediatype' => 'image'
, 'image_' . $name . '_image' => [
'size' => 400,
'resolution' => 83,
'strip' => 0,
'quality' => 90,
]]
, 'image_' . $name . '_class' => 'thumbnail'
, 'image_' . $name . '_downloadable' => 0
, 'image_' . $name . '_mediatype' => 'image'
, 'image_' . $name . '_image' => [
'size' => 400,
'resolution' => 83,
'strip' => 0,
'quality' => 90,
]]
);
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
$app = $this->getApplication();
$subdefs = new \databox_subdefsStructure($app->findDataboxById($this->databox_id), $app['translator']);
$subdef = $subdefs->get_subdef("image", $name);
/* @var $subdef \databox_subdef */
$this->assertFalse($subdef->isDownloadable());
$options = $subdef->getOptions();
$this->assertTrue(is_array($options));
$this->assertEquals(400, $options[Image::OPTION_SIZE]->getValue());
$this->assertEquals(83, $options[Image::OPTION_RESOLUTION]->getValue());
$this->assertEquals(90, $options[Image::OPTION_QUALITY]->getValue());
$this->assertFalse($options[Image::OPTION_STRIP]->getValue());
$subdefs->delete_subdef("image", $name);
}
}

View File

@@ -2,6 +2,7 @@
namespace Alchemy\Tests\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Controller\Prod\ShareController;
use Alchemy\Phrasea\ControllerProvider\Prod\Share;
use Symfony\Component\HttpKernel\Exception\HttpException;
@@ -19,37 +20,56 @@ class ShareTest extends \PhraseanetAuthenticatedWebTestCase
/**
* @covers Alchemy\Phrasea\Controller\Prod\Share::shareRecord
* @covers Alchemy\Phrasea\Controller\Prod\Share::connect
* @covers Alchemy\Phrasea\Controller\Prod\Share::call
*/
public function testMountedRouteSlash()
public function testRouteSlashALL()
{
$url = sprintf('/prod/share/record/%d/%d/', self::$DI['record_1']->get_base_id(), self::$DI['record_1']->get_record_id());
self::$DI['client']->request('GET', $url);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
$this->_RouteSlash("all", [0 => true, 1 => true, 2 => true, 3 => true]);
}
/**
* @covers Alchemy\Phrasea\Controller\Prod\Share::shareRecord
* @covers Alchemy\Phrasea\Controller\Prod\Share::connect
*/
public function testRouteSlash()
public function testRouteSlashPublishers()
{
$stubbedACL = $this->stubACL();
$this->_RouteSlash("publishers", [0 => false, 1 => true, 2 => false, 3 => true]);
}
//has_right_on_base return true
$stubbedACL->expects($this->once())
->method('has_right_on_sbas')
->will($this->returnValue(true));
public function testRouteSlashNone()
{
$this->_RouteSlash("none", [0 => false, 1 => false, 2 => false, 3 => false]);
}
//has_access_to_subdef return true
$stubbedACL->expects($this->once())
->method('has_access_to_subdef')
->will($this->returnValue(true));
private function _RouteSlash($setting, $expected)
{
$app = $this->getApplication();
$_conf = $app['conf'];
$app['conf'] = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\PropertyAccess')
->disableOriginalConstructor()
->getMock();
$app['conf']
->expects($this->any())
->method('get')
->will($this->returnCallback(function ($param, $default) use ($_conf, $setting) {
switch ($param) {
case ['registry', 'actions', 'social-tools']:
return $setting;
}
$url = sprintf('/prod/share/record/%d/%d/', self::$DI['record_1']->get_base_id(), self::$DI['record_1']->get_record_id());
self::$DI['client']->request('GET', $url);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
return $_conf->get($param, $default);
}));
$result = [];
foreach ($expected as $flags => $v) {
$stubbedACL = $this->stubACL();
// "has_right_on_sbas" IS checked by the route->before(), the url will return 403
$stubbedACL->expects($this->any())
->method('has_right_on_sbas')
->will($this->returnValue(($flags & 1) ? true : false));
// but "has_access_to_subdef" IS NOT checked (the url will return a 200 with a message "no subdef to share")
$stubbedACL->expects($this->any())
->method('has_access_to_subdef')
->will($this->returnValue(($flags & 2) ? true : false));
$url = sprintf('/prod/share/record/%d/%d/', self::$DI['record_1']->get_base_id(), self::$DI['record_1']->get_record_id());
self::$DI['client']->request('GET', $url);
$result[$flags] = self::$DI['client']->getResponse()->isOk();
}
$this->assertEquals($expected, $result);
}
/**
@@ -58,47 +78,9 @@ class ShareTest extends \PhraseanetAuthenticatedWebTestCase
public function testShareRecord()
{
$share = new ShareController(self::$DI['app']);
/** @var \record_adapter $record_1 */
$record_1 = self::$DI['record_1'];
$response = $share->shareRecord($record_1->getBaseId(), $record_1->getRecordId());
$this->assertTrue($response->isOk());
}
/**
* @covers Alchemy\Phrasea\Controller\Prod\Share::shareRecord
*/
public function testShareRecordBadAccess()
{
$share = new ShareController(self::$DI['app']);
$stubbedACL = $this->getMockBuilder('\ACL')
->disableOriginalConstructor()
->getMock();
//has_access_to_subdef return false
$stubbedACL->expects($this->once())
->method('has_access_to_subdef')
->will($this->returnValue(false));
$aclProvider = $this->getMockBuilder('Alchemy\Phrasea\Authentication\ACLProvider')
->disableOriginalConstructor()
->getMock();
$aclProvider->expects($this->any())
->method('get')
->will($this->returnValue($stubbedACL));
self::$DI['app']['acl'] = $aclProvider;
try {
$share->shareRecord(self::$DI['record_1']->get_base_id(), self::$DI['record_1']->get_record_id());
} catch (HttpException $exception) {
$this->assertEquals(403, $exception->getStatusCode());
return;
}
$this->fail('An access denied exception should have been thrown.');
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB