<?php
/* SMS Pilot.Class API/PHP v1.8.5
 * SEE: http://www.smspilot.ru/apikey.php

 Example (send):
 	require_once('smspilot.class.php');
	$sms = new SMSPilot( '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J' );
	$sms->send( '79087964781', 'Привет, разработчик!');

 Example 2 (replace sender + send):
 	require_once('smspilot.class.php');
	$sms = new SMSPilot( '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J', 'WINDOWS-1251' );
 	if ($sms->send('79121234512','Завтра контрольная!', 'SCHOOL_N2')) {
		echo 'Сообщение успешно отправлено<br />';
		echo 'Цена='.$sms->cost.' кредитов<br />';
		echo 'Баланс='.$sms->balance.' кредитов<br />';
	} else
		echo 'Ошибка! '.$sms->error;

  Example 3 (send + get sms status):
 	require_once('smspilot.class.php');
	$sms = new SMSPilot( '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J' );
	$sms->send('79087964781', 'Novy zakaz http://www.smspilot.ru!');
	print_r( $sms->status[0] ); // Array ( [id] => 94 [phone] => 79087964781 [zone] => 2 [status] => 0 )
	print_r( $sms->statusByPhone( '79087964781' ) ); // // Array ( [id] => 94 [phone] => 79087964781 [zone] => 2 [status] => 0 )

  Example 4: (указываем что наша кодировка Windows-1251, проверяем автозамену 89.. получателя)
  	require_once('smspilot.class.php');
	$sms = new SMSPilot('4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J','WINDOWS-1251');
	$status = $sms->send('89087964781', 'Сообщение в Windows-1251 кодировке!', '89088038965');
	print_r( $status )

	
	Array
(
    [0] => Array
        (
            [id] => 129
            [phone] => 79087964781
            [zone] => 2
            [status] => 0
        )
)

	
  Example 5 (check status):
 	require_once('smspilot.class.php');
	$sms = new SMSPilot( '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J' ); 
	$status = $sms->check( array( 94,95) );
	print_r( $status );

	
	Array
(
    [0] => Array
        (
            [id] => 94
            [phone] => 79087964781
            [zone] => 2
            [status] => 2
        )

    [1] => Array
        (
            [id] => 95
            [phone] => 79087964781
            [zone] => 2
            [status] => -1
        )

) 
	
  Example 6 ( balance  ):
 	require_once('smspilot.class.php');
	$sms = new SMSPilot( '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J' );
	echo $sms->balance(); // 23004

*/
class SMSPilot {
	public $api = 'http://smspilot.ru/api.php';
	public $apikey = '4J410J321K6S7E68FWU08694X5683DI0F1Z858L6E832TQLQ5RA30DOVWP3XHF2J';
	public $charset = 'UTF-8';
//	public $use_ssl = false; //removed in 1.8.3, see $sms->api property
	public $to;
	public $text;
	public $from = false;
	public $send_datetime = false; // 1.8.4
	public $error;
	public $success;
	public $status; // new in 1.7
	public $info;
	public $cost; // new in 1.8
	public $balance; // new in 1.8
	// public $limit; // removed 1.8
	
	public function __construct( $apikey = false,  $charset = false, $from = false ) {
		
		if ($apikey)
			$this->apikey = $apikey;
		else if (defined('SMSPILOT_APIKEY'))
			$this->apikey = SMSPILOT_APIKEY;
			
		if ($charset)
			$this->charset = $charset;
		else if (defined('SMSPILOT_CHARSET'))	
			$this->charset = SMSPILOT_CHARSET;

		if ($from)
			$this->from = $from;
		else if (defined('SMSPILOT_FROM'))
			$this->from = SMSPILOT_FROM;
		
		if (defined('SMSPILOT_API'))
			$this->api = SMSPILOT_API;
		
	}
	// send sms via smspilot.ru
	public function send( $to = false, $text = false, $from = false, $send_datetime = false ) {
		
		if ($to)
			$this->to = $to;
				
		if ( $text )
			$this->text = $text;

		if ( $from )
			$this->from = $from;
			
		if ( $send_datetime )
			$this->send_datetime = $send_datetime;
			
		$this->error = false;
		$this->success = false;
		$this->status = array();
		
		$text = ($this->charset != 'UTF-8') ? mb_convert_encoding($this->text, 'utf-8', $this->charset ) : $this->text;	
		
		$result = $this->http_post($this->api, array(
			'send' => $text,
			'to' => ((is_array($this->to)) ? implode(',', $this->to) : $this->to),
			'from' => $this->from,
			'send_datetime' => $this->send_datetime,
			'apikey' => $this->apikey,
		));
		
		//echo $result;
		
		if ($result) {
			if (substr($result,0,6) == 'ERROR=') {
				$this->error = substr($result,6);
				return false;
			} elseif (substr($result,0,8) == 'SUCCESS=') {
				
				$this->success = substr($result,8,($p = strpos($result,"\n"))-8);
				
				if (preg_match('~(\d+)/(\d+)~', $this->success, $matches )) {
					$this->cost = $matches[1]; // new in 1.8
					$this->balance = $matches[2]; // new in 1.8
				}

				$status_csv = substr( $result, $p+1 );
				//status
				$status_csv = explode( "\n", $status_csv );
				foreach( $status_csv as $line ) {
					$s = explode(',', $line);
					$this->status[] = array(
						'id' => $s[0],
						'phone' => $s[1],
						'zone' => $s[2],
						'status' => $s[3]
					);
				}				
				return $this->status;
			} else {
				$this->error = 'UNKNOWN RESPONSE';
				return false;
			}
		} else {
			$this->error = 'CONNECTION ERROR';
			return false;
		}
	}
	// check status by sms id or ids
	public function check( $ids ) { // new in 1.7
	
		if (is_array($ids))
			$ids = implode(',', $ids);
			
		$this->error = false;
		$this->success = false;
		$this->status = array();
		
		$result = $this->http_post($this->api, array(
			'check' => $ids,
			'apikey' => $this->apikey
		));
		
		if ($result) {
			
			if (substr($result,0,6) == 'ERROR=') {
				
				$this->error = substr($result,6);
				return false;
				
			} else {
				
				$status_csv = $result;
				//status
				$status_csv = explode( "\n", $status_csv );
				foreach( $status_csv as $line ) {
					$s = explode(',', $line);
					$this->status[] = array(
						'id' => $s[0],
						'phone' => $s[1],
						'zone' => $s[2],
						'status' => $s[3]
					);
				}
				return $this->status;

			}
		} else {
			$this->error = 'CONNECTION ERROR';
			return false;
		}
	}
	// helper to find status by phone
	public function statusByPhone( $phone ) {
		
		foreach( $this->status as $s )
			if ( $s['phone'] == $phone )
				return $s;

		return false;
	}
	public function balance( $currency = 'sms' ) {
		
		$result = $this->http_post($this->api, array(
			'balance' => $currency,
			'apikey' => $this->apikey
		));

		if (strlen($result)) {
			if (substr($result,0,6) == 'ERROR=') {
				$this->error = substr($result, 6);
				return false;				
			} else
				return $this->balance = $result;
		} else {
			$this->error = 'CONNECTION ERROR';
			return false;				
		}

	}
	// apikey info
	public function info() {
		
		$result = $this->http_post( $this->api, array(
			'apikey' => $this->apikey
		));

		if ($result) {
			if (substr($result,0,6) == 'ERROR=') {
				$this->error = substr($result, 6);
				return false;
				
			} elseif (substr($result,0,8) == 'SUCCESS=') {
				$s = substr($result,8, ($p = strpos($result,"\n"))-8);
				
				$this->success = $s;
				
				$lines = explode("\n",substr($result,$p));
				
				$this->info = array();
				foreach( $lines as $line )
					if ($p = strpos($line,'='))
						$this->info[ substr($line,0,$p) ] = substr($line,$p+1);
						
	
				if ($this->charset != 'UTF-8')
					foreach( $this->info as $k => $v)
						$this->info[ $k ] = mb_convert_encoding($v,$this->charset,'UTF-8');
				
				if (isset($this->info['balance'])) $this->balance = $this->info['balance'];
				
				return true;
			} else {
				$this->error = 'UNKNOWN RESPONSE';
				return false;
			}
		} else {
			$this->error = 'CONNECTION ERROR';
			return false;				
		}
	}
	// sockets version HTTP/POST
	public function http_post( $url, $data ) {
		
		$eol = "\r\n";
		
		$post = '';
	
		if (is_array($data)) {
			foreach( $data as $k => $v)
				$post .= $k.'='.urlencode($v).'&';
			$post = substr($post,0,-1);
			$content_type = 'application/x-www-form-urlencoded';
		} else {
			$post = $data;
			if (strpos($post, '<?xml') === 0)
				$content_type = 'text/xml';
			else if (strpos($post, '{') === 0)
				$content_type = 'application/json';
			else
				$content_type = 'text/html';
		}
		if ((($u = parse_url($url)) === false) || !isset($u['host'])) return false;
		
		if (!isset($u['scheme'])) $u['scheme'] = 'http';
				
		$request = 'POST '.(isset($u['path']) ? $u['path'] : '/').((isset($u['query'])) ? '?'.$u['query'] : '' ).' HTTP/1.1'.$eol
			.'Host: '.$u['host'].$eol
			.'Content-Type: '.$content_type.$eol
			.'Content-Length: '.mb_strlen($post, 'latin1').$eol
			.'Connection: close'.$eol.$eol
			.$post;
		
		$host = ($u['scheme'] == 'https') ? 'ssl://'.$u['host'] : $u['host'];
		
		if (isset($u['port']))
			$port = $u['port'];
		else
			$port = ($u['scheme'] == 'https') ? 443 : 80;
		
		$fp = @fsockopen( $host, $port, $errno, $errstr, 10);
		if ($fp) {
			
			$content = '';
			$content_length = false;
			$chunked = false;
			
			fwrite($fp, $request);
			
			// read headers				
			while ($line = fgets($fp)) {
				
				if (preg_match('~Content-Length: (\d+)~i', $line, $matches)) {	
					$content_length = (int) $matches[1];
				} else if (preg_match('~Transfer-Encoding: chunked~i', $line)) {
					$chunked = true;
				} else if ($line == "\r\n") {
					break;
				}

			}
			// read content		
			if ($content_length !== false) {
				
				$_size = 4096;
				do {
					$_data = fread($fp, $_size );
					$content .= $_data;
					$_size = min($content_length-strlen($content), 4096);
				} while( $_size > 0 );
				
//				$content = fread($fp, $content_length);
				
			} else if ($chunked) {
		
				while ( $chunk_length = hexdec(trim(fgets($fp))) ) {
					
					$chunk = '';
					$read_length = 0;

					while ( $read_length < $chunk_length ) {

						$chunk .= fread($fp, $chunk_length - $read_length);
						$read_length = strlen($chunk);

					}				
					$content .= $chunk;

					fgets($fp);

				}
			} else {
				while(!feof($fp)) $content .= fread($fp, 4096);
			}
			fclose($fp);
			
			return $content;
			
		} else {
			return false;
		}
	}
}

?>