diff --git a/src/AbstractConnection.php b/src/AbstractConnection.php index 1354770..3008bf3 100644 --- a/src/AbstractConnection.php +++ b/src/AbstractConnection.php @@ -56,7 +56,7 @@ abstract class AbstractConnection extends Component implements ConnectionInterfa protected $_handler; /** - * @var QueryBuilder the query builder for this connection + * @var AbstractQueryBuilder the query builder for this connection */ protected $_builder; @@ -77,6 +77,10 @@ abstract class AbstractConnection extends Component implements ConnectionInterfa */ protected $_errorChecker; + /** + * @param null $dbname + * @return ConnectionInterface|AbstractConnection + */ public static function getDb($dbname = null) { return $dbname ? Yii::$app->get($dbname) : Yii::$container->get(ConnectionInterface::class); @@ -144,7 +148,7 @@ public function createCommand(array $config = []) } /** - * @return QueryBuilder the query builder for this connection + * @return AbstractQueryBuilder the query builder for this connection */ public function getQueryBuilder() { @@ -220,45 +224,30 @@ public function setErrorChecker($checker) } /** - * Checks response with checkError method and raises exception if error. + * Checks response method and raises exception if error found. * @param ResponseInterface $response response data from API - * @throws ErrorResponseException - * @return mixed response data + * @throws ResponseErrorException when response is invalid */ public function checkResponse(ResponseInterface $response) - { - $error = $this->checkError($response); - if ($error) { - throw new ErrorResponseException($error, [ - 'request' => $response->getRequest()->getParts(), - 'response' => $response->getData(), - ]); - } - } - - /** - * Checks response with errorChecker callback and returns error text if error. - * @param ResponseInterface $response - * @return string|false error text or false - */ - public function checkError(ResponseInterface $response) { if (isset($this->_errorChecker)) { - return call_user_func($this->_errorChecker, $response); + $error = call_user_func($this->_errorChecker, $response); } else { - return $this->isError($response); + $error = $this->getResponseError($response); + } + + if ($error) { + throw new ResponseErrorException($error, $response); } } /** - * Default error checker. TODO check something in response? + * Method checks whether the response is an error + * * @param ResponseInterface $response - * @return bool + * @return false|string the error text or boolean `false`, when the response is not an error */ - public function isError(ResponseInterface $response) - { - return false; - } + abstract public function getResponseError(ResponseInterface $response); /** * Return API base uri. diff --git a/src/AbstractQueryBuilder.php b/src/AbstractQueryBuilder.php index 0b050c8..0870a49 100644 --- a/src/AbstractQueryBuilder.php +++ b/src/AbstractQueryBuilder.php @@ -81,7 +81,7 @@ abstract public function buildBody(Query $query); * @param string $table * @param array $columns * @param array $options - * @return Request + * @return AbstractRequest */ public function insert($table, $columns, array $options = []) { @@ -93,7 +93,7 @@ public function insert($table, $columns, array $options = []) * @param string $table * @param array $columns * @param array $options - * @return Request + * @return AbstractRequest */ public function update($table, $columns, $condition = [], array $options = []) { diff --git a/src/AbstractRequest.php b/src/AbstractRequest.php index 3afe2f4..a2c6347 100644 --- a/src/AbstractRequest.php +++ b/src/AbstractRequest.php @@ -258,6 +258,9 @@ protected function prepareUserAgent() return $this->getDb()->getUserAgent(); } + /** + * @return AbstractConnection|ConnectionInterface + */ public function getDb() { return isset($this->builder) ? $this->builder->db : AbstractConnection::getDb($this->dbname); diff --git a/src/AbstractResponse.php b/src/AbstractResponse.php index cdcacce..aa71a6b 100644 --- a/src/AbstractResponse.php +++ b/src/AbstractResponse.php @@ -20,10 +20,15 @@ abstract class AbstractResponse implements ResponseInterface protected $request; /** - * @var mixed response data + * @var string response data. The property contains RAW response data + * @see decodeData() + * @see isDecoded */ protected $data; + /** + * @var bool whether response is already decoded + */ protected $isDecoded = false; public function getRequest() @@ -44,20 +49,42 @@ public function getData() public function decodeData() { $data = $this->getRawData(); - if (!$this->isRaw() && $this->isJson()) { - $data = Json::decode($data); + + if ($this->isRaw()) { + return $data; } + if ($this->isJson()) { + return Json::decode($data); + } + + // TODO: implement decoding for XML and other types + + // throw new ResponseDecodingException('Failed to detect response data type', $this); + // TODO: throw exception instead of returning return $data; } + /** + * Method returns RAW request data + * + * @return string + */ abstract public function getRawData(); + /** + * Whether the request is RAW and should not be decoded + * @return bool + */ public function isRaw() { return $this->request->isRaw(); } + /** + * Method checks whether response is a JSON response + * @return bool + */ public function isJson() { return !empty(preg_grep('|application/json|i', $this->getHeader('Content-Type'))); diff --git a/src/ActiveQuery.php b/src/ActiveQuery.php index fbc5577..ee1ad58 100644 --- a/src/ActiveQuery.php +++ b/src/ActiveQuery.php @@ -10,6 +10,7 @@ namespace hiqdev\hiart; +use hiqdev\hiart\rest\QueryBuilder; use yii\db\ActiveQueryInterface; use yii\db\ActiveQueryTrait; use yii\db\ActiveRelationTrait; diff --git a/src/ActiveRecord.php b/src/ActiveRecord.php index 3f7e110..f596a9f 100644 --- a/src/ActiveRecord.php +++ b/src/ActiveRecord.php @@ -25,7 +25,7 @@ class ActiveRecord extends BaseActiveRecord * By default, the "hiart" application component is used as the database connection. * You may override this method if you want to use a different database connection. * - * @return Connection the database connection used by this AR class + * @return AbstractConnection the database connection used by this AR class */ public static function getDb() { diff --git a/src/Collection.php b/src/Collection.php index cde5f0a..e8e1974 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -334,7 +334,7 @@ public function insert($runValidation = true, $attributes = null, array $options $model->afterSave(true, $changedAttributes); } - $this->afterSave(true); + $this->afterSave(); return true; } diff --git a/src/Command.php b/src/Command.php index 4303da1..5247148 100644 --- a/src/Command.php +++ b/src/Command.php @@ -18,7 +18,7 @@ class Command extends \yii\base\Component { /** - * @var Connection + * @var AbstractConnection */ public $db; diff --git a/src/Exception.php b/src/Exception.php index a78f839..9e48ae8 100644 --- a/src/Exception.php +++ b/src/Exception.php @@ -10,6 +10,9 @@ namespace hiqdev\hiart; +/** + * Class Exception represent general exception occurred in HiArt + */ class Exception extends \yii\db\Exception { /** diff --git a/src/QueryBuilderInterface.php b/src/QueryBuilderInterface.php index 47b5ba2..3682e4d 100644 --- a/src/QueryBuilderInterface.php +++ b/src/QueryBuilderInterface.php @@ -37,4 +37,6 @@ public function buildQueryParams(Query $query); public function buildFormParams(Query $query); public function buildBody(Query $query); + + public function prepare(Query $query); } diff --git a/src/RequestErrorException.php b/src/RequestErrorException.php index 0880525..3d9fbca 100644 --- a/src/RequestErrorException.php +++ b/src/RequestErrorException.php @@ -11,12 +11,37 @@ namespace hiqdev\hiart; /** - * Request error exception. - * - * For exceptions during request sending. + * Class RequestErrorException represents an error occurred during the request sending */ class RequestErrorException extends Exception { + /** + * @var RequestInterface + */ + protected $request; + + /** + * RequestErrorException constructor. + * + * @param string $message + * @param RequestInterface $request + * @param array $errorInfo + * @param int $code + * @param \Exception|null $previous + */ + public function __construct( + $message, + RequestInterface $request, + array $errorInfo = [], + $code = 0, + \Exception $previous = null + ) { + $this->request = $request; + $errorInfo = array_merge($this->getDetailsArray(), $errorInfo); + + parent::__construct($message, $errorInfo, $code, $previous); + } + /** * @return RequestInterface */ @@ -24,4 +49,18 @@ public function getRequest() { return $this->errorInfo['request']; } + + /** + * @return array + */ + protected function getDetailsArray() + { + $request = $this->getRequest(); + + return [ + 'method' => $request->getMethod(), + 'uri' => $request->getFullUri(), + 'body' => $request->getBody(), + ]; + } } diff --git a/src/RequestInterface.php b/src/RequestInterface.php index 1c7c1af..4e18563 100644 --- a/src/RequestInterface.php +++ b/src/RequestInterface.php @@ -10,7 +10,30 @@ namespace hiqdev\hiart; +use hiqdev\hiart\curl\Response; + interface RequestInterface extends \Serializable { + /** + * @param array $options + * @return Response + * @throws RequestErrorException + */ public function send($options = []); + + /** + * @return string + */ + public function getBody(); + + /** + * @return string + */ + public function getFullUri(); + + /** + * Method returns the Request method in the uppercase, e.g. GET, POST, DELETE + * @return string + */ + public function getMethod(); } diff --git a/src/ResponseDecodingException.php b/src/ResponseDecodingException.php new file mode 100644 index 0000000..b91cf47 --- /dev/null +++ b/src/ResponseDecodingException.php @@ -0,0 +1,33 @@ +getRequest(); + $response = $this->getResponse(); + + return [ + 'statusCode' => $response->getStatusCode(), + 'responseData' => $response->getRawData(), + 'request' => [ + 'method' => $request->getMethod(), + 'uri' => $request->getFullUri(), + 'body' => $request->getBody(), + ], + ]; + } +} diff --git a/src/ResponseErrorException.php b/src/ResponseErrorException.php index 97ea331..b6c21a8 100644 --- a/src/ResponseErrorException.php +++ b/src/ResponseErrorException.php @@ -11,17 +11,77 @@ namespace hiqdev\hiart; /** - * Response error exception. - * - * For exceptions during response processing. + * Class ResponseErrorException represent exception occurred during the response processing. */ class ResponseErrorException extends Exception { + /** + * @var ResponseInterface + */ + protected $response; + + /** + * ResponseErrorException constructor + * + * @param string $message the error message + * @param ResponseInterface $response + * @param array $errorInfo + * @param int $code + * @param \Exception|null $previous + */ + public function __construct( + $message, + ResponseInterface $response, + array $errorInfo = [], + $code = 0, + \Exception $previous = null + ) { + $this->response = $response; + $errorInfo = array_merge($this->getDetailsArray(), $errorInfo); + + parent::__construct($message, $errorInfo, $code, $previous); + } + /** * @return ResponseInterface */ public function getResponse() { - return $this->errorInfo['response']; + return $this->response; + } + + /** + * @return RequestInterface + */ + public function getRequest() + { + return $this->response->getRequest(); + } + + /** + * @return mixed + */ + public function getResponseData() + { + return $this->getResponse()->getData(); + } + + /** + * @return array + */ + protected function getDetailsArray() + { + $request = $this->getRequest(); + $response = $this->getResponse(); + + return [ + 'statusCode' => $response->getStatusCode(), + 'responseData' => $response->getData(), + 'request' => [ + 'method' => $request->getMethod(), + 'uri' => $request->getFullUri(), + 'body' => $request->getBody(), + ], + ]; } } diff --git a/src/ResponseInterface.php b/src/ResponseInterface.php index 72cd5a4..6be6c78 100644 --- a/src/ResponseInterface.php +++ b/src/ResponseInterface.php @@ -12,6 +12,9 @@ interface ResponseInterface { + /** + * @return RequestInterface + */ public function getRequest(); public function getData(); @@ -19,4 +22,8 @@ public function getData(); public function getRawData(); public function getHeader($name); + + public function getStatusCode(); + + public function getReasonPhrase(); } diff --git a/src/curl/Request.php b/src/curl/Request.php index 404ea6c..6dcab75 100644 --- a/src/curl/Request.php +++ b/src/curl/Request.php @@ -13,15 +13,12 @@ use hiqdev\hiart\AbstractRequest; /** - * cURL request implementation. - * - * @author Andrii Vasyliev + * Class Request represents request using cURL library */ class Request extends AbstractRequest { - protected $workerClass = RequestWorker::class; - - protected function createWorker() + public function send($options = []) { + } } diff --git a/src/curl/Response.php b/src/curl/Response.php index b4e6e14..391713e 100644 --- a/src/curl/Response.php +++ b/src/curl/Response.php @@ -19,8 +19,23 @@ */ class Response extends AbstractResponse { - /** - * @var ResponseWorker - */ - protected $worker; + public function getRawData() + { + + } + + public function getHeader($name) + { + + } + + public function getStatusCode() + { + + } + + public function getReasonPhrase() + { + + } } diff --git a/src/rest/Connection.php b/src/rest/Connection.php index 9a032e6..bbc9dcc 100644 --- a/src/rest/Connection.php +++ b/src/rest/Connection.php @@ -17,16 +17,20 @@ class Connection extends \hiqdev\hiart\AbstractConnection { public $queryBuilderClass = QueryBuilder::class; - public function checkResponse(ResponseInterface $response) + /** + * Method checks whether the response is an error + * + * @param ResponseInterface $response + * @return false|string the error text or boolean `false`, when the response is not an error + */ + public function getResponseError(ResponseInterface $response) { $code = $response->getStatusCode(); if ($code >= 200 && $code < 300) { - return; + return false; } - throw new ResponseErrorException($response->getReasonPhrase(), [ - 'request' => $response->getRequest()->getParts(), - 'response' => $response->getData(), - ], $code); + return $response->getReasonPhrase(); + } }