-
Notifications
You must be signed in to change notification settings - Fork 2k
feat: support object values in array dot helpers #10226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.8
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,7 +13,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace CodeIgniter\Helpers\Array; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use ArrayAccess; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use CodeIgniter\Exceptions\InvalidArgumentException; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use ReflectionMethod; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @internal This is internal implementation for the framework. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -34,11 +36,12 @@ final class ArrayHelper | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @used-by dot_array_search() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param string $index The index as dot array syntax. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param string $index The index as dot array syntax. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array|bool|int|object|string|null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<array-key, mixed>|bool|int|object|string|null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function dotSearch(string $index, array $array) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function dotSearch(string $index, array|object $array) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::arraySearchDot(self::convertToArray($index), $array); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -78,9 +81,12 @@ private static function convertToArray(string $index): array | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @used-by dotSearch() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array|bool|float|int|object|string|null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param list<string> $indexes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<array-key, mixed>|bool|float|int|object|string|null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function arraySearchDot(array $indexes, array $array) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function arraySearchDot(array $indexes, array|object $array) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If index is empty, returns null. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($indexes === []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -90,7 +96,7 @@ private static function arraySearchDot(array $indexes, array $array) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Grab the current index | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $currentIndex = array_shift($indexes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! isset($array[$currentIndex]) && $currentIndex !== '*') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! self::valueExists($array, $currentIndex) && $currentIndex !== '*') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -99,7 +105,7 @@ private static function arraySearchDot(array $indexes, array $array) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| $answer = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foreach ($array as $value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($value) && ! is_object($value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -119,12 +125,14 @@ private static function arraySearchDot(array $indexes, array $array) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If this is the last index, make sure to return it now, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // and not try to recurse through things. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($indexes === []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $array[$currentIndex]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::value($array, $currentIndex); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $value = self::value($array, $currentIndex); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Do we need to recursively search this value? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($array[$currentIndex]) && $array[$currentIndex] !== []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::arraySearchDot($indexes, $array[$currentIndex]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ((is_array($value) && $value !== []) || is_object($value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::arraySearchDot($indexes, $value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Otherwise, not found. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -136,9 +144,9 @@ private static function arraySearchDot(array $indexes, array $array) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * If wildcard `*` is used, all items for the key after it must have the key. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed> $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function dotHas(string $index, array $array): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function dotHas(string $index, array|object $array): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::ensureValidWildcardPattern($index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -154,10 +162,10 @@ public static function dotHas(string $index, array $array): bool | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Recursively check key existence by dot path, including wildcard support. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed> $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param list<string> $indexes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param list<string> $indexes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function hasByDotPath(array $array, array $indexes): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function hasByDotPath(array|object $array, array $indexes): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($indexes === []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -167,27 +175,29 @@ private static function hasByDotPath(array $array, array $indexes): bool | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($currentIndex === '*') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foreach ($array as $item) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normalize first: $iterable = is_object($array) ? self::toIterable($array) : $array; |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($item) || ! self::hasByDotPath($item, $indexes)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ((! is_array($item) && ! is_object($item)) || ! self::hasByDotPath($item, $indexes)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! array_key_exists($currentIndex, $array)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! self::keyExists($array, $currentIndex)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($indexes === []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($array[$currentIndex])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $value = self::value($array, $currentIndex); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($value) && ! is_object($value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::hasByDotPath($array[$currentIndex], $indexes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self::hasByDotPath($value, $indexes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -333,13 +343,16 @@ public static function groupBy(array $array, array $indexes, bool $includeEmpty | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Recursively attach $row to the $indexes path of values found by | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * `dot_array_search()`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * dot syntax. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @used-by groupBy() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $row | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param list<string> $indexes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function arrayAttachIndexedValue( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| array $result, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| array $row, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| array|object $row, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| array $indexes, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool $includeEmpty, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): array { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -349,7 +362,7 @@ private static function arrayAttachIndexedValue( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $value = dot_array_search($index, $row); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $value = self::dotSearch($index, $row); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_scalar($value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $value = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -447,6 +460,118 @@ public static function sortValuesByNatural(array &$array, $sortByIndex = null): | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function keyExists(array|object $data, string $key): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($data)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return array_key_exists($key, $data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $array = self::objectToArray($data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($array !== null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return array_key_exists($key, $array); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($data instanceof ArrayAccess && $data->offsetExists($key)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (array_key_exists($key, get_object_vars($data))) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return isset($data->{$key}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function valueExists(array|object $data, string $key): bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($data)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return isset($data[$key]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $array = self::objectToArray($data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($array !== null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return isset($array[$key]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($data instanceof ArrayAccess && $data->offsetExists($key)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isset(get_object_vars($data)[$key])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return isset($data->{$key}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<array-key, mixed>|object $data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function value(array|object $data, string $key): mixed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($data)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $data[$key]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $array = self::objectToArray($data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($array !== null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $array[$key]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($data instanceof ArrayAccess && $data->offsetExists($key)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $data->offsetGet($key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $properties = get_object_vars($data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (array_key_exists($key, $properties)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $properties[$key]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $data->{$key}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<array-key, mixed>|null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static function objectToArray(object $data): ?array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (method_exists($data, 'toRawArray')) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $method = new ReflectionMethod($data, 'toRawArray'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($method->isPublic() && $method->getNumberOfRequiredParameters() === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $array = $data->toRawArray(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($array)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $array; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (method_exists($data, 'toArray')) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $method = new ReflectionMethod($data, 'toArray'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($method->isPublic() && $method->getNumberOfRequiredParameters() === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $array = $data->toArray(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($array)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $array; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+548
to
+570
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Creating reflection instances on every property access is very expensive. We only want to support entities. This gives users the cast values they would expect.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Throws exception for invalid wildcard patterns. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -606,7 +731,7 @@ private static function projectByDotPath( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| $currentIndex = array_shift($indexes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($currentIndex === '*') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($source)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($source) && ! is_object($source)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -617,10 +742,10 @@ private static function projectByDotPath( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (! is_array($source) || ! array_key_exists($currentIndex, $source)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ((! is_array($source) && ! is_object($source)) || ! self::keyExists($source, $currentIndex)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::projectByDotPath($source[$currentIndex], $indexes, $result, [...$prefix, $currentIndex]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self::projectByDotPath(self::value($source, $currentIndex), $indexes, $result, [...$prefix, $currentIndex]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
$arrayis an object this iterates public properties via PHP default object iteration. For an Entity, that would give you internal properties like$_options,$_cast, etc. - not the data attributes.You need to normalize the object to an array before iterating:
Same applies to
hasByDotPath.