From 57bb1f705a7fded1a8df40591be46c486b8474ba Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Thu, 23 Apr 2015 16:42:03 +0200 Subject: [PATCH 01/17] Clickatell API calls as GET request --- library/Xi/Sms/Gateway/ClickatellGateway.php | 23 +++++++++++++++---- .../Tests/Gateway/ClickatellGatewayTest.php | 18 ++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 4979936..2060fb4 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -48,16 +48,31 @@ public function __construct( /** * @see GatewayInterface::send * @todo Implement a smarter method of sending (batch) + * @param SmsMessage $message + * @param bool $urlEncoding To ensure backwards compatibility */ - public function send(SmsMessage $message) + public function send(SmsMessage $message, $urlEncoding = false) { $body = urlencode(utf8_decode($message->getBody())); $from = urlencode($message->getFrom()); foreach ($message->getTo() as $to) { - $url = "{$this->endpoint}/http/sendmsg?api_id={$this->apiKey}&user={$this->user}" . - "&password={$this->password}&to={$to}&text={$body}&from={$from}"; - $this->getClient()->post($url, array()); + $params = array( + 'api_id' => $this->apiKey, + 'user' => $this->user, + 'password' => $this->password, + 'to' => $to, + 'text' => $body, + 'from' => $from + ); + $query_string = $urlEncoding ? + "api_id={$this->apiKey}&user={$this->user}" . + "&password={$this->password}&to={$to}&text={$body}&from={$from}" : + http_build_query($params); + $this->getClient()->get( + $this->endpoint . '/http/sendmsg?'.$query_string, + array() + ); } return true; } diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 7215d78..c85e11c 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -21,10 +21,22 @@ public function sendsRequest() $browser ->expects($this->once()) - ->method('post') + ->method('get') ->with( - 'http://api.dr-kobros.com/http/sendmsg?api_id=lussavain&user=lussuta&password=' . - 'tussia&to=358503028030&text=Pekkis+tassa+lussuttaa.&from=358503028030', + $this->callback(function($actual) { + $url = parse_url($actual); + parse_str($url['query'], $query); + return + $url['scheme'] === 'http' && + $url['host'] === 'api.dr-kobros.com' && + $url['path'] === '/http/sendmsg' && + $query['api_id'] === 'lussavain' && + $query['user'] === 'lussuta' && + $query['password'] === 'tussia' && + $query['to'] === '358503028030' && + urldecode($query['text']) === 'Pekkis tassa lussuttaa.' && + $query['from'] === '358503028030'; + }), array() ); From 48f3351f7416d24dd695e3efce2262306c43256a Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Thu, 23 Apr 2015 17:03:37 +0200 Subject: [PATCH 02/17] Fixed BC --- library/Xi/Sms/Gateway/ClickatellGateway.php | 23 ++++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 2060fb4..5daa0b2 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -49,28 +49,27 @@ public function __construct( * @see GatewayInterface::send * @todo Implement a smarter method of sending (batch) * @param SmsMessage $message - * @param bool $urlEncoding To ensure backwards compatibility + * @param bool $utf8decode To ensure backwards compatibility */ - public function send(SmsMessage $message, $urlEncoding = false) + public function send(SmsMessage $message, $utf8decode = true) { - $body = urlencode(utf8_decode($message->getBody())); - $from = urlencode($message->getFrom()); - foreach ($message->getTo() as $to) { $params = array( 'api_id' => $this->apiKey, 'user' => $this->user, 'password' => $this->password, 'to' => $to, - 'text' => $body, - 'from' => $from + 'text' => $message->getBody(), + 'from' => $message->getFrom() ); - $query_string = $urlEncoding ? - "api_id={$this->apiKey}&user={$this->user}" . - "&password={$this->password}&to={$to}&text={$body}&from={$from}" : - http_build_query($params); + + // BC + if ($utf8decode) { + $params['text'] = utf8_decode($params['text']); + } + $this->getClient()->get( - $this->endpoint . '/http/sendmsg?'.$query_string, + $this->endpoint . '/http/sendmsg?'.http_build_query($params), array() ); } From 9bfd1930e8ef261c162d502c3d7968c5cb73abd5 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Thu, 23 Apr 2015 17:04:53 +0200 Subject: [PATCH 03/17] Fixed BC --- library/Xi/Sms/Gateway/ClickatellGateway.php | 23 ++++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 2060fb4..5daa0b2 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -49,28 +49,27 @@ public function __construct( * @see GatewayInterface::send * @todo Implement a smarter method of sending (batch) * @param SmsMessage $message - * @param bool $urlEncoding To ensure backwards compatibility + * @param bool $utf8decode To ensure backwards compatibility */ - public function send(SmsMessage $message, $urlEncoding = false) + public function send(SmsMessage $message, $utf8decode = true) { - $body = urlencode(utf8_decode($message->getBody())); - $from = urlencode($message->getFrom()); - foreach ($message->getTo() as $to) { $params = array( 'api_id' => $this->apiKey, 'user' => $this->user, 'password' => $this->password, 'to' => $to, - 'text' => $body, - 'from' => $from + 'text' => $message->getBody(), + 'from' => $message->getFrom() ); - $query_string = $urlEncoding ? - "api_id={$this->apiKey}&user={$this->user}" . - "&password={$this->password}&to={$to}&text={$body}&from={$from}" : - http_build_query($params); + + // BC + if ($utf8decode) { + $params['text'] = utf8_decode($params['text']); + } + $this->getClient()->get( - $this->endpoint . '/http/sendmsg?'.$query_string, + $this->endpoint . '/http/sendmsg?'.http_build_query($params), array() ); } From 329f7f4303d3f2dd4cb1ed63673748b50656ade5 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Apr 2015 09:36:58 +0200 Subject: [PATCH 04/17] First draft for ClickatellGateway::parseResponse() --- library/Xi/Sms/Gateway/ClickatellGateway.php | 17 +++++++++++++++++ .../Sms/Tests/Gateway/ClickatellGatewayTest.php | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 5daa0b2..1109c7f 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -75,4 +75,21 @@ public function send(SmsMessage $message, $utf8decode = true) } return true; } + + public static function parseResponse($response) { + $return = array( + 'id' => null, + 'error' => null + ); + if (preg_match_all('/((ERR|ID): ([^\n]*))+/', $response, $matches)) { + for ($i = 1; $i < count($matches[0]); $i++) { + if ($matches[2][$i] === 'ERR') { + $return['error'] = $matches[3][$i]; + } elseif ($matches[2][$i] === 'ID') { + $return['id'] = $matches[3][$i]; + } + } + } + return $return; + } } diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index c85e11c..2b5b6bc 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -6,6 +6,17 @@ class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase { + /** + * @test + */ + public function parseResponse1() + { + $response = ClickatellGateway::parseResponse('ERR: 114, Cannot route message'); + $this->assertArrayHasKey('id', $response); + $this->assertArrayHasKey('error', $response); + $this->assertEquals('114, Cannot route message', $response['error']); + } + /** * @test */ From 27d004ad903efc29ab18b65bef95ca0ed539fab9 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Apr 2015 11:59:49 +0200 Subject: [PATCH 05/17] Parsing Clickatell response --- library/Xi/Sms/Gateway/ClickatellGateway.php | 53 ++++++++++++++----- .../Tests/Gateway/ClickatellGatewayTest.php | 45 +++++++++++++++- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 1109c7f..21b373c 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -10,6 +10,7 @@ namespace Xi\Sms\Gateway; use Xi\Sms\SmsMessage; +use Xi\Sms\SmsException; class ClickatellGateway extends BaseHttpRequestGateway { @@ -49,9 +50,8 @@ public function __construct( * @see GatewayInterface::send * @todo Implement a smarter method of sending (batch) * @param SmsMessage $message - * @param bool $utf8decode To ensure backwards compatibility */ - public function send(SmsMessage $message, $utf8decode = true) + public function send(SmsMessage $message) { foreach ($message->getTo() as $to) { $params = array( @@ -59,37 +59,64 @@ public function send(SmsMessage $message, $utf8decode = true) 'user' => $this->user, 'password' => $this->password, 'to' => $to, - 'text' => $message->getBody(), + 'text' => utf8_decode($message->getBody()), 'from' => $message->getFrom() ); - // BC - if ($utf8decode) { - $params['text'] = utf8_decode($params['text']); - } - - $this->getClient()->get( + $response_string = $this->getClient()->get( $this->endpoint . '/http/sendmsg?'.http_build_query($params), array() ); + $response = $this->parseResponse($response_string); + if (!empty($response['error'])) { + throw new SmsException(sprintf('Error(s): %s', var_export($response['error'], true))); + } + if (empty($response['id'])) { + throw new SmsException(sprintf('Error: No message ID returned')); + } + return $response['id']; } return true; } + /** + * Parses a Clickatell HTTP API response + * @param string $response + * @return array error messages, messages IDs, phone numbers... + * @throws SmsException + */ public static function parseResponse($response) { $return = array( 'id' => null, 'error' => null ); if (preg_match_all('/((ERR|ID): ([^\n]*))+/', $response, $matches)) { - for ($i = 1; $i < count($matches[0]); $i++) { + for ($i = 0; $i < count($matches[0]); $i++) { + $phone_number = null; + if (preg_match('/(.*)( To: ([0-9]+))$/', $matches[3][$i], $ms)) { + $message = $ms[1]; + $phone_number = $ms[3]; + } else { + $message = $matches[3][$i]; + } + if ($matches[2][$i] === 'ERR') { - $return['error'] = $matches[3][$i]; + if ($phone_number) { + $return['error'][$phone_number] = $message; + } else { + $return['error'] = $message; + } } elseif ($matches[2][$i] === 'ID') { - $return['id'] = $matches[3][$i]; + if ($phone_number) { + $return['id'][$phone_number] = $message; + } else { + $return['id'] = $message; + } } } + return $return; + } else { + throw new SmsException(sprintf('Could not parse response: %s', $response)); } - return $return; } } diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 2b5b6bc..8d23230 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -2,18 +2,59 @@ namespace Xi\Sms\Tests\Gateway; +use Xi\Sms\SmsMessage; +use Xi\Sms\SmsService; +use Xi\Sms\SmsException; use Xi\Sms\Gateway\ClickatellGateway; +use Buzz\Message\Response; class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase { + + /** + * @test + */ + public function parseResponse5() + { + $response = ClickatellGateway::parseResponse("ERR: 114, Cannot route message To: 49123456789\nERR: 567, Bla bla bla To: 4987654321"); + $this->assertEquals('114, Cannot route message', $response['error']['49123456789']); + $this->assertEquals('567, Bla bla bla', $response['error']['4987654321']); + } + + /** + * @test + */ + public function parseResponse4() + { + $response = ClickatellGateway::parseResponse("ID: CE07B3BFEFF35F4E2667B3A47116FDD2 To: 49123456789\nID: QWERTYUIO123456789ASDFGHJK To: 4987654321"); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['id']['49123456789']); + $this->assertEquals('QWERTYUIO123456789ASDFGHJK', $response['id']['4987654321']); + } + + /** + * @test + */ + public function parseResponse3() + { + $this->setExpectedException('Xi\Sms\SmsException'); + $response = ClickatellGateway::parseResponse('foo bar'); + } + + /** + * @test + */ + public function parseResponse2() + { + $response = ClickatellGateway::parseResponse('ID: CE07B3BFEFF35F4E2667B3A47116FDD2'); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['id']); + } + /** * @test */ public function parseResponse1() { $response = ClickatellGateway::parseResponse('ERR: 114, Cannot route message'); - $this->assertArrayHasKey('id', $response); - $this->assertArrayHasKey('error', $response); $this->assertEquals('114, Cannot route message', $response['error']); } From 62e17f4ef4fce23b8ee70190cd51c3685cf774c9 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Apr 2015 12:25:51 +0200 Subject: [PATCH 06/17] Clickatell: bulk sending in one API call --- library/Xi/Sms/Gateway/ClickatellGateway.php | 49 ++++++++++--------- .../Tests/Gateway/ClickatellGatewayTest.php | 38 +++++++++++++- 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 21b373c..b30668b 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -48,35 +48,36 @@ public function __construct( /** * @see GatewayInterface::send - * @todo Implement a smarter method of sending (batch) * @param SmsMessage $message */ public function send(SmsMessage $message) { - foreach ($message->getTo() as $to) { - $params = array( - 'api_id' => $this->apiKey, - 'user' => $this->user, - 'password' => $this->password, - 'to' => $to, - 'text' => utf8_decode($message->getBody()), - 'from' => $message->getFrom() - ); + if (count($message->getTo()) > 100) { + // @todo chunk $message->getTo() by 100 + throw new SmsException('Error: sending through to 100+ addresses is not yet implemented'); + } - $response_string = $this->getClient()->get( - $this->endpoint . '/http/sendmsg?'.http_build_query($params), - array() - ); - $response = $this->parseResponse($response_string); - if (!empty($response['error'])) { - throw new SmsException(sprintf('Error(s): %s', var_export($response['error'], true))); - } - if (empty($response['id'])) { - throw new SmsException(sprintf('Error: No message ID returned')); - } - return $response['id']; - } - return true; + $params = array( + 'api_id' => $this->apiKey, + 'user' => $this->user, + 'password' => $this->password, + 'to' => implode(',', $message->getTo()), + 'text' => utf8_decode($message->getBody()), + 'from' => $message->getFrom() + ); + + $response_string = $this->getClient()->get( + $this->endpoint . '/http/sendmsg?'.http_build_query($params), + array() + ); + $response = $this->parseResponse($response_string); + if (!empty($response['error'])) { + throw new SmsException(sprintf('Error(s): %s', var_export($response['error'], true))); + } + if (empty($response['id'])) { + throw new SmsException('Error: No message ID returned'); + } + return $response['id']; } /** diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 8d23230..4abe871 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -10,6 +10,39 @@ class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase { + /** + * @test + */ + public function sendMultiple() + { + $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); + + $browser = $this->getMockBuilder('Buzz\Browser') + ->disableOriginalConstructor() + ->getMock(); + + $gateway->setClient($browser); + + $browser + ->expects($this->once()) + ->method('get') + ->with( + $this->callback(function($actual) { + $url = parse_url($actual); + parse_str($url['query'], $query); + return $query['to'] === '358503028030,49123456789'; + }), + $this->isType('array') + ) + ->will($this->returnValue("ID: QWERTYUI12345678 To: 358503028030\nID: 12345678QWERTYUI To: 49123456789")); + + $message = new \Xi\Sms\SmsMessage( + 'Pekkis tassa lussuttaa.', + '358503028030', + array('358503028030', '49123456789') + ); + $ret = $gateway->send($message); + } /** * @test @@ -90,7 +123,8 @@ public function sendsRequest() $query['from'] === '358503028030'; }), array() - ); + ) + ->will($this->returnValue('ID: QWERTYUI12345678')); $message = new \Xi\Sms\SmsMessage( 'Pekkis tassa lussuttaa.', @@ -99,6 +133,6 @@ public function sendsRequest() ); $ret = $gateway->send($message); - $this->assertTrue($ret); + $this->assertEquals('QWERTYUI12345678', $ret); } } From 0d3832d50036b508f935c1b2f02242fcfe66b764 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Apr 2015 12:52:47 +0200 Subject: [PATCH 07/17] Clickatell: bulk sending in one API call, even for more than 100 addressees --- library/Xi/Sms/Gateway/ClickatellGateway.php | 11 ++++- .../Tests/Gateway/ClickatellGatewayTest.php | 42 ++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index b30668b..91f243f 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -52,9 +52,16 @@ public function __construct( */ public function send(SmsMessage $message) { + // Sending is limited to max 100 addressees if (count($message->getTo()) > 100) { - // @todo chunk $message->getTo() by 100 - throw new SmsException('Error: sending through to 100+ addresses is not yet implemented'); + $return = array(); + foreach (array_chunk($message->getTo(), 100) as $tos) { + $message_alt = clone $message; + $message_alt->setTo($tos); + $response = $this->send($message_alt); + $return = array_merge($return, $response); + } + return $return; } $params = array( diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 4abe871..63199a2 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -13,7 +13,47 @@ class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase /** * @test */ - public function sendMultiple() + public function sendMultiple2() + { + $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); + + $browser = $this->getMockBuilder('Buzz\Browser') + ->disableOriginalConstructor() + ->getMock(); + + $gateway->setClient($browser); + + $addressees = array(); + for ($i = 0; $i < 345; $i++) { + $addressees[] = rand(); + } + + $browser + ->expects($this->exactly(4)) + ->method('get') + ->with( + $this->callback(function($actual) { + $url = parse_url($actual); + parse_str($url['query'], $query); + return count(explode(',', $query['to'])) === 100 || + count(explode(',', $query['to'])) === 45; + }), + $this->isType('array') + ) + ->will($this->returnValue("ID: QWERTYUI12345678 To: 358503028030\nID: 12345678QWERTYUI To: 49123456789")); + + $message = new \Xi\Sms\SmsMessage( + 'Pekkis tassa lussuttaa.', + '358503028030', + $addressees + ); + $ret = $gateway->send($message); + } + + /** + * @test + */ + public function sendMultiple1() { $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); From 08337357bb183a25f58fde04435a0ed4ef747cd6 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Apr 2015 18:31:29 +0200 Subject: [PATCH 08/17] Renamed composer package to be able to register package --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 00e3ece..e248802 100755 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "xi/sms", + "name": "felixmaier1989/xi-sms", "type": "library", "description": "Short messaging for PHP 5.3", "keywords": ["SMS"], From 8f880d3f653eff72423ef078114c6d3e52e08563 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Wed, 6 May 2015 09:46:55 +0200 Subject: [PATCH 09/17] Changed parsing of response string --- library/Xi/Sms/Gateway/ClickatellGateway.php | 17 +++++------------ .../Sms/Tests/Gateway/ClickatellGatewayTest.php | 10 +++++----- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 91f243f..76e7f12 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -108,18 +108,11 @@ public static function parseResponse($response) { $message = $matches[3][$i]; } - if ($matches[2][$i] === 'ERR') { - if ($phone_number) { - $return['error'][$phone_number] = $message; - } else { - $return['error'] = $message; - } - } elseif ($matches[2][$i] === 'ID') { - if ($phone_number) { - $return['id'][$phone_number] = $message; - } else { - $return['id'] = $message; - } + $key = $matches[2][$i]; + if ($phone_number) { + $return[$key][$phone_number] = $message; + } else { + $return[$key] = $message; } } return $return; diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 63199a2..c636bd9 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -91,7 +91,7 @@ public function parseResponse5() { $response = ClickatellGateway::parseResponse("ERR: 114, Cannot route message To: 49123456789\nERR: 567, Bla bla bla To: 4987654321"); $this->assertEquals('114, Cannot route message', $response['error']['49123456789']); - $this->assertEquals('567, Bla bla bla', $response['error']['4987654321']); + $this->assertEquals('567, Bla bla bla', $response['ERR']['4987654321']); } /** @@ -100,8 +100,8 @@ public function parseResponse5() public function parseResponse4() { $response = ClickatellGateway::parseResponse("ID: CE07B3BFEFF35F4E2667B3A47116FDD2 To: 49123456789\nID: QWERTYUIO123456789ASDFGHJK To: 4987654321"); - $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['id']['49123456789']); - $this->assertEquals('QWERTYUIO123456789ASDFGHJK', $response['id']['4987654321']); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['ID']['49123456789']); + $this->assertEquals('QWERTYUIO123456789ASDFGHJK', $response['ID']['4987654321']); } /** @@ -119,7 +119,7 @@ public function parseResponse3() public function parseResponse2() { $response = ClickatellGateway::parseResponse('ID: CE07B3BFEFF35F4E2667B3A47116FDD2'); - $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['id']); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['ID']); } /** @@ -128,7 +128,7 @@ public function parseResponse2() public function parseResponse1() { $response = ClickatellGateway::parseResponse('ERR: 114, Cannot route message'); - $this->assertEquals('114, Cannot route message', $response['error']); + $this->assertEquals('114, Cannot route message', $response['ERR']); } /** From 66a5e808cbe58a464658030ff3799a9ab8d0eebc Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Wed, 6 May 2015 10:01:42 +0200 Subject: [PATCH 10/17] Changed parsing of response string --- library/Xi/Sms/Gateway/ClickatellGateway.php | 8 ++++---- tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 76e7f12..8a1cab8 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -78,13 +78,13 @@ public function send(SmsMessage $message) array() ); $response = $this->parseResponse($response_string); - if (!empty($response['error'])) { - throw new SmsException(sprintf('Error(s): %s', var_export($response['error'], true))); + if (!empty($response['ERR'])) { + throw new SmsException(sprintf('Error(s): %s', var_export($response['ERR'], true))); } - if (empty($response['id'])) { + if (empty($response['ID'])) { throw new SmsException('Error: No message ID returned'); } - return $response['id']; + return $response['ID']; } /** diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index c636bd9..c51a80b 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -90,7 +90,7 @@ public function sendMultiple1() public function parseResponse5() { $response = ClickatellGateway::parseResponse("ERR: 114, Cannot route message To: 49123456789\nERR: 567, Bla bla bla To: 4987654321"); - $this->assertEquals('114, Cannot route message', $response['error']['49123456789']); + $this->assertEquals('114, Cannot route message', $response['ERR']['49123456789']); $this->assertEquals('567, Bla bla bla', $response['ERR']['4987654321']); } From 64cea5713a116a4d889532fae5a8c424146f85d0 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Wed, 6 May 2015 10:14:07 +0200 Subject: [PATCH 11/17] Autentication function --- library/Xi/Sms/Gateway/ClickatellGateway.php | 30 +++++++- .../Tests/Gateway/ClickatellGatewayTest.php | 77 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 8a1cab8..f88c5f4 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -46,6 +46,34 @@ public function __construct( $this->endpoint = $endpoint; } + /** + * Authentication + * @return array + * @throws SmsException + */ + public function authenticate() + { + $params = array( + 'api_id' => $this->apiKey, + 'user' => $this->user, + 'password' => $this->password, + ); + + $response_string = $this->getClient()->get( + $this->endpoint . '/http/auth?'.http_build_query($params), + array() + ); + + $response = $this->parseResponse($response_string); + if (!empty($response['ERR'])) { + throw new SmsException(sprintf('Error(s): %s', var_export($response['ERR'], true))); + } + if (empty($response['OK'])) { + throw new SmsException('Error: No Session ID returned'); + } + return $response['OK']; + } + /** * @see GatewayInterface::send * @param SmsMessage $message @@ -98,7 +126,7 @@ public static function parseResponse($response) { 'id' => null, 'error' => null ); - if (preg_match_all('/((ERR|ID): ([^\n]*))+/', $response, $matches)) { + if (preg_match_all('/((ERR|ID|OK): ([^\n]*))+/', $response, $matches)) { for ($i = 0; $i < count($matches[0]); $i++) { $phone_number = null; if (preg_match('/(.*)( To: ([0-9]+))$/', $matches[3][$i], $ms)) { diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index c51a80b..1eeffaf 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -10,6 +10,83 @@ class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase { + /** + * @test + */ + public function parseResponse6() + { + $response = ClickatellGateway::parseResponse("OK: CE07B3BFEFF35F4E2667B3A47116FDD2"); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['OK']); + } + + /** + * @test + */ + public function authenticate2() + { + $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia'); + + $browser = $this->getMockBuilder('Buzz\Browser') + ->disableOriginalConstructor() + ->getMock(); + + $gateway->setClient($browser); + + $browser + ->expects($this->once()) + ->method('get') + ->with( + $this->callback(function($actual) { + $url = parse_url($actual); + parse_str($url['query'], $query); + return + $url['path'] === '/http/auth' && + $query['api_id'] === 'lussavain' && + $query['user'] === 'lussuta' && + $query['password'] === 'tussia'; + }), + array() + ) + ->will($this->returnValue('')); + + $this->setExpectedException('Xi\Sms\SmsException'); + $ret = $gateway->authenticate(); + } + + /** + * @test + */ + public function authenticate1() + { + $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); + + $browser = $this->getMockBuilder('Buzz\Browser') + ->disableOriginalConstructor() + ->getMock(); + + $gateway->setClient($browser); + + $browser + ->expects($this->once()) + ->method('get') + ->with( + $this->callback(function($actual) { + $url = parse_url($actual); + parse_str($url['query'], $query); + return + $url['path'] === '/http/auth' && + $query['api_id'] === 'lussavain' && + $query['user'] === 'lussuta' && + $query['password'] === 'tussia'; + }), + array() + ) + ->will($this->returnValue('OK: QWERTYUI12345678')); + + $ret = $gateway->authenticate(); + $this->assertEquals('QWERTYUI12345678', $ret); + } + /** * @test */ From 8719a2f2eec788d87cfb6e60a25c4301ba659bf2 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Mon, 11 May 2015 17:42:09 +0200 Subject: [PATCH 12/17] composer package name --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e248802..b822e8f 100755 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "felixmaier1989/xi-sms", + "name": "fotografde/xi-sms", "type": "library", "description": "Short messaging for PHP 5.3", "keywords": ["SMS"], From 286d83fe12c65d2cd518af527a06da7ad915b582 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Jul 2015 21:37:23 +0700 Subject: [PATCH 13/17] [clickatell] fixes after merge with master --- library/Xi/Sms/Gateway/ClickatellGateway.php | 13 +++++++------ .../Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index f88c5f4..5c91f38 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -9,6 +9,7 @@ namespace Xi\Sms\Gateway; +use Xi\Sms\RuntimeException; use Xi\Sms\SmsMessage; use Xi\Sms\SmsException; @@ -66,10 +67,10 @@ public function authenticate() $response = $this->parseResponse($response_string); if (!empty($response['ERR'])) { - throw new SmsException(sprintf('Error(s): %s', var_export($response['ERR'], true))); + throw new RuntimeException(sprintf('Error(s): %s', var_export($response['ERR'], true))); } if (empty($response['OK'])) { - throw new SmsException('Error: No Session ID returned'); + throw new RuntimeException('Error: No Session ID returned'); } return $response['OK']; } @@ -85,7 +86,7 @@ public function send(SmsMessage $message) $return = array(); foreach (array_chunk($message->getTo(), 100) as $tos) { $message_alt = clone $message; - $message_alt->setTo($tos); + $message_alt->addTo($tos); $response = $this->send($message_alt); $return = array_merge($return, $response); } @@ -107,10 +108,10 @@ public function send(SmsMessage $message) ); $response = $this->parseResponse($response_string); if (!empty($response['ERR'])) { - throw new SmsException(sprintf('Error(s): %s', var_export($response['ERR'], true))); + throw new RuntimeException(sprintf('Error(s): %s', var_export($response['ERR'], true))); } if (empty($response['ID'])) { - throw new SmsException('Error: No message ID returned'); + throw new RuntimeException('Error: No message ID returned'); } return $response['ID']; } @@ -145,7 +146,7 @@ public static function parseResponse($response) { } return $return; } else { - throw new SmsException(sprintf('Could not parse response: %s', $response)); + throw new RuntimeException(sprintf('Could not parse response: %s', $response)); } } } diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 1eeffaf..315914e 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -49,7 +49,7 @@ public function authenticate2() ) ->will($this->returnValue('')); - $this->setExpectedException('Xi\Sms\SmsException'); + $this->setExpectedException('Xi\Sms\RuntimeException'); $ret = $gateway->authenticate(); } @@ -186,7 +186,7 @@ public function parseResponse4() */ public function parseResponse3() { - $this->setExpectedException('Xi\Sms\SmsException'); + $this->setExpectedException('Xi\Sms\RuntimeException'); $response = ClickatellGateway::parseResponse('foo bar'); } From 86fb5a737674deec91a2d5636bbb54a906ad27c1 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Jul 2015 21:57:17 +0700 Subject: [PATCH 14/17] [clickatell] Fixed deletion of SmsMessage::setTo() --- library/Xi/Sms/Gateway/ClickatellGateway.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 5c91f38..592b2f0 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -85,8 +85,11 @@ public function send(SmsMessage $message) if (count($message->getTo()) > 100) { $return = array(); foreach (array_chunk($message->getTo(), 100) as $tos) { - $message_alt = clone $message; - $message_alt->addTo($tos); + $message_alt = new SmsMessage( + $message->getBody(), + $message->getFrom(), + $tos + ); $response = $this->send($message_alt); $return = array_merge($return, $response); } From b547f1fb799b9dc3f4d0ba1daf5dc067445381b3 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Jul 2015 22:03:46 +0700 Subject: [PATCH 15/17] [clickatell] Methods should not throw that many exceptions --- library/Xi/Sms/Gateway/ClickatellGateway.php | 31 ++++++------ .../Tests/Gateway/ClickatellGatewayTest.php | 47 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/library/Xi/Sms/Gateway/ClickatellGateway.php b/library/Xi/Sms/Gateway/ClickatellGateway.php index 592b2f0..5edb8f8 100644 --- a/library/Xi/Sms/Gateway/ClickatellGateway.php +++ b/library/Xi/Sms/Gateway/ClickatellGateway.php @@ -5,13 +5,14 @@ * * For copyright and license information, please view the LICENSE * file that was distributed with this source code. + * + * This class implements Clickatell API + * @link https://www.clickatell.com/downloads/http/Clickatell_HTTP.pdf */ namespace Xi\Sms\Gateway; -use Xi\Sms\RuntimeException; use Xi\Sms\SmsMessage; -use Xi\Sms\SmsException; class ClickatellGateway extends BaseHttpRequestGateway { @@ -50,7 +51,7 @@ public function __construct( /** * Authentication * @return array - * @throws SmsException + * @return bool|string Success|Session ID */ public function authenticate() { @@ -66,11 +67,14 @@ public function authenticate() ); $response = $this->parseResponse($response_string); + if ($response === false) { + return false; + } if (!empty($response['ERR'])) { - throw new RuntimeException(sprintf('Error(s): %s', var_export($response['ERR'], true))); + return false; } if (empty($response['OK'])) { - throw new RuntimeException('Error: No Session ID returned'); + return false; } return $response['OK']; } @@ -78,22 +82,21 @@ public function authenticate() /** * @see GatewayInterface::send * @param SmsMessage $message + * @return bool Success */ public function send(SmsMessage $message) { // Sending is limited to max 100 addressees if (count($message->getTo()) > 100) { - $return = array(); foreach (array_chunk($message->getTo(), 100) as $tos) { $message_alt = new SmsMessage( $message->getBody(), $message->getFrom(), $tos ); - $response = $this->send($message_alt); - $return = array_merge($return, $response); + $this->send($message_alt); } - return $return; + return true; } $params = array( @@ -111,19 +114,19 @@ public function send(SmsMessage $message) ); $response = $this->parseResponse($response_string); if (!empty($response['ERR'])) { - throw new RuntimeException(sprintf('Error(s): %s', var_export($response['ERR'], true))); + return false; } if (empty($response['ID'])) { - throw new RuntimeException('Error: No message ID returned'); + return false; } - return $response['ID']; + return true; } /** * Parses a Clickatell HTTP API response * @param string $response * @return array error messages, messages IDs, phone numbers... - * @throws SmsException + * @return bool|array Success|Parsed API response */ public static function parseResponse($response) { $return = array( @@ -149,7 +152,7 @@ public static function parseResponse($response) { } return $return; } else { - throw new RuntimeException(sprintf('Could not parse response: %s', $response)); + return false; } } } diff --git a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php index 315914e..8bcbf43 100644 --- a/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php +++ b/tests/Xi/Sms/Tests/Gateway/ClickatellGatewayTest.php @@ -13,16 +13,7 @@ class ClickatellGatewayTest extends \PHPUnit_Framework_TestCase /** * @test */ - public function parseResponse6() - { - $response = ClickatellGateway::parseResponse("OK: CE07B3BFEFF35F4E2667B3A47116FDD2"); - $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['OK']); - } - - /** - * @test - */ - public function authenticate2() + public function authenticateFail() { $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia'); @@ -49,14 +40,13 @@ public function authenticate2() ) ->will($this->returnValue('')); - $this->setExpectedException('Xi\Sms\RuntimeException'); - $ret = $gateway->authenticate(); + $this->assertFalse($gateway->authenticate()); } /** * @test */ - public function authenticate1() + public function authenticateOk() { $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); @@ -83,14 +73,13 @@ public function authenticate1() ) ->will($this->returnValue('OK: QWERTYUI12345678')); - $ret = $gateway->authenticate(); - $this->assertEquals('QWERTYUI12345678', $ret); + $this->assertEquals('QWERTYUI12345678', $gateway->authenticate()); } /** * @test */ - public function sendMultiple2() + public function sendMultipleMoreThan100() { $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); @@ -130,7 +119,7 @@ public function sendMultiple2() /** * @test */ - public function sendMultiple1() + public function sendMultiple() { $gateway = new ClickatellGateway('lussavain', 'lussuta', 'tussia', 'http://api.dr-kobros.com'); @@ -164,7 +153,7 @@ public function sendMultiple1() /** * @test */ - public function parseResponse5() + public function parseResponseMassSendingError() { $response = ClickatellGateway::parseResponse("ERR: 114, Cannot route message To: 49123456789\nERR: 567, Bla bla bla To: 4987654321"); $this->assertEquals('114, Cannot route message', $response['ERR']['49123456789']); @@ -174,7 +163,7 @@ public function parseResponse5() /** * @test */ - public function parseResponse4() + public function parseResponseMassSendingId() { $response = ClickatellGateway::parseResponse("ID: CE07B3BFEFF35F4E2667B3A47116FDD2 To: 49123456789\nID: QWERTYUIO123456789ASDFGHJK To: 4987654321"); $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['ID']['49123456789']); @@ -184,16 +173,25 @@ public function parseResponse4() /** * @test */ - public function parseResponse3() + public function parseResponseErrorParse() { - $this->setExpectedException('Xi\Sms\RuntimeException'); $response = ClickatellGateway::parseResponse('foo bar'); + $this->assertFalse($response); + } + + /** + * @test + */ + public function parseResponseOK() + { + $response = ClickatellGateway::parseResponse("OK: CE07B3BFEFF35F4E2667B3A47116FDD2"); + $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['OK']); } /** * @test */ - public function parseResponse2() + public function parseResponseId() { $response = ClickatellGateway::parseResponse('ID: CE07B3BFEFF35F4E2667B3A47116FDD2'); $this->assertEquals('CE07B3BFEFF35F4E2667B3A47116FDD2', $response['ID']); @@ -202,7 +200,7 @@ public function parseResponse2() /** * @test */ - public function parseResponse1() + public function parseResponseErrorApi() { $response = ClickatellGateway::parseResponse('ERR: 114, Cannot route message'); $this->assertEquals('114, Cannot route message', $response['ERR']); @@ -249,7 +247,6 @@ public function sendsRequest() '358503028030' ); - $ret = $gateway->send($message); - $this->assertEquals('QWERTYUI12345678', $ret); + $this->assertTrue($gateway->send($message)); } } From 6c433fa0e23383dc92b82f4a532d0a0c04ae7ed8 Mon Sep 17 00:00:00 2001 From: felixmaier1989 Date: Fri, 24 Jul 2015 22:05:07 +0700 Subject: [PATCH 16/17] [clickatell] Revert change of package name --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6bcfb4d..47f0f6c 100755 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "fotografde/xi-sms", + "name": "xi/sms", "type": "library", "description": "Short messaging for PHP 5.3", "keywords": ["SMS"], From d536d53750bc6b546be3781c9fccf32478f04f24 Mon Sep 17 00:00:00 2001 From: Marco B Date: Mon, 29 Jan 2018 20:42:51 +0100 Subject: [PATCH 17/17] update to valid licence type in composer.json (cherry picked from commit 5b639cc) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 47f0f6c..d4b3571 100755 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "description": "Short messaging for PHP 5.3", "keywords": ["SMS"], "homepage": "http://github.com/xi-project/xi-sms", - "license": "BSD", + "license": "BSD-3-Clause", "authors": [ { "name": "Mikko Forsström",