From d5c8ca313489930a7935f906391a63c2e8478bf5 Mon Sep 17 00:00:00 2001 From: Oleksandr Mykhailenko Date: Sat, 28 Dec 2024 15:27:31 +0200 Subject: [PATCH] Fixed way of sending request with JSON body. loadMetrics works. Adjusted tests. Fixed warning related to the php 8.4 and nullable types --- CHANGELOG.md | 3 ++ README.md | 28 +++++++++++-------- src/Api/Domain.php | 8 +++--- src/Api/DomainV4.php | 3 +- src/Api/HttpApi.php | 18 +++++++----- src/Api/MailingList/Member.php | 8 +++--- src/Api/Metrics.php | 2 ++ src/Api/Route.php | 6 ++-- src/Api/Suppression/Complaint.php | 2 +- src/Api/Suppression/Unsubscribe.php | 2 +- src/HttpClient/RequestBuilder.php | 9 ++++++ src/Mailgun.php | 4 +-- .../Exceptions/MissingRequiredParameter.php | 2 +- src/Message/MessageBuilder.php | 8 +++--- tests/HttpClient/RequestBuilderTest.php | 2 +- 15 files changed, 63 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f1595c5..43a85dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release. +## 4.3.3 + - Fixed way of sending request with JSON body. loadMetrics works. Adjusted tests. Fixed warning related to the php 8.4 and nullable types + ## 4.3.2 - Added new API endpoint for getting metrics @see https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/ diff --git a/README.md b/README.md index 7d24d13d..03d599fb 100644 --- a/README.md +++ b/README.md @@ -202,20 +202,24 @@ use Mailgun\Mailgun; $mgClient = Mailgun::create('xxx'); $domain = "xxx.mailgun.org"; -$result = $mgClient->metrics()->loadMetrics([ - 'start' => 'Wed, 11 Sep 2024 18:29:02 +0300', - 'end' => 'Wed, 25 Sep 2024 18:29:02 +0300', - 'metrics' => [ - "failed_count", "opened_count", "sent_count", "delivered_count" +$payload = [ + "resolution" => "day", + "metrics" => [ + "accepted_count", + "delivered_count", + "clicked_rate", + "opened_rate" ], - 'resolution' => 'month', - 'precision' => 'day', - 'dimensions' => [ - 'time', + "include_aggregates" => true, + "start" => "Sun, 22 Dec 2024 18:29:02 +0000", + "dimensions" => [ + "time" ], - 'include_aggregates' => true, - 'include_subaccounts' => true, -]); + "end" => "Wed, 25 Dec 2024 18:29:02 +0000", + "include_subaccounts" => true +]; + +$result = $mgClient->metrics()->loadMetrics($payload); print_r($result->getItems()); diff --git a/src/Api/Domain.php b/src/Api/Domain.php index 44274419..73214553 100644 --- a/src/Api/Domain.php +++ b/src/Api/Domain.php @@ -101,10 +101,10 @@ public function show(string $domain, array $requestHeaders = []) */ public function create( string $domain, - string $smtpPass = null, - string $spamAction = null, - bool $wildcard = null, - bool $forceDkimAuthority = null, + ?string $smtpPass = null, + ?string $spamAction = null, + ?bool $wildcard = null, + ?bool $forceDkimAuthority = null, ?array $ips = null, ?string $pool_id = null, string $webScheme = 'http', diff --git a/src/Api/DomainV4.php b/src/Api/DomainV4.php index 7b530c77..fc2ee3ee 100644 --- a/src/Api/DomainV4.php +++ b/src/Api/DomainV4.php @@ -109,8 +109,7 @@ public function create( string $dkimKeySize = '1024', array $requestHeaders = [], ?string $dkimHostName = null, - ?string $dkimSelector = null, - + ?string $dkimSelector = null ) { Assert::stringNotEmpty($domain); diff --git a/src/Api/HttpApi.php b/src/Api/HttpApi.php index 358c1f88..c29abfa0 100644 --- a/src/Api/HttpApi.php +++ b/src/Api/HttpApi.php @@ -33,17 +33,17 @@ abstract class HttpApi * * @var ClientInterface */ - protected $httpClient; + protected ClientInterface $httpClient; /** * @var Hydrator|null */ - protected $hydrator; + protected ?Hydrator $hydrator; /** * @var RequestBuilder */ - protected $requestBuilder; + protected RequestBuilder $requestBuilder; /** * @param ClientInterface $httpClient @@ -117,7 +117,7 @@ protected function handleErrors(ResponseInterface $response): void * @param string $path Request path * @param array $parameters GET parameters * @param array $requestHeaders Request Headers - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface|\JsonException */ protected function httpGet(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface { @@ -142,10 +142,14 @@ protected function httpGet(string $path, array $parameters = [], array $requestH * @param string $path Request path * @param array $parameters POST parameters * @param array $requestHeaders Request headers - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface|\JsonException */ protected function httpPost(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface { + if (isset($requestHeaders['Content-Type']) && $requestHeaders['Content-Type'] === 'application/json') { + return $this->httpPostRaw($path, $parameters, $requestHeaders); + } + return $this->httpPostRaw($path, $this->createRequestBody($parameters), $requestHeaders); } @@ -155,7 +159,7 @@ protected function httpPost(string $path, array $parameters = [], array $request * @param string $path Request path * @param array|string $body Request body * @param array $requestHeaders Request headers - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface|\JsonException */ protected function httpPostRaw(string $path, $body, array $requestHeaders = []): ResponseInterface { @@ -176,7 +180,7 @@ protected function httpPostRaw(string $path, $body, array $requestHeaders = []): * @param string $path Request path * @param array $parameters PUT parameters * @param array $requestHeaders Request headers - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface|\JsonException */ protected function httpPut(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface { diff --git a/src/Api/MailingList/Member.php b/src/Api/MailingList/Member.php index ee9c725f..b12c2c4d 100644 --- a/src/Api/MailingList/Member.php +++ b/src/Api/MailingList/Member.php @@ -39,7 +39,7 @@ class Member extends HttpApi * @return IndexResponse * @throws ClientExceptionInterface */ - public function index(string $address, int $limit = 100, bool $subscribed = null, array $requestHeaders = []) + public function index(string $address, int $limit = 100, ?bool $subscribed = null, array $requestHeaders = []) { Assert::stringNotEmpty($address); Assert::greaterThan($limit, 0); @@ -92,10 +92,10 @@ public function show(string $list, string $address, array $requestHeaders = []) public function create( string $list, string $address, - string $name = null, + ?string $name = null, array $vars = [], - bool $subscribed = true, - bool $upsert = false, + ?bool $subscribed = true, + ?bool $upsert = false, array $requestHeaders = [] ) { Assert::stringNotEmpty($list); diff --git a/src/Api/Metrics.php b/src/Api/Metrics.php index 43da0622..ca1f27bc 100644 --- a/src/Api/Metrics.php +++ b/src/Api/Metrics.php @@ -64,6 +64,8 @@ public function loadMetrics(array $payload = [], array $requestHeaders = []): Me } } + $requestHeaders['Content-Type'] = 'application/json'; + $response = $this->httpPost('/v1/analytics/metrics', $payload, $requestHeaders); return $this->hydrateResponse($response, MetricsResponse::class); diff --git a/src/Api/Route.php b/src/Api/Route.php index bcf28702..64c76479 100644 --- a/src/Api/Route.php +++ b/src/Api/Route.php @@ -107,10 +107,10 @@ public function create(string $expression, array $actions, string $description, */ public function update( string $routeId, - string $expression = null, + ?string $expression = null, array $actions = [], - string $description = null, - int $priority = null, + ?string $description = null, + ?int $priority = null, array $requestHeaders = [] ) { Assert::stringNotEmpty($routeId); diff --git a/src/Api/Suppression/Complaint.php b/src/Api/Suppression/Complaint.php index 4e25121c..18b6014e 100644 --- a/src/Api/Suppression/Complaint.php +++ b/src/Api/Suppression/Complaint.php @@ -73,7 +73,7 @@ public function show(string $domain, string $address, array $requestHeaders = [] * @return CreateResponse * @throws ClientExceptionInterface */ - public function create(string $domain, string $address, string $createdAt = null, array $requestHeaders = []) + public function create(string $domain, string $address, ?string $createdAt = null, array $requestHeaders = []) { Assert::stringNotEmpty($domain); Assert::stringNotEmpty($address); diff --git a/src/Api/Suppression/Unsubscribe.php b/src/Api/Suppression/Unsubscribe.php index 646470fb..54cd93dd 100644 --- a/src/Api/Suppression/Unsubscribe.php +++ b/src/Api/Suppression/Unsubscribe.php @@ -95,7 +95,7 @@ public function create(string $domain, string $address, array $params = [], arra * @return DeleteResponse * @throws ClientExceptionInterface */ - public function delete(string $domain, string $address, string $tag = null, array $requestHeaders = []) + public function delete(string $domain, string $address, ?string $tag = null, array $requestHeaders = []) { Assert::stringNotEmpty($domain); Assert::stringNotEmpty($address); diff --git a/src/HttpClient/RequestBuilder.php b/src/HttpClient/RequestBuilder.php index 5ee230d3..4348fa23 100644 --- a/src/HttpClient/RequestBuilder.php +++ b/src/HttpClient/RequestBuilder.php @@ -51,6 +51,7 @@ class RequestBuilder * 'filename'=> string (optional) * 'headers' => array (optinal) ['header-name' => 'header-value'] * ) + * @throws \JsonException */ public function create(string $method, string $uri, array $headers = [], $body = null): RequestInterface { @@ -60,6 +61,14 @@ public function create(string $method, string $uri, array $headers = [], $body = return $this->createRequest($method, $uri, $headers, $stream); } + if (isset($headers['Content-Type']) && $headers['Content-Type'] === 'application/json') { + $jsonBody = json_encode($body, JSON_THROW_ON_ERROR); + $stream = $this->getStreamFactory()->createStream($jsonBody); + $headers['Content-Type'] = 'application/json'; + + return $this->createRequest($method, $uri, $headers, $stream); + } + $builder = $this->getMultipartStreamBuilder(); foreach ($body as $item) { $name = $this->getItemValue($item, 'name'); diff --git a/src/Mailgun.php b/src/Mailgun.php index 7821320e..ba381165 100644 --- a/src/Mailgun.php +++ b/src/Mailgun.php @@ -77,8 +77,8 @@ class Mailgun */ public function __construct( HttpClientConfigurator $configurator, - Hydrator $hydrator = null, - RequestBuilder $requestBuilder = null + ?Hydrator $hydrator = null, + ?RequestBuilder $requestBuilder = null ) { $this->requestBuilder = $requestBuilder ?: new RequestBuilder(); $this->hydrator = $hydrator ?: new ModelHydrator(); diff --git a/src/Message/Exceptions/MissingRequiredParameter.php b/src/Message/Exceptions/MissingRequiredParameter.php index 02104aff..33d2e770 100644 --- a/src/Message/Exceptions/MissingRequiredParameter.php +++ b/src/Message/Exceptions/MissingRequiredParameter.php @@ -20,7 +20,7 @@ class MissingRequiredParameter extends \Exception implements Exception * @param string|null $message * @return self */ - public static function create(string $parameter, string $message = null) + public static function create(string $parameter, ?string $message = null) { if (null === $message) { $message = 'The parameters passed to the API were invalid. Please specify "%s".'; diff --git a/src/Message/MessageBuilder.php b/src/Message/MessageBuilder.php index 2063d7f2..6c3d2e0e 100644 --- a/src/Message/MessageBuilder.php +++ b/src/Message/MessageBuilder.php @@ -318,7 +318,7 @@ public function setHtmlBody(string $htmlBody): self * @param string|null $attachmentName * @return $this */ - public function addAttachment(string $attachmentPath, string $attachmentName = null): self + public function addAttachment(string $attachmentPath, ?string $attachmentName = null): self { if (!isset($this->message['attachment'])) { $this->message['attachment'] = []; @@ -337,7 +337,7 @@ public function addAttachment(string $attachmentPath, string $attachmentName = n * @param string|null $attachmentName * @return $this */ - public function addStringAttachment(string $attachmentContent, string $attachmentName = null): self + public function addStringAttachment(string $attachmentContent, ?string $attachmentName = null): self { if (!isset($this->message['attachment'])) { $this->message['attachment'] = []; @@ -356,7 +356,7 @@ public function addStringAttachment(string $attachmentContent, string $attachmen * @param string|null $inlineImageName * @return $this */ - public function addInlineImage(string $inlineImagePath, string $inlineImageName = null): self + public function addInlineImage(string $inlineImagePath, ?string $inlineImageName = null): self { if (!isset($this->message['inline'])) { $this->message['inline'] = []; @@ -466,7 +466,7 @@ public function setClickTracking(bool $enabled, bool $htmlOnly = false): self * @return $this * @throws \Exception */ - public function setDeliveryTime(string $timeDate, string $timeZone = null): self + public function setDeliveryTime(string $timeDate, ?string $timeZone = null): self { if (null !== $timeZone) { $timeZoneObj = new DateTimeZone($timeZone); diff --git a/tests/HttpClient/RequestBuilderTest.php b/tests/HttpClient/RequestBuilderTest.php index e4617054..ee68f3f6 100644 --- a/tests/HttpClient/RequestBuilderTest.php +++ b/tests/HttpClient/RequestBuilderTest.php @@ -166,7 +166,7 @@ function (array $data) use ($item0) { $this->requestBuilder->setMultipartStreamBuilder($multipartStreamBuilder); $result = $this->requestBuilder - ->create('GET', 'http://foo.bar', ['Content-Type' => 'application/json'], [$item0]); + ->create('GET', 'http://foo.bar', [], [$item0]); $this->assertSame($request, $result); }