Código PHP:
class ExchangeRate {
/** @var resource Connection with database. */
private $connection;
/** @var Mixed Array of urls of rss resources. */
private $resources;
/** @var Mixed Array of Regular Expressions used to obtain the exchange rate. */
private $regex;
/** @var Mixed Results obtained from the search. */
private $result = NULL;
/** @var buffer obtained from the resource. */
private $buffer = NULL;
/** @var int clave del array de resources de la que se obtuvo el buffer. */
private $key = NULL;
/** @var String Codigo retornado por la cabecera HTTP. 200 en success. */
private $code = NULL;
/** @var Int Offset del UTC de la zona horaria que se esta manejando en segundos. Default UTC-6 */
private $UTCOffset = -21600;
/** @var Int Offset del Ahorro de luz de la region de donde se obtuvo el dato. */
private $DayLightOffset;
/** @var String Fecha Hora local de la hora en la que se publico el tipo de cambio */
private $fechaCambio = NULL;
/** @var String Valor del tipo de cambio obtenido. */
private $tipoCambio = NULL;
private $tmp = NULL;
private $curlError = NULL;
/**
* Constructor del objeto ExchangeRate
* @param resource $connection Conexion a la base de datos
*/
function __construct($connection){
if(func_num_args()<1)return false;
$this->connection = $connection;
$this->resources = array('http://www.currencysource.com/rss/CNY.xml',
'http://themoneyconverter.com/CNY/rss.xml',
'http://download.finance.yahoo.com/d/quotes.csv?s=CNYUSD=X&f=sl1d1t1ba&e=.csv');
$this->regex=array('~\\<item\\>\\s*\\<title\\>1 CNY = USD \\((?P<tipoCambio>[\\d]+\\.?[\\d]+)\\)\\<\\/title\\>\\s*\\<link\\>http://[w{3}.]?(?:\\w+[/_-\\d]*.)*\\<\\/link\\>\\s*\\<description\\>(?:[\\s\\w-_#;,:.=()<>\\\'"!¡$%&/¿?+\\[\\]{}@])+?<\\/description\\>\\s*(?:\\<guid\\s+(?:[\\w]+=["|\']{1}[\\w]+["|\'{1}])*\\>(?:[\\s\\w-_#;,:.=()<>\\\'"!¡$%&/¿?+\\[\\]{}@])+?\\<\\/guid\\>\\s*)?\\<pubDate\\>\\w{3},\\s*(?P<day>\\d{1,2})\\s*(?P<month>\\w{3})\\s*(?P<year>\\d{1,4})\\s*(?P<hour>\\d{1,2}:\\d{1,2}:\\d{1,2})\\s*(?P<timeZone>[+|-]?\\w{1,4})\\<\\/pubDate\\>\\s*\\<\\/item\\>~i',
'~\\<item\\>\\s*\\<title\\>USD/CNY\\<\\/title\\>\\s*\\<link\\>http://[w{3}.]?(?:\\w+[/_-\\d]*.)*\\<\\/link\\>\\s*\\<guid\\s*(?:[\\w]+=["|\']{1}[\\w]+["|\'{1}])*\\>(?:[\\s\\w-_#;,:.=()<>\\\\\'"!¡$%&/¿?+\\[\\]{}@])+?\\<\\/guid\\>\\s*\\<pubDate\\>\\w{3},\\s*(?P<day>\\d{1,2})\\s*(?P<month>\\w{3})\\s*(?P<year>\\d{1,4})\\s*(?P<hour>\\d{1,2}:\\d{1,2}:\\d{1,2})\\s*(?P<timeZone>[+|-]?\\w{1,4})\\<\\/pubDate\\>\\s*\\<description\\>1 Chinese Yuan = (?P<tipoCambio>[\\d]+\\.?[\\d]+) United States Dollar<\\/description\\>\\s*\\<category\\>(?:[\\s\\w-_#;,:.=()<>\\\\\'"!¡$%&/¿?+\\[\\]{}@])+?\\<\\/category\\>\\s*\\<\\/item\\>~i',
'~,(?P<tipoCambio>[\\d]+(?:\\.\\d+)),(?:"|\')?(?P<month>\\d{1,2})/(?P<day>\\d{1,2})/(?P<year>\\d{2,4})(?:"|\')?,(?:"|\')?(?P<hour>\\d{1,2}:\\d{2}(?:am|pm))~i');
}
/**
* Establece los recursos (urls) de donde se obtendran los tipos de cambio. <b>El numero de elementos debe ser el mismo que el que se pase con setRegEx()</b>
* @param Mixed $resources Arreglo con las urls de las que se obtendran los tipos de cambio.
*/
function setResources($resources){
$this->resources = (array)$resources;
}
/**
* Establece las expresiones regulares que serviran para parsear la cadena de xml obtenida. <b>El numero de elementos debe ser el mismo que el que se pase con setResources()</b>
* @param Mixed $regex Arreglo con las expresiones regulares con las que se obtendran los datos para los tipos de cambio.
*/
function setRegEx($regex){
$this->regex = (array)$regex;
}
/**
* Establece el offset en segundos con el que se comparara la hora del rss para ajuste.
* @param Int $offset valor en segundos con el que será comparada la hora del rss.
*/
function setUTCOffset($offset){
$this->UTCOffset = (int) $offset;
}
/**
* Obtiene de resources el documento que contiene la informacion.
* @return Bool True en success, false en error.
*/
protected function setBuffer(){
$curlResource = curl_init();
curl_setopt($curlResource, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curlResource, CURLOPT_TIMEOUT, 30);
curl_setopt($curlResource,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlResource,CURLOPT_FAILONERROR,true);
reset($this->resources);
do{
$val=current($this->resources);
if($val!==false){
curl_setopt($curlResource,CURLOPT_URL,$val);
$this->buffer = curl_exec($curlResource);
$this->key = key($this->resources);
$this->code = (string) curl_getinfo($curlResource, CURLINFO_HTTP_CODE);
$this->curlError = curl_error($curlResource);
$this->tmp = curl_getinfo($curlResource);
//$this->debug_log("SetBuffer Code : ".$this->code." key ".$this->key."\nBuff: ".$this->buffer." url ".$val." ".print_r(curl_getinfo($curlResource),true));
}
else if($val===false){
$this->debug_log("Llegue hasta el fin del arreglo","data",__METHOD__);
return false;
}
next($this->resources);
}while(!empty($this->buffer) && $this->code != "200");
return true;
}
/**
* Parsea la cadena del buffer para obtener los datos.
* @return Bool True en success, false en error.
*/
protected function setResult(){
if(empty($this->buffer)||$this->code!= "200"){
$this->debug_log("There was an error with the service :".$this->resources[$this->key]." The server has returned the code : ".$this->code." and the following budffer: ".$this->buffer." CurlInfo ".print_r($this->tmp,true)." Error_Curl: ".$this->curlError,'curl',__METHOD__);
return false;
}
if(preg_match($this->regex[$this->key], $this->buffer, $resultado)){
$this->result['tipoCambio'] = $resultado['tipoCambio'];
$resultado['timeZone']=(strlen($resultado['timeZone'])>1)?$resultado['timeZone']:"EDT";
$dtstr=(strlen($resultado['month'])>2)?$resultado['month']." ".$resultado['day']." ".$resultado['year'] : $resultado['year']."-".$resultado['month']."-".$resultado['day'];
$dtstr.=$resultado["hour"]." ".$resultado['timeZone'];
//////////////////////////////
if(class_exists("DateTime", false)){
$conversion_date = new DateTime($dtstr);
if(!$conversion_date)return false;
$conversion_date->setTimezone(new DateTimeZone("America/Mexico_City"));
$this->result['date_time']=$conversion_date->format("Y-m-d H:m:s");
$this->result['original_date_time'] = $resultado['day']."-".$resultado['month']."-".$resultado['year']." @ ".$resultado['hour']." ".$resultado['timeZone']." off ".$conversion_date->getOffset();
}else{
$anteriorDTZ=date_default_timezone_get();
date_default_timezone_set("America/Mexico_City");
$this->result['date_time']=date("Y-m-d H:m:s",strtotime($dtstr));
$this->result['original_date_time']=$resultado['day']."-".$resultado['month']."-".$resultado['year']." @ ".$resultado['hour']." ".$resultado['timeZone']." off N/A";
date_default_timezone_set($anteriorDTZ);
}
/////////////////////////////
$this->fechaCambio = $this->result['date_time'];
$this->tipoCambio = $this->result['tipoCambio'];
return true;
}
else{
$this->debug_log("The RegEx didnt find any match of ".$this->resources[$this->key]." Please make sure that its corresponding RegEx is correct.","regexp",__METHOD__);
return false;
}
}
/**
* Imprime el buffer en la salida standard (Pantalla).
*/
function printBuffer(){
print_r($this->buffer);
}
/**
* Obtiene la llave de la clave del arreglo de la que se obtuvo la informacion.
* @return Int Llave de la clave del arreglo de la que se obtuvo la informacion.
*/
function getKey(){
return $this->key;
}
/**
* Codigo HTTP que regreso el servidor del cual se obtuvo la informacion.
* @return String Codigo HTTP de la petición.
*/
function getCode(){
return $this->code;
}
/**
* Obtiene los resultados de la peticion. Si no se pasa ningun valor, obtiene todo el arreglo.
* @param String $opt Resultado a obtener. Puede ser uno de los siguientes: tipoCambio | date_time | original_date_time
* @return Mixed Resultado pedido. Si no hay ningun parametro se obtiene un arreglo.
*/
function getResult($opt = NULL){
if(count($this->result)<1) return false;
if($opt==NULL) return $this->result;
return $this->result[$opt];
}