<?php

/**
 *	Core Class
 *  --------------
 *	Description : Move functions to objects
 *	Written by  : Kyriazis
 *	Version     : 1.0.0
 *  Created     : 09/07/2015
 *  Updated	    : 
 *	
 **/

class SmsApi {
	
    
	public function __construct()
	{
        
	}
	
	//==========================================================================
    // Class Destructor
	//==========================================================================
    public function __destruct()
	{
		//echo 'Object has been destroyed';
    }
    
    
    ##--------------------------------------------------------------------------
    ## Puts all table settings into an array
    ##--------------------------------------------------------------------------
    public static function GetSmsApiSettings()
    {
        ## Initialize Connection
        $mysqli = Database::GetConnection();
        $output = '';
        
        $sql= "SELECT 
                primary_acc_user, 
                primary_acc_pass, 
                url_balance, 
                url_http_send, 
                sender_id, 
                sender_mobile, 
                max_chars,
                enable_concat,
                phones_rule_len, 
                phones_rule_pre, 
                phones_country_pre
                FROM ".TABLE_CORE_SMS." WHERE primary_gateway_provider = 'SMSAPI'";
        $result = database_query($mysqli, $sql, DATA_ONLY, FIRST_ROW_ONLY);
        $output =  array(
                'primary_acc_user'=>$result['primary_acc_user'], 
                'primary_acc_pass'=>$result['primary_acc_pass'],
                'url_balance'=>$result['url_balance'],
                'url_http_send'=>$result['url_http_send'],
                'sender_id'=>$result['sender_id'],
                'sender_mobile'=>$result['sender_mobile'],
                'max_chars'=>$result['max_chars'],
                'enable_concat'=>$result['enable_concat'],
                'phones_rule_len'=>$result['phones_rule_len'],
                'phones_rule_pre'=>$result['phones_rule_pre'],
                'phones_country_pre'=>$result['phones_country_pre']
                );
        return $output;
        ## Close Connection
        mysqli_close($mysqli);
        
    }
    
    public static function GetSmsApiBalance()
    {
        ## Initialize Connection
        $mysqli = Database::GetConnection();
        $sms_provider = Core::GetSmsProvider();
        $output = '';
        $balance = 0;
        
        if ($sms_provider == 'SMSAPI') {//1
            $smsapi_settings = self::GetSmsApiSettings();
            $smsapi_username = $smsapi_settings['primary_acc_user'];
            $smsapi_password = md5($smsapi_settings['primary_acc_pass']);
            $smsapi_url_balance = $smsapi_settings['url_balance'];
            $connection = curl_init();
            curl_setopt($connection, CURLOPT_URL, $smsapi_url_balance);
            curl_setopt($connection, CURLOPT_POST, true);
            curl_setopt($connection, CURLOPT_POSTFIELDS, 'username='.$smsapi_username.'&password='.$smsapi_password.'&credits=1');
            curl_setopt($connection, CURLOPT_RETURNTRANSFER, true); 
            $api_response = curl_exec($connection);
            curl_close($connection); 
                if ($api_response){ //2
                    $api_response = trim($api_response);
                    if(strpos($api_response, 'ERROR') !== false) { //3
                        $system_message = Core::DrawSystemMessage('SMSAPI Authentication Error'); 
                        $output = array('connected' => 'false',  'credit_balance' => 0, 'system_message'=>$system_message); 
                        Core::UpdateErrorLog('301', 'SMSAPI_BALANCE', 'SMSAPI Authentication Error, '.$api_response, 'HIGH');     
                    } else {
                    $credit_balance = number_format(substr($api_response, 9), 4, ',', '.');
                    $output = array('connected' => 'true',  'credit_balance' => $credit_balance, 'system_message'=>'');
                    } //end 3   
                }else { 
                    $system_message = Core::DrawSystemMessage('Error connecting SMSAPI to get balance', 'ERROR');
                    $output = array('connected' => 'false',  'credit_balance' => 0, 'system_message'=> $system_message);
                    //Update error log
                    Core::UpdateErrorLog('300', 'SMSAPI_BALANCE', 'Error connecting SMSAPI to get balance', 'MEDIUM');
                } //end 2
            
            return $output;
        } else { //mid 1
            return false;
        } //end 1
        
        ## Close Connection
        mysqli_close($mysqli);
    }

