From 440dc7313379bc291a63ee0ef7fd9ca243a30091 Mon Sep 17 00:00:00 2001 From: i-just <iwona@pixelandtonic.com> Date: Thu, 16 Jan 2025 14:53:42 +0000 Subject: [PATCH 1/3] move getting datetime attributes to a helper --- src/base/Model.php | 18 ++---------------- src/helpers/Component.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/base/Model.php b/src/base/Model.php index ca8ae365f0c..98f0d16e75a 100644 --- a/src/base/Model.php +++ b/src/base/Model.php @@ -12,13 +12,10 @@ use craft\events\DefineFieldsEvent; use craft\events\DefineRulesEvent; use craft\helpers\App; +use craft\helpers\Component; use craft\helpers\DateTimeHelper; use craft\helpers\StringHelper; use craft\helpers\Typecast; -use DateTime; -use ReflectionClass; -use ReflectionNamedType; -use ReflectionProperty; use yii\validators\Validator; /** @@ -242,18 +239,7 @@ public function fields(): array { $fields = parent::fields(); - $datetimeAttributes = []; - foreach ((new ReflectionClass($this))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { - if (!$property->isStatic()) { - $type = $property->getType(); - if ($type instanceof ReflectionNamedType && $type->getName() === DateTime::class) { - $datetimeAttributes[] = $property->getName(); - } - } - } - - // Include datetimeAttributes() for now - $datetimeAttributes = array_unique(array_merge($datetimeAttributes, $this->datetimeAttributes())); + $datetimeAttributes = Component::datetimeAttributes($this); // Have all DateTime attributes converted to ISO-8601 strings foreach ($datetimeAttributes as $attribute) { diff --git a/src/helpers/Component.php b/src/helpers/Component.php index 05e4c1ef122..b909fdcb3a7 100644 --- a/src/helpers/Component.php +++ b/src/helpers/Component.php @@ -9,7 +9,13 @@ use Craft; use craft\base\ComponentInterface; +use craft\base\ElementInterface; +use craft\base\Model; use craft\errors\MissingComponentException; +use DateTime; +use ReflectionClass; +use ReflectionNamedType; +use ReflectionProperty; use yii\base\InvalidConfigException; /** @@ -176,4 +182,26 @@ public static function iconSvg(?string $icon, string $label): string return Cp::iconSvg($icon, $label); } + + /** + * Return all DateTime attributes for given model. + * + * @param Model|ElementInterface $model + * @return array + */ + public static function datetimeAttributes(Model|ElementInterface $model): array + { + $datetimeAttributes = []; + foreach ((new ReflectionClass($model))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { + if (!$property->isStatic()) { + $type = $property->getType(); + if ($type instanceof ReflectionNamedType && $type->getName() === DateTime::class) { + $datetimeAttributes[] = $property->getName(); + } + } + } + + // Include datetimeAttributes() for now + return array_unique(array_merge($datetimeAttributes, $model->datetimeAttributes())); + } } From 17f9d440a5f5feaa9880000b44514fedd500a85f Mon Sep 17 00:00:00 2001 From: i-just <iwona@pixelandtonic.com> Date: Thu, 16 Jan 2025 14:54:02 +0000 Subject: [PATCH 2/3] expanded export should return localised datetime attributes --- src/elements/exporters/Expanded.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/elements/exporters/Expanded.php b/src/elements/exporters/Expanded.php index 3b759f65416..82ddc6966f8 100644 --- a/src/elements/exporters/Expanded.php +++ b/src/elements/exporters/Expanded.php @@ -13,6 +13,8 @@ use craft\base\ElementInterface; use craft\elements\db\ElementQuery; use craft\elements\db\ElementQueryInterface; +use craft\helpers\Component; +use craft\helpers\DateTimeHelper; use craft\helpers\Db; /** @@ -63,7 +65,29 @@ public function export(ElementQueryInterface $query): mixed unset($attributes[$field->handle]); } } - $elementArr = $element->toArray(array_keys($attributes)); + // because of changes in https://github.com/craftcms/cms/commit/e662ee32d7a5c15dfaa911ae462155615ce7a320 + // we need to split attributes to the date ones and all other; + // pass all other to toArray() + // and then return DateTimeHelper::toIso8601($date, false); for all the date ones + $datetimeAttributes = Component::datetimeAttributes($element); + $otherAttributes = array_diff(array_keys($attributes), $datetimeAttributes); + + $elementArr = $element->toArray($otherAttributes); + + foreach ($datetimeAttributes as $attribute) { + $date = $element->$attribute; + if ($date) { + $elementArr[$attribute] = DateTimeHelper::toIso8601($date); + } else { + $elementArr[$attribute] = $element->$attribute; + } + } + + // sort the $elementArr so the keys are in the same order as the values in the $attributes table + uksort($elementArr, function($a, $b) use ($attributes) { + return $attributes[$a] <=> $attributes[$b]; + }); + if ($fieldLayout !== null) { foreach ($fieldLayout->getCustomFields() as $field) { $value = $element->getFieldValue($field->handle); From 67e1a207805a2ce2bb6e06be9ca3827827477844 Mon Sep 17 00:00:00 2001 From: brandonkelly <brandon@pixelandtonic.com> Date: Mon, 20 Jan 2025 08:11:37 -0800 Subject: [PATCH 3/3] Release note [ci skip] --- CHANGELOG-WIP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index 549df2f53eb..24173b36ba2 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -16,6 +16,7 @@ - Structure views are now available to element indexes on mobile browsers. ([#16190](https://github.com/craftcms/cms/discussions/16190)) - Datepickers now include a dropdown menu for selecting the year. ([#16376](https://github.com/craftcms/cms/pull/16376)) - Custom fields within element edit pages can now have action menus with “Copy value from site…”, “Edit field” and “Copy field handle” items. ([#16415](https://github.com/craftcms/cms/pull/16415), [#14056](https://github.com/craftcms/cms/pull/14056)) +- Element exports now include date attribute values set to the system time zone. ([#16447](https://github.com/craftcms/cms/pull/16447)) - Heads-up displays now reposition themselves on window scroll. ### Accessibility