<?php

/**
 * Class sms handles the methods and properties of sending an SMS message with your websms.lu account.
 * 
 * Usage: $var = new sms ( $websms_login, $websms_password );
 * Methods:
 *     send( $to, $from, $message, $subject = null )
 *     displayOverview ( $websms_response=null ) *     
 *
 */
    
class sms {

	// websms account credentials
	private $sms_login = '';
	private $sms_password = '';

	/**
	 * @var string websms server URI
	 */
	var $sms_uri_send    = 'https://www.websms.lu/api/send';

	/**
	 * @var array The most recent parsed websms response.
	 */
	private $websms_response = '';

	// Current message
	public $to = '';
	public $from = '';
	public $text = '';
	public $message_id = '';

	// A few options
	public $ssl_verify = false; // Verify SSL before sending any message

	function __construct ( $sms_login, $sms_password) {
		$this->sms_login = $sms_login;
		$this->sms_password = $sms_password;
	}

	/**
	 * Prepare new text message.
	 */
	function send ( $to, $from, $message, $subject=null) {
	
		// Making sure strings are UTF-8 encoded
		if ( !is_numeric($from) && !mb_check_encoding($from, 'UTF-8') ) {
			trigger_error('$from needs to be a valid UTF-8 encoded string');
			return false;
		}

		if ( !mb_check_encoding($message, 'UTF-8') ) {
			trigger_error('$message needs to be a valid UTF-8 encoded string');
			return false;
		}
		
		if ( $subject && !mb_check_encoding($subject, 'UTF-8') ) {
			trigger_error('$subject needs to be a valid UTF-8 encoded string');
			return false;
		}
		
		// Make sure $from is valid
		$from = $this->validateOriginator($from);

		// URL Encode
		$from = urlencode( $from );
		$message = urlencode( $message );
		$subject = urlencode( $subject );
		
		// Send away!
		$post = array(
			'from' => $from,
			'to' => $to,
			'subject' => $subject,
			'text' => $message
		);
		return $this->sendRequest ( $post );		
	}
	
	/**
	 * Prepare and send a new message.
	 */
	private function sendRequest ( $data ) {
		// Build the post data
		$data = array_merge($data, array('username' => $this->sms_login, 'password' => $this->sms_password));
		$post = '';
		foreach($data as $k => $v){
			$post .= "&$k=$v";
		}

		// If available, use CURL
		if (function_exists('curl_version')) {

			$to_websms = curl_init( $this->sms_uri_send );
			curl_setopt( $to_websms, CURLOPT_POST, true );
			curl_setopt( $to_websms, CURLOPT_RETURNTRANSFER, true );
			curl_setopt( $to_websms, CURLOPT_POSTFIELDS, $post );

			if (!$this->ssl_verify) {
				curl_setopt( $to_websms, CURLOPT_SSL_VERIFYPEER, false);
			}

			$from_websms = curl_exec( $to_websms );
			curl_close ( $to_websms );

		} elseif (ini_get('allow_url_fopen')) {
			// No CURL available so try the awesome file_get_contents

			$opts = array('http' =>
				array(
					'method'  => 'POST',
					'header'  => 'Content-type: application/x-www-form-urlencoded',
					'content' => $post
				)
			);
			$context = stream_context_create($opts);
			$from_websms = file_get_contents($this->sms_uri_send, false, $context);

		} else {
			// No way of sending a HTTP post :(
			return false;
		}
		return $this->websmsParse( $from_websms );	 
	}


	/**
	 * Parse server response.
	 */
	private function websmsParse ( $from_websms ) {
		$response_obj = json_decode($from_websms);
		if ($response_obj) 
		{
			$this->websms_response = $response_obj;	
			return $response_obj;
		} else {
			// A malformed response
			$this->websms_response = array();
			return false;
		}		
	}


	/**
	 * Validate an originator string
	 *
	 * If the originator ('from' field) is invalid, some networks may reject the network
	 * whilst stinging you with the financial cost! While this cannot correct them, it
	 * will try its best to correctly format them.
	 */
	private function validateOriginator ( $inp){
		// Remove any invalid characters
		$ret = preg_replace('/[^a-zA-Z0-9]/', '', (string)$inp);

		if(preg_match('/[a-zA-Z]/', $inp)){
			// Alphanumeric format so make sure it's < 11 chars
			$ret = substr($ret, 0, 11);
		} else {
			// Numerical, remove any prepending '00'
			if(substr($ret, 0, 2) == '00'){
				$ret = substr($ret, 2);
				$ret = substr($ret, 0, 15);
			}
		}		
		return (string)$ret;
	}



	/**
	 * Display a brief overview of a sent message.
	 * Useful for debugging and quick-start purposes.
	 */
	public function displayOverview ( $websms_response=null ){
		$info = (!$websms_response) ? $this->websms_response : $websms_response;

		if (!$info ) 
			return 'Cannot display an overview of this response';

		if ( $info->statusCode !== "0" )		
			$status='There was an error sending your message';
		else
			$status='Your message was saved for sending';
			
		// Build the output
		$ret = $status."\n";
		$ret .= '  '.str_pad('Status', 8, ' ').'   ';
		if ( $info->statusCode === "0" ) {
			$ret .= str_pad('Message ID', 10, ' ').'   ';
			$ret .= str_pad('Parts', 10, ' ').'   ';
			$ret .= str_pad('Price', 8, ' ').'   ';
			$ret .= str_pad('Balance', 10, ' ').'   ';
		}
		$ret .= str_pad('Response', 10, ' ')."\n";		

		$ret .= '  '.str_pad($info->statusCode, 8, ' ').'   ';
		if ( $info->statusCode === "0" ) {
			$ret .= str_pad($info->message_id, 10, ' ').'   ';
			$ret .= str_pad($info->smsParts, 10, ' ').'   ';
			$ret .= str_pad($info->messagePrice, 8, ' ').'   ';
			$ret .= str_pad($info->remainingBalance, 10, ' ').'   ';
		}
		$ret .= str_pad($info->statusText, 10, ' ')."\n";		

		return $ret;
	}

}