Skip to content

Commit b1ec090

Browse files
committed
Merge branch '8.4' into 9.0
2 parents ffe3694 + b8dbfce commit b1ec090

File tree

7 files changed

+214
-5
lines changed

7 files changed

+214
-5
lines changed

Neos.Eel/Classes/Helper/DateHelper.php

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Neos\Eel\Helper;
34

45
/*
@@ -13,6 +14,7 @@
1314

1415
use Neos\Flow\Annotations as Flow;
1516
use Neos\Eel\ProtectedContextAwareInterface;
17+
use Neos\Flow\I18n\Cldr\Reader\DatesReader;
1618
use Neos\Flow\I18n\Formatter\DatetimeFormatter;
1719
use Neos\Flow\I18n\Locale;
1820
use Neos\Flow\I18n\Service as I18nService;
@@ -91,14 +93,52 @@ public function formatCldr($date, $cldrFormat, $locale = null)
9193
if (empty($cldrFormat)) {
9294
throw new \InvalidArgumentException('CLDR date formatting parameter not passed.');
9395
}
94-
if ($locale === null) {
95-
$useLocale = $this->localizationService->getConfiguration()->getCurrentLocale();
96-
} else {
97-
$useLocale = new Locale($locale);
98-
}
96+
$useLocale = $this->getLocaleOrDefault($locale);
9997
return $this->datetimeFormatter->formatDateTimeWithCustomPattern($date, $cldrFormat, $useLocale);
10098
}
10199

100+
/**
101+
* Format a date to a string with a given cldr formatLength
102+
*
103+
* @param \DateTimeInterface $dateTime
104+
* @param string $formatLength FormatLength in CLDR format ("Full", "Long", "Medium", "Short") (see https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-date-formats)
105+
* @param null|string $locale String locale - example (de|en|en_US). If not provided the current locale of I18nService is used.
106+
* @return string
107+
*/
108+
public function formatCldrDate(\DateTimeInterface $dateTime, string $formatLength = DatesReader::FORMAT_LENGTH_DEFAULT, ?string $locale = null): string
109+
{
110+
$locale = $this->getLocaleOrDefault($locale);
111+
return $this->datetimeFormatter->formatDate($dateTime, $locale, $formatLength);
112+
}
113+
114+
/**
115+
* Format a time to a string with a given cldr formatLength
116+
*
117+
* @param \DateTimeInterface $dateTime
118+
* @param string $formatLength FormatLength in CLDR format ("Full", "Long", "Medium", "Short") (see https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-time-formats)
119+
* @param null|string $locale String locale - example (de|en|en_US). If not provided the current locale of I18nService is used.
120+
* @return string
121+
*/
122+
public function formatCldrTime(\DateTimeInterface $dateTime, string $formatLength = DatesReader::FORMAT_LENGTH_DEFAULT, ?string $locale = null): string
123+
{
124+
$locale = $this->getLocaleOrDefault($locale);
125+
return $this->datetimeFormatter->formatTime($dateTime, $locale, $formatLength);
126+
}
127+
128+
/**
129+
* Format a datetime to a string with a given cldr formatLength
130+
*
131+
* @param \DateTimeInterface $dateTime
132+
* @param string $formatLength FormatLength in CLDR format ("Full", "Long", "Medium", "Short") (see https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-date-formats and https://cldr.unicode.org/translation/date-time/date-time-patterns#basic-date-formats)
133+
* @param null|string $locale String locale - example (de|en|en_US). If not provided the current locale of I18nService is used.
134+
* @return string
135+
*/
136+
public function formatCldrDateTime(\DateTimeInterface $dateTime, string $formatLength = DatesReader::FORMAT_LENGTH_DEFAULT, ?string $locale = null): string
137+
{
138+
$locale = $this->getLocaleOrDefault($locale);
139+
return $this->datetimeFormatter->formatDateTime($dateTime, $locale, $formatLength);
140+
}
141+
102142
/**
103143
* Get a date object by given date or time format
104144
*
@@ -249,6 +289,14 @@ public function second(\DateTimeInterface $dateTime)
249289
return (integer)$dateTime->format('s');
250290
}
251291

292+
private function getLocaleOrDefault(?string $locale): Locale
293+
{
294+
if ($locale === null) {
295+
return $this->localizationService->getConfiguration()->getCurrentLocale();
296+
}
297+
return new Locale($locale);
298+
}
299+
252300
/**
253301
* All methods are considered safe
254302
*

Neos.Eel/Tests/Unit/Helper/DateHelperTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,72 @@ public function formatCldrCallsFormatService()
124124
$helper->formatCldr($date, $format, $locale);
125125
}
126126

127+
/**
128+
* @test
129+
*/
130+
public function formatCldrDate()
131+
{
132+
$date = \DateTime::createFromFormat('Y-m-d H:i:s', '2013-07-03 12:34:56');
133+
$formatLength = 'long';
134+
$localeString = 'en';
135+
136+
$locale = new Locale('en');
137+
$expectedString = '2013-07-03 12:34:56';
138+
139+
$formatMock = $this->createMock(\Neos\Flow\I18n\Formatter\DatetimeFormatter::class);
140+
$formatMock->expects(self::atLeastOnce())->method('formatDate')->with($date, $locale, $formatLength)->willReturn($expectedString);
141+
142+
$helper = new DateHelper();
143+
$this->inject($helper, 'datetimeFormatter', $formatMock);
144+
145+
$result = $helper->formatCldrDate($date, $formatLength, $localeString);
146+
$this->assertEquals($expectedString, $result);
147+
}
148+
149+
/**
150+
* @test
151+
*/
152+
public function formatCldrTime()
153+
{
154+
$date = \DateTime::createFromFormat('Y-m-d H:i:s', '2013-07-03 12:34:56');
155+
$formatLength = 'long';
156+
$localeString = 'en';
157+
158+
$locale = new Locale('en');
159+
$expectedString = '2013-07-03 12:34:56';
160+
161+
$formatMock = $this->createMock(\Neos\Flow\I18n\Formatter\DatetimeFormatter::class);
162+
$formatMock->expects(self::atLeastOnce())->method('formatTime')->with($date, $locale, $formatLength)->willReturn($expectedString);
163+
164+
$helper = new DateHelper();
165+
$this->inject($helper, 'datetimeFormatter', $formatMock);
166+
167+
$result = $helper->formatCldrTime($date, $formatLength, $localeString);
168+
$this->assertEquals($expectedString, $result);
169+
}
170+
171+
/**
172+
* @test
173+
*/
174+
public function formatCldrDateTime()
175+
{
176+
$date = \DateTime::createFromFormat('Y-m-d H:i:s', '2013-07-03 12:34:56');
177+
$formatLength = 'long';
178+
$localeString = 'en';
179+
180+
$locale = new Locale('en');
181+
$expectedString = '2013-07-03 12:34:56';
182+
183+
$formatMock = $this->createMock(\Neos\Flow\I18n\Formatter\DatetimeFormatter::class);
184+
$formatMock->expects(self::atLeastOnce())->method('formatDateTime')->with($date, $locale, $formatLength)->willReturn($expectedString);
185+
186+
$helper = new DateHelper();
187+
$this->inject($helper, 'datetimeFormatter', $formatMock);
188+
189+
$result = $helper->formatCldrDateTime($date, $formatLength, $localeString);
190+
$this->assertEquals($expectedString, $result);
191+
}
192+
127193
/**
128194
* @test
129195
*/

