diff --git a/src/Backend/Core/Engine/DataGridFunctions.php b/src/Backend/Core/Engine/DataGridFunctions.php index a586396024..574fe13383 100644 --- a/src/Backend/Core/Engine/DataGridFunctions.php +++ b/src/Backend/Core/Engine/DataGridFunctions.php @@ -70,10 +70,8 @@ public static function getDate(int $timestamp): string return ''; } - // 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()); } @@ -91,10 +89,8 @@ public static function getLongDate(int $timestamp): string return ''; } - // 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()); } @@ -112,10 +108,8 @@ public static function getTime(int $timestamp): string return ''; } - // 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 +123,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/Core/Engine/Model.php b/src/Backend/Core/Engine/Model.php index 464db45690..e4e655b433 100644 --- a/src/Backend/Core/Engine/Model.php +++ b/src/Backend/Core/Engine/Model.php @@ -265,50 +265,6 @@ public static function generateRandomString( return $string; } - /** - * Fetch the list of long date formats including examples of these formats. - * - * @return array - */ - public static function getDateFormatsLong(): array - { - $possibleFormats = []; - - // loop available formats - foreach ((array) self::get('fork.settings')->get('Core', 'date_formats_long') as $format) { - // get date based on given format - $possibleFormats[$format] = \SpoonDate::getDate( - $format, - null, - Authentication::getUser()->getSetting('interface_language') - ); - } - - return $possibleFormats; - } - - /** - * Fetch the list of short date formats including examples of these formats. - * - * @return array - */ - public static function getDateFormatsShort(): array - { - $possibleFormats = []; - - // loop available formats - foreach ((array) self::get('fork.settings')->get('Core', 'date_formats_short') as $format) { - // get date based on given format - $possibleFormats[$format] = \SpoonDate::getDate( - $format, - null, - Authentication::getUser()->getSetting('interface_language') - ); - } - - return $possibleFormats; - } - public static function getExtras(array $ids): array { // get database @@ -453,23 +409,6 @@ public static function getNumberFormats(): array return (array) self::get('fork.settings')->get('Core', 'number_formats'); } - /** - * Fetch the list of time formats including examples of these formats. - * - * @return array - */ - public static function getTimeFormats(): array - { - $possibleFormats = []; - $interfaceLanguage = Authentication::getUser()->getSetting('interface_language'); - - foreach (self::get('fork.settings')->get('Core', 'time_formats') as $format) { - $possibleFormats[$format] = \SpoonDate::getDate($format, null, $interfaceLanguage); - } - - return $possibleFormats; - } - /** * Get the token which will protect us * 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; } /** diff --git a/src/Backend/Core/Installer/CoreInstaller.php b/src/Backend/Core/Installer/CoreInstaller.php index 3c40dbade8..88d747aaca 100644 --- a/src/Backend/Core/Installer/CoreInstaller.php +++ b/src/Backend/Core/Installer/CoreInstaller.php @@ -66,62 +66,6 @@ private function configureDefaultSettings(): void $this->setSetting('Core', 'site_html_head', ''); $this->setSetting('Core', 'site_html_end_of_body', ''); - // date & time - $this->setSetting('Core', 'date_format_short', 'j.n.Y'); - $this->setSetting( - 'Core', - 'date_formats_short', - [ - 'j/n/Y', - 'j-n-Y', - 'j.n.Y', - 'n/j/Y', - 'n/j/Y', - 'n/j/Y', - 'd/m/Y', - 'd-m-Y', - 'd.m.Y', - 'm/d/Y', - 'm-d-Y', - 'm.d.Y', - 'j/n/y', - 'j-n-y', - 'j.n.y', - 'n/j/y', - 'n-j-y', - 'n.j.y', - 'd/m/y', - 'd-m-y', - 'd.m.y', - 'm/d/y', - 'm-d-y', - 'm.d.y', - ] - ); - $this->setSetting('Core', 'date_format_long', 'l j F Y'); - $this->setSetting( - 'Core', - 'date_formats_long', - [ - 'j F Y', - 'D j F Y', - 'l j F Y', - 'j F, Y', - 'D j F, Y', - 'l j F, Y', - 'd F Y', - 'd F, Y', - 'F j Y', - 'D F j Y', - 'l F j Y', - 'F d, Y', - 'D F d, Y', - 'l F d, Y', - ] - ); - $this->setSetting('Core', 'time_format', 'H:i'); - $this->setSetting('Core', 'time_formats', ['H:i', 'H:i:s', 'g:i a', 'g:i A']); - // number formats $this->setSetting('Core', 'number_format', 'dot_nothing'); $this->setSetting( 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/Settings/Actions/Index.php b/src/Backend/Modules/Settings/Actions/Index.php index 5b1e080ed7..40207868e2 100644 --- a/src/Backend/Modules/Settings/Actions/Index.php +++ b/src/Backend/Modules/Settings/Actions/Index.php @@ -150,23 +150,6 @@ private function loadForm(): void $this->get('fork.settings')->get('Core', 'ckfinder_image_max_height', 1200) ); - // date & time formats - $this->form->addDropdown( - 'time_format', - BackendModel::getTimeFormats(), - $this->get('fork.settings')->get('Core', 'time_format') - ); - $this->form->addDropdown( - 'date_format_short', - BackendModel::getDateFormatsShort(), - $this->get('fork.settings')->get('Core', 'date_format_short') - ); - $this->form->addDropdown( - 'date_format_long', - BackendModel::getDateFormatsLong(), - $this->get('fork.settings')->get('Core', 'date_format_long') - ); - // number formats $this->form->addDropdown( 'number_format', @@ -355,11 +338,6 @@ private function validateForm(): void ); } - // date & time - $this->form->getField('time_format')->isFilled(BL::err('FieldIsRequired')); - $this->form->getField('date_format_short')->isFilled(BL::err('FieldIsRequired')); - $this->form->getField('date_format_long')->isFilled(BL::err('FieldIsRequired')); - // number $this->form->getField('number_format')->isFilled(BL::err('FieldIsRequired')); @@ -489,23 +467,6 @@ private function validateForm(): void ); } - // date & time formats - $this->get('fork.settings')->set( - 'Core', - 'time_format', - $this->form->getField('time_format')->getValue() - ); - $this->get('fork.settings')->set( - 'Core', - 'date_format_short', - $this->form->getField('date_format_short')->getValue() - ); - $this->get('fork.settings')->set( - 'Core', - 'date_format_long', - $this->form->getField('date_format_long')->getValue() - ); - // date & time formats $this->get('fork.settings')->set( 'Core', diff --git a/src/Backend/Modules/Settings/Layout/Templates/Index.html.twig b/src/Backend/Modules/Settings/Layout/Templates/Index.html.twig index b9930478a9..31490bd76f 100644 --- a/src/Backend/Modules/Settings/Layout/Templates/Index.html.twig +++ b/src/Backend/Modules/Settings/Layout/Templates/Index.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 %} @@ -136,32 +136,6 @@ -
-
-
-
-

