SMS Gateways
Il gateway SMS per VikBooking può essere esteso creando un file PHP contenente la classe VikSmsApi.
Il file generato deve essere caricato via FTP seguendo il percorso seguente:
/wp-content/plugins/vikbooking/admin/smsapi/
Segui lo schema sottostante per vedere la struttura del file della Classe:
<?php
defined('ABSPATH') OR die('Restricted Area');
class VikSmsApi {
private $order_info;
private $params;
private $log = '';
public static function getAdminParameters() {
return array();
}
public function __construct($order, $params=array()) {
$this->order_info=$order;
$this->params = ( !empty($params) ) ? $params : $this->params;
}
public function sendMessage( $phone_number, $msg_text ) {
/** See the code below to build this method */
return new stdClass;
}
public function estimate( $phone_number, $msg_text ) {
/** See the code below to build this method */
return new stdClass;
}
public function validateResponse($response_obj) {
/** See the code below to build this method */
return true;
}
public function getLog() {
return $this->log;
}
}
?>
Il modulo dei parametri per l'amministatore può essere costruiti attraverso il metodo statico getAdminParameters(), per compilare dati privati richiesti per la creazione e la validazione delle API, come la API key e l'API Secret.
I parametri del form sono restituiti come un array dalla struttura seguente:
[
"param_1" : [
"label" : "Label 1",
"type" : "text",
],
"param_2" : [
"label" : "Label 2",
"type" : "select",
],
]
- param_1 è la chiave dell'array e deve essere univoca (required).
Rappresenta il nome del parametro da usare. - label indica il testo da assegnare al parametro nella sezione amministratore (optional).
Piazzando un doppio slash (//) dopo la label, il testo seguente sarà mostrato come suggerimento vicino al campo del parametro(come "Mittente//massimo 11 caratteri"). - type è usato per renderizzare il giusto tipo d'input nella sezione amministratore (required).
Il valore assunto può essere uno dei seguenti: custom, select, text. - html sarà usato solo quando il tipo di carattere è custom (optional).
- options è un array contente tutti i possibili valori da usare nella lista a cascata (required quando il tipo è select).
public static function getAdminParameters() {
return array(
'apikey' => array(
'label' => 'API Key',
'type' => 'text'
),
'apisecret' => array(
'label' => 'API Secret',
'type' => 'text'
),
'sender' => array(
'label' => 'Sender Name//max 11 characters',
'type' => 'text'
),
'sandbox' => array(
'label' => 'Sandbox',
'type' => 'select',
'options' => array('NO', 'YES')
)
);
}
Il codice soprastante genererà un form dei parametri nella sezione amministrativa come seguente.
Se il tuo form non compare, probabilmente è perchè c'è un errore di sintassi nel tuo file.
Dopo aver inserito i parametri del Gateway, essi saranno disponibili nell'array $params e sarai in grado di accedere a questi valori usando il codice sottostante:
$api_key = $this->params['apikey']; /* returns "TS8KJSGV20E7SG2K" */
$api_secret = $this->params['apisecret']; /* returns "ks03bsoaqsdlew83hdswlsn2ie7d2hndmwq" */
$sender_name = $this->params['sender']; /* returns "e4j.com" */
$sandbox = $this->params['sandbox']; /* returns "NO" */
Il metodo sendMessage($phone_number, $msg_text) dell'oggetto VikSmsApi è invocato ogni volta che un ordine diventa CONFERMATO, tipo dopo un pagamento. Attraverso questa funzione, dovresti inviare via POST (probabilmente) tutte le variabili necessarie per l'autenticazione sul Gateway e il contenuto del messaggio, includendo il numero di telefono del destinatario. Generalmente, cURL è il metodo più sicuro per inviare i dati a un Gateway remoto, ma questo dipende dai requisiti del gateway sul quale stai lavorando.
La funzione sendMessage richiede 2 argomenti:
- $phone_number - (string) il numero di telefono del destinatario. Questo valore deve essere convalidato prima di inviare il messaggio, perchè potrebbe mancare il prefisso o potrebbe includere caratteri invalidi (come @ o /)
- $msg_text - (string) il testo da spedire al cliente. Molti provider consentono di spedire massimo 160 caratteri per messaggio, ricordati questo limite.
Il codice qui sotto è un esempio di come una richiesta cURL può stabilire una connessione con il gateway SMS e spedire il messaggio.
public function sendMessage($phone_number, $msg_text) {
$phone_number = $this->sanitizePhoneNumber($phone_number);
if( $this->params['sandbox'] == "NO" ) {
$this->params['sandbox'] = 0;
} else {
$this->params['sandbox'] = 1;
}
$request = array(
"apikey" => $this->params['apikey'],
"apisecret" => $this->params['apisecret'],
"from" => $this->params['sender'],
"to" => $phone_number,
"msg" => $msg_text,
"sandbox" => $this->params['sandbox']
);
$json = json_encode($request);
$curl_opts = array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/json;charset=UTF-8',
'Content-Length: '.strlen($json)
),
CURLOPT_VERBOSE => true,
);
$ch = curl_init('https://secure.sms.fakeprovider.com/send');
curl_setopt_array($ch, $curl_opts);
$response = curl_exec($ch);
return json_decode($response);
}
La funzione sanitizePhoneNumber usata qui sotto non è una funzione nativa della classe VikSmsApi, quindi dovresti scrivere questo metodo nel tuo codice.
Questo è giusto un esempio su come un numero di telefono può essere elaborato e corretto:
protected function sanitizePhoneNumber($phone_number) {
$str = '';
for( $i = 0; $i < strlen($phone_number); $i++ ) {
if( ($phone_number[$i] >= '0' && $phone_number[$i] <= '9') || $phone_number[$i] == '+' ) {
$str .= $phone_number[$i]; // copy only numbers and plus character
}
}
$default_prefix = '+1'; // US, Canada phone prefix
if( $phone_number[0] != '+' ) {
// $phone_number doesn't contain the phone prefix. Checking if it starts with 00 would be smart as well
$str = $default_prefix.$str;
}
return $str;
}
Il metodo validateResponse($response_obj) è usato per convalidare l'oggetto ritornato dal gateway durante l'invio del messaggio. Alcuni gateway ritornano un oggetto contenenti un messaggio d'errore e il codice status http.
{
"httpcode" : 200,
"errmsg" : "",
}
{
"httpcode" : 401,
"errmsg" : "BAD_CREDENTIALS",
}
{
"httpcode" : 402,
"errmsg" : "BAD_CREDIT",
}
Mentre, a volte, l'oggetto ritornato è un valore boolean(true/false).
In questo metodo devi ritornare un valore boolean(true/false) per dire al framework se il messaggio è stato spedito. Ritornando TRUE, nessun errore è ritornato o notificato, l'errore sarà spedito via mail all'amministratore altrimenti. Nota che l'errore che deve essere ritornato deve essere inserito nell'attributo $log.
//in this example, the method requires an object as first and only argument
public function validateResponse($response_obj) {
if( $response_obj->httpcode == 200 ) {
return true;
}
$this->log .= $response_obj->errmsg;
return false;
}
La funzione estimate($phone_number, $msg_text) è un metodo opzionale usato nel back-end del plugin per sapere quanto credito è rimasto. Non è un metodo obbligatorio e la classe può non avercelo., dato che non tutti i provider consentono una richiesta del genere.
$phone_number e $msg_text sono solo usati come esempio nel gateway.
Il valore ritornato da questa funzione deve essere una stringa che sarà mostrata nel back-end.
La maggior parte delle volte, la struttura di questa funzione è simile a quella del metodo sendMessage ,e di solito chiama variabili diverse del gateway SMS del provider.
public function estimate($phone_number, $msg_text) {
$fixedResponse = '----';
$phone_number = $this->sanitizePhoneNumber($phone_number);
$request = array(
"apikey" => $this->params['apikey'],
"apisecret" => $this->params['apisecret'],
"from" => $this->params['sender'],
"to" => $phone_number,
"msg" => $msg_text,
);
$json = json_encode($request);
$curl_opts = array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/json;charset=UTF-8',
'Content-Length: '.strlen($json)
),
CURLOPT_VERBOSE => true,
);
$ch = curl_init('https://secure.sms.fakeprovider.com/estimate');
curl_setopt_array($ch, $curl_opts);
$response = curl_exec($ch);
$response = json_decode($response);
if(is_object($response)) {
$fixedResponse = (float)$response->credit;
}
return $fixedResponse;
}