From 4d3259ef0ffc7e7b2a9f8447d3ee990186b07923 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:30:41 +0100 Subject: [PATCH 01/17] Add method for lbl with parameters --- src/Frontend/Core/Language/Language.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Frontend/Core/Language/Language.php b/src/Frontend/Core/Language/Language.php index 7571bac630..3bb7fb1bc9 100644 --- a/src/Frontend/Core/Language/Language.php +++ b/src/Frontend/Core/Language/Language.php @@ -402,4 +402,24 @@ public static function msg(string $key, bool $fallback = true): string { return self::getMessage($key, $fallback); } + + /** + * Get a label with parameters + * + * @param string $key + * @param array $parameters + * @param bool $fallback + * + * @return string + */ + public static function lblWithParameters(string $key, array $parameters = [], bool $fallback = true): string + { + $label = self::getLabel($key, $fallback); + + if ($parameters === []) { + return $label; + } + + return vsprintf($label, $parameters); + } } From 8bd6b3c6e28b548544c81e67bf814afc1c5aa62c Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:32:34 +0100 Subject: [PATCH 02/17] Use IntlDateFormatter instead of spoon date --- src/Backend/Core/Engine/TemplateModifiers.php | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/Backend/Core/Engine/TemplateModifiers.php b/src/Backend/Core/Engine/TemplateModifiers.php index 1ef0510fe1..eb4439a4e5 100644 --- a/src/Backend/Core/Engine/TemplateModifiers.php +++ b/src/Backend/Core/Engine/TemplateModifiers.php @@ -5,7 +5,7 @@ use Backend\Core\Engine\Model as BackendModel; use Common\Core\Twig\Extensions\BaseTwigModifiers; use Backend\Core\Language\Language as BackendLanguage; -use SpoonDate; +use IntlDateFormatter; use function Symfony\Component\String\s; /** @@ -23,15 +23,20 @@ class TemplateModifiers extends BaseTwigModifiers */ public static function formatDate($var): string { - // get setting - $format = Authentication::getUser()->getSetting('date_format'); - if ($var instanceof \DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, BackendLanguage::getInterfaceLanguage()); + $date = new IntlDateFormatter( + BackendLanguage::getInterfaceLanguage(), + IntlDateFormatter::SHORT, + IntlDateFormatter::NONE, + null, + null, + 'dd MMMM yyyy' + )->format((int) $var); + + return $date; } /** @@ -44,15 +49,21 @@ public static function formatDate($var): string */ public static function formatDateTime($var): string { - // get setting - $format = Authentication::getUser()->getSetting('datetime_format'); if ($var instanceof \DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, BackendLanguage::getInterfaceLanguage()); + $date = new IntlDateFormatter( + BackendLanguage::getInterfaceLanguage(), + IntlDateFormatter::SHORT, + IntlDateFormatter::SHORT, + null, + null, + 'dd MMMM yyyy HH:mm' + )->format((int) $var); + + return $date; } /** @@ -114,7 +125,7 @@ public static function formatNumber(float $number, ?int $decimals = null): strin /** * Format a UNIX-timestamp as a date - * syntax: {{ $var|formatdate }} + * syntax: {{ $var|formattime }} * * @param int|\DateTime $var The UNIX-timestamp to format. * @@ -122,15 +133,20 @@ public static function formatNumber(float $number, ?int $decimals = null): strin */ public static function formatTime($var): string { - // get setting - $format = Authentication::getUser()->getSetting('time_format'); - if ($var instanceof \DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, BackendLanguage::getInterfaceLanguage()); + $date = new IntlDateFormatter( + BackendLanguage::getInterfaceLanguage(), + IntlDateFormatter::NONE, + IntlDateFormatter::SHORT, + null, + null, + 'HH:mm' + )->format((int) $var); + + return $date; } /** From 075f32fdf4e4e722d3bae333434b350cc57d31f0 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:33:33 +0100 Subject: [PATCH 03/17] Use IntlDateFormatter instead of spoon date for the BaseTwigModifiers --- .../Core/Twig/Extensions/BaseTwigModifiers.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php b/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php index cce331b8fd..657798a238 100644 --- a/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php +++ b/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php @@ -2,6 +2,9 @@ namespace Common\Core\Twig\Extensions; +use Backend\Core\Language\Language as BackendLanguage; +use IntlDateFormatter; + /** * Contains Base Frontend-related custom modifiers. * These filters work independent of front/backend. @@ -187,7 +190,16 @@ public static function spoonDate($timestamp, $format = 'Y-m-d H:i:s', $language $timestamp = strtotime($timestamp); } - return \SpoonDate::getDate($format, $timestamp, $language); + $date = new IntlDateFormatter( + BackendLanguage::getInterfaceLanguage(), + IntlDateFormatter::SHORT, + IntlDateFormatter::NONE, + null, + null, + 'dd MMMM yyyy' + )->format((int) $timestamp); + + return $date; } /** From 7e55d51191af6a36f2a42486e5ed4b3921c75005 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:36:56 +0100 Subject: [PATCH 04/17] Use IntlDateFormatter instead of spoon date for the frontend TemplateModifiers --- .../Core/Engine/TemplateModifiers.php | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Frontend/Core/Engine/TemplateModifiers.php b/src/Frontend/Core/Engine/TemplateModifiers.php index 8adbaf3996..0a5d30bee2 100644 --- a/src/Frontend/Core/Engine/TemplateModifiers.php +++ b/src/Frontend/Core/Engine/TemplateModifiers.php @@ -10,7 +10,7 @@ use Frontend\Core\Language\Locale; use Frontend\Modules\Profiles\Engine\Model as FrontendProfilesModel; use Common\Core\Twig\Extensions\BaseTwigModifiers; -use SpoonDate; +use IntlDateFormatter; use Twig\Error\Error; use function Symfony\Component\String\s; @@ -29,15 +29,20 @@ class TemplateModifiers extends BaseTwigModifiers */ public static function formatDate($var): string { - // get setting - $format = FrontendModel::get('fork.settings')->get('Core', 'date_format_short'); - if ($var instanceof DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, Locale::frontendLanguage()); + $date = new IntlDateFormatter( + Locale::frontendLanguage(), + IntlDateFormatter::SHORT, + IntlDateFormatter::NONE, + null, + null, + 'dd.MM.yyyy' + )->format((int) $var); + + return $date; } /** @@ -50,15 +55,20 @@ public static function formatDate($var): string */ public static function formatDateTime($var): string { - // get setting - $format = FrontendModel::get('fork.settings')->get('Core', 'date_format_long'); - if ($var instanceof DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, Locale::frontendLanguage()); + $date = new IntlDateFormatter( + Locale::frontendLanguage(), + IntlDateFormatter::LONG, + IntlDateFormatter::NONE, + null, + null, + 'EEEE d MMMM yyyy' + )->format((int) $var); + + return $date; } /** @@ -108,7 +118,7 @@ public static function formatNumber(float $number, ?int $decimals = null): strin /** * Format a UNIX-timestamp as a date - * syntax: {{ $var|formatdate }} + * syntax: {{ $var|formattime }} * * @param int|DateTime $var The UNIX-timestamp to format or \DateTime * @@ -116,15 +126,20 @@ public static function formatNumber(float $number, ?int $decimals = null): strin */ public static function formatTime($var): string { - // get setting - $format = FrontendModel::get('fork.settings')->get('Core', 'time_format'); - if ($var instanceof DateTime) { $var = $var->getTimestamp(); } - // format the date - return SpoonDate::getDate($format, (int) $var, Locale::frontendLanguage()); + $date = new IntlDateFormatter( + Locale::frontendLanguage(), + IntlDateFormatter::NONE, + IntlDateFormatter::SHORT, + null, + null, + 'HH:mm' + )->format((int) $var); + + return $date; } /** From 585b012857a9ce8568520c57ca725ef8dae08b4e Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:37:48 +0100 Subject: [PATCH 05/17] Calculate time ago for twig date filter --- .../Core/Engine/TemplateModifiers.php | 62 ++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/Frontend/Core/Engine/TemplateModifiers.php b/src/Frontend/Core/Engine/TemplateModifiers.php index 0a5d30bee2..5cf801ac97 100644 --- a/src/Frontend/Core/Engine/TemplateModifiers.php +++ b/src/Frontend/Core/Engine/TemplateModifiers.php @@ -202,13 +202,61 @@ public static function timeAgo($timestamp = null): string return ''; } - // return - return ''.\SpoonDate::getTimeAgo($timestamp, Locale::frontendLanguage()).''; + $now = time(); + $diff = $now - $timestamp; + + if ($diff < 0) { + $diff = -$diff; + } + + $seconds = (int) $diff; + $minutes = (int) floor($seconds / 60); + $hours = (int) floor($seconds / 3600); + $days = (int) floor($seconds / 86400); + $months = (int) floor($seconds / (30 * 86400)); + $years = (int) floor($seconds / (365 * 86400)); + + // Decide unit + if ($years > 0) { + $count = $years; + $keySingular = 'TimeAgoYearSingular'; + $keyPlural = 'TimeAgoYearPlural'; + } elseif ($months > 0) { + $count = $months; + $keySingular = 'TimeAgoMonthSingular'; + $keyPlural = 'TimeAgoMonthPlural'; + } elseif ($days > 0) { + $count = $days; + $keySingular = 'TimeAgoDaySingular'; + $keyPlural = 'TimeAgoDayPlural'; + } elseif ($hours > 0) { + $count = $hours; + $keySingular = 'TimeAgoHourSingular'; + $keyPlural = 'TimeAgoHourPlural'; + } elseif ($minutes > 0) { + $count = $minutes; + $keySingular = 'TimeAgoMinuteSingular'; + $keyPlural = 'TimeAgoMinutePlural'; + } else { + $count = $seconds; + $keySingular = 'TimeAgoSecondSingular'; + $keyPlural = 'TimeAgoSecondPlural'; + } + + if ($count <= 0) { + return Language::lbl('TimeAgoEmpty'); + } + + if ($count === 1) { + return Language::lbl($keySingular); + } + + return Language::lblWithParameters( + $keyPlural, + [ + $count + ] + ); } /** From 61df0260a04fa549eeeadf54d333573677320e03 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 08:38:01 +0100 Subject: [PATCH 06/17] Add translations for time ago labels --- src/Backend/Core/Installer/Data/locale.xml | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/Backend/Core/Installer/Data/locale.xml b/src/Backend/Core/Installer/Data/locale.xml index c9567a134d..1b769996c0 100644 --- a/src/Backend/Core/Installer/Data/locale.xml +++ b/src/Backend/Core/Installer/Data/locale.xml @@ -4395,6 +4395,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From fcc154050f657f2e5ab0e4e39f852faf820627f3 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Tue, 24 Mar 2026 09:11:11 +0100 Subject: [PATCH 07/17] Also add method for messages and errors with parameters --- src/Frontend/Core/Language/Language.php | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Frontend/Core/Language/Language.php b/src/Frontend/Core/Language/Language.php index 3bb7fb1bc9..9da108c9c8 100644 --- a/src/Frontend/Core/Language/Language.php +++ b/src/Frontend/Core/Language/Language.php @@ -422,4 +422,44 @@ public static function lblWithParameters(string $key, array $parameters = [], bo return vsprintf($label, $parameters); } + + /** + * Get a message with parameters + * + * @param string $key + * @param array $parameters + * @param bool $fallback + * + * @return string + */ + public static function msgWithParameters(string $key, array $parameters = [], bool $fallback = true): string + { + $message = self::getMessage($key, $fallback); + + if ($parameters === []) { + return $message; + } + + return vsprintf($message, $parameters); + } + + /** + * Get an error with parameters + * + * @param string $key + * @param array $parameters + * @param bool $fallback + * + * @return string + */ + public static function errWithParameters(string $key, array $parameters = [], bool $fallback = true): string + { + $error = self::getError($key, $fallback); + + if ($parameters === []) { + return $error; + } + + return vsprintf($error, $parameters); + } } From d94a3ca05be46cb6e22c05e2df7803e01b46d882 Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Wed, 25 Mar 2026 14:38:59 +0100 Subject: [PATCH 08/17] Remove date and time formats from user settings. Use hardcoded in DataGridFunctions where they were still used. --- src/Backend/Core/Engine/DataGridFunctions.php | 8 ++-- src/Backend/Modules/Users/Actions/Add.php | 15 ------ src/Backend/Modules/Users/Actions/Edit.php | 15 ------ src/Backend/Modules/Users/Engine/Model.php | 48 +------------------ .../Modules/Users/Installer/Installer.php | 5 -- .../Users/Layout/Templates/Add.html.twig | 12 +---- .../Users/Layout/Templates/Edit.html.twig | 23 +++------ 7 files changed, 15 insertions(+), 111 deletions(-) diff --git a/src/Backend/Core/Engine/DataGridFunctions.php b/src/Backend/Core/Engine/DataGridFunctions.php index a586396024..0cc1f60729 100644 --- a/src/Backend/Core/Engine/DataGridFunctions.php +++ b/src/Backend/Core/Engine/DataGridFunctions.php @@ -71,7 +71,7 @@ public static function getDate(int $timestamp): string } // get user setting for long dates - $format = Authentication::getUser()->getSetting('date_format'); + $format = 'j F Y'; // format the date according the user his settings return SpoonDate::getDate($format, $timestamp, BackendLanguage::getInterfaceLanguage()); @@ -92,7 +92,7 @@ public static function getLongDate(int $timestamp): string } // get user setting for long dates - $format = Authentication::getUser()->getSetting('datetime_format'); + $format = 'j F Y H:i'; // format the date according the user his settings return SpoonDate::getDate($format, $timestamp, BackendLanguage::getInterfaceLanguage()); @@ -113,7 +113,7 @@ public static function getTime(int $timestamp): string } // get user setting for long dates - $format = Authentication::getUser()->getSetting('time_format'); + $format = 'H:i'; // format the date according the user his settings return SpoonDate::getDate($format, $timestamp, BackendLanguage::getInterfaceLanguage()); @@ -129,7 +129,7 @@ public static function getTime(int $timestamp): string public static function getTimeAgo(int $timestamp): string { // get user setting for long dates - $format = Authentication::getUser()->getSetting('datetime_format'); + $format = 'j F Y H:i'; // get the time ago as a string $timeAgo = SpoonDate::getTimeAgo($timestamp, BackendLanguage::getInterfaceLanguage(), $format); diff --git a/src/Backend/Modules/Users/Actions/Add.php b/src/Backend/Modules/Users/Actions/Add.php index 932f89d87c..4f585347c3 100644 --- a/src/Backend/Modules/Users/Actions/Add.php +++ b/src/Backend/Modules/Users/Actions/Add.php @@ -70,16 +70,6 @@ private function loadForm(): void BackendModel::getContainer()->getParameter('fork.form.available_editors'), BackendModel::getContainer()->getParameter('fork.form.default_preferred_editor') ); - $this->form->addDropdown( - 'date_format', - BackendUsersModel::getDateFormats(), - BackendAuthentication::getUser()->getSetting('date_format') - ); - $this->form->addDropdown( - 'time_format', - BackendUsersModel::getTimeFormats(), - BackendAuthentication::getUser()->getSetting('time_format') - ); $this->form->addDropdown( 'number_format', BackendUsersModel::getNumberFormats(), @@ -140,8 +130,6 @@ private function validateForm(): void $this->form->getField('surname')->isFilled(BL::err('SurnameIsRequired')); $this->form->getField('interface_language')->isFilled(BL::err('FieldIsRequired')); $this->form->getField('preferred_editor')->isFilled(BL::err('FieldIsRequired')); - $this->form->getField('date_format')->isFilled(BL::err('FieldIsRequired')); - $this->form->getField('time_format')->isFilled(BL::err('FieldIsRequired')); $this->form->getField('number_format')->isFilled(BL::err('FieldIsRequired')); $this->form->getField('groups')->isFilled(BL::err('FieldIsRequired')); if ($this->form->getField('password')->isFilled()) { @@ -159,9 +147,6 @@ private function validateForm(): void $settings['surname'] = $this->form->getField('surname')->getValue(); $settings['interface_language'] = $this->form->getField('interface_language')->getValue(); $settings['preferred_editor'] = $this->form->getField('preferred_editor')->getValue(); - $settings['date_format'] = $this->form->getField('date_format')->getValue(); - $settings['time_format'] = $this->form->getField('time_format')->getValue(); - $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format']; $settings['number_format'] = $this->form->getField('number_format')->getValue(); $settings['csv_split_character'] = $this->form->getField('csv_split_character')->getValue(); $settings['csv_line_ending'] = $this->form->getField('csv_line_ending')->getValue(); diff --git a/src/Backend/Modules/Users/Actions/Edit.php b/src/Backend/Modules/Users/Actions/Edit.php index 0657b4ebef..bae3dc608b 100644 --- a/src/Backend/Modules/Users/Actions/Edit.php +++ b/src/Backend/Modules/Users/Actions/Edit.php @@ -154,16 +154,6 @@ private function loadForm(): void BackendModel::getContainer()->getParameter('fork.form.available_editors'), $this->record['settings']['preferred_editor'] ?? BackendModel::getPreferredEditor() ); - $this->form->addDropdown( - 'date_format', - BackendUsersModel::getDateFormats(), - $this->user->getSetting('date_format') - ); - $this->form->addDropdown( - 'time_format', - BackendUsersModel::getTimeFormats(), - $this->user->getSetting('time_format') - ); $this->form->addDropdown( 'number_format', BackendUsersModel::getNumberFormats(), @@ -279,8 +269,6 @@ private function validateForm(): void $fields['surname']->isFilled(BL::err('SurnameIsRequired')); $fields['interface_language']->isFilled(BL::err('FieldIsRequired')); $fields['preferred_editor']->isFilled(BL::err('FieldIsRequired')); - $fields['date_format']->isFilled(BL::err('FieldIsRequired')); - $fields['time_format']->isFilled(BL::err('FieldIsRequired')); $fields['number_format']->isFilled(BL::err('FieldIsRequired')); if ($this->allowUserRights) { $fields['groups']->isFilled(BL::err('FieldIsRequired')); @@ -324,9 +312,6 @@ private function validateForm(): void $settings['surname'] = $fields['surname']->getValue(); $settings['interface_language'] = $fields['interface_language']->getValue(); $settings['preferred_editor'] = $fields['preferred_editor']->getValue(); - $settings['date_format'] = $fields['date_format']->getValue(); - $settings['time_format'] = $fields['time_format']->getValue(); - $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format']; $settings['number_format'] = $fields['number_format']->getValue(); $settings['csv_split_character'] = $fields['csv_split_character']->getValue(); $settings['csv_line_ending'] = $fields['csv_line_ending']->getValue(); diff --git a/src/Backend/Modules/Users/Engine/Model.php b/src/Backend/Modules/Users/Engine/Model.php index 3f5806fcc0..9a8fbbbc3f 100644 --- a/src/Backend/Modules/Users/Engine/Model.php +++ b/src/Backend/Modules/Users/Engine/Model.php @@ -5,6 +5,8 @@ use Backend\Core\Engine\Authentication as BackendAuthentication; use Backend\Core\Engine\Model as BackendModel; use Backend\Core\Engine\User as BackendUser; +use Backend\Core\Language\Language as BackendLanguage; +use IntlDateFormatter; /** * In this file we store all generic functions that we will be using in the users module. @@ -184,29 +186,6 @@ public static function getCSVSplitCharacters(): array ]; } - /** - * Fetch the list of date formats including examples of these formats. - * - * @return array - */ - public static function getDateFormats(): array - { - // init var - $possibleFormats = []; - - // loop available formats - foreach ((array) BackendModel::get('fork.settings')->get('Users', 'date_formats') as $format) { - $possibleFormats[$format] = \SpoonDate::getDate( - $format, - null, - BackendAuthentication::getUser()->getSetting('interface_language') - ); - } - - // return - return $possibleFormats; - } - public static function getGroups(): array { return (array) BackendModel::getContainer()->get('database')->getPairs( @@ -293,29 +272,6 @@ public static function getSetting(int $userId, string $setting) ); } - /** - * Fetch the list of time formats including examples of these formats. - * - * @return array - */ - public static function getTimeFormats(): array - { - // init var - $possibleFormats = []; - - // loop available formats - foreach (BackendModel::get('fork.settings')->get('Users', 'time_formats') as $format) { - $possibleFormats[$format] = \SpoonDate::getDate( - $format, - null, - BackendAuthentication::getUser()->getSetting('interface_language') - ); - } - - // return - return $possibleFormats; - } - public static function getUsers(): array { // fetch users diff --git a/src/Backend/Modules/Users/Installer/Installer.php b/src/Backend/Modules/Users/Installer/Installer.php index e172aa1abc..ff25892bd9 100644 --- a/src/Backend/Modules/Users/Installer/Installer.php +++ b/src/Backend/Modules/Users/Installer/Installer.php @@ -54,9 +54,7 @@ private function configureBackendRights(): void private function configureSettings(): void { - $this->setSetting($this->getModule(), 'date_formats', ['j/n/Y', 'd/m/Y', 'j F Y', 'F j, Y']); $this->setSetting($this->getModule(), 'default_group', 1); - $this->setSetting($this->getModule(), 'time_formats', ['H:i', 'H:i:s', 'g:i a', 'g:i A']); } public function getPasswordStrength(): string @@ -148,9 +146,6 @@ private function loadGodUser(): void $settings['preferred_editor'] = Model::getContainer()->getParameter('fork.form.default_preferred_editor'); $settings['surname'] = 'CMS'; $settings['interface_language'] = $this->getVariable('default_interface_language'); - $settings['date_format'] = 'j F Y'; - $settings['time_format'] = 'H:i'; - $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format']; $settings['number_format'] = 'dot_nothing'; $settings['password_key'] = uniqid('', true); $settings['password_strength'] = $this->getPasswordStrength(); diff --git a/src/Backend/Modules/Users/Layout/Templates/Add.html.twig b/src/Backend/Modules/Users/Layout/Templates/Add.html.twig index 0ad959d4d3..4681813fad 100644 --- a/src/Backend/Modules/Users/Layout/Templates/Add.html.twig +++ b/src/Backend/Modules/Users/Layout/Templates/Add.html.twig @@ -1,5 +1,5 @@ {% extends 'Layout/Templates/base.html.twig' %} -{% import "Layout/Templates/macros.html.twig" as macro %} +{% import 'Layout/Templates/macros.html.twig' as macro %} {% block actionbar %} @@ -126,14 +126,6 @@ {% form_field preferred_editor %} {% form_field_error preferred_editor %} -
- - {% form_field date_format %} {% form_field_error date_format %} -
-
- - {% form_field time_format %} {% form_field_error time_format %} -
{% form_field number_format %} {% form_field_error number_format %} @@ -189,7 +181,7 @@
- {{ macro.buttonIcon('', 'plus-square', 'lbl.Add'|trans|ucfirst, 'btn-primary', { "id":"addButton", "type":"submit", "name":"add" }) }} + {{ macro.buttonIcon('', 'plus-square', 'lbl.Add'|trans|ucfirst, 'btn-primary', {id: 'addButton', type: 'submit', name: 'add'}) }}
diff --git a/src/Backend/Modules/Users/Layout/Templates/Edit.html.twig b/src/Backend/Modules/Users/Layout/Templates/Edit.html.twig index ab1f66d0fa..e3d50c4998 100644 --- a/src/Backend/Modules/Users/Layout/Templates/Edit.html.twig +++ b/src/Backend/Modules/Users/Layout/Templates/Edit.html.twig @@ -1,5 +1,5 @@ {% extends 'Layout/Templates/base.html.twig' %} -{% import "Layout/Templates/macros.html.twig" as macro %} +{% import 'Layout/Templates/macros.html.twig' as macro %} {% block actionbar %} @@ -32,20 +32,20 @@ {{ 'lbl.LastLogin'|trans|ucfirst }}: - {% if record.settings.last_login %}{{ record.settings.last_login|spoondate(authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }}{% endif %} + {% if record.settings.last_login %}{{ record.settings.last_login|formatdate }}{% endif %} {% if not record.settings.last_login %}{{ 'lbl.NoPreviousLogin'|trans|ucfirst }}{% endif %} {% if record.settings.last_failed_login_attempt %} {{ 'lbl.LastFailedLoginAttempt'|trans|ucfirst }}: - {{ record.settings.last_failed_login_attempt|spoondate(authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }} + {{ record.settings.last_failed_login_attempt|formatdate }} {% endif %} {{ 'lbl.LastPasswordChange'|trans|ucfirst }}: - {% if record.settings.last_password_change %}{{ record.settings.last_password_change|spoondate(authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }}{% endif %} + {% if record.settings.last_password_change %}{{ record.settings.last_password_change|formatdate }}{% endif %} {% if not record.settings.last_password_change %}{{ 'lbl.Never'|trans|ucfirst }}{% endif %} @@ -206,14 +206,6 @@ {% form_field preferred_editor %} {% form_field_error preferred_editor %}
-
- - {% form_field date_format %} {% form_field_error date_format %} -
-
- - {% form_field time_format %} {% form_field_error time_format %} -
{% form_field number_format %} {% form_field_error number_format %} @@ -277,11 +269,11 @@
{% if isAllowedAction('Delete') and allowUsersDelete %} - {{ macro.buttonIcon('', 'trash-o', 'lbl.Delete'|trans|ucfirst, 'btn-danger', { "data-toggle":"modal", "type":"button", "data-target":"#confirmDelete" }) }} + {{ macro.buttonIcon('', 'trash-o', 'lbl.Delete'|trans|ucfirst, 'btn-danger', {'data-toggle': 'modal', type: 'button', 'data-target': '#confirmDelete'}) }} {% endif %}
- {{ macro.buttonIcon('', 'floppy-o', 'lbl.Save'|trans|ucfirst, 'btn-primary', { "id":"editButton", "type":"submit", "name":"edit" }) }} + {{ macro.buttonIcon('', 'floppy-o', 'lbl.Save'|trans|ucfirst, 'btn-primary', {id: 'editButton', type: 'submit', name: 'edit'}) }}
@@ -302,7 +294,7 @@

{{ 'msg.ConfirmDelete'|trans|format(record.settings.nickname|e)|raw }}

@@ -311,4 +303,3 @@ {{ form_end(deleteForm) }} {% endif %} {% endblock %} - From 4d7a140f1e26f4c402830fe3d61482b5b544309e Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Wed, 25 Mar 2026 14:40:03 +0100 Subject: [PATCH 09/17] Change spoondate to customformatdate so we have a method to pass a custom date format --- .../Core/Twig/Extensions/BaseTwigModifiers.php | 12 ++++++++---- src/Common/Core/Twig/Extensions/TwigFilters.php | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php b/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php index 657798a238..ce09571700 100644 --- a/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php +++ b/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php @@ -175,7 +175,7 @@ public static function camelCase(string $string): string /** * Formats a language specific date. - * syntax: {{ $timestamp|spoondate($format, $language) }}. + * syntax: {{ $timestamp|customformatdate($format, $language) }}. * * @param string|int $timestamp The timestamp or date that you want to apply the format to. * @param string $format The optional format that you want to apply on the provided timestamp. @@ -183,20 +183,24 @@ public static function camelCase(string $string): string * * @return string The formatted date according to the timestamp, format and provided language. */ - public static function spoonDate($timestamp, $format = 'Y-m-d H:i:s', $language = 'en') + public static function customFormatDate($timestamp, $format = 'yyyy-MM-dd HH:mm:ss', $language = null) { if (is_string($timestamp) && !is_numeric($timestamp)) { // use strptime if you want to restrict the input format $timestamp = strtotime($timestamp); } + if ($language === null) { + $language = BackendLanguage::getInterfaceLanguage(); + } + $date = new IntlDateFormatter( - BackendLanguage::getInterfaceLanguage(), + $language, IntlDateFormatter::SHORT, IntlDateFormatter::NONE, null, null, - 'dd MMMM yyyy' + $format )->format((int) $timestamp); return $date; diff --git a/src/Common/Core/Twig/Extensions/TwigFilters.php b/src/Common/Core/Twig/Extensions/TwigFilters.php index 92a98425d4..cc6b4a0a5a 100644 --- a/src/Common/Core/Twig/Extensions/TwigFilters.php +++ b/src/Common/Core/Twig/Extensions/TwigFilters.php @@ -117,7 +117,7 @@ public static function addFilters(Environment $twig, string $app): void // @Deprecated We should look for replacements because they run on spoon library // after we have those we can remove them - $twig->addFilter(new TwigFilter('spoondate', $app . '::spoonDate')); + $twig->addFilter(new TwigFilter('customformatdate', $app . '::customFormatDate')); $twig->addFilter(new TwigFilter('formatdate', $app . '::formatDate')); $twig->addFilter(new TwigFilter('formattime', $app . '::formatTime')); $twig->addFilter(new TwigFilter('timeago', $app . '::timeAgo')); From b626f8e14a65de4f6456d6af0536e03bf5bbf3fb Mon Sep 17 00:00:00 2001 From: Ilaria Orlando Date: Wed, 25 Mar 2026 14:42:08 +0100 Subject: [PATCH 10/17] Change all spoondate filters to customformatdate and pass equivalent format to filter. fix twig-cs warnings on templates --- .../Layout/Templates/DataDetails.html.twig | 10 +++++----- .../Users/Layout/Widgets/Statistics.html.twig | 6 +++--- .../Blog/Layout/Templates/Archive.html.twig | 8 ++++---- .../Blog/Layout/Templates/Category.html.twig | 12 ++++++------ .../Modules/Blog/Layout/Templates/Detail.html.twig | 14 +++++++------- .../Modules/Blog/Layout/Templates/Index.html.twig | 12 ++++++------ .../Modules/Blog/Layout/Widgets/Archive.html.twig | 2 +- .../Layout/Widgets/RecentArticlesFull.html.twig | 8 ++++---- .../Faq/Layout/Templates/Mails/Feedback.html.twig | 2 +- .../Layout/Templates/Mails/OwnQuestion.html.twig | 2 +- .../Layout/Templates/Mails/Form.html.twig | 4 ++-- .../Blog/Layout/Templates/Archive.html.twig | 8 ++++---- .../Blog/Layout/Templates/Article.html.twig | 2 +- .../Modules/Blog/Layout/Templates/Detail.html.twig | 6 +++--- .../Modules/Blog/Layout/Widgets/Archive.html.twig | 2 +- .../Faq/Layout/Templates/Mails/Feedback.html.twig | 2 +- .../Layout/Templates/Mails/OwnQuestion.html.twig | 2 +- .../Layout/Templates/Mails/Form.html.twig | 4 ++-- .../Modules/Blog/Layout/Templates/Detail.html.twig | 8 ++++---- .../Modules/Blog/Layout/Templates/Index.html.twig | 10 +++++----- .../Layout/Widgets/RecentArticlesFull.html.twig | 10 +++++----- 21 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/Backend/Modules/FormBuilder/Layout/Templates/DataDetails.html.twig b/src/Backend/Modules/FormBuilder/Layout/Templates/DataDetails.html.twig index 7b17a3c641..0b1553ebb6 100644 --- a/src/Backend/Modules/FormBuilder/Layout/Templates/DataDetails.html.twig +++ b/src/Backend/Modules/FormBuilder/Layout/Templates/DataDetails.html.twig @@ -1,11 +1,11 @@ {% extends 'Layout/Templates/base.html.twig' %} -{% import "Layout/Templates/macros.html.twig" as macro %} +{% import 'Layout/Templates/macros.html.twig' as macro %} {% block actionbar %}
{% if isAllowedAction('Data') %} - {{ macro.buttonIcon( geturl('data') ~ '&id=' ~ formId ~ '&start_date=' ~ filter.start_date ~ '&end_date=' ~ filter.end_date, 'list', 'lbl.BackToData'|trans|ucfirst) }} + {{ macro.buttonIcon(geturl('data') ~ '&id=' ~ formId ~ '&start_date=' ~ filter.start_date ~ '&end_date=' ~ filter.end_date, 'list', 'lbl.BackToData'|trans|ucfirst) }} {% endif %}
@@ -41,7 +41,7 @@ - +
{{ 'lbl.SentOn'|trans|ucfirst }}:{{ sentOn|spoondate }}{{ sentOn|formatdatetime }}
@@ -71,8 +71,8 @@

{{ 'msg.ConfirmDeleteData'|trans|ucfirst }}

diff --git a/src/Backend/Modules/Users/Layout/Widgets/Statistics.html.twig b/src/Backend/Modules/Users/Layout/Widgets/Statistics.html.twig index aff846cb90..f4f7bfa8e3 100644 --- a/src/Backend/Modules/Users/Layout/Widgets/Statistics.html.twig +++ b/src/Backend/Modules/Users/Layout/Widgets/Statistics.html.twig @@ -9,20 +9,20 @@ {{ 'lbl.LastLogin'|trans|ucfirst }}: - {% if authenticatedUserLastLogin %}{{ authenticatedUserLastLogin|spoondate(authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }} {% endif %} + {% if authenticatedUserLastLogin %}{{ authenticatedUserLastLogin|formatdate }} {% endif %} {% if not authenticatedUserLastLogin %}{{ 'lbl.NoPreviousLogin'|trans|ucfirst }}{% endif %} {% if authenticatedUserLastFailedLoginAttempt %} {{ 'lbl.LastFailedLoginAttempt'|trans|ucfirst }}: - {{ authenticatedUserLastFailedLoginAttempt|spoondate( authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }} + {{ authenticatedUserLastFailedLoginAttempt|formatdate }} {% endif %} {{ 'lbl.LastPasswordChange'|trans|ucfirst }}: - {% if authenticatedUserLastPasswordChange %}{{ authenticatedUserLastPasswordChange|spoondate(authenticatedUserDateFormat, authenticatedUserTimeFormat, INTERFACE_LANGUAGE) }}{% endif %} + {% if authenticatedUserLastPasswordChange %}{{ authenticatedUserLastPasswordChange|formatdate }}{% endif %} {% if not authenticatedUserLastPasswordChange %}{{ 'lbl.Never'|trans|ucfirst }}{% endif %} diff --git a/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig b/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig index f9a806e5bf..2b53fcbfdc 100644 --- a/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig +++ b/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig @@ -17,7 +17,7 @@