diff --git a/bin/smsq b/bin/smsq new file mode 100755 index 0000000..4da3f3d --- /dev/null +++ b/bin/smsq @@ -0,0 +1,302 @@ +#!/usr/bin/php +add('done', 'Show done queue.' ); +$specs->add('h|help', 'Show this help message.' ); +$specs->add('v|verbose', 'Enable verbose mode.' ); +$specs->add('d|debug', 'Enable debug mode.' ); + +// Subcommands +$subcommands = array( + 'send' => array ( + 'desc' => "Send a SMS", + 'args' => array( + 'number' => 'check_phone_number', + 'text' => 'check_sms_text' + ), + ), + 'cron' => array ( + 'desc' => "Execute cron mode", + 'args' => array(), + ), + 'check-gateway' => array ( + 'desc' => "Check SMS gateway is alive", + 'args' => array(), + ), + 'info' => array ( + 'desc' => "Get information on SMS message", + 'args' => array('uuid' => 'check_uuid'), + ), + 'process' => array ( + 'desc' => "Process SMS pending message", + 'args' => array('uuid' => 'check_uuid'), + ), + 'delete' => array ( + 'desc' =>"Delete SMS message", + 'args' => array('uuid' => 'check_uuid'), + ), +); + +// Subcommands specs +$subcommandSpecs = array(); +foreach ($subcommands as $subcmd => $infos) { + $subcommandSpecs[$subcmd] = new OptionCollection; + $subcommandSpecs[$subcmd] -> add('h|help', 'Show this help message.' ); +} + +// Additionnals subcommands options +$subcommandSpecs['info'] -> add('show-frags', "Show fragments infos"); + +// Format help usage method +function usage($subcmd=false, $error=false) { + global $argv, $specs, $subcommandSpecs, $subcommands; + + if ($error) + echo "$error\n\n"; + + $printer = new ConsoleOptionPrinter(); + if ($subcmd) { + echo "Usage : ".$argv[0]."[-v|-d] $subcmd [options]"; + if (isset($subcommands[$subcmd]) && is_array($subcommands[$subcmd]['args'])) { + foreach($subcommands[$subcmd]['args'] as $arg => $check_func) { + echo " [$arg]"; + } + } + echo "\n".$printer->render($subcommandSpecs[$subcmd]); + } + else { + echo "Usage : ".$argv[0]."[options] [subcommand] [subcommand options] [subcommand args]\n".$printer->render($specs); + echo "\nSubcommands :\n"; + foreach($subcommands as $subcmd => $infos) { + echo " - $subcmd : ".$infos['desc']."\n"; + } + echo "\n Use ".$argv[0]." [subcommand] --help to get more information about subcommand\n"; + } + + if ($error) + exit(1); +} + + +// Parse application and subcommand options +$subcommandOptions = array(); +$subcommandArgs = array(); +$args = array(); +try { + // parse application options first + $parser = new ContinuousOptionParser( $specs ); + $app_options = $parser->parse( $argv ); + + // parse subcommands options + $subcommand = false; + while (! $parser->isEnd()) { + $arg = $parser->getCurrentArgument(); + if (array_key_exists($arg, $subcommandSpecs)) { + $subcommand = $arg; + $parser->advance(); + $parser->setSpecs( $subcommandSpecs[$subcommand] ); + $subcommandArgs[$subcommand] = array(); + $subcommandOptions[ $subcommand ] = $parser->continueParse(); + } else { + if ($subcommand) { + $subcommandArgs[$subcommand][] = $parser->advance(); + } + else { + $args[] = $parser->advance(); + } + } + } +} catch( Exception $e ) { + echo $e->getMessage()."\n\n"; + usage(); + if ($subcommand) + usage($subcommand); + exit(1); +} + +// Set main help message and log level +if (array_key_exists('help', $app_options->keys)) { + usage(); + exit(0); +} +elseif (array_key_exists('debug', $app_options->keys)) { + $log_level='DEBUG'; + echo "App options :\n"; + var_dump($app_options); + echo "Subcommands options :\n"; + var_dump($subcommandOptions); + echo "Subcommands args :\n"; + var_dump($subcommandArgs); + echo "Arguments :\n"; + var_dump($args); +} +elseif (array_key_exists('verbose', $app_options->keys)) { + $log_level='INFO'; +} + +// Handle subcommands +if (!empty($subcommandOptions)) { + foreach($subcommandOptions as $subcmd => $subopts) { + if (array_key_exists('help', $subopts->keys)) { + usage($subcmd); + exit(0); + } + if (count($subcommands[$subcmd]['args']) != count($subcommandArgs[$subcmd])) { + usage($subcmd, "Invalid number of argument."); + } + $idx=0; + foreach($subcommands[$subcmd]['args'] as $arg => $check_func) { + if (!call_user_func($check_func, $subcommandArgs[$subcmd][$idx])) { + usage($subcmd, "Invalid $arg value"); + } + $idx++; + } + + switch($subcmd) { + case 'send': + $result = send_sms($subcommandArgs[$subcmd][0], $subcommandArgs[$subcmd][1]); + if ($result[0] == 'error') { + echo "Error sending sms : ".$result[1]."\n"; + exit(1); + } + echo "Your SMS has been registred as UUID ".$result[1].". Status : ".$result[0]."\n"; + exit(0); + break; + case 'cron': + logging('DEBUG', 'Execute cron mode'); + logging('DEBUG', 'Handle outgoing pending messages'); + if (handle_outgoing_msgs() !== True) + logging('ERROR', 'Error handling outgoing pending messages'); + exit(0); + break; + case 'check-gateway': + if ($smsgw->check_gateway()) { + echo "SMS gateway is alive.\n"; + exit(0); + } + echo "SMS gateway not responding.\n"; + exit(1); + break; + case 'info': + $uuid=$subcommandArgs[$subcmd][0]; + $msg=get_outgoing_msg($uuid); + if (!$msg) { + echo "Message $uuid not found.\n"; + exit(1); + } + echo "Message $uuid :\n"; + echo "----------------------------------------------\n"; + echo "Date : ".$msg['datetime']."\n"; + echo "Recipient : ".$msg['number']."\n"; + echo "Status : ".$msg['status']."\n"; + if ($msg['uniqueid']) + echo "Unique SMS gateway message ID : ".$msg['uniqueid']."\n"; + if ($msg['nbfrag']) + echo "Number of fragment(s) : ".$msg['nbfrag']."\n"; + echo "Last update : ".$msg['lastupdate']."\n"; + echo "\nText :\n------\n"; + echo preg_replace('/(^|\n)/',"\n ",wordwrap($msg['text'], 70, "\n", true)); + echo "\n\n"; + if ($msg['uniqueid'] && array_key_exists('show-frags', $subopts->keys)) { + $frags = get_outgoing_msg_frags($msg['uniqueid']); + if (is_array($frags)) { + echo "Fragments :\n"; + echo "-----------\n"; + foreach($frags as $frag) { + echo " Fragment ".$frag['fragid']." : ".$frag['status']."\n"; + } + } + else { + echo " Error getting message's fragments infos\n"; + exit(1); + } + } + exit(0); + break; + case 'process': + $uuid=$subcommandArgs[$subcmd][0]; + $msg=get_outgoing_msg($uuid); + if (!$msg) { + echo "Message $uuid not found.\n"; + exit(1); + } + if (handle_outgoing_msg($msg)===True) { + echo "Message push on SMS gateway\n"; + exit(0); + } + echo "An error occured sending message on SMS gateway. Please see log file for more informations.\n"; + exit(1); + break; + case 'delete': + $uuid=$subcommandArgs[$subcmd][0]; + $msg=get_outgoing_msg($uuid); + if (!$msg) { + echo "Message $uuid not found.\n"; + exit(1); + } + if (delete_outgoing_msg($msg)===True) { + echo "Message deleted.\n"; + exit(0); + } + echo "An error occured deleting message. Please see log file for more informations.\n"; + exit(1); + break; + } + } +} + +// Main command + +// Format messages queue output +function show_queue($q) { + $tbl = new Console_Table(); + $tbl->setHeaders( + array('Id', 'Date', 'Recipient', 'Status', 'Text') + ); + foreach($q as $msg) { + $tbl->addRow( + array( + $msg['uuid'], + $msg['datetime'], + $msg['number'], + $msg['status'], + (strlen($msg['text'])>40?substr($msg['text'],0,37)."...":$msg['text']) + ) + ); + } + echo $tbl->getTable(); +} + +if (array_key_exists('done', $app_options->keys)) { + $q = get_outgoing_msgs('delivered'); + if (!is_array($q)) + die("Invalid get_outgoing_msg() result !\n"); + if (empty($q)) { + echo "SMS done queue is empty.\n"; + exit(0); + } + show_queue($q); + echo count($q)." message(s) in done queue\n"; +} +else { + $q = get_smsq(); + if (!is_array($q)) + die("Invalid get_smsq() result !\n"); + if (empty($q)) { + echo "SMS queue is empty.\n"; + exit(0); + } + show_queue($q); + echo count($q)." message(s) in queue\n"; +} diff --git a/includes/db.php b/includes/db.php index 2edbb1a..d130397 100644 --- a/includes/db.php +++ b/includes/db.php @@ -94,6 +94,21 @@ function get_outgoing_msg_by_uniqueid($uniqueid) { return -1; } +function get_outgoing_msgs($status=false) { + global $fpdo; + $where=array(); + if ($status) + $where['status']=$status; + $result = $fpdo -> from('outgoing_msg') + -> where($where) + -> execute(); + + if ($result !== false) { + return $result -> fetchAll(); + } + return -1; +} + function create_outgoing_msg($number, $text) { global $fpdo; @@ -155,6 +170,44 @@ function handle_outgoing_msg($msg) { return -1; } +function handle_outgoing_msgs() { + $msgs=get_outgoing_msgs('pending'); + if (!is_array($msgs)) + return -1; + foreach($msgs as $msg) { + if (handle_outgoing_msg($msg) !== True) + return -1; + } + return True; +} + +function delete_outgoing_msg($msg) { + global $fpdo; + if (!is_array($msg)) + $msg=get_outgoing_msg($msg); + if (is_array($msg)) { + if ($msg['uniqueid']) { + $result = $fpdo -> deleteFrom('outgoing_msg_frag') + -> where('msguid', $msg['uniqueid']) + -> execute(); + if ($result === false) { + logging('ERROR', 'Error deleting fragments of message '.$msg['uuid']); + return -1; + } + } + $result = $fpdo -> deleteFrom('outgoing_msg') + -> where('uuid', $msg['uuid']) + -> execute(); + if ($result === false) { + logging('ERROR', 'Error deleting message '.$msg['uuid']); + return -1; + } + return True; + } + return -1; +} + + function get_outgoing_msg_frag($msguid, $fragid) { global $fpdo; $where=array( @@ -171,6 +224,22 @@ function get_outgoing_msg_frag($msguid, $fragid) { return -1; } +function get_outgoing_msg_frags($msguid) { + global $fpdo; + $where=array( + 'msguid' => $msguid, + ); + $result = $fpdo -> from('outgoing_msg_frag') + -> where($where) + -> orderBy('fragid') + -> execute(); + + if ($result !== false) { + return $result -> fetchAll(); + } + return -1; +} + function get_outgoing_msg_status_from_frags($msg) { if (!is_array($msg)) $msg=get_outgoing_msg($msg); diff --git a/includes/functions.php b/includes/functions.php index b2d5f7c..82319c4 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -46,6 +46,33 @@ function check_uuid($uuid) { return false; } +function send_sms($number, $text) { + $status=false; + $msg=false; + if (check_phone_number($number) && check_sms_text($text)) { + logging('INFO','New outgoing message for '.$number); + $uuid = create_outgoing_msg($number, $text); + if (check_uuid($uuid)) { + $msg=$uuid; + if(handle_outgoing_msg($uuid)===True) { + $status='pushed'; + } + else { + $status='pending'; + } + } + else { + $status='error'; + $msg='Error creating your outgoing message'; + } + } + else { + $status='error'; + $msg='Invalid parameters'; + } + return array($status, $msg); +} + /* * From LdapSaisie */ diff --git a/public_html/index.php b/public_html/index.php index 455345e..7f391aa 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -20,26 +20,14 @@ logging('DEBUG','POST Body : '.print_r($post_body,1)); $data=array(); switch($go) { case 'send_sms': - if (check_phone_number($_REQUEST['number']) && check_sms_text($_REQUEST['text'])) { - logging('INFO','New outgoing message for '.$_REQUEST['number']); - $uuid = create_outgoing_msg($_REQUEST['number'], $_REQUEST['text']); - if (check_uuid($uuid)) { - $data['uuid']=$uuid; - if(handle_outgoing_msg($uuid)===True) { - $data['status']='ok'; - } - else { - $data['status']='pending'; - } - } - else { - $data['status']='error'; - $data['msg']='Error creating your outgoing message'; - } + $result = send_sms($_REQUEST['number'], $_REQUEST['text']); + if ($result[0] == 'error') { + $data['status']='error'; + $data['msg']=$result[1]; } else { - $data['status']='error'; - $data['msg']='Invalid parameters'; + $data['status']=$result[0]; + $data['uuid']=$result[1]; } break; case 'ack':