From 75fb7ba155a4f8eee929e8b41617dacba67bd508 Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Tue, 27 Oct 2026 18:17:21 +0000 Subject: [PATCH] - Added some attributes-related manipulation in SearchRequest trait - Removed default page setting based on query params adn - Added DateTime format doc --- docs/100-datetime-format.md | 64 +++++++++++++++++++ src/Entity/Field/DatetimeTrait.php | 2 + .../SearchRequestFromRequestTrait.php | 24 +++++-- 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 docs/100-datetime-format.md diff --git a/docs/100-datetime-format.md b/docs/100-datetime-format.md new file mode 100644 index 0000000..8611394 --- /dev/null +++ b/docs/100-datetime-format.md @@ -0,0 +1,64 @@ +#### Date Field Symbol Table + +source: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table + +| Symbol | Meaning | Pattern | Example Output | +| --- | --- | --- | --- | +| `G` | era designator | `G`, `GG`, or `GGG`
`GGGG`
`GGGGG` | AD
Anno Domini
A | +| `y` | year | `yy`
`y` or `yyyy` | 96
1996 | +| `Y` | year in “Week of Year” based calendars in which the year transition occurs on a week boundary; may differ from calendar year ‘y’ near a year transition. This year designation is used with pattern character ‘w’ in the ISO 8601 year-week calendar, for example. | `Y` | 1997 | +| `u` | extended year | `u` | 4601 | +| `U` | cyclic year name, as in Chinese lunar calendar | `U` | 甲子 | +| `r` | related Gregorian year | `r` | 1996 | +| `Q` | quarter | `Q`
`QQ`
`QQQ`
`QQQQ`
`QQQQQ` | 2
02
Q2
2nd quarter
2 | +| `q` | stand-alone quarter | `q`
`qq`
`qqq`
`qqqq`
`qqqqq` | 2
02
Q2
2nd quarter
2 | +| `M` | month in year | `M`
`MM`
`MMM`
`MMMM`
`MMMMM` | 9
09
Sep
September
S | +| `L` | stand-alone month in year | `L`
`LL`
`LLL`
`LLLL`
`LLLLL` | 9
09
Sep
September
S | +| `w` | week of year | `w`
`ww` | 27
27 | +| `W` | week of month | `W` | 2 | +| `d` | day in month | `d`
`dd` | 2
02 | +| `D` | day of year | `D` | 189 | +| `F` | day of week in month | `F` | 2 (2nd Wed in July) | +| `g` | modified julian day | `g` | 2451334 | +| `E` | day of week | `E,` `EE`, or `EEE`
`EEEE`
`EEEEE`
`EEEEEE` | Tue
Tuesday
T
Tu | +| `e` | local day of week
example: if Monday is 1st day, Tuesday is 2nd ) | `e`
`ee`
`eee`
`eeee`
`eeeee`
`eeeeee` | 2
02
Tue
Tuesday
T
Tu | +| `c` | stand-alone local day of week | `c` or `cc`
`ccc`
`cccc`
`ccccc`
`cccccc` | 2
Tue
Tuesday
T
Tu | +| `a` | AM or PM | `a`, `aa`, or `aaa`
`aaaa`
`aaaaa` | PM [abbrev]
PM [wide]
p | +| `b` | am, pm, noon, midnight | `b`, `bb`, or `bbb`
`bbbb`
`bbbbb` | mid.
midnight
md | +| `B` | flexible day periods | `B`, `BB`, or `BBB`
`BBBB`
`BBBBB` | at night [abbrev]
at night [wide]
at night [narrow] | +| `h` | hour in am/pm (1~12) | `h`
`hh` | 7
07 | +| `H` | hour in day (0~23) | `H`
`HH` | 0
00 | +| `k` | hour in day (1~24) | `k`
`kk` | 24
24 | +| `K` | hour in am/pm (0~11) | `K`
`KK` | 0
00 | +| `m` | minute in hour | `m`
`mm` | 4
04 | +| `s` | second in minute | `s`
`ss` | 5
05 | +| `S` | fractional second - truncates (like other time fields)
to the count of letters when formatting. Appends
zeros if more than 3 letters specified. Truncates at
three significant digits when parsing. | `S`
`SS`
`SSS`
`SSSS` | 2
23
235
2350 | +| `A` | milliseconds in day | `A` | 61201235 | +| `z` | Time Zone: specific non-location | `z`, `zz`, or `zzz`
`zzzz` | PDT
Pacific Daylight Time | +| `Z` | Time Zone: ISO8601 basic hms? / RFC 822
Time Zone: long localized GMT (=OOOO)
Time Zone: ISO8601 extended hms? (=XXXXX) | `Z`, `ZZ`, or `ZZZ`
`ZZZZ`
`ZZZZZ` | -0800
GMT-08:00
-08:00, -07:52:58, Z | +| `O` | Time Zone: short localized GMT
Time Zone: long localized GMT (=ZZZZ) | `O`
`OOOO` | GMT-8
GMT-08:00 | +| `v` | Time Zone: generic non-location
(falls back first to VVVV) | `v`
`vvvv` | PT
Pacific Time or Los Angeles Time | +| `V` | Time Zone: short time zone ID
Time Zone: long time zone ID
Time Zone: time zone exemplar city
Time Zone: generic location (falls back to OOOO) | `V`
`VV`
`VVV`
`VVVV` | uslax
America/Los_Angeles
Los Angeles
Los Angeles Time | +| `X` | Time Zone: ISO8601 basic hm?, with Z for 0
Time Zone: ISO8601 basic hm, with Z
Time Zone: ISO8601 extended hm, with Z
Time Zone: ISO8601 basic hms?, with Z
Time Zone: ISO8601 extended hms?, with Z | `X`
`XX`
`XXX`
`XXXX`
`XXXXX` | -08, +0530, Z
-0800, Z
-08:00, Z
-0800, -075258, Z
-08:00, -07:52:58, Z | +| `x` | Time Zone: ISO8601 basic hm?, without Z for 0
Time Zone: ISO8601 basic hm, without Z
Time Zone: ISO8601 extended hm, without Z
Time Zone: ISO8601 basic hms?, without Z
Time Zone: ISO8601 extended hms?, without Z | `x`
`xx`
`xxx`
`xxxx`
`xxxxx` | -08, +0530
-0800
-08:00
-0800, -075258
-08:00, -07:52:58 | +| `'` | escape for text | `'` | (nothing) | +| `''` | two single quotes produce one | `''` | ' | + +> :point_right: **Note**: *Any characters in the pattern that are not in the ranges of +['a'..'z'] and ['A'..'Z'] will be treated as quoted text. For instance, +characters like `':'`, `'.'`, `' '`, `'#'` and `'@'` will appear in the resulting time +text even they are not enclosed within single quotes. The single quote is used to +'escape' letters. Two single quotes in a row, whether inside or outside a quoted +sequence, represent a 'real' single quote.* + +> :point_right: **Note**: *A pattern containing any invalid pattern letter results in a failing `UErrorCode` +result during formatting or parsing.* + +| Format Pattern | Result | +| --- | --- | +| `"yyyy.MM.dd G 'at' HH:mm:ss zzz"` | "1996.07.10 AD at 15:08:56 PDT" | +| `"EEE, MMM d, ''yy"` | "Wed, July 10, '96" | +| `"h:mm a"` | "12:08 PM" | +| `"hh 'o''clock' a, zzzz"` | "12 o'clock PM, Pacific Daylight Time" | +| `"K:mm a, z"` | "0:00 PM, PST" | +| `"yyyyy.MMMM.dd GGG hh:mm aaa"` | "01996.July.10 AD 12:08 PM" | \ No newline at end of file diff --git a/src/Entity/Field/DatetimeTrait.php b/src/Entity/Field/DatetimeTrait.php index e8f96ff..bf369c9 100644 --- a/src/Entity/Field/DatetimeTrait.php +++ b/src/Entity/Field/DatetimeTrait.php @@ -49,6 +49,8 @@ trait DatetimeTrait return strftime($format, $this->getTimestamp()); } + # patterns: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table + # see also 100-datetime-format.md file in DOC public function formatLocaleIntl(int $dateFormatter = \IntlDateFormatter::LONG, int $timeFormatter = \IntlDateFormatter::NONE, ? string $pattern = null) : string { $formatter = new \IntlDateFormatter(\Locale::getDefault(), $dateFormatter, $timeFormatter, \date_default_timezone_get(), \IntlDateFormatter::GREGORIAN, $pattern); diff --git a/src/SearchRequest/SearchRequestFromRequestTrait.php b/src/SearchRequest/SearchRequestFromRequestTrait.php index f082a53..f1d10d0 100644 --- a/src/SearchRequest/SearchRequestFromRequestTrait.php +++ b/src/SearchRequest/SearchRequestFromRequestTrait.php @@ -61,7 +61,8 @@ trait SearchRequestFromRequestTrait { $this->objectReflection = ObjectReflection::fromClass(static::class)->reflectClass(); - $this->page = $data['page'] ?? 1; + # REMOVED - this could cause legacy problems, kept in case of a quick uncomment is needed + # $this->page = $data['page'] ?? 1; $this->applyValues( fn($propertyName, $attribute) => $data[$propertyName] ?? null @@ -86,9 +87,9 @@ trait SearchRequestFromRequestTrait $this->prepare($request); } - $queryParams = new \ArrayObject(array_filter($request->getQueryParams(), function($i) { return ! is_null($i) && $i !== ""; })); - - $this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1; + # REMOVED - this could cause legacy problems, kept in case of a quick uncomment is needed + # $queryParams = new \ArrayObject(array_filter($request->getQueryParams(), function($i) { return ! is_null($i) && $i !== ""; })); + # $this->page = $queryParams->offsetExists('page') ? $queryParams['page'] : 1; $this->applyValues( fn($propertyName, $attribute) =>$this->getValueFromSource($request, $propertyName, $attribute) @@ -155,6 +156,21 @@ trait SearchRequestFromRequestTrait } } + public function getPropertyAttribute(string $name) : ? Attribute\SearchParameter + { + foreach($this->objectReflection->getProperties() as $propertyName => $property) { + if ($propertyName === $name) { + $attribute = $property->getAttribute(Attribute\SearchParameter::class)->object ?? false; + + if ($attribute) { + return $attribute; + } + } + } + + return null; + } + protected function applyValues(\Closure $getValue) : void { foreach($this->objectReflection->getProperties() as $propertyName => $property) {