From b6df492b1069348e9509d31ea3725f385493b584 Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Fri, 17 Oct 2014 09:34:24 +0200 Subject: [PATCH 1/8] Add websms provider. --- src/SmsSender/Provider/WebsmsProvider.php | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 src/SmsSender/Provider/WebsmsProvider.php diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php new file mode 100755 index 0000000..01dcfca --- /dev/null +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -0,0 +1,153 @@ + + * @see + */ +class WebsmsProvider extends AbstractProvider +{ + /** + * @var string + */ + protected $accessToken; + + 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} + */ + protected function getEndPointUrl() + { + return 'https://api.websms.com/rest/smsmessaging/text'; + } + + /** + * Send a message to the given phone number. + * + * @param string $recipient The phone number. + * @param string $body The message to send. + * @param string $originator The name of the person which sends the message. + * @return array The data returned by the API. + */ + public function send($recipient, $body, $originator = '') + { + if (null === $this->accessToken) { + throw new Exception\InvalidCredentialsException('No API credentials provided'); + } + + $recipient = $this->localNumberToInternational($recipient, $this->internationalPrefix); + $recipient = $this->removeLeadingPlusIfPresent($recipient); + + $params = array( + 'messageContent' => $body, + 'recipientAddressList' => array($recipient) + ); + + return $this->executeQuery($this->getEndPointUrl(), $params, array( + 'recipient' => $recipient, + 'body' => $body, + 'originator' => $originator, + )); + } + + 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' + ); + $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); + } + + /** + * Parse 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); + } + + 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); + } + } +} From 5557ccbd77f02e456ae13818cbc8f7204070f95c Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Fri, 17 Oct 2014 09:42:15 +0200 Subject: [PATCH 2/8] Add websms to the list of supported providers. --- README.md | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 README.md diff --git a/README.md b/README.md old mode 100644 new mode 100755 index c631fe5..817c8aa --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The following providers are supported: * [CardBoardFish](http://www.cardboardfish.com/) * [ValueFirst](http://vfirst.com/) (only covering India's networks) * [Swisscom](http://developer.swisscom.com/) (based on the [GSMA OneAPI](http://www.gsma.com/oneapi/) Specification) +* [websms](https://websms.at/) Installation ------------ From fe911067f5ef61f413a7dee634b007df9af41ba9 Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Fri, 17 Oct 2014 11:37:35 +0200 Subject: [PATCH 3/8] Change websms provider to return the originally provided recipient. --- src/SmsSender/Provider/WebsmsProvider.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php index 01dcfca..2e30384 100755 --- a/src/SmsSender/Provider/WebsmsProvider.php +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -70,12 +70,13 @@ public function send($recipient, $body, $originator = '') throw new Exception\InvalidCredentialsException('No API credentials provided'); } - $recipient = $this->localNumberToInternational($recipient, $this->internationalPrefix); - $recipient = $this->removeLeadingPlusIfPresent($recipient); - $params = array( 'messageContent' => $body, - 'recipientAddressList' => array($recipient) + 'recipientAddressList' => array( + $this->removeLeadingPlusIfPresent( + $this->localNumberToInternational($recipient, $this->internationalPrefix) + ) + ) ); return $this->executeQuery($this->getEndPointUrl(), $params, array( From 388c66b28d193dfb8de362bfd6bc37a5fa76b3d9 Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Fri, 17 Oct 2014 11:39:37 +0200 Subject: [PATCH 4/8] Add webms unit test. --- .../Tests/Provider/WebsmsProviderTest.php | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100755 tests/SmsSender/Tests/Provider/WebsmsProviderTest.php diff --git a/tests/SmsSender/Tests/Provider/WebsmsProviderTest.php b/tests/SmsSender/Tests/Provider/WebsmsProviderTest.php new file mode 100755 index 0000000..f1f821c --- /dev/null +++ b/tests/SmsSender/Tests/Provider/WebsmsProviderTest.php @@ -0,0 +1,117 @@ +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 = <<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']); + } +} From d5b0012747566dfe092cb30ce92590f2845186d8 Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Mon, 20 Oct 2014 08:47:18 +0200 Subject: [PATCH 5/8] Remove extra whitespace. --- src/SmsSender/Provider/WebsmsProvider.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php index 2e30384..b694029 100755 --- a/src/SmsSender/Provider/WebsmsProvider.php +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -15,8 +15,6 @@ use SmsSender\Result\ResultInterface; /** - * - * * @author Thomas Konrad * @see */ From b66e7bfcee7324b2fbf6903a7cc5d8284b078551 Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Mon, 20 Oct 2014 08:50:06 +0200 Subject: [PATCH 6/8] Use class constant for endpoint URL. --- src/SmsSender/Provider/WebsmsProvider.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php index b694029..3d54ed0 100755 --- a/src/SmsSender/Provider/WebsmsProvider.php +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -20,6 +20,11 @@ */ class WebsmsProvider extends AbstractProvider { + /** + * @var string + */ + const ENDPOINT_URL = 'https://api.websms.com/rest/smsmessaging/text'; + /** * @var string */ @@ -46,14 +51,6 @@ public function getName() return 'websms'; } - /** - * {@inheritDoc} - */ - protected function getEndPointUrl() - { - return 'https://api.websms.com/rest/smsmessaging/text'; - } - /** * Send a message to the given phone number. * @@ -77,7 +74,7 @@ public function send($recipient, $body, $originator = '') ) ); - return $this->executeQuery($this->getEndPointUrl(), $params, array( + return $this->executeQuery(self::ENDPOINT_URL, $params, array( 'recipient' => $recipient, 'body' => $body, 'originator' => $originator, From 2cd148db4fe8adbb0678729b9fd4cc179489054e Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Mon, 20 Oct 2014 08:51:32 +0200 Subject: [PATCH 7/8] Use @inheritDoc for send function. --- src/SmsSender/Provider/WebsmsProvider.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php index 3d54ed0..6eb48f7 100755 --- a/src/SmsSender/Provider/WebsmsProvider.php +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -52,12 +52,7 @@ public function getName() } /** - * Send a message to the given phone number. - * - * @param string $recipient The phone number. - * @param string $body The message to send. - * @param string $originator The name of the person which sends the message. - * @return array The data returned by the API. + * {@inheritDoc} */ public function send($recipient, $body, $originator = '') { From 9548f475f7a73572e4812ba454086529b78f585e Mon Sep 17 00:00:00 2001 From: Thomas Konrad Date: Mon, 20 Oct 2014 08:55:13 +0200 Subject: [PATCH 8/8] Added and corrected docs in websms provider class. --- src/SmsSender/Provider/WebsmsProvider.php | 25 ++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/SmsSender/Provider/WebsmsProvider.php b/src/SmsSender/Provider/WebsmsProvider.php index 6eb48f7..2821c74 100755 --- a/src/SmsSender/Provider/WebsmsProvider.php +++ b/src/SmsSender/Provider/WebsmsProvider.php @@ -30,6 +30,9 @@ class WebsmsProvider extends AbstractProvider */ protected $accessToken; + /** + * @var string + */ protected $internationalPrefix; /** @@ -76,6 +79,14 @@ public function send($recipient, $body, $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( @@ -83,6 +94,8 @@ protected function executeQuery($url, array $data = array(), array $extra_result 'Content-Type: application/json', 'Accept: application/json' ); + + // Issue the request $content = $this->getAdapter()->getContent($url, 'POST', $headers, json_encode($data)); if (null === $content) { @@ -93,7 +106,7 @@ protected function executeQuery($url, array $data = array(), array $extra_result } /** - * Parse the data returned by the API. + * Parses the data returned by the API. * * @param string $result The raw result string. * @return array @@ -103,7 +116,7 @@ protected function parseResults($result, array $extra_result_data = array()) $data = json_decode($result, true); $smsData = array(); - // there was an error + // There was an error if (empty($data['transferId']) || empty($data['statusCode'])) { return array_merge($this->getDefaults(), $extra_result_data, array( 'status' => ResultInterface::STATUS_FAILED, @@ -114,7 +127,7 @@ protected function parseResults($result, array $extra_result_data = array()) // Get the transfer id $smsData['id'] = $data['transferId']; - // get the status + // Get the status switch ($data['statusCode']) { case 2000: $smsData['status'] = ResultInterface::STATUS_SENT; @@ -130,6 +143,12 @@ protected function parseResults($result, array $extra_result_data = array()) 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] !== '+') {