diff --git a/src/Annotations/Output/OutputDateFormat.php b/src/Annotations/Output/OutputDateFormat.php index efd51c2..e2682f2 100755 --- a/src/Annotations/Output/OutputDateFormat.php +++ b/src/Annotations/Output/OutputDateFormat.php @@ -13,9 +13,6 @@ use DateTimeZone; use Exception; -/** - * toArray 输出值为 固定日期格式 默认 YYYY-MM-DD HH:ii:ss的日期格式 - */ #[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS)] class OutputDateFormat implements OutValueCastInterface { diff --git a/src/Casts/Normalizer/ArrayNormalizerCast.php b/src/Casts/Normalizer/ArrayNormalizerCast.php index c6527a5..46ef4d5 100644 --- a/src/Casts/Normalizer/ArrayNormalizerCast.php +++ b/src/Casts/Normalizer/ArrayNormalizerCast.php @@ -8,15 +8,15 @@ class ArrayNormalizerCast implements NormalizerCastInterface { public function match(mixed $values): bool { - return is_object($values) && method_exists($values, 'toArray'); + return is_object($values) && method_exists($values, 'toArray'); } public function resolve(mixed $values): mixed { - if($this->match($values)){ + if ($this->match($values)) { return $values->toArray(); } return $values; } -} \ No newline at end of file +} diff --git a/src/Casts/Normalizer/DateTimeNormalizerCast.php b/src/Casts/Normalizer/DateTimeNormalizerCast.php new file mode 100644 index 0000000..91484af --- /dev/null +++ b/src/Casts/Normalizer/DateTimeNormalizerCast.php @@ -0,0 +1,27 @@ +match($values)) { + try { + return $values->format('Y-m-d H:i:s'); + } catch (Throwable $e) { + } + } + + return $values; + } +} diff --git a/src/Casts/Normalizer/JsonNormalizerCast.php b/src/Casts/Normalizer/JsonNormalizerCast.php index 1bf6fe0..a4f50f3 100644 --- a/src/Casts/Normalizer/JsonNormalizerCast.php +++ b/src/Casts/Normalizer/JsonNormalizerCast.php @@ -12,9 +12,9 @@ public function match(mixed $values): bool return is_string($values); } - public function resolve(mixed $values): array + public function resolve(mixed $values): mixed { - if($this->match($values)){ + if ($this->match($values)) { try { $decoded = json_decode($values, true, 512, JSON_THROW_ON_ERROR); return is_array($decoded) ? $decoded : $values; @@ -25,4 +25,4 @@ public function resolve(mixed $values): array return $values; } -} \ No newline at end of file +} diff --git a/src/Casts/Normalizer/ObjectNormalizerCast.php b/src/Casts/Normalizer/ObjectNormalizerCast.php new file mode 100644 index 0000000..a8e9c12 --- /dev/null +++ b/src/Casts/Normalizer/ObjectNormalizerCast.php @@ -0,0 +1,22 @@ +match($values)) { + return (array)$values; + } + + return $values; + } +} diff --git a/src/Contracts/Normalizer/NormalizerCastInterface.php b/src/Contracts/Normalizer/NormalizerCastInterface.php index 09d49fa..eca8a02 100644 --- a/src/Contracts/Normalizer/NormalizerCastInterface.php +++ b/src/Contracts/Normalizer/NormalizerCastInterface.php @@ -7,4 +7,4 @@ interface NormalizerCastInterface public function match(mixed $values): bool; public function resolve(mixed $values): mixed; -} \ No newline at end of file +} diff --git a/src/Enums/ConfigCastEnum.php b/src/Enums/ConfigCastEnum.php new file mode 100644 index 0000000..e5b0c1f --- /dev/null +++ b/src/Enums/ConfigCastEnum.php @@ -0,0 +1,32 @@ + DataCollectionCastInterface::class, + self::OUTPUT_VALUE => OutValueCastInterface::class, + self::INPUT_VALUE => InputValueCastInterface::class, + self::INPUT_NORMALIZER, self::OUT_NORMALIZER => NormalizerCastInterface::class, + }; + } + + public static function getValues(): array + { + return array_column(self::cases(), 'value'); + } +} diff --git a/src/OpenApi/Collections/OpenApiCollection.php b/src/OpenApi/Collections/OpenApiCollection.php index 33dc041..02d33f3 100644 --- a/src/OpenApi/Collections/OpenApiCollection.php +++ b/src/OpenApi/Collections/OpenApiCollection.php @@ -19,7 +19,6 @@ use Astral\Serialize\OpenApi\Storage\OpenAPI\SchemaStorage; use Astral\Serialize\Resolvers\GroupResolver; use Astral\Serialize\Serialize; -use Astral\Serialize\SerializeContainer; use Astral\Serialize\Support\Factories\ContextFactory; use Psr\SimpleCache\InvalidArgumentException; use ReflectionMethod; @@ -32,8 +31,8 @@ public function __construct( public string $methodName, public reflectionMethod $reflectionMethod, public Tag $tag, - public Summary $summary, - public Route $route, + public Summary|null $summary, + public Route|null $route, public Headers|null $headers, public array $attributes, public RequestBody|null $requestBody, @@ -58,7 +57,7 @@ public function build(): Method $requestBody = $this->buildRequestBody( className:$this->getRequestBodyClass(), contentType:$this->requestBody->contentType ?? ContentTypeEnum::JSON, - groups: $this->requestBody->groups ?? [] + groups: $this->requestBody->groups ?? [] ); $response = $this->buildResponse( @@ -71,10 +70,9 @@ className:$this->getResponseClass(), return $openAPIMethod; } - public function getRequestBodyClass(): string { - if($this->requestBody?->className){ + if ($this->requestBody?->className) { return $this->requestBody->className; } @@ -88,12 +86,11 @@ public function getRequestBodyClass(): string return ''; } - - public function buildRequestBody(string $className,ContentTypeEnum $contentType,array $groups = []): RequestBodyStorage + public function buildRequestBody(string $className, ContentTypeEnum $contentType, array $groups = []): RequestBodyStorage { $openAPIRequestBody = new RequestBodyStorage($contentType); if (is_subclass_of($className, Serialize::class)) { - $schemaStorage = (new SchemaStorage())->build($this->buildRequestParameterCollections($className,$groups)); + $schemaStorage = (new SchemaStorage())->build($this->buildRequestParameterCollections($className, $groups)); $openAPIRequestBody->withParameter($schemaStorage); } @@ -102,7 +99,7 @@ public function buildRequestBody(string $className,ContentTypeEnum $contentType, public function getResponseClass(): string { - if($this->response?->className){ + if ($this->response?->className) { return $this->response->className; } @@ -118,18 +115,18 @@ public function getResponseClass(): string /** * @throws InvalidArgumentException */ - public function buildResponse(string $className,array $groups = []): ResponseStorage + public function buildResponse(string $className, array $groups = []): ResponseStorage { $responseStorage = new ResponseStorage(); - $baseResponse = Config::get('response',[]); + $baseResponse = Config::get('response', []); if ($className) { - $schemaStorage = (new SchemaStorage())->build($this->buildResponseParameterCollections($className,$groups)); + $schemaStorage = (new SchemaStorage())->build($this->buildResponseParameterCollections($className, $groups)); $responseStorage->withParameter($schemaStorage); } - if($baseResponse){ + if ($baseResponse) { $responseStorage->addGlobParameters($baseResponse); } @@ -148,13 +145,13 @@ public function buildRequestParameterCollections(string $className, array $group $serializeContext = ContextFactory::build($className); $serializeContext->setGroups($groups)->from(); $properties = $serializeContext->getGroupCollection()->getProperties(); - $groups = $groups ?: [$className]; + $groups = $groups ?: [$className]; $vols = []; foreach ($properties as $property) { - if($property->isInputIgnoreByGroups($groups) || !$this->groupResolver->resolveExistsGroupsByDataCollection($property, $groups, $className)){ + if ($property->isInputIgnoreByGroups($groups) || !$this->groupResolver->resolveExistsGroupsByDataCollection($property, $groups, $className)) { continue; } @@ -192,12 +189,12 @@ public function buildResponseParameterCollections(string $className, array $grou $serializeContext = ContextFactory::build($className); $serializeContext->from(); $properties = $serializeContext->getGroupCollection()->getProperties(); - $groups = $groups ?: [$className]; + $groups = $groups ?: [$className]; $vols = []; foreach ($properties as $property) { - if($property->isOutIgnoreByGroups($groups) || !$this->groupResolver->resolveExistsGroupsByDataCollection($property, $groups, $className)){ + if ($property->isOutIgnoreByGroups($groups) || !$this->groupResolver->resolveExistsGroupsByDataCollection($property, $groups, $className)) { continue; } diff --git a/src/OpenApi/Frankenphp/docs/index.php b/src/OpenApi/Frankenphp/docs/index.php index f93de6f..3d2ef0d 100644 --- a/src/OpenApi/Frankenphp/docs/index.php +++ b/src/OpenApi/Frankenphp/docs/index.php @@ -15,7 +15,7 @@ diff --git a/src/OpenApi/Frankenphp/index.php b/src/OpenApi/Frankenphp/index.php index eeed3d5..5dee947 100644 --- a/src/OpenApi/Frankenphp/index.php +++ b/src/OpenApi/Frankenphp/index.php @@ -1,4 +1,5 @@ tags[$tag->name] = $tag; + // $this->tags[$tag->name] = $tag; } public function withPaths(array $paths): self diff --git a/src/OpenApi/Storage/OpenAPI/ResponseStorage.php b/src/OpenApi/Storage/OpenAPI/ResponseStorage.php index 10126c9..5ac25a6 100755 --- a/src/OpenApi/Storage/OpenAPI/ResponseStorage.php +++ b/src/OpenApi/Storage/OpenAPI/ResponseStorage.php @@ -25,19 +25,19 @@ public function withParameter(SchemaStorage $schema): static public function addGlobParameters(array $vols): void { - $dates = $this->parameter['properties'] ?? []; - $required = $this->parameter['required'] ?? []; + $dates = $this->parameter['properties'] ?? []; + $required = $this->parameter['required'] ?? []; $this->parameter['properties'] = []; - foreach ($vols as $field => $item){ - if($item === 'T'){ + foreach ($vols as $field => $item) { + if ($item === 'T') { $this->parameter['properties'][$field] = [ 'type' => 'object', - 'properties' => $dates, - 'required' => $required, + 'properties' => $dates, + 'required' => $required, ]; - }else{ + } else { $this->parameter['properties'][$field] = [ 'type' => 'string', 'description' => $item['description'] ?? '', diff --git a/src/Resolvers/Casts/NormalizerCastResolver.php b/src/Resolvers/Casts/InputNormalizerCastResolver.php similarity index 62% rename from src/Resolvers/Casts/NormalizerCastResolver.php rename to src/Resolvers/Casts/InputNormalizerCastResolver.php index b3e648a..212e9dc 100644 --- a/src/Resolvers/Casts/NormalizerCastResolver.php +++ b/src/Resolvers/Casts/InputNormalizerCastResolver.php @@ -2,11 +2,9 @@ namespace Astral\Serialize\Resolvers\Casts; -use Astral\Serialize\Support\Collections\DataCollection; use Astral\Serialize\Support\Config\ConfigManager; -use Astral\Serialize\Support\Context\InputValueContext; -class NormalizerCastResolver +class InputNormalizerCastResolver { public function __construct( private readonly ConfigManager $configManager @@ -16,10 +14,10 @@ public function __construct( public function resolve(mixed $values): mixed { - foreach ($this->configManager->getNormalizerCasts() as $cast) { + foreach ($this->configManager->getInputNormalizerCasts() as $cast) { $values = $cast->resolve($values); } return $values; } -} \ No newline at end of file +} diff --git a/src/Resolvers/Casts/OutNormalizerCastResolver.php b/src/Resolvers/Casts/OutNormalizerCastResolver.php new file mode 100644 index 0000000..4bcb132 --- /dev/null +++ b/src/Resolvers/Casts/OutNormalizerCastResolver.php @@ -0,0 +1,23 @@ +configManager->getOutNormalizerCasts() as $cast) { + $values = $cast->resolve($values); + } + + return $values; + } +} diff --git a/src/Resolvers/OutputResolver.php b/src/Resolvers/OutputResolver.php index d8df062..8570186 100644 --- a/src/Resolvers/OutputResolver.php +++ b/src/Resolvers/OutputResolver.php @@ -2,8 +2,8 @@ namespace Astral\Serialize\Resolvers; +use Astral\Serialize\Resolvers\Casts\OutNormalizerCastResolver; use Astral\Serialize\Resolvers\Casts\OutputCastResolver; -use Astral\Serialize\Serialize; use Astral\Serialize\Support\Collections\DataCollection; use Astral\Serialize\Support\Collections\GroupDataCollection; use Astral\Serialize\Support\Context\ChoosePropertyContext; @@ -17,6 +17,7 @@ public function __construct( protected readonly ReflectionClassInstanceManager $reflectionClassInstanceManager, private readonly OutputCastResolver $outValueCastResolver, protected readonly GroupResolver $groupResolver, + private readonly OutNormalizerCastResolver $normalizerCastResolver, ) { } @@ -52,7 +53,7 @@ classInstance: $object, ); foreach ($matchData['names'] as $name) { - $toArray[$name] = $resolvedValue instanceof Serialize ? $resolvedValue->toArray() : $resolvedValue; + $toArray[$name] = $this->normalizerCastResolver->resolve($resolvedValue); } } diff --git a/src/Serialize.php b/src/Serialize.php index 11e4f9e..30bfca9 100644 --- a/src/Serialize.php +++ b/src/Serialize.php @@ -84,7 +84,6 @@ public static function faker(): static return $instance; } - public function __debugInfo() { $res = get_object_vars($this); @@ -95,16 +94,16 @@ public function __debugInfo() public function jsonSerialize(): array { - $baseResponses = Config::get('response',[]); + $baseResponses = Config::get('response', []); $customerResponses = $this->getContext()?->getResponses() ?? []; - $responses = array_merge($baseResponses, $customerResponses); + $responses = array_merge($baseResponses, $customerResponses); - if($responses){ + if ($responses) { $resultData = []; - foreach ($responses as $field => $item){ - if($item === 'T'){ + foreach ($responses as $field => $item) { + if ($item === 'T') { $resultData[$field] = $this->toArray(); - }else{ + } else { $resultData[$field] = $item['value'] ?? ($item['example'] ?? ''); } } diff --git a/src/SerializeContainer.php b/src/SerializeContainer.php index 8715a71..b96620a 100644 --- a/src/SerializeContainer.php +++ b/src/SerializeContainer.php @@ -7,8 +7,9 @@ use Astral\Serialize\Faker\FakerResolver; use Astral\Serialize\Faker\Rule\FakerDefaultRules; use Astral\Serialize\Resolvers\Casts\DataCollectionCastResolver; +use Astral\Serialize\Resolvers\Casts\InputNormalizerCastResolver; use Astral\Serialize\Resolvers\Casts\InputValueCastResolver; -use Astral\Serialize\Resolvers\Casts\NormalizerCastResolver; +use Astral\Serialize\Resolvers\Casts\OutNormalizerCastResolver; use Astral\Serialize\Resolvers\Casts\OutputCastResolver; use Astral\Serialize\Resolvers\GroupResolver; use Astral\Serialize\Resolvers\InputResolver; @@ -42,7 +43,8 @@ class SerializeContainer protected ?GroupResolver $groupResolver = null; protected ?ReflectionClassInstanceManager $reflectionClassInstanceManager = null; protected ?SerializeInstanceManager $serializeInstanceManager = null; - protected ?NormalizerCastResolver $normalizerCastResolver = null; + protected ?InputNormalizerCastResolver $inputNormalizerCastResolver = null; + protected ?OutNormalizerCastResolver $outNormalizerCastResolver = null; protected ?DataCollectionCastResolver $attributePropertyResolver = null; protected ?InputResolver $propertyInputValueResolver = null; protected ?OutputResolver $propertyToArrayResolver = null; @@ -121,9 +123,14 @@ public function propertyInputValueResolver(): InputResolver ); } - public function normalizerCastResolver(): NormalizerCastResolver + public function inputNormalizerCastResolver(): InputNormalizerCastResolver { - return $this->normalizerCastResolver ??= new NormalizerCastResolver(ConfigManager::getInstance()); + return $this->inputNormalizerCastResolver ??= new InputNormalizerCastResolver(ConfigManager::getInstance()); + } + + public function outNormalizerCastResolver(): OutNormalizerCastResolver + { + return $this->outNormalizerCastResolver ??= new OutNormalizerCastResolver(ConfigManager::getInstance()); } public function inputValueCastResolver(): InputValueCastResolver @@ -147,6 +154,7 @@ public function propertyToArrayResolver(): OutputResolver reflectionClassInstanceManager:$this->reflectionClassInstanceManager(), outValueCastResolver:$this->outValueCastResolver(), groupResolver: $this->groupResolver(), + normalizerCastResolver:$this->outNormalizerCastResolver(), ); } diff --git a/src/Support/Config/ConfigManager.php b/src/Support/Config/ConfigManager.php index 20db6a3..310d26f 100644 --- a/src/Support/Config/ConfigManager.php +++ b/src/Support/Config/ConfigManager.php @@ -8,8 +8,9 @@ use Astral\Serialize\Casts\InputValue\InputValueEnumCast; use Astral\Serialize\Casts\InputValue\InputValueNullCast; use Astral\Serialize\Casts\Normalizer\ArrayNormalizerCast; +use Astral\Serialize\Casts\Normalizer\DateTimeNormalizerCast; use Astral\Serialize\Casts\Normalizer\JsonNormalizerCast; -use Astral\Serialize\Casts\OutValue\OutArrayChildCast; +use Astral\Serialize\Casts\Normalizer\ObjectNormalizerCast; use Astral\Serialize\Casts\OutValue\OutValueEnumCast; use Astral\Serialize\Casts\OutValue\OutValueGetterCast; use Astral\Serialize\Contracts\Attribute\DataCollectionCastInterface; @@ -17,8 +18,9 @@ use Astral\Serialize\Contracts\Attribute\OutValueCastInterface; use Astral\Serialize\Contracts\Normalizer\NormalizerCastInterface; use Astral\Serialize\Enums\CacheDriverEnum; -use Astral\Serialize\Exceptions\NotFoundAttributePropertyResolver; +use Astral\Serialize\Enums\ConfigCastEnum; use Astral\Serialize\Support\Caching\MemoryCache; +use RuntimeException; class ConfigManager { @@ -38,88 +40,71 @@ class ConfigManager /** @var (OutValueCastInterface|string)[] $outputValueCasts */ private array $outputValueCasts = [ -// OutArrayChildCast::class, OutValueEnumCast::class, OutValueGetterCast::class, ]; - /** @var (NormalizerCastInterface|string)[] $normalizerCasts */ - private array $normalizerCasts = [ + /** @var (NormalizerCastInterface|string)[] $inputNormalizerCasts */ + private array $inputNormalizerCasts = [ // JsonNormalizerCast::class, ArrayNormalizerCast::class, ]; + /** @var (NormalizerCastInterface|string)[] $inputNormalizerCasts */ + private array $outNormalizerCasts = [ + DateTimeNormalizerCast::class, + ArrayNormalizerCast::class, + ObjectNormalizerCast::class + ]; + /** @var CacheDriverEnum|class-string $cacheDriver */ private string|CacheDriverEnum $cacheDriver = MemoryCache::class; - public function __construct() - { - foreach ($this->inputValueCasts as $key => $cast) { - $this->inputValueCasts[$key] = new $cast(); - } - - foreach ($this->outputValueCasts as $key => $cast) { - $this->outputValueCasts[$key] = new $cast(); - } - - foreach ($this->normalizerCasts as $key => $cast) { - $this->normalizerCasts[$key] = new $cast(); - } - } - public static function getInstance(): ConfigManager { return self::$instance ??= new self(); } - /** - * @throws NotFoundAttributePropertyResolver - */ - public function addNormalizerCasts(NormalizerCastInterface|string $resolverClass): static + public function __construct() { - if (is_string($resolverClass) && !is_subclass_of($resolverClass, NormalizerCastInterface::class)) { - throw new NotFoundAttributePropertyResolver('Resolver class must be an instance of NormalizerCastInterface'); - } - $this->attributePropertyResolver[] = (is_string($resolverClass) ? new $resolverClass() : $resolverClass); - - return $this; + $this->instantiateArrayProperties(ConfigCastEnum::getValues()); } /** - * @throws NotFoundAttributePropertyResolver + * @param array $propertyNames + * @return void */ - public function addAttributePropertyResolver(DataCollectionCastInterface|string $resolverClass): static + private function instantiateArrayProperties(array $propertyNames): void { - if (is_string($resolverClass) && !is_subclass_of($resolverClass, DataCollectionCastInterface::class)) { - throw new NotFoundAttributePropertyResolver('Resolver class must be an instance of DataCollectionCastInterface'); + foreach ($propertyNames as $property) { + if (!property_exists($this, $property)) { + throw new RuntimeException("Property $property does not exist"); + } + + $this->$property = array_map( + fn ($class) => is_string($class) ? new $class() : $class, + $this->$property + ); } - $this->attributePropertyResolver[] = (is_string($resolverClass) ? new $resolverClass() : $resolverClass); - - return $this; } /** - * @throws NotFoundAttributePropertyResolver + * @param object|string $castClass + * @param ConfigCastEnum $castEnum + * @return static + * @throws RuntimeException */ - public function addOutputValueCasts(OutValueCastInterface|string $castClass): static + public function addCast(object|string $castClass, ConfigCastEnum $castEnum): static { - if (is_string($castClass) && !is_subclass_of($castClass, OutValueCastInterface::class)) { - throw new NotFoundAttributePropertyResolver('Resolver class must be an instance of OutValueCastInterface'); + if (is_string($castClass) && !is_subclass_of($castClass, $castEnum->getCastInterface())) { + throw new RuntimeException("Cast class must be an instance of {$castEnum->getCastInterface()}"); } - $this->outputValueCasts[] = (is_string($castClass) ? new $castClass() : $castClass); - - return $this; - } - /** - * @throws NotFoundAttributePropertyResolver - */ - public function addInputValueCasts(InputValueCastInterface|string $castClass): static - { - if (is_string($castClass) && !is_subclass_of($castClass, InputValueCastInterface::class)) { - throw new NotFoundAttributePropertyResolver('Resolver class must be an instance of InputValueCastInterface'); + if (!property_exists($this, $castEnum->value)) { + throw new RuntimeException("Property {$castEnum->value} does not exist"); } - $this->inputValueCasts[] = (is_string($castClass) ? new $castClass() : $castClass); + + $this->{$castEnum->value}[] = is_string($castClass) ? new $castClass() : $castClass; return $this; } @@ -139,9 +124,14 @@ public function getOutValueCasts(): array return $this->outputValueCasts; } - public function getNormalizerCasts(): array + public function getInputNormalizerCasts(): array + { + return $this->inputNormalizerCasts; + } + + public function getOutNormalizerCasts(): array { - return $this->normalizerCasts; + return $this->outNormalizerCasts; } public function getCacheDriver(): string diff --git a/src/Support/Context/SerializeContext.php b/src/Support/Context/SerializeContext.php index b601405..c376bb7 100644 --- a/src/Support/Context/SerializeContext.php +++ b/src/Support/Context/SerializeContext.php @@ -5,7 +5,7 @@ use Astral\Serialize\Exceptions\NotFoundGroupException; use Astral\Serialize\Faker\FakerResolver; use Astral\Serialize\Resolvers\Casts\DataCollectionCastResolver; -use Astral\Serialize\Resolvers\Casts\NormalizerCastResolver; +use Astral\Serialize\Resolvers\Casts\InputNormalizerCastResolver; use Astral\Serialize\Resolvers\GroupResolver; use Astral\Serialize\Resolvers\InputResolver; use Astral\Serialize\Resolvers\OutputResolver; @@ -25,7 +25,7 @@ */ class SerializeContext { - private array $groups = []; + private array $groups = []; private array $responses = []; public function __construct( @@ -39,18 +39,18 @@ public function __construct( private readonly ConstructDataCollectionManager $constructDataCollectionManager, private readonly InputResolver $propertyInputValueResolver, private readonly OutputResolver $propertyToArrayResolver, + private readonly InputNormalizerCastResolver $inputNormalizerCastResolver, private readonly FakerResolver $fakerResolver, - private readonly NormalizerCastResolver $normalizerCastResolver, ) { } - public function setCode(string|int $code, $description ='' , $field = 'code'): void + public function setCode(string|int $code, $description = '', $field = 'code'): void { $this->responses[$field] = ['description' => $description,'value' => $code]; } - public function setMessage(string $message, $description ='' , $field = 'message'): void + public function setMessage(string $message, $description = '', $field = 'message'): void { $this->responses[$field] = ['description' => $description,'value' => $message]; } @@ -213,9 +213,9 @@ public function from(mixed ...$payload): object { $payloads = []; foreach ($payload as $field => $itemPayload) { - $itemPayload = $this->normalizerCastResolver->resolve($itemPayload); - $values = is_numeric($field) && is_array($itemPayload) ? $itemPayload : [$field => $itemPayload]; - $payloads = [...$payloads, ...$values]; + $itemPayload = $this->inputNormalizerCastResolver->resolve($itemPayload); + $values = is_numeric($field) && is_array($itemPayload) ? $itemPayload : [$field => $itemPayload]; + $payloads = [...$payloads, ...$values]; } $this->chooseSerializeContext->setGroups($this->getGroups()); @@ -245,5 +245,4 @@ public function toArray(object $object): array $this->chooseSerializeContext->setGroups($this->getGroups()); return $this->propertyToArrayResolver->resolve($this->chooseSerializeContext, $this->getGroupCollection(), $object); } - } diff --git a/src/Support/Factories/ContextFactory.php b/src/Support/Factories/ContextFactory.php index 4661f00..f462f0f 100644 --- a/src/Support/Factories/ContextFactory.php +++ b/src/Support/Factories/ContextFactory.php @@ -19,16 +19,16 @@ public static function build(string $className): SerializeContext { return (new SerializeContext( serializeClassName: $className, - chooseSerializeContext:new ChooseSerializeContext($className), + chooseSerializeContext: new ChooseSerializeContext($className), cache: CacheFactory::build(), reflectionClassInstanceManager: SerializeContainer::get()->reflectionClassInstanceManager(), groupResolver: SerializeContainer::get()->groupResolver(), dataCollectionCastResolver: SerializeContainer::get()->attributePropertyResolver(), constructDataCollectionManager: SerializeContainer::get()->constructDataCollectionManager(), propertyInputValueResolver: SerializeContainer::get()->propertyInputValueResolver(), - propertyToArrayResolver: SerializeContainer::get()->propertyToArrayResolver(), + propertyToArrayResolver: SerializeContainer::get()->propertyToArrayResolver(), + inputNormalizerCastResolver: SerializeContainer::get()->inputNormalizerCastResolver(), fakerResolver: SerializeContainer::get()->fakerResolver(), - normalizerCastResolver: SerializeContainer::get()->normalizerCastResolver(), )); } } diff --git a/tests/Openapi/BaseGroupOpenApiTest.php b/tests/Openapi/BaseGroupOpenApiTest.php index e83f48e..3acba1b 100644 --- a/tests/Openapi/BaseGroupOpenApiTest.php +++ b/tests/Openapi/BaseGroupOpenApiTest.php @@ -8,7 +8,6 @@ class TestBaseGroupRequest extends Serialize { - public int $input_group_0; #[\Astral\Serialize\Annotations\Groups('group_1')] @@ -17,8 +16,8 @@ class TestBaseGroupRequest extends Serialize #[\Astral\Serialize\Annotations\Groups('group_1')] public string $input_group_1_22; - #[\Astral\Serialize\Annotations\Groups('group_1','group_2')] - #[\Astral\Serialize\Annotations\DataCollection\InputName('input_change_group_1_33_2_11',['group_2'])] + #[\Astral\Serialize\Annotations\Groups('group_1', 'group_2')] + #[\Astral\Serialize\Annotations\DataCollection\InputName('input_change_group_1_33_2_11', ['group_2'])] public string $input_group_1_33_2_11; #[\Astral\Serialize\Annotations\Groups('group_2')] @@ -39,7 +38,7 @@ class TestBaseGroupResponse extends Serialize #[\Astral\Serialize\Annotations\Groups('group_1')] public string $out_group_1_22; - #[\Astral\Serialize\Annotations\Groups('group_1','group_2')] + #[\Astral\Serialize\Annotations\Groups('group_1', 'group_2')] public string $out_group_1_33_2_11; #[\Astral\Serialize\Annotations\Groups('group_2')] diff --git a/tests/Openapi/EnumOpenApiTest.php b/tests/Openapi/EnumOpenApiTest.php index ff8660e..72b21f7 100644 --- a/tests/Openapi/EnumOpenApiTest.php +++ b/tests/Openapi/EnumOpenApiTest.php @@ -69,24 +69,24 @@ public function one(OpenapiEnumRequest $request): void 'test_one_of_enum', ]) ->and($schema['properties']['test_enum'])->toMatchArray([ - 'type' => 'string', + 'type' => 'string', 'description' => 'optional values:ENUM_1、ENUM_2', - 'example' => '', + 'example' => '', ]) ->and($schema['properties']['test_string_enum'])->toMatchArray([ - 'type' => 'string', + 'type' => 'string', 'description' => 'optional values:ENUM_1、ENUM_2、ENUM_3、ENUM_4', - 'example' => '', + 'example' => '', ]) ->and($schema['properties']['test_string_2_enum'])->toMatchArray([ - 'type' => 'string', + 'type' => 'string', 'description' => 'optional values:ENUM_1、ENUM_2、ENUM_3、ENUM_4', - 'example' => '', + 'example' => '', ]) ->and($schema['properties']['test_one_of_enum'])->toMatchArray([ - 'type' => 'oneOf', + 'type' => 'oneOf', 'description' => 'optional values:ENUM_1、ENUM_2、ENUM_3、ENUM_4', - 'example' => '', + 'example' => '', ]) ->and($schema['properties']['test_one_of_enum']['oneOf'])->toBeArray()->toHaveCount(2) ->and($schema['properties']['test_one_of_enum']['oneOf'][0])->toMatchArray(['type' => 'string']) diff --git a/tests/Openapi/OpenApiTest.php b/tests/Openapi/OpenApiTest.php index 70f491a..8db1fc2 100644 --- a/tests/Openapi/OpenApiTest.php +++ b/tests/Openapi/OpenApiTest.php @@ -59,37 +59,30 @@ public function one(TestOpenApiRequest $request): TestOpenApiResponse // 顶层结构断言 expect($openApi->openapi)->toBe('3.1.1') ->and($openApi->info->version)->toBe('1.0.0'); -// ->and($openApi->tags[0]->name)->toBe('接口测试'); + // ->and($openApi->tags[0]->name)->toBe('接口测试'); - // 路径是否存在 $paths = $openApi->paths; expect($paths)->toHaveKey('/test/one-action'); - // 方法与标签断言 $post = $paths['/test/one-action']['post']; expect($post->summary)->toBe('测试方法一') ->and($post->tags)->toContain('接口测试'); - // 请求体断言 $requestBody = $post->requestBody; expect($requestBody['required'])->toBeTrue(); $schema = $requestBody['content']['application/json']['schema']; - // 请求字段存在 expect($schema['properties'])->toHaveKeys(['name', 'id', 'any_array']); - // id 字段是 oneOf 并包含 string, integer, number $idOneOf = $schema['properties']['id']['oneOf']; $types = array_map(static fn ($item) => $item['type'], $idOneOf); expect($types)->toMatchArray(['string', 'integer', 'number']); - // any_array 是 oneOf 并包含至少一个 array 类型 $anyArray = $schema['properties']['any_array']; expect($anyArray['type'])->toBe('oneOf') ->and($anyArray['oneOf'])->toBeArray() ->and($anyArray['oneOf'][0]['type'])->toBe('array'); - // 响应体 200 是否定义成功 $response200 = $post->responses[200]; expect($response200['description'])->toBe('成功'); diff --git a/tests/Serialize/Config/AddCastTest.php b/tests/Serialize/Config/AddCastTest.php new file mode 100644 index 0000000..fb34ce3 --- /dev/null +++ b/tests/Serialize/Config/AddCastTest.php @@ -0,0 +1,36 @@ +toArray())->toHaveCount(2) + ->and($res->toArray()['name_three'])->toBeNull() + ->and($res->toArray()['id_three'])->toBeNull(); + + ConfigManager::getInstance()->addCast(JsonNormalizerCast::class, ConfigCastEnum::INPUT_NORMALIZER); + $res = AddCastTestClass::from('{"name_three_other":"1223","id_three":3}'); + expect($res->toArray())->toHaveCount(2) + ->and($res->toArray()['name_three'])->toBe('1223') + ->and($res->toArray()['id_three'])->toBe(3); + +}); diff --git a/tests/Serialize/From/NormalizerFromSerializeTest.php b/tests/Serialize/From/NormalizerFromSerializeTest.php index 9feac3a..b83d09e 100644 --- a/tests/Serialize/From/NormalizerFromSerializeTest.php +++ b/tests/Serialize/From/NormalizerFromSerializeTest.php @@ -31,13 +31,13 @@ class NormalizerClass extends Serialize it('test normalizer Serialize class', function () { - $normalizerOne = new NormalizerOne(); + $normalizerOne = new NormalizerOne(); $normalizerOne->name_one = 'one name'; - $normalizerOne->id_one = 1; + $normalizerOne->id_one = 1; $normalizerTwo = new NormalizerTwo(); $normalizerTwo->name_two = 'two name'; - $normalizerTwo->id_two = 2; + $normalizerTwo->id_two = 2; $res = NormalizerClass::from(one: $normalizerOne, two: $normalizerTwo, three: $normalizerOne); @@ -50,21 +50,21 @@ class NormalizerClass extends Serialize ->and($res->three)->toBeArray() ->and($res->three)->toMatchArray([ 'name_one' => 'one name', - 'id_one' => 1 + 'id_one' => 1 ]); -// + // }); it('test json_encode Serialize class', function () { - $normalizerOne = new NormalizerOne(); + $normalizerOne = new NormalizerOne(); $normalizerOne->name_one = 'one name'; - $normalizerOne->id_one = 1; + $normalizerOne->id_one = 1; - $normalizerTwo = new NormalizerTwo(); + $normalizerTwo = new NormalizerTwo(); $normalizerTwo->name_two = 'two name'; - $normalizerTwo->id_two = 2; + $normalizerTwo->id_two = 2; $res = NormalizerClass::from(one: $normalizerOne, two: $normalizerTwo, three: $normalizerOne); @@ -80,10 +80,9 @@ class NormalizerClass extends Serialize expect($resJson)->toBe('{"code":-1,"message":"233","data":{"one":{"name_one":"one name","id_one":1},"two":{"name_two":"two name","id_2":2},"three":{"name_one":"one name","id_one":1}}}'); $resJson = $res->withoutResponseToJsonString(); - var_dump($resJson); expect($resJson)->toBe('{"one":{"name_one":"one name","id_one":1},"two":{"name_two":"two name","id_2":2},"three":{"name_one":"one name","id_one":1}}'); $resJson = $res->toJsonString(); expect($resJson)->toBe('{"code":-1,"message":"233","data":{"one":{"name_one":"one name","id_one":1},"two":{"name_two":"two name","id_2":2},"three":{"name_one":"one name","id_one":1}}}'); -}); \ No newline at end of file +}); diff --git a/tests/Serialize/ToArray/OutDateFormatToArraySerializeTest.php b/tests/Serialize/ToArray/OutDateFormatToArraySerializeTest.php index eb91a6a..36bec39 100644 --- a/tests/Serialize/ToArray/OutDateFormatToArraySerializeTest.php +++ b/tests/Serialize/ToArray/OutDateFormatToArraySerializeTest.php @@ -36,7 +36,7 @@ class TestOutDateFormat extends Serialize $object->date_3 = new DateTime('2023-10-05 14:30:00'); // DateTime object $object->date_4 = Carbon::create(2023, 10, 5); // Carbon object $object->date_5 = new DateTime('2023-10-05'); // DateTime object without annotation - $object->date_6 = Carbon::create(2023, 10, 5); // Carbon object without annotation + $object->date_6 = Carbon::create(2023, 10, 6); // Carbon object without annotation // Serialize the object to an array $result = $object->toArray(); @@ -46,6 +46,6 @@ class TestOutDateFormat extends Serialize ->and($result['date_2'])->toBe('2023-10-05 00:00:00') // Default format Y-m-d H:i:s ->and($result['date_3'])->toBe('05/10/2023 14:30:00') // Formatted with 'd/m/Y H:i:s' ->and($result['date_4'])->toBe('05/10/2023') // Formatted with 'd/m/Y' - ->and($result['date_5'])->toBeInstanceOf(DateTime::class) // Default DateTime format - ->and($result['date_6'])->toBeInstanceOf(Carbon::class); // Default Carbon format + ->and($result['date_5'])->toBe('2023-10-05 00:00:00') // Default DateTime format Y-m-d H:i:s + ->and($result['date_6'])->toBe('2023-10-06 00:00:00'); // Default Carbon format Y-m-d H:i:s });