Skip to content

Instantly share code, notes, and snippets.

@it-can
Forked from piwi91/ ExactOnlineApi - API.php
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save it-can/d6dd6f0e14c71a7370e9 to your computer and use it in GitHub Desktop.
Save it-can/d6dd6f0e14c71a7370e9 to your computer and use it in GitHub Desktop.
<?php
/**
*
* This file contains a class which can be used to connect with the Exact Online API
*/
namespace ExactOnlineApi;
use \ExactOnlineApi\ApiException;
class API
{
/**
* @var string
*/
private $baseurl;
/**
* @var string
*/
private $username;
/**
* @var string
*/
private $password;
/**
* @var string
*/
private $applicationKey;
/**
* @var string
*/
private $division;
/**
* @var string
*/
private $cookiefile;
/**
* @var string
*/
private $crtBundleFile;
/**
* @var string
*/
private $endpoint;
/**
* @var string
*/
private $xml;
/**
* @var array
*/
private $endpointParameters = array();
/**
* @var resource
*/
private $curl;
/**
* @var string
*/
private $curlData;
/**
* @var string
*/
private $url;
/**
* Constructs the Exact Online API class
* If all parameters are given, the constructor initializes a Curl instance
* It's possible to do this manual to provide all parameters with the set methods and then call $this->init()
*
* @param string $baseUrl
* @param string $username
* @param string $password
* @param string $applicationKey
* @param string $division
* @param string $cookieFile
* @param string $crtBundleFile
*/
function __construct(
$baseUrl = "https://start.exactonline.nl",
$username = "",
$password = "",
$applicationKey = "",
$division = "",
$cookieFile = "",
$crtBundleFile = ""
)
{
// Set all properties if not empty
if (!empty($baseUrl)) {
$this->setBaseurl($baseUrl);
}
if (!empty($username)) {
$this->setUsername($username);
}
if (!empty($password)) {
$this->setPassword($password);
}
if (!empty($applicationKey)) {
$this->setApplicationKey($applicationKey);
}
if (!empty($division)) {
$this->setDivision($division);
}
if (!empty($cookieFile)) {
$this->setCookiefile($cookieFile);
}
if (!empty($crtBundleFile)) {
$this->setCrtBundleFile($crtBundleFile);
}
// Check if all properties exists
// If all properties exist, initialize Curl and set the division
if (
!empty($baseUrl) &&
!empty($username) &&
!empty($password) &&
!empty($applicationKey) &&
!empty($division) &&
!empty($cookieFile) &&
!empty($crtBundleFile)
) {
$this->init();
}
}
function __destruct()
{
if ($this->isInit()) {
$ch = $this->getCurl();
curl_close($ch);
}
}
/**
* Initialize the Exact Online API
* This method initializes a CURL instance and saves it in the private $curl variable.
* Other methods can retrieve this CURL instance by calling $this->getCurl().
* This method should called only once
*
* @throws \ApiException
*/
public function init()
{
// Check if the curl object isn't set already
if ($this->isInit()) {
throw new \ExactOnlineApi\ApiException("A Curl instance is already initialized");
}
// Check if all needed properties are set
if ($this->getCookiefile() == null || $this->getCrtBundleFile() == null || $this->getUsername() == null || $this->getPassword() == null) {
throw new \ExactOnlineApi\ApiException("Not all properties are set: cookieFile, crtBundleFile, username or password");
}
// Define headers
$header[1] = "Cache-Control: private";
$header[2] = "Connection: Keep-Alive";
// Initialize Curl
$ch = curl_init();
// Use POST instead of GET
curl_setopt($ch, CURLOPT_POST, 1);
// Set the HTTP header
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// Expect returndata
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set cookiefile for sessiondata
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->getCookiefile());
// Set crtBundleFile (certificate)
curl_setopt($ch, CURLOPT_CAINFO, $this->getCrtBundleFile());
// Define _UserName_ and _Password_ post fields
curl_setopt($ch, CURLOPT_POSTFIELDS, array (
"_UserName_" => $this->getUsername(),
"_Password_" => $this->getPassword()
));
// Save Curl object in the class so it can be used by other methods
$this->setCurl($ch);
}
/**
* Call the Exact Online API with an endpoint
*/
public function callEndpoint($sendApplicationKey = true)
{
$ch = $this->prepareCall($sendApplicationKey);
// Execute
$data = curl_exec($ch);
$this->finishCall($ch, $data);
}
/**
* Call the Exact Online API with an endpoint and upload XML data
*/
public function callUploadEndpoint($sendApplicationKey = true)
{
$ch = $this->prepareCall($sendApplicationKey);
// set XML in the postfields
curl_setopt($ch, CURLOPT_POSTFIELDS, utf8_encode($this->getXml()));
// Execute
$data = curl_exec($ch);
$this->finishCall($ch, $data);
}
public function getCurlDataAsObject()
{
return new \SimpleXMLElement($this->getCurlData());
}
/**
* Finishes the call and set the data or throws an exception if the request was not OK
*
* @param $ch
* @param $data
* @throws ApiException
*/
private function finishCall($ch, $data)
{
// Reset endpoint parameters
$this->setEndpointParameters(array());
// Get HTTP status code from Curl
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Check if the HTTP code is 200, else throw exception
if ($httpStatus == 200) {
// If HTTP code is 200, set the data in $this->curlData;
$this->setCurlData($data);
} else {
throw new \ExactOnlineApi\ApiException(
"HTTP status is not OK!<br />Url: " .
$this->getUrl() .
"<br />Status: " . $httpStatus,
$data,
$httpStatus
);
}
}
/**
* Prepares the call and sets the endpoint URL
*
* @return resource
*/
private function prepareCall($sendApplicationKey)
{
// Check if the curl object is set
if (!$this->isInit()) {
// If it isn't, we do it right now
$this->init();
}
// Get Curl object
$ch = $this->getCurl();
$parameters = $this->getEndpointParameters();
if ($sendApplicationKey) {
$parameters = array("ApplicationKey" => $this->getApplicationKey()) + $parameters;
}
$url = vsprintf('%s/docs/%s?%s', array (
$this->getBaseurl(),
$this->getEndpoint(),
http_build_query($parameters)
));
$this->setUrl($url);
// Set full URL in Curl
curl_setopt($ch, CURLOPT_URL, $url);
return $ch;
}
/**
* Returns if Curl is initialized or not
*
* @return bool
*/
private function isInit()
{
if ($this->getCurl() != null) {
return true;
}
return false;
}
/**
* Remove BOM from returned data
*
* @param string $xml
* @return string
*/
private function removeBOM($xml)
{
return preg_replace('/\x{EF}\x{BB}\x{BF}/', '', $xml);
}
// GETTERS AND SETTERS
/**
* @param string $applicationKey
*/
public function setApplicationKey($applicationKey)
{
$this->applicationKey = $applicationKey;
}
/**
* @return string
*/
public function getApplicationKey()
{
return $this->applicationKey;
}
/**
* @param string $baseurl
*/
public function setBaseurl($baseurl)
{
$this->baseurl = $baseurl;
}
/**
* @return string
*/
public function getBaseurl()
{
return $this->baseurl;
}
/**
* @param string $cookiefile
*/
public function setCookiefile($cookiefile)
{
$this->cookiefile = $cookiefile;
}
/**
* @return string
*/
public function getCookiefile()
{
return $this->cookiefile;
}
/**
* @param string $crtBundleFile
*/
public function setCrtBundleFile($crtBundleFile)
{
$this->crtBundleFile = $crtBundleFile;
}
/**
* @return string
*/
public function getCrtBundleFile()
{
return $this->crtBundleFile;
}
/**
* @param string $division
*/
public function setDivision($division)
{
$this->division = $division;
}
/**
* @return string
*/
public function getDivision()
{
return $this->division;
}
/**
* @param string $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* @param string $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* @param resource $curl
*/
public function setCurl($curl)
{
$this->curl = $curl;
}
/**
* @return resource
*/
public function getCurl()
{
return $this->curl;
}
/**
* @param string $curlData
*/
public function setCurlData($curlData)
{
$this->curlData = $this->removeBOM($curlData);
}
/**
* @return string
*/
public function getCurlData()
{
return $this->curlData;
}
/**
* @param string $endpoint
*/
public function setEndpoint($endpoint)
{
$this->endpoint = $endpoint;
}
/**
* @return string
*/
public function getEndpoint()
{
return $this->endpoint;
}
/**
* @param string $xml
*/
public function setXml($xml)
{
$this->xml = $xml;
}
/**
* @return string
*/
public function getXml()
{
return $this->xml;
}
/**
* @param array $endpointParameters
*/
public function setEndpointParameters($endpointParameters)
{
$this->endpointParameters = $endpointParameters;
}
/**
* @return array
*/
public function getEndpointParameters()
{
return $this->endpointParameters;
}
/**
* @param string $url
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
}
<?php
/**
*
* This file contains a custom exception for ExactOnlineAPI
*/
namespace ExactOnlineApi;
class ApiException extends \Exception
{
/**
* @var string
*/
protected $apiData;
function __construct($message = "", $apiData = "", $code = 0, Exception $previous = null)
{
$this->apiData = $apiData;
parent::__construct($message, $code, $previous);
}
/**
* @return string
*/
public function getApiData()
{
return $this->apiData;
}
}
<?php
namespace ExactOnlineApi;
try {
// Init ExactOnlineApi class and provide all properties
// The constructor will init a Curl instance and set the divison
$exactOnlineApi = new \ExactOnlineApi\API(
$baseurl,
$username,
$password,
$applicationkey,
$division,
$cookiefile,
$crtbundlefile
);
// First set the division
$exactOnlineApi->setEndpoint("ClearSession.aspx");
$exactOnlineApi->setEndpointParameters(array(
"Division" => $division,
"Remember" => 3
));
$exactOnlineApi->callEndpoint(false);
// Retrieve item
$exactOnlineApi->setEndpoint("XMLDownload.aspx");
$exactOnlineApi->setEndpointParameters(array(
"Topic" => "Items",
"Params_AssortmentCode" => "01"
));
$exactOnlineApi->callEndpoint();
$xmlObject = $exactOnlineApi->getCurlDataAsObject();
} catch (\ExactOnlineApi\ApiException $e) {
echo "<h3>ApiException occurred</h3>";
echo "<div class=\"message\">" . $e->getMessage() . "</div>";
echo "<pre class='prettyprint lang-xml linenums'>".htmlentities($e->getApiData())."</pre>";
die;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment