Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\ScanbotApi\Client;
|
||||
|
||||
class CurlHttpClient
|
||||
{
|
||||
protected $url;
|
||||
protected $method;
|
||||
protected $header;
|
||||
protected $post;
|
||||
|
||||
// Nachfolgende Properties sind erst nach dem Absenden gefüllt
|
||||
protected $errorCode;
|
||||
protected $errorMessage;
|
||||
protected $responseContent;
|
||||
protected $responseDebugInfo;
|
||||
protected $responseStatusCode;
|
||||
protected $responseContentType;
|
||||
|
||||
protected $isSent = false;
|
||||
protected $hasError = false;
|
||||
|
||||
/**
|
||||
* @param string $method [GET|POST|PUT]
|
||||
* @param string $url
|
||||
* @param array $header HTTP-Header
|
||||
* @param array|null $post Nutzdaten für POST-/PUT-Requests (GET-Parameter in URL übergeben)
|
||||
*/
|
||||
public function __construct($method, $url, array $header = [], $post = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->method = strtoupper($method);
|
||||
$this->header = $header;
|
||||
$this->post = $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetContent()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return $this->responseContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function IsSent()
|
||||
{
|
||||
return $this->isSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request abschicken
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function Send()
|
||||
{
|
||||
$this->isSent = true;
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||
if ($this->method === 'POST') {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->post);
|
||||
}
|
||||
if ($this->method === 'PUT') {
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->post);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
|
||||
$this->responseContent = curl_exec($ch);
|
||||
$this->responseStatusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
|
||||
$this->responseContentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
$this->responseDebugInfo = curl_getinfo($ch);
|
||||
|
||||
if ($this->responseContent === false) {
|
||||
$this->hasError = true;
|
||||
$this->errorCode = curl_errno($ch);
|
||||
$this->errorMessage = curl_error($ch);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetStatusCode()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return (int)$this->responseStatusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetDebugInfo()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return $this->responseDebugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function HasError()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return $this->hasError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetErrorCode()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetErrorMessage()
|
||||
{
|
||||
if (!$this->IsSent()) {
|
||||
$this->Send();
|
||||
}
|
||||
|
||||
return $this->errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\ScanbotApi\Client;
|
||||
|
||||
use Xentral\Components\ScanbotApi\Exception\RuntimeException;
|
||||
|
||||
class ScanbotApiOcrClient
|
||||
{
|
||||
/** @var string $apiUrl */
|
||||
private $apiUrl;
|
||||
|
||||
/** @var string $apiKey */
|
||||
private $apiKey;
|
||||
|
||||
/** @var array $result */
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* @var string $resultHandle
|
||||
* Referenz-ID zum Invoice-Recognition-Task
|
||||
* Unter dem Handle lässt sich das Ergebnis der OCR-Erkennung abrufen.
|
||||
* Das Handle wird auch benötigt um die korrigierten Daten zurückzumelden.
|
||||
*/
|
||||
private $resultHandle;
|
||||
|
||||
/**
|
||||
* @param string $apiUrl
|
||||
* @param string $apiKey
|
||||
*/
|
||||
public function __construct(string $apiUrl, string $apiKey)
|
||||
{
|
||||
if (empty($apiUrl)) {
|
||||
throw new RuntimeException('Api-URL can not be empty.');
|
||||
}
|
||||
if (empty($apiKey)) {
|
||||
throw new RuntimeException('Api-Key can not be empty.');
|
||||
}
|
||||
$this->apiUrl = $apiUrl;
|
||||
$this->apiKey = $apiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filePath Absoluter Dateipfad
|
||||
* @param string $fileMimeType [image/jpeg|application/pdf]
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fetchApi(string $filePath, string $fileMimeType): void
|
||||
{
|
||||
// Datei hochladen + FileHandle abholen
|
||||
$fileHandle = $this->fetchFileHandle($filePath, $fileMimeType);
|
||||
|
||||
// Handle zum Abfragen es Ergebnisses abholen
|
||||
$this->resultHandle = $this->fetchResultHandle($fileHandle);
|
||||
|
||||
// Anhand des ResultHandles das Ergebnis abholen
|
||||
$this->pollResult($this->resultHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* API-Ergebnis als Array
|
||||
*
|
||||
* Das Ergebnis hat folgende Struktur:
|
||||
* [
|
||||
* 'IBAN' => array|null,
|
||||
* 'invoiceDate' => array|null,
|
||||
* 'invoiceNumber' => array|null,
|
||||
* 'orderId' => array|null,
|
||||
* 'totalAmount' => array|null,
|
||||
* 'totalTax' => array|null,
|
||||
* 'hocrOutput' => string,
|
||||
* ]
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResult(): array
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResultHandle(): string
|
||||
{
|
||||
return $this->resultHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @param string $fileMimeType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function fetchFileHandle(string $filePath, string $fileMimeType): string
|
||||
{
|
||||
if (!is_file($filePath)) {
|
||||
throw new RuntimeException(sprintf('Datei "%s" nicht gefunden.', $filePath));
|
||||
}
|
||||
|
||||
$url = $this->apiUrl . '/file';
|
||||
$header = [
|
||||
'Content-Type: ' . $fileMimeType,
|
||||
'x-api-key: ' . $this->apiKey,
|
||||
];
|
||||
$curlFile = curl_file_create($filePath, $fileMimeType);
|
||||
|
||||
$client = new CurlHttpClient('PUT', $url, $header, [$curlFile]);
|
||||
|
||||
if ($client->HasError()) {
|
||||
throw new RuntimeException(sprintf('Curl-Fehler: %s', $client->GetErrorMessage()));
|
||||
}
|
||||
|
||||
$result = $client->GetContent();
|
||||
$arrayResult = json_decode($result, true);
|
||||
|
||||
if (json_last_error() > 0) {
|
||||
throw new RuntimeException(sprintf('JSON-Fehler: %s', json_last_error_msg()));
|
||||
}
|
||||
|
||||
if (!empty($arrayResult['message'])) {
|
||||
throw new RuntimeException(sprintf('API-Fehler: %s', $arrayResult['message']));
|
||||
}
|
||||
|
||||
return $arrayResult['handle'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileHandle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function fetchResultHandle(string $fileHandle): string
|
||||
{
|
||||
$url = $this->apiUrl . '/invoice/' . $fileHandle;
|
||||
$header = [
|
||||
'Accept: */*',
|
||||
'x-api-key: ' . $this->apiKey,
|
||||
];
|
||||
|
||||
$client = new CurlHttpClient('POST', $url, $header);
|
||||
|
||||
if ($client->HasError()) {
|
||||
throw new RuntimeException(sprintf('Curl-Fehler: %s', $client->GetErrorMessage()));
|
||||
}
|
||||
|
||||
$result = $client->GetContent();
|
||||
$arrayResult = json_decode($result, true);
|
||||
|
||||
if (json_last_error() > 0) {
|
||||
throw new RuntimeException(sprintf('JSON-Fehler: %s', json_last_error_msg()));
|
||||
}
|
||||
|
||||
if (!empty($arrayResult['message'])) {
|
||||
throw new RuntimeException(sprintf('API-Fehler: %s', $arrayResult['message']));
|
||||
}
|
||||
|
||||
return $arrayResult['handle'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resultHandle
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function pollResult(string $resultHandle)
|
||||
{
|
||||
for ($try = 1; $try < 7; $try++) {
|
||||
$statusCode = $this->sendPollRequest($resultHandle);
|
||||
if ($statusCode === 200) {
|
||||
// Beim HTTP-Status 200 ist entweder ein Ergebnis zurückgekommen, oder ein Fehler > Schleife beenden
|
||||
break;
|
||||
}
|
||||
|
||||
// Beim HTTP-Staus 404 ist noch kein Ergebnis verfügbar > Kurze Pause und weiter pollen...
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
// Schleife ist ergebnislos durchgelaufen
|
||||
if ($this->result === null) {
|
||||
throw new RuntimeException('Timeout: Kein Ergebnis von der API.');
|
||||
}
|
||||
|
||||
// Ergebnis ist da > Versuchen JSON zu lesen
|
||||
$arrayResult = json_decode($this->result, true);
|
||||
if (json_last_error() > 0) {
|
||||
throw new RuntimeException(sprintf('JSON-Fehler: %s', json_last_error_msg()));
|
||||
}
|
||||
|
||||
if (isset($arrayResult['message'])) {
|
||||
throw new RuntimeException(sprintf('API-Meldung: %s', $arrayResult['message']));
|
||||
}
|
||||
if (isset($arrayResult['errorCode']) && isset($arrayResult['error'])) {
|
||||
throw new RuntimeException(
|
||||
sprintf('API-Fehler: Code #%s %s', $arrayResult['errorCode'], $arrayResult['error'])
|
||||
);
|
||||
}
|
||||
|
||||
// Wenn Programm bis hierhin durchgelaufen ist,
|
||||
// dann ist $this->result mit API-Ergebnis gefüllt
|
||||
$this->result = $arrayResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resultHandle
|
||||
*
|
||||
* @return int HTTP-Statuscode
|
||||
*/
|
||||
private function sendPollRequest(string $resultHandle): int
|
||||
{
|
||||
$url = $this->apiUrl . '/file/' . $resultHandle;
|
||||
$header = [
|
||||
'Accept: */*',
|
||||
'x-api-key: ' . $this->apiKey,
|
||||
];
|
||||
|
||||
$client = new CurlHttpClient('GET', $url, $header);
|
||||
$content = $client->GetContent();
|
||||
$httpCode = $client->GetStatusCode();
|
||||
|
||||
if ($client->HasError()) {
|
||||
throw new RuntimeException(sprintf('Curl-Fehler: %s', $client->GetErrorMessage()));
|
||||
}
|
||||
|
||||
// Beim HTTP-Status 200 ist entweder ein Ergebnis zurückgekommen, oder ein Fehler; aber immer als JSON
|
||||
// Beim HTTP-Staus 404 ist noch kein Ergebnis verfügbar > nochmal pollen...
|
||||
if ($httpCode === 200) {
|
||||
$this->result = $content;
|
||||
}
|
||||
|
||||
return $httpCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\ScanbotApi\Client;
|
||||
|
||||
use Xentral\Components\ScanbotApi\Exception\RuntimeException;
|
||||
|
||||
class ScanbotApiRegistrationClient
|
||||
{
|
||||
/** @var string $apiUrl */
|
||||
private $apiUrl;
|
||||
|
||||
/** @var string $clientId ClientID von Xentral bei freigeist (ist gleich für alle Xentral-Kunden) */
|
||||
private $clientId;
|
||||
|
||||
/**
|
||||
* @param string $apiUrl
|
||||
* @param string $clientId
|
||||
*/
|
||||
public function __construct(string $apiUrl, string $clientId)
|
||||
{
|
||||
if (empty($apiUrl)) {
|
||||
throw new RuntimeException('ApiURL can not be empty.');
|
||||
}
|
||||
if (empty($clientId)) {
|
||||
throw new RuntimeException('ClientID can not be empty.');
|
||||
}
|
||||
$this->apiUrl = $apiUrl;
|
||||
$this->clientId = $clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $companyMail Pro Mailadresse kann nur ein ApiKey registriert werden
|
||||
* @param string $companyName
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register(string $companyMail, string $companyName): array
|
||||
{
|
||||
if (empty($companyMail)) {
|
||||
throw new RuntimeException('Mail parameter can not be empty.');
|
||||
}
|
||||
if (empty($companyName)) {
|
||||
throw new RuntimeException('Name parameter can not be empty.');
|
||||
}
|
||||
|
||||
$url = $this->apiUrl . '/createApiKey?' . sprintf(
|
||||
'email=%s&company=%s&client_id=%s',
|
||||
rawurlencode($companyMail),
|
||||
rawurlencode($companyName),
|
||||
$this->clientId
|
||||
);
|
||||
|
||||
$client = new CurlHttpClient('POST', $url);
|
||||
|
||||
if ($client->HasError()) {
|
||||
throw new RuntimeException(sprintf('Curl-Fehler: %s', $client->GetErrorMessage()));
|
||||
}
|
||||
|
||||
$result = $client->GetContent();
|
||||
$arrayResult = json_decode($result, true);
|
||||
|
||||
if (json_last_error() > 0) {
|
||||
throw new RuntimeException(sprintf('JSON-Fehler: %s', json_last_error_msg()));
|
||||
}
|
||||
|
||||
if (isset($arrayResult['error'])) {
|
||||
throw new RuntimeException(sprintf('API-Fehler: %s', $arrayResult['error']));
|
||||
}
|
||||
|
||||
return $arrayResult;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user