diff --git a/src/Api/Domain.php b/src/Api/Domain.php
index 0a5750d..68d3585 100644
--- a/src/Api/Domain.php
+++ b/src/Api/Domain.php
@@ -20,8 +20,12 @@ use Mailgun\Model\Domain\DeleteCredentialResponse;
use Mailgun\Model\Domain\DeleteResponse;
use Mailgun\Model\Domain\IndexResponse;
use Mailgun\Model\Domain\ShowResponse;
+use Mailgun\Model\Domain\TrackingResponse;
+use Mailgun\Model\Domain\UpdateClickTrackingResponse;
use Mailgun\Model\Domain\UpdateConnectionResponse;
use Mailgun\Model\Domain\UpdateCredentialResponse;
+use Mailgun\Model\Domain\UpdateOpenTrackingResponse;
+use Mailgun\Model\Domain\UpdateUnsubscribeTrackingResponse;
use Mailgun\Model\Domain\VerifyResponse;
use Psr\Http\Message\ResponseInterface;
@@ -299,4 +303,80 @@ class Domain extends HttpApi
return $this->hydrateResponse($response, VerifyResponse::class);
}
+
+ /**
+ * Returns a domain tracking settings.
+ *
+ * @param string $domain name of the domain
+ *
+ * @return TrackingResponse|array|ResponseInterface
+ */
+ public function tracking(string $domain)
+ {
+ Assert::stringNotEmpty($domain);
+
+ $response = $this->httpGet(sprintf('/v3/domains/%s/tracking', $domain));
+
+ return $this->hydrateResponse($response, TrackingResponse::class);
+ }
+
+ /**
+ * Updates a domain click tracking settings.
+ *
+ * @param string $domain name of the domain
+ *
+ * @param bool $active
+ * @return UpdateClickTrackingResponse|array|ResponseInterface
+ */
+ public function updateClickTracking(string $domain, bool $active)
+ {
+ $params = [
+ 'active' => $active ? 'true' : 'false',
+ ];
+
+ $response = $this->httpPut(sprintf('/v3/domains/%s/tracking/click', $domain), $params);
+
+ return $this->hydrateResponse($response, UpdateClickTrackingResponse::class);
+ }
+
+ /**
+ * Updates a domain open tracking settings.
+ *
+ * @param string $domain name of the domain
+ * @param bool $active
+ *
+ * @return UpdateOpenTrackingResponse|array|ResponseInterface
+ */
+ public function updateOpenTracking(string $domain, bool $active)
+ {
+ $params = [
+ 'active' => $active ? 'true' : 'false',
+ ];
+
+ $response = $this->httpPut(sprintf('/v3/domains/%s/tracking/open', $domain), $params);
+
+ return $this->hydrateResponse($response, UpdateOpenTrackingResponse::class);
+ }
+
+ /**
+ * Updates a domain unsubscribe tracking settings.
+ *
+ * @param string $domain name of the domain
+ * @param bool $active
+ * @param string $htmlFooter
+ * @param string $textFooter
+ * @return UpdateUnsubscribeTrackingResponse|array|ResponseInterface
+ */
+ public function updateUnsubscribeTracking(string $domain, bool $active, string $htmlFooter, string $textFooter)
+ {
+ $params = [
+ 'active' => $active ? 'true' : 'false',
+ 'html_footer' => $htmlFooter,
+ 'text_footer' => $textFooter,
+ ];
+
+ $response = $this->httpPut(sprintf('/v3/domains/%s/tracking/unsubscribe', $domain), $params);
+
+ return $this->hydrateResponse($response, UpdateUnsubscribeTrackingResponse::class);
+ }
}
diff --git a/src/Model/Domain/ClickTracking.php b/src/Model/Domain/ClickTracking.php
new file mode 100644
index 0000000..aa31e81
--- /dev/null
+++ b/src/Model/Domain/ClickTracking.php
@@ -0,0 +1,42 @@
+
+ */
+final class ClickTracking
+{
+ private $active;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->active = !!($data['active'] ?? null);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return bool
+ */
+ public function isActive(): bool
+ {
+ return $this->active;
+ }
+}
diff --git a/src/Model/Domain/OpenTracking.php b/src/Model/Domain/OpenTracking.php
new file mode 100644
index 0000000..54e5dfb
--- /dev/null
+++ b/src/Model/Domain/OpenTracking.php
@@ -0,0 +1,42 @@
+
+ */
+final class OpenTracking
+{
+ private $active;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->active = !!($data['active'] ?? null);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return bool
+ */
+ public function isActive(): bool
+ {
+ return $this->active;
+ }
+}
diff --git a/src/Model/Domain/TrackingResponse.php b/src/Model/Domain/TrackingResponse.php
new file mode 100644
index 0000000..ebb13e2
--- /dev/null
+++ b/src/Model/Domain/TrackingResponse.php
@@ -0,0 +1,68 @@
+
+ */
+final class TrackingResponse implements ApiResponse
+{
+ private $click;
+ private $open;
+ private $unsubscribe;
+
+ public static function create(array $data): ?self
+ {
+ if (!isset($data['tracking'])) {
+ return null;
+ }
+
+ $trackingSettings = $data['tracking'];
+
+ $model = new self();
+ $model->click = ClickTracking::create($trackingSettings['click'] ?? []);
+ $model->open = OpenTracking::create($trackingSettings['click'] ?? []);
+ $model->unsubscribe = UnsubscribeTracking::create($trackingSettings['unsubscribe'] ?? []);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return ClickTracking
+ */
+ public function getClick(): ClickTracking
+ {
+ return $this->click;
+ }
+
+ /**
+ * @return OpenTracking
+ */
+ public function getOpen(): OpenTracking
+ {
+ return $this->open;
+ }
+
+ /**
+ * @return UnsubscribeTracking
+ */
+ public function getUnsubscribe(): UnsubscribeTracking
+ {
+ return $this->unsubscribe;
+ }
+}
diff --git a/src/Model/Domain/UnsubscribeTracking.php b/src/Model/Domain/UnsubscribeTracking.php
new file mode 100644
index 0000000..8974976
--- /dev/null
+++ b/src/Model/Domain/UnsubscribeTracking.php
@@ -0,0 +1,62 @@
+
+ */
+final class UnsubscribeTracking
+{
+ private $active;
+ private $htmlFooter;
+ private $textFooter;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->active = !!($data['active'] ?? null);
+ $model->htmlFooter = $data['html_footer'] ?? '';
+ $model->textFooter = $data['text_footer'] ?? '';
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return bool
+ */
+ public function isActive(): bool
+ {
+ return $this->active;
+ }
+
+ /**
+ * @return string
+ */
+ public function getHtmlFooter(): string
+ {
+ return $this->htmlFooter;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTextFooter(): string
+ {
+ return $this->textFooter;
+ }
+}
diff --git a/src/Model/Domain/UpdateClickTrackingResponse.php b/src/Model/Domain/UpdateClickTrackingResponse.php
new file mode 100644
index 0000000..0c085d6
--- /dev/null
+++ b/src/Model/Domain/UpdateClickTrackingResponse.php
@@ -0,0 +1,52 @@
+
+ */
+final class UpdateClickTrackingResponse implements ApiResponse
+{
+ private $message;
+ private $click;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->message = $data['message'] ?? null;
+ $model->click = ClickTracking::create($data['click'] ?? []);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getMessage(): ?string
+ {
+ return $this->message;
+ }
+
+ /**
+ * @return ClickTracking
+ */
+ public function getClick(): ClickTracking
+ {
+ return $this->click;
+ }
+}
diff --git a/src/Model/Domain/UpdateOpenTrackingResponse.php b/src/Model/Domain/UpdateOpenTrackingResponse.php
new file mode 100644
index 0000000..b62cf29
--- /dev/null
+++ b/src/Model/Domain/UpdateOpenTrackingResponse.php
@@ -0,0 +1,52 @@
+
+ */
+final class UpdateOpenTrackingResponse implements ApiResponse
+{
+ private $message;
+ private $open;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->message = $data['message'] ?? null;
+ $model->open = OpenTracking::create($data['open'] ?? []);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getMessage(): ?string
+ {
+ return $this->message;
+ }
+
+ /**
+ * @return OpenTracking
+ */
+ public function getOpen(): OpenTracking
+ {
+ return $this->open;
+ }
+}
diff --git a/src/Model/Domain/UpdateUnsubscribeTrackingResponse.php b/src/Model/Domain/UpdateUnsubscribeTrackingResponse.php
new file mode 100644
index 0000000..dc1623e
--- /dev/null
+++ b/src/Model/Domain/UpdateUnsubscribeTrackingResponse.php
@@ -0,0 +1,52 @@
+
+ */
+final class UpdateUnsubscribeTrackingResponse implements ApiResponse
+{
+ private $message;
+ private $unsubscribe;
+
+ public static function create(array $data): self
+ {
+ $model = new self();
+ $model->message = $data['message'] ?? null;
+ $model->unsubscribe = UnsubscribeTracking::create($data['unsubscribe'] ?? []);
+
+ return $model;
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getMessage(): ?string
+ {
+ return $this->message;
+ }
+
+ /**
+ * @return UnsubscribeTracking
+ */
+ public function getUnsubscribe(): UnsubscribeTracking
+ {
+ return $this->unsubscribe;
+ }
+}
diff --git a/tests/Api/DomainTest.php b/tests/Api/DomainTest.php
index 7ee036b..42bd103 100644
--- a/tests/Api/DomainTest.php
+++ b/tests/Api/DomainTest.php
@@ -20,8 +20,12 @@ use Mailgun\Model\Domain\DeleteCredentialResponse;
use Mailgun\Model\Domain\DeleteResponse;
use Mailgun\Model\Domain\IndexResponse;
use Mailgun\Model\Domain\ShowResponse;
+use Mailgun\Model\Domain\TrackingResponse;
+use Mailgun\Model\Domain\UpdateClickTrackingResponse;
use Mailgun\Model\Domain\UpdateConnectionResponse;
use Mailgun\Model\Domain\UpdateCredentialResponse;
+use Mailgun\Model\Domain\UpdateOpenTrackingResponse;
+use Mailgun\Model\Domain\UpdateUnsubscribeTrackingResponse;
use Mailgun\Model\Domain\VerifyResponse;
class DomainTest extends TestCase
@@ -256,4 +260,95 @@ JSON
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, null, ['127.0.0.1', '127.0.0.2']);
}
+
+ public function testTracking()
+ {
+ $this->setRequestMethod('GET');
+ $this->setRequestUri('/v3/domains/example.com/tracking');
+ $this->setHydrateClass(TrackingResponse::class);
+
+ /**
+ * @var $api Domain
+ */
+ $api = $this->getApiInstance();
+ $api->tracking('example.com');
+ }
+
+ public function activeInactiveDataProvider(): array
+ {
+ return [
+ [true],
+ [false],
+ ];
+ }
+
+ /**
+ * @dataProvider activeInactiveDataProvider
+ */
+ public function testUpdateClickTracking(bool $isActive)
+ {
+ $this->setRequestMethod('PUT');
+ $this->setRequestUri('/v3/domains/example.com/tracking/click');
+ $this->setRequestBody([
+ 'active' => $isActive ? 'true' : 'false',
+ ]);
+ $this->setHydrateClass(UpdateClickTrackingResponse::class);
+
+ /**
+ * @var $api Domain
+ */
+ $api = $this->getApiInstance();
+ $api->updateClickTracking('example.com', $isActive);
+ }
+
+ /**
+ * @dataProvider activeInactiveDataProvider
+ */
+ public function testUpdateOpenTracking(bool $isActive)
+ {
+ $this->setRequestMethod('PUT');
+ $this->setRequestUri('/v3/domains/example.com/tracking/open');
+ $this->setRequestBody([
+ 'active' => $isActive ? 'true' : 'false',
+ ]);
+ $this->setHydrateClass(UpdateOpenTrackingResponse::class);
+
+ /**
+ * @var $api Domain
+ */
+ $api = $this->getApiInstance();
+ $api->updateOpenTracking('example.com', $isActive);
+ }
+
+ public function unsubscribeDataProvider(): array
+ {
+ return [
+ [true, 'Test', 'Test1'],
+ [false, 'Test', 'Test2'],
+ ];
+ }
+
+ /**
+ * @dataProvider unsubscribeDataProvider
+ * @param bool $isActive
+ * @param string $htmlFooter
+ * @param string $textFooter
+ */
+ public function testUpdateUnsubscribeTracking(bool $isActive, string $htmlFooter, string $textFooter)
+ {
+ $this->setRequestMethod('PUT');
+ $this->setRequestUri('/v3/domains/example.com/tracking/unsubscribe');
+ $this->setRequestBody([
+ 'active' => $isActive ? 'true' : 'false',
+ 'html_footer' => $htmlFooter,
+ 'text_footer' => $textFooter,
+ ]);
+ $this->setHydrateClass(UpdateUnsubscribeTrackingResponse::class);
+
+ /**
+ * @var $api Domain
+ */
+ $api = $this->getApiInstance();
+ $api->updateUnsubscribeTracking('example.com', $isActive, $htmlFooter, $textFooter);
+ }
}
diff --git a/tests/Model/Domain/ClickTrackingTest.php b/tests/Model/Domain/ClickTrackingTest.php
new file mode 100644
index 0000000..4007ffb
--- /dev/null
+++ b/tests/Model/Domain/ClickTrackingTest.php
@@ -0,0 +1,30 @@
+assertTrue($model->isActive());
+ }
+}
diff --git a/tests/Model/Domain/OpenTrackingTest.php b/tests/Model/Domain/OpenTrackingTest.php
new file mode 100644
index 0000000..fbd864f
--- /dev/null
+++ b/tests/Model/Domain/OpenTrackingTest.php
@@ -0,0 +1,30 @@
+assertTrue($model->isActive());
+ }
+}
diff --git a/tests/Model/Domain/TrackingResponseTest.php b/tests/Model/Domain/TrackingResponseTest.php
new file mode 100644
index 0000000..371c984
--- /dev/null
+++ b/tests/Model/Domain/TrackingResponseTest.php
@@ -0,0 +1,57 @@
+Test<\/s>",
+ "text_footer": "Test"
+ }
+ }
+}
+JSON;
+ $model = TrackingResponse::create(json_decode($json, true));
+ $this->assertNotEmpty($model->getClick());
+ $this->assertInstanceOf(ClickTracking::class, $model->getClick());
+ $this->assertTrue($model->getClick()->isActive());
+
+ $this->assertNotEmpty($model->getOpen());
+ $this->assertInstanceOf(OpenTracking::class, $model->getOpen());
+ $this->assertTrue($model->getOpen()->isActive());
+
+ $this->assertNotEmpty($model->getUnsubscribe());
+ $this->assertInstanceOf(UnsubscribeTracking::class, $model->getUnsubscribe());
+ $this->assertTrue($model->getUnsubscribe()->isActive());
+ $this->assertEquals('Test', $model->getUnsubscribe()->getHtmlFooter());
+ $this->assertEquals('Test', $model->getUnsubscribe()->getTextFooter());
+ }
+}
diff --git a/tests/Model/Domain/UnsubscribeTrackingTest.php b/tests/Model/Domain/UnsubscribeTrackingTest.php
new file mode 100644
index 0000000..251f030
--- /dev/null
+++ b/tests/Model/Domain/UnsubscribeTrackingTest.php
@@ -0,0 +1,34 @@
+Test<\/s>",
+ "text_footer": "Test"
+}
+JSON;
+ $model = UnsubscribeTracking::create(json_decode($json, true));
+ $this->assertTrue($model->isActive());
+ $this->assertEquals('Test', $model->getHtmlFooter());
+ $this->assertEquals('Test', $model->getTextFooter());
+ }
+}
diff --git a/tests/Model/Domain/UpdateClickTrackingResponseTest.php b/tests/Model/Domain/UpdateClickTrackingResponseTest.php
new file mode 100644
index 0000000..6aa27e0
--- /dev/null
+++ b/tests/Model/Domain/UpdateClickTrackingResponseTest.php
@@ -0,0 +1,38 @@
+assertNotEmpty($model->getMessage());
+ $this->assertEquals('Domain tracking settings have been updated', $model->getMessage());
+ $this->assertNotEmpty($model->getClick());
+ $this->assertInstanceOf(ClickTracking::class, $model->getClick());
+ $this->assertTrue($model->getClick()->isActive());
+ }
+}
diff --git a/tests/Model/Domain/UpdateOpenTrackingResponseTest.php b/tests/Model/Domain/UpdateOpenTrackingResponseTest.php
new file mode 100644
index 0000000..6afd7c2
--- /dev/null
+++ b/tests/Model/Domain/UpdateOpenTrackingResponseTest.php
@@ -0,0 +1,38 @@
+assertNotEmpty($model->getMessage());
+ $this->assertEquals('Domain tracking settings have been updated', $model->getMessage());
+ $this->assertNotEmpty($model->getOpen());
+ $this->assertInstanceOf(OpenTracking::class, $model->getOpen());
+ $this->assertTrue($model->getOpen()->isActive());
+ }
+}
diff --git a/tests/Model/Domain/UpdateUnsubscribeTrackingResponseTest.php b/tests/Model/Domain/UpdateUnsubscribeTrackingResponseTest.php
new file mode 100644
index 0000000..6bce007
--- /dev/null
+++ b/tests/Model/Domain/UpdateUnsubscribeTrackingResponseTest.php
@@ -0,0 +1,42 @@
+test",
+ "text_footer": "test"
+ },
+ "message": "Domain tracking settings have been updated"
+}
+JSON;
+ $model = UpdateUnsubscribeTrackingResponse::create(json_decode($json, true));
+ $this->assertNotEmpty($model->getMessage());
+ $this->assertEquals('Domain tracking settings have been updated', $model->getMessage());
+ $this->assertNotEmpty($model->getUnsubscribe());
+ $this->assertInstanceOf(UnsubscribeTracking::class, $model->getUnsubscribe());
+ $this->assertTrue($model->getUnsubscribe()->isActive());
+ $this->assertEquals('test', $model->getUnsubscribe()->getHtmlFooter());
+ $this->assertEquals('test', $model->getUnsubscribe()->getTextFooter());
+ }
+}