Neos.Flow/Classes/ObjectManagement/DependencyInjection/ProxyClassBuilder.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ protected function buildPropertyInjectionCode(Configuration $objectConfiguration
390390
$preparedSetterArgument = var_export($propertyValue, true);
391391
} elseif (is_bool($propertyValue)) {
392392
$preparedSetterArgument = $propertyValue ? 'true' : 'false';
393+
} elseif ($propertyValue === null) {
394+
$preparedSetterArgument = 'null';
393395
} else {
394396
$preparedSetterArgument = $propertyValue;
395397
}

Neos.Flow/Configuration/Testing/Objects.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Neos\Flow\Tests\Functional\ObjectManagement\Fixtures\SingletonClassC:
4242
value: true
4343
protectedBooleanFalsePropertySetViaObjectsYaml:
4444
value: false
45+
protectedNullPropertySetViaObjectsYaml:
46+
value: null
4547
protectedArrayPropertyWithSetterSetViaObjectsYaml:
4648
value: {'and': 'something from Objects.yaml'}
4749
arguments:
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
`8.3.14 (2025-03-04) <https://github.com/neos/flow-development-collection/releases/tag/8.3.14>`_
2+
================================================================================================
3+
4+
Overview of merged pull requests
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
7+
`BUGFIX: Avoid type error during `publishFile()` <https://github.com/neos/flow-development-collection/pull/3449>`_
8+
------------------------------------------------------------------------------------------------------------------
9+
10+
This avoids an error when the file cannot be opened or writing. That would result in
11+
``stream_copy_to_stream(): Argument ``#2 <https://github.com/neos/flow-development-collection/issues/2>``_($to) must be of type resource, bool given``
12+
for recent PHP versions.
13+
14+
**Review instructions**
15+
16+
Probably a bit tricky, but you need to create a scenario, where the target file already
17+
exists and cannot be written to.
18+
19+
20+
* Packages: ``Flow``
21+
22+
`BUGFIX: Drop use of `E_STRICT` to fix PHP 8.4 deprecation <https://github.com/neos/flow-development-collection/pull/3437>`_
23+
----------------------------------------------------------------------------------------------------------------------------
24+
25+
The use of ``E_STRICT`` is deprecated as of PHP 8.4, so this fixes deprecation warnings. Furthermore, the constant is no longer useful…
26+
27+
In PHP 5.4, the functionality of ``E_STRICT`` was incorporated into ``E_ALL``, meaning strict standards notices are included in the ``E_ALL`` error level. As a result, there is no need to use ``E_STRICT`` separately starting with PHP 5.4. This change is documented in the PHP manual under the migration guide for PHP 7.0, which states:
28+
29+
> All of the E_STRICT notices have been reclassified to other levels.
30+
> The E_STRICT constant is retained, so calls like
31+
> ``error_reporting(E_ALL|E_STRICT)`` will not cause an error.
32+
33+
(see https://www.php.net/manual/en/migration70.incompatible)
34+
35+
36+
* Packages: ``Flow``
37+
38+
`BUGFIX: Silence warning in `readCacheFile()` <https://github.com/neos/flow-development-collection/pull/3438>`_
39+
---------------------------------------------------------------------------------------------------------------
40+
41+
readCacheFile() in SimpleFileBackend does fopen(). It wraps it into a try-catch clause and checks the result, but it still produces a warning if the file does not exist:
42+
43+
``Warning: fopen(/application/Data/Temporary/…): Failed to open stream: No such file or directory``
44+
45+
The only way to suppress that warning is to use the shut-up operator (``@``) in this place. Given that everything that can go wrong here is taken care of, I think this is fine.
46+
47+
48+
* Packages: ``Flow`` ``Cache``
49+
50+
`TASK: Handle non-integer error codes in throwabe FileStorage <https://github.com/neos/flow-development-collection/pull/3416>`_
51+
-------------------------------------------------------------------------------------------------------------------------------
52+
53+
This will no longer swallow certain error codes but instead emit them in the message.
54+
55+
56+
* Packages: ``Flow``
57+
58+
`TASK: Fix override of runBare() in functional test <https://github.com/neos/flow-development-collection/pull/3421>`_
59+
---------------------------------------------------------------------------------------------------------------------
60+
61+
As of PHPUnit 11 ``runBare()`` is a ``final`` method.
62+
63+
This was written ages ago by Sebastian Kurfürst, who recently said:
64+
65+
> IMHO we wanted to run each test twice to run it without cache and
66+
> then with cache. But it seems this was broken anyways since a long
67+
> time – so we can drop it
68+
69+
70+
* Packages: ``Flow``
71+
72+
`TASK: Run pipeline also in PHP 8.4 <https://github.com/neos/flow-development-collection/pull/3436>`_
73+
-----------------------------------------------------------------------------------------------------
74+
75+
76+
77+
* Packages: ``Flow`` ``.github``
78+
79+
`Detailed log <https://github.com/neos/flow-development-collection/compare/8.3.13...8.3.14>`_
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Neos.Flow/Tests/Functional/ObjectManagement/DependencyInjectionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public function propertiesOfVariousPrimitiveTypeAreSetInSingletonPropertiesIfCon
7676
self::assertSame(['iAm' => ['aConfigured' => 'arrayValue']], $objectC->getProtectedArrayPropertySetViaObjectsYaml());
7777
self::assertTrue($objectC->getProtectedBooleanTruePropertySetViaObjectsYaml());
7878
self::assertFalse($objectC->getProtectedBooleanFalsePropertySetViaObjectsYaml());
79+
self::assertNull($objectC->getProtectedNullPropertySetViaObjectsYaml());
7980
}
8081

8182
/**

Neos.Flow/Tests/Functional/ObjectManagement/Fixtures/SingletonClassC.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class SingletonClassC
6060
*/
6161
protected $protectedBooleanFalsePropertySetViaObjectsYaml;
6262

63+
/**
64+
* @var null
65+
*/
66+
protected $protectedNullPropertySetViaObjectsYaml;
67+
6368
/**
6469
* @var array
6570
*/
@@ -123,6 +128,11 @@ public function getProtectedBooleanFalsePropertySetViaObjectsYaml()
123128
return $this->protectedBooleanFalsePropertySetViaObjectsYaml;
124129
}
125130

131+
public function getProtectedNullPropertySetViaObjectsYaml()
132+
{
133+
return $this->protectedNullPropertySetViaObjectsYaml;
134+
}
135+
126136
/**
127137
* @return array
128138
*/

0 commit comments

Comments
 (0)