diff --git a/.bowerrc b/.bowerrc index 764e156e8a..bb6d6aafdb 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,3 +1,4 @@ { - "directory" : "www/bower_components" + "directory" : "www/bower_components", + "timeout": 1200000 } diff --git a/cache/.gitkeep b/cache/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/Alchemy/Phrasea/Command/Setup/Install.php b/lib/Alchemy/Phrasea/Command/Setup/Install.php index f5a7ccf817..071baf5bb2 100644 --- a/lib/Alchemy/Phrasea/Command/Setup/Install.php +++ b/lib/Alchemy/Phrasea/Command/Setup/Install.php @@ -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\tData-Box : Connection successful !\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 '$template'\n"); } catch (\Exception $e) { diff --git a/lib/Alchemy/Phrasea/Controller/Admin/SubdefsController.php b/lib/Alchemy/Phrasea/Controller/Admin/SubdefsController.php index 166ee61c56..cdee52835e 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/SubdefsController.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/SubdefsController.php @@ -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(), + '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,7 @@ 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 +76,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 +163,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 +179,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 +192,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 +202,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 = array( + Type::TYPE_IMAGE => array(Subdef::TYPE_IMAGE), + Type::TYPE_VIDEO => array(Subdef::TYPE_IMAGE, Subdef::TYPE_VIDEO, Subdef::TYPE_ANIMATION), + Type::TYPE_AUDIO => array(Subdef::TYPE_IMAGE, Subdef::TYPE_AUDIO), + Type::TYPE_DOCUMENT => array(Subdef::TYPE_IMAGE, Subdef::TYPE_FLEXPAPER), + Type::TYPE_FLASH => array(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 = array( + Subdef::TYPE_IMAGE => array( + "definitions" => array( + "JPG" => null, + "160px JPG" => array( + 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)" => array( + 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" => array( + 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)" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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 => array( + "definitions" => array( + "video codec H264" => null, + "144P H264 128 kbps ACC 128kbps" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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" => array( + 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 => array( + "definitions" => array( + "256 px fast 200 ms" => array( + Gif::OPTION_SIZE => "256", + Gif::OPTION_DELAY => "200", + Subdef::OPTION_DEVICE => ["all"] + ), + "256 px very fast 120 ms" => array( + Gif::OPTION_SIZE => "256", + Gif::OPTION_DELAY => "120", + Subdef::OPTION_DEVICE => ["all"] + ), + "320 px fast 200 ms" => array( + Gif::OPTION_SIZE => "320", + Gif::OPTION_DELAY => "200", + Subdef::OPTION_DEVICE => ["all"] + ), + ), + "form" => array( + Gif::OPTION_SIZE => "slide", + Gif::OPTION_DELAY => "slide", + Subdef::OPTION_DEVICE => "checkbox", + ), + ), + Subdef::TYPE_AUDIO => array( + "definitions" => array( + "Low AAC 96 kbit/s" => array( + Audio::OPTION_AUDIOBITRATE => "100", + Audio::OPTION_AUDIOSAMPLERATE => "8000", + Audio::OPTION_ACODEC => "libmp3lame", + Subdef::OPTION_DEVICE => ["all"] + ), + "Normal AAC 128 kbit/s" => array( + Audio::OPTION_AUDIOBITRATE => "180", + Audio::OPTION_AUDIOSAMPLERATE => "44100", + Audio::OPTION_ACODEC => "libmp3lame", + Subdef::OPTION_DEVICE => ["all"] + ), + "High AAC 320 kbit/s" => array( + Audio::OPTION_AUDIOBITRATE => "230", + Audio::OPTION_AUDIOSAMPLERATE => "50000", + Audio::OPTION_ACODEC => "libmp3lame", + Subdef::OPTION_DEVICE => ["all"] + ), + ), + "form" => array( + Audio::OPTION_AUDIOBITRATE => "slide", + Audio::OPTION_AUDIOSAMPLERATE => "select", + Audio::OPTION_ACODEC => "select", + Subdef::OPTION_DEVICE => "checkbox", + ), + ), + Subdef::TYPE_FLEXPAPER => array( + "definitions" => array( + ), + "form" => array(), + ), + ); - $changedGroups[] = $subdefsGroup; - } - } - - if ($changedGroups) { - $subdefs->updateSubdefGroups($changedGroups); - } + return $config; } } diff --git a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php index e838b61d5f..d89fc9ae32 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/MoveCollectionController.php @@ -36,6 +36,31 @@ 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 = array(); + 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' => '', diff --git a/lib/Alchemy/Phrasea/Controller/Prod/ShareController.php b/lib/Alchemy/Phrasea/Controller/Prod/ShareController.php index 85df3351cf..04b0f00612 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/ShareController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/ShareController.php @@ -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); } } diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php index 846b934fd7..85bd81def4 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php @@ -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; + } /** diff --git a/lib/Alchemy/Phrasea/Controller/SetupController.php b/lib/Alchemy/Phrasea/Controller/SetupController.php index b18dd7965b..36eaaae141 100644 --- a/lib/Alchemy/Phrasea/Controller/SetupController.php +++ b/lib/Alchemy/Phrasea/Controller/SetupController.php @@ -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() . '/', diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php index e4e58e53b2..d2f1901814 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Share.php @@ -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'); diff --git a/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php b/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php index b82b3501e0..532c8cf247 100644 --- a/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php +++ b/lib/Alchemy/Phrasea/Core/Configuration/DisplaySettingService.php @@ -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', diff --git a/lib/Alchemy/Phrasea/Core/Configuration/StructureTemplate.php b/lib/Alchemy/Phrasea/Core/Configuration/StructureTemplate.php new file mode 100644 index 0000000000..727cdd0bce --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Configuration/StructureTemplate.php @@ -0,0 +1,93 @@ +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; + } +} \ No newline at end of file diff --git a/lib/Alchemy/Phrasea/Core/Provider/ConfigurationServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/ConfigurationServiceProvider.php index 55623e0081..c7cec0227e 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/ConfigurationServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/ConfigurationServiceProvider.php @@ -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); + }); } /** diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPreset.php b/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPreset.php new file mode 100644 index 0000000000..7a954badc7 --- /dev/null +++ b/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPreset.php @@ -0,0 +1,46 @@ +mediaType = (string) $mediaType; + $this->definitions = $definitions; + } + /** + * @return string + */ + public function getMediaType() + { + return $this->label; + } + /** + * @return array + */ + public function getDefinitions() + { + return $this->definitions; + } +} \ No newline at end of file diff --git a/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPresetProvider.php b/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPresetProvider.php new file mode 100644 index 0000000000..2f6c989ad8 --- /dev/null +++ b/lib/Alchemy/Phrasea/Databox/Subdef/SubdefPresetProvider.php @@ -0,0 +1,19 @@ +presets[$type])) { + throw new \InvalidArgumentException('Invalid type'); + } + return $this->presets[$type]; + } +} \ No newline at end of file diff --git a/lib/Alchemy/Phrasea/Helper/Prod.php b/lib/Alchemy/Phrasea/Helper/Prod.php index 3537b367c0..54470f60ee 100644 --- a/lib/Alchemy/Phrasea/Helper/Prod.php +++ b/lib/Alchemy/Phrasea/Helper/Prod.php @@ -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 = array(); + 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; diff --git a/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php b/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php index 339d50002f..3853958f4c 100644 --- a/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php +++ b/lib/Alchemy/Phrasea/Media/Subdef/Subdef.php @@ -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'; diff --git a/lib/Alchemy/Phrasea/Setup/Installer.php b/lib/Alchemy/Phrasea/Setup/Installer.php index 2868f79835..0700eb1907 100644 --- a/lib/Alchemy/Phrasea/Setup/Installer.php +++ b/lib/Alchemy/Phrasea/Setup/Installer.php @@ -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) diff --git a/lib/classes/databox/subdef.php b/lib/classes/databox/subdef.php index 1cac20b970..188e1ccc22 100644 --- a/lib/classes/databox/subdef.php +++ b/lib/classes/databox/subdef.php @@ -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() @@ -328,7 +303,7 @@ class databox_subdef return $this->downloadable; } - /** + /** * @return bool */ public function isOrderable() @@ -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 * @@ -424,4 +403,4 @@ class databox_subdef { return $this->subdef_type->getOptions(); } -} +} \ No newline at end of file diff --git a/lib/classes/databox/subdefsStructure.php b/lib/classes/databox/subdefsStructure.php index 1f856f5bf3..9afd912e36 100644 --- a/lib/classes/databox/subdefsStructure.php +++ b/lib/classes/databox/subdefsStructure.php @@ -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'); diff --git a/lib/classes/record/preview.php b/lib/classes/record/preview.php index 8712b0c1fe..dd0ae0fe43 100644 --- a/lib/classes/record/preview.php +++ b/lib/classes/record/preview.php @@ -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; diff --git a/resources/ansible/roles/app/templates/configuration.tpl b/resources/ansible/roles/app/templates/configuration.tpl index 346f11020b..bf39dd9a68 100644 --- a/resources/ansible/roles/app/templates/configuration.tpl +++ b/resources/ansible/roles/app/templates/configuration.tpl @@ -12,7 +12,7 @@ main: port: 3306 user: '{{ mariadb.user }}' password: '{{ mariadb.password }}' - dbname: '{{ mariadb.database }}' + dbname: '{{ mariadb.appbox_db }}' driver: pdo_mysql charset: UTF8 database-test: diff --git a/resources/ansible/roles/mariadb/tasks/main.yml b/resources/ansible/roles/mariadb/tasks/main.yml index 6e87843ac9..0fbc016ca1 100644 --- a/resources/ansible/roles/mariadb/tasks/main.yml +++ b/resources/ansible/roles/mariadb/tasks/main.yml @@ -47,7 +47,7 @@ - "{{ mariadb.alt_databox_db }}" - name: mariadb | Import dump - mysql_db: name={{ mariadb.database }} state=import login_user=root login_password={{ mariadb.root_password }} target=/vagrant/{{ mariadb.dump }} + mysql_db: name={{ mariadb.appbox_db }} state=import login_user=root login_password={{ mariadb.root_password }} target=/vagrant/{{ mariadb.dump }} when: mariadb.dump - name: mariadb | Create users diff --git a/resources/ansible/roles/php/tasks/pecl.yml b/resources/ansible/roles/php/tasks/pecl.yml index 5f72cce3df..d8edc0fcc2 100644 --- a/resources/ansible/roles/php/tasks/pecl.yml +++ b/resources/ansible/roles/php/tasks/pecl.yml @@ -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 diff --git a/resources/ansible/vars/all.yml b/resources/ansible/vars/all.yml index 1475cc804d..26f2941820 100644 --- a/resources/ansible/vars/all.yml +++ b/resources/ansible/vars/all.yml @@ -41,7 +41,7 @@ nginx: mariadb: install: '1' root_password: toor - database: ab_master + appbox_db: ab_master databox_db: db_master alt_databox_db: db_alt user: phraseanet diff --git a/resources/locales/messages.de.xlf b/resources/locales/messages.de.xlf index 5532826611..4464898fd5 100644 --- a/resources/locales/messages.de.xlf +++ b/resources/locales/messages.de.xlf @@ -2352,7 +2352,7 @@ Detailed view URL Detailansicht URL - prod/Share/record.html.twig + prod/Share/record.html.twig Details @@ -2677,7 +2677,7 @@ Embed code Embed-Code - prod/Share/record.html.twig + prod/Share/record.html.twig Empty a collection @@ -4347,7 +4347,7 @@ No URL available keine verfügbare URL - prod/Share/record.html.twig + prod/Share/record.html.twig No account yet? @@ -5563,7 +5563,7 @@ Resource URL Resource URL - prod/Share/record.html.twig + prod/Share/record.html.twig Resquest access @@ -5841,12 +5841,12 @@ Send to Facebook Auf Facebook teilen - prod/Share/record.html.twig + prod/Share/record.html.twig Send to Twitter Auf Twitter teilen - prod/Share/record.html.twig + prod/Share/record.html.twig Sent @@ -9427,9 +9427,9 @@ copyClipboardLabel in der Zwischenablage kopieren - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig dans %category% @@ -10754,9 +10754,9 @@ previewLinkLabel ansichten - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig print:: image de choix et description @@ -11069,6 +11069,7 @@ prod::tools: document Dokument + Controller/Prod/ShareController.php Controller/Prod/ToolsController.php @@ -12269,6 +12270,15 @@ setup::custom-link:title-custom-link setup::custom-link:title-custom-link web/admin/setup.html.twig + + share::share-record: advance + share::share-record: advance + prod/Share/record.html.twig + + + share::share-record: select-shared-def + share::share-record: select-shared-def + prod/Share/record.html.twig sport diff --git a/resources/locales/messages.en.xlf b/resources/locales/messages.en.xlf index e8286bc599..7ebc52997c 100644 --- a/resources/locales/messages.en.xlf +++ b/resources/locales/messages.en.xlf @@ -2352,7 +2352,7 @@ Detailed view URL URL of the detailed view - prod/Share/record.html.twig + prod/Share/record.html.twig Details @@ -2677,7 +2677,7 @@ Embed code Embed code - prod/Share/record.html.twig + prod/Share/record.html.twig Empty a collection @@ -4347,7 +4347,7 @@ No URL available No URL available - prod/Share/record.html.twig + prod/Share/record.html.twig No account yet? @@ -5563,7 +5563,7 @@ Resource URL Resource URL - prod/Share/record.html.twig + prod/Share/record.html.twig Resquest access @@ -5841,12 +5841,12 @@ Send to Facebook Send to Facebook - prod/Share/record.html.twig + prod/Share/record.html.twig Send to Twitter Send to Twitter - prod/Share/record.html.twig + prod/Share/record.html.twig Sent @@ -9428,9 +9428,9 @@ copyClipboardLabel Copy to clipboard - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig dans %category% @@ -10755,9 +10755,9 @@ previewLinkLabel Preview - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig print:: image de choix et description @@ -11070,6 +11070,7 @@ prod::tools: document Document + Controller/Prod/ShareController.php Controller/Prod/ToolsController.php @@ -12270,6 +12271,15 @@ setup::custom-link:title-custom-link setup::custom-link:title-custom-link web/admin/setup.html.twig + + share::share-record: advance + share::share-record: advance + prod/Share/record.html.twig + + + share::share-record: select-shared-def + share::share-record: select-shared-def + prod/Share/record.html.twig sport diff --git a/resources/locales/messages.fr.xlf b/resources/locales/messages.fr.xlf index 340af52166..f1aa86af2b 100644 --- a/resources/locales/messages.fr.xlf +++ b/resources/locales/messages.fr.xlf @@ -2352,7 +2352,7 @@ Detailed view URL URL de la vue détaillée - prod/Share/record.html.twig + prod/Share/record.html.twig Details @@ -2677,7 +2677,7 @@ Embed code Code d'intégration (Embed code) - prod/Share/record.html.twig + prod/Share/record.html.twig Empty a collection @@ -4347,7 +4347,7 @@ No URL available Aucune URL de disponible - prod/Share/record.html.twig + prod/Share/record.html.twig No account yet? @@ -5565,7 +5565,7 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Resource URL URL de la ressource - prod/Share/record.html.twig + prod/Share/record.html.twig Resquest access @@ -5843,12 +5843,12 @@ Pour les utilisateurs authentifiés, la demande de validation est également dis Send to Facebook Envoyer vers Facebook - prod/Share/record.html.twig + prod/Share/record.html.twig Send to Twitter Envoyer vers Twitter - prod/Share/record.html.twig + prod/Share/record.html.twig Sent @@ -9431,9 +9431,9 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le copyClipboardLabel Copier dans le presse-papier - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig dans %category% @@ -10758,9 +10758,9 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le previewLinkLabel Prévisualiser - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig print:: image de choix et description @@ -11073,6 +11073,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le prod::tools: document Document + Controller/Prod/ShareController.php Controller/Prod/ToolsController.php @@ -12273,6 +12274,15 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le setup::custom-link:title-custom-link setup::custom-link:title-custom-link web/admin/setup.html.twig + + share::share-record: advance + share::share-record: advance + prod/Share/record.html.twig + + + share::share-record: select-shared-def + share::share-record: select-shared-def + prod/Share/record.html.twig sport diff --git a/resources/locales/messages.nl.xlf b/resources/locales/messages.nl.xlf index eceb16c78f..bbafcf6363 100644 --- a/resources/locales/messages.nl.xlf +++ b/resources/locales/messages.nl.xlf @@ -2356,7 +2356,7 @@ Detailed view URL Gedetailleerde weergave URL - prod/Share/record.html.twig + prod/Share/record.html.twig Details @@ -2681,7 +2681,7 @@ Embed code Sluit de code in - prod/Share/record.html.twig + prod/Share/record.html.twig Empty a collection @@ -4351,7 +4351,7 @@ No URL available Geen URL beschikbaar - prod/Share/record.html.twig + prod/Share/record.html.twig No account yet? @@ -5567,7 +5567,7 @@ Resource URL Bron URL - prod/Share/record.html.twig + prod/Share/record.html.twig Resquest access @@ -5845,12 +5845,12 @@ Send to Facebook Verstuur naar Facebook - prod/Share/record.html.twig + prod/Share/record.html.twig Send to Twitter Verstuur naar Twitter - prod/Share/record.html.twig + prod/Share/record.html.twig Sent @@ -9431,9 +9431,9 @@ copyClipboardLabel copyClipboardLabel - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig dans %category% @@ -10758,9 +10758,9 @@ previewLinkLabel previewLinkLabel - prod/Share/record.html.twig - prod/Share/record.html.twig - prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig + prod/Share/record.html.twig print:: image de choix et description @@ -11073,6 +11073,7 @@ prod::tools: document prod::tools: document + Controller/Prod/ShareController.php Controller/Prod/ToolsController.php @@ -12273,6 +12274,15 @@ setup::custom-link:title-custom-link setup::custom-link:title-custom-link web/admin/setup.html.twig + + share::share-record: advance + share::share-record: advance + prod/Share/record.html.twig + + + share::share-record: select-shared-def + share::share-record: select-shared-def + prod/Share/record.html.twig sport diff --git a/resources/www/account/images/favicon.ico b/resources/www/account/images/favicon.ico new file mode 100644 index 0000000000..9d0de806a9 Binary files /dev/null and b/resources/www/account/images/favicon.ico differ diff --git a/resources/www/admin/styles/main.scss b/resources/www/admin/styles/main.scss index c5453d6d9e..8e9235c66d 100644 --- a/resources/www/admin/styles/main.scss +++ b/resources/www/admin/styles/main.scss @@ -336,6 +336,93 @@ 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%; @@ -433,6 +520,12 @@ span.simplecolorpicker.picker { background-position: center center; } +@media screen and (max-width: 1150px) { + .langTab{ + display: block; + } +} + @import './databases'; @import './fields'; -@import './tables'; +@import './tables'; \ No newline at end of file diff --git a/resources/www/common/images/icons/browse_basket.png b/resources/www/common/images/icons/browse_basket.png new file mode 100644 index 0000000000..585684376e Binary files /dev/null and b/resources/www/common/images/icons/browse_basket.png differ diff --git a/resources/www/common/images/icons/icon_audio.png b/resources/www/common/images/icons/icon_audio.png index 7765028fdd..2f6ae11e34 100644 Binary files a/resources/www/common/images/icons/icon_audio.png and b/resources/www/common/images/icons/icon_audio.png differ diff --git a/resources/www/common/images/icons/icon_collection_bin.png b/resources/www/common/images/icons/icon_collection_bin.png new file mode 100644 index 0000000000..fe12ad821a Binary files /dev/null and b/resources/www/common/images/icons/icon_collection_bin.png differ diff --git a/resources/www/common/images/icons/icon_document.png b/resources/www/common/images/icons/icon_document.png index 990015b4c7..c44e9fd113 100644 Binary files a/resources/www/common/images/icons/icon_document.png and b/resources/www/common/images/icons/icon_document.png differ diff --git a/resources/www/common/images/icons/icon_empty_bin.png b/resources/www/common/images/icons/icon_empty_bin.png new file mode 100644 index 0000000000..240aa01118 Binary files /dev/null and b/resources/www/common/images/icons/icon_empty_bin.png differ diff --git a/resources/www/common/images/icons/icon_image.png b/resources/www/common/images/icons/icon_image.png index 5f9d51c108..4aa5270af4 100644 Binary files a/resources/www/common/images/icons/icon_image.png and b/resources/www/common/images/icons/icon_image.png differ diff --git a/resources/www/common/images/icons/icon_video.png b/resources/www/common/images/icons/icon_video.png index b97bb59f60..14c917bee0 100644 Binary files a/resources/www/common/images/icons/icon_video.png and b/resources/www/common/images/icons/icon_video.png differ diff --git a/resources/www/common/images/icons/new_basket.png b/resources/www/common/images/icons/new_basket.png new file mode 100644 index 0000000000..a85a564919 Binary files /dev/null and b/resources/www/common/images/icons/new_basket.png differ diff --git a/resources/www/common/images/icons/new_report.png b/resources/www/common/images/icons/new_report.png new file mode 100644 index 0000000000..d29a06a1dc Binary files /dev/null and b/resources/www/common/images/icons/new_report.png differ diff --git a/resources/www/common/images/icons/sort_alpha.png b/resources/www/common/images/icons/sort_alpha.png new file mode 100644 index 0000000000..69f98fce0a Binary files /dev/null and b/resources/www/common/images/icons/sort_alpha.png differ diff --git a/resources/www/common/images/icons/sort_date.png b/resources/www/common/images/icons/sort_date.png new file mode 100644 index 0000000000..247a48835e Binary files /dev/null and b/resources/www/common/images/icons/sort_date.png differ diff --git a/resources/www/common/js/components/common.js b/resources/www/common/js/components/common.js index 5f5db50428..ee198857d8 100644 --- a/resources/www/common/js/components/common.js +++ b/resources/www/common/js/components/common.js @@ -31,11 +31,11 @@ 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 + // }); }); function showOverlay(n, appendto, callback, zIndex) { diff --git a/templates/web/account/base.html.twig b/templates/web/account/base.html.twig index c6f2213f57..f1574dcbdb 100644 --- a/templates/web/account/base.html.twig +++ b/templates/web/account/base.html.twig @@ -3,6 +3,10 @@ {% extends "common/index_bootstrap.html.twig" %} +{% block icon %} + +{% endblock %} + {% block stylesheet %}