Skip to content

Conversation

@SamuelMwangiW
Copy link
Contributor

The SDK is overdue for a major review.

This is a first of (hopefully multiple) PRs aimed at bringing the SDK to the AI age.

This PR is restricted to the following:

  • Drop support for unsupported PHP versions
  • Update dependency versions
  • Add type hints for an improved DX
  • Deleted composer.lock file - This being a library, the lock file is only required for local development and ignored in user-space
  • Run code formatting to comply with PER coding style

@SamuelMwangiW SamuelMwangiW marked this pull request as ready for review August 28, 2025 11:38
Copy link
Contributor Author

@SamuelMwangiW SamuelMwangiW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self review

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary for a library

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use phpunit.xml.dist instead. This allows maintainers to override phpunit.xml locally during development. This is especially important as I intend to push a PR that adds tests and the test credentials are expected to be in phpunit.xml.

This is also why phpunit.xml is now added to .gitignore

}

$this->baseUrl = 'https://api.' . $this->baseDomain . '/version1/';
$this->voiceUrl = 'https://voice.africastalking.com/';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Voice is disabled on sandbox.

Comment on lines -98 to +110
$sms = new SMS($this->client, $this->username, $this->apiKey, $content);
return $sms;
}

public function content()
{
$content = new Content($this->contentClient, $this->username, $this->apiKey);
return $content;
}

public function airtime()
{
$airtime = new Airtime($this->client, $this->username, $this->apiKey);
return $airtime;
}

public function voice()
{
$voice = new Voice($this->voiceClient, $this->username, $this->apiKey);
return $voice;
}

public function application()
{
$application = new Application($this->client, $this->username, $this->apiKey);
return $application;
}

public function mobileData()
{
$mobileData = new MobileData($this->mobileDataClient, $this->username, $this->apiKey);
return $mobileData;
}

public function token()
{
$token = new Token($this->tokenClient, $this->username, $this->apiKey);
return $token;
}
public const BASE_DOMAIN = 'africastalking.com';

public const BASE_SANDBOX_DOMAIN = 'sandbox.' . self::BASE_DOMAIN;

protected string $username;

protected string $apiKey;

protected Client $client;

protected Client $contentClient;

protected Client $voiceClient;

protected Client $tokenClient;

protected Client $mobileDataClient;

protected string $baseDomain;

public string $baseUrl;

protected string $voiceUrl;

protected string $checkoutTokenUrl;

protected string $contentUrl;

protected string $mobileDataUrl;

public function __construct(string $username, string $apiKey)
{
if ($username === 'sandbox') {
$this->baseDomain = self::BASE_SANDBOX_DOMAIN;
} else {
$this->baseDomain = self::BASE_DOMAIN;
}

$this->baseUrl = 'https://api.' . $this->baseDomain . '/version1/';
$this->voiceUrl = 'https://voice.africastalking.com/';
$this->mobileDataUrl = 'https://bundles.' . $this->baseDomain . '/';
$this->contentUrl = ($username === 'sandbox') ? ($this->baseUrl) : ('https://content.' . $this->baseDomain . '/version1/');
$this->checkoutTokenUrl = 'https://api.' . $this->baseDomain . '/';

if ($username === 'sandbox') {
$this->contentUrl = $this->baseUrl;
}

$this->username = $username;
$this->apiKey = $apiKey;

$this->client = new Client([
'base_uri' => $this->baseUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->contentClient = new Client([
'base_uri' => $this->contentUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->voiceClient = new Client([
'base_uri' => $this->voiceUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->mobileDataClient = new Client([
'base_uri' => $this->mobileDataUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);

$this->tokenClient = new Client([
'base_uri' => $this->checkoutTokenUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);
}

public function sms(): SMS
{
$content = new Content($this->contentClient, $this->username, $this->apiKey);

return new SMS($this->client, $this->username, $this->apiKey, $content);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable is unnecessary here

Comment on lines -104 to +115
$content = new Content($this->contentClient, $this->username, $this->apiKey);
return $content;
}

public function airtime()
{
$airtime = new Airtime($this->client, $this->username, $this->apiKey);
return $airtime;
}

public function voice()
{
$voice = new Voice($this->voiceClient, $this->username, $this->apiKey);
return $voice;
}

public function application()
{
$application = new Application($this->client, $this->username, $this->apiKey);
return $application;
}

public function mobileData()
{
$mobileData = new MobileData($this->mobileDataClient, $this->username, $this->apiKey);
return $mobileData;
}

public function token()
{
$token = new Token($this->tokenClient, $this->username, $this->apiKey);
return $token;
}
public const BASE_DOMAIN = 'africastalking.com';

public const BASE_SANDBOX_DOMAIN = 'sandbox.' . self::BASE_DOMAIN;

protected string $username;

protected string $apiKey;

protected Client $client;

protected Client $contentClient;

protected Client $voiceClient;

protected Client $tokenClient;

protected Client $mobileDataClient;

protected string $baseDomain;

public string $baseUrl;

protected string $voiceUrl;

protected string $checkoutTokenUrl;

protected string $contentUrl;

protected string $mobileDataUrl;

public function __construct(string $username, string $apiKey)
{
if ($username === 'sandbox') {
$this->baseDomain = self::BASE_SANDBOX_DOMAIN;
} else {
$this->baseDomain = self::BASE_DOMAIN;
}

$this->baseUrl = 'https://api.' . $this->baseDomain . '/version1/';
$this->voiceUrl = 'https://voice.africastalking.com/';
$this->mobileDataUrl = 'https://bundles.' . $this->baseDomain . '/';
$this->contentUrl = ($username === 'sandbox') ? ($this->baseUrl) : ('https://content.' . $this->baseDomain . '/version1/');
$this->checkoutTokenUrl = 'https://api.' . $this->baseDomain . '/';

if ($username === 'sandbox') {
$this->contentUrl = $this->baseUrl;
}

$this->username = $username;
$this->apiKey = $apiKey;

$this->client = new Client([
'base_uri' => $this->baseUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->contentClient = new Client([
'base_uri' => $this->contentUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->voiceClient = new Client([
'base_uri' => $this->voiceUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
],
]);

$this->mobileDataClient = new Client([
'base_uri' => $this->mobileDataUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);

$this->tokenClient = new Client([
'base_uri' => $this->checkoutTokenUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);
}

public function sms(): SMS
{
$content = new Content($this->contentClient, $this->username, $this->apiKey);

return new SMS($this->client, $this->username, $this->apiKey, $content);
}

public function content(): Content
{
return new Content($this->contentClient, $this->username, $this->apiKey);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable is unnecessary here

}

protected function buildSay($options)
protected function buildSay(string|array $options): array|string
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests were failing that $options received is an array or string.

// change trimSilence to true or false string
$trimSilence ? $trimSilence = "true" : $trimSilence ="false";
$trimSilence ? $trimSilence = 'true' : $trimSilence = 'false';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look right but can't update without tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No changes to tests besides formatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No changes to tests besides formatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No changes to tests.

@SamuelMwangiW
Copy link
Contributor Author

Please squash commits while merging

@SamuelMwangiW SamuelMwangiW changed the base branch from develop to master August 28, 2025 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant