Skip to content

Commit

Permalink
Mockup of hooks implementation mesilov#1
Browse files Browse the repository at this point in the history
  • Loading branch information
Stanislav Belichenko committed Oct 19, 2017
1 parent 425813f commit c4f2422
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/bitrix24.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class Bitrix24 implements iBitrix24
protected $rawRequest;

/**
* @var array, contain all api-method parameters, vill be available after call method
* @var array, contain all api-method parameters, will be available after call method
*/
protected $methodParameters;

Expand Down
274 changes: 274 additions & 0 deletions src/bitrix24webhook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
<?php
/**
* Created by PhpStorm.
* User: Stanislav Belichenko, E-mail: [email protected], Skype: s.belichenko.sold
* Company: «SOLD», E-mail: [email protected]
* Date: 15.10.2017
* Time: 12:28
*/

namespace Bitrix24;

use Bitrix24\Contracts\iBitrix24Webhook;

use Bitrix24\Exceptions\Bitrix24Exception;
use Bitrix24\Exceptions\Bitrix24IoException;
use Bitrix24\Exceptions\Bitrix24PortalDeletedException;
use Bitrix24\Exceptions\Bitrix24BadGatewayException;
use Bitrix24\Exceptions\Bitrix24EmptyResponseException;


class Bitrix24Webhook implements iBitrix24Webhook {
/**
* @var string SDK version
*/
const VERSION = '1.0';

/**
* @var string domain
*/
protected $domain;

/**
* @var string access token
*/
protected $accessToken;

/**
* @var array, contain all api-method parameters, will be available after call method
*/
protected $methodParameters;

/**
* @var array custom options for cURL
*/
protected $customCurlOptions;

/**
* @var integer CURL request count retries
*/
protected $retriesToConnectCount;

/**
* @var array raw request, contain all cURL options array and API query
*/
protected $rawRequest;

/**
* @var array request info data structure акщь curl_getinfo function
*/
protected $requestInfo;

/**
* @var integer retries to connect timeout in microseconds
*/
protected $retriesToConnectTimeout;

/**
* @var array raw response from bitrix24
*/
protected $rawResponse;

/**
* @param $methodName
* @param array $additionalParameters
*
* @return mixed
* @throws Bitrix24Exception
*/
public function call( $methodName, array $additionalParameters = array() ) {
$result = $this->_call( $methodName, $additionalParameters );

return $result;
}

/**
* Set domain
*
* @param $domain
*
* @throws Bitrix24Exception
*
* @return true;
*/
public function setDomain( $domain ) {
if ( '' === $domain ) {
throw new Bitrix24Exception( 'domain is empty' );
}
$this->domain = $domain;

return true;
}

/**
* Set access token
*
* @param string $accessToken
*
* @throws Bitrix24Exception
*
* @return true
*/
public function setAccessToken( $accessToken ) {
if ( '' === $accessToken ) {
throw new Bitrix24Exception( 'access token is empty' );
}
$this->accessToken = $accessToken;

return true;
}

/**
* Get domain
*
* @return string | null
*/
public function getDomain() {
return $this->domain;
}

/**
* Get access token
*
* @return string | null
*/
public function getAccessToken() {
return $this->accessToken;
}

/**
* @param $methodName
* @param array $additionalParameters
*
* @return mixed
* @throws Bitrix24Exception
*/
protected function _call( $methodName, array $additionalParameters = array() ) {
if ( null === $this->getDomain() ) {
throw new Bitrix24Exception( 'domain not found, you must call setDomain method before' );
}
if ( null === $this->getAccessToken() ) {
throw new Bitrix24Exception( 'access token not found, you must call setAccessToken method before' );
}
if ( '' === $methodName ) {
throw new Bitrix24Exception( 'method name not found, you must set method name' );
}

$url = 'https://' . $this->domain . '/rest/1/' . $this->accessToken . '/' . $methodName;

// save method parameters for debug
$this->methodParameters = $additionalParameters;

$requestResult = $this->executeRequest( $url, $additionalParameters );

return $requestResult;
}

/**
* @param $url
* @param array $additionalParameters
*
* @return mixed
* @throws Bitrix24Exception
* @throws Bitrix24IoException
*/
protected function executeRequest( $url, array $additionalParameters = array() ) {
$retryableErrorCodes = array(
CURLE_COULDNT_RESOLVE_HOST,
CURLE_COULDNT_CONNECT,
CURLE_HTTP_NOT_FOUND,
CURLE_READ_ERROR,
CURLE_OPERATION_TIMEOUTED,
CURLE_HTTP_POST_ERROR,
CURLE_SSL_CONNECT_ERROR
);

$curlOptions = array(
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLINFO_HEADER_OUT => true,
CURLOPT_VERBOSE => true,
CURLOPT_CONNECTTIMEOUT => 65,
CURLOPT_TIMEOUT => 70,
CURLOPT_USERAGENT => strtolower( __CLASS__ . '-PHP-SDK/v' . self::VERSION ),
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query( $additionalParameters ),
CURLOPT_URL => $url
);

if ( is_array( $this->customCurlOptions ) ) {
foreach ( $this->customCurlOptions as $customCurlOptionKey => $customCurlOptionValue ) {
$curlOptions[ $customCurlOptionKey ] = $customCurlOptionValue;
}
}

$this->rawRequest = $curlOptions;
$curl = curl_init();
curl_setopt_array( $curl, $curlOptions );

$curlResult = false;
$retriesCnt = $this->retriesToConnectCount;
while ( $retriesCnt -- ) {
$curlResult = curl_exec( $curl );
// handling network I/O errors
if ( false === $curlResult ) {
$curlErrorNumber = curl_errno( $curl );
$errorMsg = sprintf( 'in try[%s] cURL error (code %s): %s' . PHP_EOL, $retriesCnt,
$curlErrorNumber,
curl_error( $curl ) );
if ( false === in_array( $curlErrorNumber, $retryableErrorCodes, true ) || ! $retriesCnt ) {
curl_close( $curl );
throw new Bitrix24IoException( $errorMsg );
}
usleep( $this->getRetriesToConnectTimeout() );
continue;
}
$this->requestInfo = curl_getinfo( $curl );
$this->rawResponse = $curlResult;
curl_close( $curl );
break;
}

// handling URI level resource errors
switch ( $this->requestInfo['http_code'] ) {
case 403:
$errorMsg = sprintf( 'portal [%s] deleted, query aborted', $this->getDomain() );
throw new Bitrix24PortalDeletedException( $errorMsg );
break;

case 502:
$errorMsg = sprintf( 'bad gateway to portal [%s]', $this->getDomain() );
throw new Bitrix24BadGatewayException( $errorMsg );
break;
}

// handling server-side API errors: empty response from bitrix24 portal
if ( $curlResult === '' ) {
$errorMsg = sprintf( 'empty response from portal [%s]', $this->getDomain() );
throw new Bitrix24EmptyResponseException( $errorMsg );
}

// handling json_decode errors
$jsonResult = json_decode( $curlResult, true );
unset( $curlResult );
$jsonErrorCode = json_last_error();
if ( null === $jsonResult && ( JSON_ERROR_NONE !== $jsonErrorCode ) ) {
/**
* @todo add function json_last_error_msg()
*/
$errorMsg = 'fatal error in function json_decode.' . PHP_EOL . 'Error code: ' . $jsonErrorCode . PHP_EOL;
throw new Bitrix24Exception( $errorMsg );
}

return $jsonResult;
}

/**
* get retries to connect timeout in microseconds
*
* @return mixed
*/
public function getRetriesToConnectTimeout() {
return $this->retriesToConnectTimeout;
}
}
26 changes: 26 additions & 0 deletions src/classes/bitrix24incomingwebhook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Created by PhpStorm.
* User: Stanislav Belichenko, E-mail: [email protected], Skype: s.belichenko.sold
* Company: «SOLD», E-mail: [email protected]
* Date: 15.10.2017
* Time: 12:33
*/

