This commit is contained in:
Alexander 2022-12-05 17:45:30 +03:00 committed by GitHub
commit e95363ae10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
153 changed files with 6691 additions and 442 deletions

16
.github/main.workflow vendored
View file

@ -1,16 +0,0 @@
workflow "Main" {
on = "push"
resolves = ["Roave BC Check", "PHPStan"]
}
action "Roave BC Check" {
uses = "docker://nyholm/roave-bc-check-ga"
secrets = ["GITHUB_TOKEN"]
args = ""
}
action "PHPStan" {
uses = "docker://oskarstark/phpstan-ga"
secrets = ["GITHUB_TOKEN"]
args = "analyse"
}

49
.github/workflows/php.yml vendored Normal file
View file

@ -0,0 +1,49 @@
name: Tests
on:
push: ~
pull_request: ~
jobs:
php:
strategy:
matrix:
php-versions: [ '7.3', '7.4', '8.0' ]
runs-on: 'Ubuntu-20.04'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: none
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: PHP Unit Tests
run: vendor/bin/phpunit
lowest:
name: Lowest deps
runs-on: ubuntu-20.04
steps:
- name: Set up PHP
uses: shivammathur/setup-php@2.9.0
with:
php-version: 7.4
coverage: pcov
- name: Checkout code
uses: actions/checkout@v2
- name: Download dependencies
run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable --prefer-lowest
- name: Run tests
run: vendor/bin/phpunit

92
.github/workflows/static.yml vendored Normal file
View file

@ -0,0 +1,92 @@
on: [ pull_request ]
name: Static analysis
jobs:
phpstan:
name: PHPStan
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
tools: phpstan:0.12.92, cs2pr
- name: Download dependencies
uses: ramsey/composer-install@v1
- name: PHPStan
run: phpstan analyze --no-progress --error-format=checkstyle | cs2pr
php-cs-fixer:
name: PHP-CS-Fixer
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
tools: php-cs-fixer:3.9.5, cs2pr
- name: PHP-CS-Fixer
run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr
psalm:
name: Psalm
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
tools: vimeo/psalm:4.8.1
- name: Download dependencies
uses: ramsey/composer-install@v1
- name: Psalm
run: psalm --no-progress --output-format=github
roave-bc-check:
name: Roave BC Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Roave BC Check
uses: docker://nyholm/roave-bc-check-ga
composer-normalize:
name: Composer Normalize
runs-on: ubuntu-20.04
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
tools: composer-normalize
- name: Checkout code
uses: actions/checkout@v2
- name: Normalize
run: composer-normalize --dry-run

4
.gitignore vendored
View file

@ -5,3 +5,7 @@ composer.lock
phpunit.phar
phpunit.xml
modd.conf
.phpunit.result.cache
.php_cs.cache
.idea
.php-cs-fixer.cache

View file

