diff --git a/composer.json b/composer.json index 705a250..ed77850 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "OfflineAgency\\FattureInCloud\\FattureInCloudServiceProvider" ], "aliases": { - "FattureInCloud": "GarbinLuca\\FattureInCloud\\FattureInCloudFacade" + "FattureInCloud": "OfflineAgency\\FattureInCloud\\FattureInCloudFacade" } } } diff --git a/config/fatture-in-cloud.php b/config/fatture-in-cloud.php index 6f93599..db64bd6 100644 --- a/config/fatture-in-cloud.php +++ b/config/fatture-in-cloud.php @@ -50,4 +50,7 @@ 'message' => 'Non è possibile completare la richiesta perché è stato raggiunto il limite massimo di anagrafiche.', ], ], + 'timeout-errors-codes' => [ + 2002 + ] ]; diff --git a/src/Auth.php b/src/Auth.php index e7d42dd..9965fde 100644 --- a/src/Auth.php +++ b/src/Auth.php @@ -3,23 +3,24 @@ namespace OfflineAgency\FattureInCloud; use Exception; +use OfflineAgency\FattureInCloud\Events\DocumentRequestPerformed; class Auth { - private $errors = []; + private $attempts; private $params = []; /** - * Auth constructor. - * - * @param string $apiUid - * @param string $apiKey - * + * @param string $apiUid + * @param string $apiKey * @throws Exception */ - public function __construct($apiUid = '', $apiKey = '') + public function __construct( + string $apiUid = '', + string $apiKey = '' + ) { - $this->errors = config('fatture-in-cloud.errors'); + $this->attempts = 0; if (empty($apiUid) || empty($apiKey)) { throw new \Exception('You need to pass apiUid and apiKey'); @@ -32,68 +33,234 @@ public function __construct($apiUid = '', $apiKey = '') } /** - * Exec API call. - * - * @param string $url - * @param array $data - * @param string $method - * @return array|mixed + * @param string $url + * @param array $data + * @param string $method + * @param array $additional_data + * @param string $action + * @param string $type + * @return mixed|object */ - private function call($url = '', $data = [], $method = 'post') + private function call( + string $url = '', + array $data = [], + string $method = 'post', + array $additional_data = [], + string $action = '', + string $type = '' + ) { try { - $url = config('fatture-in-cloud.endpoint').$url; + $url = config('fatture-in-cloud.endpoint') . $url; $options = [ 'http' => [ - 'header' => "Content-type: text/json\r\n", - 'method' => $method, + 'header' => "Content-type: text/json\r\n", + 'method' => $method, 'content' => json_encode($data), ], ]; $context = stream_context_create($options); - $result = file_get_contents($url, false, $context); + $response = file_get_contents($url, false, $context); - return self::parseResponse($result); + $response = $this->parseResponse( + $response, + $url, + $data, + $method, + $additional_data, + $action, + $type + ); + + event(new DocumentRequestPerformed( + $type, + $action, + $data, + $additional_data, + $response, + $this->parseHeaders($http_response_header) + )); + + return $response; } catch (Exception $e) { - return (object) [ - 'error' => $e->getMessage(), - 'code' => $e->getCode(), + $response = (object)[ + 'error' => $e->getMessage(), + 'code' => $e->getCode(), + 'success' => false, + ]; + + event(new DocumentRequestPerformed( + $type, + $action, + $data, + $additional_data, + $response, + $this->parseHeaders($http_response_header) + )); + + return (object)[ + 'error' => $e->getMessage(), + 'code' => $e->getCode(), 'success' => false, ]; } } /** - * Parse response. - * * @param $response + * @param $url + * @param $data + * @param $method + * @param $additional_data + * @param $action + * @param $type * @return mixed - * * @throws Exception */ - private function parseResponse($response) + private function parseResponse( + $response, + $url, + $data, + $method, + $additional_data, + $action, + $type + ) { $json = json_decode($response); - if (isset($json->error)) { - throw new \Exception($json->error, $this->errors[$json->error_code]['code']); + if ( + isset($json->error) + && isset($json->error_code) + ) { + $timeout_errors_codes = config('fatture-in-cloud.timeout-errors-codes'); + if (in_array($json->error_code, $timeout_errors_codes)) { + $this->handleThrottle( + $json, + $url, + $data, + $method, + $additional_data, + $action, + $type + ); + } else { + throw new \Exception($json->error, $json->error_code); + } } return $json; } /** - * POST call. - * + * @param $json + * @param $url + * @param $data + * @param $method + * @param $additional_data + * @param $action + * @param $type + * @throws Exception + */ + private function handleThrottle( + $json, + $url, + $data, + $method, + $additional_data, + $action, + $type + ) + { + $attempts = $this->attempts; + $times = config('nom.config', 3); + + if ($attempts < $times) { + $this->attempts++; + $seconds = $this->getRetrySeconds( + $json->error + ); + + $seconds = $seconds * 1000; + usleep($seconds); + + $this->call( + $url, + $data, + $method, + $additional_data, + $action, + $type + ); + } else { + throw new \Exception('Timeout error', 'OA0001'); + } + } + + /** + * @param $error_message + * @return float|int + */ + private function getRetrySeconds( + $error_message + ) + { + $seconds = 0; + $split_error_message = explode('Attendi ', $error_message); + if (count($split_error_message) > 1) { + $split_error_message = explode(' secondi', $split_error_message[1]); + $seconds = (int)$split_error_message[0]; + } + return $seconds * 1000; + } + + /** * @param $path - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @param string $action + * @param string $type + * @return mixed|object */ - public function post($path, $data = []) + public function post( + $path, + array $data = [], + array $additional_data = [], + string $action = '', + string $type = '' + ) { $params = array_merge($this->params, $data); - return $this->call($path, $params, 'POST'); + return $this->call( + $path, $params, + 'POST', + $additional_data, + $action, + $type + ); + } + + /** + * @param $headers + * @return array + */ + private function parseHeaders( + $headers + ): array + { + $head = array(); + foreach ($headers as $k => $v) { + $t = explode(':', $v, 2); + if (isset($t[1])) + $head[trim($t[0])] = trim($t[1]); + else { + $head[] = $v; + if (preg_match("#HTTP/[0-9\.]+\s+([0-9]+)#", $v, $out)) + $head['reponse_code'] = intval($out[1]); + } + } + return $head; } } diff --git a/src/Entities/Documenti.php b/src/Entities/Documenti.php index 06150e5..527f6d6 100644 --- a/src/Entities/Documenti.php +++ b/src/Entities/Documenti.php @@ -10,94 +10,170 @@ class Documenti extends FattureInCloud protected $docType = 'fatture'; /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function lista($data = []) + public function lista( + array $data = [], + array $additional_data = [] + ) { Request::lista($data); - return $this->auth->post("{$this->docType}/lista", $data); + return $this->auth->post( + "{$this->docType}/lista", + $data, + $additional_data, + 'lista', + $this->docType + ); } /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function dettagli($data = []) + public function dettagli( + array $data = [], + array $additional_data = [] + ) { Request::dettagli($data); - return $this->auth->post("{$this->docType}/dettagli", $data); + return $this->auth->post( + "{$this->docType}/dettagli", + $data, + $additional_data, + 'dettagli', + $this->docType + ); } /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function nuovo($data = []) + public function nuovo( + array $data = [], + array $additional_data = [] + ) { Request::nuovo($data); - return $this->auth->post("{$this->docType}/nuovo", $data); + return $this->auth->post( + "{$this->docType}/nuovo", + $data, + $additional_data, + 'nuovo', + $this->docType + ); } /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function modifica($data = []) + public function modifica( + array $data = [], + array $additional_data = [] + ) { Request::modifica($data); - return $this->auth->post("{$this->docType}/modifica", $data); + return $this->auth->post( + "{$this->docType}/modifica", + $data, + $additional_data, + 'modifica', + $this->docType + ); } /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function elimina($data = []) + public function elimina( + array $data = [], + array $additional_data = [] + ) { Request::elimina($data); - return $this->auth->post("{$this->docType}/elimina", $data); + return $this->auth->post( + "{$this->docType}/elimina", + $data, + $additional_data, + 'elimina', + $this->docType + ); } /** - * @param array $data - * @return mixed|string + * @param array $data + * @param array $additional_data + * @return array|mixed|object|string */ - public function info($data = []) + public function info( + array $data = [], + array $additional_data = [] + ) { Request::info($data); - return $this->auth->post("{$this->docType}/info", $data); + return $this->auth->post( + "{$this->docType}/info", + $data, + $additional_data, + 'info', + $this->docType + ); } /** - * @param array $data + * @param array $data + * @param array $additional_data * @return array|mixed|object|string - * - * @throws \Exception */ - public function infoMail($data = []) + public function infoMail( + array $data = [], + array $additional_data = [] + ) { Request::infoMail($data); - return $this->auth->post("{$this->docType}/infomail", $data); + return $this->auth->post( + "{$this->docType}/infomail", + $data, + $additional_data, + 'infoMail', + $this->docType + ); } /** - * @param array $data + * @param array $data + * @param array $additional_data * @return array|mixed|object|string - * - * @throws \Exception */ - public function inviaMail($data = []) + public function inviaMail( + array $data = [], + array $additional_data = [] + ) { Request::inviaMail($data); - return $this->auth->post("{$this->docType}/inviamail", $data); + return $this->auth->post( + "{$this->docType}/inviamail", + $data, + $additional_data, + 'inviaMail', + $this->docType + ); } } diff --git a/src/Events/DocumentRequestPerformed.php b/src/Events/DocumentRequestPerformed.php new file mode 100644 index 0000000..62f73d6 --- /dev/null +++ b/src/Events/DocumentRequestPerformed.php @@ -0,0 +1,129 @@ +setDocType( + $docType + ); + + $this->setMethod( + $method + ); + + $this->setRequest( + $request + ); + + $this->setAdditionalInfo( + $additional_info + ); + + $this->setResponse( + $response + ); + + $this->setResponseHeader( + $response_header + ); + } + + /* GETTERs AND SETTERs */ + + public function getDocType() + { + return $this->docType; + } + + public function setDocType( + $docType + ): void + { + $this->docType = $docType; + } + + public function getMethod() + { + return $this->method; + } + + public function setMethod( + $method + ): void + { + $this->method = $method; + } + + public function getRequest() + { + return $this->request; + } + + public function setRequest( + $request + ): void + { + $this->request = $request; + } + + public function getAdditionalInfo() + { + return $this->additional_info; + } + + public function setAdditionalInfo( + $additional_info + ): void + { + $this->additional_info = $additional_info; + } + + public function getResponse() + { + return $this->response; + } + + public function setResponse( + $response + ): void + { + $this->response = $response; + } + + public function getResponseHeader() + { + return $this->response_header; + } + + public function setResponseHeader( + $response_header + ): void + { + $this->response_header = $response_header; + } +} diff --git a/src/FattureInCloudFacade.php b/src/FattureInCloudFacade.php index 95d13f1..2270a9f 100644 --- a/src/FattureInCloudFacade.php +++ b/src/FattureInCloudFacade.php @@ -2,10 +2,12 @@ namespace OfflineAgency\FattureInCloud; -class FattureInCloudFacade extends \Illuminate\Support\Facades\Facade +use Illuminate\Support\Facades\Facade; + +class FattureInCloudFacade extends Facade { public static function getFacadeAccessor() { return 'fatture-in-cloud'; } -} \ No newline at end of file +}