Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- Support for API token authentication. Username and password can still be used
as a fallback.
### Changed
- Deprecate `getConfig()` method. Packages can maintain their config internally.

## [6.0.0] - 2025-02-14
### Added
Expand All @@ -14,6 +19,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- **BC break**: Removed support for PHP versions <= v8.0 as they are no longer
[actively supported](https://php.net/supported-versions.php) by the PHP project.

## [5.2.0] - 2025-06-25
### Added
- Support for API token authentication. Username and password can still be used
as a fallback.
### Changed
- Deprecate `getConfig()` method. Packages can maintain their config internally.

## [5.1.1] - 2021-08-10
### Fixed
- Clean-up temporary local file for any errors while trying to download a file.
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ $ composer require maxemail/api-php
```php
// Instantiate Client:
$config = [
'username' => 'api@user.com',
'password' => 'apipass'
'token' => 'apitoken',
];
$api = new \Maxemail\Api\Client($config);

Expand Down
3 changes: 1 addition & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
<!-- Configuration to enable functional tests -->
<env name="FUNC_ENABLED" value="false" />
<env name="FUNC_API_URI" value="https://mxm.xtremepush.com/" />
<env name="FUNC_API_USERNAME" value="api@user.com" />
<env name="FUNC_API_PASSWORD" value="apipass" />
<env name="FUNC_API_TOKEN" value="apitoken" />
</php>

<testsuites>
Expand Down
69 changes: 52 additions & 17 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Maxemail\Api;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface as GuzzleClientInterface;
use GuzzleHttp\HandlerStack;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -63,6 +64,8 @@ class Client implements LoggerAwareInterface

private string $uri = 'https://mxm.xtremepush.com/';

private readonly string $token;

private readonly string $username;

private readonly string $password;
Expand All @@ -76,26 +79,37 @@ class Client implements LoggerAwareInterface

private LoggerInterface $logger;

private GuzzleClient $httpClient;
private GuzzleClientInterface $httpClient;

private bool $debugLoggingEnabled = false;

/**
* @var \Closure(array):GuzzleClientInterface
*/
private \Closure $httpClientFactory;

/**
* @param array{
* username: string, // Required
* password: string, // Required
* token: string, // Required, or username & password
* username: string, // Required, if no token
* password: string, // Required, if no token
* uri: string, // Optional. Default https://mxm.xtremepush.com/
* debugLogging: bool, // Optional. Enable logging of request/response. Default false
* } $config
*/
public function __construct(array $config)
{
// Must have user/pass
if (!isset($config['username']) || !isset($config['password'])) {
throw new Exception\InvalidArgumentException('API config requires username & password');
// Must have API token
if (!isset($config['token'])) {
// Must have user/pass
if (!isset($config['username']) || !isset($config['password'])) {
throw new Exception\InvalidArgumentException('API config requires token OR username & password');
}
$this->username = $config['username'];
$this->password = $config['password'];
} else {
$this->token = $config['token'];
}
$this->username = $config['username'];
$this->password = $config['password'];

if (isset($config['uri'])) {
$parsed = parse_url($config['uri']);
Expand Down Expand Up @@ -127,7 +141,7 @@ private function getInstance(string $serviceName): Service
return $this->services[$serviceName];
}

private function getClient(): GuzzleClient
private function getClient(): GuzzleClientInterface
{
if (!isset($this->httpClient)) {
$stack = HandlerStack::create();
Expand All @@ -136,19 +150,31 @@ private function getClient(): GuzzleClient
if ($this->debugLoggingEnabled) {
Middleware::addLogging($stack, $this->getLogger());
}
$this->httpClient = new GuzzleClient([

$clientConfig = [
'base_uri' => $this->uri . 'api/json/',
'auth' => [
$this->username,
$this->password,
],
'headers' => [
'User-Agent' => 'MxmApiClient/' . self::VERSION . ' PHP/' . PHP_VERSION,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
'handler' => $stack,
]);
];

if (isset($this->token)) {
$clientConfig['headers']['Authorization'] = 'Bearer ' . $this->token;
} else {
$clientConfig['auth'] = [
$this->username,
$this->password,
];
}

if (!isset($this->httpClientFactory)) {
$this->httpClient = new GuzzleClient($clientConfig);
} else {
$this->httpClient = ($this->httpClientFactory)($clientConfig);
}
}

return $this->httpClient;
Expand All @@ -157,6 +183,7 @@ private function getClient(): GuzzleClient
/**
* Get API connection config
*
* @deprecated v5.2 No replacement; packages can maintain their own config; to be removed in v7.
* @return array{
* uri: string,
* username: string,
Expand All @@ -167,8 +194,8 @@ public function getConfig(): array
{
return [
'uri' => $this->uri,
'username' => $this->username,
'password' => $this->password,
'username' => $this->username ?? null,
'password' => $this->password ?? null,
];
}

Expand All @@ -194,4 +221,12 @@ public function getLogger(): LoggerInterface

return $this->logger;
}

/**
* @internal This method is not part of the BC promise. Used for DI for unit tests only.
*/
public function setHttpClientFactory(\Closure $httpClientFactory): void
{
$this->httpClientFactory = $httpClientFactory;
}
}
2 changes: 1 addition & 1 deletion src/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Maxemail\Api;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface as GuzzleClient;
use Psr\Log\LogLevel;

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Maxemail\Api;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface as GuzzleClient;

/**
* Maxemail API Client
Expand Down
Loading