{{ 'lbl.DateAndTime'|trans|ucfirst }}

-
-
-
- - {% form_field time_format %} {% form_field_error time_format %} - {{ 'msg.HelpTimeFormat'|trans|ucfirst }} -
-
- - {% form_field date_format_short %} {% form_field_error date_format_short %} - {{ 'msg.HelpDateFormatShort'|trans|ucfirst }} -
-
- - {% form_field date_format_long %} {% form_field_error date_format_long %} - {{ 'msg.HelpDateFormatLong'|trans|ucfirst }} -
-
-
-
-
@@ -305,8 +279,8 @@

{{ 'msg.HelpPrivacyConsents'|trans }}

    - {% for level in privacy_consent_levels %} - {% set camelCasedLevel = level|title|replace({'_':''}) %} + {% for level in privacy_consent_levels %} + {% set camelCasedLevel = level|title|replace({_: ''}) %}
-
- - {% 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 %} - 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/Common/Core/Twig/BaseTwigTemplate.php b/src/Common/Core/Twig/BaseTwigTemplate.php index 89382523e8..83f7e339c9 100644 --- a/src/Common/Core/Twig/BaseTwigTemplate.php +++ b/src/Common/Core/Twig/BaseTwigTemplate.php @@ -138,10 +138,6 @@ protected function startGlobals(Environment $twig) return; } - $twig->addGlobal('timeFormat', $this->forkSettings->get('Core', 'time_format')); - $twig->addGlobal('dateFormatShort', $this->forkSettings->get('Core', 'date_format_short')); - $twig->addGlobal('dateFormatLong', $this->forkSettings->get('Core', 'date_format_long')); - // old theme checker if ($this->forkSettings->get('Core', 'theme') !== null) { $twig->addGlobal('THEME', $this->forkSettings->get('Core', 'theme', 'Fork')); diff --git a/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php b/src/Common/Core/Twig/Extensions/BaseTwigModifiers.php index cce331b8fd..4b1b245aac 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. @@ -172,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. @@ -180,14 +183,29 @@ 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); } - return \SpoonDate::getDate($format, $timestamp, $language); + if (defined('APPLICATION') && APPLICATION === 'Frontend') { + $language = FRONTEND_LANGUAGE; + } else { + $language = BackendLanguage::getInterfaceLanguage(); + } + + $date = new IntlDateFormatter( + $language, + IntlDateFormatter::SHORT, + IntlDateFormatter::NONE, + null, + null, + $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')); diff --git a/src/Common/Tests/ModulesSettingsTest.php b/src/Common/Tests/ModulesSettingsTest.php index 0f9fbf1add..9b95b66dfc 100644 --- a/src/Common/Tests/ModulesSettingsTest.php +++ b/src/Common/Tests/ModulesSettingsTest.php @@ -21,7 +21,6 @@ public function testFetchingSettingsCallsTheDatabaseOnce(): void ); $modulesSettings->get('Core', 'theme', 'Fork'); - $modulesSettings->get('Core', 'time_format', 'H:i'); } public function testFetchingSettingWorks(): void diff --git a/src/Frontend/Core/Engine/TemplateModifiers.php b/src/Frontend/Core/Engine/TemplateModifiers.php index 8adbaf3996..cc4db60ccb 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; } /** @@ -170,7 +185,7 @@ public static function getNavigation( /** * Formats a timestamp as a string that indicates the time ago - * syntax: {{ $$timestamp|timeago }}. + * syntax: {{ $timestamp|timeago|raw }}. * * @param int|DateTime $timestamp A UNIX-timestamp that will be formatted as a time-ago-string. * @@ -187,13 +202,65 @@ 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); + } + + $date = new IntlDateFormatter( + Locale::frontendLanguage(), + IntlDateFormatter::LONG, + IntlDateFormatter::NONE, + null, + null, + 'EEEE d MMMM yyyy' + )->format((int) $timestamp); + + return '' . Language::lblWithParameters($keyPlural, [$count]) . ''; } /** diff --git a/src/Frontend/Core/Language/Language.php b/src/Frontend/Core/Language/Language.php index 7571bac630..9da108c9c8 100644 --- a/src/Frontend/Core/Language/Language.php +++ b/src/Frontend/Core/Language/Language.php @@ -402,4 +402,64 @@ 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); + } + + /** + * 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); + } } diff --git a/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig b/src/Frontend/Modules/Blog/Layout/Templates/Archive.html.twig index f9a806e5bf..52cc10e19a 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 @@