2016-03-11 2 views
0

Я пытаюсь создать php-скрипт для отправки XML-файла через API в режиме онлайн.загрузить файл xml через API

Мой файл на /tmp/xxx.xml

PHP код (связь на точном онлайн апи):

<?php 



require_once 'ExactApi.php'; 

// Configuration, change these: 
$clientId  = '{x}'; 
$clientSecret = 'x'; 
$redirectUri = "x"; 
$division  = "x"; 

try { 

    // Initialize ExactAPI 
    $exactApi = new ExactApi('fr', $clientId, $clientSecret, $division); 

    $exactApi->getOAuthClient()->setRedirectUri($redirectUri); 

    if (!isset($_GET['code'])) { 

     // Redirect to Auth-endpoint 
     $authUrl = $exactApi->getOAuthClient()->getAuthenticationUrl(); 
     header('Location: ' . $authUrl, TRUE, 302); 
     die('Redirect'); 

    } else { 

     // Receive data from Token-endpoint 
     $tokenResult = $exactApi->getOAuthClient()->getAccessToken($_GET['code']); 
     $exactApi->setRefreshToken($tokenResult['refresh_token']); 

     // List accounts 
     $response = $exactApi->sendRequest('crm/Accounts', 'get'); 
     var_dump($response); 

     // Create account 
     $response = $exactApi->sendRequest('crm/Accounts', 'post', array(
      'Status'   => 'C', 
      'IsSupplier'  => True, 
      'Name'    => 'xx', 
      'AddressLine1'  => 'xx', 
      'Postcode'   => 'xx', 
      'City'    => 'xx', 
      'Country'   => 'xx', 
      'Email'    => 'xx', 
      'Phone'    => 'xx', 
      'Website'   => 'xx' 

     )); 
     var_dump($response); 

    } 

}catch(ErrorException $e){ 

    var_dump($e); 

} 

ExactApi.php

<?php 



require_once 'ExactOAuth.php'; 

class ExactApi 
{ 

    const METHOD_POST = 'post'; 

    const URL_API = 'https://start.exactonline.%s/api/v1/'; 

    /** @var string */ 
    protected $countryCode; 

    /** @var string */ 
    protected $clientId; 

    /** @var string */ 
    protected $clientSecret; 

    /** @var string */ 
    protected $refreshToken; 

    /** @var string */ 
    protected $accessToken; 

    /** @var int */ 
    protected $expiresIn; 

    /** @var string */ 
    protected $division; 

    /** @var ExactOAuth */ 
    protected $oAuthClient; 


    /** 
    * @param string $countryCode 
    * @param string $clientId 
    * @param string $clientSecret 
    * @param string $division 
    * @param string|NULL $refreshToken 
    */ 
    public function __construct($countryCode, $clientId, $clientSecret, $division, $refreshToken = NULL) 
    { 
     $this->countryCode = $countryCode; 
     $this->clientId = $clientId; 
     $this->clientSecret = $clientSecret; 
     $this->refreshToken = $refreshToken; 
     $this->division = $division; 
    } 

    /** 
    * @return ExactOAuth 
    */ 
    public function getOAuthClient() 
    { 
     if (!$this->oAuthClient) { 
      $this->oAuthClient = new ExactOAuth(
       $this->countryCode, $this->clientId, $this->clientSecret 
      ); 
     } 

     return $this->oAuthClient; 
    } 

    /** 
    * @param string $token 
    */ 
    public function setRefreshToken($token) 
    { 
     $this->refreshToken = $token; 
    } 

    /** 
    * @return string|FALSE 
    * @throws \ErrorException 
    */ 
    protected function initAccessToken() 
    { 
     if (empty($this->accessToken) || $this->isExpired()) { 

      if (empty($this->refreshToken)) { 
       throw new \ErrorException('Refresh token is not specified.'); 
      } 

      $refreshed = $this->getOAuthClient()->refreshAccessToken($this->refreshToken); 
      if (!$refreshed) { 
       return FALSE; 
      } 
      $this->setExpiresIn($refreshed['expires_in']); 
      $this->refreshToken = $refreshed['refresh_token']; 
      $this->accessToken = $refreshed['access_token']; 
     } 

     return $this->accessToken; 
    } 

    /** 
    * @param int $expiresInTime 
    */ 
    protected function setExpiresIn($expiresInTime) 
    { 
     $this->expiresIn = time() + $expiresInTime; 
    } 

