diff --git a/module/VuFind/src/VuFind/SMS/Clickatell.php b/module/VuFind/src/VuFind/SMS/Clickatell.php index 875435e68f76a2b020fd7a3b0fd3a9c4e4af0649..60cf8a2957ce5ee773c4b26fecea934fbe3b44fd 100644 --- a/module/VuFind/src/VuFind/SMS/Clickatell.php +++ b/module/VuFind/src/VuFind/SMS/Clickatell.php @@ -73,39 +73,7 @@ class Clickatell extends AbstractBase */ public function text($provider, $to, $from, $message) { - // Get API settings from config - $user = isset($this->smsConfig->Clickatell->user) - ? $this->smsConfig->Clickatell->user : null; - $password = isset($this->smsConfig->Clickatell->password) - ? $this->smsConfig->Clickatell->password : null; - $api_id = isset($this->smsConfig->Clickatell->api_id) - ? $this->smsConfig->Clickatell->api_id : null; - $url = isset($this->smsConfig->Clickatell->url) - ? trim($this->smsConfig->Clickatell->url, '?') - : "https://api.clickatell.com/http/sendmsg"; - - // Clickatell expects UCS-2 encoding: - if (!function_exists('iconv')) { - throw new MailException('Clickatell requires iconv PHP extension.'); - } - // Normalize UTF-8 if intl extension is installed: - if (class_exists('Normalizer')) { - $message = \Normalizer::normalize($message); - } - $message = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $message); - - // We need to trim to 160 bytes (note that we need to use substr and not - // mb_substr, because the limit is BYTES not CHARACTERS; this may result - // in broken multi-byte characters but it seems unavoidable): - $message = substr($message, 0, 160); - - // Add parameters to URL: - $url .= "?api_id=" . urlencode($api_id); - $url .= "&user=" . urlencode($user); - $url .= "&password=" . urlencode($password); - $url .= "&to=" . urlencode($this->filterPhoneNumber($to)); - $url .= "&text=" . urlencode($message); - + $url = $this->getApiUrl($to, $message); try { $result = $this->client->setMethod('GET')->setUri($url)->send(); } catch (\Exception $e) { @@ -134,4 +102,87 @@ class Clickatell extends AbstractBase 'Clickatell' => array('name' => 'Clickatell', 'domain' => null) ); } + + /** + * Get API username. + * + * @return string + */ + protected function getApiUsername() + { + return isset($this->smsConfig->Clickatell->user) + ? $this->smsConfig->Clickatell->user : null; + } + + /** + * Get API password. + * + * @return string + */ + protected function getApiPassword() + { + return isset($this->smsConfig->Clickatell->password) + ? $this->smsConfig->Clickatell->password : null; + } + + /** + * Get API ID. + * + * @return string + */ + protected function getApiId() + { + return isset($this->smsConfig->Clickatell->api_id) + ? $this->smsConfig->Clickatell->api_id : null; + } + + /** + * Get API URL. + * + * @param string $to The phone number at the provider + * @param string $message The message to send + * + * @return string + */ + protected function getApiUrl($to, $message) + { + // Get base URL: + $url = isset($this->smsConfig->Clickatell->url) + ? trim($this->smsConfig->Clickatell->url, '?') + : "https://api.clickatell.com/http/sendmsg"; + + // Add parameters to URL: + $url .= "?api_id=" . urlencode($this->getApiId()); + $url .= "&user=" . urlencode($this->getApiUsername()); + $url .= "&password=" . urlencode($this->getApiPassword()); + $url .= "&to=" . urlencode($this->filterPhoneNumber($to)); + $url .= "&text=" . urlencode($this->formatMessage($message)); + + return $url; + } + + /** + * Format message for texting. + * + * @param string $message Message to format + * + * @return string + */ + protected function formatMessage($message) + { + // Clickatell expects UCS-2 encoding: + if (!function_exists('iconv')) { + throw new MailException('Clickatell requires iconv PHP extension.'); + } + // Normalize UTF-8 if intl extension is installed: + if (class_exists('Normalizer')) { + $message = \Normalizer::normalize($message); + } + $message = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $message); + + // We need to trim to 160 bytes (note that we need to use substr and not + // mb_substr, because the limit is BYTES not CHARACTERS; this may result + // in broken multi-byte characters but it seems unavoidable): + return substr($message, 0, 160); + } } diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php index efedf0a00b085099e64a1ecbd9870a0780c1ad14..b4d6e223ae2a808a4992bc3eb0b9ef3c3f7498a4 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php @@ -87,6 +87,27 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase ); } + /** + * Test unexpected response + * + * @return void + * @expectedException VuFind\Exception\Mail + * @expectedExceptionMessage badbadbad + */ + public function testUnexpectedResponse() + { + $client = $this->getMockClient(); + $expectedUri = 'https://api.clickatell.com/http/sendmsg?api_id=api_id&user=user&password=password&to=1234567890&text=hello'; + $response = new \Zend\Http\Response(); + $response->setStatusCode(200); + $response->setContent('badbadbad'); + $client->expects($this->once())->method('setMethod')->with($this->equalTo('GET'))->will($this->returnValue($client)); + $client->expects($this->once())->method('setUri')->with($this->equalTo($expectedUri))->will($this->returnValue($client)); + $client->expects($this->once())->method('send')->will($this->returnValue($response)); + $obj = $this->getClickatell($client); + $obj->text('Clickatell', '1234567890', 'test@example.com', 'hello'); + } + /** * Test unsuccessful query *