    ##--------------------------------------------------------------------------
    ## Sends single SMS
    ##--------------------------------------------------------------------------   
        public static function SendSmsApiSingle($phone_number, $sender_id, $sms_text, $delivery_datetime = '') 
    {
        $mysqli = Database::GetConnection();
        $sms_mode = Core::GetSmsMode();
        $sms_settings = SmsApi::GetSmsApiSettings();
        $user_id = Core::GetUserId();
            
        $sms_username = $sms_settings['primary_acc_user'];
        $sms_password = md5($sms_settings['primary_acc_pass']);
        $sms_api_url = $sms_settings['url_http_send']; 
        $phone_prefix = $sms_settings['phones_country_pre'].$phone_number;
        $url_text = urlencode($sms_text);
        $sms_max_parts = $sms_settings['enable_concat'];
        
        //datetime handlers 
        ($delivery_datetime !='') ? $date_iso8601 = date(DATE_ISO8601, strtotime($delivery_datetime)) : $date_iso8601 = '';
        ($date_iso8601 !='' ) ? $mysqli_datime = date("Y-m-d H:i:s",strtotime($date_iso8601)) : $mysqli_datime = '0000-00-00 00:00:00';
        //echo $date_iso8601; //debugger
        
            
        //Curl it
        $connection = curl_init();
        curl_setopt($connection, CURLOPT_URL, $sms_api_url);
        curl_setopt($connection, CURLOPT_POST, true);
        
        curl_setopt($connection, CURLOPT_POSTFIELDS, 'username='.$sms_username.'&password='.$sms_password.'&from='.$sender_id.'&to='.$phone_prefix.'&message='.$url_text.'&normalize=1&nounicode=1&'.
        (($sms_mode == 'TEST') ? '&test=1' : '').(($date_iso8601 != '') ? '&date='.$date_iso8601.'&date_validate=1' : '').(($sms_max_parts != '') ? '&max_parts='.$sms_max_parts : '')); 
        
        curl_setopt($connection, CURLOPT_RETURNTRANSFER, true); 
        $api_response = curl_exec($connection);
        curl_close($connection); 
            
        if (substr($api_response, 0, 2) == 'OK' ){//2 if (substr($api_response, 0, 2) == 'OK' )
            echo '<div class="completed"><ul><li>'._SMS_WAS_SENT.' '. $api_response.'</li></ul></div>';
            # Get message id
            $api_message_id = Core::StringFromDelimiters($api_response, 'OK:', ':');
            $api_message_cost = substr($api_response, -5);
            
            $sql_outbox = "INSERT INTO sms_outbox 
                           (batch_id, phone, status, message_id, sender, message, message_url, priority_queue, delivery_delay, scheduled_time, source_module, created_on, created_by, campaign_id, customer_id, carrier, charge, time_sent) 
                           VALUES ('SINGLE', '$phone_number', '000', '$api_message_id', '$sender_id', '$sms_text', '$url_text','1', '', '$mysqli_datime', '', NOW(), '$user_id', '', '', 'SMSAPI', '$api_message_cost', NOW())";
            mysqli_query($mysqli, $sql_outbox) or die ("Error while updating sms_outbox");
        }elseif(strpos($api_response, 'ERROR') !== false ){
            echo '<div class="critical"><ul><li>'._ERROR_OCCURED_WHILE_SENDING_SMS.' '.$api_response.'</li></ul></div>';
            Core::UpdateErrorLog('302', 'SMSAPI_SINGLE', 'Unable to send single SMS, '.$api_response, 'HIGH');
        }else{    
            echo '<div class="critical"><ul><li>'._COULD_NOT_CONNECT_WITH_GATEWAY.' '.$api_response.'</li></ul></div>';
        }//end 2 
    }
        
    ##--------------------------------------------------------------------------
    ## Returns SMS max chars according to SMSAPI documentation 
    ##--------------------------------------------------------------------------  
    public static function GetSmsApiMaxChars()
    {
        $sms_settings = SmsApi::GetSmsApiSettings();
        $enable_concat = $sms_settings['enable_concat'];
        $max_chars = $sms_settings['max_chars'];
        
        if ($enable_concat == '1') $output = $max_chars;
        if ($enable_concat > '1') $output = ($enable_concat * $max_chars) - ($enable_concat * 7);
        if ($enable_concat < 1) $output = 0;
        
        return $output;
    }
    