    /** 
    * @return int 
    */ 
    protected function isExpired() 
    { 
     return $this->expiresIn > time(); 
    } 

    /** 
    * @param string $resourceUrl 
    * @param array|NULL $params 
    * @return string 
    */ 
    protected function getRequestUrl($resourceUrl, $params = NULL) 
    { 
     $resourceUrlParts = parse_url($resourceUrl); 
     $baseUrl = sprintf(self::URL_API, $this->countryCode); 
     $apiUrl = $baseUrl . $this->division.'/'.$resourceUrlParts['path']; 

     if (isset($resourceUrlParts['query'])) { 
      $apiUrl .= '?' . $resourceUrlParts['query']; 
     } else 
     if ($params && is_array($params)) { 
      $apiUrl .= '?' . http_build_query($params, '', '&'); 
     } 

     return $apiUrl; 
    } 

    /** 
    * @param string $url 
    * @param string $method 
    * @param array|NULL $payload 
    * @return string 
    */ 
    public function sendRequest($url, $method, $payload = NULL) 
    { 
     if ($payload && !is_array($payload)) { 
      throw new \ErrorException('Payload is not valid.'); 
     } 

     if (!$accessToken = $this->initAccessToken()) { 
      throw new \ErrorException('Access token was not initialized'); 
     } 

     $requestUrl = $this->getRequestUrl($url, array(
      'access_token' => $accessToken 
     )); 

     // Base cURL option 
     $curlOpt = array(); 
     $curlOpt[CURLOPT_URL] = $requestUrl; 
     $curlOpt[CURLOPT_RETURNTRANSFER] = TRUE; 
     $curlOpt[CURLOPT_SSL_VERIFYPEER] = TRUE; 
     $curlOpt[CURLOPT_HEADER] = false; 

     if ($method == self::METHOD_POST) { 

      $curlOpt[CURLOPT_HTTPHEADER] = array(
       'Content-Type:application/json', 
       'access_token:' . $accessToken, 
       'Content-length: ' . strlen(json_encode($payload)) 
      ); 
      $curlOpt[CURLOPT_POSTFIELDS] = json_encode($payload); 
      $curlOpt[CURLOPT_CUSTOMREQUEST] = strtoupper($method); 
     } 

     $curlHandle = curl_init(); 
     curl_setopt_array($curlHandle, $curlOpt); 

     return curl_exec($curlHandle); 
    } 

} 

ExactOAuth.php

<?php 



class ExactOAuth 
{ 

    const URL_AUTH = 'https://start.exactonline.%s/api/oauth2/auth'; 
    const URL_TOKEN = 'https://start.exactonline.%s/api/oauth2/token'; 

    const GRANT_AUTHORIZATION_CODE = 'authorization_code'; 
    const GRANT_REFRESH_TOKEN = 'refresh_token'; 

    const RESPONSE_TYPE_CODE = 'code'; 

    /** @var string */ 
    public $clientId; 

    /** @var string */ 
    public $clientSecret; 

    /** @var string */ 
    public $countryCode; 

    /** @var string */ 
    public $redirectUri; 

    /** 
    * @param string $countryCode 
    * @param string $clientId 
    * @param string $clientSecret 
    */ 
    public function __construct($countryCode, $clientId, $clientSecret) 
    { 
     $this->clientId = $clientId; 
     $this->clientSecret = $clientSecret; 
     $this->countryCode = $countryCode; 
    } 

    /** 
    * @param string|NULL $redirectUri 
    * @param string $responseType 
    * @return string 
    * @throws \ErrorException 
    */ 
    public function getAuthenticationUrl($redirectUri = NULL, $responseType = self::RESPONSE_TYPE_CODE) 
    { 
     if (empty($this->redirectUri) && empty($redirectUri)) { 
      throw new \ErrorException('Redirect Uri is not specified.'); 
     } 

     $params = array(
      'client_id' => $this->clientId, 
      'redirect_uri' => $redirectUri ? $redirectUri : $this->redirectUri, 
      'response_type' => $responseType 
     ); 

     $url = sprintf(self::URL_AUTH, $this->countryCode); 

     return $url . '?' . http_build_query($params, '', '&'); 
    } 

    /** 
    * @param string $code 
    * @param string|NULL $redirectUri 
    * @param string $grantType 
    * @return array {access_token, token_type, expires_in, refresh_token} 
    * @throws \ErrorException 
    */ 
    public function getAccessToken($code, $redirectUri = NULL, $grantType = self::GRANT_AUTHORIZATION_CODE) 
    { 
     if (empty($this->redirectUri) && empty($redirectUri)) { 
      throw new \ErrorException('Redirect Uri is not specified.'); 
     } 

     $params = array(
      'code' => $code, 
      'client_id' => $this->clientId, 
      'grant_type' => $grantType, 
      'client_secret' => $this->clientSecret, 
      'redirect_uri' => $redirectUri ? $redirectUri : $this->redirectUri, 
     ); 

     $url = sprintf(self::URL_TOKEN, $this->countryCode); 

     return $this->getResponse($url, $params); 
    } 

    /** 
    * @param string $refreshToken 
    * @return array {access_token, expires_in, refresh_token} 
    */ 
    public function refreshAccessToken($refreshToken) 
    { 
     $params = array(
      'refresh_token' => $refreshToken, 
      'grant_type' => self::GRANT_REFRESH_TOKEN, 
      'client_id' => $this->clientId, 
      'client_secret' => $this->clientSecret 
     ); 

     $url = sprintf(self::URL_TOKEN, $this->countryCode); 

     return $this->getResponse($url, $params); 
    } 

    /** 
    * @param string $url 
    * @param array $params 
    * @return array|NULL 
    */ 
    public function getResponse($url, $params) 
    { 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($ch, CURLOPT_URL, $url); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
     curl_setopt($ch, CURLOPT_POST, 1); 
     curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params, '', '&')); 
     $result = curl_exec($ch); 

     $decodedResult = json_decode($result, TRUE); 

     if (isset($decodedResult['error'])) { 
      return FALSE; 
     } 

     return $decodedResult; 
    } 

    /** 
    * @param string $uri 
    */ 
    public function setRedirectUri($uri) 
    { 
     $this->redirectUri = $uri; 
    } 

} 

I woul хотел бы отправить XML-файл (xxx.xml)

<?xml version="1.0" encoding="utf-8"?> 
<eExact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="eExact-XML.xsd"> 
<Items><Item code="2M31E93_IM"><IsSalesItem>1</IsSalesItem><Sales><Price><Currency code="EUR" /><Value>80.00</Value><VAT code="VN"></VAT></Price><Unit code="pc"><Description>Piece</Description></Unit></Sales><Costs><Price><Currency code="EUR" /><Value>591.53</Value></Price></Costs><ItemAccounts><ItemAccount><Account code="0000002"></Account><IsPrimary>1</IsPrimary><SupplierItemCode>2M31E93_IM</SupplierItemCode><Purchase><Price><Currency code="EUR" /><Value>50.00</Value><VAT code="AN"></VAT></Price><Unit code="pc"><Description>Piece</Description></Unit></Purchase><CanDropShip>1</CanDropShip></ItemAccount></ItemAccounts></Item></Items> 
</eExact> 

То, что я должен добавить в моем файле PHP, чтобы отправить мой файл XML?

Thanks ВСЕ

+0

Можете ли вы разработать то, что вы пытались POST в XML для точного Интернет API? Обратите внимание, что вы можете протестировать свой XML с помощью импорта XML из точного онлайн-интерфейса. –

ответ

0

Действительно, это не так сложно.

Вы должны использовать библиотеку, которая уже делает это. Например, я использовать эту библиотеку (это очень хорошо):

https://github.com/picqer/exact-php-client

Затем я продлил подключение добавить ReadXml и WriteXml свойства, как так:

https://gist.github.com/alexjeen/6211c363c4efd4c3034cb3f81f7520bf

И тогда вы просто позвонить Класс RawConnection вместо обычного класса подключения библиотеки:

$connection = new \app\exact\RawConnection(); 
$connection->setRedirectUrl(Yii::$app->params['exact_redirect_url']); 
$connection->setExactClientId(Yii::$app->params['exact_client_id']); 
$connection->setExactClientSecret(Yii::$app->params['exact_client_secret']); 

А затем использовать его следующим образом:

$simpleXmlElement = $connection->getXml(1337, 'GLTransactions'); 

или опубликовать некоторые XML:

$simpleXmlElement = $connection->postXml(1337, 'GLTransactions', '<xmlstringhere>'); 
Смежные вопросы