diff --git a/src/App/Order/Model/PdkProduct.php b/src/App/Order/Model/PdkProduct.php index f43a24065..e92211393 100644 --- a/src/App/Order/Model/PdkProduct.php +++ b/src/App/Order/Model/PdkProduct.php @@ -84,6 +84,7 @@ public function toStorableArray(): array /** * @return \MyParcelNL\Pdk\Settings\Model\ProductSettings + * @noinspection PhpUnused */ protected function getMergedSettingsAttribute(): ProductSettings { @@ -121,12 +122,13 @@ private function resolveMergedSettings(): ProductSettings return $settings; } + /** @var \MyParcelNL\Pdk\Types\Contract\TriStateServiceInterface $triStateService */ $triStateService = Pdk::get(TriStateServiceInterface::class); foreach ($settings->getAttributes() as $key => $value) { $coerced = $triStateService->coerce($settings->getAttribute($key)); - if ($coerced === '-1') { + if ((string) TriStateService::INHERIT === $coerced) { $coerced = (int) $coerced; } diff --git a/src/Base/Concern/HasAttributes.php b/src/Base/Concern/HasAttributes.php index c7be71d9a..0e29405dd 100644 --- a/src/Base/Concern/HasAttributes.php +++ b/src/Base/Concern/HasAttributes.php @@ -14,12 +14,12 @@ use MyParcelNL\Pdk\Base\Exception\InvalidCastException; use MyParcelNL\Pdk\Base\Support\Arr; use MyParcelNL\Pdk\Base\Support\Collection; +use MyParcelNL\Pdk\Base\Support\Str; use MyParcelNL\Pdk\Base\Support\Utils; use MyParcelNL\Pdk\Facade\Logger; use MyParcelNL\Pdk\Facade\Pdk; use MyParcelNL\Pdk\Types\Contract\TriStateServiceInterface; use MyParcelNL\Pdk\Types\Service\TriStateService; -use MyParcelNL\Pdk\Base\Support\Str; use Throwable; /** @@ -183,7 +183,7 @@ public function getAttribute(string $key) return null; } - $key = Utils::changeCase($key); + $key = Str::changeCase($key); if ($this->isGuarded($key)) { return $this->guarded[$key]; @@ -269,7 +269,7 @@ public function only($attributes, ?int $flags = null): array */ public function setAttribute(string $key, $value): self { - $key = $this->convertDeprecatedKey(Utils::changeCase($key)); + $key = $this->convertDeprecatedKey(Str::changeCase($key)); if ($this->isGuarded($key)) { return $this; @@ -301,8 +301,8 @@ public function setAttribute(string $key, $value): self protected function addCastAttributesToArray(array $attributes, array $mutatedAttributes, ?int $flags): array { foreach ($this->getCasts() as $key => $value) { - $originalKey = Utils::changeCase($key); - $key = Utils::changeCase($key, $flags); + $originalKey = Str::changeCase($key); + $key = Str::changeCase($key, $flags); if (! array_key_exists($key, $attributes) || in_array($key, $mutatedAttributes, true)) { continue; @@ -358,8 +358,8 @@ protected function addCastAttributesToArray(array $attributes, array $mutatedAtt protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes, ?int $flags): array { foreach ($mutatedAttributes as $key) { - $originalKey = Utils::changeCase($key); - $key = Utils::changeCase($key, $flags); + $originalKey = Str::changeCase($key); + $key = Str::changeCase($key, $flags); if (! array_key_exists($key, $attributes)) { continue; @@ -585,7 +585,7 @@ protected function getCastAttributeValue(string $string) protected function getCastType(string $key): ?string { $casts = $this->getCasts(); - $normalizedKey = Utils::changeCase($key); + $normalizedKey = Str::changeCase($key); return $casts[$normalizedKey]; } @@ -597,7 +597,7 @@ protected function getCastType(string $key): ?string */ protected function getCasts(): array { - return Utils::changeArrayKeysCase($this->casts); + return $this->casts; } /** diff --git a/src/Base/Model/Model.php b/src/Base/Model/Model.php index 0b40e57fd..073111aca 100644 --- a/src/Base/Model/Model.php +++ b/src/Base/Model/Model.php @@ -10,8 +10,9 @@ use MyParcelNL\Pdk\Base\Contract\Arrayable; use MyParcelNL\Pdk\Base\Contract\ModelInterface; use MyParcelNL\Pdk\Base\Contract\StorableArrayable; -use MyParcelNL\Pdk\Base\Support\Utils; +use MyParcelNL\Pdk\Base\Support\Arr; use MyParcelNL\Pdk\Base\Support\Str; +use MyParcelNL\Pdk\Base\Support\Utils; /** * @SuppressWarnings(PHPMD.TooManyPublicMethods) @@ -36,6 +37,11 @@ class Model implements StorableArrayable, ArrayAccess, ModelInterface */ protected $cloned = false; + /** + * @var array + */ + protected $lazy = []; + /** * @param null|array $data */ @@ -43,14 +49,19 @@ public function __construct(?array $data = null) { $this->bootIfNotBooted(); - $this->guarded = Utils::changeArrayKeysCase($this->guarded); - $this->attributes = $this->guarded + Utils::changeArrayKeysCase($this->attributes); + $this->attributes = $this->guarded + $this->attributes; $this->initializeTraits(); - $convertedData = Utils::changeArrayKeysCase($data ?? []); + // filter out the items that are in $this->lazy + $attributes = Utils::changeArrayKeysCase($data ?? []) + $this->attributes; - $this->fill($convertedData + $this->attributes); + $filteredAttributes = count($this->lazy) + ? Arr::where($attributes, function ($value, $key) { + return $value !== null || ! $this->isLazy($key); + }) : $attributes; + + $this->fill($filteredAttributes); } public static function isBooted(): bool @@ -215,7 +226,7 @@ public function offsetSet($offset, $value): void */ public function offsetUnset($offset): void { - unset($this->attributes[(Utils::changeCase($offset))]); + unset($this->attributes[(Str::changeCase($offset))]); } /** @@ -293,6 +304,16 @@ protected function initializeTraits(): void } } + /** + * @param string $key + * + * @return bool + */ + private function isLazy(string $key): bool + { + return in_array($key, $this->lazy, true); + } + /** * @param array $attributes * @@ -303,7 +324,7 @@ private function normalizeAttributes(array $attributes): array $normalizedAttributes = []; foreach ($attributes as $initialKey => $value) { - $caseKey = Utils::changeCase($initialKey); + $caseKey = Str::changeCase($initialKey); $key = $this->convertDeprecatedKey($caseKey); if (array_key_exists($key, $normalizedAttributes)) { diff --git a/src/Base/Support/Str.php b/src/Base/Support/Str.php index 5b731fd9b..18c72eff1 100644 --- a/src/Base/Support/Str.php +++ b/src/Base/Support/Str.php @@ -4,8 +4,28 @@ namespace MyParcelNL\Pdk\Base\Support; +use MyParcelNL\Pdk\Base\Contract\Arrayable; + class Str extends \Illuminate\Support\Str { + /** + * @var array + */ + private static $flagCaseCache = []; + + /** + * @param string $string + * @param null|int $flags + * + * @return string + */ + public static function changeCase(string $string, ?int $flags = null): string + { + $case = self::getFlagCase($flags); + + return self::{$case}($string); + } + /** * @param string $value * @param int $limit @@ -17,4 +37,32 @@ public static function limit($value, $limit = 100, $end = '...'): string { return parent::limit($value, $limit - strlen($end), $end); } + + /** + * @param null|int $flags + * + * @return string + */ + private static function getFlagCase(?int $flags = null): string + { + if (! isset(self::$flagCaseCache[$flags])) { + $case = 'camel'; + + if ($flags & Arrayable::CASE_SNAKE) { + $case = 'snake'; + } + + if ($flags & Arrayable::CASE_KEBAB) { + $case = 'kebab'; + } + + if ($flags & Arrayable::CASE_STUDLY) { + $case = 'studly'; + } + + self::$flagCaseCache[$flags] = $case; + } + + return self::$flagCaseCache[$flags]; + } } diff --git a/src/Base/Support/Utils.php b/src/Base/Support/Utils.php index c283cfac7..5bdd0ecdb 100644 --- a/src/Base/Support/Utils.php +++ b/src/Base/Support/Utils.php @@ -67,26 +67,13 @@ public static function changeArrayKeysCase(array $array, ?int $flags = null): ar $value = self::changeArrayKeysCase($value, $flags); } - $newKey = self::changeCase($key, $flags); + $newKey = Str::changeCase($key, $flags); $newArray[$newKey] = $value; } return $newArray; } - /** - * @param string $string - * @param null|int $flags - * - * @return string - */ - public static function changeCase(string $string, ?int $flags = null): string - { - $case = self::getFlagCase($flags); - - return Str::{$case}($string); - } - /** * Get the class "basename" of the given object / class. * @@ -264,26 +251,4 @@ public static function toRecursiveCollection(array $array): Collection return $collection; } - - /** - * @param null|int $flags - * - * @return string - */ - private static function getFlagCase(?int $flags = null): string - { - if ($flags & Arrayable::CASE_SNAKE) { - return 'snake'; - } - - if ($flags & Arrayable::CASE_KEBAB) { - return 'kebab'; - } - - if ($flags & Arrayable::CASE_STUDLY) { - return 'studly'; - } - - return 'camel'; - } } diff --git a/src/Context/Model/ContextBag.php b/src/Context/Model/ContextBag.php index 67953c1c6..c8e90b9b0 100644 --- a/src/Context/Model/ContextBag.php +++ b/src/Context/Model/ContextBag.php @@ -39,4 +39,19 @@ class ContextBag extends Model Context::ID_PRODUCT_DATA => ProductDataContextCollection::class, Context::ID_PRODUCT_SETTINGS_VIEW => ProductSettingsViewContext::class, ]; + + public $lazy = [ + Context::ID_GLOBAL, + Context::ID_DYNAMIC, + Context::ID_CHECKOUT, + Context::ID_ORDER_DATA, + Context::ID_PLUGIN_SETTINGS_VIEW, + Context::ID_PRODUCT_DATA, + Context::ID_PRODUCT_SETTINGS_VIEW, + ]; + + public function __construct(?array $data = null) + { + parent::__construct($data); + } } diff --git a/src/Fulfilment/Model/ShippedItem.php b/src/Fulfilment/Model/ShippedItem.php index 1cd69bde2..6fc70b2ec 100644 --- a/src/Fulfilment/Model/ShippedItem.php +++ b/src/Fulfilment/Model/ShippedItem.php @@ -13,12 +13,12 @@ class ShippedItem extends Model { public $attributes = [ - 'order_line_identifier' => null, - 'quantity' => 1, + 'orderLineIdentifier' => null, + 'quantity' => 1, ]; protected $casts = [ - 'order_line_identifier' => 'string', - 'quantity' => 'int', + 'orderLineIdentifier' => 'string', + 'quantity' => 'int', ]; } diff --git a/src/Shipment/Repository/ShipmentRepository.php b/src/Shipment/Repository/ShipmentRepository.php index 677562383..aa255f349 100644 --- a/src/Shipment/Repository/ShipmentRepository.php +++ b/src/Shipment/Repository/ShipmentRepository.php @@ -132,7 +132,7 @@ public function fetchLabelPdf( */ public function getByReferenceIdentifiers(array $referenceIdentifiers, ?int $size = null): ShipmentCollection { - return $this->query(['reference_identifier' => $referenceIdentifiers, 'size' => $size]); + return $this->query(['referenceIdentifier' => $referenceIdentifiers, 'size' => $size]); } /** diff --git a/tests/Mocks/MockCastingModel.php b/tests/Mocks/MockCastingModel.php index 5048fb212..31ba87f18 100644 --- a/tests/Mocks/MockCastingModel.php +++ b/tests/Mocks/MockCastingModel.php @@ -31,7 +31,7 @@ class MockCastingModel extends Model { protected $attributes = [ - 'collection' => [ + 'collection' => [ [ 'value' => 1, ], @@ -39,56 +39,56 @@ class MockCastingModel extends Model 'value' => 2, ], ], - 'object' => ['property' => 'hello'], - 'date' => '2022-01-10', - 'datetime' => '2022-01-10 14:03:00', - 'date_from_arr' => [ - 'date' => '2022-12-25 17:02:32.000000', - 'timezone_type' => 3, - 'timezone' => 'Europe/Amsterdam', + 'object' => ['property' => 'hello'], + 'date' => '2022-01-10', + 'datetime' => '2022-01-10 14:03:00', + 'dateFromArr' => [ + 'date' => '2022-12-25 17:02:32.000000', + 'timezoneType' => 3, + 'timezone' => 'Europe/Amsterdam', ], - 'timestamp' => '2022-01-10 14:03:00', - 'string_bool' => 'true', - 'string_false_bool' => 'false', - 'string_false_int' => 'false', - 'string_int' => '4', - 'string_true_bool' => 'true', - 'string_true_int' => 'true', - 'int_string' => 1234, - 'int_float' => 2, - 'string_float' => '2', - 'without_a_cast' => 'whatever', - 'null' => null, - 'tristate1' => TriStateService::ENABLED, - 'tristate2' => TriStateService::INHERIT, - 'tristateCoerced1' => 1000, - 'tristateCoerced2' => TriStateService::INHERIT, - 'tristateString1' => 'hello', - 'tristateString2' => TriStateService::INHERIT, + 'timestamp' => '2022-01-10 14:03:00', + 'stringBool' => 'true', + 'stringFalseBool' => 'false', + 'stringFalseInt' => 'false', + 'stringInt' => '4', + 'stringTrueBool' => 'true', + 'stringTrueInt' => 'true', + 'intString' => 1234, + 'intFloat' => 2, + 'stringFloat' => '2', + 'withoutACast' => 'whatever', + 'null' => null, + 'tristate1' => TriStateService::ENABLED, + 'tristate2' => TriStateService::INHERIT, + 'tristateCoerced1' => 1000, + 'tristateCoerced2' => TriStateService::INHERIT, + 'tristateString1' => 'hello', + 'tristateString2' => TriStateService::INHERIT, ]; protected $casts = [ - 'collection' => Collection::class, - 'object' => MockCastModel::class, - 'date' => 'date', - 'datetime' => 'datetime', - 'date_from_arr' => DateTime::class, - 'timestamp' => 'timestamp', - 'string_bool' => 'bool', - 'string_false_bool' => 'bool', - 'string_false_int' => 'int', - 'string_int' => 'int', - 'string_true_bool' => 'bool', - 'string_true_int' => 'int', - 'int_string' => 'string', - 'int_float' => 'float', - 'string_float' => 'float', - 'null' => 'string', - 'tristate1' => TriStateService::TYPE_STRICT, - 'tristate2' => TriStateService::TYPE_STRICT, - 'tristateCoerced1' => TriStateService::TYPE_COERCED, - 'tristateCoerced2' => TriStateService::TYPE_COERCED, - 'tristateString1' => TriStateService::TYPE_STRING, - 'tristateString2' => TriStateService::TYPE_STRING, + 'collection' => Collection::class, + 'object' => MockCastModel::class, + 'date' => 'date', + 'datetime' => 'datetime', + 'dateFromArr' => DateTime::class, + 'timestamp' => 'timestamp', + 'stringBool' => 'bool', + 'stringFalseBool' => 'bool', + 'stringFalseInt' => 'int', + 'stringInt' => 'int', + 'stringTrueBool' => 'bool', + 'stringTrueInt' => 'int', + 'intString' => 'string', + 'intFloat' => 'float', + 'stringFloat' => 'float', + 'null' => 'string', + 'tristate1' => TriStateService::TYPE_STRICT, + 'tristate2' => TriStateService::TYPE_STRICT, + 'tristateCoerced1' => TriStateService::TYPE_COERCED, + 'tristateCoerced2' => TriStateService::TYPE_COERCED, + 'tristateString1' => TriStateService::TYPE_STRING, + 'tristateString2' => TriStateService::TYPE_STRING, ]; } diff --git a/tests/Mocks/MockNestedModel.php b/tests/Mocks/MockNestedModel.php index 6df68aa26..2256e8dd4 100644 --- a/tests/Mocks/MockNestedModel.php +++ b/tests/Mocks/MockNestedModel.php @@ -9,12 +9,12 @@ class MockNestedModel extends Model { public $attributes = [ - 'my_value' => null, - 'myModel' => null, + 'myValue' => null, + 'myModel' => null, ]; protected $casts = [ - 'my_value' => 'string', - 'myModel' => MockNestedModel::class, + 'myValue' => 'string', + 'myModel' => MockNestedModel::class, ]; } diff --git a/tests/Unit/Base/Model/ModelToArrayTest.php b/tests/Unit/Base/Model/ModelToArrayTest.php index 3f4f325c7..6d7563ce8 100644 --- a/tests/Unit/Base/Model/ModelToArrayTest.php +++ b/tests/Unit/Base/Model/ModelToArrayTest.php @@ -9,10 +9,10 @@ use MyParcelNL\Pdk\Tests\Mocks\MockNestedModel; const MODEL_DATA = [ - 'my_value' => 1, - 'myModel' => [ + 'myValue' => 1, + 'myModel' => [ 'myModel' => [ - 'my_value' => null, + 'myValue' => null, ], ], ];