Your IP : 18.188.247.133
<?
namespace Bitrix\Socialservices\Properties;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Error;
use Bitrix\Main\ErrorCollection;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Text\Encoding;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Json;
use Bitrix\Main\Context;
Loc::loadMessages(__FILE__);
class Client
{
const SERVICE_HOST = 'https://properties.bitrix.info';
const REST_URI = '/rest/';
const REGISTER_URI = '/oauth/register/';
const SCOPE = 'ps';
const SERVICE_ACCESS_OPTION = 'properties_service_access';
const METHOD_COMMON_GET_BY_INN = 'ps.common.getByInn';
const METHOD_COMMON_GET_BY_OGRN = 'ps.common.getByOgrn';
const METHOD_ORGANIZATION_SEARCH_BY_NAME = 'ps.organization.searchByName';
const METHOD_IP_SEARCH_BY_NAME = 'ps.ip.searchByName';
const METHOD_UA_GET_BY_EDRPOU = 'ps.ua.getByEdrpou';
const METHOD_UA_GET_UO_BY_ID = 'ps.ua.getUoById';
const METHOD_UA_GET_FO_BY_ID = 'ps.ua.getFoById';
const METHOD_UA_SEARCH_UO_BY_NAME = 'ps.ua.searchUoByName';
const METHOD_UA_SEARCH_FO_BY_NAME = 'ps.ua.searchFoByName';
const METHOD_UA_SEARCH_BY_NAME = 'ps.ua.searchByName';
const METHOD_IS_SERVICE_ONLINE = 'ps.common.isOnline';
const ERROR_WRONG_INPUT = 1;
const ERROR_WRONG_LICENSE = 2;
const ERROR_SERVICE_UNAVAILABLE = 3;
const ERROR_NOTHING_FOUND = 4;
protected $httpTimeout = 5;
protected $accessSettings = null;
/** @var ErrorCollection */
protected $errorCollection;
/**
* Constructor of the client of the properties service.
*/
public function __construct()
{
$this->errorCollection = new ErrorCollection();
}
/**
* Returns properties of the organization or individual businessman by its OGRN code.
* @param string $ogrn OGRN code of the organization or individual businessman.
* @return array|false
*/
public function getByOgrn($ogrn, $showTerminated = false)
{
return $this->call(static::METHOD_COMMON_GET_BY_OGRN, array('ogrn' => $ogrn, 'showTerminated'=> $showTerminated));
}
/**
* Returns properties of the organization or individual businessman by its INN code.
* @param string $inn INN code of the organization or individual businessman.
* @return array|false
*/
public function getByInn($inn, $showTerminated = false)
{
return $this->call(static::METHOD_COMMON_GET_BY_INN, array('inn' => $inn, 'showTerminated' => $showTerminated));
}
/**
* Performs search of organizations by name and returns array of found organizations.
* @param string $name Part of the organization's name.
* @param int $limit Maximum size of returning array.
* @param int $offset Offset of the returning array.
* @return array|false Array of found organizations or false in case of error.
*/
public function searchOrganizationByName($name, $limit, $offset = 0)
{
return $this->call(static::METHOD_ORGANIZATION_SEARCH_BY_NAME, array(
'name' => $name,
'limit' => $limit,
'offset' => $offset
));
}
/**
* Performs search of individual businessmen by name and returns array of found businessmen.
* @param string $name First name (full or partial).
* @param string $secondName Second name (full or partial).
* @param string $lastName Last name (full or partial).
* @param int $limit Maximum size of returning array.
* @param int $offset Offset of the returning array.
* @return array|false Array of found businessmen or false in case of error.
*/
public function searchIpByName($name, $secondName, $lastName, $limit, $offset = 0)
{
return $this->call(static::METHOD_IP_SEARCH_BY_NAME, array(
'name' => $name,
'second_name' => $secondName,
'last_name' => $lastName,
'limit' => $limit,
'offset' => $offset
));
}
/**
* Returns properties of the ukrainian organization by its EDRPOU code.
* @param string $edrpou EDRPOU code of the organization.
* @return array|false
*/
public function uaGetByEdrpou($edrpou)
{
return $this->call(static::METHOD_UA_GET_BY_EDRPOU, array('edrpou' => $edrpou));
}
/**
* Performs search of ukrainian organization by identifier and returns its properties.
* @param int $id idenrifier of the organization.
* @return array|false Properties of found organization or false in case of error.
*/
public function uaGetUoById($id)
{
return $this->call(static::METHOD_UA_GET_UO_BY_ID, array('id' => $id));
}
/**
* Performs search of ukrainian individual businessmen by identifier and returns its properties.
* @param int $id idenrifier of the individual.
* @return array|false Properties of found individual or false in case of error.
*/
public function uaGetFoById($id)
{
return $this->call(static::METHOD_UA_GET_FO_BY_ID, array('id' => $id));
}
/**
* Performs search of ukrainian organizations by name and returns array of found organizations.
* @param string $name Part of the organization's name.
* @param int $limit Maximum size of returning array.
* @param int $offset Offset of the returning array.
* @return array|false Array of found organizations or false in case of error.
*/
public function uaSearchUoByName($name, $limit, $offset = 0)
{
return $this->call(static::METHOD_UA_SEARCH_UO_BY_NAME, array(
'name' => $name,
'limit' => $limit,
'offset' => $offset
));
}
/**
* Performs search of ukrainian individual businessmen by name and returns array of found individuals.
* @param string $name Part of the individual's name.
* @param int $limit Maximum size of returning array.
* @param int $offset Offset of the returning array.
* @return array|false Array of found individuals or false in case of error.
*/
public function uaSearchFoByName($name, $limit, $offset = 0)
{
return $this->call(static::METHOD_UA_SEARCH_FO_BY_NAME, array(
'name' => $name,
'limit' => $limit,
'offset' => $offset
));
}
/**
* Performs search of ukrainian organizations and individuals by name and returns array of found
* organizations and individuals.
* @param string $name Part of the name.
* @param int $limit Maximum size of returning array.
* @param int $offset Offset of the returning array.
* @return array|false Array of found organizations and individuals or false in case of error.
*/
public function uaSearchByName($name, $limit, $offset = 0)
{
return $this->call(static::METHOD_UA_SEARCH_BY_NAME, array(
'name' => $name,
'limit' => $limit,
'offset' => $offset
));
}
/**
* Checks service's availability.
* @return bool Returns true if service is ready and false otherwise.
*/
public function isServiceOnline()
{
return $this->call(static::METHOD_IS_SERVICE_ONLINE);
}
/**
* Performs call to the REST method and returns decoded results of the call.
* @param string $methodName Name of the REST method.
* @param array $additionalParams Parameters, that should be passed to the method.
* @param bool $licenseCheck Should client send license key as a parameter of the http request.
* @param bool $clearAccessSettings Should client clear authorization before performing http request.
* @return array|false
*/
protected function call($methodName, $additionalParams = null, $licenseCheck = false, $clearAccessSettings = false)
{
$this->errorCollection->clear();
if($clearAccessSettings)
$this->clearAccessSettings();
if(is_null($this->accessSettings))
$this->accessSettings = $this->getAccessSettings();
if($this->accessSettings === false)
return false;
if(!is_array($additionalParams))
{
$additionalParams = array();
}
else
{
$additionalParams = Encoding::convertEncodingArray($additionalParams, LANG_CHARSET, "utf-8");
}
$additionalParams['client_id'] = $this->accessSettings['client_id'];
$additionalParams['client_secret'] = $this->accessSettings['client_secret'];
if($licenseCheck)
$additionalParams['key'] = static::getLicenseHash();
$http = new HttpClient(array('socketTimeout' => $this->httpTimeout));
$result = $http->post(
static::SERVICE_HOST.static::REST_URI.$methodName,
$additionalParams
);
if($result === false)
{
$httpErrors = $http->getError();
foreach ($httpErrors as $errorCode => $errorText)
{
$this->errorCollection->add(array(new Error($errorText, $errorCode)));
}
return false;
}
$answer = $this->prepareAnswer($result);
if(!is_array($answer) || count($answer) == 0)
{
$this->errorCollection->add(array(new Error('Malformed answer from service: '.$http->getStatus().' '.$result, static::ERROR_SERVICE_UNAVAILABLE)));
return false;
}
if(array_key_exists('error', $answer))
{
if($answer['error'] === 'verification_needed' && !$licenseCheck)
{
return $this->call($methodName, $additionalParams, true);
}
else if(($answer['error'] === 'ACCESS_DENIED' || $answer['error'] === 'Invalid client')
&& !$clearAccessSettings)
{
return $this->call($methodName, $additionalParams, true, true);
}
$this->errorCollection->add(array(new Error($answer['error'].". ".$answer['error_description'])));
return false;
}
if($answer['result'] == false)
{
$this->errorCollection->add(array(new Error(Loc::getMessage('SALE_PROPERTIES_ERROR_NOTHING_FOUND'), static::ERROR_NOTHING_FOUND)));
}
return $answer['result'];
}
/**
* Decodes answer of the method.
* @param string $result Json-encoded answer.
* @return array|bool|mixed|string Decoded answer.
*/
protected function prepareAnswer($result)
{
return Json::decode($result);
}
/**
* Registers client on the properties service.
* @return array|false Access credentials if registration was successful or false otherwise.
*/
protected function register()
{
$httpClient = new HttpClient();
$queryParams = array(
"key" => static::getLicenseHash(),
"scope" => static::SCOPE,
"redirect_uri" => static::getRedirectUri(),
);
$result = $httpClient->post(static::SERVICE_HOST.static::REGISTER_URI, $queryParams);
if($result === false)
{
$this->errorCollection->add(array(new Error($result["error"], static::ERROR_SERVICE_UNAVAILABLE)));
return false;
}
$result = Json::decode($result);
if($result["error"])
{
$this->errorCollection->add(array(new Error($result["error"], static::ERROR_WRONG_LICENSE)));
return false;
}
else
{
return $result;
}
}
/**
* Stores access credentials.
* @param array $params Access credentials.
* @return void
*/
protected static function setAccessSettings(array $params)
{
Option::set('sale', static::SERVICE_ACCESS_OPTION, serialize($params));
}
/**
* Reads and returns access credentials.
* @return array|false Access credentials or false in case of errors.
*/
protected function getAccessSettings()
{
$accessSettings = Option::get('sale', static::SERVICE_ACCESS_OPTION);
if($accessSettings != '')
{
return unserialize($accessSettings);
}
else
{
if($accessSettings = $this->register())
{
$this->setAccessSettings($accessSettings);
return $accessSettings;
}
else
{
return false;
}
}
}
/**
* Drops current stored access credentials.
* @return void
*/
public function clearAccessSettings()
{
Option::set('sale', static::SERVICE_ACCESS_OPTION, null);
}
/**
* Internal method for usage in registration process.
* @return string URL of the host.
*/
protected static function getRedirectUri()
{
$request = Context::getCurrent()->getRequest();
$host = $request->getHttpHost();
$isHttps = $request->isHttps();
return ($isHttps ? 'https' : 'http').'://'.$host."/";
}
/**
* Returns array of errors.
* @return Error[] Errors.
*/
public function getErrors()
{
return $this->errorCollection->toArray();
}
/**
* Returns md5 hash of the license key.
* @return string md5 hash of the license key.
*/
protected static function getLicenseHash()
{
return md5(LICENSE_KEY);
}
}