    ##--------------------------------------------------------------------------
    ## Clears erro flaf in automated Sms 
    ##-------------------------------------------------------------------------- 
        public static function ClearAutoSmsErrors()
    {
  		$mysqli = Database::GetConnection();
        $logged_user = $_SESSION['user'];
        
        $sql = "UPDATE ".TABLE_SMS_AUTO_SETUP." SET error_flag = 0, updated_on = NOW(), updated_by = '".$logged_user."' WHERE error_flag = 1";		
		$result = database_void_query($mysqli, $sql, false, false);
        // or die("Query failed : " . mysqli_error($wce_conn));
        if($result) {
            Core::UpdateErrorLog('355', 'SMSAPI_AUTO', 'Errors were eliminated by user', 'INFO');
            return true;
        } else {
            return false;
        }
        mysqli_close($mysqli);
    }
    
    ##--------------------------------------------------------------------------
    ## Returns SMS status and charhe
    ##--------------------------------------------------------------------------      
    public static function GetSmsApiStatus($msgid)
    {
        ## Initialize Connection
        $mysqli = Database::GetConnection();
        $sms_provider = Core::GetSmsProvider();
        $user_id = Core::GetUserId();
        $output = '';
        $balance = 0;
        
        if ($sms_provider == 'SMSAPI') {//1
            $smsapi_settings = self::GetSmsApiSettings();
            $smsapi_username = $smsapi_settings['primary_acc_user'];
            $smsapi_password = md5($smsapi_settings['primary_acc_pass']);
            $sms_api_url = $smsapi_settings['url_http_send']; 
                        
            //echo $sms_api_url.'?username='.$smsapi_username.'&password='.$smsapi_password.'&status='.$msgid; //debug
        //Curl it
        $connection = curl_init();
        curl_setopt($connection, CURLOPT_URL, $sms_api_url);
        curl_setopt($connection, CURLOPT_POST, true);
        
        curl_setopt($connection, CURLOPT_POSTFIELDS, 'username='.$smsapi_username.'&password='.$smsapi_password.'&status='.$msgid); 
        
        curl_setopt($connection, CURLOPT_RETURNTRANSFER, true); 
        $api_response = curl_exec($connection);
        curl_close($connection); 
            
            if (substr($api_response, 0, 2) == 'OK' ){//2 if (substr($api_response, 0, 2) == 'OK' )
                $smsapi_explode = explode(":",$api_response);
                $smsapi_status = trim($smsapi_explode[1]);
                //echo $smsapi_status; //debug
                
                //prepare input
                $status = mysqli_real_escape_string($mysqli, $smsapi_status);
                $msgid = mysqli_real_escape_string($mysqli, $msgid);
                
                $sql_status = "UPDATE sms_outbox SET status = '$status', updated_on = NOW(), updated_by = '$user_id' WHERE message_id ='$msgid'";
                mysqli_query($mysqli, $sql_status) or die(mysqli_error($mysqli));
                mysqli_close($mysqli);
                return true;

            }elseif(strpos($api_response, 'ERROR') !== false ){
                echo '<div class="critical"><ul><li>'._ERROR_OCCURED_WHILE_UPDATING_SMS_STATUS.' '.$api_response.'</li></ul></div>';
                Core::UpdateErrorLog('303', 'SMSAPI_STATUS', 'Unable to retrieve SMS status, '.$api_response, 'MEDIUM');
                return false;
            }else{    
                echo '<div class="critical"><ul><li>'._COULD_NOT_CONNECT_WITH_GATEWAY.' '.$api_response.'</li></ul></div>';
                Core::UpdateErrorLog('304', 'SMSAPI_STATUS', 'SMSAPI Authentication Error, '.$api_response, 'MEDIUM');
                return false;
            }//end 2 
            
        } else { //mid 1
            return false;
        } //end 1
                
    }
    
