diff --git a/README.md b/README.md index 03d599fb..86a313da 100644 --- a/README.md +++ b/README.md @@ -359,3 +359,6 @@ If you find a bug, please submit the issue in Github directly. As always, if you need additional assistance, drop us a note through your account at [https://app.mailgun.com/support](https://app.mailgun.com/support). + +## Examples section +[Examples section](doc/examples.md) contains examples of how to use the SDK. diff --git a/doc/examples.md b/doc/examples.md new file mode 100644 index 00000000..e5d3be20 --- /dev/null +++ b/doc/examples.md @@ -0,0 +1,58 @@ +## Domain Keys Example + +```php +domainKeys()->listKeysForDomains(); + print_r($res); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} + +try { + $res = $mgClient->domainKeys()->deleteDomainKey($domain, 'xxx'); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} + +try { + $res = $mgClient->domainKeys()->listDomainKeys($domain); + print_r($res); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} +try { + $res = $mgClient->domainKeys()->createDomainKey($domain, sprintf('key-%s', time())); + print_r($res); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} + +try { + $res = $mgClient->domainKeys()->deleteDomainKey($domain, 'key-xxx'); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} + + +try { + $res = $mgClient->domainKeys()->createDomainKey($domain, sprintf('key-%s', time())); + print_r($res); +} catch (Throwable $t) { + print_r($t->getMessage()); + print_r($t->getTraceAsString()); +} + +``` diff --git a/src/Api/DomainKeys.php b/src/Api/DomainKeys.php new file mode 100644 index 00000000..6e4fb728 --- /dev/null +++ b/src/Api/DomainKeys.php @@ -0,0 +1,142 @@ +httpGet('/v1/dkim/keys', $params, $requestHeaders); + + return $this->hydrateResponse($response, IndexResponse::class); + } + + /** + * Returns a list of domains on the account. + * @param string $authorityName + * @param array $requestHeaders + * @return IndexResponse|array + * @throws ClientExceptionInterface + * @throws \JsonException + * @throws Exception + */ + public function listDomainKeys(string $authorityName, array $requestHeaders = []) + { + Assert::stringNotEmpty($authorityName); + + $response = $this->httpGet(sprintf('/v4/domains/%s/keys', $authorityName), [], $requestHeaders); + + return $this->hydrateResponse($response, DomainKeyResponse::class); + } + + /** + * @param string $signingDomain + * @param string $selector + * @param string|null $bits + * @param array $requestHeaders + * @return mixed|ResponseInterface + * @throws ClientExceptionInterface + * @throws \JsonException + * @throws Exception + */ + public function createDomainKey(string $signingDomain, string $selector, ?string $bits = null, array $requestHeaders = []) + { + Assert::stringNotEmpty($signingDomain); + Assert::stringNotEmpty($selector); + + $params = [ + 'signing_domain' => $signingDomain, + 'selector' => $selector, + ]; + + if (!empty($bits)) { + Assert::oneOf( + $bits, + self::BITS_SIZE, + 'Length of your domain’s generated DKIM key must be 1024 or 2048' + ); + $params['bits'] = $bits; + } + + $response = $this->httpPost('/v1/dkim/keys', $params, $requestHeaders); + + return $this->hydrateResponse($response, DomainKeyResponse::class); + } + + /** + * @param string $signingDomain + * @param string $selector + * @param array $requestHeaders + * @return mixed|ResponseInterface + * @throws ClientExceptionInterface + * @throws \JsonException + */ + public function deleteDomainKey(string $signingDomain, string $selector, array $requestHeaders = []) + { + Assert::stringNotEmpty($signingDomain); + Assert::stringNotEmpty($selector); + + $params = [ + 'signing_domain' => $signingDomain, + 'selector' => $selector, + ]; + + $response = $this->httpDelete('/v1/dkim/keys', $params, $requestHeaders); + + return $this->hydrateResponse($response, DeleteResponse::class); + } +} diff --git a/src/Mailgun.php b/src/Mailgun.php index ba381165..81e6833c 100644 --- a/src/Mailgun.php +++ b/src/Mailgun.php @@ -14,6 +14,7 @@ use Http\Client\Common\PluginClient; use Mailgun\Api\Attachment; use Mailgun\Api\Domain; +use Mailgun\Api\DomainKeys; use Mailgun\Api\EmailValidation; use Mailgun\Api\EmailValidationV4; use Mailgun\Api\Event; @@ -263,4 +264,12 @@ public function metrics(): Metrics { return new Metrics($this->httpClient, $this->requestBuilder, $this->hydrator); } + + /** + * @return DomainKeys + */ + public function domainKeys(): Api\DomainKeys + { + return new Api\DomainKeys($this->httpClient, $this->requestBuilder, $this->hydrator); + } } diff --git a/src/Model/Domain/DnsRecord.php b/src/Model/Domain/DnsRecord.php index f4c71676..8ea4e1b5 100644 --- a/src/Model/Domain/DnsRecord.php +++ b/src/Model/Domain/DnsRecord.php @@ -24,6 +24,7 @@ final class DnsRecord private ?string $priority; private ?string $valid; private array $cached; + private bool $isActive; public static function create(array $data): self { @@ -34,6 +35,7 @@ public static function create(array $data): self $model->priority = $data['priority'] ?? null; $model->valid = $data['valid'] ?? null; $model->cached = $data['cached'] ?? []; + $model->isActive = $data['is_active'] ?? false; return $model; } @@ -95,4 +97,21 @@ public function getCached(): array { return $this->cached; } + + /** + * @return bool + */ + public function isActive(): bool + { + return $this->isActive; + } + + /** + * @param bool $isActive + * @return void + */ + public function setIsActive(bool $isActive): void + { + $this->isActive = $isActive; + } } diff --git a/src/Model/Domain/DomainKeyResponse.php b/src/Model/Domain/DomainKeyResponse.php new file mode 100644 index 00000000..6ca16bfa --- /dev/null +++ b/src/Model/Domain/DomainKeyResponse.php @@ -0,0 +1,123 @@ +setSelector($item['selector'] ?? ''); + $model->setSigningDomain($item['signing_domain'] ?? ''); + if (!empty($item['dns_record'])) { + $model->setDnsRecord(DnsRecord::create($item['dns_record'])); + } + + $items[] = $model; + } + $object->setItems($items); + + return $object; + } + + $model = new self(); + $model->setSelector($data['selector'] ?? ''); + $model->setDnsRecord(DnsRecord::create($data)); + $model->setSigningDomain($data['signing_domain'] ?? ''); + + return $model; + } + + /** + * @return string + */ + public function getSigningDomain(): string + { + return $this->signingDomain; + } + + /** + * @param string $signingDomain + */ + public function setSigningDomain(string $signingDomain): void + { + $this->signingDomain = $signingDomain; + } + + /** + * @return string + */ + public function getSelector(): string + { + return $this->selector; + } + + /** + * @param string $selector + */ + public function setSelector(string $selector): void + { + $this->selector = $selector; + } + + /** + * @return DnsRecord + */ + public function getDnsRecord(): DnsRecord + { + return $this->dnsRecord; + } + + /** + * @param DnsRecord $dnsRecord + */ + public function setDnsRecord(DnsRecord $dnsRecord): void + { + $this->dnsRecord = $dnsRecord; + } + + /** + * @return array + */ + public function getItems(): array + { + return $this->items; + } + + /** + * @param array $items + * @return void + */ + public function setItems(array $items): void + { + $this->items = $items; + } + + private function __construct() + { + } +} diff --git a/src/Model/Domain/IndexResponse.php b/src/Model/Domain/IndexResponse.php index cb905a10..92edae0a 100644 --- a/src/Model/Domain/IndexResponse.php +++ b/src/Model/Domain/IndexResponse.php @@ -20,10 +20,12 @@ final class IndexResponse implements ApiResponse { private int $totalCount; private array $items; + private array $paging; public static function create(array $data): self { $items = []; + $paging = []; if (isset($data['items'])) { foreach ($data['items'] as $item) { @@ -37,9 +39,12 @@ public static function create(array $data): self $count = count($items); } + $paging = $data['paging'] ?? []; + $model = new self(); $model->totalCount = $count; $model->items = $items; + $model->paging = $paging; return $model; } @@ -63,4 +68,21 @@ public function getDomains(): array { return $this->items; } + + /** + * @return array + */ + public function getPaging(): array + { + return $this->paging; + } + + /** + * @param array $paging + * @return void + */ + public function setPaging(array $paging): void + { + $this->paging = $paging; + } } diff --git a/tests/Api/DomainKeysTest.php b/tests/Api/DomainKeysTest.php new file mode 100644 index 00000000..54732721 --- /dev/null +++ b/tests/Api/DomainKeysTest.php @@ -0,0 +1,123 @@ +setRequestMethod('GET'); + $this->setRequestUri(sprintf('/v4/domains/%s/keys', $domain)); + $this->setHttpResponse( + new Response( + 200, + ['Content-Type' => 'application/json'], + <<getApiInstance(); + /** + * @var DomainKeyResponse $response + */ + $response = $api->listDomainKeys($domain); + $this->assertInstanceOf(DomainKeyResponse::class, $response); + $this->assertEquals(2, count($response->getItems())); + foreach ($response->getItems() as $item) { + $this->assertInstanceOf(DomainKeyResponse::class, $item); + } + } + + public function testCreateDomainKey() + { + $this->setRequestMethod('POST'); + $this->setRequestUri('/v1/dkim/keys'); + $this->setRequestBody( + [ + 'signing_domain' => 'example.com', + 'selector' => 'foo', + ] + ); + $this->setHttpResponse( + new Response( + 200, + ['Content-Type' => 'application/json'], + <<setHydrateClass(DomainKeyResponse::class); + + /** + * @var DomainKeyResponse $response + */ + $api = $this->getApiInstance(); + $res = $api->createDomainKey('example.com', 'foo'); + $this->assertInstanceOf(DomainKeyResponse::class, $res); + } +}