@ -11,7 +11,8 @@ $finder = PhpCsFixer\Finder::create()
->in('src')
->in('tests');
return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
@ -19,10 +20,12 @@ return PhpCsFixer\Config::create()
'strict_param' => true,
'array_syntax' => ['syntax' => 'short'],
'declare_strict_types' => true,
'no_empty_phpdoc' => true,
'no_superfluous_phpdoc_tags' => true,
'no_empty_phpdoc' => false,
'no_superfluous_phpdoc_tags' => false,
'phpdoc_separation' => false,
'no_unneeded_final_method' => false, # prevent phpstan divergence
'header_comment' => [
'commentType' => 'comment',
'comment_type' => 'comment',
'header' => $header,
'location' => 'after_declare_strict',
'separate' => 'both',

View file

@ -1,10 +0,0 @@
filter:
paths: [src/*]
checks:
php:
code_rating: true
duplication: true
tools:
external_code_coverage:
timeout: 1200 # Timeout in seconds.
php_cpd: false

View file

@ -1,12 +0,0 @@
preset: symfony
finder:
path:
- "src"
- "tests"
enabled:
- short_array_syntax
disabled:
- phpdoc_annotation_without_dot # This is still buggy: https://github.com/symfony/symfony/pull/19198

View file

@ -1,52 +0,0 @@
language: php
sudo: false
cache:
directories:
- $HOME/.composer/cache/files
php:
- 7.1
- 7.2
- 7.3
branches:
except:
- /^analysis-.*$/
- /^patch-.*$/
env:
- TEST_COMMAND="composer test"
matrix:
fast_finish: true
include:
- php: 7.1
env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" PREFER_COVERAGE=true
- name: Backward compatibility test (Disabled)
php: 7.3
env: DEPENDENCIES="roave/backward-compatibility-check"
script: ./vendor/bin/roave-backward-compatibility-check || true
- name: PHPStan
php: 7.2
env: DEPENDENCIES="phpstan/phpstan"
script:
- ./vendor/bin/phpstan --version
- ./vendor/bin/phpstan analyse
before_install:
- if [[ "$PREFER_COVERAGE" = true ]] && [[ "$TRAVIS_PULL_REQUEST" = false ]]; then TEST_COMMAND="composer test-coverage" COVERAGE=true; fi
- if ! [ -z "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi;
install:
- composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction
script:
- composer validate --strict --no-check-lock
- echo $TEST_COMMAND
- $TEST_COMMAND
after_success:
- if [[ "$COVERAGE" = true ]]; then wget https://scrutinizer-ci.com/ocular.phar; fi
- if [[ "$COVERAGE" = true ]]; then php ocular.phar code-coverage:upload --format=php-clover build/coverage.xml; fi

View file

@ -1,13 +1,113 @@
# Change Log
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
## 3.5.5
### Fixed
- Cast integer values to string for sending multipart data
## 3.5.4
### Added
- Added ability to make own API request to needed endpoint
## 3.5.3
### Added
- Ability to update web_scheme for domain
- `http` or `https` - set your open, click and unsubscribe URLs to use http or https. The default is http
## 3.5.1
### Fixed
- Error with empty array for param recipient-variables. Fix was suggested by @deviarte
- Use null coalescing operator in IndexResponse.php when. Fix proposed by @TWithers
## 3.5.0
### Added
- Support for new webhook endpoints (#609 by @svenbw & #749 by @Nyholm)
## 3.4.1
### Fixed
- Fix double urlencoding (#747 by @uavn)
## 3.4.0
### Added
- Email Validation (#726 by @uavn)
- Please note the Email Validation requires **always** to use the US servers. The Mailgun Team didn't enable this service on the European endpoints.
## 3.3.0
### Added
- Support for PHP 8 (#727 by @DavidGarciaCat)
- Added `opened`, `clicked`, `unsubscribed` and `stored` to the `TotalResponseItem` (#739 by @Arkitecht)
### Removed
- Support for PHP 7.1 and 7.2 as they both have reached their end of life
## 3.2.0
### Added
- Domain tracking implementation (#711 by @uavn)
- Mailing list validation (#712 by @uavn)
- Suppression Whitelists (#713 by @uavn)
### Fixed
- Added pagination to tags (#717 by @uavn)
### Changed
- Expect Client to be of type ClientInterface or PluginClient (#660 by @tonythomas01)
## 3.1.0
### Added
- Suppressions allow now deleting an address passing an optional tag (#643 by @iwahara)
- Allow both `^1.0` and `^2.0` for `php-http/guzzle6-adapter` (#680 by @boboldehampsink)
- Add support for Mailing List `reply_preference` parameter (#684 by @twoonesixdigital)
- Add support for `Force DKIM Authority` when creating a Domain (#686 by @Tiboonn)
- Add support for PHP 7.4 (#698 by @snapshotpl)
- Allow assigning a domain to a list of ips during creation (#703 by @josephshanak)
- Add unmapped `log-level` property for Events (#704 by @uavn)
### Fixed
- Provide the Member's name just when it's not `null` (#639 by @indapublic)
- Fix typehint for Message `ShowResponse::getContentIdMap()` (#664 by @lvdhoorn)
- Fix endpoint for Domain's API (#668 by @tomschlick)
- Webhook support for array handling (#675 by @martin-sanjuan)
- Fix parameter name when assigning an IP to the specified Domain (#702 by @josephshanak)
- `Ip::index()` now returns all IPs instead of the shared IPs (#707 by @josephshanak)
### Changed
- Updated examples for Debugging and Hydrator usage (#634 by @tonybolzan and #681 by @Jiia)
- Updated link to the Mailgun Documentation page (#688 by @Casmo)
- Remove deprecated Laravel package due to it is archived (#695 by @tomschlick)
### Removed
- Remove method for non-existing Stats URL (#705 by @uavn)
## 3.0.0
### Added
- Support for PSR-4
- All classes `Mailgun\Model` are final or abstract.
- All classes `Mailgun\Model` are final or abstract.
### Changed
@ -18,13 +118,7 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee
### Removed
- Dependency on `php-http/message`.
### [Unreleased]
- API v4 Email Validation; please use US Servers with your public key instead
(please check the Issues [617](https://github.com/mailgun/mailgun-php/issues/617)
and [619](https://github.com/mailgun/mailgun-php/issues/619) for further details)
- Dependency on `php-http/message`.
## 2.8.1
@ -62,12 +156,12 @@ and [619](https://github.com/mailgun/mailgun-php/issues/619) for further details
### Changed
- Second argument to `Mailgun\Message\MessageBuilder::addBccRecipient()` is now optional.
- Second argument to `Mailgun\Message\MessageBuilder::addBccRecipient()` is now optional.
- We try to close open resources
### Fixed
- Fixed the type error when creating tags.
- Fixed the type error when creating tags.
## 2.6.0
@ -109,16 +203,16 @@ and [619](https://github.com/mailgun/mailgun-php/issues/619) for further details
- Add cached property for DNS record
- Add domain verification
- `HttpClientException::getResponseCode()`
- Added `AbstractDomainResponse` that `VerifyResponse` and `CreateResponse` extends.
- Added `AbstractDomainResponse` that `VerifyResponse` and `CreateResponse` extends.
### Fixed
- Possible empty content of `WebhookIndexResponse`.
- Typo in `TotalResponse` that caused the content to be empty.
- Typo in `TotalResponse` that caused the content to be empty.
### Changed
- Allow some parameters to `Domain::create` to be optional.
- Allow some parameters to `Domain::create` to be optional.
## 2.3.4
@ -137,7 +231,7 @@ and [619](https://github.com/mailgun/mailgun-php/issues/619) for further details
### Fixed
- When parsing an address in `MessageBuilder` we surround the recipient name with double quotes instead of single quotes.
- When parsing an address in `MessageBuilder` we surround the recipient name with double quotes instead of single quotes.
## 2.3.1
@ -154,25 +248,25 @@ and [619](https://github.com/mailgun/mailgun-php/issues/619) for further details
## 2.2.0
This version contains a new way of using the API. Each endpoint return a domain object and the
endpoints are grouped like the API documentation.
endpoints are grouped like the API documentation.
### Added
- Api classes in Mailgun\Api\*
- Api models/responses in Mailgun\Model\*
- Added Hydrators to hydrate PSR-7 responses to arrays or domain objects.
- Added Hydrators to hydrate PSR-7 responses to arrays or domain objects.
- All exceptions extend `Mailgun\Exception`.
- New exceptions in `Mailgun\Exception` namespace.
- Added `HttpClientConfigurator` to configure the HTTP client.
- Added `HttpClientConfigurator` to configure the HTTP client.
- Added HttpClient plugins `History` and `ReplaceUriPlugin`
- Assertions with Webmozart\Assert
- Assertions with Webmozart\Assert
- `Mailgun\Mailgun::getLastResponse()`
- `Mailgun\Connection\RestClient::getAttachment($url)`
- Clear license information
### Fixed
- Fix disordered POST parameters. We do not use array syntax.
- Fix disordered POST parameters. We do not use array syntax.
- Code styles
### Deprecated
@ -278,7 +372,7 @@ Bugfixes:
## 1.3 (2013-09-12)
Bugfixes:
- relaxed Guzzle requirement (#7 @travelton)
- fixed reply-to bug (#9 @travelton)

130
README.md
View file

@ -5,17 +5,14 @@ with the Mailgun API. Below are examples to get you started. For additional
examples, please see our official documentation at http://documentation.mailgun.com
[![Latest Version](https://img.shields.io/github/release/mailgun/mailgun-php.svg?style=flat-square)](https://github.com/mailgun/mailgun-php/releases)
[![Build Status](https://img.shields.io/travis/mailgun/mailgun-php/master.svg?style=flat-square)](https://travis-ci.org/mailgun/mailgun-php)
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/mailgun/mailgun-php.svg?style=flat-square)](https://scrutinizer-ci.com/g/mailgun/mailgun-php)
[![Quality Score](https://img.shields.io/scrutinizer/g/mailgun/mailgun-php.svg?style=flat-square)](https://scrutinizer-ci.com/g/mailgun/mailgun-php)
[![Total Downloads](https://img.shields.io/packagist/dt/mailgun/mailgun-php.svg?style=flat-square)](https://packagist.org/packages/mailgun/mailgun-php)
[![Join the chat at https://gitter.im/mailgun/mailgun-php](https://badges.gitter.im/mailgun/mailgun-php.svg)](https://gitter.im/mailgun/mailgun-php?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Installation
To install the SDK, you will need to be using [Composer](http://getcomposer.org/)
in your project.
If you aren't using Composer yet, it's really simple! Here's how to install
To install the SDK, you will need to be using [Composer](http://getcomposer.org/)
in your project.
If you aren't using Composer yet, it's really simple! Here's how to install
composer:
```bash
@ -25,13 +22,14 @@ curl -sS https://getcomposer.org/installer | php
The Mailgun API Client is not hard coupled to Guzzle, Buzz or any other library that sends
HTTP messages. Instead, it uses the [PSR-18](https://www.php-fig.org/psr/psr-18/) client abstraction.
This will give you the flexibility to choose what
[PSR-7 implementation and HTTP client](https://packagist.org/providers/php-http/client-implementation)
you want to use.
[PSR-7 implementation](https://packagist.org/providers/psr/http-message-implementation)
and [HTTP client](https://packagist.org/providers/psr/http-client-implementation)
you want to use.
If you just want to get started quickly you should run the following command:
If you just want to get started quickly you should run the following command:
```bash
composer require mailgun/mailgun-php kriswallsmith/buzz nyholm/psr7
composer require mailgun/mailgun-php symfony/http-client nyholm/psr7
```
## Usage
@ -64,17 +62,60 @@ $mg->messages()->send('example.com', [
Attention: `$domain` must match to the domain you have configured on [app.mailgun.com](https://app.mailgun.com/app/domains).
### Usage of new method for updating web scheme
```php
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('KEY', 'FULL_DOMAIN_URL');
$domain = "DOMAIN";
# Issue the call to the client.
$result = $mgClient->domains()->updateWebScheme($domain, 'https');
print_r($result);
```
### Custom http request to the API
```php
<?php
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('KEY', 'ENDPOINT');
$domain = "DOMAIN";
$path = 'some path';
$params = [];
# Issue the call to the client.
$resultPost = $mgClient->httpClient()->httpPost($path, $params);
$resultGet = $mgClient->httpClient()->httpGet($path, $params);
$resultPut = $mgClient->httpClient()->httpPut($path, $params);
$resultDelete = $mgClient->httpClient()->httpDelete($path, $params);
```
### All usage examples
You will find more detailed documentation at [/doc](doc/index.md) and on
[https://documentation.mailgun.com](https://documentation.mailgun.com/api_reference.html).
You will find more detailed documentation at [/doc](doc/index.md) and on
[https://documentation.mailgun.com](https://documentation.mailgun.com/en/latest/api_reference.html).
### Response
The result of an API call is, by default, a domain object. This will make it easy
to understand the response without reading the documentation. One can just read the
doc blocks on the response classes. This provides an excellent IDE integration.
```php
$mg = Mailgun::create('key-example');
$dns = $mg->domains()->show('example.com')->getInboundDNSRecords();
@ -85,7 +126,7 @@ foreach ($dns as $record) {
```
If you'd rather work with an array than an object you can inject the `ArrayHydrator`
to the Mailgun class.
to the Mailgun class.
```php
use Mailgun\Hydrator\ArrayHydrator;
@ -101,71 +142,76 @@ foreach ($data['receiving_dns_records'] as $record) {
}
```
You can also use the `NoopHydrator` to get a PSR7 Response returned from
the API calls.
You can also use the `NoopHydrator` to get a PSR7 Response returned from
the API calls.
**Warning: When using `NoopHydrator` there will be no exceptions on a non-200 response.**
### Debugging
Debugging the PHP SDK can be helpful when things aren't working quite right.
To debug the SDK, here are some suggestions:
Debugging the PHP SDK can be helpful when things aren't working quite right.
To debug the SDK, here are some suggestions:
Set the endpoint to Mailgun's Postbin. A Postbin is a web service that allows you to
post data, which then you can display it through a browser. Using Postbin is an easy way
to quickly determine what data you're transmitting to Mailgun's API.
**Step 1 - Create a new Postbin.**
Go to http://bin.mailgun.net. The Postbin will generate a special URL. Save that URL.
**Step 1 - Create a new Postbin.**
Go to http://bin.mailgun.net. The Postbin will generate a special URL. Save that URL.
**Step 2 - Instantiate the Mailgun client using Postbin.**
**Step 2 - Instantiate the Mailgun client using Postbin.**
*Tip: The bin id will be the URL part after bin.mailgun.net. It will be random generated letters and numbers.
*Tip: The bin id will be the URL part after bin.mailgun.net. It will be random generated letters and numbers.
For example, the bin id in this URL (http://bin.mailgun.net/aecf68de) is `aecf68de`.*
```php
use Mailgun\HttpClient\HttpClientConfigurator;
use Mailgun\Hydrator\NoopHydrator;
$configurator = new HttpClientConfigurator();
$configurator->setEndpoint('http://bin.mailgun.net/aecf68de');
$configurator->setApiKey('key-example');
$configurator->setDebug(true);
$mg = new Mailgun($configurator);
$mg = new Mailgun($configurator, new NoopHydrator());
# Now, compose and send your message.
$mg->messages()->send('example.com', [
'from' => 'bob@example.com',
'to' => 'sally@example.com',
'subject' => 'The PHP SDK is awesome!',
'from' => 'bob@example.com',
'to' => 'sally@example.com',
'subject' => 'The PHP SDK is awesome!',
'text' => 'It is so simple to send a message.'
]);
```
### Additional Info
For usage examples on each API endpoint, head over to our official documentation
pages.
For usage examples on each API endpoint, head over to our official documentation
pages.
This SDK includes a [Message Builder](src/Mailgun/Messages/README.md),
[Batch Message](src/Mailgun/Messages/README.md) and [Opt-In Handler](src/Mailgun/Lists/README.md) component.
This SDK includes a [Message Builder](src/Message/README.md),
[Batch Message](src/Message/README.md).
Message Builder allows you to quickly create the array of parameters, required
Message Builder allows you to quickly create the array of parameters, required
to send a message, by calling a methods for each parameter.
Batch Message is an extension of Message Builder, and allows you to easily send
a batch message job within a few seconds. The complexity of
batch messaging is eliminated!
Batch Message is an extension of Message Builder, and allows you to easily send
a batch message job within a few seconds. The complexity of
batch messaging is eliminated!
## Framework integration
If you are using a framework you might consider these composer packages to make the framework integration easier.
If you are using a framework you might consider these composer packages to make the framework integration easier.
* [tehplague/swiftmailer-mailgun-bundle](https://github.com/tehplague/swiftmailer-mailgun-bundle) for Symfony
* [Bogardo/Mailgun](https://github.com/Bogardo/Mailgun) for Laravel
* [katanyoo/yii2-mailgun-mailer](https://github.com/katanyoo/yii2-mailgun-mailer) for Yii2
* [narendravaghela/cakephp-mailgun](https://github.com/narendravaghela/cakephp-mailgun) for CakePHP
* [drupal/mailgun](https://www.drupal.org/project/mailgun) for Drupal
* [Laravel](https://laravel.com/docs/8.x/mail#mailgun-driver) Mail comes with Mailgun driver support
## Contribute
This SDK is an Open Source under the MIT license. It is, thus, maintained by collaborators and contributors.
Feel free to contribute in any way. As an example you may:
Feel free to contribute in any way. As an example you may:
* Trying out the `dev-master` code
* Create issues if you find problems
* Reply to other people's issues
@ -173,7 +219,7 @@ Feel free to contribute in any way. As an example you may:
### Running the test code
If you want to run the tests you should run the following commands:
If you want to run the tests you should run the following commands:
```terminal
git clone git@github.com:mailgun/mailgun-php.git
@ -184,11 +230,11 @@ composer test
## Support and Feedback
Be sure to visit the Mailgun official
[documentation website](http://documentation.mailgun.com/) for additional
information about our API.
Be sure to visit the Mailgun official
[documentation website](http://documentation.mailgun.com/) for additional
information about our API.
If you find a bug, please submit the issue in Github directly.
If you find a bug, please submit the issue in Github directly.
[Mailgun-PHP Issues](https://github.com/mailgun/mailgun-php/issues)
As always, if you need additional assistance, drop us a note through your account at

View file

@ -1,19 +1,30 @@
{
"name": "mailgun/mailgun-php",
"description": "The Mailgun SDK provides methods for all API functions.",
"license": "MIT",
"authors": [
{
"name": "Travis Swientek",
"email": "travis@mailgunhq.com"
}
],
"require": {
"php": "^7.1",
"psr/http-client": "^1.0",
"php-http/multipart-stream-builder": "^1.0",
"php-http/client-common": "^1.9 || ^2.0",
"php-http/discovery": "^1.6",
"webmozart/assert": "^1.2"
"php": "^7.3 || ^8.0",
"php-http/client-common": "^2.2.1",
"php-http/discovery": "^1.9.1",
"php-http/multipart-stream-builder": "^1.1.2",
"psr/http-client": "^1.0.1",
"webmozart/assert": "^1.9.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5",
"php-http/guzzle6-adapter": "^1.0",
"nyholm/psr7": "^1.0",
"nyholm/nsa": "^1.1"
"nyholm/nsa": "^1.2.1",
"nyholm/psr7": "^1.3.1",
"phpunit/phpunit": "^9.3",
"symfony/http-client": "^5.3"
},
"suggest": {
"nyholm/psr7": "PSR-7 message implementation",
"symfony/http-client": "HTTP client"
},
"autoload": {
"psr-4": {
@ -25,21 +36,6 @@
"Mailgun\\Tests\\": "tests/"
}
},
"suggest": {
"php-http/curl-client": "cURL client for PHP-HTTP",
"guzzlehttp/psr7": "PSR-7 message implementation that also provides common utility methods"
},
"license": "MIT",
"authors": [
{
"name": "Travis Swientek",
"email": "travis@mailgunhq.com"
}
],
"scripts": {
"test": "vendor/bin/phpunit",
"test-coverage": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
},
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"

View file

@ -321,12 +321,12 @@ $mailgun->webhooks()->show('example.com', 'accept');
#### Create a webhooks
```php
$mailgun->webhooks()->create('example.com', 'accept', 'https://www.exmple.com/webhook');
$mailgun->webhooks()->create('example.com', 'opened', [ 'https://www.exmple.com/webhook' ]);
```
#### Update a webhooks
```php
$mailgun->webhooks()->update('example.com', 4711, 'https://www.exmple.com/webhook');
$mailgun->webhooks()->update('example.com', 4711, [ 'https://www.exmple.com/webhook' ]);
```
#### Delete a webhooks

View file

@ -1,21 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">
<testsuites>
<testsuite name="Mailgun test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Mailgun test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>

21
phpunit.xml.dist.bak Normal file
View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">
<testsuites>
<testsuite name="Mailgun test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>

125
psalm.baseline.xml Normal file
View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.8.1@f73f2299dbc59a3e6c4d66cff4605176e728ee69">
<file src="src/Api/Domain.php">
<PossiblyUndefinedVariable occurrences="1">
<code>$params</code>
</PossiblyUndefinedVariable>
<RedundantCondition occurrences="3">
<code>boolean</code>
<code>boolean</code>
<code>nullOrString</code>
</RedundantCondition>
<TypeDoesNotContainNull occurrences="1">
<code>nullOrString</code>
</TypeDoesNotContainNull>
</file>
<file src="src/Api/HttpApi.php">
<ParamNameMismatch occurrences="1">
<code>$class</code>
</ParamNameMismatch>
</file>
<file src="src/Api/Ip.php">
<RedundantCondition occurrences="1">
<code>boolean</code>
</RedundantCondition>
</file>
<file src="src/Api/MailingList.php">
<PossiblyNullArgument occurrences="1">
<code>$this-&gt;hydrator</code>
</PossiblyNullArgument>
<RedundantCondition occurrences="1">
<code>isArray</code>
</RedundantCondition>
</file>
<file src="src/Api/MailingList/Member.php">
<RedundantCondition occurrences="2">
<code>isArray</code>
<code>isArray</code>
</RedundantCondition>
</file>
<file src="src/Api/Message.php">
<RedundantCondition occurrences="3">
<code>nullOrIsArray</code>
<code>string</code>
<code>string</code>
</RedundantCondition>
<TypeDoesNotContainNull occurrences="1">
<code>nullOrIsArray</code>
</TypeDoesNotContainNull>
</file>
<file src="src/Api/Pagination.php">
<PossiblyNullArgument occurrences="4">
<code>$response-&gt;getFirstUrl()</code>
<code>$response-&gt;getLastUrl()</code>
<code>$response-&gt;getNextUrl()</code>
<code>$response-&gt;getPreviousUrl()</code>
</PossiblyNullArgument>
</file>
<file src="src/Api/Route.php">
<RedundantCondition occurrences="1">
<code>isArray</code>
</RedundantCondition>
</file>
<file src="src/Api/Suppression/Complaint.php">
<PossiblyUndefinedVariable occurrences="1">
<code>$params</code>
</PossiblyUndefinedVariable>
</file>
<file src="src/Assert.php">
<MissingImmutableAnnotation occurrences="1">
<code>protected static function reportInvalidArgument($message)</code>
</MissingImmutableAnnotation>
</file>
<file src="src/HttpClient/Plugin/HistoryTrait.php">
<UnrecognizedStatement occurrences="1"/>
</file>
<file src="src/Mailgun.php">
<PossiblyNullArgument occurrences="1">
<code>$this-&gt;apiKey</code>
</PossiblyNullArgument>
</file>
<file src="src/Message/BatchMessage.php">
<PossiblyInvalidDocblockTag occurrences="4">
<code>@var string $first</code>
<code>@var string $full_name</code>
<code>@var string $id</code>
<code>@var string $last</code>
</PossiblyInvalidDocblockTag>
<PossiblyUndefinedMethod occurrences="1">
<code>getId</code>
</PossiblyUndefinedMethod>
</file>
<file src="src/Message/MessageBuilder.php">
<PossiblyInvalidDocblockTag occurrences="29">
<code>@var string</code>
<code>@var string</code>
<code>@var string</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $first</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $full_name</code>
<code>@var string $id If used with BatchMessage</code>
<code>@var string $id If used with BatchMessage</code>
<code>@var string $id If used with BatchMessage</code>
<code>@var string $id If used with BatchMessage</code>
<code>@var string $id If used with BatchMessage</code>
<code>@var string $last</code>
<code>@var string $last</code>
<code>@var string $last</code>
<code>@var string $last</code>
<code>@var string $last</code>
<code>@var string $last</code>
<code>@var string $last</code>
</PossiblyInvalidDocblockTag>
</file>
</files>

16
psalm.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<psalm
errorLevel="3"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm.baseline.xml"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

4
roave-bc-check.yaml Normal file
View file

@ -0,0 +1,4 @@
parameters:
ignoreErrors:
- '#Mailgun\\Api\\Webhook#'
- '#Mailgun\\Api\\Suppression#'

View file

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Mailgun\Api;
use Exception;
use Mailgun\Assert;
use Mailgun\Model\Domain\ConnectionResponse;
use Mailgun\Model\Domain\CreateCredentialResponse;
@ -20,23 +21,31 @@ 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 Mailgun\Model\Domain\WebSchemeResponse;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* @see https://documentation.mailgun.com/api-domains.html
* @see https://documentation.mailgun.com/api-domains.html
*
* @author Sean Johnson <sean@mailgun.com>
*/
class Domain extends HttpApi
{
private const DKIM_SIZES = ['1024', '2048'];
/**
* Returns a list of domains on the account.
*
*
* @return IndexResponse
* @throws ClientExceptionInterface
*/
public function index(int $limit = 100, int $skip = 0)
{
@ -58,6 +67,7 @@ class Domain extends HttpApi
* @param string $domain name of the domain
*
* @return ShowResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function show(string $domain)
{
@ -75,14 +85,20 @@ class Domain extends HttpApi
*
* @see https://documentation.mailgun.com/en/latest/api-domains.html#domains
*
* @param string $domain name of the domain
* @param string $smtpPass password for SMTP authentication
* @param string $spamAction `disable` or `tag` - inbound spam filtering
* @param bool $wildcard domain will accept email for subdomains
* @param string $domain name of the domain
* @param string $smtpPass password for SMTP authentication
* @param string $spamAction `disable` or `tag` - inbound spam filtering
* @param bool $wildcard domain will accept email for subdomains
* @param bool $forceDkimAuthority force DKIM authority
* @param string[] $ips an array of ips to be assigned to the domain
* @param ?string $pool_id pool id to assign to the domain
* @param string $webScheme `http` or `https` - set your open, click and unsubscribe URLs to use http or https. The default is http
* @param string $dkimKeySize Set length of your domains generated DKIM key
*
* @return CreateResponse|array|ResponseInterface
* @throws Exception
*/
public function create(string $domain, string $smtpPass = null, string $spamAction = null, bool $wildcard = null)
public function create(string $domain, string $smtpPass = null, string $spamAction = null, bool $wildcard = null, bool $forceDkimAuthority = null, ?array $ips = null, ?string $pool_id = null, string $webScheme = 'http', string $dkimKeySize = '1024')
{
Assert::stringNotEmpty($domain);
@ -107,6 +123,39 @@ class Domain extends HttpApi
$params['wildcard'] = $wildcard ? 'true' : 'false';
}
if (null !== $forceDkimAuthority) {
Assert::boolean($forceDkimAuthority);
$params['force_dkim_authority'] = $forceDkimAuthority ? 'true' : 'false';
}
if (null !== $ips) {
Assert::isList($ips);
Assert::allString($ips);
$params['ips'] = join(',', $ips);
}
if (!empty($webScheme)) {
Assert::stringNotEmpty($webScheme);
Assert::oneOf($webScheme, ['https', 'http']);
$params['web_scheme'] = $webScheme;
}
if (null !== $pool_id) {
Assert::stringNotEmpty($pool_id);
$params['pool_id'] = $pool_id;
}
if (!empty($dkimKeySize)) {
Assert::oneOf(
$dkimKeySize,
self::DKIM_SIZES,
'Length of your domains generated DKIM key must be 1024 or 2048'
);
$params['dkim_key_size'] = $dkimKeySize;
}
$response = $this->httpPost('/v3/domains', $params);
return $this->hydrateResponse($response, CreateResponse::class);
@ -119,6 +168,7 @@ class Domain extends HttpApi
* @param string $domain name of the domain
*
* @return DeleteResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function delete(string $domain)
{
@ -137,6 +187,7 @@ class Domain extends HttpApi
* @param int $skip Number of credentials to omit from the list
*
* @return CredentialResponse
* @throws ClientExceptionInterface
*/
public function credentials(string $domain, int $limit = 100, int $skip = 0)
{
@ -159,6 +210,7 @@ class Domain extends HttpApi
* @param string $password SMTP Password. Length min 5, max 32.
*
* @return CreateCredentialResponse|array|ResponseInterface
* @throws Exception
*/
public function createCredential(string $domain, string $login, string $password)
{
@ -185,6 +237,7 @@ class Domain extends HttpApi
* @param string $pass New SMTP Password. Length min 5, max 32.
*
* @return UpdateCredentialResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function updateCredential(string $domain, string $login, string $pass)
{
@ -209,6 +262,7 @@ class Domain extends HttpApi
* @param string $login SMTP Username
*
* @return DeleteCredentialResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function deleteCredential(string $domain, string $login)
{
@ -232,6 +286,7 @@ class Domain extends HttpApi
* @param string $domain name of the domain
*
* @return ConnectionResponse|ResponseInterface
* @throws ClientExceptionInterface
*/
public function connection(string $domain)
{
@ -251,6 +306,7 @@ class Domain extends HttpApi
* @param bool|null $noVerify disables TLS certificate and hostname verification
*
* @return UpdateConnectionResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function updateConnection(string $domain, ?bool $requireTLS, ?bool $noVerify)
{
@ -270,12 +326,40 @@ class Domain extends HttpApi
return $this->hydrateResponse($response, UpdateConnectionResponse::class);
}
/**
* Update webScheme for existing domain
* See below for spam filtering parameter information.
* {@link https://documentation.mailgun.com/user_manual.html#um-spam-filter}.
*
* @see https://documentation.mailgun.com/en/latest/api-domains.html#domains
*
* @param string $domain name of the domain
* @param string $webScheme `http` or `https` - set your open, click and unsubscribe URLs to use http or https. The default is http
* @return WebSchemeResponse|array|ResponseInterface
* @throws Exception
* @throws ClientExceptionInterface
*/
public function updateWebScheme(string $domain, string $webScheme = 'http')
{
$params = [];
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($webScheme);
Assert::oneOf($webScheme, ['https', 'http']);
$params['web_scheme'] = $webScheme;
$response = $this->httpPut(sprintf('/v3/domains/%s', $domain), $params);
return $this->hydrateResponse($response, WebSchemeResponse::class);
}
/**
* Returns a single domain.
*
* @param string $domain name of the domain
*
* @return VerifyResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function verify(string $domain)
{
@ -285,4 +369,101 @@ 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
* @throws ClientExceptionInterface
*/
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 The name of the domain
* @param string $active The status for this tracking (one of: yes, no)
*
* @return UpdateClickTrackingResponse|array|ResponseInterface
*
* @throws Exception
*/
public function updateClickTracking(string $domain, string $active)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($active);
Assert::oneOf($active, ['yes', 'no', 'htmlonly']);
$params = [
'active' => $active,
];
$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 The name of the domain
* @param string $active The status for this tracking (one of: yes, no)
*
* @return UpdateOpenTrackingResponse|array|ResponseInterface
* @throws ClientExceptionInterface
*/
public function updateOpenTracking(string $domain, string $active)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($active);
Assert::oneOf($active, ['yes', 'no']);
$params = [
'active' => $active,
];
$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 The name of the domain
* @param string $active The status for this tracking (one of: yes, no)
* @param string $htmlFooter The footer for HTML emails
* @param string $textFooter The footer for plain text emails
*
* @return UpdateUnsubscribeTrackingResponse|array|ResponseInterface
*
* @throws Exception
*/
public function updateUnsubscribeTracking(string $domain, string $active, string $htmlFooter, string $textFooter)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($active);
Assert::oneOf($active, ['yes', 'no', 'true', 'false']);
Assert::stringNotEmpty($htmlFooter);
Assert::nullOrString($textFooter);
$params = [
'active' => (in_array($active, ['yes', 'true'], true)) ? '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);
}
}

View file

@ -35,12 +35,11 @@ class EmailValidation extends HttpApi
* @param bool $mailboxVerification If set to true, a mailbox verification check will be performed
* against the address. The default is False.
*
* @throws InvalidArgumentException Thrown when local validation returns an error
* @throws HttpClientException Thrown when there's an error on Client side
* @throws HttpServerException Thrown when there's an error on Server side
* @throws \Exception Thrown when we don't catch a Client or Server side Exception
*
* @return ValidateResponse|ResponseInterface
* @throws InvalidArgumentException Thrown when local validation returns an error
* @throws HttpClientException Thrown when there's an error on Client side
* @throws HttpServerException Thrown when there's an error on Server side
* @throws \Exception Thrown when we don't catch a Client or Server side Exception
*/
public function validate(string $address, bool $mailboxVerification = false)
{
@ -73,12 +72,11 @@ class EmailValidation extends HttpApi
* @param bool $syntaxOnly Perform only syntax checks or DNS and ESP specific validation as well.
* The default is True.
*
* @throws InvalidArgumentException Thrown when local validation returns an error
* @throws HttpClientException Thrown when there's an error on Client side
* @throws HttpServerException Thrown when there's an error on Server side
* @throws \Exception Thrown when we don't catch a Client or Server side Exception
*
* @return ParseResponse|ResponseInterface
* @throws InvalidArgumentException Thrown when local validation returns an error
* @throws HttpClientException Thrown when there's an error on Client side
* @throws HttpServerException Thrown when there's an error on Server side
* @throws \Exception Thrown when we don't catch a Client or Server side Exception
*/
public function parse(string $addresses, bool $syntaxOnly = true)
{

273
src/Api/EmailValidationV4.php Executable file
View file

@ -0,0 +1,273 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Api;
use Exception;
use Mailgun\Assert;
use Mailgun\Model\EmailValidationV4\CreateBulkJobResponse;
use Mailgun\Model\EmailValidationV4\CreateBulkPreviewResponse;
use Mailgun\Model\EmailValidationV4\DeleteBulkJobResponse;
use Mailgun\Model\EmailValidationV4\GetBulkJobResponse;
use Mailgun\Model\EmailValidationV4\GetBulkJobsResponse;
use Mailgun\Model\EmailValidationV4\GetBulkPreviewResponse;
use Mailgun\Model\EmailValidationV4\GetBulkPreviewsResponse;
use Mailgun\Model\EmailValidationV4\PromoteBulkPreviewResponse;
use Mailgun\Model\EmailValidationV4\ValidateResponse;
use Psr\Http\Message\ResponseInterface;
/**
* @see https://documentation.mailgun.com/en/latest/api-email-validation.html
*/
class EmailValidationV4 extends HttpApi
{
/**
* Addresses are validated based off defined checks.
*
* @param string $address An email address to validate. Maximum: 512 characters.
* @param bool $providerLookup A provider lookup will be performed if Mailguns internal analysis is insufficient
*
* @return ValidateResponse|ResponseInterface
*
* @throws Exception Thrown when we don't catch a Client or Server side Exception
*/
public function validate(string $address, bool $providerLookup = true)
{
Assert::stringNotEmpty($address);
$params = [
'address' => $address,
'provider_lookup' => $providerLookup,
];
$response = $this->httpGet('/v4/address/validate', $params);
return $this->hydrateResponse($response, ValidateResponse::class);
}
/**
* @param string $listId ID given when the list created
* @param mixed $filePath File path or file content
*
* @return mixed|ResponseInterface
*
* @throws Exception
*/
public function createBulkJob(string $listId, $filePath)
{
Assert::stringNotEmpty($listId);
if (strlen($filePath) < PHP_MAXPATHLEN && is_file($filePath)) {
$fileData = ['filePath' => $filePath];
} else {
$fileData = [
'fileContent' => $filePath,
'filename' => 'file',
];
}
$postDataMultipart = [];
$postDataMultipart[] = $this->prepareFile('file', $fileData);
$response = $this->httpPostRaw(sprintf('/v4/address/validate/bulk/%s', $listId), $postDataMultipart);
$this->closeResources($postDataMultipart);
return $this->hydrateResponse($response, CreateBulkJobResponse::class);
}
/**
* @param string $listId ID given when the list created
*
* @return DeleteBulkJobResponse|ResponseInterface
*
* @throws Exception
*/
public function deleteBulkJob(string $listId)
{
Assert::stringNotEmpty($listId);
$response = $this->httpDelete(sprintf('/v4/address/validate/bulk/%s', $listId));
return $this->hydrateResponse($response, DeleteBulkJobResponse::class);
}
/**
* @param string $listId ID given when the list created
*
* @return GetBulkJobResponse|ResponseInterface
*
* @throws Exception
*/
public function getBulkJob(string $listId)
{
Assert::stringNotEmpty($listId);
$response = $this->httpGet(sprintf('/v4/address/validate/bulk/%s', $listId));
return $this->hydrateResponse($response, GetBulkJobResponse::class);
}
/**
* @param int $limit Jobs limit
*
* @return GetBulkJobsResponse|ResponseInterface
*
* @throws Exception
*/
public function getBulkJobs(int $limit = 500)
{
Assert::greaterThan($limit, 0);
$response = $this->httpGet('/v4/address/validate/bulk', [
'limit' => $limit,
]);
return $this->hydrateResponse($response, GetBulkJobsResponse::class);
}
/**
* @param int $limit Previews Limit
*
* @return mixed|ResponseInterface
*
* @throws Exception
*/
public function getBulkPreviews(int $limit = 500)
{
Assert::greaterThan($limit, 0);
$response = $this->httpGet('/v4/address/validate/preview', [
'limit' => $limit,
]);
return $this->hydrateResponse($response, GetBulkPreviewsResponse::class);
}
/**
* @param string $previewId ID given when the list created
* @param mixed $filePath File path or file content
*
* @return mixed|ResponseInterface
*
* @throws Exception
*/
public function createBulkPreview(string $previewId, $filePath)
{
Assert::stringNotEmpty($previewId);
if (strlen($filePath) < PHP_MAXPATHLEN && is_file($filePath)) {
$fileData = ['filePath' => $filePath];
} else {
$fileData = [
'fileContent' => $filePath,
'filename' => 'file',
];
}
$postDataMultipart = [];
$postDataMultipart[] = $this->prepareFile('file', $fileData);
$response = $this->httpPostRaw(sprintf('/v4/address/validate/preview/%s', $previewId), $postDataMultipart);
$this->closeResources($postDataMultipart);
return $this->hydrateResponse($response, CreateBulkPreviewResponse::class);
}
/**
* @param string $previewId ID given when the list created
*
* @return mixed|ResponseInterface
*
* @throws Exception
*/
public function getBulkPreview(string $previewId)
{
Assert::stringNotEmpty($previewId);
$response = $this->httpGet(sprintf('/v4/address/validate/preview/%s', $previewId));
return $this->hydrateResponse($response, GetBulkPreviewResponse::class);
}
/**
* @param string $previewId ID given when the list created
*
* @return bool
*/
public function deleteBulkPreview(string $previewId)
{
Assert::stringNotEmpty($previewId);
$response = $this->httpDelete(sprintf('/v4/address/validate/preview/%s', $previewId));
return 204 === $response->getStatusCode();
}
/**
* @param string $previewId ID given when the list created
*
* @return mixed|ResponseInterface
*
* @throws Exception
*/
public function promoteBulkPreview(string $previewId)
{
Assert::stringNotEmpty($previewId);
$response = $this->httpPut(sprintf('/v4/address/validate/preview/%s', $previewId));
return $this->hydrateResponse($response, PromoteBulkPreviewResponse::class);
}
/**
* @param string $fieldName Field Name
* @param array $filePath ['fileContent' => 'content'] or ['filePath' => '/foo/bar']
*
* @return array File Data
*/
private function prepareFile(string $fieldName, array $filePath): array
{
$filename = isset($filePath['filename']) ? $filePath['filename'] : null;
$resource = null;
if (isset($filePath['fileContent'])) {
// File from memory
$resource = fopen('php://temp', 'r+');
fwrite($resource, $filePath['fileContent']);
rewind($resource);
} elseif (isset($filePath['filePath'])) {
// File form path
$path = $filePath['filePath'];
$resource = fopen($path, 'r');
}
return [
'name' => $fieldName,
'content' => $resource,
'filename' => $filename,
];
}
/**
* Close open resources.
*
* @param array $params Resource params
*/
private function closeResources(array $params): void
{
foreach ($params as $param) {
if (is_array($param) && array_key_exists('content', $param) && is_resource($param['content'])) {
fclose($param['content']);
}
}
}
}

View file

@ -11,13 +11,14 @@ declare(strict_types=1);
namespace Mailgun\Api;
use Mailgun\Exception\UnknownErrorException;
use Mailgun\Hydrator\Hydrator;
use Mailgun\Hydrator\NoopHydrator;
use Mailgun\Exception\HttpClientException;
use Mailgun\Exception\HttpServerException;
use Mailgun\Exception\UnknownErrorException;
use Mailgun\HttpClient\RequestBuilder;
use Mailgun\Hydrator\Hydrator;
use Mailgun\Hydrator\NoopHydrator;
use Psr\Http\Client as Psr18;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
@ -43,7 +44,12 @@ abstract class HttpApi
*/
protected $requestBuilder;
public function __construct(ClientInterface $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
/**
* @param ClientInterface $httpClient
* @param RequestBuilder $requestBuilder
* @param Hydrator $hydrator
*/
public function __construct($httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
{
$this->httpClient = $httpClient;
$this->requestBuilder = $requestBuilder;
@ -53,6 +59,8 @@ abstract class HttpApi
}
/**
* @param class-string $class
*
* @return mixed|ResponseInterface
*
* @throws \Exception
@ -63,7 +71,7 @@ abstract class HttpApi
return $response;
}
if (200 !== $response->getStatusCode() && 201 !== $response->getStatusCode()) {
if (!in_array($response->getStatusCode(), [200, 201, 202], true)) {
$this->handleErrors($response);
}
@ -86,11 +94,15 @@ abstract class HttpApi
case 402:
throw HttpClientException::requestFailed($response);
case 403:
throw HttpClientException::forbidden($response);
throw HttpClientException::forbidden($response);
case 404:
throw HttpClientException::notFound($response);
case 409:
throw HttpClientException::conflict($response);
case 413:
throw HttpClientException::payloadTooLarge($response);
case 429:
throw HttpClientException::tooManyRequests($response);
case 500 <= $statusCode:
throw HttpServerException::serverError($statusCode);
default:
@ -101,9 +113,10 @@ abstract class HttpApi
/**
* Send a GET request with query parameters.
*
* @param string $path Request path
* @param array $parameters GET parameters
* @param array $requestHeaders Request Headers
* @param string $path Request path
* @param array $parameters GET parameters
* @param array $requestHeaders Request Headers
* @throws ClientExceptionInterface
*/
protected function httpGet(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
@ -137,9 +150,10 @@ abstract class HttpApi
/**
* Send a POST request with raw data.
*
* @param string $path Request path
* @param array|string $body Request body
* @param array $requestHeaders Request headers
* @param string $path Request path
* @param array|string $body Request body
* @param array $requestHeaders Request headers
* @throws ClientExceptionInterface
*/
protected function httpPostRaw(string $path, $body, array $requestHeaders = []): ResponseInterface
{
@ -157,9 +171,10 @@ abstract class HttpApi
/**
* Send a PUT request.
*
* @param string $path Request path
* @param array $parameters PUT parameters
* @param array $requestHeaders Request headers
* @param string $path Request path
* @param array $parameters PUT parameters
* @param array $requestHeaders Request headers
* @throws ClientExceptionInterface
*/
protected function httpPut(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
@ -177,9 +192,10 @@ abstract class HttpApi
/**
* Send a DELETE request.
*
* @param string $path Request path
* @param array $parameters DELETE parameters
* @param array $requestHeaders Request headers
* @param string $path Request path
* @param array $parameters DELETE parameters
* @param array $requestHeaders Request headers
* @throws ClientExceptionInterface
*/
protected function httpDelete(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{

101
src/Api/HttpClient.php Normal file
View file

@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Api;
use Http\Client\Common\PluginClient;
use Mailgun\HttpClient\RequestBuilder;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
/**
* @see https://documentation.mailgun.com/api-domains.html
*
* @author Sean Johnson <sean@mailgun.com>
*/
class HttpClient extends HttpApi
{
/**
* @return PluginClient|ClientInterface
*/
public function getHttpClient()
{
return $this->httpClient;
}
/**
* @return RequestBuilder
*/
public function getRequestBuilder(): RequestBuilder
{
return $this->requestBuilder;
}
/**
* @param string $path
* @param array $parameters
* @param array $requestHeaders
* @return ResponseInterface
* @throws ClientExceptionInterface
*/
public function httpDelete(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
return parent::httpDelete($path, $parameters, $requestHeaders);
}
/**
* @param string $path
* @param array $parameters
* @param array $requestHeaders
* @return ResponseInterface
* @throws ClientExceptionInterface
*/
public function httpGet(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
return parent::httpGet($path, $parameters, $requestHeaders);
}
/**
* @param string $path
* @param array $parameters
* @param array $requestHeaders
* @return ResponseInterface
*/
public function httpPost(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
return parent::httpPost($path, $parameters, $requestHeaders);
}
/**
* @param string $path
* @param array $parameters
* @param array $requestHeaders
* @return ResponseInterface
* @throws ClientExceptionInterface
*/
public function httpPut(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
return parent::httpPut($path, $parameters, $requestHeaders);
}
/**
* @param string $path
* @param array|string $body
* @param array $requestHeaders
* @return ResponseInterface
* @throws ClientExceptionInterface
*/
public function httpPostRaw(string $path, $body, array $requestHeaders = []): ResponseInterface
{
return parent::httpPostRaw($path, $body, $requestHeaders);
}
}

View file

@ -27,16 +27,15 @@ class Ip extends HttpApi
/**
* Returns a list of IPs.
*
*
* @return IndexResponse|ResponseInterface
*/
public function index(bool $dedicated = false)
public function index(?bool $dedicated = null)
{
Assert::boolean($dedicated);
$params = [
'dedicated' => $dedicated,
];
$params = [];
if (null !== $dedicated) {
Assert::boolean($dedicated);
$params['dedicated'] = $dedicated;
}
$response = $this->httpGet('/v3/ips', $params);
@ -46,14 +45,13 @@ class Ip extends HttpApi
/**
* Returns a list of IPs assigned to a domain.
*
*
* @return IndexResponse|ResponseInterface
*/
public function domainIndex(string $domain)
{
Assert::stringNotEmpty($domain);
$response = $this->httpGet(sprintf('/v3/domains/%s/ip', $domain));
$response = $this->httpGet(sprintf('/v3/domains/%s/ips', $domain));
return $this->hydrateResponse($response, IndexResponse::class);
}
@ -61,7 +59,6 @@ class Ip extends HttpApi
/**
* Returns a single ip.
*
*
* @return ShowResponse|ResponseInterface
*/
public function show(string $ip)
@ -76,7 +73,6 @@ class Ip extends HttpApi
/**
* Assign a dedicated IP to the domain specified.
*
*
* @return UpdateResponse|ResponseInterface
*/
public function assign(string $domain, string $ip)
@ -85,7 +81,7 @@ class Ip extends HttpApi
Assert::ip($ip);
$params = [
'id' => $ip,
'ip' => $ip,
];
$response = $this->httpPost(sprintf('/v3/domains/%s/ips', $domain), $params);
@ -95,8 +91,6 @@ class Ip extends HttpApi
/**
* Unassign an IP from the domain specified.
*
*
* @return UpdateResponse|ResponseInterface
*/

84
src/Api/Mailboxes.php Normal file
View file

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Api;
use Mailgun\Assert;
use Mailgun\Model\Mailboxes\CreateResponse;
use Mailgun\Model\Mailboxes\DeleteResponse;
use Mailgun\Model\Mailboxes\ShowResponse;
use Mailgun\Model\Mailboxes\UpdateResponse;
class Mailboxes extends HttpApi
{
private const MIN_PASSWORD_LENGTH = 5;
/**
* @return CreateResponse
*
* @throws \Exception
*/
public function create(string $domain, array $parameters = [])
{
Assert::stringNotEmpty($domain);
Assert::keyExists($parameters, 'mailbox');
Assert::keyExists($parameters, 'password');
Assert::minLength($parameters['password'], self::MIN_PASSWORD_LENGTH);
$response = $this->httpPost(sprintf('/v3/%s/mailboxes', $domain), $parameters);
return $this->hydrateResponse($response, CreateResponse::class);
}
/**
* @return ShowResponse
*
* @throws \Exception
*/
public function show(string $domain, array $parameters = [])
{
Assert::stringNotEmpty($domain);
$response = $this->httpGet(sprintf('/v3/%s/mailboxes', $domain), $parameters);
return $this->hydrateResponse($response, ShowResponse::class);
}
/**
* @return UpdateResponse
*
* @throws \Exception
*/
public function update(string $domain, string $mailbox, array $parameters = [])
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($mailbox);
$response = $this->httpPut(sprintf('/v3/%s/mailboxes/%s', $domain, $mailbox), $parameters);
return $this->hydrateResponse($response, UpdateResponse::class);
}
/**
* @return DeleteResponse
*
* @throws \Exception
*/
public function delete(string $domain, string $mailbox)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($mailbox);
$response = $this->httpDelete(sprintf('/v3/%s/mailboxes/%s', $domain, $mailbox));
return $this->hydrateResponse($response, DeleteResponse::class);
}
}

View file

@ -13,11 +13,14 @@ namespace Mailgun\Api;
use Mailgun\Api\MailingList\Member;
use Mailgun\Assert;
use Mailgun\Model\EmailValidation\ValidateResponse;
use Mailgun\Model\MailingList\CreateResponse;
use Mailgun\Model\MailingList\DeleteResponse;
use Mailgun\Model\MailingList\PagesResponse;
use Mailgun\Model\MailingList\ShowResponse;
use Mailgun\Model\MailingList\UpdateResponse;
use Mailgun\Model\MailingList\ValidationCancelResponse;
use Mailgun\Model\MailingList\ValidationStatusResponse;
/**
* @see https://documentation.mailgun.com/en/latest/api-mailinglists.html
@ -54,28 +57,31 @@ class MailingList extends HttpApi
/**
* Creates a new mailing list on the current domain.
*
* @param string $address Address for the new mailing list
* @param string $name Name for the new mailing list (optional)
* @param string $description Description for the new mailing list (optional)
* @param string $accessLevel List access level, one of: readonly (default), members, everyone
* @param string $address Address for the new mailing list
* @param string|null $name Name for the new mailing list (optional)
* @param string|null $description Description for the new mailing list (optional)
* @param string $accessLevel List access level, one of: readonly (default), members, everyone
* @param string $replyPreference Set where replies should go: list (default) | sender (optional)
*
* @return CreateResponse
*
* @throws \Exception
*/
public function create(string $address, string $name = null, string $description = null, string $accessLevel = 'readonly')
public function create(string $address, ?string $name = null, ?string $description = null, string $accessLevel = 'readonly', string $replyPreference = 'list')
{
Assert::stringNotEmpty($address);
Assert::nullOrStringNotEmpty($name);
Assert::nullOrStringNotEmpty($description);
Assert::oneOf($accessLevel, ['readonly', 'members', 'everyone']);
Assert::oneOf($replyPreference, ['list', 'sender']);
$params = [
'address' => $address,
'name' => $name,
'description' => $description,
'access_level' => $accessLevel,
'reply_preference' => $replyPreference,
];
$description ? $params['description'] = $description : false;
$name ? $params['name'] = $name : false;
$response = $this->httpPost('/v3/lists', $params);
@ -152,4 +158,58 @@ class MailingList extends HttpApi
return $this->hydrateResponse($response, DeleteResponse::class);
}
/**
* Validates mailing list.
*
* @param string $address Address of the mailing list
*
* @return ValidateResponse
*
* @throws \Exception
*/
public function validate(string $address)
{
Assert::stringNotEmpty($address);
$response = $this->httpPost(sprintf('/v3/lists/%s/validate', $address));
return $this->hydrateResponse($response, ValidateResponse::class);
}
/**
* Get mailing list validation status.
*
* @param string $address Address of the mailing list
*
* @return ValidationStatusResponse
*
* @throws \Exception
*/
public function getValidationStatus(string $address)
{
Assert::stringNotEmpty($address);
$response = $this->httpGet(sprintf('/v3/lists/%s/validate', $address));
return $this->hydrateResponse($response, ValidationStatusResponse::class);
}
/**
* Cancel mailing list validation.
*
* @param string $address Address of the mailing list
*
* @return ValidationCancelResponse
*
* @throws \Exception
*/
public function cancelValidation(string $address)
{
Assert::stringNotEmpty($address);
$response = $this->httpDelete(sprintf('/v3/lists/%s/validate', $address));
return $this->hydrateResponse($response, ValidationCancelResponse::class);
}
}

View file

@ -99,12 +99,15 @@ class Member extends HttpApi
$params = [
'address' => $address,
'name' => $name,
'vars' => \json_encode($vars),
'subscribed' => $subscribed ? 'yes' : 'no',
'upsert' => $upsert ? 'yes' : 'no',
];
if (null !== $name) {
$params['name'] = $name;
}
$response = $this->httpPost(sprintf('/v3/lists/%s/members', $list), $params);
return $this->hydrateResponse($response, CreateResponse::class);
@ -128,11 +131,7 @@ class Member extends HttpApi
// workaround for webmozart/asserts <= 1.2
if (count($members) > 1000) {
throw new InvalidArgumentException(sprintf(
'Expected an Array to contain at most %2$d elements. Got: %d',
1000,
count($members)
));
throw new InvalidArgumentException(sprintf('Expected an Array to contain at most %2$d elements. Got: %d', 1000, count($members)));
}
foreach ($members as $data) {
@ -195,7 +194,7 @@ class Member extends HttpApi
Assert::stringNotEmpty($address);
Assert::isArray($parameters);
foreach ($parameters as $field => $value) {
foreach ($parameters as $field => &$value) {
switch ($field) {
case 'vars':
if (is_array($value)) {
@ -204,9 +203,12 @@ class Member extends HttpApi
// We should assert that "vars"'s $value is a string.
// no break
case 'address':
case 'name':
Assert::stringNotEmpty($value);
break;
case 'name':
Assert::nullOrStringNotEmpty($value);
break;
case 'subscribed':
Assert::oneOf($value, ['yes', 'no']);
@ -215,6 +217,10 @@ class Member extends HttpApi
}
}
if (array_key_exists('name', $parameters) && null === $parameters['name']) {
unset($parameters['name']);
}
$response = $this->httpPut(sprintf('/v3/lists/%s/members/%s', $list, $address), $parameters);
return $this->hydrateResponse($response, UpdateResponse::class);

View file

@ -16,6 +16,7 @@ use Mailgun\Exception\InvalidArgumentException;
use Mailgun\Message\BatchMessage;
use Mailgun\Model\Message\SendResponse;
use Mailgun\Model\Message\ShowResponse;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
@ -34,6 +35,7 @@ class Message extends HttpApi
* @see https://documentation.mailgun.com/en/latest/api-sending.html#sending
*
* @return SendResponse|ResponseInterface
* @throws \Exception|ClientExceptionInterface
*/
public function send(string $domain, array $params)
{
@ -74,7 +76,7 @@ class Message extends HttpApi
*
* @return SendResponse|ResponseInterface
*/
public function sendMime(string $domain, array $recipients, string $message, array $params)
public function sendMime(string $domain, array $recipients, string $message, array $params)
{
Assert::string($domain);
Assert::notEmpty($domain);
@ -174,6 +176,9 @@ class Message extends HttpApi
foreach ($params as $key => $value) {
// If $value is not an array we cast it to an array
foreach ((array) $value as $subValue) {
if (is_int($subValue)) {
$subValue = (string)$subValue;
}
$postDataMultipart[] = [
'name' => $key,
'content' => $subValue,

View file

@ -22,6 +22,9 @@ trait Pagination
{
abstract protected function httpGet(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface;
/**
* @param class-string $className
*/
abstract protected function hydrateResponse(ResponseInterface $response, string $className);
public function nextPage(PagingProvider $response): ?PagingProvider
@ -44,6 +47,9 @@ trait Pagination
return $this->getPaginationUrl($response->getLastUrl(), get_class($response));
}
/**
* @param class-string $class
*/
private function getPaginationUrl(string $url, string $class): ?PagingProvider
{
Assert::stringNotEmpty($class);

View file

@ -12,7 +12,6 @@ declare(strict_types=1);
namespace Mailgun\Api;
use Mailgun\Assert;
use Mailgun\Model\Stats\AllResponse;
use Mailgun\Model\Stats\TotalResponse;
/**
@ -33,16 +32,4 @@ class Stats extends HttpApi
return $this->hydrateResponse($response, TotalResponse::class);
}
/**
* @return AllResponse|array
*/
public function all(string $domain, array $params = [])
{
Assert::stringNotEmpty($domain);
$response = $this->httpGet(sprintf('/v3/%s/stats', rawurlencode($domain)), $params);
return $this->hydrateResponse($response, AllResponse::class);
}
}

View file

@ -14,9 +14,10 @@ namespace Mailgun\Api;
use Mailgun\Api\Suppression\Bounce;
use Mailgun\Api\Suppression\Complaint;
use Mailgun\Api\Suppression\Unsubscribe;
use Mailgun\Api\Suppression\Whitelist;
use Mailgun\HttpClient\RequestBuilder;
use Mailgun\Hydrator\Hydrator;
use Psr\Http\Client\ClientInterface;
use Mailgun\HttpClient\RequestBuilder;
/**
* @see https://documentation.mailgun.com/api-suppressions.html
@ -40,7 +41,12 @@ class Suppression
*/
private $hydrator;
public function __construct(ClientInterface $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
/**
* @param ClientInterface $httpClient
* @param RequestBuilder $requestBuilder
* @param Hydrator $hydrator
*/
public function __construct($httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
{
$this->httpClient = $httpClient;
$this->requestBuilder = $requestBuilder;
@ -61,4 +67,9 @@ class Suppression
{
return new Unsubscribe($this->httpClient, $this->requestBuilder, $this->hydrator);
}
public function whitelists(): Whitelist
{
return new Whitelist($this->httpClient, $this->requestBuilder, $this->hydrator);
}
}

View file

@ -0,0 +1,148 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Api\Suppression;
use InvalidArgumentException;
use Mailgun\Api\HttpApi;
use Mailgun\Api\Pagination;
use Mailgun\Assert;
use Mailgun\Model\Suppression\Whitelist\CreateResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteAllResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteResponse;
use Mailgun\Model\Suppression\Whitelist\ImportResponse;
use Mailgun\Model\Suppression\Whitelist\IndexResponse;
use Mailgun\Model\Suppression\Whitelist\ShowResponse;
/**
* @see https://documentation.mailgun.com/en/latest/api-suppressions.html#whitelists
*
* @author Artem Bondarenko <artem@uartema.com>
*/
class Whitelist extends HttpApi
{
use Pagination;
/**
* @param string $domain Domain to get whitelist for
* @param int $limit optional
*
* @return IndexResponse
*/
public function index(string $domain, int $limit = 100)
{
Assert::stringNotEmpty($domain);
Assert::range($limit, 1, 10000, 'Limit parameter must be between 1 and 10000');
$params = [
'limit' => $limit,
];
$response = $this->httpGet(sprintf('/v3/%s/whitelists', $domain), $params);
return $this->hydrateResponse($response, IndexResponse::class);
}
/**
* @param string $domain Domain to show whitelist for
* @param string $address whitelist address
*
* @return ShowResponse
*/
public function show(string $domain, string $address)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
$response = $this->httpGet(sprintf('/v3/%s/whitelists/%s', $domain, $address));
return $this->hydrateResponse($response, ShowResponse::class);
}
/**
* @param string $domain Domain to create whitelist for
* @param string $address whitelist email address or domain name
*
* @return CreateResponse
*/
public function create(string $domain, string $address)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
$params = [];
if (false !== filter_var($address, FILTER_VALIDATE_EMAIL)) {
$params['address'] = $address;
} elseif (false !== filter_var($address, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
$params['domain'] = $address;
} else {
throw new InvalidArgumentException('Address should be valid email or domain name');
}
$response = $this->httpPost(sprintf('/v3/%s/whitelists', $domain), $params);
return $this->hydrateResponse($response, CreateResponse::class);
}
/**
* @param string $domain Domain to create whitelist for
* @param string $filePath csv file path
*
* @return ImportResponse
*/
public function import(string $domain, string $filePath)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($filePath);
Assert::fileExists($filePath);
$response = $this->httpPost(
sprintf('/v3/%s/whitelists/import', $domain),
['file' => fopen($filePath, 'r')],
[
'filename' => basename($filePath),
]
);
return $this->hydrateResponse($response, ImportResponse::class);
}
/**
* @param string $domain Domain to delete whitelist for
* @param string $address whitelist address
*
* @return DeleteResponse
*/
public function delete(string $domain, string $address)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
$response = $this->httpDelete(sprintf('/v3/%s/whitelists/%s', $domain, $address));
return $this->hydrateResponse($response, DeleteResponse::class);
}
/**
* @param string $domain Domain to delete all whitelists for
*
* @return DeleteAllResponse
*/
public function deleteAll(string $domain)
{
Assert::stringNotEmpty($domain);
$response = $this->httpDelete(sprintf('/v3/%s/whitelists', $domain));
return $this->hydrateResponse($response, DeleteAllResponse::class);
}
}

View file

@ -29,6 +29,8 @@ use Psr\Http\Message\ResponseInterface;
*/
class Tag extends HttpApi
{
use Pagination;
/**
* Returns a list of tags.
@ -67,7 +69,6 @@ class Tag extends HttpApi
/**
* Update a tag.
*
*
* @return UpdateResponse|ResponseInterface
*/
public function update(string $domain, string $tag, string $description)
@ -87,7 +88,6 @@ class Tag extends HttpApi
/**
* Returns statistics for a single tag.
*
*
* @return StatisticsResponse|ResponseInterface
*/
public function stats(string $domain, string $tag, array $params)
@ -103,7 +103,6 @@ class Tag extends HttpApi
/**
* Removes a tag from the account.
*
*
* @return DeleteResponse|ResponseInterface
*/
public function delete(string $domain, string $tag)

View file

@ -12,15 +12,15 @@ declare(strict_types=1);
namespace Mailgun\Api;
use Mailgun\Assert;
use Mailgun\HttpClient\RequestBuilder;
use Mailgun\Hydrator\Hydrator;
use Mailgun\Model\Webhook\CreateResponse;
use Mailgun\Model\Webhook\DeleteResponse;
use Mailgun\Model\Webhook\IndexResponse;
use Mailgun\Model\Webhook\ShowResponse;
use Mailgun\Model\Webhook\UpdateResponse;
use Mailgun\HttpClient\RequestBuilder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
/**
* @see https://documentation.mailgun.com/en/latest/api-webhooks.html
@ -34,7 +34,13 @@ class Webhook extends HttpApi
*/
private $apiKey;
public function __construct(ClientInterface $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator, string $apiKey)
/**
* @param ClientInterface $httpClient
* @param RequestBuilder $requestBuilder
* @param Hydrator $hydrator
* @param string $apiKey
*/
public function __construct($httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator, string $apiKey)
{
parent::__construct($httpClient, $requestBuilder, $hydrator);
$this->apiKey = $apiKey;
@ -88,7 +94,7 @@ class Webhook extends HttpApi
/**
* @return CreateResponse|ResponseInterface
*/
public function create(string $domain, string $id, string $url)
public function create(string $domain, string $id, array $url)
{
Assert::notEmpty($domain);
Assert::notEmpty($id);
@ -107,7 +113,7 @@ class Webhook extends HttpApi
/**
* @return UpdateResponse|ResponseInterface
*/
public function update(string $domain, string $id, string $url)
public function update(string $domain, string $id, array $url)
{
Assert::notEmpty($domain);
Assert::notEmpty($id);

View file

@ -78,11 +78,21 @@ final class HttpClientException extends \RuntimeException implements Exception
return new self('The endpoint you have tried to access does not exist. Check if the domain matches the domain you have configure on Mailgun.', 404, $response);
}
public static function conflict(ResponseInterface $response)
{
return new self('Request conflicts with current state of the target resource.', 409, $response);
}
public static function payloadTooLarge(ResponseInterface $response)
{
return new self('Payload too large, your total attachment size is too big.', 413, $response);
}
public static function tooManyRequests(ResponseInterface $response)
{
return new self('Too many requests.', 429, $response);
}
public static function forbidden(ResponseInterface $response)
{
$body = $response->getBody()->__toString();

View file

@ -60,8 +60,8 @@ class RequestBuilder
$builder = $this->getMultipartStreamBuilder();
foreach ($body as $item) {
$name = $item['name'];
$content = $item['content'];
$name = $this->getItemValue($item, 'name');
$content = $this->getItemValue($item, 'content');
unset($item['name']);
unset($item['content']);
@ -77,6 +77,9 @@ class RequestBuilder
return $this->createRequest($method, $uri, $headers, $multipartStream);
}
/**
* @return RequestFactoryInterface
*/
private function getRequestFactory(): RequestFactoryInterface
{
if (null === $this->requestFactory) {
@ -86,6 +89,10 @@ class RequestBuilder
return $this->requestFactory;
}
/**
* @param RequestFactoryInterface $requestFactory
* @return $this
*/
public function setRequestFactory(RequestFactoryInterface $requestFactory): self
{
$this->requestFactory = $requestFactory;
@ -93,6 +100,9 @@ class RequestBuilder
return $this;
}
/**
* @return StreamFactoryInterface
*/
private function getStreamFactory(): StreamFactoryInterface
{
if (null === $this->streamFactory) {
@ -102,6 +112,10 @@ class RequestBuilder
return $this->streamFactory;
}
/**
* @param StreamFactoryInterface $streamFactory
* @return $this
*/
public function setStreamFactory(StreamFactoryInterface $streamFactory): self
{
$this->streamFactory = $streamFactory;
@ -109,6 +123,9 @@ class RequestBuilder
return $this;
}
/**
* @return MultipartStreamBuilder
*/
private function getMultipartStreamBuilder(): MultipartStreamBuilder
{
if (null === $this->multipartStreamBuilder) {
@ -118,6 +135,10 @@ class RequestBuilder
return $this->multipartStreamBuilder;
}
/**
* @param MultipartStreamBuilder $multipartStreamBuilder
* @return $this
*/
public function setMultipartStreamBuilder(MultipartStreamBuilder $multipartStreamBuilder): self
{
$this->multipartStreamBuilder = $multipartStreamBuilder;
@ -125,7 +146,14 @@ class RequestBuilder
return $this;
}
private function createRequest(string $method, string $uri, array $headers, StreamInterface $stream)
/**
* @param string $method
* @param string $uri
* @param array $headers
* @param StreamInterface $stream
* @return RequestInterface
*/
private function createRequest(string $method, string $uri, array $headers, StreamInterface $stream): RequestInterface
{
$request = $this->getRequestFactory()->createRequest($method, $uri);
$request = $request->withBody($stream);
@ -135,4 +163,18 @@ class RequestBuilder
return $request;
}
/**
* @param array $item
* @param string $key
* @return mixed|string
*/
private function getItemValue(array $item, string $key)
{
if (is_bool($item[$key])) {
return (string) $item[$key];
}
return $item[$key];
}
}

View file

@ -22,6 +22,8 @@ use Psr\Http\Message\ResponseInterface;
final class ArrayHydrator implements Hydrator
{
/**
* @param class-string $class
*
* @return array
*/
public function hydrate(ResponseInterface $response, string $class)

View file

@ -20,6 +20,8 @@ use Psr\Http\Message\ResponseInterface;
interface Hydrator
{
/**
* @param class-string $class
*
* @throws HydrationException
*/
public function hydrate(ResponseInterface $response, string $class);

View file

@ -23,6 +23,8 @@ use Psr\Http\Message\ResponseInterface;
final class ModelHydrator implements Hydrator
{
/**
* @param class-string $class
*
* @return ResponseInterface
*/
public function hydrate(ResponseInterface $response, string $class)
@ -41,7 +43,7 @@ final class ModelHydrator implements Hydrator
}
if (is_subclass_of($class, ApiResponse::class)) {
$object = call_user_func($class.'::create', $data);
$object = call_user_func([$class, 'create'], $data);
} else {
$object = new $class($data);
}

View file

@ -21,6 +21,8 @@ use Psr\Http\Message\ResponseInterface;
final class NoopHydrator implements Hydrator
{
/**
* @param class-string $class
*
* @throws \LogicException
*/
public function hydrate(ResponseInterface $response, string $class)

View file

@ -12,13 +12,28 @@ declare(strict_types=1);
namespace Mailgun;
use Http\Client\Common\PluginClient;
use Mailgun\Api\Attachment;
use Mailgun\Api\Domain;
use Mailgun\Api\EmailValidation;
use Mailgun\Api\EmailValidationV4;
use Mailgun\Api\Event;
use Mailgun\Api\HttpClient;
use Mailgun\Api\Ip;
use Mailgun\Api\Mailboxes;
use Mailgun\Api\MailingList;
use Mailgun\Api\Message;
use Mailgun\Api\Route;
use Mailgun\Api\Stats;
use Mailgun\Api\Suppression;
use Mailgun\Api\Tag;
use Mailgun\Api\Webhook;
use Mailgun\HttpClient\HttpClientConfigurator;
use Mailgun\HttpClient\Plugin\History;
use Mailgun\HttpClient\RequestBuilder;
use Mailgun\Hydrator\ModelHydrator;
use Mailgun\Hydrator\Hydrator;
use Psr\Http\Message\ResponseInterface;
use Mailgun\Hydrator\ModelHydrator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
/**
* This class is the base class for the Mailgun SDK.
@ -52,6 +67,11 @@ class Mailgun
*/
private $responseHistory;
/**
* @param HttpClientConfigurator $configurator
* @param Hydrator|null $hydrator
* @param RequestBuilder|null $requestBuilder
*/
public function __construct(
HttpClientConfigurator $configurator,
Hydrator $hydrator = null,
@ -65,6 +85,11 @@ class Mailgun
$this->responseHistory = $configurator->getResponseHistory();
}
/**
* @param string $apiKey
* @param string $endpoint
* @return self
*/
public static function create(string $apiKey, string $endpoint = 'https://api.mailgun.net'): self
{
$httpClientConfigurator = (new HttpClientConfigurator())
@ -74,68 +99,131 @@ class Mailgun
return new self($httpClientConfigurator);
}
/**
* @return ResponseInterface|null
*/
public function getLastResponse(): ?ResponseInterface
{
return $this->responseHistory->getLastResponse();
}
/**
* @return Attachment
*/
public function attachment(): Api\Attachment
{
return new Api\Attachment($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Domain
*/
public function domains(): Api\Domain
{
return new Api\Domain($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return EmailValidation
*/
public function emailValidation(): Api\EmailValidation
{
return new Api\EmailValidation($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return EmailValidationV4
*/
public function emailValidationV4(): Api\EmailValidationV4
{
return new Api\EmailValidationV4($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Event
*/
public function events(): Api\Event
{
return new Api\Event($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Ip
*/
public function ips(): Api\Ip
{
return new Api\Ip($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return MailingList
*/
public function mailingList(): Api\MailingList
{
return new Api\MailingList($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Message
*/
public function messages(): Api\Message
{
return new Api\Message($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Route
*/
public function routes(): Api\Route
{
return new Api\Route($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Suppression
*/
public function suppressions(): Api\Suppression
{
return new Api\Suppression($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Stats
*/
public function stats(): Api\Stats
{
return new Api\Stats($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Tag
*/
public function tags(): Api\Tag
{
return new Api\Tag($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return Webhook
*/
public function webhooks(): Api\Webhook
{
return new Api\Webhook($this->httpClient, $this->requestBuilder, $this->hydrator, $this->apiKey);
}
/**
* @return Mailboxes
*/
public function mailboxes(): Api\Mailboxes
{
return new Api\Mailboxes($this->httpClient, $this->requestBuilder, $this->hydrator);
}
/**
* @return HttpClient
*/
public function httpClient(): Api\HttpClient
{
return new Api\HttpClient($this->httpClient, $this->requestBuilder, $this->hydrator);
}
}

View file

@ -114,11 +114,11 @@ class BatchMessage extends MessageBuilder
throw MissingRequiredParameter::create('subject');
}
if (empty($message['text']) && empty($message['html'])) {
throw MissingRequiredParameter::create('text" or "html');
if (empty($message['text']) && empty($message['html']) && empty($message['template'])) {
throw MissingRequiredParameter::create('text", "html" or "template');
}
$message['recipient-variables'] = json_encode($this->batchRecipientAttributes);
$message['recipient-variables'] = json_encode($this->batchRecipientAttributes, JSON_FORCE_OBJECT);
$response = $this->api->send($this->domain, $message);
$this->batchRecipientAttributes = [];

View file

@ -24,11 +24,11 @@ use Mailgun\Message\Exceptions\TooManyRecipients;
*/
class MessageBuilder
{
const RECIPIENT_COUNT_LIMIT = 1000;
public const RECIPIENT_COUNT_LIMIT = 1000;
const CAMPAIGN_ID_LIMIT = 3;
public const CAMPAIGN_ID_LIMIT = 3;
const TAG_LIMIT = 3;
public const TAG_LIMIT = 3;
/**
* @var array
@ -84,9 +84,11 @@ class MessageBuilder
}
/**
* @param array $variables {
*
* @var string
* @var string
* @var string
* @var string $first
* @var string $last
* }
*/
protected function parseAddress(string $address, array $variables): string
@ -229,6 +231,16 @@ class MessageBuilder
return $this;
}
/**
* @param string $template Name of the Mailgun template
*/
public function setTemplate(string $template): self
{
$this->message['template'] = $template;
return $this;
}
public function addCustomHeader(string $headerName, $headerData): self
{
if (!preg_match('/^h:/i', $headerName)) {
@ -276,6 +288,20 @@ class MessageBuilder
return $this;
}
public function addStringAttachment(string $attachmentContent, string $attachmentName = null): self
{
if (!isset($this->message['attachment'])) {
$this->message['attachment'] = [];
}
$this->message['attachment'][] = [
'fileContent' => $attachmentContent,
'filename' => $attachmentName,
];
return $this;
}
public function addInlineImage(string $inlineImagePath, string $inlineImageName = null): self
{
if (!isset($this->message['inline'])) {

View file

@ -1,24 +1,31 @@
Mailgun - Messages
==================
This is the Mailgun PHP *Message* utilities.
This is the Mailgun PHP *Message* utilities.
The below assumes you've already installed the Mailgun PHP SDK in to your
The below assumes you've already installed the Mailgun PHP SDK in to your
project. If not, go back to the master README for instructions.
There are two utilities included, `MessageBuilder` and `BatchMessage`.
There are two utilities included, `MessageBuilder` and `BatchMessage`.
* `MessageBuilder`: Allows you to build a message object by calling methods for
each MIME attribute.
* `BatchMessage`: Extends `MessageBuilder` and allows you to iterate through
recipients from a list. Messages will fire after the 1,000th recipient has been
added.
* `MessageBuilder`: Allows you to build a message object by calling methods for
each MIME attribute.
* `BatchMessage`: Extends `MessageBuilder` and allows you to iterate through
recipients from a list. Messages will fire after the 1,000th recipient has been
added.
Usage - Message Builder
-----------------------
Here's how to use Message Builder to build your Message.
Here's how to use Message Builder to build your Message.
```php
require 'vendor/autoload.php';
use Mailgun\Mailgun;
use Mailgun\Message\MessageBuilder;
// First, instantiate the SDK with your API credentials
$mg = Mailgun::create('key-example');
# Next, instantiate a Message Builder object from the SDK.
$builder = new MessageBuilder();
@ -28,10 +35,12 @@ $builder->setFromAddress("me@example.com", array("first"=>"PHP", "last" => "SDK"
$builder->addToRecipient("john.doe@example.com", array("first" => "John", "last" => "Doe"));
# Define a cc recipient.
$builder->addCcRecipient("sally.doe@example.com", array("full_name" => "Sally Doe"));
# Define the subject.
# Define the subject.
$builder->setSubject("A message from the PHP SDK using Message Builder!");
# Define the body of the message.
# Define the body of the message (One is required).
$builder->setTextBody("This is the text body of the message!");
$builder->setHtmlBody("<html><p>This is the HTML body of the message</p></html>");
$builder->setTemplate("template_name");
# Other Optional Parameters.
$builder->addCampaignId("My-Awesome-Campaign");
@ -41,35 +50,38 @@ $builder->setDeliveryTime("tomorrow 8:00AM", "PST");
$builder->setClickTracking(true);
# Finally, send the message.
$mg = Mailgun::create('key-example');
$domain = ;
$mg->messages()->send("example.com", $builder->getMessage());
```
Usage - Batch Message
---------------------
Here's how to use Batch Message to easily handle batch sending jobs.
Here's how to use Batch Message to easily handle batch sending jobs.
```php
# First, instantiate the SDK with your API credentials and define your domain.
$mg = new Mailgun("key-example");
require 'vendor/autoload.php';
use Mailgun\Mailgun;
// First, instantiate the SDK with your API credentials
$mg = Mailgun::create('key-example');
# Next, instantiate a Message Builder object from the SDK, pass in your sending domain.
$batchMessage = $mg->messages()->getBatchMessage("example.com");
# Define the from address.
$batchMessage->setFromAddress("me@example.com", array("first"=>"PHP", "last" => "SDK"));
# Define the subject.
# Define the subject.
$batchMessage->setSubject("A Batch Message from the PHP SDK!");
# Define the body of the message.
# Define the body of the message (One is required).
$batchMessage->setTextBody("This is the text body of the message!");
$batchMessage->setHtmlBody("<html><p>This is the HTML body of the message</p></html>");
$batchMessage->setTemplate("template_name");
# Next, let's add a few recipients to the batch job.
$batchMessage->addToRecipient("john.doe@example.com", array("first" => "John", "last" => "Doe"));
$batchMessage->addToRecipient("sally.doe@example.com", array("first" => "Sally", "last" => "Doe"));
$batchMessage->addToRecipient("mike.jones@example.com", array("first" => "Mike", "last" => "Jones"));
...
// After 1,000 recipients, Batch Message will automatically post your message to the messages endpoint.
// After 1,000 recipients, Batch Message will automatically post your message to the messages endpoint.
// Call finalize() to send any remaining recipients still in the buffer.
$batchMessage->finalize();
@ -80,5 +92,5 @@ $messageIds = $batchMessage->getMessageIds();
More Documentation
------------------
See the official [Mailgun Docs](http://documentation.mailgun.com/api-sending.html)
See the official [Mailgun Docs](https://documentation.mailgun.com/en/latest/api-sending.html)
for more information.

View file

@ -54,7 +54,7 @@ abstract class AbstractDomainResponse implements ApiResponse
return $model;
}
private function __construct()
final private function __construct()
{
}

View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
/**
* Represents a single Click Tracking setting for a domain tracking.
*
* @author Artem Bondarenko <artem@uartema.com>
*/
final class ClickTracking
{
private $active;
public static function create(array $data): self
{
$active = $data['active'] ?? null;
$model = new self();
$model->active = 'htmlonly' === $active ? $active : ($active ? 'yes' : 'no');
return $model;
}
private function __construct()
{
}
public function getActive(): ?string
{
return $this->active;
}
public function isActive(): bool
{
return 'yes' === $this->getActive();
}
public function isHtmlOnly(): bool
{
return 'htmlonly' === $this->getActive();
}
}

View file

@ -25,6 +25,7 @@ final class Domain
private $wildcard;
private $spamAction;
private $state;
private $webScheme;
public static function create(array $data): self
{
@ -36,6 +37,7 @@ final class Domain
$model->spamAction = $data['spam_action'] ?? null;
$model->state = $data['state'] ?? null;
$model->createdAt = isset($data['created_at']) ? new \DateTimeImmutable($data['created_at']) : null;
$model->webScheme = $data['web_scheme'] ?? null;
return $model;
}

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
/**
* Represents a single Open Tracking setting for a domain tracking.
*
* @author Artem Bondarenko <artem@uartema.com>
*/
final class OpenTracking
{
private $active;
public static function create(array $data): self
{
$active = $data['active'] ?? null;
$model = new self();
$model->active = $active ? 'yes' : 'no';
return $model;
}
private function __construct()
{
}
/**
* @return string
*/
public function getActive(): ?string
{
return $this->active;
}
public function isActive(): bool
{
return 'yes' === $this->getActive();
}
}

View file

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
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['open'] ?? []);
$model->unsubscribe = UnsubscribeTracking::create($trackingSettings['unsubscribe'] ?? []);
return $model;
}
private function __construct()
{
}
public function getClick(): ClickTracking
{
return $this->click;
}
public function getOpen(): OpenTracking
{
return $this->open;
}
public function getUnsubscribe(): UnsubscribeTracking
{
return $this->unsubscribe;
}
}

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
/**
* Represents a single Unsubscribe Tracking setting for a domain tracking.
*
* @author Artem Bondarenko <artem@uartema.com>
*/
final class UnsubscribeTracking
{
private $active;
private $htmlFooter;
private $textFooter;
public static function create(array $data): self
{
$model = new self();
$model->active = ($data['active'] ?? null) ? 'yes' : 'no';
$model->htmlFooter = $data['html_footer'] ?? '';
$model->textFooter = $data['text_footer'] ?? '';
return $model;
}
private function __construct()
{
}
public function isActive(): bool
{
return 'yes' === $this->getActive();
}
public function getActive(): string
{
return $this->active;
}
public function getHtmlFooter(): string
{
return $this->htmlFooter;
}
public function getTextFooter(): string
{
return $this->textFooter;
}
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
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()
{
}
public function getMessage(): ?string
{
return $this->message;
}
public function getClick(): ClickTracking
{
return $this->click;
}
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
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()
{
}
public function getMessage(): ?string
{
return $this->message;
}
public function getOpen(): OpenTracking
{
return $this->open;
}
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
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()
{
}
public function getMessage(): ?string
{
return $this->message;
}
public function getUnsubscribe(): UnsubscribeTracking
{
return $this->unsubscribe;
}
}

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Domain;
final class WebSchemeResponse extends AbstractDomainResponse
{
}

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class CreateBulkJobResponse implements ApiResponse
{
/**
* @var string|null
*/
private $id;
/**
* @var string|null
*/
private $message;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->id = $data['id'] ?? null;
$model->message = $data['message'] ?? null;
return $model;
}
public function getId(): ?string
{
return $this->id;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class CreateBulkPreviewResponse implements ApiResponse
{
/**
* @var string|null
*/
private $id;
/**
* @var string|null
*/
private $message;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->id = $data['id'] ?? null;
$model->message = $data['message'] ?? null;
return $model;
}
public function getId(): ?string
{
return $this->id;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class DeleteBulkJobResponse implements ApiResponse
{
/**
* @var string|null
*/
private $message;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
return $model;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
final class GetBulkJobResponse extends Job
{
}

View file

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
final class GetBulkJobsResponse implements ApiResponse
{
use PaginationResponse;
/**
* @var int
*/
private $total = 0;
/**
* @var array
*/
private $jobs = [];
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$jobs = [];
if (isset($data['jobs'])) {
foreach ($data['jobs'] as $job) {
$jobs[] = Job::create($job);
}
}
$model->jobs = $jobs;
$model->total = $data['total'] ?? 0;
$model->paging = $data['paging'];
return $model;
}
public function getTotal(): int
{
return $this->total;
}
public function getJobs(): array
{
return $this->jobs;
}
}

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class GetBulkPreviewResponse implements ApiResponse
{
/**
* @var Preview
*/
private $preview;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->preview = Preview::create($data['preview']);
return $model;
}
public function getPreview(): Preview
{
return $this->preview;
}
}

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class GetBulkPreviewsResponse implements ApiResponse
{
/**
* @var array
*/
private $previews = [];
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$previews = [];
if (isset($data['previews'])) {
foreach ($data['previews'] as $job) {
$previews[] = Preview::create($job);
}
}
$model->previews = $previews;
return $model;
}
public function getPreviews(): array
{
return $this->previews;
}
}

View file

@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use DateTimeImmutable;
use Mailgun\Model\ApiResponse;
class Job implements ApiResponse
{
/**
* @var DateTimeImmutable|null
*/
private $createdAt;
/**
* @var JobDownloadUrl|null
*/
private $downloadUrl;
/**
* @var string|null
*/
private $id;
/**
* @var int
*/
private $quantity = 0;
/**
* @var int
*/
private $recordsProcessed = 0;
/**
* @var string|null
*/
private $status;
/**
* @var Summary|null
*/
private $summary;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->createdAt = isset($data['created_at']) ? (DateTimeImmutable::createFromFormat('U', (string) $data['created_at']) ?: null) : null;
$model->downloadUrl = $data['download_url'] ? JobDownloadUrl::create($data['download_url']) : null;
$model->id = $data['id'] ?? null;
$model->quantity = $data['quantity'] ?? null;
$model->recordsProcessed = $data['records_processed'] ?? null;
$model->status = $data['status'] ?? null;
$model->summary = $data['summary'] ? Summary::create($data['summary']) : null;
return $model;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
public function getDownloadUrl(): ?JobDownloadUrl
{
return $this->downloadUrl;
}
public function getId(): ?string
{
return $this->id;
}
public function getQuantity(): int
{
return $this->quantity;
}
public function getRecordsProcessed(): int
{
return $this->recordsProcessed;
}
public function getStatus(): ?string
{
return $this->status;
}
public function getSummary(): ?Summary
{
return $this->summary;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class JobDownloadUrl implements ApiResponse
{
private $csv;
private $json;
public static function create(array $data): self
{
$model = new self();
$model->csv = $data['csv'] ?? null;
$model->json = $data['json'] ?? null;
return $model;
}
private function __construct()
{
}
public function getCsv(): ?string
{
return $this->csv;
}
public function getJson(): ?string
{
return $this->json;
}
}

View file

@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use DateTimeImmutable;
use Mailgun\Model\ApiResponse;
class Preview implements ApiResponse
{
/**
* @var string|null
*/
private $id;
/**
* @var bool
*/
private $valid;
/**
* @var string|null
*/
private $status;
/**
* @var int
*/
private $quantity = 0;
/**
* @var DateTimeImmutable|null
*/
private $createdAt;
/**
* @var Summary|null
*/
private $summary;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->id = $data['id'] ?? null;
$model->valid = $data['valid'] ?? null;
$model->status = $data['status'] ?? null;
$model->quantity = $data['quantity'] ?? null;
$model->createdAt = isset($data['created_at']) ? (DateTimeImmutable::createFromFormat('U', (string) $data['created_at']) ?: null) : null;
$model->summary = $data['summary'] ? Summary::create($data['summary']) : null;
return $model;
}
public function getId(): ?string
{
return $this->id;
}
public function isValid(): ?bool
{
return $this->valid;
}
public function getQuantity(): int
{
return $this->quantity;
}
public function getStatus(): ?string
{
return $this->status;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
public function getSummary(): ?Summary
{
return $this->summary;
}
}

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class PromoteBulkPreviewResponse implements ApiResponse
{
/**
* @var string|null
*/
private $message;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
return $model;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class Summary implements ApiResponse
{
/**
* @var SummaryResult
*/
private $result;
/**
* @var SummaryRisk
*/
private $risk;
public static function create(array $data): self
{
$model = new self();
$model->result = SummaryResult::create($data['result']);
$model->risk = SummaryRisk::create($data['risk']);
return $model;
}
private function __construct()
{
}
public function getResult(): SummaryResult
{
return $this->result;
}
public function getRisk(): SummaryRisk
{
return $this->risk;
}
}

View file

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class SummaryResult implements ApiResponse
{
/**
* @var int
*/
private $deliverable = 0;
/**
* @var int
*/
private $doNotSend = 0;
/**
* @var int
*/
private $undeliverable = 0;
/**
* @var int
*/
private $catchAll = 0;
/**
* @var int
*/
private $unknown = 0;
public static function create(array $data): self
{
$model = new self();
$model->deliverable = $data['deliverable'] ?? 0;
$model->doNotSend = $data['do_not_send'] ?? 0;
$model->undeliverable = $data['undeliverable'] ?? 0;
$model->catchAll = $data['catch_all'] ?? 0;
$model->unknown = $data['unknown'] ?? 0;
return $model;
}
private function __construct()
{
}
public function getDeliverable(): int
{
return $this->deliverable;
}
public function getDoNotSend(): int
{
return $this->doNotSend;
}
public function getUndeliverable(): int
{
return $this->undeliverable;
}
public function getCatchAll(): int
{
return $this->catchAll;
}
public function getUnknown(): int
{
return $this->unknown;
}
}

View file

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class SummaryRisk implements ApiResponse
{
/**
* @var int
*/
private $high = 0;
/**
* @var int
*/
private $low = 0;
/**
* @var int
*/
private $medium = 0;
/**
* @var int
*/
private $unknown = 0;
public static function create(array $data): self
{
$model = new self();
$model->high = $data['high'] ?? 0;
$model->low = $data['low'] ?? 0;
$model->medium = $data['medium'] ?? 0;
$model->unknown = $data['unknown'] ?? 0;
return $model;
}
private function __construct()
{
}
public function getHigh(): int
{
return $this->high;
}
public function getLow(): int
{
return $this->low;
}
public function getMedium(): int
{
return $this->medium;
}
public function getUnknown(): int
{
return $this->unknown;
}
}

View file

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\EmailValidationV4;
use Mailgun\Model\ApiResponse;
final class ValidateResponse implements ApiResponse
{
/**
* @var string|null
*/
private $address;
/**
* @var string|null
*/
private $didYouMean;
/**
* @var bool
*/
private $isDisposableAddress = false;
/**
* @var bool
*/
private $isRoleAddress = false;
/**
* @var array
*/
private $reason = [];
/**
* @var string|null
*/
private $result;
/**
* @var string|null
*/
private $risk;
/**
* @var string|null
*/
private $rootAddress;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->address = $data['address'] ?? null;
$model->didYouMean = $data['did_you_mean'] ?? null;
$model->isDisposableAddress = $data['is_disposable_address'] ?? false;
$model->isRoleAddress = $data['is_role_address'] ?? false;
$model->reason = $data['reason'] ?? [];
$model->result = $data['result'] ?? null;
$model->risk = $data['risk'] ?? null;
$model->rootAddress = $data['root_address'] ?? null;
return $model;
}
public function getAddress(): ?string
{
return $this->address;
}
public function getDidYouMean(): ?string
{
return $this->didYouMean;
}
public function isDisposableAddress(): bool
{
return $this->isDisposableAddress;
}
public function isRoleAddress(): bool
{
return $this->isRoleAddress;
}
public function getReason(): array
{
return $this->reason;
}
public function getResult(): ?string
{
return $this->result;
}
public function getRisk(): ?string
{
return $this->risk;
}
public function getRootAddress(): ?string
{
return $this->rootAddress;
}
}

View file

@ -37,6 +37,7 @@ final class Event
private $geolocation;
private $storage;
private $method;
private $logLevel;
private function __construct()
{
@ -66,6 +67,7 @@ final class Event
$model->clientInfo = $data['client-info'] ?? [];
$model->url = $data['url'] ?? '';
$model->storage = $data['storage'] ?? [];
$model->logLevel = $data['log-level'] ?? '';
return $model;
}
@ -192,4 +194,9 @@ final class Event
{
return $this->method;
}
public function getLogLevel(): string
{
return $this->logLevel;
}
}

View file

@ -11,9 +11,9 @@ declare(strict_types=1);
namespace Mailgun\Model\Event;
use Mailgun\Model\PagingProvider;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\PagingProvider;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>

View file

@ -28,6 +28,11 @@ final class IndexResponse implements ApiResponse
*/
private $totalCount;
/**
* @var string[]
*/
private $assignableToPools;
private function __construct()
{
}
@ -37,6 +42,7 @@ final class IndexResponse implements ApiResponse
$model = new self();
$model->items = $data['items'];
$model->totalCount = $data['total_count'] ?? 0;
$model->assignableToPools = $data['assignable_to_pools'] ?? [];
return $model;
}
@ -49,6 +55,14 @@ final class IndexResponse implements ApiResponse
return $this->items;
}
/**
* @return string[]
*/
public function getAssignableToPools(): array
{
return $this->assignableToPools;
}
public function getTotalCount(): int
{
return $this->totalCount;

View file

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Mailboxes;
use Mailgun\Model\ApiResponse;
final class CreateResponse implements ApiResponse
{
private $message;
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
return $model;
}
private function __construct()
{
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Mailboxes;
use Mailgun\Model\ApiResponse;
final class DeleteResponse implements ApiResponse
{
private $message;
private $spec;
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
$model->spec = $data['spec'] ?? null;
return $model;
}
private function __construct()
{
}
public function getMessage(): ?string
{
return $this->message;
}
public function getSpec(): ?string
{
return $this->spec;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Mailboxes;
use Mailgun\Model\ApiResponse;
final class ShowResponse implements ApiResponse
{
private $totalCount;
private $items;
public static function create(array $data): self
{
$model = new self();
$model->totalCount = $data['total_count'] ?? null;
$model->items = $data['items'] ?? null;
return $model;
}
private function __construct()
{
}
public function getTotalCount(): ?string
{
return $this->totalCount;
}
public function getItems(): ?string
{
return $this->items;
}
}

View file

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Mailboxes;
use Mailgun\Model\ApiResponse;
final class UpdateResponse implements ApiResponse
{
private $message;
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
return $model;
}
private function __construct()
{
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -18,6 +18,7 @@ final class MailingList implements ApiResponse
private $name;
private $address;
private $accessLevel;
private $replyPreference;
private $description;
private $membersCount;
private $createdAt;
@ -28,6 +29,7 @@ final class MailingList implements ApiResponse
$model->name = $data['name'] ?? null;
$model->address = $data['address'] ?? null;
$model->accessLevel = $data['access_level'] ?? null;
$model->replyPreference = $data['reply_preference'] ?? null;
$model->description = $data['description'] ?? null;
$model->membersCount = (int) ($data['members_count'] ?? 0);
$model->createdAt = isset($data['created_at']) ? new \DateTimeImmutable($data['created_at']) : null;
@ -54,6 +56,11 @@ final class MailingList implements ApiResponse
return $this->accessLevel;
}
public function getReplyPreference(): ?string
{
return $this->replyPreference;
}
public function getDescription(): ?string
{
return $this->description;

View file

@ -11,9 +11,9 @@ declare(strict_types=1);
namespace Mailgun\Model\MailingList\Member;
use Mailgun\Model\PagingProvider;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\PagingProvider;
final class IndexResponse implements ApiResponse, PagingProvider
{

View file

@ -11,9 +11,9 @@ declare(strict_types=1);
namespace Mailgun\Model\MailingList;
use Mailgun\Model\PagingProvider;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\PagingProvider;
final class PagesResponse implements ApiResponse, PagingProvider
{

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidateResponse implements ApiResponse
{
private $id;
private $message;
public static function create(array $data): self
{
$model = new self();
$model->id = $data['id'] ?? null;
$model->message = $data['message'] ?? null;
return $model;
}
private function __construct()
{
}
public function getMessage(): ?string
{
return $this->message;
}
public function getId(): ?string
{
return $this->id;
}
}

View file

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationCancelResponse implements ApiResponse
{
private $message;
public static function create(array $data): self
{
$model = new self();
$model->message = $data['message'] ?? null;
return $model;
}
private function __construct()
{
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationStatusDownloadUrl implements ApiResponse
{
private $csv;
private $json;
public static function create(array $data): self
{
$model = new self();
$model->csv = $data['csv'] ?? null;
$model->json = $data['json'] ?? null;
return $model;
}
private function __construct()
{
}
public function getCsv(): ?string
{
return $this->csv;
}
public function getJson(): ?string
{
return $this->json;
}
}

View file

@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationStatusResponse implements ApiResponse
{
private $createdAt;
private $downloadUrl;
private $id;
private $quantity;
private $recordsProcessed;
private $status;
private $summary;
public static function create(array $data): self
{
$model = new self();
$model->id = $data['id'] ?? null;
$model->createdAt = $data['created_at'] ?? null;
$model->downloadUrl = ValidationStatusDownloadUrl::create($data['download_url']);
$model->id = $data['id'] ?? null;
$model->quantity = $data['quantity'] ?? 0;
$model->recordsProcessed = $data['records_processed'] ?? null;
$model->status = $data['status'] ?? null;
$model->summary = ValidationStatusSummary::create($data['summary'] ?? []);
return $model;
}
private function __construct()
{
}
public function getCreatedAt(): ?string
{
return $this->createdAt;
}
public function getDownloadUrl(): ValidationStatusDownloadUrl
{
return $this->downloadUrl;
}
public function getId(): ?string
{
return $this->id;
}
public function getQuantity(): ?int
{
return $this->quantity;
}
public function getRecordsProcessed(): ?int
{
return $this->recordsProcessed;
}
public function getStatus(): ?string
{
return $this->status;
}
public function getSummary(): ValidationStatusSummary
{
return $this->summary;
}
}

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationStatusSummary implements ApiResponse
{
private $result;
private $risk;
public static function create(array $data): self
{
$model = new self();
$model->result = ValidationStatusSummaryResult::create($data['result'] ?? []);
$model->risk = ValidationStatusSummaryRisk::create($data['risk'] ?? []);
return $model;
}
private function __construct()
{
}
public function getResult(): ValidationStatusSummaryResult
{
return $this->result;
}
public function getRisk(): ValidationStatusSummaryRisk
{
return $this->risk;
}
}

View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationStatusSummaryResult implements ApiResponse
{
private $deliverable;
private $doNotSend;
private $undeliverable;
private $unknown;
public static function create(array $data): self
{
$model = new self();
$model->deliverable = $data['deliverable'] ?? null;
$model->doNotSend = $data['do_not_send'] ?? null;
$model->undeliverable = $data['undeliverable'] ?? null;
$model->unknown = $data['unknown'] ?? null;
return $model;
}
private function __construct()
{
}
public function getDeliverable(): ?int
{
return $this->deliverable;
}
public function getDoNotSend(): ?int
{
return $this->doNotSend;
}
public function getUndeliverable(): ?int
{
return $this->undeliverable;
}
public function getUnknown(): ?int
{
return $this->unknown;
}
}

View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\MailingList;
use Mailgun\Model\ApiResponse;
final class ValidationStatusSummaryRisk implements ApiResponse
{
private $high;
private $low;
private $medium;
private $unknown;
public static function create(array $data): self
{
$model = new self();
$model->high = $data['high'] ?? null;
$model->low = $data['low'] ?? null;
$model->medium = $data['medium'] ?? null;
$model->unknown = $data['unknown'] ?? null;
return $model;
}
private function __construct()
{
}
public function getHigh(): ?int
{
return $this->high;
}
public function getLow(): ?int
{
return $this->low;
}
public function getMedium(): ?int
{
return $this->medium;
}
public function getUnknown(): ?int
{
return $this->unknown;
}
}

View file

@ -51,7 +51,7 @@ final class ShowResponse implements ApiResponse
$model->bodyHtml = $data['body-html'] ?? null;
$model->strippedHtml = $data['stripped-html'] ?? null;
$model->messageUrl = $data['message-url'] ?? null;
$model->messageHeaders = $data['message-headers'] ?? null;
$model->messageHeaders = $data['message-headers'] ?? [];
$model->recipient = $data['recipient'] ?? null;
$model->bodyMime = $data['body-mime'] ?? null;
$model->attachments = $data['attachments'] ?? [];
@ -131,7 +131,7 @@ final class ShowResponse implements ApiResponse
return $this->messageUrl;
}
public function getContentIdMap(): ?string
public function getContentIdMap(): ?array
{
return $this->contentIdMap;
}

View file

@ -21,6 +21,10 @@ final class TotalResponseItem
private $delivered;
private $failed;
private $complained;
private $opened;
private $clicked;
private $unsubscribed;
private $stored;
public static function create(array $data): self
{
@ -30,6 +34,10 @@ final class TotalResponseItem
$model->delivered = $data['delivered'] ?? [];
$model->failed = $data['failed'] ?? [];
$model->complained = $data['complained'] ?? [];
$model->opened = $data['opened'] ?? [];
$model->clicked = $data['clicked'] ?? [];
$model->unsubscribed = $data['unsubscribed'] ?? [];
$model->stored = $data['stored'] ?? [];
return $model;
}
@ -62,4 +70,24 @@ final class TotalResponseItem
{
return $this->complained;
}
public function getOpened(): array
{
return $this->opened;
}
public function getClicked(): array
{
return $this->clicked;
}
public function getUnsubscribed(): array
{
return $this->unsubscribed;
}
public function getStored(): array
{
return $this->stored;
}
}

View file

@ -23,7 +23,7 @@ abstract class BaseResponse implements ApiResponse
private $address;
private $message;
private function __construct()
final private function __construct()
{
}

View file

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class CreateResponse implements ApiResponse
{
private $type;
private $value;
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->type = $data['type'] ?? '';
$model->value = $data['value'] ?? '';
$model->message = $data['message'] ?? '';
return $model;
}
public function getType(): string
{
return $this->type;
}
public function getValue(): string
{
return $this->value;
}
public function getMessage(): string
{
return $this->message;
}
}

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class DeleteAllResponse implements ApiResponse
{
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->message = $data['message'] ?? '';
return $model;
}
public function getMessage(): string
{
return $this->message;
}
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class DeleteResponse implements ApiResponse
{
private $value;
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->value = $data['value'] ?? '';
$model->message = $data['message'] ?? '';
return $model;
}
public function getValue(): string
{
return $this->value;
}
public function getMessage(): string
{
return $this->message;
}
}

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class ImportResponse implements ApiResponse
{
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->message = $data['message'] ?? null;
return $model;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View file

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\PagingProvider;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class IndexResponse implements ApiResponse, PagingProvider
{
use PaginationResponse;
/**
* Array to store a list of whitelist items from
* index response.
*
* @var Whitelist[]
*/
private $items = [];
/**
* Store the total number of whitelists items.
*
* @var int
*/
private $totalCount;
private function __construct()
{
}
public static function create(array $data): self
{
$whitelists = [];
if (isset($data['items'])) {
foreach ($data['items'] as $item) {
$whitelists[] = Whitelist::create($item);
}
}
$model = new self();
$model->items = $whitelists;
$model->paging = $data['paging'];
return $model;
}
/**
* @return Whitelist[]
*/
public function getItems(): array
{
return $this->items;
}
public function getTotalCount(): int
{
if (null === $this->totalCount) {
$this->totalCount = count($this->items);
}
return $this->totalCount;
}
}

View file

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class ShowResponse extends Whitelist implements ApiResponse
{
}

View file

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use DateTimeImmutable;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
class Whitelist
{
private $value;
private $reason;
private $type;
private $createdAt;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->value = $data['value'] ?? null;
$model->reason = $data['reason'] ?? null;
$model->type = $data['type'] ?? null;
$model->createdAt = isset($data['createdAt']) ? new DateTimeImmutable($data['createdAt']) : null;
return $model;
}
public function getValue(): ?string
{
return $this->value;
}
public function getReason(): ?string
{
return $this->reason;
}
public function getType(): ?string
{
return $this->type;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
}

View file

@ -40,6 +40,12 @@ final class IndexResponse implements ApiResponse, PagingProvider
$model = new self();
$model->items = $items;
// Fix http urls that is coming from server
$data['paging'] = array_map(function (string $url) {
return str_replace('http://', 'https://', $url);
}, $data['paging']);
$model->paging = $data['paging'];
return $model;

View file

@ -23,7 +23,7 @@ abstract class BaseResponse implements ApiResponse
private $webhook = [];
private $message;
private function __construct()
final private function __construct()
{
}

View file

@ -18,13 +18,20 @@ use Mailgun\Model\ApiResponse;
*/
final class IndexResponse implements ApiResponse
{
private $bounce = [];
private $deliver = [];
private $drop = [];
private $spam = [];
private $unsubscribe = [];
private $click = [];
private $open = [];
private $legacyBounce = null;
private $legacyDeliver = null;
private $legacyDrop = null;
private $legacySpam = null;
private $legacyUnsubscribe = null;
private $legacyClick = null;
private $legacyOpen = null;
private $clicked = [];
private $complained = [];
private $delivered = [];
private $opened = [];
private $permanentFail = [];
private $temporaryFail = [];
private $unsubscribed = [];
private function __construct()
{
@ -36,49 +43,92 @@ final class IndexResponse implements ApiResponse
$data = $data['webhooks'] ?? $data;
$model->bounce = $data['bounce'] ?? [];
$model->deliver = $data['deliver'] ?? [];
$model->drop = $data['drop'] ?? [];
$model->spam = $data['spam'] ?? [];
$model->unsubscribe = $data['unsubscribe'] ?? [];
$model->click = $data['click'] ?? [];
$model->open = $data['open'] ?? [];
$model->legacyBounce = $data['bounce']['url'] ?? null;
$model->legacyDeliver = $data['deliver']['url'] ?? null;
$model->legacyDrop = $data['drop']['url'] ?? null;
$model->legacySpam = $data['spam']['url'] ?? null;
$model->legacyUnsubscribe = $data['unsubscribe']['url'] ?? null;
$model->legacyClick = $data['click']['url'] ?? null;
$model->legacyOpen = $data['open']['url'] ?? null;
$model->clicked = $data['clicked']['urls'] ?? [];
$model->complained = $data['complained']['urls'] ?? [];
$model->delivered = $data['delivered']['urls'] ?? [];
$model->opened = $data['opened']['urls'] ?? [];
$model->permanentFail = $data['permanent_fail']['urls'] ?? [];
$model->temporaryFail = $data['temporary_fail']['urls'] ?? [];
$model->unsubscribed = $data['unsubscribed']['urls'] ?? [];
return $model;
}
public function getBounceUrl(): ?string
{
return $this->bounce['url'] ?? null;
return $this->legacyBounce;
}
public function getDeliverUrl(): ?string
{
return $this->deliver['url'] ?? null;
return $this->legacyDeliver;
}
public function getDropUrl(): ?string
{
return $this->drop['url'] ?? null;
return $this->legacyDrop;
}
public function getSpamUrl(): ?string
{
return $this->spam['url'] ?? null;
return $this->legacySpam;
}
public function getUnsubscribeUrl()
public function getUnsubscribeUrl(): ?string
{
return $this->unsubscribe['url'] ?? null;
return $this->legacyUnsubscribe;
}
public function getClickUrl(): ?string
{
return $this->click['url'] ?? null;
return $this->legacyClick;
}
public function getOpenUrl(): ?string
{
return $this->open['url'] ?? null;
return $this->legacyOpen;
}
public function getClickedUrls(): ?array
{
return $this->clicked;
}
public function getComplainedUrls(): ?array
{
return $this->complained;
}
public function getDeliveredUrls(): ?array
{
return $this->delivered;
}
public function getOpenedUrls(): ?array
{
return $this->opened;
}
public function getPermanentFailUrls(): ?array
{
return $this->permanentFail;
}
public function getTemporaryFailUrls(): ?array
{
return $this->temporaryFail;
}
public function getUnsubscribeUrls(): ?array
{
return $this->unsubscribed;
}
}

View file

@ -35,6 +35,15 @@ final class ShowResponse implements ApiResponse
public function getWebhookUrl(): ?string
{
return $this->webhook['url'] ?? null;
foreach ($this->getWebhookUrls() as $url) {
return $url;
}
return null;
}
public function getWebhookUrls(): array
{
return $this->webhook['urls'] ?? [];
}
}

View file

@ -11,8 +11,8 @@ declare(strict_types=1);
namespace Mailgun\Tests\Api;
use GuzzleHttp\Psr7\Response;
use Mailgun\Api\Domain;
use Mailgun\Exception\InvalidArgumentException;
use Mailgun\Model\Domain\ConnectionResponse;
use Mailgun\Model\Domain\CreateCredentialResponse;
use Mailgun\Model\Domain\CreateResponse;
@ -20,9 +20,14 @@ 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 Nyholm\Psr7\Response;
class DomainTest extends TestCase
{
@ -51,7 +56,7 @@ class DomainTest extends TestCase
]
}
JSON
));
));
$api = $this->getApiInstance();
/** @var IndexResponse $response */
@ -77,6 +82,8 @@ JSON
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
@ -91,6 +98,8 @@ JSON
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
@ -98,6 +107,23 @@ JSON
$api->create('example.com', 'foo');
}
public function testCreateWithPoolId()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'pool_id' => '123',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, null, null, '123');
}
public function testCreateWithPasswordSpamAction()
{
$this->setRequestMethod('POST');
@ -106,6 +132,8 @@ JSON
'name' => 'example.com',
'smtp_password' => 'foo',
'spam_action' => 'bar',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
@ -122,6 +150,8 @@ JSON
'smtp_password' => 'foo',
'spam_action' => 'bar',
'wildcard' => 'true',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
@ -129,6 +159,42 @@ JSON
$api->create('example.com', 'foo', 'bar', true);
}
public function testCreateWithPasswordForceDkimAuthority()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'force_dkim_authority' => 'true',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, true);
}
public function testCreateWithPasswordSpamActionWildcardForceDkimAuthority()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'spam_action' => 'bar',
'wildcard' => 'true',
'force_dkim_authority' => 'true',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', 'bar', true, true);
}
public function testDelete()
{
$this->setRequestMethod('DELETE');
@ -209,4 +275,183 @@ JSON
$api = $this->getApiInstance();
$api->verify('example.com');
}
public function testCreateWithIps()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'ips' => '127.0.0.1,127.0.0.2',
'web_scheme' => 'http',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, null, ['127.0.0.1', '127.0.0.2']);
}
public function testCreateWithDkim()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'web_scheme' => 'http',
'dkim_key_size' => '2048',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, null, null, null, 'http', '2048');
}
public function testCreateWithWebSchema()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/domains');
$this->setRequestBody([
'name' => 'example.com',
'smtp_password' => 'foo',
'web_scheme' => 'https',
'dkim_key_size' => '1024',
]);
$this->setHydrateClass(CreateResponse::class);
$api = $this->getApiInstance();
$api->create('example.com', 'foo', null, null, null, null, null, 'https');
}
public function testTracking()
{
$this->setRequestMethod('GET');
$this->setRequestUri('/v3/domains/example.com/tracking');
$this->setHydrateClass(TrackingResponse::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->tracking('example.com');
}
public function updateClickTrackingDataProvider(): array
{
return [
['yes'],
['no'],
['htmlonly'],
];
}
/**
* @dataProvider updateClickTrackingDataProvider
*/
public function testUpdateClickTracking(string $active)
{
$this->setRequestMethod('PUT');
$this->setRequestUri('/v3/domains/example.com/tracking/click');
$this->setRequestBody([
'active' => $active,
]);
$this->setHydrateClass(UpdateClickTrackingResponse::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateClickTracking('example.com', $active);
}
public function testUpdateClickTrackingException()
{
$this->expectException(InvalidArgumentException::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateClickTracking('example.com', 'non-valid-active-param');
}
public function updateOpenTrackingDataProvider(): array
{
return [
['yes'],
['no'],
];
}
/**
* @dataProvider updateOpenTrackingDataProvider
*/
public function testUpdateOpenTracking(string $active)
{
$this->setRequestMethod('PUT');
$this->setRequestUri('/v3/domains/example.com/tracking/open');
$this->setRequestBody([
'active' => $active,
]);
$this->setHydrateClass(UpdateOpenTrackingResponse::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateOpenTracking('example.com', $active);
}
public function testUpdateOpenTrackingException()
{
$this->expectException(InvalidArgumentException::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateOpenTracking('example.com', 'non-valid-active-param');
}
public function unsubscribeDataProvider(): array
{
return [
['true', '<b>Test</b>', 'Test1'],
['false', '<s>Test</s>', 'Test2'],
];
}
/**
* @dataProvider unsubscribeDataProvider
*/
public function testUpdateUnsubscribeTracking(string $active, string $htmlFooter, string $textFooter)
{
$this->setRequestMethod('PUT');
$this->setRequestUri('/v3/domains/example.com/tracking/unsubscribe');
$this->setRequestBody([
'active' => $active,
'html_footer' => $htmlFooter,
'text_footer' => $textFooter,
]);
$this->setHydrateClass(UpdateUnsubscribeTrackingResponse::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateUnsubscribeTracking('example.com', $active, $htmlFooter, $textFooter);
}
public function testUpdateUnsubscribeTrackingException()
{
$this->expectException(InvalidArgumentException::class);
/**
* @var Domain
*/
$api = $this->getApiInstance();
$api->updateUnsubscribeTracking('example.com', 'non-valid-active-param', 'html-footer', 'text-footer');
}
}

Some files were not shown because too many files have changed in this diff Show more