275 lines
9.6 KiB
PHP
275 lines
9.6 KiB
PHP
|
<?php
|
||
|
namespace dominion\api;
|
||
|
|
||
|
use Yii;
|
||
|
use yii\console\Exception;
|
||
|
use linslin\yii2\curl;
|
||
|
|
||
|
class Swagger
|
||
|
{
|
||
|
private $url;
|
||
|
private $method;
|
||
|
private $perPage;
|
||
|
private $perPageParam;
|
||
|
private $pageParam;
|
||
|
private $params;
|
||
|
private $content;
|
||
|
private $currentPage = 1;
|
||
|
private $lastPage = false;
|
||
|
public $isRaw = false;
|
||
|
|
||
|
function __construct($apiName, $function, $params = [], $urlParams = [], $version = false, $raw = false)
|
||
|
{
|
||
|
$arConfig = $this->getConfig($apiName, $function, $urlParams, $version);
|
||
|
$this->url = $arConfig['url'];
|
||
|
$this->method = $arConfig['method'];
|
||
|
$this->perPage = $arConfig['perPage'];
|
||
|
$this->perPageParam = $arConfig['perPageParam'];
|
||
|
$this->pageParam = $arConfig['pageParam'];
|
||
|
$this->content = $arConfig['content'];
|
||
|
$this->params = $params;
|
||
|
$this->isRaw = $raw;
|
||
|
}
|
||
|
|
||
|
private function getConfig($apiName, $function, $urlParams = [], $version = false)
|
||
|
{
|
||
|
$configParams = isset(Yii::$app->params[$apiName]) ? Yii::$app->params[$apiName] : [];
|
||
|
if(empty($configParams)) {
|
||
|
throw new Exception('Отсутствует конфигурация для rest-сервиса');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['defaultVersion']) or (empty($configParams['defaultVersion']))) {
|
||
|
throw new Exception('Отсутствует дефолтная версия для rest-сервиса');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['defaultPerPage']) or (empty($configParams['defaultPerPage']))) {
|
||
|
throw new Exception('Отсутствует дефолтная конфигурация постраничной навигации rest-сервиса');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['protocol']) or empty($configParams['protocol'])) {
|
||
|
throw new Exception('Протокол rest-сервиса не указан.');
|
||
|
}
|
||
|
|
||
|
if(($configParams['protocol'] !== 'http://') and ($configParams['protocol'] !== 'https://')) {
|
||
|
throw new Exception('Протокол rest-сервиса указан неверно.');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['perPageParam']) or empty($configParams['perPageParam'])) {
|
||
|
throw new Exception('Отсутствует параметр постраничной навигации perPageParam.');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['pageParam']) or empty($configParams['pageParam'])) {
|
||
|
throw new Exception('Отсутствует парамер постраничной навигации pageParam.');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['baseUrl']) or empty($configParams['baseUrl'])) {
|
||
|
throw new Exception('Отсутствует доменное имя для rest-сервиса.');
|
||
|
}
|
||
|
|
||
|
if(empty($version)) {
|
||
|
$version = $configParams['defaultVersion'];
|
||
|
}
|
||
|
|
||
|
if(empty($configParams['version'][$version])) {
|
||
|
throw new Exception('Выбранная версия rest-сервиса отсутствует');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['version'][$version]['functions'][$function])) {
|
||
|
throw new Exception('Функция '.$function.' отсутствует в api версии '.$version);
|
||
|
}
|
||
|
|
||
|
$url = '';
|
||
|
if(is_string($configParams['version'][$version]['functions'][$function]))
|
||
|
{
|
||
|
$url = $configParams['version'][$version]['functions'][$function];
|
||
|
}
|
||
|
elseif(isset($configParams['version'][$version]['functions'][$function]['url']))
|
||
|
{
|
||
|
$url = $configParams['version'][$version]['functions'][$function]['url'];
|
||
|
}
|
||
|
if(!isset($url) or empty($url)) {
|
||
|
throw new Exception('Для функции '.$function.' отсутствует url');
|
||
|
}
|
||
|
|
||
|
if(isset($configParams['version'][$version]['functions'][$function]['content']))
|
||
|
{
|
||
|
$content = $configParams['version'][$version]['functions'][$function]['content'];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$content = $configParams['version'][$version]['content'];
|
||
|
}
|
||
|
|
||
|
if(!isset($content) or empty($content)) {
|
||
|
throw new Exception('Для функции '.$function.' отсутствует ключ массива в котором содержится ответ');
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['version'][$version]['functions'][$function]['perPage']) or empty($configParams['version'][$version]['functions'][$function]['perPage'])) {
|
||
|
$perPage = $configParams['defaultPerPage'];
|
||
|
} else {
|
||
|
$perPage = $configParams['version'][$version]['functions'][$function]['perPage'];
|
||
|
}
|
||
|
|
||
|
if(!isset($configParams['version'][$version]['functions'][$function]['method']) or
|
||
|
empty($configParams['version'][$version]['functions'][$function]['method']))
|
||
|
{
|
||
|
$method = isset($configParams['version'][$version]['method']) ? $configParams['version'][$version]['method'] : 'GET';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$method = $configParams['version'][$version]['functions'][$function]['method'];
|
||
|
}
|
||
|
|
||
|
if(!empty($urlParams)) {
|
||
|
$url = vsprintf($url, $urlParams);
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
'url' => $configParams['protocol']
|
||
|
.$configParams['baseUrl']
|
||
|
.$configParams['version'][$version]['url']
|
||
|
.$url,
|
||
|
'method' => $method,
|
||
|
'perPage' => $perPage,
|
||
|
'perPageParam' => $configParams['perPageParam'],
|
||
|
'pageParam' => $configParams['pageParam'],
|
||
|
'content' => $content,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
public function resetCounter()
|
||
|
{
|
||
|
$this->currentPage = 1;
|
||
|
$this->lastPage = false;
|
||
|
}
|
||
|
|
||
|
public function getNextPage()
|
||
|
{
|
||
|
if($this->lastPage) return false;
|
||
|
$result = [];
|
||
|
|
||
|
$response = $this->sendRequest($this->currentPage);
|
||
|
|
||
|
if(isset($response[$this->content]))
|
||
|
{
|
||
|
foreach ($response[$this->content] as $value)
|
||
|
{
|
||
|
$result[] = $value;
|
||
|
}
|
||
|
}
|
||
|
if(
|
||
|
!isset($response['_meta']['pageCount']) or
|
||
|
empty($response['_meta']['pageCount']) or
|
||
|
$response['_meta']['pageCount'] === $this->currentPage
|
||
|
) {
|
||
|
$this->lastPage = true;
|
||
|
} else {
|
||
|
$this->currentPage++;
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
public function getOne()
|
||
|
{
|
||
|
$result = $this->getNextPage();
|
||
|
return isset($result[0]) ? $result[0] : false;
|
||
|
}
|
||
|
|
||
|
public function doBatchRequest()
|
||
|
{
|
||
|
$result = [];
|
||
|
$page = 1;
|
||
|
while(true) {
|
||
|
$response = $this->sendRequest($page);
|
||
|
|
||
|
if (isset($response[$this->content]) and is_array($response[$this->content]) and !empty($response[$this->content]) ) {
|
||
|
foreach ($response[$this->content] as $value) {
|
||
|
$result[] = $value;
|
||
|
}
|
||
|
} else {
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
if(
|
||
|
!isset($response['_meta']['pageCount']) or
|
||
|
empty($response['_meta']['pageCount']) or
|
||
|
$response['_meta']['pageCount'] === $page
|
||
|
) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
unset($response);
|
||
|
$page++;
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
public function getBody()
|
||
|
{
|
||
|
return $this->isRaw ? json_encode($this->params) : json_encode(['filter' => $this->params]) ;
|
||
|
}
|
||
|
|
||
|
private function sendRequest($page = 1)
|
||
|
{
|
||
|
$curl = new curl\Curl();
|
||
|
$curl->setHeader('Content-Type', 'application/json; charset=UTF-8');
|
||
|
|
||
|
$params = [$this->perPageParam => $this->perPage, $this->pageParam => $page];
|
||
|
if (!empty($this->sort))
|
||
|
{
|
||
|
$params['sort'] = $this->sort;
|
||
|
}
|
||
|
if($this->method === 'POST')
|
||
|
{
|
||
|
$curl->setGetParams($params);
|
||
|
if(!empty($this->params))
|
||
|
{
|
||
|
$curl->setRequestBody($this->getBody());
|
||
|
}
|
||
|
$response = $curl->post($this->url,false);
|
||
|
}
|
||
|
elseif($this->method === 'GET') {
|
||
|
$curl->setGetParams(array_merge($params, ['filter' => $this->params]));
|
||
|
$response = $curl->get($this->url,false);
|
||
|
} else {
|
||
|
throw new Exception('Метод '.$this->method.' не поддерживается');
|
||
|
}
|
||
|
|
||
|
switch ($curl->responseCode) {
|
||
|
case 'timeout':
|
||
|
throw new Exception('Network timeout');
|
||
|
break;
|
||
|
case 200:
|
||
|
return $response;
|
||
|
break;
|
||
|
case 404:
|
||
|
throw new Exception('404. Page not found '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 403:
|
||
|
throw new Exception('403. Access deny '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 401:
|
||
|
throw new Exception('401. Autorization required '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 400:
|
||
|
throw new Exception('400. Bad request '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 500:
|
||
|
throw new Exception('500. Internal server error '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 503:
|
||
|
throw new Exception('503. Service unavailable '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
case 502:
|
||
|
throw new Exception('502. Bad gateway '. $this->url . ' ' . $this->getBody());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
public function setSort($str)
|
||
|
{
|
||
|
$this->sort = $str;
|
||
|
}
|
||
|
}
|