From cfd6016512b3e7a8fda75fa7e3b3008fc92e140c Mon Sep 17 00:00:00 2001 From: shimonhaga Date: Thu, 15 Dec 2022 23:28:14 +0900 Subject: [PATCH] Implement send sales mail --- client | 7 ++-- composer.json | 2 +- src/Communicator/Errors.php | 5 ++- src/Communicator/Request.php | 13 +++---- src/Communicator/RequestMeta.php | 33 +++++++++++++++++ src/Communicator/Response.php | 23 ++++++++---- src/Constants/AuthScope.php | 11 ------ src/Constants/ErrorCode.php | 19 ++++++++++ src/Constants/MailType.php | 19 ++++++++++ src/Entities/Error.php | 10 ++++++ src/Services/Sales.php | 62 +++++++++++++++++++++++++------- 11 files changed, 163 insertions(+), 41 deletions(-) create mode 100644 src/Communicator/RequestMeta.php create mode 100644 src/Constants/ErrorCode.php create mode 100644 src/Constants/MailType.php diff --git a/client b/client index 2fabe0a..534c3a3 100755 --- a/client +++ b/client @@ -6,11 +6,14 @@ namespace Shimoning\ColorMeShopApi; require_once __DIR__ . '/vendor/autoload.php'; echo __NAMESPACE__ . " shell\n"; -echo "-----\nexample:\n"; +echo "-----\n - example1: for OAuth\n"; echo "\$oAuth = new Services\OAuth(\$options);\n"; echo "\$uri = \$oAuth->getOAuthUrl(\$scopes);\n"; echo "\$accessToken = \$oAuth->exchangeCode2Token(\$code);\n"; echo "echo \$accessToken->getAccessToken();\n"; +echo "-----\n - example2: for Sales\n"; +echo "\$salesService = new Services\Sales(\$token);"; +echo "\$salesPage = \$salesService->page(new Entities\Sales\SearchParameters([]));"; // load .env if (\file_exists(__DIR__ . \DIRECTORY_SEPARATOR . '.env')) { @@ -28,7 +31,7 @@ $options = new Entities\OAuth\Options( $_ENV['CLIENT_SECRET'], $_ENV['REDIRECT_URI'] ?? Constants\AuthRedirectUri::NO_REDIRECT, ); -$scopes = new Values\Scopes(Constants\AuthScope::all()); +$scopes = new Values\Scopes(Constants\AuthScope::cases()); $sh->setScopeVariables([ 'options' => $options, diff --git a/composer.json b/composer.json index 4c1db99..edb565f 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ ], "minimum-stability": "dev", "prefer-stable": true, - "version": "0.0.9", + "version": "0.0.10", "license": "MIT", "authors": [ { diff --git a/src/Communicator/Errors.php b/src/Communicator/Errors.php index 7bbe287..033ffc3 100644 --- a/src/Communicator/Errors.php +++ b/src/Communicator/Errors.php @@ -3,6 +3,7 @@ namespace Shimoning\ColorMeShopApi\Communicator; use Shimoning\ColorMeShopApi\Entities\Collection; +use Shimoning\ColorMeShopApi\Entities\Error; class Errors extends Collection { @@ -23,7 +24,9 @@ static public function build(Response $response): self { return new self( $response, - $response->getParsedBody()['errors'] ?? [], + \array_map(function ($error) { + return new Error($error); + }, $response->getParsedBody()['errors'] ?? []), ); } } diff --git a/src/Communicator/Request.php b/src/Communicator/Request.php index f32db15..a9ede8e 100644 --- a/src/Communicator/Request.php +++ b/src/Communicator/Request.php @@ -4,7 +4,6 @@ use GuzzleHttp\Client; -// TODO: support PSR-7 class Request { private Options $_options; @@ -79,7 +78,7 @@ protected function sendRequest(string $method, string $uri, array $headers = [], ...$headers, ], ]; - if (($method === 'POST' || $method === 'PUT') && !isset($headers['Content-Type'])) { + if (!isset($headers['Content-Type']) && ($method === 'POST' || $method === 'PUT')) { if ($this->_options->isForm()) { $headers['Content-Type'] = 'application/x-www-form-urlencoded'; } else if ($this->_options->isJson()) { @@ -89,8 +88,7 @@ protected function sendRequest(string $method, string $uri, array $headers = [], if (!empty($data)) { if ($this->_options->isForm()) { $options['form_params'] = $data; - } else - if ($this->_options->isJson()) { + } else if ($this->_options->isJson()) { $options['json'] = $data; } else { $options['body'] = $data; @@ -101,11 +99,14 @@ protected function sendRequest(string $method, string $uri, array $headers = [], $response = $this->_client->request( $method, $uri, - $options + $options, ); // レスポンスを返す - return new Response($response); + return new Response( + $response, + new RequestMeta($method, $uri, $options), + ); } /** diff --git a/src/Communicator/RequestMeta.php b/src/Communicator/RequestMeta.php new file mode 100644 index 0000000..1ff72b2 --- /dev/null +++ b/src/Communicator/RequestMeta.php @@ -0,0 +1,33 @@ +_method = $method; + $this->_uri = $uri; + $this->_options = $options; + } + + public function getMethod(): string + { + return $this->_method; + } + public function getUri(): string + { + return $this->_uri; + } + public function getOptions(): array + { + return $this->_options; + } +} diff --git a/src/Communicator/Response.php b/src/Communicator/Response.php index a523524..b0c7800 100644 --- a/src/Communicator/Response.php +++ b/src/Communicator/Response.php @@ -6,16 +6,20 @@ class Response { + private RequestMeta $_requestMeta; private array $_rawHeader = []; private string $_rawBody = ''; - private array $_parsedBody; + private ?array $_parsedBody; private int $_status; /** * @param \Psr\Http\Message\ResponseInterface $response */ - public function __construct(ResponseInterface $response) - { + public function __construct( + ResponseInterface $response, + RequestMeta $requestMeta, + ) { + $this->_requestMeta = $requestMeta; $this->_rawHeader = $response->getHeaders(); $this->_status = $response->getStatusCode(); @@ -27,9 +31,9 @@ public function __construct(ResponseInterface $response) /** * ボディをパースする * @param string $body - * @return array + * @return ?array */ - private function parse(string $body): array + private function parse(string $body): ?array { // $utf8Body = \mb_convert_encoding($body, 'UTF-8', 'SJIS'); return \json_decode($body, true); @@ -55,9 +59,9 @@ public function getRawBody(): string /** * パース後のボディ - * @return array + * @return array|null */ - public function getParsedBody(): array + public function getParsedBody(): ?array { return $this->_parsedBody; } @@ -79,4 +83,9 @@ public function isSuccess(): bool { return 200 <= $this->_status && $this->_status < 300; } + + public function getRequestMeta(): RequestMeta + { + return $this->_requestMeta; + } } diff --git a/src/Constants/AuthScope.php b/src/Constants/AuthScope.php index 30cd0dc..716c7f1 100644 --- a/src/Constants/AuthScope.php +++ b/src/Constants/AuthScope.php @@ -9,15 +9,4 @@ enum AuthScope: string case READ_SALES = 'read_sales'; case WRITE_SALES = 'write_sales'; case READ_SHOP_COUPONS = 'read_shop_coupons'; - - static public function all() - { - return [ - self::READ_PRODUCTS, - self::WRITE_PRODUCTS, - self::READ_SALES, - self::WRITE_SALES, - self::READ_SHOP_COUPONS, - ]; - } } diff --git a/src/Constants/ErrorCode.php b/src/Constants/ErrorCode.php new file mode 100644 index 0000000..3c336ae --- /dev/null +++ b/src/Constants/ErrorCode.php @@ -0,0 +1,19 @@ + 'レコードが見つかりませんでした。', + // self::VALIDATE_ERROR_STOCK => '', + self::VALIDATE_ERROR_FIELD => 'パラメータが指定されていません。', + ]; + } +} diff --git a/src/Constants/MailType.php b/src/Constants/MailType.php new file mode 100644 index 0000000..98f02eb --- /dev/null +++ b/src/Constants/MailType.php @@ -0,0 +1,19 @@ + '受注メール', + self::PAID => '入金確認メール', + self::DELIVERED => '商品発送メール', + }; + } +} diff --git a/src/Entities/Error.php b/src/Entities/Error.php index 99a1307..929f1ff 100644 --- a/src/Entities/Error.php +++ b/src/Entities/Error.php @@ -6,6 +6,7 @@ class Error extends Entity { protected string $code; protected string $message; + protected ?string $field; protected int $status; /** @@ -26,6 +27,15 @@ public function getMessage(): string return $this->message; } + /** + * 対象フィールドを取得 + * @return string|null + */ + public function getField(): ?string + { + return $this->field; + } + /** * ステータスコードを取得 * @return string diff --git a/src/Services/Sales.php b/src/Services/Sales.php index 3729ac3..49cb297 100644 --- a/src/Services/Sales.php +++ b/src/Services/Sales.php @@ -6,14 +6,14 @@ use Shimoning\ColorMeShopApi\Communicator\Request; use Shimoning\ColorMeShopApi\Communicator\Options as RequestOption; use Shimoning\ColorMeShopApi\Communicator\Errors; - use Shimoning\ColorMeShopApi\Entities\Sales\SearchParameters; use Shimoning\ColorMeShopApi\Entities\Sales\Sale; use Shimoning\ColorMeShopApi\Entities\Sales\Stat; +use Shimoning\ColorMeShopApi\Entities\Sales\SaleUpdater; use Shimoning\ColorMeShopApi\Entities\Collection; use Shimoning\ColorMeShopApi\Entities\Pagination; use Shimoning\ColorMeShopApi\Entities\Page; -use Shimoning\ColorMeShopApi\Entities\Sales\SaleUpdater; +use Shimoning\ColorMeShopApi\Constants\MailType; class Sales { @@ -53,11 +53,11 @@ public function page( /** * @link https://developer.shop-pro.jp/docs/colorme-api#tag/sale/operation/getSale - * @param string $id + * @param int|string $id * @param string|null $accessToken * @return Sale|Errors */ - public function one(string $id, ?string $accessToken = null): Sale|Errors + public function one(int|string $id, ?string $accessToken = null): Sale|Errors { $response = (new Request(new RequestOption([ 'authorization' => $accessToken ?? $this->_accessToken, @@ -75,10 +75,13 @@ public function one(string $id, ?string $accessToken = null): Sale|Errors * @link https://developer.shop-pro.jp/docs/colorme-api#tag/sale/operation/statSale * @param DateTimeInterface $dateTime * @param string|null $accessToken + * @param string|null $accessToken * @return Stat|Errors */ - public function stat(DateTimeInterface $dateTime, ?string $accessToken = null): Stat|Errors - { + public function stat( + DateTimeInterface $dateTime, + ?string $accessToken = null, + ): Stat|Errors { $response = (new Request(new RequestOption([ 'authorization' => $accessToken ?? $this->_accessToken, ])))->get( @@ -97,10 +100,13 @@ public function stat(DateTimeInterface $dateTime, ?string $accessToken = null): /** * @link https://developer.shop-pro.jp/docs/colorme-api#tag/sale/operation/updateSale * @param SaleUpdater $updater + * @param string|null $accessToken * @return Sale|Errors */ - public function update(SaleUpdater $updater): Sale|Errors - { + public function update( + SaleUpdater $updater, + ?string $accessToken = null, + ): Sale|Errors { $response = (new Request(new RequestOption([ 'authorization' => $accessToken ?? $this->_accessToken, 'json' => true, @@ -119,12 +125,16 @@ public function update(SaleUpdater $updater): Sale|Errors /** * @link https://developer.shop-pro.jp/docs/colorme-api#tag/sale/operation/cancelSale - * @param string $id + * @param int|string $id * @param bool|null $restock + * @param string|null $accessToken * @return Sale|Errors */ - public function cancel(string $id, ?bool $restock = false): Sale|Errors - { + public function cancel( + int|string $id, + ?bool $restock = false, + ?string $accessToken = null, + ): Sale|Errors { $response = (new Request(new RequestOption([ 'authorization' => $accessToken ?? $this->_accessToken, 'json' => true, @@ -141,6 +151,32 @@ public function cancel(string $id, ?bool $restock = false): Sale|Errors return new Sale($data['sale'] ?? []); } - // TODO: implement - public function sendMail() {} + /** + * @link https://developer.shop-pro.jp/docs/colorme-api#tag/sale/operation/sendSalesMail + * @param int|string $id + * @param MailType $mailType + * @param string|null $accessToken + * @return true|Errors + */ + public function sendMail( + int|string $id, + MailType $mailType, + ?string $accessToken = null, + ): bool|Errors { + $response = (new Request(new RequestOption([ + 'authorization' => $accessToken ?? $this->_accessToken, + 'json' => true, + ])))->post( + 'https://api.shop-pro.jp/v1/sales/' . $id . '/mails', + [ + 'mail' => [ + 'type' => $mailType->value, + ], + ], + ); + if (! $response->isSuccess()) { + return Errors::build($response); + } + return true; + } }