    ##--------------------------------------------------------------------------
    ## Sends Campaign Bulk SMS
    ##--------------------------------------------------------------------------   
        public static function SendSmsApiCampaign($campaign_id, $sender_id, $sms_text, $delivery_datetime = '', $delivery_name) 
    {
        $mysqli = Database::GetConnection();
        $sms_mode = Core::GetSmsMode();
        $sms_settings = SmsApi::GetSmsApiSettings();
        $user_id = Core::GetUserId();
        
        ## Check if is not empty
        $count_mob = ("SELECT COUNT(id) AS phones_count FROM ".TABLE_SMS_CAMPAIGN_DETAILS." WHERE campaign_id='$campaign_id'");
        $result_mob = database_query($mysqli, $count_mob, DATA_ONLY, FIRST_ROW_ONLY, FETCH_ASSOC, false) or die ('An error occurred while fetching the number of phones in campaign: ' . mysqli_error($mysqli));
        //echo $result_mob['phn'];//debug it
        
        if ($result_mob['phones_count']>0) { //0
        
            $sms_username = $sms_settings['primary_acc_user'];
            $sms_password = md5($sms_settings['primary_acc_pass']);
            $sms_api_url = $sms_settings['url_http_send'];
            $url_text = urlencode($sms_text);
            $sms_max_parts = $sms_settings['enable_concat'];
            $phone_prefix = $sms_settings['phones_country_pre'];
            //datetime handlers 
            ($delivery_datetime !='') ? $date_unix = strtotime($delivery_datetime) : $date_unix = '';
            ($date_unix !='' ) ? $mysqli_datime = date("Y-m-d H:i:s",strtotime($delivery_datetime)) : $mysqli_datime = '0000-00-00 00:00:00';
            
            //($delivery_datetime !='') ? $date_iso8601 = date(DATE_ISO8601, strtotime($delivery_datetime)) : $date_iso8601 = '';
            //($date_iso8601 !='' ) ? $mysqli_datime = date("Y-m-d H:i:s",strtotime($date_iso8601)) : $mysqli_datime = '0000-00-00 00:00:00';
            
            // delivery name handler
            $delivery_name = $delivery_name."_".date("d")."_".date("m")."_".date("Y")."_".date("His");
            
            ##Get the phones from the campaign
            $sql_phones = 'SELECT phone FROM '.TABLE_SMS_CAMPAIGN_DETAILS.' WHERE campaign_id = "'.$campaign_id.'"';
            $result_phones = database_query($mysqli, $sql_phones, DATA_AND_ROWS, ALL_ROWS, FETCH_ASSOC, false) or die ('An error occurred while fetching the phone numbers list of the campaign: ' . mysqli_error($mysqli));
            
            if ($result_phones[1]>0) { //1
                for($i=0; $i < $result_phones[1]; $i++){ //2
                    $all_phones[] = $phone_prefix.$result_phones[0][$i]['phone'];
                }//end 2
                
                $imploded_phones =  implode(",", $all_phones);
                //echo $imploded_phones."<br />"; //debug it 
                
                set_time_limit(1000); //for long requests
                ignore_user_abort(true);
                // Start execution timer;
                $execution_time = microtime(true);
                
                //Curl it
                $connection = curl_init();
                curl_setopt($connection, CURLOPT_URL, $sms_api_url);
                curl_setopt($connection, CURLOPT_POST, true);
                curl_setopt($connection, CURLOPT_POSTFIELDS, 'username='.$sms_username.'&password='.$sms_password.'&from='.$sender_id.'&to='.$imploded_phones.'&message='.$url_text.'&normalize=1&nounicode=1'.
                (($sms_mode == 'TEST') ? '&test=1' : '').(($date_unix != '') ? '&date='.$date_unix.'&date_validate=1' : '').(($sms_max_parts != '') ? '&max_parts='.$sms_max_parts : '')); 
                curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);
                $api_response = curl_exec($connection);
                curl_close($connection); 
                //echo $api_response.'<br />'; //debug it
                
                if ($api_response){// -1
                    //break the response
                    $smsapi_explode = explode(":",$api_response);
                    $smsapi_status = trim($smsapi_explode[0]);
                    $smsapi_error_code = trim($smsapi_explode[1]);
                        
                    if ($smsapi_status != 'ERROR' && $smsapi_status == 'OK') { //end 6
                        $succesfull_response = explode(';', $api_response);
                        //print_r($succesfull_response); //debug it
                        foreach( $succesfull_response as $key => $value){//3
                        	
                            $broken_response = explode(':', $value);
                            $ok_sent =  $broken_response[0];                    
                            $api_message_id =  $broken_response[1];
                            $api_message_cost =  $broken_response[2];
                            $prefixed_phone_sent =  $broken_response[3];
                            
                            //normalize back phone numbers (remove prefix)
                            if (substr($prefixed_phone_sent, 0, strlen($phone_prefix)) == $phone_prefix) {//4
                                 $clear_phone_sent = substr($prefixed_phone_sent, strlen($phone_prefix));
                            }//end 4
                            
                            if ($ok_sent == 'OK') {//5
                                //find the customer id by the phone
                                $sql_customer = 'SELECT customer_id FROM '.TABLE_SMS_CAMPAIGN_DETAILS.' WHERE phone = "'.$clear_phone_sent.'" LIMIT 0,1';
                                $result_customer = database_query($mysqli, $sql_customer, DATA_ONLY, FIRST_ROW_ONLY, FETCH_ASSOC, false);
                                $api_customer_id = $result_customer['customer_id'];
                                
                                $sql_outbox = "INSERT INTO sms_outbox 
                               (batch_id, phone, status, message_id, sender, message, message_url, priority_queue, delivery_delay, scheduled_time, source_module, created_on, created_by, campaign_id, customer_id, carrier, charge, time_sent) 
                                VALUES ('$delivery_name', '$clear_phone_sent', '000', '$api_message_id', '$sender_id', '$sms_text', '$url_text','1', '', '$mysqli_datime', '', NOW(), '$user_id', '$campaign_id', '$api_customer_id', 'SMSAPI', '$api_message_cost', NOW())";
                                mysqli_query($mysqli, $sql_outbox) or die ("Error while inserting bulk messages sms_outbox");
                                         
                            }//end 5
                        }//end 3
                        /*Update log succesfull delivery*/
                        $execution_time = number_format(microtime(true)-$execution_time, 4);
                        echo '<div class="completed"><ul><li>'._SMS_WAS_SENT.' ('._EXECUTION_TIME.': '.$execution_time.')</li></ul></div>';
                        Core::UpdateErrorLog('307', 'SMSAPI_BULK', 'Bulk SMS created succesfully, exec time: '.$execution_time, 'INFO');      
                    } elseif ($smsapi_status == 'ERROR' && $smsapi_error_code = '103') { 
                        $execution_time = number_format(microtime(true)-$execution_time, 4);
                        echo '<div class="critical"><ul><li>'._INSUFFICIENT_CREDITS.' '.$api_response.' ('._EXECUTION_TIME.': '.$execution_time.')</li></ul></div>';
                        Core::UpdateErrorLog('305', 'SMSAPI_BULK', 'Insufficient credits, exec time: '.$execution_time.', '.$api_response, 'INFO');
                        return false;
                    } else {
                        $execution_time = number_format(microtime(true)-$execution_time, 4);
                        echo '<div class="critical"><ul><li>'._ERROR_OCCURED_WHILE_SENDING_SMS.' '.$api_response.' ('._EXECUTION_TIME.': '.$execution_time.')</li></ul></div>';
                        Core::UpdateErrorLog('306', 'SMSAPI_BULK', 'SMSAPI Bulk Error, '.$execution_time.', '.$api_response, 'HIGH');
                        return false;
                    } //end 6
                } else { //if no response at all
                        $execution_time = number_format(microtime(true)-$execution_time, 4);
                        echo '<div class="critical"><ul><li>'._UNKNOWN_ERROR.' '.$api_response.' ('._EXECUTION_TIME.': '.$execution_time.')</li></ul></div>';
                        Core::UpdateErrorLog('308', 'SMSAPI_BULK', 'Unknown error, exec time: '.$execution_time.', '.$api_response, 'HIGH');
                        return false;
                }//end -1
            } else {
                echo '<div class="critical"><ul><li>'._CAMPAIGN_IS_EMPTY.'</li></ul></div>';
            } //end 1
        } else {
            echo '<div class="critical"><ul><li>'._CAMPAIGN_IS_EMPTY.'</li></ul></div>';    
        }//end 0
    }
}
?>