namespace Bitrix24;

use Bitrix24\Contracts\iBitrix24Webhook;

abstract class Bitrix24IncomingWebhook {
/**
* @var iBitrix24Webhook
*/
public $client = null;

/**
* @param $client iBitrix24Webhook
*/
public function __construct( iBitrix24Webhook $client ) {
$this->client = $client;
}
}
36 changes: 36 additions & 0 deletions src/classes/crm/lead/leadincwebhook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Created by PhpStorm.
* User: Stanislav Belichenko, E-mail: [email protected], Skype: s.belichenko.sold
* Company: «SOLD», E-mail: [email protected]
* Date: 15.10.2017
* Time: 12:37
*/

namespace Bitrix24\CRM;

use Bitrix24\Bitrix24IncomingWebhook;

class LeadIncWebhook extends Bitrix24IncomingWebhook {
/**
* Add a new lead to CRM
*
* @param array $fields array of fields
* @param array $params Set of parameters. REGISTER_SONET_EVENT - performs registration of a change event in a lead
* in the Activity Stream. The lead's Responsible person will also receive notification.
*
* @link http://dev.1c-bitrix.ru/rest_help/crm/leads/crm_lead_add.php
* @return array
*/
public function add( $fields = array(), $params = array() ) {
$fullResult = $this->client->call(
'crm.lead.add',
array(
'fields' => $fields,
'params' => $params
)
);

return $fullResult;
}
}
15 changes: 15 additions & 0 deletions src/contracts/ibitrix24webhook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: Stanislav Belichenko, E-mail: [email protected], Skype: s.belichenko.sold
* Company: «SOLD», E-mail: [email protected]
* Date: 15.10.2017
* Time: 12:25
*/

namespace Bitrix24\Contracts;


interface iBitrix24Webhook {
public function call( $methodName, array $additionalParameters = array() );
}

0 comments on commit c4f2422

Please sign in to comment.