diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..e9572fb --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,40 @@ +preset: psr2 + +risky: false + +enabled: + - alpha_ordered_imports + - binary_operator_spaces + - blank_line_after_opening_tag + - cast_spaces + - concat_with_spaces + - function_typehint_space + - hash_to_slash_comment + - include + - lowercase_cast + - method_separation + - native_function_casing + - no_blank_lines_after_class_opening + - no_blank_lines_after_phpdoc + - no_blank_lines_after_return + - no_blank_lines_after_throw + - no_blank_lines_between_imports + - no_blank_lines_between_traits + - no_empty_statement + - no_extra_consecutive_blank_lines + - no_spaces_inside_offset + - no_spaces_outside_offset + - no_trailing_comma_in_singleline_array + - no_unused_imports + - no_whitespace_before_comma_in_array + - normalize_index_brace + - object_operator_without_whitespace + - return_type_declaration + - short_array_syntax + - short_scalar_cast + - single_blank_line_before_namespace + - single_quote + - trailing_comma_in_multiline_array + - unalign_double_arrow + - unalign_equals + - whitespace_after_comma_in_array diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..325ce85 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +notifications: + email: false + +language: php + +php: + - 7.1 + +script: echo "skip" diff --git a/src/Client.php b/src/Client.php index 852d4f1..e4d7f7a 100644 --- a/src/Client.php +++ b/src/Client.php @@ -9,15 +9,11 @@ use Dadata\Response\Name; use Dadata\Response\Passport; use Dadata\Response\Phone; -use Dadata\Response\Vehicle; use Dadata\Response\Suggestions\Party; -use Exception; +use Dadata\Response\Vehicle; use GuzzleHttp\ClientInterface; +use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Psr7\Request; -use InvalidArgumentException; -use ReflectionClass; -use ReflectionProperty; -use RuntimeException; /** * Class Client @@ -28,19 +24,21 @@ class Client * Исходное значение распознано уверенно. Не требуется ручная проверка */ const QC_OK = 0; + /** * Исходное значение распознано с допущениями или не распознано. Требуется ручная проверка */ const QC_UNSURE = 1; + /** * Исходное значение пустое или заведомо "мусорное" */ const QC_INVALID = 2; - + const METHOD_GET = 'GET'; - + const METHOD_POST = 'POST'; - + /** * @var string */ @@ -92,8 +90,9 @@ public function __construct(ClientInterface $httpClient, array $config = []) * * @return Address * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanAddress($address) { @@ -111,14 +110,15 @@ public function cleanAddress($address) * * @return Phone * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanPhone($phone) { $response = $this->query($this->prepareUri('clean/phone'), [$phone]); /** @var Phone $result */ - $result = $this->populate(new Phone, $response); + $result = $this->populate(new Phone(), $response); return $result; } @@ -130,8 +130,9 @@ public function cleanPhone($phone) * * @return Passport * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanPassport($passport) { @@ -149,8 +150,9 @@ public function cleanPassport($passport) * * @return Name * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanName($name) { @@ -168,14 +170,15 @@ public function cleanName($name) * * @return Email * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanEmail($email) { $response = $this->query($this->prepareUri('clean/email'), [$email]); /** @var Email $result */ - $result = $this->populate(new Email, $response); + $result = $this->populate(new Email(), $response); return $result; } @@ -187,14 +190,15 @@ public function cleanEmail($email) * * @return Date * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanDate($date) { $response = $this->query($this->prepareUri('clean/birthdate'), [$date]); /** @var Date $result */ - $result = $this->populate(new Date, $response); + $result = $this->populate(new Date(), $response); return $result; } @@ -206,14 +210,15 @@ public function cleanDate($date) * * @return Vehicle * @throws \ReflectionException - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function cleanVehicle($vehicle) { $response = $this->query($this->prepareUri('clean/vehicle'), [$vehicle]); /** @var Vehicle $result */ - $result = $this->populate(new Vehicle, $response); + $result = $this->populate(new Vehicle(), $response); return $result; } @@ -222,33 +227,35 @@ public function cleanVehicle($vehicle) * Gets balance. * * @return float - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ public function getBalance() { $response = $this->query($this->prepareUri('profile/balance'), [], self::METHOD_GET); - return (double) $response; + return (float) $response; } /** * Requests API. * * @param string $uri - * @param array $params + * @param array $params * * @param string $method * * @return array - * @throws RuntimeException - * @throws InvalidArgumentException + * @throws \RuntimeException + * @throws \InvalidArgumentException + * @throws GuzzleException */ protected function query($uri, array $params = [], $method = self::METHOD_POST) { $request = new Request($method, $uri, [ - 'Content-Type' => 'application/json', + 'Content-Type' => 'application/json', 'Authorization' => 'Token ' . $this->token, - 'X-Secret' => $this->secret, + 'X-Secret' => $this->secret, ], 0 < count($params) ? json_encode($params) : null); $response = $this->httpClient->send($request, $this->httpOptions); @@ -256,11 +263,11 @@ protected function query($uri, array $params = [], $method = self::METHOD_POST) $result = json_decode($response->getBody(), true); if (json_last_error() !== JSON_ERROR_NONE) { - throw new RuntimeException('Error parsing response: ' . json_last_error_msg()); + throw new \RuntimeException('Error parsing response: ' . json_last_error_msg()); } if (empty($result)) { - throw new RuntimeException('Empty result'); + throw new \RuntimeException('Empty result'); } return array_shift($result); @@ -288,9 +295,9 @@ protected function prepareUri($endpoint) */ protected function populate(AbstractResponse $object, array $data) { - $reflect = new ReflectionClass($object); + $reflect = new \ReflectionClass($object); - $properties = $reflect->getProperties(ReflectionProperty::IS_PUBLIC); + $properties = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC); foreach ($properties as $property) { if (array_key_exists($property->name, $data)) { @@ -309,10 +316,14 @@ protected function populate(AbstractResponse $object, array $data) * @return Party\Party * @throws \ReflectionException */ - protected function populateParty (array $response) + protected function populateParty(array $response) { - list($name, $post) = array_values($response['data']['management']); - $management = new Party\ManagementDto($name, $post); + $management = null; + $managementData = $response['data']['management']; + if (is_array($managementData) && array_key_exists('name', $managementData) && array_key_exists('post', $managementData)) { + list($name, $post) = array_values($response['data']['management']); + $management = new Party\ManagementDto($name, $post); + } list($code, $full, $short) = array_values($response['data']['opf']); $opf = new Party\OpfDto($code, $full, $short); @@ -326,7 +337,10 @@ protected function populateParty (array $response) list($value, $unrestrictedValue) = array_values($response['data']['address']); $simpleAddress = new Party\AddressDto($value, $unrestrictedValue); - $address = $this->populate(new Address(), $response['data']['address']['data']); + $address = null; + if (is_array($response['data']['address']['data'])) { + $address = $this->populate(new Address(), $response['data']['address']['data']); + } return new Party\Party( $response['value'], @@ -350,11 +364,11 @@ protected function populateParty (array $response) /** * Guesses and converts property type by phpdoc comment. * - * @param ReflectionProperty $property + * @param \ReflectionProperty $property * @param mixed $value * @return mixed */ - protected function getValueByAnnotatedType(ReflectionProperty $property, $value) + protected function getValueByAnnotatedType(\ReflectionProperty $property, $value) { $comment = $property->getDocComment(); if (preg_match('/@var (.+?)(\|null)? /', $comment, $matches)) { @@ -375,12 +389,13 @@ protected function getValueByAnnotatedType(ReflectionProperty $property, $value) /** * @param string $ip * @return null|Address - * @throws Exception + * @throws \Exception + * @throws GuzzleException */ public function detectAddressByIp($ip) { $request = new Request('get', $this->baseSuggestionsUrl . 'detectAddressByIp' . '?ip=' . $ip, [ - 'Accept' => 'application/json', + 'Accept' => 'application/json', 'Authorization' => 'Token ' . $this->token, ]); @@ -389,11 +404,11 @@ public function detectAddressByIp($ip) $result = json_decode($response->getBody(), true); if (json_last_error() !== JSON_ERROR_NONE) { - throw new RuntimeException('Error parsing response: ' . json_last_error_msg()); + throw new \RuntimeException('Error parsing response: ' . json_last_error_msg()); } if (!array_key_exists('location', $result)) { - throw new Exception('Required key "location" is missing'); + throw new \Exception('Required key "location" is missing'); } if (null === $result['location']) { @@ -401,7 +416,7 @@ public function detectAddressByIp($ip) } if (!array_key_exists('data', $result['location'])) { - throw new Exception('Required key "data" is missing'); + throw new \Exception('Required key "data" is missing'); } if (null === $result['location']['data']) { @@ -427,6 +442,7 @@ public function detectAddressByIp($ip) * @throws \ReflectionException * @throws \RuntimeException * @throws \InvalidArgumentException + * @throws GuzzleException */ public function getAddressById($addressId) { @@ -450,10 +466,10 @@ public function getAddressById($addressId) * ФИО руководителя компании; * адресу до улицы. * - * @param $party + * @param string $party * * @return \SplObjectStorage - * @throws \GuzzleHttp\Exception\GuzzleException + * @throws GuzzleException * @throws \ReflectionException * @throws \InvalidArgumentException * @throws \RuntimeException @@ -481,6 +497,4 @@ protected function prepareSuggestionsUri($endpoint) { return $this->baseSuggestionsUrl . $endpoint; } - - } diff --git a/src/Response/Suggestions/Party/Party.php b/src/Response/Suggestions/Party/Party.php index 0d8bf0c..a1be3be 100644 --- a/src/Response/Suggestions/Party/Party.php +++ b/src/Response/Suggestions/Party/Party.php @@ -28,7 +28,7 @@ class Party extends AbstractResponse */ private $kpp; /** - * @var ManagementDto Информация о руководителе + * @var ManagementDto|null Информация о руководителе */ private $management; /** @@ -76,11 +76,28 @@ class Party extends AbstractResponse */ private $simpleAddress; + /** + * @param $value + * @param $unrestrictedValue + * @param $kpp + * @param ManagementDto|null $management + * @param $branchType + * @param $type + * @param OpfDto $opf + * @param NameDto $name + * @param $inn + * @param $ogrn + * @param $okpo + * @param $okved + * @param StateDto $state + * @param AddressDto $simpleAddress + * @param Address|null $address + */ public function __construct( $value, $unrestrictedValue, $kpp, - ManagementDto $management, + $management, $branchType, $type, OpfDto $opf, @@ -91,11 +108,18 @@ public function __construct( $okved, StateDto $state, AddressDto $simpleAddress, - Address $address + $address ) { $this->value = $value; $this->unrestrictedValue = $unrestrictedValue; $this->kpp = $kpp; + if ($management !== null && !$management instanceof ManagementDto) { + throw new \InvalidArgumentException(sprintf( + 'Argument $management passed to Part::__construct must be instance of %s, %s given', + ManagementDto::class, + gettype($management) + )); + } $this->management = $management; $this->branchType = $branchType; $this->type = $type; @@ -106,6 +130,13 @@ public function __construct( $this->okpo = $okpo; $this->okved = $okved; $this->state = $state; + if ($address !== null && !$address instanceof Address) { + throw new \InvalidArgumentException(sprintf( + 'Argument $address passed to Part::__construct must be instance of %s, %s given', + Address::class, + gettype($address) + )); + } $this->address = $address; $this->simpleAddress = $simpleAddress; }