diff --git a/Command/AccountBalanceCommand.php b/Command/AccountBalanceCommand.php
new file mode 100644
index 0000000..2bd3f3d
--- /dev/null
+++ b/Command/AccountBalanceCommand.php
@@ -0,0 +1,34 @@
+setName('nexmo:account:balance')
+ ->setDescription('Gets account balance')
+ ->setHelp("The nexmo:account:balance command gets Nexmo API account balance");
+ }
+
+ /**
+ * @see Command
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $account = $this->getContainer()->get('jhg_nexmo.account');
+ $balance = $account->balance();
+ $output->writeln(sprintf('Account balance: %f',$balance));
+ }
+
+}
diff --git a/Command/SmsPricingCommand.php b/Command/SmsPricingCommand.php
new file mode 100644
index 0000000..ba936d2
--- /dev/null
+++ b/Command/SmsPricingCommand.php
@@ -0,0 +1,44 @@
+setName('nexmo:sms:pricing')
+ ->setDescription('Gets sms price for given country')
+ ->setDefinition(array(
+ new InputArgument('country', InputArgument::REQUIRED, 'The country code'),
+ ))
+ ->setHelp("The nexmo:sms:pricing command gets Nexmo API SMS pricing for a given country");
+ }
+
+ /**
+ * @see Command
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $country = $input->getArgument('country');
+
+ $account = $this->getContainer()->get('jhg_nexmo.account');
+ $price = $account->smsPricing($country);
+
+ if($price===false) {
+ throw new \Exception("Country not valid");
+ } else {
+ $output->writeln(sprintf('SMS sending price for "%s": %f',$country,$price));
+ }
+ }
+
+}
diff --git a/Command/SmsSendCommand.php b/Command/SmsSendCommand.php
index ff7b734..9636508 100644
--- a/Command/SmsSendCommand.php
+++ b/Command/SmsSendCommand.php
@@ -8,15 +8,14 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
- * @author Javi Hernández Gil
+ * @author Javi Hernández
*/
class SmsSendCommand extends ContainerAwareCommand
{
/**
* @see Command
*/
- protected function configure()
- {
+ protected function configure() {
$this
->setName('nexmo:sms:send')
->setDescription('Send a SMS message')
@@ -24,10 +23,11 @@ class SmsSendCommand extends ContainerAwareCommand
new InputArgument('number', InputArgument::REQUIRED, 'The number'),
new InputArgument('fromName', InputArgument::REQUIRED, 'The name shown as origin'),
new InputArgument('message', InputArgument::REQUIRED, 'The message'),
+ new InputOption('report','r',InputOption::VALUE_OPTIONAL,'Ask for status report'),
))
->setHelp(<<nexmo:sms:send command sends a SMS message through Nexmo API
- php app/console nexmo:sms:send +34666555444 MyApp "Hello World!!"
+php app/console nexmo:sms:send +34666555444 MyApp "Hello World!!"
EOT
);
}
@@ -35,18 +35,23 @@ EOT
/**
* @see Command
*/
- protected function execute(InputInterface $input, OutputInterface $output)
- {
+ protected function execute(InputInterface $input, OutputInterface $output) {
$number = $input->getArgument('number');
$fromName = $input->getArgument('fromName');
$message = $input->getArgument('message');
-
- $sender = $this->getContainer()->get('jhg_nexmo.sms.sender');
-
- if($sender->send($number,$fromName,$message,null,0)) {
- $output->writeln(sprintf('SMS send to %u from %s: "%s"',$number,$fromName,$message));
+ $report = (int)$input->getOption('report');
+
+ $smsManager = $this->getContainer()->get('jhg_nexmo_sms');
+
+ if($response = $smsManager->sendText($number,$message,$fromName,$report)) {
+ $output->writeln(sprintf('SMS send to %s from %s: "%s"',$number,$fromName,$message));
+ $output->writeln(sprintf(' message id: %s',$response->getMessageId()));
+ $output->writeln(sprintf(' status: %s',$response->getStatus()));
+ $output->writeln(sprintf(' message price: %f',$response->getMessagePrice()));
+ $output->writeln(sprintf(' remaining balance: %f',$response->getRemainingBalance()));
+ $output->writeln(sprintf(' network: %u',$response->getNetwork()));
} else {
- $output->writeln(sprintf('There was an error sending SMS to %u from %s: "%s"',$number,$fromName,$message));
+ $output->writeln(sprintf('There was an error sending SMS to %s from %s: "%s"',$number,$fromName,$message));
}
}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 259a496..369eb3b 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -20,16 +20,28 @@ class Configuration implements ConfigurationInterface
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('jhg_nexmo');
- // Here you should define the parameters that are allowed to
- // configure your bundle. See the documentation linked above for
- // more information on that topic.
-
$rootNode
->children()
- ->scalarNode('api_key')->end()
- ->scalarNode('api_secret')->end()
- ->scalarNode('from_name')->end()
- ->booleanNode('disable_delivery')->end()
+ ->scalarNode('api_key')
+ ->isRequired()
+ ->end()
+
+ ->scalarNode('api_secret')
+ ->isRequired()
+ ->end()
+
+ ->scalarNode('from_name')
+ ->validate()
+ ->ifTrue(function ($s) {
+ return (strlen($s)>11 || strlen($s)<2) && preg_match('/^[0-9a-z]{11}$/i', $s) !== 1;
+ })
+ ->thenInvalid('Invalid from_name, only alphanumeric characters are allowed')
+ ->end()
+ ->end()
+
+ ->booleanNode('disable_delivery')
+ ->defaultFalse()
+ ->end()
->end()
;
diff --git a/DependencyInjection/JhgNexmoExtension.php b/DependencyInjection/JhgNexmoExtension.php
index d5f5b4e..893447c 100644
--- a/DependencyInjection/JhgNexmoExtension.php
+++ b/DependencyInjection/JhgNexmoExtension.php
@@ -21,35 +21,11 @@ class JhgNexmoExtension extends Extension
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
- if (!isset($config['api_key'])) {
- throw new \InvalidArgumentException('The "api_key" option must be set for JhgNexmoBundle');
- }
-
- if (!isset($config['api_secret'])) {
- throw new \InvalidArgumentException('The "api_secret" option must be set for JhgNexmoBundle');
- }
-
$container->setParameter('jhg_nexmo.api_key', $config['api_key']);
$container->setParameter('jhg_nexmo.api_secret', $config['api_secret']);
-
- if(isset($config['disable_delivery'])) {
- $container->setParameter('jhg_nexmo.disable_delivery', $config['disable_delivery']);
- }
-
- if(isset($config['from_name'])) {
- if (strlen($config['from_name'])>11) {
- throw new \InvalidArgumentException('The "jhg_nexmo.from_name" option can not be larger than 11 characters');
- }
-
- if (!preg_match('/^[0-9a-z]{11}$/i', $config['from_name'])) {
- throw new \InvalidArgumentException('The "jhg_nexmo.from_name" option only have alphanumeric characters');
- }
-
- $container->setParameter('jhg_nexmo.from_name', $config['from_name']);
- } else {
- $container->setParameter('jhg_nexmo.from_name', 'MyAppName');
- }
-
+ $container->setParameter('jhg_nexmo.disable_delivery', $config['disable_delivery']);
+ $container->setParameter('jhg_nexmo.from_name', $config['from_name']);
+
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
diff --git a/JhgNexmoBundle.php b/JhgNexmoBundle.php
index 89fafaa..df93148 100644
--- a/JhgNexmoBundle.php
+++ b/JhgNexmoBundle.php
@@ -5,7 +5,7 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Bundle.
- * @author Javi Hernández Gil
+ * @author Javi Hernández
*/
class JhgNexmoBundle extends Bundle
{
diff --git a/Managers/AccountManager.php b/Managers/AccountManager.php
new file mode 100644
index 0000000..a0490e4
--- /dev/null
+++ b/Managers/AccountManager.php
@@ -0,0 +1,87 @@
+nexmoClient = $nexmoClient;
+ }
+
+ /**
+ * @return bool|float - account balance | false on fail
+ */
+ public function balance() {
+ $response = $this->nexmoClient->accountBalance();
+ return floatval($response['value']);
+ }
+
+ /**
+ * @param $country
+ * @return bool|float - sms pricing | false on fail
+ */
+ public function smsPricing($country) {
+ $response = $this->nexmoClient->accountSmsPrice($country);
+ return floatval($response['mt']);
+ }
+
+
+ /**
+ * @todo Implement getCountryDialingCode method
+ * @param $country_code
+ * @throws \Exception
+ */
+ public function getCountryDialingCode ($country_code) {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ /**
+ * @todo Implement numbersList method
+ * @throws \Exception
+ */
+ public function numbersList () {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ /**
+ * @todo Implement numbersSearch method
+ * @param $country_code
+ * @param $pattern
+ * @throws \Exception
+ */
+ public function numbersSearch ($country_code, $pattern) {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ /**
+ * @todo Implement numbersBuy method
+ * @param $country_code
+ * @param $msisdn
+ * @throws \Exception
+ */
+ public function numbersBuy ($country_code, $msisdn) {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ /**
+ * @todo Implement numbersCancel method
+ * @throws \Exception
+ */
+ public function numbersCancel() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+}
\ No newline at end of file
diff --git a/Managers/NumberManager.php b/Managers/NumberManager.php
new file mode 100644
index 0000000..186eb8d
--- /dev/null
+++ b/Managers/NumberManager.php
@@ -0,0 +1,40 @@
+nexmoClient = $nexmoClient;
+ }
+
+ public function search() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function buy() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function cancel() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function update() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+}
\ No newline at end of file
diff --git a/Managers/SmsManager.php b/Managers/SmsManager.php
new file mode 100644
index 0000000..2ae3152
--- /dev/null
+++ b/Managers/SmsManager.php
@@ -0,0 +1,67 @@
+nexmoClient = $nexmoClient;
+ $this->defaultFromName = $defaultFromName;
+ }
+
+ /**
+ * @param string $number
+ * @param string $message
+ * @param null|string $fromName
+ * @param int $status_report_req
+ * @return mixed
+ */
+ public function sendText($number,$message,$fromName=null,$status_report_req=0) {
+ $fromName = $fromName!==null ? $fromName : $this->defaultFromName;
+ $number = PhoneNumber::prefixFilter($number);
+ $response = $this->nexmoClient->sendTextMessage($fromName,$number,$message,$status_report_req);
+ return SmsSendResponse::createFromResponse($response);
+ }
+
+ public function sendBinary() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function sendWapPush() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function searchMessage() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function searchMessages() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+
+ public function searchRejections() {
+ throw new \Exception(__METHOD__.' not yet implemented');
+ }
+}
\ No newline at end of file
diff --git a/Model/Sms.php b/Model/Sms.php
new file mode 100644
index 0000000..87ebb0e
--- /dev/null
+++ b/Model/Sms.php
@@ -0,0 +1,11 @@
+setTo($response['to']);
+ $smsSendResponse->setMessageId($response['message-id']);
+ $smsSendResponse->setStatus((int)$response['status']);
+ $smsSendResponse->setRemainingBalance(floatval($response['remaining-balance']));
+ $smsSendResponse->setMessagePrice(floatval($response['message-price']));
+ $smsSendResponse->setNetwork((int)$response['network']);
+
+ return $smsSendResponse;
+ }
+
+
+
+ /**
+ * @param string $messageId
+ */
+ public function setMessageId($messageId)
+ {
+ $this->messageId = $messageId;
+ }
+
+ /**
+ * @return string
+ */
+ public function getMessageId()
+ {
+ return $this->messageId;
+ }
+
+ /**
+ * @param float $messagePrice
+ */
+ public function setMessagePrice($messagePrice)
+ {
+ $this->messagePrice = $messagePrice;
+ }
+
+ /**
+ * @return float
+ */
+ public function getMessagePrice()
+ {
+ return $this->messagePrice;
+ }
+
+ /**
+ * @param int $network
+ */
+ public function setNetwork($network)
+ {
+ $this->network = $network;
+ }
+
+ /**
+ * @return int
+ */
+ public function getNetwork()
+ {
+ return $this->network;
+ }
+
+ /**
+ * @param float $remainingBalance
+ */
+ public function setRemainingBalance($remainingBalance)
+ {
+ $this->remainingBalance = $remainingBalance;
+ }
+
+ /**
+ * @return float
+ */
+ public function getRemainingBalance()
+ {
+ return $this->remainingBalance;
+ }
+
+ /**
+ * @param int $status
+ */
+ public function setStatus($status)
+ {
+ $this->status = $status;
+ }
+
+ /**
+ * @return int
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ /**
+ * @param string $to
+ */
+ public function setTo($to)
+ {
+ $this->to = $to;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTo()
+ {
+ return $this->to;
+ }
+
+
+}
\ No newline at end of file
diff --git a/NexmoClient/NexmoClient.php b/NexmoClient/NexmoClient.php
new file mode 100644
index 0000000..9012c53
--- /dev/null
+++ b/NexmoClient/NexmoClient.php
@@ -0,0 +1,107 @@
+rest_url = 'https://rest.nexmo.com';
+ $this->api_key = $api_key;
+ $this->api_secret = $api_secret;
+ $this->api_method = $api_method;
+ }
+
+ /**
+ * @param $url
+ * @param array $params
+ * @return array
+ */
+ protected function jsonRequest($url,$params=array()) {
+
+ $params['api_key'] = $this->api_key;
+ $params['api_secret'] = $this->api_secret;
+
+ $request_url = $this->rest_url.'/'.trim($url,'/').'?'.http_build_query($params);
+
+ $request = curl_init($request_url);
+ curl_setopt($request,CURLOPT_RETURNTRANSFER,true );
+ curl_setopt($request,CURLOPT_SSL_VERIFYPEER,false);
+ curl_setopt($request, CURLOPT_HTTPHEADER,array('Accept: application/json'));
+
+ $response = curl_exec($request);
+ $curl_info = curl_getinfo($request);
+ $http_response_code = (int)$curl_info['http_code'];
+ curl_close($request);
+
+ switch($http_response_code) {
+ case 200:
+ return json_decode($response,true);
+ }
+ }
+
+
+ /**
+ * @example {"autoReload":false,"value":0.2}
+ * @return array
+ */
+ public function accountBalance() {
+ return $this->jsonRequest('/account/get-balance');
+ }
+
+
+ /**
+ * @param $country
+ * @return array[country=ES,mt=0.060000,name=Spain,prefix=34]
+ */
+ public function accountSmsPrice($country) {
+ return $this->jsonRequest('/account/get-pricing/outbound',array('country'=>$country));
+ }
+
+ /**
+ * @param string $fromName
+ * @param string $toNumber
+ * @param string $text
+ * @param int $status_report_req
+ * @return array
+ * @throws \Exception
+ */
+ public function sendTextMessage($fromName,$toNumber,$text,$status_report_req=0) {
+ $params = array(
+ 'from'=>$fromName,
+ 'to'=>$toNumber,
+ 'text'=>$text,
+ 'status-report-req'=>$status_report_req,
+ );
+ $response = $this->jsonRequest('/sms/json',$params);
+
+ if((int)$response['messages'][0]['status']!=0) {
+ throw new \Exception($response['messages'][0]['error-text']);
+ }
+
+ return $response['messages'][0];
+ }
+}
\ No newline at end of file
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 2ffbdf8..6d013a6 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -1,10 +1,16 @@
-parameters:
-
services:
- jhg_nexmo.sms_message:
- class: Nexmo\NexmoMessage
+ jhg_nexmo_client:
+ class: Jhg\NexmoBundle\NexmoClient\NexmoClient
arguments: ["%jhg_nexmo.api_key%","%jhg_nexmo.api_secret%"]
- jhg_nexmo.sms.sender:
- class: Jhg\NexmoBundle\Sender\SmsSender
- arguments: [@service_container,@jhg_nexmo.sms_message]
\ No newline at end of file
+ jhg_nexmo_account:
+ class: Jhg\NexmoBundle\Managers\AccountManager
+ arguments: [@jhg_nexmo_client]
+
+ jhg_nexmo_sms:
+ class: Jhg\NexmoBundle\Managers\SmsManager
+ arguments: [@jhg_nexmo_client,"%jhg_nexmo.from_name%"]
+
+ jhg_nexmo_number:
+ class: Jhg\NexmoBundle\Managers\NumberManager
+ arguments: [@jhg_nexmo_client]
\ No newline at end of file
diff --git a/Sender/SmsSender.php b/Sender/SmsSender.php
deleted file mode 100644
index db68353..0000000
--- a/Sender/SmsSender.php
+++ /dev/null
@@ -1,49 +0,0 @@
-container = $container;
- $this->nexmoMessage = $nexmoMessage;
- }
-
- /**
- * @param $number
- * @param null $fromName
- * @param $message
- * @param null $unicode
- * @param int $status_report_req
- * @return array|bool|\Nexmo\stdClass
- */
- public function send($number,$fromName=null,$message,$unicode=null, $status_report_req=0) {
-
- if($fromName===null)
- $fromName = $this->container->getParameter('jhg_nexmo.from_name');
-
- return $this->nexmoMessage->sendText($number,$fromName,$message,$unicode,$status_report_req);
- }
-}
diff --git a/Tests/Command/SmsSendCommandTest.php b/Tests/Command/SmsSendCommandTest.php
deleted file mode 100644
index 8986380..0000000
--- a/Tests/Command/SmsSendCommandTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-add(new SmsSendCommand());
-
- $command = $application->find('nexmo:sms:send');
- $commandTester = new CommandTester($command);
-
- try {
- $commandTester->execute(array());
- $this->assertTrue(false);
- } catch(\RuntimeException $e) {
- $this->assertEquals('Not enough arguments.',$e->getMessage());
- }
-
- $arguments = array(
- 'command' => 'nexmo:sms:send',
- 'number' => 'demo:greet',
- 'fromName' => 'Fabien',
- 'message' => '',
- );
-
- $input = new ArrayInput($arguments);
- $returnCode = $command->run($input, $output);
-
- $commandTester->execute(array("+34666555444","MyApp","Hello World!!"));
-
-// $this->assertRegExp('/.../', $commandTester->getDisplay());
- }
-}
\ No newline at end of file
diff --git a/Tests/Sender/SmsSenderTest.php b/Tests/Sender/SmsSenderTest.php
deleted file mode 100644
index 41462e7..0000000
--- a/Tests/Sender/SmsSenderTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-'asdfghjkl',
- 'jhg_nexmo.api_secret'=>'1234567890',
- 'jhg_nexmo.from_name'=>'From Name',
- ),
- '+34666555444',
- 'From Name',
- 'Message',
- null,
- 0,
- array(),
- ),
- );
- }
-
-
- /**
- * @dataProvider getSendData
- */
- public function testSend($containerParameters,$number,$fromName,$message,$unicode,$status_report_req,$sendRequestReturnData) {
- $containerMock = $this->getMock('Symfony\Component\DependencyInjection\Container');
-
- $nexmoMessageMock = $this->getMock('Nexmo\NexmoMessage',array(),array($containerMock,$containerParameters['jhg_nexmo.api_key'],$containerParameters['jhg_nexmo.api_secret']));
- $nexmoMessageMock->expects($this->any())
- ->method('sendRequest')
- ->will($this->returnValue($sendRequestReturnData));
-
-
- $sender = new SmsSender($containerMock,$nexmoMessageMock);
- $result = $sender->send($number,$fromName,$message,$unicode,$status_report_req);
-
- $this->assertEquals(null,$result);
- }
-}
\ No newline at end of file
diff --git a/Utils/PhoneNumber.php b/Utils/PhoneNumber.php
new file mode 100644
index 0000000..518f982
--- /dev/null
+++ b/Utils/PhoneNumber.php
@@ -0,0 +1,17 @@
+