diff --git a/composer.json b/composer.json index 922ed5e307..c47cc75503 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "cbschuld/browser.php": "^1.9.6", "phpoffice/phpspreadsheet": "^1.24 || ^2.1", - "pimcore/pimcore": "^11.3.0", + "pimcore/pimcore": "11.3.0-RC1", "symfony/webpack-encore-bundle": "^1.13.2" }, "require-dev": { diff --git a/public/js/pimcore/asset/helpers/grid.js b/public/js/pimcore/asset/helpers/grid.js index 30d5b8e736..9ba14089e2 100644 --- a/public/js/pimcore/asset/helpers/grid.js +++ b/public/js/pimcore/asset/helpers/grid.js @@ -230,7 +230,7 @@ pimcore.asset.helpers.grid = Class.create({ locked: this.getColumnLock(field), renderer: function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }); } else if (key == "filename") { diff --git a/public/js/pimcore/asset/helpers/gridConfigDialog.js b/public/js/pimcore/asset/helpers/gridConfigDialog.js index 1500a9f8b4..9e96f4b51a 100644 --- a/public/js/pimcore/asset/helpers/gridConfigDialog.js +++ b/public/js/pimcore/asset/helpers/gridConfigDialog.js @@ -365,7 +365,7 @@ pimcore.asset.helpers.gridConfigDialog = Class.create(pimcore.element.helpers.gr } else if ((key == "modificationDate" || key == "creationDate") && value) { var timestamp = intval(value) * 1000; var date = new Date(timestamp); - return Ext.Date.format(date, "Y-m-d H:i"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); } else { var fieldType = record.data.dataType; diff --git a/public/js/pimcore/asset/listfolder.js b/public/js/pimcore/asset/listfolder.js index d84de0aba5..6ef8cb948a 100644 --- a/public/js/pimcore/asset/listfolder.js +++ b/public/js/pimcore/asset/listfolder.js @@ -374,7 +374,7 @@ pimcore.asset.listfolder = Class.create(pimcore.asset.helpers.gridTabAbstract, { gridColumns.push({text: t(field.label), width: this.getColumnWidth(field, 150), sortable: true, dataIndex: field.key, editable: false, filter: 'date', renderer: function(d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }); } else if (key == "filename") { @@ -396,7 +396,7 @@ pimcore.asset.listfolder = Class.create(pimcore.asset.helpers.gridTabAbstract, { renderer: function(d) { if (d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } } diff --git a/public/js/pimcore/asset/metadata/tags/date.js b/public/js/pimcore/asset/metadata/tags/date.js index ad34e5bd1c..9d166fbdff 100644 --- a/public/js/pimcore/asset/metadata/tags/date.js +++ b/public/js/pimcore/asset/metadata/tags/date.js @@ -45,7 +45,7 @@ pimcore.asset.metadata.tags.date = Class.create(pimcore.asset.metadata.tags.abst var timestamp = intval(value) * 1000; var date = new Date(timestamp); - return Ext.Date.format(date, "Y-m-d"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } return ""; }.bind(this, field.key) @@ -63,7 +63,6 @@ pimcore.asset.metadata.tags.date = Class.create(pimcore.asset.metadata.tags.abst name:this.fieldConfig.name, componentCls:"object_field", width:130, - format: "Y-m-d" }; if (this.fieldConfig.labelWidth) { @@ -96,9 +95,7 @@ pimcore.asset.metadata.tags.date = Class.create(pimcore.asset.metadata.tags.abst }, getGridCellEditor: function (gridtype, record) { - return Ext.create('Ext.form.field.Date', { - format: "Y-m-d" - }); + return Ext.create('Ext.form.field.Date'); }, convertPredefinedGridData: function(v, r) { @@ -114,7 +111,7 @@ pimcore.asset.metadata.tags.date = Class.create(pimcore.asset.metadata.tags.abst if(!(value instanceof Date)) { value = new Date(value * 1000); } - return Ext.Date.format(value, "Y-m-d"); + return Ext.Date.format(value, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } return Ext.util.Format.htmlEncode(value); diff --git a/public/js/pimcore/asset/versions.js b/public/js/pimcore/asset/versions.js index d9a5fd8ee0..dfa74a0179 100644 --- a/public/js/pimcore/asset/versions.js +++ b/public/js/pimcore/asset/versions.js @@ -92,14 +92,14 @@ pimcore.asset.versions = Class.create({ return ""; }.bind(this), editable: false}, {text: t("date"), width:150, sortable: true, dataIndex: 'date', filter: 'date', renderer: function(d) { - return Ext.Date.format(d, "Y-m-d H:i:s"); + return Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }}, {text: "ID", sortable: true, dataIndex: 'id', editable: false, width: 60}, {text: t("user"), sortable: true, dataIndex: 'name', filter: 'list'}, {text: t("scheduled"), width:130, sortable: true, dataIndex: 'scheduled', renderer: function(d) { if (d != null){ var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, editable: false}, {text: t("note"), sortable: true, dataIndex: 'note', editor: new Ext.form.TextField(), filter: 'string', renderer: Ext.util.Format.htmlEncode} diff --git a/public/js/pimcore/document/editables/scheduledblock.js b/public/js/pimcore/document/editables/scheduledblock.js index 6114ae46bc..b5ebd70054 100644 --- a/public/js/pimcore/document/editables/scheduledblock.js +++ b/public/js/pimcore/document/editables/scheduledblock.js @@ -103,7 +103,7 @@ pimcore.document.editables.scheduledblock = Class.create(pimcore.document.editab var timestamp = new Date(element.date * 1000); jumpMenuEntries.push({ - text: Ext.Date.format(timestamp, 'Y-m-d H:i'), + text: Ext.Date.format(timestamp, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()), iconCls: 'pimcore_icon_time', handler: function(element, timestamp) { this.dateField.setValue(timestamp); diff --git a/public/js/pimcore/document/pages/preview.js b/public/js/pimcore/document/pages/preview.js index d3cc25acb2..bc06b86fd9 100644 --- a/public/js/pimcore/document/pages/preview.js +++ b/public/js/pimcore/document/pages/preview.js @@ -124,8 +124,8 @@ Ext.define('pimcore.document.pages.preview', { width: '100%', cls: 'pimcore_document_preview_timeslider', tipText: function(thumb){ - var date = new Date(thumb.value * 1000); - return Ext.Date.format(date, 'H:i'); + const date = new Date(thumb.value * 1000); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); }, listeners: { change: function(field, newValue, oldValue) { diff --git a/public/js/pimcore/document/settings_abstract.js b/public/js/pimcore/document/settings_abstract.js index b633c0efbf..232a010a5c 100644 --- a/public/js/pimcore/document/settings_abstract.js +++ b/public/js/pimcore/document/settings_abstract.js @@ -344,7 +344,7 @@ pimcore.document.settings_abstract = Class.create({ if (this.document.data.staticLastGenerated) { const date = new Date(this.document.data.staticLastGenerated * 1000); - lastGenerated = Ext.Date.format(date, "Y-m-d H:i"); + lastGenerated = Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); }else{ lastGenerated = t('never'); } diff --git a/public/js/pimcore/document/versions.js b/public/js/pimcore/document/versions.js index 3c19ceac88..6008fb3be1 100644 --- a/public/js/pimcore/document/versions.js +++ b/public/js/pimcore/document/versions.js @@ -125,7 +125,7 @@ pimcore.document.versions = Class.create({ }, { text: t("date"), width: 150, sortable: true, dataIndex: 'date', filter: 'date', renderer: function (d) { - return Ext.Date.format(d, "Y-m-d H:i:s"); + return Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }, editable: false }, {text: "ID", sortable: true, dataIndex: 'id', editable: false, width: 60}, @@ -138,7 +138,7 @@ pimcore.document.versions = Class.create({ renderer: function (d) { if (d != null) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } return d; }, diff --git a/public/js/pimcore/element/helpers/gridColumnConfig.js b/public/js/pimcore/element/helpers/gridColumnConfig.js index dc8b0018fc..5a45f106d8 100644 --- a/public/js/pimcore/element/helpers/gridColumnConfig.js +++ b/public/js/pimcore/element/helpers/gridColumnConfig.js @@ -237,7 +237,7 @@ pimcore.element.helpers.gridColumnConfig = { var value = filterData[i].getValue(); if (value instanceof Date) { - value = Ext.Date.format(value, "Y-m-d"); + value = Ext.Date.format(value, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } if (value && typeof value == "object") { diff --git a/public/js/pimcore/element/note_details.js b/public/js/pimcore/element/note_details.js index af9944ef54..59055c2511 100644 --- a/public/js/pimcore/element/note_details.js +++ b/public/js/pimcore/element/note_details.js @@ -124,7 +124,7 @@ pimcore.element.note_details = Class.create({ xtype: "textfield", fieldLabel: t('date'), readOnly: true, - value: Ext.Date.format(date, "Y-m-d H:i:s") + value: Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()) } ); diff --git a/public/js/pimcore/element/notes.js b/public/js/pimcore/element/notes.js index ce6aec4403..872d118cfe 100644 --- a/public/js/pimcore/element/notes.js +++ b/public/js/pimcore/element/notes.js @@ -139,7 +139,7 @@ pimcore.element.notes = Class.create({ }}, {text: t("date"), sortable: true, dataIndex: 'date', flex: 100, filter: 'date', renderer: function(d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }} ]; @@ -291,7 +291,7 @@ pimcore.element.notes = Class.create({ } else if (record.get("type") == "date") { if(value) { var date = new Date(value * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } } diff --git a/public/js/pimcore/element/scheduler.js b/public/js/pimcore/element/scheduler.js index da9562feb1..d600f73d58 100644 --- a/public/js/pimcore/element/scheduler.js +++ b/public/js/pimcore/element/scheduler.js @@ -43,7 +43,7 @@ pimcore.element.scheduler = Class.create({ td = [ rawTask.id, d, - Ext.Date.format(d, "H:i"), + Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()), rawTask.action ]; @@ -63,7 +63,7 @@ pimcore.element.scheduler = Class.create({ convert: function (v, rec) { var ret = v; if (v instanceof Date) { - ret = Ext.Date.format(v, "Y-m-d"); + ret = Ext.Date.format(v, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } return ret; } @@ -73,7 +73,7 @@ pimcore.element.scheduler = Class.create({ convert: function (v, rec) { var ret = v; if (v instanceof Date) { - ret = Ext.Date.format(v, "H:i"); + ret = Ext.Date.format(v, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); } return ret; } @@ -112,7 +112,7 @@ pimcore.element.scheduler = Class.create({ fields: ['id', {name: 'date', convert: function (v, rec) { var d = new Date(intval(v) * 1000); - var ret = Ext.Date.format(d, "Y-m-d H:i"); + var ret = Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); if (rec.data.note) { ret += " - " + rec.data.note; @@ -141,12 +141,9 @@ pimcore.element.scheduler = Class.create({ }); var propertiesColumns = [ - {text: t("date"), width: 120, sortable: true, dataIndex: 'date', editor: new Ext.form.DateField({ - format: "Y-m-d" - }) + {text: t("date"), width: 120, sortable: true, dataIndex: 'date', editor: new Ext.form.DateField() }, {text: t("time"), width: 100, sortable: true, dataIndex: 'time', editor: new Ext.form.TimeField({ - format: "H:i", listeners: { focus : function(component) { component.setValue(Ext.util.Format.htmlDecode(component.value)); diff --git a/public/js/pimcore/layout/portlets/modifiedAssets.js b/public/js/pimcore/layout/portlets/modifiedAssets.js index 503d776880..029d94669e 100644 --- a/public/js/pimcore/layout/portlets/modifiedAssets.js +++ b/public/js/pimcore/layout/portlets/modifiedAssets.js @@ -52,7 +52,7 @@ pimcore.layout.portlets.modifiedAssets = Class.create(pimcore.layout.portlets.ab {text: t('path'), sortable: false, dataIndex: 'path', flex: 1}, {text: t('date'), width: 150, sortable: false, renderer: function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date,"Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }, dataIndex: 'date'} ], stripeRows: true, diff --git a/public/js/pimcore/layout/portlets/modifiedDocuments.js b/public/js/pimcore/layout/portlets/modifiedDocuments.js index c858115e46..3504635a66 100644 --- a/public/js/pimcore/layout/portlets/modifiedDocuments.js +++ b/public/js/pimcore/layout/portlets/modifiedDocuments.js @@ -52,7 +52,7 @@ pimcore.layout.portlets.modifiedDocuments = Class.create(pimcore.layout.portlets {text: t('path'), sortable: false, dataIndex: 'path', flex: 1}, {text: t('date'), width: 150, sortable: false, renderer: function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date,"Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }, dataIndex: 'date'} ], diff --git a/public/js/pimcore/layout/portlets/modifiedObjects.js b/public/js/pimcore/layout/portlets/modifiedObjects.js index 07d47df6d8..0ee6c9649d 100644 --- a/public/js/pimcore/layout/portlets/modifiedObjects.js +++ b/public/js/pimcore/layout/portlets/modifiedObjects.js @@ -53,7 +53,7 @@ pimcore.layout.portlets.modifiedObjects = Class.create(pimcore.layout.portlets.a {text: t('path'), sortable: false, dataIndex: 'path', flex: 1}, {text: t('date'), width: 150, sortable: false, renderer: function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date,"Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }, dataIndex: 'date'} ], diff --git a/public/js/pimcore/localeDateTime.js b/public/js/pimcore/localeDateTime.js new file mode 100644 index 0000000000..c681e5dc57 --- /dev/null +++ b/public/js/pimcore/localeDateTime.js @@ -0,0 +1,154 @@ +/** + * Pimcore + * + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) + * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. + * + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL + */ + +pimcore.registerNS("pimcore.localeDateTime"); + +pimcore.localeDateTime = { + shortDate: 'Y-m-d', + shortTime: 'H:i', // Short time is without seconds + mediumTime: 'H:i:s', + systemShortDate: 'Y-m-d', + systemShortTime: 'H:i', + systemMediumTime: 'H:i:s', + + getShortDateFormat: function () { + return this.shortDate; + }, + getShortTimeFormat: function () { + return this.shortTime; + }, + getMediumTimeFormat: function () { + return this.mediumTime; + }, + getShortDateTimeFormat: function () { + return this.shortDate + ' ' + this.shortTime; + }, + getDateTimeFormat: function () { + return this.shortDate + ' ' + this.mediumTime; + }, + + // Set the default date and time format based on the given locale and override forms/fields globally + setDefaultDateTime: function (locale) { + if (locale) { + this.shortDate = this.convertDateFormatFromIntl(locale); + this.shortTime = this.convertTimeFroamtFromIntl(locale, 'short'); + this.mediumTime = this.convertTimeFroamtFromIntl(locale, 'medium'); + } + + if (Ext.util && Ext.util.Format) { + Ext.apply(Ext.util.Format, { + dateFormat: this.getShortDateFormat() + }) + } + Ext.override(Ext.form.field.Date, { + format: this.getShortDateFormat(), + }); + + Ext.override(Ext.grid.column.Date, { + format: this.getShortDateFormat(), + }); + + Ext.override(Ext.form.field.Time, { + format: this.getShortTimeFormat(), + }); + }, + + // Returns the EXT JS date format equivalent based on the localized date by Intl.DateTimeFormat + // It checks wheter it is leading zero or 4 digits years by guessing it by checking the output of a dummy date + convertDateFormatFromIntl: function (locale) { + const dateFormatter = new Intl.DateTimeFormat(locale, {dateStyle: "short"}); + const localizedDate = dateFormatter.format(new Date('2021-06-03')); + let dayFormat = 'j'; //no leading zero + let monthFormat = 'n'; //no leading zero + let yearFormat = 'y'; // 2 digits year + + if (localizedDate.includes('2021')) { + yearFormat = 'Y'; + } + if (localizedDate.includes('03')) { + dayFormat = 'd'; + } + if (localizedDate.includes('06')) { + monthFormat = 'm'; + } + + const getPatternForPart = (part) => { + switch (part.type) { + case 'day': + return dayFormat; + case 'month': + return monthFormat; + case 'year': + return yearFormat; + case 'literal': + return part.value; + default: + console.log('Unsupported date part', part); + return ''; + } + }; + return dateFormatter.formatToParts() + .map(getPatternForPart) + .join(''); + }, + + // Returns the EXT JS time format equivalent based on the localized date by Intl.DateTimeFormat + // It checks wheter it is 0-12 AM/PM, 0-23. Minutes and seconds are internationally with a leading zero as 00-59. + convertTimeFroamtFromIntl: function (locale, timeStyle) { + const dummyDate = new Date('2020-01-01 09:30:59'); + const dateFormatter = new Intl.DateTimeFormat(locale, {timeStyle: timeStyle}); + const localizedDateTime = dateFormatter.format(dummyDate); + + let dayPeriodFormat = ''; + if (localizedDateTime.includes('am') || localizedDateTime.includes('a.m.')) { //lowecased eg. am/pm + dayPeriodFormat = 'a'; + } else if (localizedDateTime.includes('AM') || localizedDateTime.includes('A.M.')) { + dayPeriodFormat = 'A'; + } + + let hourFormat = ''; + if (localizedDateTime.includes('09')) { + hourFormat = 'H'; + if (dayPeriodFormat) { + hourFormat = 'h'; + } + } else if (localizedDateTime.includes('9')) { + hourFormat = 'G'; + if (dayPeriodFormat) { + hourFormat = 'g'; + } + } + + const getPatternForPart = (part) => { + switch (part.type) { + case 'hour': + return hourFormat; + case 'minute': + return 'i'; + case 'second': + return 's'; + case 'dayPeriod': + return dayPeriodFormat; + case 'literal': + return part.value; + default: + console.log('Unsupported date part', part); + return ''; + } + }; + + return dateFormatter.formatToParts() + .map(getPatternForPart) + .join(''); + } +}; diff --git a/public/js/pimcore/notification/panel.js b/public/js/pimcore/notification/panel.js index 2c109715ab..b85d5bfb8b 100644 --- a/public/js/pimcore/notification/panel.js +++ b/public/js/pimcore/notification/panel.js @@ -94,7 +94,7 @@ pimcore.notification.panel = Class.create({ { header: t("date"), flex: 3, sortable: true, filter: 'date', dataIndex: 'timestamp', renderer: function(d) { - return Ext.Date.format(new Date(d*1000), "Y-m-d H:i:s"); + return Ext.Date.format(new Date(d*1000), pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, { diff --git a/public/js/pimcore/object/classes/data/datetime.js b/public/js/pimcore/object/classes/data/datetime.js index 90ce0bb482..ca6e61b107 100644 --- a/public/js/pimcore/object/classes/data/datetime.js +++ b/public/js/pimcore/object/classes/data/datetime.js @@ -98,7 +98,7 @@ pimcore.object.classes.data.datetime = Class.create(pimcore.object.classes.data. } date.value = tmpDate; - time.value = Ext.Date.format(tmpDate, "H:i"); + time.value = Ext.Date.format(tmpDate, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); } var datefield = new Ext.form.DateField(date); @@ -195,10 +195,10 @@ pimcore.object.classes.data.datetime = Class.create(pimcore.object.classes.data. setDefaultValue:function (defaultValue, datefield, timefield) { if (datefield.getValue() && typeof datefield.getValue() === 'object') { - var dateString = Ext.Date.format(datefield.getValue(), "Y-m-d"); + var dateString = Ext.Date.format(datefield.getValue(), pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); if (timefield.getValue()) { - dateString += " " + Ext.Date.format(timefield.getValue(), "H:i"); + dateString += " " + Ext.Date.format(timefield.getValue(), pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); } else { dateString += " 00:00"; } diff --git a/public/js/pimcore/object/classificationstore/collectionsPanel.js b/public/js/pimcore/object/classificationstore/collectionsPanel.js index c27504cc83..93230d398d 100644 --- a/public/js/pimcore/object/classificationstore/collectionsPanel.js +++ b/public/js/pimcore/object/classificationstore/collectionsPanel.js @@ -281,7 +281,7 @@ pimcore.object.classificationstore.collectionsPanel = Class.create({ var dateRenderer = function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/object/classificationstore/groupsPanel.js b/public/js/pimcore/object/classificationstore/groupsPanel.js index 5a28d8c267..a6890076ef 100644 --- a/public/js/pimcore/object/classificationstore/groupsPanel.js +++ b/public/js/pimcore/object/classificationstore/groupsPanel.js @@ -289,7 +289,7 @@ pimcore.object.classificationstore.groupsPanel = Class.create({ var dateRenderer = function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/object/classificationstore/propertiesPanel.js b/public/js/pimcore/object/classificationstore/propertiesPanel.js index 10a49af795..4ae74e1552 100644 --- a/public/js/pimcore/object/classificationstore/propertiesPanel.js +++ b/public/js/pimcore/object/classificationstore/propertiesPanel.js @@ -168,7 +168,7 @@ pimcore.object.classificationstore.propertiespanel = Class.create({ var dateRenderer = function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/object/helpers/grid.js b/public/js/pimcore/object/helpers/grid.js index d5919330ba..3731518d0b 100644 --- a/public/js/pimcore/object/helpers/grid.js +++ b/public/js/pimcore/object/helpers/grid.js @@ -336,13 +336,13 @@ pimcore.object.helpers.grid = Class.create({ } else if(field.key == "creationDate") { gridColumns.push({text: t("creationdate") + " (System)", width: this.getColumnWidth(field, 160), sortable: true, dataIndex: "creationDate", filter: 'date', editable: false, locked: this.getColumnLock(field), renderer: function(d) { - return Ext.Date.format(d, "Y-m-d H:i:s"); + return Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }/*, hidden: !propertyVisibility.creationDate*/}); } else if(field.key == "modificationDate") { gridColumns.push({text: t("modificationdate") + " (System)", width: this.getColumnWidth(field, 160), sortable: true, dataIndex: "modificationDate", filter: 'date', editable: false, locked: this.getColumnLock(field), renderer: function(d) { - return Ext.Date.format(d, "Y-m-d H:i:s"); + return Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }/*, hidden: !propertyVisibility.modificationDate*/}); } else { if (fields[i].isOperator) { diff --git a/public/js/pimcore/object/helpers/gridConfigDialog.js b/public/js/pimcore/object/helpers/gridConfigDialog.js index 06ee1008db..e30c9486bc 100644 --- a/public/js/pimcore/object/helpers/gridConfigDialog.js +++ b/public/js/pimcore/object/helpers/gridConfigDialog.js @@ -299,7 +299,7 @@ pimcore.object.helpers.gridConfigDialog = Class.create(pimcore.element.helpers.g if (key == "modificationDate" || key == "creationDate") { var timestamp = intval(value) * 1000; var date = new Date(timestamp); - return Ext.Date.format(date, "Y-m-d H:i"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); } else if (key == "published") { return Ext.String.format('
', value ? '-checked' : ''); diff --git a/public/js/pimcore/object/tags/calculatedValue.js b/public/js/pimcore/object/tags/calculatedValue.js index 152102b1dd..e9ab14917e 100644 --- a/public/js/pimcore/object/tags/calculatedValue.js +++ b/public/js/pimcore/object/tags/calculatedValue.js @@ -110,7 +110,7 @@ pimcore.object.tags.calculatedValue = Class.create(pimcore.object.tags.abstract, if (!isNaN(+value)) { const timestamp = parseInt(value) * 1000; const date = new Date(timestamp); - return Ext.Date.format(date, "Y-m-d"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } } else if (this.fieldConfig?.elementType === 'boolean') { if (this.fieldConfig.calculatorType !== "expression") { diff --git a/public/js/pimcore/object/tags/date.js b/public/js/pimcore/object/tags/date.js index 71292130e4..a690560532 100644 --- a/public/js/pimcore/object/tags/date.js +++ b/public/js/pimcore/object/tags/date.js @@ -62,7 +62,7 @@ pimcore.object.tags.date = Class.create(pimcore.object.tags.abstract, { } } - return Ext.Date.format(date, "Y-m-d"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); } return ""; }.bind(this, field.key)}; @@ -79,7 +79,6 @@ pimcore.object.tags.date = Class.create(pimcore.object.tags.abstract, { name:this.fieldConfig.name, componentCls: this.getWrapperClassNames(), width:130, - format: "Y-m-d" }; if (this.fieldConfig.labelWidth) { diff --git a/public/js/pimcore/object/tags/dateRange.js b/public/js/pimcore/object/tags/dateRange.js index 537f68e0fe..32951eeeab 100644 --- a/public/js/pimcore/object/tags/dateRange.js +++ b/public/js/pimcore/object/tags/dateRange.js @@ -28,8 +28,8 @@ pimcore.object.tags.dateRange = Class.create(pimcore.object.tags.abstract, { }, getLayoutEdit: function () { - const startDateConfig = { format: 'Y-m-d' }; - const endDateConfig = { format: 'Y-m-d' }; + const startDateConfig = {}; + const endDateConfig = {}; if (this.data && 'start_date' in this.data) { startDateConfig.value = new Date(intval(this.data['start_date']) * 1000); @@ -106,7 +106,7 @@ pimcore.object.tags.dateRange = Class.create(pimcore.object.tags.abstract, { const minDate = new Date(intval(value['start_date'] || 0) * 1000); const maxDate = new Date(intval(value['end_date'] || 0) * 1000); - return `${Ext.Date.format(minDate, 'Y-m-d')}, ${Ext.Date.format(maxDate, 'Y-m-d')}`; + return `${Ext.Date.format(minDate, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()), Ext.Date.format(maxDate, pimcore.globalmanager.get('localeDateTime').getShortDateFormat())}`; } return ''; diff --git a/public/js/pimcore/object/tags/datetime.js b/public/js/pimcore/object/tags/datetime.js index 1bfe381006..ec3f8eb1b9 100644 --- a/public/js/pimcore/object/tags/datetime.js +++ b/public/js/pimcore/object/tags/datetime.js @@ -62,8 +62,7 @@ pimcore.object.tags.datetime = Class.create(pimcore.object.tags.abstract, { date = dateToServerTimezone(date); } } - - return Ext.Date.format(date, "Y-m-d H:i"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); } return ""; }.bind(this, field.key)}; @@ -77,7 +76,6 @@ pimcore.object.tags.datetime = Class.create(pimcore.object.tags.abstract, { var date = { width:130, - format: "Y-m-d" }; var time = { @@ -139,7 +137,7 @@ pimcore.object.tags.datetime = Class.create(pimcore.object.tags.abstract, { if (this.datefield.getValue()) { var value = this.datefield.getValue(); - var dateString = Ext.Date.format(value, "Y-m-d"); + var dateString = Ext.Date.format(value, pimcore.globalmanager.get('localeDateTime').getShortDateFormat()); if (this.timefield.getValue()) { var timeValue = this.timefield.getValue(); @@ -150,7 +148,7 @@ pimcore.object.tags.datetime = Class.create(pimcore.object.tags.abstract, { dateString += " 00:00"; } - value = Ext.Date.parseDate(dateString, "Y-m-d H:i"); + value = Ext.Date.parseDate(dateString, pimcore.globalmanager.get('localeDateTime').getShortDateTimeFormat()); if (value && this.fieldConfig.columnType === "datetime" && !this.isRespectTimezone()) { return dateString; diff --git a/public/js/pimcore/object/tags/time.js b/public/js/pimcore/object/tags/time.js index 3492efd15e..aaa7ee1101 100644 --- a/public/js/pimcore/object/tags/time.js +++ b/public/js/pimcore/object/tags/time.js @@ -64,8 +64,8 @@ pimcore.object.tags.time = Class.create(pimcore.object.tags.abstract, { }, getValue: function () { - var date = this.component.getValue(); - return Ext.Date.format(date, "H:i"); + const date = this.component.getValue(); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); }, getName: function () { diff --git a/public/js/pimcore/object/versions.js b/public/js/pimcore/object/versions.js index eed24bcd69..c037687518 100644 --- a/public/js/pimcore/object/versions.js +++ b/public/js/pimcore/object/versions.js @@ -104,7 +104,8 @@ pimcore.object.versions = Class.create({ }, { text: t("date"), width: 150, sortable: true, dataIndex: 'date', filter: 'date', renderer: function (d) { - return Ext.Date.format(d, "Y-m-d H:i:s"); + console.log(pimcore.globalmanager.get('localeDateTime')); + return Ext.Date.format(d, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, {text: "ID", sortable: true, dataIndex: 'id', editable: false, width: 60}, @@ -117,7 +118,7 @@ pimcore.object.versions = Class.create({ renderer: function (d) { if (d != null) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, editable: false diff --git a/public/js/pimcore/settings/docTypes.js b/public/js/pimcore/settings/docTypes.js index 0673a99a6c..23af0513c2 100644 --- a/public/js/pimcore/settings/docTypes.js +++ b/public/js/pimcore/settings/docTypes.js @@ -195,7 +195,7 @@ pimcore.settings.document.doctypes = Class.create({ renderer: function (d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } @@ -211,7 +211,7 @@ pimcore.settings.document.doctypes = Class.create({ renderer: function (d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/settings/email/blocklist.js b/public/js/pimcore/settings/email/blocklist.js index 6ee725dc8c..ebd78409f0 100644 --- a/public/js/pimcore/settings/email/blocklist.js +++ b/public/js/pimcore/settings/email/blocklist.js @@ -98,7 +98,7 @@ pimcore.settings.email.blocklist = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } @@ -110,7 +110,7 @@ pimcore.settings.email.blocklist = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/settings/email/log.js b/public/js/pimcore/settings/email/log.js index 220695ec71..985f0bd0fc 100644 --- a/public/js/pimcore/settings/email/log.js +++ b/public/js/pimcore/settings/email/log.js @@ -111,8 +111,8 @@ pimcore.settings.email.log = Class.create({ flex: false, sortable: false, renderer: function (d) { - var date = new Date(intval(d) * 1000); - return Ext.Date.format(date, 'Y-m-d H:i:s'); + const date = new Date(intval(d) * 1000); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, { diff --git a/public/js/pimcore/settings/gdpr/dataproviders/sentMail.js b/public/js/pimcore/settings/gdpr/dataproviders/sentMail.js index ddd571e527..b7b0e94b63 100644 --- a/public/js/pimcore/settings/gdpr/dataproviders/sentMail.js +++ b/public/js/pimcore/settings/gdpr/dataproviders/sentMail.js @@ -68,7 +68,7 @@ pimcore.settings.gdpr.dataproviders.sentMail = Class.create({ sortable: false, renderer: function (d) { var date = new Date(intval(d) * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } }, { diff --git a/public/js/pimcore/settings/metadata/predefined.js b/public/js/pimcore/settings/metadata/predefined.js index d8559749f5..b4741dd0b5 100644 --- a/public/js/pimcore/settings/metadata/predefined.js +++ b/public/js/pimcore/settings/metadata/predefined.js @@ -230,7 +230,7 @@ pimcore.settings.metadata.predefined = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return date.format("Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } return ""; } @@ -240,7 +240,7 @@ pimcore.settings.metadata.predefined = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return date.format("Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } return ""; } diff --git a/public/js/pimcore/settings/profile/panel.js b/public/js/pimcore/settings/profile/panel.js index fa240f7734..f2ec39ad6e 100644 --- a/public/js/pimcore/settings/profile/panel.js +++ b/public/js/pimcore/settings/profile/panel.js @@ -55,6 +55,7 @@ pimcore.settings.profile.panel = Class.create({ getEditPanel: function () { this.forceReloadOnSave = false; this.currentUser = pimcore.currentuser; + console.log(pimcore.currentuser); var passwordCheck = function (el) { if (pimcore.helpers.isValidPassword(el.getValue())) { @@ -119,6 +120,43 @@ pimcore.settings.profile.panel = Class.create({ } }); + const validLocales = [ + ['', '(system)'] + ]; + const allLocales = this.currentUser.validLocales ?? []; + // Rely on supportedLocalesOf to exclude any non-supported locales + Intl.DateTimeFormat.supportedLocalesOf(Object.keys(allLocales), {localeMatcher: "lookup"}).forEach(function (locale) { + validLocales.push([locale, allLocales[locale]]) + }); + + const localesStore = new Ext.data.ArrayStore({ + fields: ['code', 'text'], + data : validLocales + }); + + baseItems.push({ + xtype: 'combo', + fieldLabel: t('datetime_locale'), + typeAhead: true, + queryMode: 'local', + value: this.currentUser.datetimeLocale ?? '', + listWidth: 400, + store: localesStore, + displayField: 'text', + valueField: 'code', + forceSelection: true, + triggerAction: 'all', + name: 'datetimeLocale', + listeners: { + change: function () { + this.forceReloadOnSave = true; + }.bind(this), + select: function () { + this.forceReloadOnSave = true; + }.bind(this) + } + }); + baseItems.push({ xtype: "checkbox", boxLabel: t("show_welcome_screen"), diff --git a/public/js/pimcore/settings/properties/predefined.js b/public/js/pimcore/settings/properties/predefined.js index 26cdcd511c..44b6166d82 100644 --- a/public/js/pimcore/settings/properties/predefined.js +++ b/public/js/pimcore/settings/properties/predefined.js @@ -240,7 +240,7 @@ pimcore.settings.properties.predefined = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } @@ -255,7 +255,7 @@ pimcore.settings.properties.predefined = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } diff --git a/public/js/pimcore/settings/recyclebin.js b/public/js/pimcore/settings/recyclebin.js index 818b0b2a55..8b2525b641 100644 --- a/public/js/pimcore/settings/recyclebin.js +++ b/public/js/pimcore/settings/recyclebin.js @@ -111,7 +111,7 @@ pimcore.settings.recyclebin = Class.create({ text: t("date"), flex: 140, sortable: true, dataIndex: 'date', renderer: function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }, filter: 'date' diff --git a/public/js/pimcore/settings/translation.js b/public/js/pimcore/settings/translation.js index eee7f594e3..25ff61657b 100644 --- a/public/js/pimcore/settings/translation.js +++ b/public/js/pimcore/settings/translation.js @@ -299,7 +299,7 @@ pimcore.settings.translation.domain = Class.create({ var dateRenderer = function (d) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); }; typesColumns.push({ diff --git a/public/js/pimcore/settings/user/user/settings.js b/public/js/pimcore/settings/user/user/settings.js index 6acd9bd8bf..7f73ccc135 100644 --- a/public/js/pimcore/settings/user/user/settings.js +++ b/public/js/pimcore/settings/user/user/settings.js @@ -282,8 +282,8 @@ pimcore.settings.user.user.settings = Class.create({ xtype: 'combo', fieldLabel: t('language'), typeAhead: true, + queryMode: 'local', value: this.currentUser.language, - mode: 'local', listWidth: 100, store: pimcore.globalmanager.get("pimcorelanguages"), displayField: 'display', @@ -301,6 +301,43 @@ pimcore.settings.user.user.settings = Class.create({ } }); + const validLocales = [ + ['', '(system)'] + ]; + const allLocales = this.data.validLocales ?? []; + // Rely on supportedLocalesOf to exclude any non-supported locales + Intl.DateTimeFormat.supportedLocalesOf(Object.keys(allLocales), {localeMatcher: "lookup"}).forEach(function (locale) { + validLocales.push([locale, allLocales[locale]]) + }); + + const localesStore = new Ext.data.ArrayStore({ + fields: ['code', 'text'], + data : validLocales + }); + + generalItems.push({ + xtype: 'combo', + fieldLabel: t('datetime_locale'), + typeAhead: true, + queryMode: 'local', + value: this.currentUser.datetimeLocale ?? '', + listWidth: 400, + store: localesStore, + displayField: 'text', + valueField: 'code', + forceSelection: true, + triggerAction: 'all', + name: 'datetimeLocale', + listeners: { + change: function () { + this.forceReloadOnSave = true; + }.bind(this), + select: function () { + this.forceReloadOnSave = true; + }.bind(this) + } + }); + var rolesStore = Ext.create('Ext.data.ArrayStore', { fields: ["id", "name"], data: this.data.roles diff --git a/public/js/pimcore/settings/website.js b/public/js/pimcore/settings/website.js index a8c2a5d66c..21b451c4e3 100644 --- a/public/js/pimcore/settings/website.js +++ b/public/js/pimcore/settings/website.js @@ -167,7 +167,7 @@ pimcore.settings.website = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } @@ -182,7 +182,7 @@ pimcore.settings.website = Class.create({ renderer: function(d) { if (d !== undefined) { var date = new Date(d * 1000); - return Ext.Date.format(date, "Y-m-d H:i:s"); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getDateTimeFormat()); } else { return ""; } @@ -400,9 +400,7 @@ pimcore.settings.website = Class.create({ value: data.data } } else if (type == "date") { - property = Ext.create('Ext.form.field.Date', { - format: "Y-m-d" - }); + property = Ext.create('Ext.form.field.Date'); } else if (type == "checkbox" || type == "bool") { property = { xtype: 'checkbox', diff --git a/public/js/pimcore/startup.js b/public/js/pimcore/startup.js index 3f3e45d662..87e2107629 100644 --- a/public/js/pimcore/startup.js +++ b/public/js/pimcore/startup.js @@ -301,9 +301,14 @@ Ext.onReady(function () { } }); - var user = new pimcore.user(pimcore.currentuser); + let user = new pimcore.user(pimcore.currentuser); pimcore.globalmanager.add("user", user); + // set the default date time format according to user locale settings + let localeDateTime = pimcore.localeDateTime; + pimcore.globalmanager.add("localeDateTime", localeDateTime); + localeDateTime.setDefaultDateTime(user.datetimeLocale); + // document types Ext.define('pimcore.model.doctypes', { extend: 'Ext.data.Model', diff --git a/public/js/pimcore/tool/milestoneslider.js b/public/js/pimcore/tool/milestoneslider.js index affe3c12ab..9db86eb62d 100644 --- a/public/js/pimcore/tool/milestoneslider.js +++ b/public/js/pimcore/tool/milestoneslider.js @@ -16,7 +16,7 @@ Ext.define('Ext.pimcore.slider.Milestone', { this.useTips = true; this.tipText = function(thumb){ var date = new Date(thumb.value * 1000); - return Ext.Date.format(date, 'H:i'); + return Ext.Date.format(date, pimcore.globalmanager.get('localeDateTime').getShortTimeFormat()); }; this.callParent(); diff --git a/src/Controller/Admin/UserController.php b/src/Controller/Admin/UserController.php index ed981498a2..04148f6531 100644 --- a/src/Controller/Admin/UserController.php +++ b/src/Controller/Admin/UserController.php @@ -464,6 +464,7 @@ public function getAction(Request $request): JsonResponse 'availablePermissions' => $availableUserPermissionsData, 'availablePerspectives' => $availablePerspectives, 'validLanguages' => Tool::getValidLanguages(), + 'validLocales' => Tool::getSupportedJSLocales(), 'objectDependencies' => [ 'hasHidden' => $hasHidden, 'dependencies' => $userObjectData, @@ -629,6 +630,8 @@ public function getCurrentUserAction(Request $request): Response return $adminSession->get('password_reset'); }); + $userData['validLocales'] = Tool::getSupportedJSLocales(); + $response = new Response('pimcore.currentuser = ' . $this->encodeJson($userData)); $response->headers->set('Content-Type', 'text/javascript'); diff --git a/templates/admin/index/index.html.twig b/templates/admin/index/index.html.twig index 9f5e47160d..c791d0ec1f 100644 --- a/templates/admin/index/index.html.twig +++ b/templates/admin/index/index.html.twig @@ -224,6 +224,7 @@ "pimcore/perspective.js", "pimcore/user.js", + "pimcore/localeDateTime.js", "pimcore/tool/paralleljobs.js", "pimcore/tool/genericiframewindow.js", diff --git a/translations/admin.en.yaml b/translations/admin.en.yaml index 79ca726d42..95b613b035 100644 --- a/translations/admin.en.yaml +++ b/translations/admin.en.yaml @@ -22,6 +22,7 @@ creationdate: 'Creation Date' usermodification: 'User Modification' userowner: Owner languages: Languages +datetime_locale: Date Time Locale password_was_not_changed: "Password wasn't changed because it isn't secure enough" password_does_not_match: "New password and confirm password doesn't match" incorrect_password: "Given password is incorrect"