diff --git a/.env b/.env index 152f0e6fa91..a5a7c2f3d12 100644 --- a/.env +++ b/.env @@ -133,7 +133,7 @@ PHRASEANET_DOCKER_REGISTRY=local # Docker images tag. # @run -PHRASEANET_DOCKER_TAG=4.1.8-rc2 +PHRASEANET_DOCKER_TAG=4.1.8-rc3 # Stack Name # An optionnal Name for the stack diff --git a/.gitignore b/.gitignore index 730df1318e1..d33424b147d 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,14 @@ # Exclude log folder /logs +# Exclude backup folder +/backup +!/backup/.gitkeep + +# Exclude ftp folder +/ftp +!/ftp/.gitkeep + # Exclude plugin folder /plugins # Excluse assets plugin folder diff --git a/CHANGELOG.md b/CHANGELOG.md index 56ada6c6f11..5d48910b6ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # CHANGELOG +## 4.1.8-rc3 + +### Update instructions + +- Migration patch: no patch to play, just run upgrade for bump version +- Elasticsearch index action : none + +### Version summary + +- bugfix an minor improvement + +### Stack (docker compose) + + - no change + +## What's Changed +* PHRAS-3859 fix gateway fastcgi https default value in https://github.com/alchemy-fr/Phraseanet/pull/4329 +* PHRAS-3860 bin/console user:edit in https://github.com/alchemy-fr/Phraseanet/pull/4328 +* PHRAS-3855 Prod - Facettes : color html tags in https://github.com/alchemy-fr/Phraseanet/pull/4330 +* PHRAS-3860 Sync phraseanet root account info in https://github.com/alchemy-fr/Phraseanet/pull/4331 +* PHRAS-3409: Prod - Edit : A user that have no right is bloqued when trying to edit in https://github.com/alchemy-fr/Phraseanet/pull/4332 +* PHRAS-3872 prod- printed pdf - title content encoding in https://github.com/alchemy-fr/Phraseanet/pull/4336 +* PHRAS-3873: prod -advance search - field , leave only label and real field name in https://github.com/alchemy-fr/Phraseanet/pull/4335 +* PHRAS-3869: secure locale cookie in https://github.com/alchemy-fr/Phraseanet/pull/4333 +* PHRAS-3874 Prod - tools - subdefinition tab - use subdefintion label in https://github.com/alchemy-fr/Phraseanet/pull/4337 + + +**Full Changelog**: https://github.com/alchemy-fr/Phraseanet/compare/4.1.8-rc2...4.1.8-rc3 + + + +## 4.1.8-rc2 + +### Update instructions : + +- Migration patch: no patch to play, just run upgrade for bump version +- Elasticsearch index action : none + +### Version summary : + +- Docker Nginx vhost, set security headers +- and allow secure cookies + +### Stack (docker compose, helm) + +It is now possible to use secure cookies with an env variable + + - `COOKIE_SECURE` true | false , true activates cookie secure when https is setup + +see .env + +## What's New +* PHRAS-3859 set security headers and allow secure cookies by in https://github.com/alchemy-fr/Phraseanet/pull/4324 +* PHRAS-3859 increased security with headers by in https://github.com/alchemy-fr/Phraseanet/pull/4325 + + +**Full Changelog**: https://github.com/alchemy-fr/Phraseanet/compare/4.1.8-rc1...4.1.8-rc2 + ## 4.1.8-rc1 diff --git a/Phraseanet-production-client/config/config.js b/Phraseanet-production-client/config/config.js index d19f8be8dfd..7c45c222c48 100644 --- a/Phraseanet-production-client/config/config.js +++ b/Phraseanet-production-client/config/config.js @@ -13,5 +13,5 @@ module.exports = { setupDir: _root + 'tests/setup/node.js', karmaConf: _root + 'config/karma.conf.js', // change this version when you change JS file for lazy loading - assetFileVersion: 87 + assetFileVersion: 88 }; diff --git a/Phraseanet-production-client/dist/authenticate.js b/Phraseanet-production-client/dist/authenticate.js index 37ad6f1893a..c761818b119 100644 --- a/Phraseanet-production-client/dist/authenticate.js +++ b/Phraseanet-production-client/dist/authenticate.js @@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=87"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=88"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/authenticate.min.js b/Phraseanet-production-client/dist/authenticate.min.js index 94a73c5e466..810502d244d 100644 --- a/Phraseanet-production-client/dist/authenticate.min.js +++ b/Phraseanet-production-client/dist/authenticate.min.js @@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=87"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=88"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/commons.js b/Phraseanet-production-client/dist/commons.js index f80b19bf7a4..53ad4b829bf 100644 --- a/Phraseanet-production-client/dist/commons.js +++ b/Phraseanet-production-client/dist/commons.js @@ -91,7 +91,7 @@ /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=87"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=88"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/commons.min.js b/Phraseanet-production-client/dist/commons.min.js index 6bf26f8695d..3fc9ef229b6 100644 --- a/Phraseanet-production-client/dist/commons.min.js +++ b/Phraseanet-production-client/dist/commons.min.js @@ -91,7 +91,7 @@ /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=87"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=88"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/production.js b/Phraseanet-production-client/dist/production.js index 67b10bd1fa0..82e74531304 100644 --- a/Phraseanet-production-client/dist/production.js +++ b/Phraseanet-production-client/dist/production.js @@ -3882,7 +3882,6 @@ var workzoneFacets = function workzoneFacets(services) { if (match && match[2] != null) { // text looks like a color ! var colorCode = '#' + match[2]; - // add color circle and remove color code from text; var textWithoutColorCode = text.replace('[' + colorCode + ']', ''); if (textLimit > 0 && textWithoutColorCode.length > textLimit) { textWithoutColorCode = textWithoutColorCode.substring(0, textLimit) + '…'; @@ -3890,7 +3889,9 @@ var workzoneFacets = function workzoneFacets(services) { // patch type = "COLOR-AGGREGATE"; label = textWithoutColorCode; + textWithoutColorCode = (0, _jquery2.default)('
').text(textWithoutColorCode).html(); // escape html tooltip = _.escape(textWithoutColorCode); + title = ' ' + tooltip; } else { // keep text as it is, just cut if too long @@ -3898,7 +3899,7 @@ var workzoneFacets = function workzoneFacets(services) { text = text.substring(0, textLimit) + '…'; } label = text; - /*title = tooltip = _.escape(text);*/ + title = (0, _jquery2.default)('').text(text).html(); // escape html } return { @@ -3952,8 +3953,6 @@ var workzoneFacets = function workzoneFacets(services) { treeSource = _shouldMaskNodes(treeSource, hiddenFacetsList); } - treeSource = _parseColors(treeSource); - treeSource = _colorUnsetText(treeSource); return _getFacetsTree().reload(treeSource).done(function () { @@ -3980,18 +3979,6 @@ var workzoneFacets = function workzoneFacets(services) { }); }; - function _parseColors(source) { - _.forEach(source, function (facet) { - if (!_.isUndefined(facet.children) && facet.children.length > 0) { - _.forEach(facet.children, function (child) { - var title = child.title; - child.title = _formatColorText(title.toString()); - }); - } - }); - return source; - } - function _formatColorText(string) { var textLimit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; @@ -5534,6 +5521,14 @@ var editRecord = function editRecord(services) { success: function success(data) { (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').empty().html(data); + // if the user have not "edit" right in all selected document + if (window.recordEditorConfig.state.T_records.length === 0) { + alert(window.recordEditorConfig.notActionableMsg); + (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').hide(); + + return; + } + if (window.recordEditorConfig.hasMultipleDatabases === true) { (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').hide(); diff --git a/Phraseanet-production-client/dist/production.min.js b/Phraseanet-production-client/dist/production.min.js index 67b10bd1fa0..82e74531304 100644 --- a/Phraseanet-production-client/dist/production.min.js +++ b/Phraseanet-production-client/dist/production.min.js @@ -3882,7 +3882,6 @@ var workzoneFacets = function workzoneFacets(services) { if (match && match[2] != null) { // text looks like a color ! var colorCode = '#' + match[2]; - // add color circle and remove color code from text; var textWithoutColorCode = text.replace('[' + colorCode + ']', ''); if (textLimit > 0 && textWithoutColorCode.length > textLimit) { textWithoutColorCode = textWithoutColorCode.substring(0, textLimit) + '…'; @@ -3890,7 +3889,9 @@ var workzoneFacets = function workzoneFacets(services) { // patch type = "COLOR-AGGREGATE"; label = textWithoutColorCode; + textWithoutColorCode = (0, _jquery2.default)('').text(textWithoutColorCode).html(); // escape html tooltip = _.escape(textWithoutColorCode); + title = ' ' + tooltip; } else { // keep text as it is, just cut if too long @@ -3898,7 +3899,7 @@ var workzoneFacets = function workzoneFacets(services) { text = text.substring(0, textLimit) + '…'; } label = text; - /*title = tooltip = _.escape(text);*/ + title = (0, _jquery2.default)('').text(text).html(); // escape html } return { @@ -3952,8 +3953,6 @@ var workzoneFacets = function workzoneFacets(services) { treeSource = _shouldMaskNodes(treeSource, hiddenFacetsList); } - treeSource = _parseColors(treeSource); - treeSource = _colorUnsetText(treeSource); return _getFacetsTree().reload(treeSource).done(function () { @@ -3980,18 +3979,6 @@ var workzoneFacets = function workzoneFacets(services) { }); }; - function _parseColors(source) { - _.forEach(source, function (facet) { - if (!_.isUndefined(facet.children) && facet.children.length > 0) { - _.forEach(facet.children, function (child) { - var title = child.title; - child.title = _formatColorText(title.toString()); - }); - } - }); - return source; - } - function _formatColorText(string) { var textLimit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; @@ -5534,6 +5521,14 @@ var editRecord = function editRecord(services) { success: function success(data) { (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').empty().html(data); + // if the user have not "edit" right in all selected document + if (window.recordEditorConfig.state.T_records.length === 0) { + alert(window.recordEditorConfig.notActionableMsg); + (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').hide(); + + return; + } + if (window.recordEditorConfig.hasMultipleDatabases === true) { (0, _jquery2.default)('#EDITWINDOW').removeClass('loading').hide(); diff --git a/Phraseanet-production-client/src/components/record/edit.js b/Phraseanet-production-client/src/components/record/edit.js index 2257cc76ebb..5cbc15756c9 100644 --- a/Phraseanet-production-client/src/components/record/edit.js +++ b/Phraseanet-production-client/src/components/record/edit.js @@ -52,6 +52,14 @@ const editRecord = (services) => { success: (data) => { $('#EDITWINDOW').removeClass('loading').empty().html(data); + // if the user have not "edit" right in all selected document + if (window.recordEditorConfig.state.T_records.length === 0) { + alert(window.recordEditorConfig.notActionableMsg); + $('#EDITWINDOW').removeClass('loading').hide(); + + return; + } + if (window.recordEditorConfig.hasMultipleDatabases === true) { $('#EDITWINDOW').removeClass('loading').hide(); diff --git a/Phraseanet-production-client/src/components/ui/workzone/facets/index.js b/Phraseanet-production-client/src/components/ui/workzone/facets/index.js index 2c7d177f302..b382bab083d 100644 --- a/Phraseanet-production-client/src/components/ui/workzone/facets/index.js +++ b/Phraseanet-production-client/src/components/ui/workzone/facets/index.js @@ -78,7 +78,6 @@ const workzoneFacets = services => { if(match && match[2] != null) { // text looks like a color ! var colorCode = '#' + match[2]; - // add color circle and remove color code from text; var textWithoutColorCode = text.replace('[' + colorCode + ']', ''); if (textLimit > 0 && textWithoutColorCode.length > textLimit) { textWithoutColorCode = textWithoutColorCode.substring(0, textLimit) + '…'; @@ -86,7 +85,9 @@ const workzoneFacets = services => { // patch type = "COLOR-AGGREGATE"; label = textWithoutColorCode; + textWithoutColorCode = $('').text(textWithoutColorCode).html(); // escape html tooltip = _.escape(textWithoutColorCode); + title = ' ' + tooltip; } else { @@ -95,7 +96,7 @@ const workzoneFacets = services => { text = text.substring(0, textLimit) + '…'; } label = text; - /*title = tooltip = _.escape(text);*/ + title = $('').text(text).html(); // escape html } return { @@ -154,8 +155,6 @@ const workzoneFacets = services => { treeSource = _shouldMaskNodes(treeSource, hiddenFacetsList); } - treeSource = _parseColors(treeSource); - treeSource = _colorUnsetText(treeSource); return _getFacetsTree().reload(treeSource) @@ -183,18 +182,6 @@ const workzoneFacets = services => { }); }; - function _parseColors(source) { - _.forEach(source, function (facet) { - if (!_.isUndefined(facet.children) && (facet.children.length > 0)) { - _.forEach(facet.children, function (child) { - var title = child.title; - child.title = _formatColorText(title.toString()); - }); - } - }); - return source; - } - function _formatColorText(string) { var textLimit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; diff --git a/docker-compose.yml b/docker-compose.yml index e98a531dbc3..1f00de2ab75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -207,9 +207,6 @@ services: restart: on-failure environment: - STACK_NAME - - PHRASEANET_INSTALL - - PHRASEANET_SETUP - - PHRASEANET_UPGRADE - PHRASEANET_PROJECT_NAME - PHRASEANET_TRUSTED_PROXIES - PHRASEANET_DEBUG_ALLOWED_IP @@ -222,37 +219,9 @@ services: - OPCACHE_ENABLED - SESSION_CACHE_LIMITER - PHP_LOG_LEVEL - - PHRASEANET_ADMIN_ACCOUNT_ID - - PHRASEANET_ADMIN_ACCOUNT_EMAIL - - PHRASEANET_ADMIN_ACCOUNT_PASSWORD - - PHRASEANET_DB_HOST - - PHRASEANET_DB_PORT - - PHRASEANET_DB_USER - - PHRASEANET_DB_PASSWORD - - INSTALL_DB_TEMPLATE - - INSTALL_APPBOX - - INSTALL_DATABOX - PHRASEANET_SCHEME - PHRASEANET_HOSTNAME - PHRASEANET_APP_PORT - - PHRASEANET_AVAILABLE_LANGUAGE - - PHRASEANET_DEFAULT_LANGUAGE - - PHRASEANET_RABBITMQ_HOST - - PHRASEANET_RABBITMQ_PORT - - PHRASEANET_RABBITMQ_SSL - - PHRASEANET_RABBITMQ_VHOST - - PHRASEANET_RABBITMQ_HEARTBEAT - - PHRASEANET_RABBITMQ_USER=$RABBITMQ_DEFAULT_USER - - PHRASEANET_RABBITMQ_PASSWORD=$RABBITMQ_DEFAULT_PASS - - PHRASEANET_EMITTER_EMAIL - - PHRASEANET_MAIL_OBJECT_PREFIX - - PHRASEANET_SMTP_ENABLED - - PHRASEANET_SMTP_HOST - - PHRASEANET_SMTP_PORT - - PHRASEANET_SMTP_AUTH_ENABLED - - PHRASEANET_SMTP_SECURE_MODE - - PHRASEANET_SMTP_USER - - PHRASEANET_SMTP_PASSWORD - PHRASEANET_DOWNLOAD_DIR - PHRASEANET_LAZARET_DIR - PHRASEANET_CAPTION_DIR @@ -284,23 +253,6 @@ services: - BLACKFIRE_SERVER_TOKEN - SESSION_SAVE_HANDLER - SESSION_SAVE_PATH - - PHRASEANET_CACHE_TYPE - - PHRASEANET_CACHE_HOST - - PHRASEANET_CACHE_PORT - - PHRASEANET_ELASTICSEARCH_HOST - - PHRASEANET_ELASTICSEARCH_PORT - - PHRASEANET_ELASTICSEARCH_INDEX - - PHRASEANET_ELASTICSEARCH_SHARD - - PHRASEANET_ELASTICSEARCH_REPLICAS - - PHRASEANET_ELASTICSEARCH_MINSCORE - - PHRASEANET_ELASTICSEARCH_HIGHLIGHT - - PHRASEANET_ELASTICSEARCH_MAXRESULTWINDOW - - PHRASEANET_ELASTICSEARCH_POPULATEORDER - - PHRASEANET_ELASTICSEARCH_ACTIVETAB - - PHRASEANET_ELASTICSEARCH_FACET_BASE - - PHRASEANET_ELASTICSEARCH_FACET_COLLECTION - - PHRASEANET_ELASTICSEARCH_FACET_DOCTYPE - - PHRASEANET_ELASTICSEARCH_FACET_ORIENTATION - PHRASEANET_MAINTENANCE volumes: diff --git a/docker/nginx/root/entrypoint.sh b/docker/nginx/root/entrypoint.sh index cfb87b5f6a6..313744a81be 100755 --- a/docker/nginx/root/entrypoint.sh +++ b/docker/nginx/root/entrypoint.sh @@ -68,6 +68,7 @@ if [[ ! -z $GATEWAY_ALLOWED_IPS ]] || [[ ! -z $GATEWAY_DENIED_IPS ]] || [[ ! -z echo "deny all;" >> /etc/nginx/restrictions fi fi - - +unset GATEWAY_USERS +unset GATEWAY_DENIED_IPS +unset GATEWAY_ALLOWED_IPS exec "$@" diff --git a/docker/phraseanet/setup/entrypoint.sh b/docker/phraseanet/setup/entrypoint.sh index 0baf7bafc01..23c8453fbf3 100755 --- a/docker/phraseanet/setup/entrypoint.sh +++ b/docker/phraseanet/setup/entrypoint.sh @@ -193,9 +193,10 @@ if [[ -f "$FILE" && $PHRASEANET_SETUP = 1 ]]; then bin/setup system:config set -q registry.email.prefix "$PHRASEANET_MAIL_OBJECT_PREFIX" fi - echo `date +"%Y-%m-%d %H:%M:%S"` " - Phraseanet root account Password sync" + echo `date +"%Y-%m-%d %H:%M:%S"` " - Phraseanet Root account sync" if [[ -n ${PHRASEANET_ADMIN_ACCOUNT_ID} && $PHRASEANET_ADMIN_ACCOUNT_ID =~ ^[0-9]+$ ]]; then - bin/console user:password --user_id=$PHRASEANET_ADMIN_ACCOUNT_ID --password $PHRASEANET_ADMIN_ACCOUNT_PASSWORD -y + bin/console user:edit --user_id=$PHRASEANET_ADMIN_ACCOUNT_ID --login $PHRASEANET_ADMIN_ACCOUNT_EMAIL --email $PHRASEANET_ADMIN_ACCOUNT_EMAIL --password $PHRASEANET_ADMIN_ACCOUNT_PASSWORD -y + echo `date +"%Y-%m-%d %H:%M:%S"` " - Phraseanet Root account synced" fi echo `date +"%Y-%m-%d %H:%M:%S"` " - config/configuration.yml update by Phraseanet entrypoint.sh Finished !" @@ -234,7 +235,6 @@ chown -R app:app www echo `date +"%Y-%m-%d %H:%M:%S"` " - End of chown!" - echo `date +"%Y-%m-%d %H:%M:%S"` " - End of Phraseanet setup entrypoint.sh" if [[ $PHRASEANET_MAINTENANCE = 2 ]];then diff --git a/docker/phraseanet/setup/init-test-install.sh b/docker/phraseanet/setup/init-test-install.sh index 5f96ebc58ca..3bb0696794f 100755 --- a/docker/phraseanet/setup/init-test-install.sh +++ b/docker/phraseanet/setup/init-test-install.sh @@ -8,33 +8,21 @@ php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer composer install --ignore-platform-reqs --no-interaction - - -if [ -z "$PHRASEANET_ADMIN_ACCOUNT_EMAIL" ]; then - echo "PHRASEANET_ADMIN_ACCOUNT_EMAIL, Phraseanet admin account var is not set." - exit 1 -fi - -if [ -z "$PHRASEANET_ADMIN_ACCOUNT_PASSWORD " ]; then - echo "$PHRASEANET_ADMIN_ACCOUNT_PASSWORD, Phaseanet admin password var is not set." - exit 1 -fi - FILE=config/configuration.yml while [[ ! -e "$FILE" ]] do sleep 10 /var/alchemy/Phraseanet/bin/setup system:install \ - --email=$PHRASEANET_ADMIN_ACCOUNT_EMAIL \ - --password=$PHRASEANET_ADMIN_ACCOUNT_PASSWORD \ - --db-host=$PHRASEANET_DB_HOST \ - --db-port=$PHRASEANET_DB_PORT \ - --db-user=$PHRASEANET_DB_USER \ - --db-password=$PHRASEANET_DB_PASSWORD \ - --db-template=$INSTALL_DB_TEMPLATE \ - --appbox=$INSTALL_APPBOX \ - --databox=$INSTALL_DATABOX \ + --email=test@test.fr \ + --password=test \ + --db-host=db \ + --db-port=3306 \ + --db-user=root \ + --db-password=root \ + --db-template=DublinCore \ + --appbox=ab_master \ + --databox=db_databox1 \ --server-name=$PHRASEANET_BASE_URL \ --download-path=$PHRASEANET_DOWNLOAD_DIR \ --lazaret-path=$PHRASEANET_LAZARET_DIR \ diff --git a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php index fa48ca253eb..3987296e0c5 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/ToolsController.php @@ -92,7 +92,7 @@ public function indexAction(Request $request) } } - $availableSubdefName = []; + $availableSubdefLabel = []; $countSubdefTodo = []; /** @var record_adapter $rec */ @@ -101,11 +101,12 @@ public function indexAction(Request $request) if ($databoxSubdefs !== null) { foreach ($databoxSubdefs as $sub) { if ($sub->isTobuild()) { - $availableSubdefName[] = $sub->get_name(); - if (isset($countSubdefTodo[$sub->get_name()])) { - $countSubdefTodo[$sub->get_name()] ++; + $label = trim($sub->get_label($this->app['locale'])); + $availableSubdefLabel[] = $label; + if (isset($countSubdefTodo[$label])) { + $countSubdefTodo[$label] ++; } else { - $countSubdefTodo[$sub->get_name()] = 1; + $countSubdefTodo[$label] = 1; } } } @@ -118,7 +119,7 @@ public function indexAction(Request $request) 'recordSubdefs' => $recordAccessibleSubdefs, 'metadatas' => $metadatas, 'listsubdef' => $listsubdef, - 'availableSubdefName' => array_unique($availableSubdefName), + 'availableSubdefLabel' => array_unique($availableSubdefLabel), 'nbRecords' => count($records), 'countSubdefTodo' => $countSubdefTodo ]); @@ -167,10 +168,11 @@ public function imageAction(Request $request) $return = ['success' => true]; $force = $request->request->get('force_substitution') == '1'; - $subdefsName = $request->request->get('subdefs', []); + $subdefsLabel = $request->request->get('subdefsLabel', []); $selection = RecordsRequest::fromRequest($this->app, $request, false, [\ACL::CANMODIFRECORD]); + /** @var record_adapter $record */ foreach ($selection as $record) { $substituted = false; /** @var \media_subdef $subdef */ @@ -187,6 +189,18 @@ public function imageAction(Request $request) } if (!$substituted || $force) { + $subdefsName = []; + + // get subdefinition name from selected subdefinition label + $databoxSubdefs = $record->getDatabox()->get_subdef_structure()->getSubdefGroup($record->getType()); + if ($databoxSubdefs !== null) { + foreach ($databoxSubdefs as $sub) { + if (in_array(trim($sub->get_label($this->app['locale'])), $subdefsLabel)) { + $subdefsName[] = $sub->get_name(); + } + } + } + $this->dispatch(RecordEvents::SUBDEFINITION_CREATE, new SubdefinitionCreateEvent($record, false, $subdefsName)); } } diff --git a/lib/Alchemy/Phrasea/Controller/Root/RootController.php b/lib/Alchemy/Phrasea/Controller/Root/RootController.php index f842827b0fc..8a11b8b31db 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/RootController.php +++ b/lib/Alchemy/Phrasea/Controller/Root/RootController.php @@ -37,7 +37,7 @@ public function getRoot() public function setLocale($locale) { $response = $this->app->redirectPath('root'); - $response->headers->setCookie(new Cookie('locale', $locale)); + $response->headers->setCookie(new Cookie('locale', $locale, 0, '/', null, true, false)); $authenticatedUser = $this->getAuthenticatedUser(); diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/PhraseaLocaleSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/PhraseaLocaleSubscriber.php index 9eeea98feaa..42e84c52cb3 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/PhraseaLocaleSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/PhraseaLocaleSubscriber.php @@ -81,7 +81,7 @@ public function addLocaleCookie(FilterResponseEvent $event) $cookies = $event->getRequest()->cookies; if (isset($this->locale) && (false === $cookies->has('locale') || $cookies->get('locale') !== $this->locale)) { - $event->getResponse()->headers->setCookie(new Cookie('locale', $this->locale, 0, '/', null, false, false)); + $event->getResponse()->headers->setCookie(new Cookie('locale', $this->locale, 0, '/', null, true, false)); } } } diff --git a/lib/Alchemy/Phrasea/Core/Version.php b/lib/Alchemy/Phrasea/Core/Version.php index a6b486f4222..3137e0fde50 100644 --- a/lib/Alchemy/Phrasea/Core/Version.php +++ b/lib/Alchemy/Phrasea/Core/Version.php @@ -17,7 +17,7 @@ class Version * @var string */ - private $number = '4.1.8-rc2'; + private $number = '4.1.8-rc3'; /** * @var string diff --git a/lib/Alchemy/Phrasea/Helper/Prod.php b/lib/Alchemy/Phrasea/Helper/Prod.php index 2bf1fe089da..409c653d31d 100644 --- a/lib/Alchemy/Phrasea/Helper/Prod.php +++ b/lib/Alchemy/Phrasea/Helper/Prod.php @@ -97,7 +97,7 @@ public function get_search_datas() 'sbas' => array($sbasId), 'fieldname' => $name, 'type' => $type, - 'label' => ($name === $label) ? [$label] : [$name . ' - ' .trim($label)], // add the fieldname in the label + 'label' => ($name === $label) ? [] : [trim($label)], 'id' => $id ); @@ -108,7 +108,7 @@ public function get_search_datas() $dates[$name]['sbas'][] = $sbasId; // add different label for the same field if exist - if (!isset($dates[$name]['label']) || !in_array(strtolower($label), array_map('strtolower', $dates[$name]['label']))) { + if ($name !== $label && (!isset($dates[$name]['label']) || !in_array(strtolower($label), array_map('strtolower', $dates[$name]['label'])))) { $dates[$name]['label'][] = trim($label); } } @@ -126,7 +126,7 @@ public function get_search_datas() $fields[$name]['sbas'][] = $sbasId; // add different label for the same field if exist - if (!in_array(strtolower($label), array_map('strtolower', $fields[$name]['label']))) { + if ($name !== $label && (!in_array(strtolower($label), array_map('strtolower', $fields[$name]['label'])))) { $fields[$name]['label'][] = trim($label); } } else { diff --git a/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php b/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php index 05a5f384bad..446db161278 100644 --- a/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php +++ b/lib/Alchemy/Phrasea/Out/Module/PDFRecords.php @@ -285,7 +285,7 @@ protected function print_thumbnailGrid($links = false) ); } - $downloadLink = $rec->get_title(['encode'=> record_adapter::ENCODE_FOR_URI]); + $downloadLink = $rec->get_title(['encode'=> record_adapter::ENCODE_FOR_HTML]); if ($this->canDownload && !empty($this->downloadSubdef) && $rec->has_subdef($this->downloadSubdef) diff --git a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php index 601d0fe00ce..7dd9da004e1 100644 --- a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php +++ b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php @@ -62,7 +62,7 @@ public function getGlobals() { return [ // change this version when you change JS file to force the navigation to reload js file - 'assetFileVersion' => 87 + 'assetFileVersion' => 88 ]; } diff --git a/templates/web/prod/actions/Tools/index.html.twig b/templates/web/prod/actions/Tools/index.html.twig index e2615b60273..d4fa372ec0f 100644 --- a/templates/web/prod/actions/Tools/index.html.twig +++ b/templates/web/prod/actions/Tools/index.html.twig @@ -83,11 +83,11 @@ - {% for subdefName in availableSubdefName %} + {% for subdefLabel in availableSubdefLabel %}