From 38faad9f452a3941e593a91d8cee5b12b5550818 Mon Sep 17 00:00:00 2001 From: yaozm Date: Tue, 6 Feb 2024 15:50:17 +0800 Subject: [PATCH] refactor(options): Improve options handling in Traits - Refactor the `HasOptions` trait to improve options handling - Update the `setOptions` method to iterate over the options and call `setOption` for each option - Update the `setOption` method to directly set the option value in the `$options` array - Update the `getOption` method to directly retrieve the option value from the `$options` array - Add a new method `resolveOptions` to configure and resolve the options using an `OptionsResolver` - Update the `configureAndResolveOptions` method to accept a callable `configurator` for configuring the `OptionsResolver` - Update the `configureOptionsResolver` and `preConfigureOptionsResolver` methods to allow custom configuration of the `OptionsResolver` - Remove unused magic methods from the trait --- .php-cs-fixer.php | 6 + src/Chanify/Messages/TextMessage.php | 13 +- src/Foundation/Concerns/AsBody.php | 3 +- src/Foundation/Concerns/AsFormParams.php | 2 +- src/Foundation/Concerns/AsJson.php | 2 +- src/Foundation/Concerns/AsMultipart.php | 2 +- src/Foundation/Concerns/AsQuery.php | 2 +- .../Traits/ConfigureOptionsable.php | 21 --- src/Foundation/Traits/HasOptions.php | 121 ++++++++++-------- src/MicrosoftTeams/Messages/Message.php | 25 ++-- src/Pushover/Messages/Message.php | 93 +++++++------- src/Slack/Messages/Message.php | 15 +-- src/WeWorkGroupBot/Messages/NewsMessage.php | 15 +-- src/WeWorkGroupBot/Messages/TextMessage.php | 21 ++- 14 files changed, 153 insertions(+), 188 deletions(-) delete mode 100644 src/Foundation/Traits/ConfigureOptionsable.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 471d35c4..2b3f1044 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -258,6 +258,12 @@ // ], 'phpdoc_to_comment' => false, 'phpdoc_param_order' => true, + 'phpdoc_no_alias_tag' => [ + 'replacements' => [ + 'type' => 'var', + 'link' => 'see', + ], + ], // return_notation 'simplified_null_return' => true, diff --git a/src/Chanify/Messages/TextMessage.php b/src/Chanify/Messages/TextMessage.php index 03ed92dc..9165e970 100644 --- a/src/Chanify/Messages/TextMessage.php +++ b/src/Chanify/Messages/TextMessage.php @@ -48,16 +48,11 @@ class TextMessage extends Message // 'priority' => 10, // ]; - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $optionsResolver): void { - $optionsResolver->setNormalizer( - 'actions', - static fn (OptionsResolver $optionsResolver, $value): array => (array) $value - ); - } + $optionsResolver->setNormalizer( + 'actions', + static fn (OptionsResolver $optionsResolver, $value): array => (array) $value ); } } diff --git a/src/Foundation/Concerns/AsBody.php b/src/Foundation/Concerns/AsBody.php index 1525fe3d..5cb26f0d 100644 --- a/src/Foundation/Concerns/AsBody.php +++ b/src/Foundation/Concerns/AsBody.php @@ -12,6 +12,7 @@ namespace Guanguans\Notify\Foundation\Concerns; +use GuzzleHttp\Psr7\Utils; use GuzzleHttp\RequestOptions; /** @@ -22,7 +23,7 @@ trait AsBody public function toHttpOptions(): array { return [ - RequestOptions::BODY => $this->getOptions(), + RequestOptions::BODY => Utils::streamFor($this->resolveOptions()), ]; } } diff --git a/src/Foundation/Concerns/AsFormParams.php b/src/Foundation/Concerns/AsFormParams.php index bc0ba640..fc00f3ea 100644 --- a/src/Foundation/Concerns/AsFormParams.php +++ b/src/Foundation/Concerns/AsFormParams.php @@ -22,7 +22,7 @@ trait AsFormParams public function toHttpOptions(): array { return [ - RequestOptions::FORM_PARAMS => $this->getOptions(), + RequestOptions::FORM_PARAMS => $this->resolveOptions(), ]; } } diff --git a/src/Foundation/Concerns/AsJson.php b/src/Foundation/Concerns/AsJson.php index 469cd7d6..85c3cf9e 100644 --- a/src/Foundation/Concerns/AsJson.php +++ b/src/Foundation/Concerns/AsJson.php @@ -22,7 +22,7 @@ trait AsJson public function toHttpOptions(): array { return [ - RequestOptions::JSON => $this->getOptions(), + RequestOptions::JSON => $this->resolveOptions(), ]; } } diff --git a/src/Foundation/Concerns/AsMultipart.php b/src/Foundation/Concerns/AsMultipart.php index 8d000bd7..6010bb46 100644 --- a/src/Foundation/Concerns/AsMultipart.php +++ b/src/Foundation/Concerns/AsMultipart.php @@ -22,7 +22,7 @@ trait AsMultipart public function toHttpOptions(): array { return [ - RequestOptions::MULTIPART => to_multipart($this->getOptions()), + RequestOptions::MULTIPART => to_multipart($this->resolveOptions()), ]; } } diff --git a/src/Foundation/Concerns/AsQuery.php b/src/Foundation/Concerns/AsQuery.php index db126695..8f6bcbdd 100644 --- a/src/Foundation/Concerns/AsQuery.php +++ b/src/Foundation/Concerns/AsQuery.php @@ -22,7 +22,7 @@ trait AsQuery public function toHttpOptions(): array { return [ - RequestOptions::QUERY => $this->getOptions(), + RequestOptions::QUERY => $this->resolveOptions(), ]; } } diff --git a/src/Foundation/Traits/ConfigureOptionsable.php b/src/Foundation/Traits/ConfigureOptionsable.php deleted file mode 100644 index dc83024d..00000000 --- a/src/Foundation/Traits/ConfigureOptionsable.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled. - */ - -namespace Guanguans\Notify\Foundation\Traits; - -trait ConfigureOptionsable -{ - public function configureOptions(array $options, \Closure $closure): array - { - return configure_options($options, $closure); - } -} diff --git a/src/Foundation/Traits/HasOptions.php b/src/Foundation/Traits/HasOptions.php index 58010be9..fc621f56 100644 --- a/src/Foundation/Traits/HasOptions.php +++ b/src/Foundation/Traits/HasOptions.php @@ -1,5 +1,8 @@ $defaults + * @property-read array $required + * @property-read array $defined + * @property-read array $deprecated + * @property-read array $normalizers + * @property-read array $allowedValues + * @property-read array|string> $allowedTypes; + * @property-read array $infos + * @property-read bool $prototype */ trait HasOptions { protected array $options = []; - public function __get($option) - { - return $this->offsetGet($option); - } - - public function __set($option, $value): void - { - $this->offsetSet($option, $value); - } - - public function __isset($option) - { - return $this->offsetExists($option); - } - - public function __unset($option): void - { - $this->offsetUnset($option); - } - + /** + * @noinspection MissingParameterTypeDeclarationInspection + * @noinspection MissingReturnTypeInspection + * + * @param mixed $name + * @param mixed $arguments + */ public function __call($name, $arguments) { $defined = $this->defined ?? []; @@ -59,7 +49,11 @@ public function __call($name, $arguments) if (\in_array($casedName, $defined, true)) { if (empty($arguments)) { - throw new \InvalidArgumentException(sprintf('Method %s::%s requires an argument', static::class, $name)); + throw new \InvalidArgumentException(sprintf( + 'Method %s::%s requires an argument', + static::class, + $name + )); } return $this->setOption($casedName, $arguments[0]); @@ -71,25 +65,35 @@ public function __call($name, $arguments) public function setOptions(array $options): self { - $this->options = array_replace_recursive($this->options, $options); + foreach ($options as $option => $value) { + $this->setOption($option, $value); + } return $this; } public function setOption(string $option, $value): self { - return $this->setOptions([$option => $value]); + $this->options[$option] = $value; + + return $this; } public function getOption(string $option, $default = null) { - return $this->getOptions()[$option] ?? $default; + return $this->options[$option] ?? $default; } public function getOptions(): array { - return $this->options = $this->configureAndResolveOptions($this->options, function (OptionsResolver $optionsResolver): void { - $this->configureOptionsResolver($this->preConfigureOptionsResolver($optionsResolver)); + return $this->options; + } + + public function resolveOptions(): array + { + return $this->configureAndResolveOptions($this->options, function (OptionsResolver $optionsResolver): void { + $this->preConfigureOptionsResolver($optionsResolver); + $this->configureOptionsResolver($optionsResolver); }); } @@ -113,13 +117,7 @@ public function offsetUnset($offset): void unset($this->options[$offset]); } - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver - { - // configure options resolver... - return $optionsResolver; - } - - private function configureAndResolveOptions(array $options, callable $configurator): array + protected function configureAndResolveOptions(array $options, callable $configurator): array { $optionsResolver = new OptionsResolver; @@ -128,17 +126,34 @@ private function configureAndResolveOptions(array $options, callable $configurat return $optionsResolver->resolve($options); } - private function preConfigureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void + { + // configure options resolver... + } + + private function preConfigureOptionsResolver(OptionsResolver $optionsResolver): void { - property_exists($this, 'defined') and $optionsResolver->setDefined($this->defined); - property_exists($this, 'required') and $optionsResolver->setRequired($this->required); property_exists($this, 'defaults') and $optionsResolver->setDefaults($this->defaults); - property_exists($this, 'prototype') and $optionsResolver->setPrototype($this->prototype); + property_exists($this, 'required') and $optionsResolver->setRequired($this->required); + property_exists($this, 'defined') and $optionsResolver->setDefined($this->defined); if (property_exists($this, 'deprecated')) { - foreach ($this->deprecated as $option => $deprecated) { - array_unshift($deprecated, $option); - $optionsResolver->setDeprecated(...$deprecated); + foreach ($this->deprecated as $option => $arguments) { + if (\is_string($arguments)) { + $arguments = [$arguments]; + } + + if (\is_string($option)) { + array_unshift($arguments, $option); + } + + $optionsResolver->setDeprecated(...$arguments); + } + } + + if (property_exists($this, 'normalizers')) { + foreach ($this->normalizers as $option => $normalizer) { + $optionsResolver->setNormalizer($option, $normalizer); } } @@ -154,18 +169,12 @@ private function preConfigureOptionsResolver(OptionsResolver $optionsResolver): } } - if (property_exists($this, 'normalizers')) { - foreach ($this->normalizers as $option => $normalizer) { - $optionsResolver->setNormalizer($option, $normalizer); - } - } - if (property_exists($this, 'infos')) { foreach ($this->infos as $option => $info) { $optionsResolver->setInfo($option, $info); } } - return $optionsResolver; + property_exists($this, 'prototype') and $optionsResolver->setPrototype($this->prototype); } } diff --git a/src/MicrosoftTeams/Messages/Message.php b/src/MicrosoftTeams/Messages/Message.php index 1622858d..39db90c5 100644 --- a/src/MicrosoftTeams/Messages/Message.php +++ b/src/MicrosoftTeams/Messages/Message.php @@ -143,21 +143,16 @@ public function toHttpUri(): string return ''; } - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $resolver): void { - $resolver->setNormalizer('sections', static fn ( - OptionsResolver $optionsResolver, - array $value - ): array => isset($value[0]) ? $value : [$value]); - - $resolver->setNormalizer('potentialAction', static fn ( - OptionsResolver $optionsResolver, - array $value - ): array => isset($value[0]) ? $value : [$value]); - } - ); + $optionsResolver->setNormalizer('sections', static fn ( + OptionsResolver $optionsResolver, + array $value + ): array => isset($value[0]) ? $value : [$value]); + + $optionsResolver->setNormalizer('potentialAction', static fn ( + OptionsResolver $optionsResolver, + array $value + ): array => isset($value[0]) ? $value : [$value]); } } diff --git a/src/Pushover/Messages/Message.php b/src/Pushover/Messages/Message.php index 6cef416a..723d966a 100644 --- a/src/Pushover/Messages/Message.php +++ b/src/Pushover/Messages/Message.php @@ -92,57 +92,52 @@ public function toHttpUri(): string return 'https://api.pushover.net/1/messages.json'; } - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $optionsResolver): void { - $optionsResolver->setNormalizer( - 'priority', - static function (OptionsResolver $optionsResolver, $value): int { - if (2 !== $value) { - return $value; - } - - if (isset($optionsResolver['retry'], $optionsResolver['expire'])) { - return $value; - } - - throw new MissingOptionsException('The required option "retry" or "expire" is missing.'); - } - ); - - $optionsResolver->setNormalizer( - 'html', - static function (OptionsResolver $optionsResolver, $value): int { - if (1 !== $value) { - return $value; - } - - if (! isset($optionsResolver['monospace'])) { - return $value; - } - - if (1 !== $optionsResolver['monospace']) { - return $value; - } - - throw new InvalidOptionsException('Html cannot be set with monospace, Monospace cannot be set with html, Html and monospace are mutually.'); - } - ); - - // $optionsResolver->setNormalizer( - // 'attachment', - // static function (OptionsResolver $optionsResolver, $value) { - // if (\is_string($value)) { - // // $value = fopen($value, 'r'); - // $value = Utils::tryFopen($value, 'r'); - // } - // - // return $value; - // } - // ); + $optionsResolver->setNormalizer( + 'priority', + static function (OptionsResolver $optionsResolver, $value): int { + if (2 !== $value) { + return $value; + } + + if (isset($optionsResolver['retry'], $optionsResolver['expire'])) { + return $value; + } + + throw new MissingOptionsException('The required option "retry" or "expire" is missing.'); } ); + + $optionsResolver->setNormalizer( + 'html', + static function (OptionsResolver $optionsResolver, $value): int { + if (1 !== $value) { + return $value; + } + + if (! isset($optionsResolver['monospace'])) { + return $value; + } + + if (1 !== $optionsResolver['monospace']) { + return $value; + } + + throw new InvalidOptionsException('Html cannot be set with monospace, Monospace cannot be set with html, Html and monospace are mutually.'); + } + ); + + // $optionsResolver->setNormalizer( + // 'attachment', + // static function (OptionsResolver $optionsResolver, $value) { + // if (\is_string($value)) { + // // $value = fopen($value, 'r'); + // $value = Utils::tryFopen($value, 'r'); + // } + // + // return $value; + // } + // ); } } diff --git a/src/Slack/Messages/Message.php b/src/Slack/Messages/Message.php index 794f142c..dee1e23c 100644 --- a/src/Slack/Messages/Message.php +++ b/src/Slack/Messages/Message.php @@ -73,16 +73,11 @@ public function toHttpUri(): string return ''; } - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $resolver): void { - $resolver->setNormalizer('attachments', static fn ( - OptionsResolver $optionsResolver, - array $value - ): array => isset($value[0]) ? $value : [$value]); - } - ); + $optionsResolver->setNormalizer('attachments', static fn ( + OptionsResolver $optionsResolver, + array $value + ): array => isset($value[0]) ? $value : [$value]); } } diff --git a/src/WeWorkGroupBot/Messages/NewsMessage.php b/src/WeWorkGroupBot/Messages/NewsMessage.php index 5c41c5f9..38bf15d2 100644 --- a/src/WeWorkGroupBot/Messages/NewsMessage.php +++ b/src/WeWorkGroupBot/Messages/NewsMessage.php @@ -48,17 +48,12 @@ static function (OptionsResolver $optionsResolver): void { return $this; } - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $resolver): void { - $resolver->setNormalizer('articles', static fn ( - OptionsResolver $optionsResolver, - array $value - ): array => isset($value[0]) ? $value : [$value]); - } - ); + $optionsResolver->setNormalizer('articles', static fn ( + OptionsResolver $optionsResolver, + array $value + ): array => isset($value[0]) ? $value : [$value]); } protected function type(): string diff --git a/src/WeWorkGroupBot/Messages/TextMessage.php b/src/WeWorkGroupBot/Messages/TextMessage.php index c42f023f..21e1b3fd 100644 --- a/src/WeWorkGroupBot/Messages/TextMessage.php +++ b/src/WeWorkGroupBot/Messages/TextMessage.php @@ -38,20 +38,15 @@ class TextMessage extends Message 'mentioned_mobile_list' => ['int', 'string', 'array'], ]; - protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver + protected function configureOptionsResolver(OptionsResolver $optionsResolver): void { - return tap( - parent::configureOptionsResolver($optionsResolver), - static function (OptionsResolver $resolver): void { - $resolver->setNormalizer( - 'mentioned_list', - static fn (OptionsResolver $optionsResolver, $value): array => (array) $value - ); - $resolver->setNormalizer( - 'mentioned_mobile_list', - static fn (OptionsResolver $optionsResolver, $value): array => (array) $value - ); - } + $optionsResolver->setNormalizer( + 'mentioned_list', + static fn (OptionsResolver $optionsResolver, $value): array => (array) $value + ); + $optionsResolver->setNormalizer( + 'mentioned_mobile_list', + static fn (OptionsResolver $optionsResolver, $value): array => (array) $value ); }