<?php
/*
* This library is provided without warranty under the MIT license
* Created by Jacob Davis <jacob@1forge.com>
*/
namespace OneForge\ForexQuotes;
use GuzzleHttp\Client;
use Wrench\Client as WebSocket;
class ForexDataClient
{
private $api_key;
public function __construct($api_key)
{
$this->api_key = $api_key;
$this->client = new Client([// Base URI is used with relative requests
'base_uri' => 'https://api.1forge.com/',
'timeout' => 5.0,
'headers' => ['Content-Type' => 'application/json']]);
}
public function beat()
{
$this->socket_client->sendData('beat');
}
public function login()
{
$this->socket_client->sendData('login|'.$this->api_key);
}
public function handleIncomingMessage($message)
{
switch ($message["event"])
{
case "update":
if(property_exists($this, 'update_function'))
{
$update_function = $this->update_function;
$data = $message["data"];
$update_function($data["s"], $data);
}
break;
case "message":
$this->handleMessage($message["data"]);
break;
case "login":
$this->login();
break;
case "post_login_success":
$this->handlePostLoginSuccess();
break;
case "heart":
$this->beat();
break;
case "force_close":
$this->handleMessage("The connection was forced closed by the server");
die();
default:
$this->onServerError();
}
}
public function onServerError()
{
try
{
$this->handleMessage("The connection to the server was lost, trying to reconnect in 5 seconds");
sleep(5);
$this->connect($this->post_login);
}
catch (\Exception $e)
{
$this->onServerError();
}
}
public function handleMessage($message)
{
if(property_exists($this, 'message_function'))
{
$message_function = $this->message_function;
$message_function($message);
}
}
public function onUpdate($update_function)
{
$this->update_function = $update_function;
}
public function onMessage($message_function)
{
$this->message_function = $message_function;
}
public function subscribeTo($symbols)
{
foreach ((array)$symbols AS $symbol)
{
$this->socket_client->sendData("subscribe_to|$symbol");
}
}
public function subscribeToAll()
{
$this->socket_client->sendData('subscribe_to_all');
}
public function unsubscribeFrom($symbols)
{
foreach ((array)$symbols AS $symbol)
{
$this->socket_client->sendData("unsubscribe_from|$symbol");
}
}
public function unsubscribeFromAll()
{
$this->socket_client->sendData('unsubscribe_from_all');
}
private function handlePostLoginSuccess()
{
if(!$this->post_login)
{
return;
}
$post_login = $this->post_login;
$post_login($this);
}
public function connect($callback)
{
$this->post_login = $callback;
$this->socket_client = new WebSocket('wss://sockets.1forge.com/socket','http://localhost');
$this->socket_client->connect();
$this->login();
// $this->socket_client->send("Hello WebSocket.org!");
while(true){
$receive = $this->socket_client->receive();
if(isset($receive) && !empty($receive)){
foreach($receive as $id => $body){
$message = $this->decodeSocketMessage($body);
$this->handleIncomingMessage($message);
}
}
}
}
public function fetch($uri)
{
return $this->client->get($uri . '&api_key=' . $this->api_key)->getBody();
}
public function quota()
{
$body = $this->fetch('quota?cache=false');
return json_decode($body, true);
}
public function getSymbols()
{
$body = $this->fetch('symbols?cache=false');
return json_decode($body, true);
}
public function getQuotes(array $symbols = null)
{
if($symbols === null)
{
$body = $this->fetch('quotes?cache=false');
}
else
{
$pairs = implode(",", $symbols);
try{
if(strlen($pairs) > 7664)
{
throw new \Exception('No more than 957 pairs');
}
else
{
$body = $this->fetch('quotes?pairs=' . $pairs);
}
} catch(\Exception $e){
echo $e->getMessage();
exit();
}
}
$quotes = json_decode($body);
$quotes_array = [];
foreach ($quotes as $quote)
{
$quotes_array[] = ['s' => $quote->s,
'b' => $quote->b,
'a' => $quote->a,
'p' => $quote->p,
't' => $quote->t];
}
return $quotes_array;
}
public function marketIsOpen()
{
$body = $this->fetch('market_status?cache=false');
$body = json_decode($body);
if(property_exists($body, 'market_is_open'))
{
return (bool)$body->market_is_open;
}
return false;
}
public function convert($from, $to, $quantity)
{
$body = $this->fetch('convert?from=' . $from . '&to=' . $to . '&quantity=' . $quantity);
return json_decode($body, true);
}
private function decodeSocketMessage($message)
{
// $cleaned = str_replace("42[", "", $message);
// $cleaned = str_replace("]", "", $cleaned);
$event = explode("|", $message)[0];
$data = str_replace($event . "|", "", $message);
$event = str_replace('"', "", $event);
if($data)
{
$data = json_decode($data, true);
}
return ["event" => $event,
"data" => $data];
}
}
|