<?php
class swd_SMS
{
/**
* =========================================================================
* SMS Class
* =========================================================================
*
* @author: Nicolas Oelgart
* @copyright: Nicolas Oelgart
* @version: Revision: 0.9
* @date: 22nd April 2007
* @last modified: 29th April 2007
* @license GPL
*
* @website: www.nicoswd.com
* @email: nico@nicoswd.com
*
* @requirements: PHP 5
*
* =========================================================================
*
* Copyright (C) 2007 Nicolas Oelgart
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* =========================================================================
*/
/**
* Your TM4B username. If you don't have one yet, register here for free:
* https://www.tm4b.com/register/
*
* @type string
*/
private
$username =
'username';
/**
* Your TM4B login password.
*
* @type string
*/
private
$password =
'password';
/**
* The SMS sender. Use your company name or whatever you want display
* to the recipient
*
* @type string
*/
private
$from =
'You';
/**
* Message route. Both Global I and Global II messaging routes are
* identical with regards to reliability, delivery speed and support
* for delivery states. More info here: http://www.tm4bhelp.com/kb/a-8.php#8
*
* @type string
*/
public
$msg_route =
'GD02';
/**
* Minimum message length. Will set an error if the messags is shorter than
* this value.
*
* @type integer
*/
public
$msg_min_length =
2;
/**
* Maximum message length. Will set an error if the messags is larger than
* this value. If the message is larger than 160 chars, it will be split into
* 2 or more messages.
*
* @type integer
*/
public
$msg_max_length =
160;
/**
* Minimum number length. Will set an error if the number is shorter than
* this value.
*
* @type integer
*/
public
$min_num_length =
8;
/**
* An array of errors that ocurred while any request.
*
* @type array
*/
public
$errors =
array();
/**
* An array with the details of the sent messages.
*
* @type array
*/
public
$sent_messages =
array();
/**
* An array with all details of failed messages.
*
* @type array
*/
public
$failed_messages =
array();
/**
* Class constructor. Takes 0 or 2 parameters. Parameter 1 being the username,
* and parameter 2 being the password, for quick login.
*
* @param string Login username
* @param string Login password
*
* @return none
*/
public
function __construct
()
{
if (func_num_args() ==
2)
{
list($this->
username,
$this->
password) =
func_get_args();
}
}
/**
* Sends the message out. The country code without the leading 00 must be
* specified in the number.
*
* @param string Recipient phone number.
* @param string Message for recipient
* @param string "From" header.
* @param string Message route. Either GD01 or GD02
*
* @return boolean
*/
public
function send
($number,
$message,
$from =
false,
$route =
false)
{
$number =
preg_replace('/\D/',
null,
$number);
if (strlen($number) <
$this->
min_num_length)
{
self::
set_error("Invalid number: {$number}");
return false;
}
// Convert message into a single line string.
$message =
preg_replace('/[\r\n\t]+/',
' ',
trim(strval($message)));
$message =
preg_replace('/\s{2,}/',
' ',
$message);
$messagelength =
strlen($message);
if ($messagelength <
$this->
msg_min_length)
{
self::
set_error('Message too short.');
return false;
}
else if ($messagelength >
$this->
msg_max_length)
{
self::
set_error('Message too long.');
return false;
}
if ($from)
{
$this->
from =
$from;
}
if ($route AND
in_array($route,
array('GD01',
'GD02')))
{
$this->
msg_route =
$route;
}
$request =
array(
'version' =>
'2.0',
'type' =>
'broadcast',
'msg' =>
$message,
'to' =>
$number,
'from' =>
$this->
from,
'route' =>
$this->
msg_route
);
$response = self::
http_request($request);
$request['delivertime'] =
time();
if (self::
is_error($response))
{
array_push($this->
failed_messages,
$request);
return false;
}
$request['messageid'] =
$response;
array_push($this->
sent_messages,
$request);
return true;
}
/**
* Receives the message status and returns an array with the status and deliver time.
*
* @param string Message ID
*
* @return array Deliver status/Deliver time
*/
public
function fetch_msg_status
($messageid)
{
$request =
array('type' =>
'check_status');
if (preg_match('/^MT[\d]{10}-\d$/',
$messageid))
{
$request['id'] =
$messageid;
}
else if (preg_match('/^[a-f0-9]{21}$/',
$messageid))
{
$request['custom'] =
$messageid;
}
else
{
self::
set_error('Invalid Message ID.');
return false;
}
$response = self::
http_request($request);
if (self::
is_error($response))
{
return false;
}
list($status,
$delivertime) =
explode('|',
$response);
list($year,
$month,
$day,
$hour,
$minute) = str_split
($delivertime,
2);
return array(
'delivered' =>
($status ==
'DELIVRD'),
'delivertime' =>
mktime($hour,
$minute,
0,
$month,
$day,
$year) // Don't we all prefer working with UNIX timestamps?
);
}
/**
* Gets the current balance of your account.
*
* @return mixed Balance on success, false on failure.
*/
public
function fetch_balance
()
{
$request =
array(
'version' =>
'2.0',
'type' =>
'check_balance'
);
$response = self::
http_request($request);
return self::
is_error($response) ?
false :
$response;
}
/**
* Checks if a specific destination is available on a message route
*
* @param string Country code
* @param string Message route
*
* @return array Availability, country, and credits needed to send SMS to this country
*/
public
function check_destination
($dest,
$route =
'GD01')
{
$request =
array(
'type' =>
'check_destination',
'dest' =>
$dest,
'route' =>
$route
);
$response = self::
http_request($request);
if (self::
is_error($response))
{
return false;
}
@
list($status,
$country,
$credits) =
explode('|',
$response);
return array(
'status' =>
($status ==
'Yes'),
'country' =>
$country,
'credits' =>
$credits
);
}
/**
* Sends the HTTP request to the server and receives the response.
* Either the cURL library needs to be installed, or allow_url_fopen
* needs to be enabled in php.ini
*
* @param array request values
*
* @return string Server response
*/
private
function http_request
($request =
array())
{
// Should never exceed the time limit, but just in case.
@
set_time_limit(0);
$request['username'] =
$this->
username;
$request['password'] =
$this->
password;
// Takes also care of the URL encoding.
$request = http_build_query
($request,
'',
'&');
if (function_exists('curl_init') AND
$ch = @curl_init
('https://www.tm4b.com/client/api/http.php'))
{
curl_setopt
($ch, CURLOPT_POST,
true);
curl_setopt
($ch, CURLOPT_POSTFIELDS,
$request);
curl_setopt
($ch, CURLOPT_RETURNTRANSFER,
true);
curl_setopt
($ch, CURLOPT_SSL_VERIFYPEER,
false);
$response = curl_exec
($ch);
curl_close
($ch);
}
else if (ini_get('allow_url_fopen'))
{
if (!
$fp = @
fsockopen('ssl://tm4b.com',
443))
{
self::
set_error('Unable to connect to host. Try again later.');
return false;
}
$header =
"POST /client/api/http.php HTTP/1.1\r\n";
$header .=
"Host: tm4b.com\r\n";
$header .=
"User-Agent: HTTP/1.1\r\n";
$header .=
"Content-Type: application/x-www-form-urlencoded\r\n";
$header .=
"Content-Length: " .
strlen($request) .
"\r\n";
$header .=
"Connection: close\r\n\r\n";
$header .=
"{$request}\r\n";
fputs($fp,
$header);
$result =
array();
while(!
feof($fp))
{
$result[] =
fgets($fp);
}
fclose($fp);
$response =
$result[9];
}
else
{
trigger_error('Server does not support HTTP(S) requests.',
E_USER_ERROR);
}
return trim($response);
}
/**
* Checks for errors in the API response and adds it to the array if there's one.
*
* @param string API response
*
* @return boolean True if error, false if not.
*/
private
function is_error
($string)
{
if (preg_match('/^error\(\d+\|([^\)]+)/',
$string,
$error))
{
self::
set_error($error[1]);
return true;
}
return false;
}
/**
* Sets the minumum and maximum message length
*
* @param integer Minimum message length. Use false to keep default
* @param integer Maximum message length.
*
* @return none
*/
public
function set_message_length
($min,
$max =
false)
{
if ($min !==
false)
{
$this->
msg_min_length =
intval($min);
}
if ($max !==
false)
{
$this->
msg_max_length =
intval($max);
}
}
/**
* Returns the number of sent messages.
*
* @return integer Number of sent messages.
*/
public
function nr_sentmessages
()
{
return sizeof($this->
sent_messages);
}
/**
* Adds an error string to the error array
*
* @param string Error string
*
* @return none
*/
private
function set_error
($error)
{
$this->
errors[] =
$error;
}
/**
* =========================================================================
* SMS Class end
* =========================================================================
* Copyright (C) 2007 by Nicolas Oelgart.
*/
}
?>