-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from thomaskonrad/websms
Add websms provider
- Loading branch information
Showing
3 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the SmsSender package. | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* | ||
* @license MIT License | ||
*/ | ||
|
||
namespace SmsSender\Provider; | ||
|
||
use SmsSender\Exception as Exception; | ||
use SmsSender\HttpAdapter\HttpAdapterInterface; | ||
use SmsSender\Result\ResultInterface; | ||
|
||
/** | ||
* @author Thomas Konrad <[email protected]> | ||
* @see <https://websms.at/entwickler/sms-api/api-rest/rest-schnittstellenspezifikation> | ||
*/ | ||
class WebsmsProvider extends AbstractProvider | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
const ENDPOINT_URL = 'https://api.websms.com/rest/smsmessaging/text'; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $accessToken; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $internationalPrefix; | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function __construct(HttpAdapterInterface $adapter, $accessToken, $internationalPrefix = '+43') | ||
{ | ||
parent::__construct($adapter); | ||
|
||
$this->accessToken = $accessToken; | ||
$this->internationalPrefix = $internationalPrefix; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'websms'; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function send($recipient, $body, $originator = '') | ||
{ | ||
if (null === $this->accessToken) { | ||
throw new Exception\InvalidCredentialsException('No API credentials provided'); | ||
} | ||
|
||
$params = array( | ||
'messageContent' => $body, | ||
'recipientAddressList' => array( | ||
$this->removeLeadingPlusIfPresent( | ||
$this->localNumberToInternational($recipient, $this->internationalPrefix) | ||
) | ||
) | ||
); | ||
|
||
return $this->executeQuery(self::ENDPOINT_URL, $params, array( | ||
'recipient' => $recipient, | ||
'body' => $body, | ||
'originator' => $originator, | ||
)); | ||
} | ||
|
||
/** | ||
* Issues the actual HTTP query. | ||
* | ||
* @param $url | ||
* @param array $data | ||
* @param array $extra_result_data | ||
* @return array | ||
*/ | ||
protected function executeQuery($url, array $data = array(), array $extra_result_data = array()) | ||
{ | ||
$headers = array( | ||
sprintf('Authorization: Bearer %s', $this->accessToken), | ||
'Content-Type: application/json', | ||
'Accept: application/json' | ||
); | ||
|
||
// Issue the request | ||
$content = $this->getAdapter()->getContent($url, 'POST', $headers, json_encode($data)); | ||
|
||
if (null === $content) { | ||
return array_merge($this->getDefaults(), $extra_result_data); | ||
} | ||
|
||
return $this->parseResults($content, $extra_result_data); | ||
} | ||
|
||
/** | ||
* Parses the data returned by the API. | ||
* | ||
* @param string $result The raw result string. | ||
* @return array | ||
*/ | ||
protected function parseResults($result, array $extra_result_data = array()) | ||
{ | ||
$data = json_decode($result, true); | ||
$smsData = array(); | ||
|
||
// There was an error | ||
if (empty($data['transferId']) || empty($data['statusCode'])) { | ||
return array_merge($this->getDefaults(), $extra_result_data, array( | ||
'status' => ResultInterface::STATUS_FAILED, | ||
) | ||
); | ||
} | ||
|
||
// Get the transfer id | ||
$smsData['id'] = $data['transferId']; | ||
|
||
// Get the status | ||
switch ($data['statusCode']) { | ||
case 2000: | ||
$smsData['status'] = ResultInterface::STATUS_SENT; | ||
break; | ||
case 2001: | ||
$smsData['status'] = ResultInterface::STATUS_QUEUED; | ||
break; | ||
default: | ||
$smsData['status'] = ResultInterface::STATUS_FAILED; | ||
break; | ||
} | ||
|
||
return array_merge($this->getDefaults(), $extra_result_data, $smsData); | ||
} | ||
|
||
/** | ||
* Removes the leading plus sign from the international phone number as websms requires it that way. | ||
* | ||
* @param string $number The number to strip the plus sign from | ||
* @return string | ||
*/ | ||
protected function removeLeadingPlusIfPresent($number) | ||
{ | ||
if ($number[0] !== '+') { | ||
// The number has no leading "+" sign | ||
return $number; | ||
} else { | ||
|
||
// Remove the leading "+" sign and add the prefix | ||
return substr($number, 1); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<?php | ||
|
||
namespace SmsSender\Tests\Provider; | ||
|
||
use SmsSender\Provider\TwilioProvider; | ||
use SmsSender\Provider\WebsmsProvider; | ||
use SmsSender\Result\ResultInterface; | ||
|
||
class WebsmsProviderTest extends BaseProviderTest | ||
{ | ||
protected function getProvider($adapter) | ||
{ | ||
return new WebsmsProvider($adapter, 'access_token'); | ||
} | ||
|
||
/** | ||
* @expectedException \SmsSender\Exception\InvalidCredentialsException | ||
* @expectedExceptionMessage No API credentials provided | ||
*/ | ||
public function testSendWithNullApiCredentials() | ||
{ | ||
$adapter = $this->getMock('\SmsSender\HttpAdapter\HttpAdapterInterface'); | ||
$provider = new WebsmsProvider($adapter, null, null); | ||
$provider->send('066412345678', 'foo!'); | ||
} | ||
|
||
public function testSend() | ||
{ | ||
$provider = $this->getProvider($this->getMockAdapter()); | ||
$result = $provider->send('066412345678', 'foo', 'originator'); | ||
|
||
$this->assertNull($result['id']); | ||
$this->assertEquals(ResultInterface::STATUS_FAILED, $result['status']); | ||
$this->assertEquals('066412345678', $result['recipient']); | ||
$this->assertEquals('foo', $result['body']); | ||
$this->assertEquals('originator', $result['originator']); | ||
} | ||
|
||
public function testSendWithMockData() | ||
{ | ||
$data = <<<EOF | ||
{"statusCode":2000,"statusMessage":"OK","transferId":"005440da3e00078f5214"} | ||
EOF; | ||
$provider = $this->getProvider($this->getMockAdapter(null, $data)); | ||
$result = $provider->send('066412345678', 'foo'); | ||
|
||
$this->assertEquals('005440da3e00078f5214', $result['id']); | ||
$this->assertEquals(ResultInterface::STATUS_SENT, $result['status']); | ||
$this->assertEquals('066412345678', $result['recipient']); | ||
$this->assertEquals('foo', $result['body']); | ||
} | ||
|
||
/** | ||
* @dataProvider validRecipientProvider | ||
*/ | ||
public function testSendCleansRecipientNumber($recipient, $expectedRecipient, $internationalPrefix = null) | ||
{ | ||
// setup the adapter | ||
$adapter = $this->getMock('\SmsSender\HttpAdapter\HttpAdapterInterface'); | ||
$adapter | ||
->expects($this->once()) | ||
->method('getContent') | ||
->with( | ||
$this->anything(), // URL | ||
$this->equalTo('POST'), // method | ||
$this->anything(), // headers | ||
$this->callback(function ($data) use ($expectedRecipient) { | ||
$dataArray = json_decode($data, true); | ||
|
||
return is_array($dataArray['recipientAddressList']) | ||
&& count($dataArray['recipientAddressList']) > 0 | ||
&& $dataArray['recipientAddressList'][0] === $expectedRecipient; | ||
}) | ||
); | ||
|
||
// setup the provider | ||
if ($internationalPrefix === null) { | ||
$provider = new WebsmsProvider($adapter, 'access_token'); | ||
} else { | ||
$provider = new WebsmsProvider($adapter, 'access_token', $internationalPrefix); | ||
} | ||
|
||
// launch the test | ||
$provider->send($recipient, 'foo'); | ||
} | ||
|
||
public function validRecipientProvider() | ||
{ | ||
return array( | ||
array('066412345678', '4366412345678', null), | ||
array('066412345678', '4366412345678', '+43'), | ||
array('066412345678', '4466412345678', '+44'), | ||
array('+4366412345678', '4366412345678', '+43'), | ||
array('+4366412345678', '4366412345678', '+44'), | ||
); | ||
} | ||
|
||
/** | ||
* @requires extension curl | ||
*/ | ||
public function testRealSend() | ||
{ | ||
if (empty($_SERVER['WEBSMS_ACCESS_TOKEN'])) { | ||
$this->markTestSkipped('No test credentials configured.'); | ||
} | ||
|
||
$adapter = new \SmsSender\HttpAdapter\CurlHttpAdapter(); | ||
$provider = new WebsmsProvider($adapter, $_SERVER['WEBSMS_ACCESS_TOKEN']); | ||
$sender = new \SmsSender\SmsSender($provider); | ||
$result = $sender->send('066412345678', 'foo'); | ||
|
||
$this->assertTrue(!empty($result['id'])); | ||
$this->assertEquals(ResultInterface::STATUS_SENT, $result['status']); | ||
$this->assertEquals('066412345678', $result['recipient']); | ||
$this->assertEquals('foo', $result['body']); | ||
} | ||
} |