Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
|
||||
final class PipedriveClientService
|
||||
{
|
||||
|
||||
/** @var string[] $endPoints */
|
||||
private $endPoints = [
|
||||
'allPersons' => '/v1/persons',
|
||||
'recentlyUpdatedPersons' => '/v1/recents',
|
||||
'deleteContact' => '/v1/persons/:id',
|
||||
'updateContact' => '/v1/persons/:id',
|
||||
'createContact' => '/v1/persons',
|
||||
'getContactById' => '/v1/persons/:id',
|
||||
'recentlyUpdatedDeals' => '/v1/recents',
|
||||
'createDeal' => '/v1/deals',
|
||||
'allDeals' => '/v1/deals',
|
||||
'deleteDeal' => '/v1/deals/:id',
|
||||
'updateDeal' => '/v1/deals/:id',
|
||||
'getDealById' => '/v1/deals/:id',
|
||||
'getPersonFields' => '/v1/personFields',
|
||||
'getOnePersonField' => '/v1/personFields/:id',
|
||||
'getStages' => '/v1/stages',
|
||||
'getPipelines' => '/v1/pipelines',
|
||||
];
|
||||
|
||||
/** @var string $authMethod */
|
||||
private $authMethod = 'key';
|
||||
|
||||
/** @var string|null $apiKey */
|
||||
private $apiKey;
|
||||
|
||||
/** @var PipedriveHttpClientService $client */
|
||||
private $client;
|
||||
|
||||
/** @var PipedriveConfigurationService $confService */
|
||||
private $confService;
|
||||
|
||||
/**
|
||||
* @param PipedriveHttpClientService $client
|
||||
* @param PipedriveConfigurationService $confService
|
||||
* @param string|null $apiKey
|
||||
*/
|
||||
public function __construct(
|
||||
PipedriveHttpClientService $client,
|
||||
PipedriveConfigurationService $confService,
|
||||
?string $apiKey = null
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->apiKey = $apiKey;
|
||||
$this->confService = $confService;
|
||||
}
|
||||
|
||||
/** @var string $apiUrl */
|
||||
private $apiUrl = 'https://api.pipedrive.com%s';
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @param array $args
|
||||
* @param string|null $suffix
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEndPoint(string $resource, array $args = [], ?string $suffix = null): string
|
||||
{
|
||||
|
||||
if (!array_key_exists($resource, $this->endPoints)) {
|
||||
throw new PipedriveClientException('Undefined resource endpoint');
|
||||
}
|
||||
|
||||
$suffixUrl = $suffix ?? $this->endPoints[$resource];
|
||||
$url = sprintf($this->apiUrl, $suffixUrl);
|
||||
if ($this->authMethod === 'key') {
|
||||
$apiKey = $this->apiKey ?? $this->getConfApiKey();
|
||||
$url .= sprintf('?api_token=%s', $apiKey);
|
||||
}
|
||||
if (!empty($args)) {
|
||||
preg_match_all('/:[a-zA-Z0-9._-]+/', $url, $match);
|
||||
if (!empty($match) && !empty($match[0])) {
|
||||
$url = str_replace($match[0], $args, $url);
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $ressource
|
||||
* @param array $data
|
||||
* @param array $endPointArgs
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function read(string $ressource, array $data = [], array $endPointArgs = []): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->get($this->getEndPoint($ressource, $endPointArgs), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getConfApiKey(): ?string
|
||||
{
|
||||
return $this->confService->getDecryptedConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ressource
|
||||
* @param array $data
|
||||
* @param array $endPointArgs
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function post(string $ressource, array $data = [], array $endPointArgs = []): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->post($this->getEndPoint($ressource, $endPointArgs), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ressource
|
||||
* @param array $data
|
||||
* @param array $endPointArgs
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function delete(string $ressource, array $endPointArgs = [], array $data = []): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->delete($this->getEndPoint($ressource, $endPointArgs), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ressource
|
||||
* @param array $data
|
||||
* @param array $endPointArgs
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function put(string $ressource, array $data = [], array $endPointArgs = []): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->put($this->getEndPoint($ressource, $endPointArgs), $data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
use Xentral\Modules\Pipedrive\Gateway\PipedriveDealGateway;
|
||||
use Xentral\Modules\Pipedrive\Gateway\PipedrivePersonPropertyGateway;
|
||||
use Xentral\Modules\Pipedrive\Wrapper\PipedriveAddAddressRoleWrapper;
|
||||
use Xentral\Modules\SystemConfig\SystemConfigModule;
|
||||
|
||||
final class PipedriveConfigurationService
|
||||
{
|
||||
/** @var string */
|
||||
private const PIPEDRIVE_SETTINGS = 'pipedrive_settings';
|
||||
|
||||
/** @var string */
|
||||
private const PIPEDRIVE_CONF_NAME = 'pipedrive_conf.json';
|
||||
|
||||
/** @var array $_defaultSettings */
|
||||
private static $_defaultSettings = [
|
||||
'pd_sync_deals' => true,
|
||||
'pd_sync_addresses' => true,
|
||||
'pd_api_key' => null,
|
||||
];
|
||||
|
||||
/** @var SystemConfigModule $configWrapper */
|
||||
private $configWrapper;
|
||||
|
||||
/** @var PipedriveMetaWriterService $metaWriterService */
|
||||
private $metaWriterService;
|
||||
|
||||
/** @var PipedrivePersonPropertyGateway $propertyGateway */
|
||||
private $propertyGateway;
|
||||
|
||||
/** @var PipedriveDealGateway $pipedriveDealGateway */
|
||||
private $pipedriveDealGateway;
|
||||
|
||||
/** @var PipedriveMetaReaderService $metaReaderService */
|
||||
private $metaReaderService;
|
||||
|
||||
/** @var PipedriveAddAddressRoleWrapper $addAddressRoleWrapper */
|
||||
private $addAddressRoleWrapper;
|
||||
|
||||
/**
|
||||
* @param SystemConfigModule $configWrapper
|
||||
* @param PipedriveMetaWriterService $metaWriterService
|
||||
* @param PipedrivePersonPropertyGateway $propertyGateway
|
||||
* @param PipedriveDealGateway $pipedriveDealGateway
|
||||
* @param PipedriveMetaReaderService $metaReaderService
|
||||
* @param PipedriveAddAddressRoleWrapper $addAddressRoleWrapper
|
||||
*/
|
||||
public function __construct(
|
||||
SystemConfigModule $configWrapper,
|
||||
PipedriveMetaWriterService $metaWriterService,
|
||||
PipedrivePersonPropertyGateway $propertyGateway,
|
||||
PipedriveDealGateway $pipedriveDealGateway,
|
||||
PipedriveMetaReaderService $metaReaderService,
|
||||
PipedriveAddAddressRoleWrapper $addAddressRoleWrapper
|
||||
) {
|
||||
$this->configWrapper = $configWrapper;
|
||||
$this->metaWriterService = $metaWriterService;
|
||||
$this->propertyGateway = $propertyGateway;
|
||||
$this->pipedriveDealGateway = $pipedriveDealGateway;
|
||||
$this->metaReaderService = $metaReaderService;
|
||||
$this->addAddressRoleWrapper = $addAddressRoleWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function trySetConfiguration(string $name, string $value): void
|
||||
{
|
||||
if (empty($name)) {
|
||||
throw new PipedriveConfigurationException('Cannot set Configuration');
|
||||
}
|
||||
|
||||
$this->configWrapper->setValue(self::PIPEDRIVE_SETTINGS, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function tryGetConfiguration(string $name): ?string
|
||||
{
|
||||
if (empty($name)) {
|
||||
throw new PipedriveConfigurationException('Cannot get configuration on Empty');
|
||||
}
|
||||
|
||||
return $this->configWrapper->tryGetValue(self::PIPEDRIVE_SETTINGS, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @param string $value
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEncryptedConfiguration(array $settings, string $value): array
|
||||
{
|
||||
if (empty($settings)) {
|
||||
throw new PipedriveConfigurationException('Cannot set Configuration');
|
||||
}
|
||||
$encValue = $this->encrypt($value);
|
||||
$settings['pd_api_key'] = $encValue;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDecryptedConfiguration(): ?string
|
||||
{
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return $settings['pd_api_key'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plaintext
|
||||
* @param string $sCipher
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function encrypt(string $plaintext, string $sCipher = 'aes-128-gcm'): string
|
||||
{
|
||||
if (!in_array($sCipher, openssl_get_cipher_methods(), true)) {
|
||||
throw new PipedriveConfigurationException(sprintf('Cipher method %s does not exist', $sCipher));
|
||||
}
|
||||
if (null === $this->getNonceSalt()) {
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
$key = hash('sha256', $this->getNonceSalt());
|
||||
$ivLen = openssl_cipher_iv_length($sCipher);
|
||||
$iv = openssl_random_pseudo_bytes($ivLen, $crypto_strong);
|
||||
|
||||
if ($iv === false || $crypto_strong === false) {
|
||||
throw new PipedriveConfigurationException('Bad Random length');
|
||||
}
|
||||
$cipherTextRaw = openssl_encrypt($plaintext, $sCipher, $key, $options = 0, $iv, $tag);
|
||||
|
||||
return base64_encode($iv . $cipherTextRaw . '..' . $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param string $sCipher
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return false|string|null
|
||||
*/
|
||||
protected function decrypt(string $string, string $sCipher = 'aes-128-gcm')
|
||||
{
|
||||
if (empty($string) || !$this->isBase64Encoded($string)) {
|
||||
return '';
|
||||
}
|
||||
if (null === $this->getNonceSalt()) {
|
||||
return $this->isBase64Encoded($string) ? null : $string;
|
||||
}
|
||||
$stringDecode = base64_decode($string);
|
||||
$encExploded = explode('..', $stringDecode);
|
||||
$enc = array_shift($encExploded);
|
||||
$tag = implode('', $encExploded);
|
||||
$key = hash('sha256', $this->getNonceSalt());
|
||||
$ivLen = openssl_cipher_iv_length($sCipher);
|
||||
$iv = substr($enc, 0, $ivLen);
|
||||
$cipherTextRaw = substr($enc, $ivLen);
|
||||
|
||||
return openssl_decrypt($cipherTextRaw, $sCipher, $key, $options = 0, $iv, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isBase64Encoded(string $string): bool
|
||||
{
|
||||
return base64_encode(base64_decode($string)) === $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string|null
|
||||
*/
|
||||
private function generateSecureSalt()
|
||||
{
|
||||
$rand = sprintf('%s', mt_rand());
|
||||
|
||||
return password_hash(uniqid($rand, true), PASSWORD_BCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $force
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
public function createSalt(bool $force = false)
|
||||
{
|
||||
if ($force === true) {
|
||||
$this->metaWriterService->delete(self::PIPEDRIVE_CONF_NAME);
|
||||
}
|
||||
if ($this->metaReaderService->exists(self::PIPEDRIVE_CONF_NAME) && $this->metaReaderService->hasKey(
|
||||
'nonce_salt',
|
||||
self::PIPEDRIVE_CONF_NAME
|
||||
)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return $this->metaWriterService->save(self::PIPEDRIVE_CONF_NAME, ['nonce_salt' => $this->generateSecureSalt()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function getNonceSalt(): ?string
|
||||
{
|
||||
$data = $this->metaReaderService->readFromFile(self::PIPEDRIVE_CONF_NAME);
|
||||
|
||||
return $data['nonce_salt'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $hContact
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatAddressByResponse(array $hContact): array
|
||||
{
|
||||
if (empty($hContact)) {
|
||||
throw new PipedriveConfigurationException('Invalid contact');
|
||||
}
|
||||
|
||||
$leadFields = $this->matchSelectedAddressFreeField();
|
||||
$lsField = $leadFields['pipedrive_ls_field'];
|
||||
|
||||
$ahEmail = array_map(
|
||||
static function ($email) {
|
||||
if (!array_key_exists('primary', $email) && $email['primary'] === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $email;
|
||||
},
|
||||
$hContact['email']
|
||||
);
|
||||
$email = array_filter($ahEmail);
|
||||
$primaryEmail = is_array($email[0]) && array_key_exists('value', $email[0]) ? $email[0]['value'] : '';
|
||||
|
||||
$ahPhone = array_map(
|
||||
static function ($phone) {
|
||||
if (!array_key_exists('primary', $phone) && $phone['primary'] === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $phone;
|
||||
},
|
||||
$hContact['phone']
|
||||
);
|
||||
|
||||
$phone = array_filter($ahPhone);
|
||||
$primaryPhone = is_array($phone[0]) && array_key_exists('value', $phone[0]) ? $phone[0]['value'] : '';
|
||||
|
||||
return [
|
||||
'lead' => 1,
|
||||
'typ' => !empty($hContact['org_name']) ? 'firma' : 'herr',
|
||||
'sprache' => 'deutsch',
|
||||
'name' => $hContact['org_name'] ?? $hContact['name'],
|
||||
'vorname' => empty($hContact['first_name']) ? 'Pipedrive - ' : $hContact['first_name'],
|
||||
'nachname' => empty($hContact['last_name']) ? $primaryEmail : $hContact['last_name'],
|
||||
'land' => empty($hContact['country']) ? 'DE' : $hContact['country'],
|
||||
'telefon' => $primaryPhone ?? '',
|
||||
'email' => $primaryEmail,
|
||||
'kundenfreigabe' => 1,
|
||||
'waehrung' => 'EUR',
|
||||
'ansprechpartner' => !empty($hContact['org_name']) ? $hContact['name'] : '',
|
||||
$lsField => empty($hContact['label']) ? '' : $hContact['label'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function matchSelectedAddressFreeField(): array
|
||||
{
|
||||
$hFields = [];
|
||||
$asAddressFreeFieldValues = $this->propertyGateway->getConfiguredFreeAddressFieldValues();
|
||||
$pdConfFields = [
|
||||
'pipedrive_ls_field' => $this->tryGetConfiguration('pipedrive_ls_field'),
|
||||
];
|
||||
|
||||
foreach ($asAddressFreeFieldValues as $fieldName) {
|
||||
$addrField = 'adresse' . $fieldName;
|
||||
if (in_array($addrField, $pdConfFields, true)) {
|
||||
$indexField = array_search($addrField, $pdConfFields, true);
|
||||
$hFields[$indexField] = $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($hFields)) {
|
||||
throw new PipedriveConfigurationException('Pipedrive Label-Status fields cannot be matched');
|
||||
}
|
||||
|
||||
return $hFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $address
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatAddressToPipedriveContact(array $address): array
|
||||
{
|
||||
if (empty($address)) {
|
||||
throw new PipedriveConfigurationException('Address is invalid');
|
||||
}
|
||||
|
||||
$leadFields = $this->matchSelectedAddressFreeField();
|
||||
$lsField = $leadFields['pipedrive_ls_field'];
|
||||
|
||||
return [
|
||||
'email' => $address['email'],
|
||||
'first_name' => empty($address['vorname']) ? $address['name'] : $address['vorname'],
|
||||
'last_name' => empty($address['nachname']) ? $address['name'] : $address['nachname'],
|
||||
'name' => $address['name'],
|
||||
'phone' => $address['telefon'],
|
||||
'label' => $address[$lsField],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $hDeal
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatDealToInternal(array $hDeal): array
|
||||
{
|
||||
if (empty($hDeal)) {
|
||||
throw new PipedriveConfigurationException('Error! Deal cannot be formatted for Xentral');
|
||||
}
|
||||
|
||||
$dealStage = $this->propertyGateway->getMappingByValueAndType($hDeal['stage_id'], 'deals');
|
||||
$asAddTime = [];
|
||||
$addTime = $hDeal['add_time'] ?? null;
|
||||
if ($addTime !== null) {
|
||||
$asAddTime = explode(' ', $addTime);
|
||||
}
|
||||
|
||||
return [
|
||||
'bezeichnung' => $hDeal['title'],
|
||||
'datum_angelegt' => !empty($asAddTime) ? $asAddTime[0] : null,
|
||||
'zeit_angelegt' => !empty($asAddTime) ? $asAddTime[1] : null,
|
||||
'datum_erinnerung' => null,
|
||||
'zeit_erinnerung' => null,
|
||||
'betrag' => array_key_exists('value', $hDeal) ? (float)$hDeal['value'] : 0.00,
|
||||
'stages' => !empty($dealStage['wiedervorlage_stage_id']) ?
|
||||
$dealStage['wiedervorlage_stage_id'] : 0,
|
||||
'chance' => !empty($hDeal['probability']) ? $hDeal['probability'] : 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $resubmission
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatResubmissionToPipedriveDeal(array $resubmission): array
|
||||
{
|
||||
if (empty($resubmission)) {
|
||||
throw new PipedriveConfigurationException('Resubmission is invalid');
|
||||
}
|
||||
|
||||
$status = 'open';
|
||||
if (!empty($resubmission['abgeschlossen'])) {
|
||||
if ($resubmission['status'] === 'gewonnen') {
|
||||
$status = 'won';
|
||||
} elseif ($resubmission['status'] === 'verloren') {
|
||||
$status = 'lost';
|
||||
}
|
||||
}
|
||||
|
||||
$mapping = $this->pipedriveDealGateway->getMappingStageByResubmissionStageId($resubmission['stages']);
|
||||
|
||||
return [
|
||||
'title' => $resubmission['bezeichnung'],
|
||||
'stage_id' => !empty($mapping) ? $mapping['value'] : null,
|
||||
'value' => empty($resubmission['betrag']) ? 0.00 : $resubmission['betrag'],
|
||||
'probability' => $resubmission['chance'],
|
||||
'status' => $status,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
*/
|
||||
public function setSettings($settings = []): void
|
||||
{
|
||||
$this->trySetConfiguration(
|
||||
self::PIPEDRIVE_SETTINGS,
|
||||
json_encode($settings, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings(): array
|
||||
{
|
||||
$settingsRaw = $this->tryGetConfiguration(self::PIPEDRIVE_SETTINGS);
|
||||
if (empty($settingsRaw)) {
|
||||
return static::$_defaultSettings;
|
||||
}
|
||||
|
||||
$settings = json_decode($settingsRaw, true);
|
||||
if ($settings === null && json_last_error() === JSON_ERROR_NONE) {
|
||||
throw new PipedriveConfigurationException(json_last_error_msg());
|
||||
}
|
||||
|
||||
if (empty($settings)) {
|
||||
return static::$_defaultSettings;
|
||||
}
|
||||
|
||||
if (array_key_exists('pd_api_key', $settings) && !empty($settings['pd_api_key'])) {
|
||||
$settings['pd_api_key'] = $this->decrypt($settings['pd_api_key']);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contactId
|
||||
*
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addContactToGroup(int $contactId = 0): void
|
||||
{
|
||||
$defaultSettings = $this->getSettings();
|
||||
$contactGrpId = array_key_exists('pd_contact_grp', $defaultSettings) ? $defaultSettings['pd_contact_grp'] : 0;
|
||||
if (!empty($contactGrpId)) {
|
||||
$this->addAddressRoleWrapper->add($contactId, $contactGrpId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveDealPropertyServiceException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
use Xentral\Modules\Pipedrive\Gateway\PipedrivePersonPropertyGateway;
|
||||
use Xentral\Modules\Pipedrive\Wrapper\PipedriveResubmissionWrapper;
|
||||
use Xentral\Modules\Resubmission\Exception\StageNotFoundException;
|
||||
use Xentral\Modules\Resubmission\Exception\ViewNotFoundException;
|
||||
use Xentral\Modules\Resubmission\Service\ResubmissionGateway;
|
||||
|
||||
final class PipedriveDealPropertyService
|
||||
{
|
||||
|
||||
/** @var PipedriveClientService $client */
|
||||
private $client;
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/** @var PipedrivePersonPropertyGateway $propertyGateway */
|
||||
private $propertyGateway;
|
||||
|
||||
/** @var ResubmissionGateway $resubmissionGateway */
|
||||
private $resubmissionGateway;
|
||||
|
||||
/** @var PipedriveResubmissionWrapper $resubmissionWrapper */
|
||||
private $resubmissionWrapper;
|
||||
|
||||
/**
|
||||
* @param PipedriveClientService $client
|
||||
* @param Database $db
|
||||
* @param PipedrivePersonPropertyGateway $propertyGateway
|
||||
* @param ResubmissionGateway $resubmissionGateway
|
||||
* @param PipedriveResubmissionWrapper $resubmissionWrapper
|
||||
*/
|
||||
public function __construct(
|
||||
PipedriveClientService $client,
|
||||
Database $db,
|
||||
PipedrivePersonPropertyGateway $propertyGateway,
|
||||
ResubmissionGateway $resubmissionGateway,
|
||||
PipedriveResubmissionWrapper $resubmissionWrapper
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->db = $db;
|
||||
$this->propertyGateway = $propertyGateway;
|
||||
$this->resubmissionGateway = $resubmissionGateway;
|
||||
$this->resubmissionWrapper = $resubmissionWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $pipelineId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveDealPropertyServiceException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDealStages(int $pipelineId = 0): array
|
||||
{
|
||||
$data = [];
|
||||
if ($pipelineId !== 0) {
|
||||
$data = ['pipeline_id' => $pipelineId];
|
||||
}
|
||||
$response = $this->client->read('getStages', $data);
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
throw new PipedriveDealPropertyServiceException($response->getError());
|
||||
}
|
||||
|
||||
return $response->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $pipelineId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveDealPropertyServiceException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws StageNotFoundException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function installDealStages(?int $pipelineId = null): void
|
||||
{
|
||||
// Get Deal Stages
|
||||
$firstStage = 0;
|
||||
$viewId = 0;
|
||||
if ($dealStages = $this->propertyGateway->getLeadsByType('deals')) {
|
||||
$stage = array_unique(array_column($dealStages, 'wiedervorlage_stage_id'));
|
||||
$firstStage = $stage[0];
|
||||
}
|
||||
|
||||
if ($firstStage > 0) {
|
||||
$viewId = $this->resubmissionGateway->getViewIdByStage($firstStage);
|
||||
}
|
||||
|
||||
if (empty($firstStage) || empty($viewId)) {
|
||||
try {
|
||||
$viewId = $this->resubmissionGateway->getViewIdByNameAndDescription('Pipedrive', 'Pipedrive');
|
||||
} catch (ViewNotFoundException $exception) {
|
||||
$viewId = $this->resubmissionWrapper->addResubmissionView('Pipedrive', 'Pipedrive');
|
||||
}
|
||||
}
|
||||
|
||||
// Default Pipeline
|
||||
if ($pipelineId === null) {
|
||||
$pipeline = $this->getDefaultPipeline();
|
||||
$pipelineId = $pipeline['id'] ?? 0;
|
||||
}
|
||||
|
||||
if ($viewId > 0 && ($ahDealStages = $this->getDealStages($pipelineId))) {
|
||||
$position = $this->resubmissionGateway->getMaxSortByViewId($viewId) + 1;
|
||||
foreach ($ahDealStages as $hDealStage) {
|
||||
if ($this->db->fetchValue(
|
||||
'SELECT hm.id FROM `pipedrive_mappings` AS `hm` WHERE hm.value=:value AND hm.type = :type',
|
||||
[
|
||||
'value' => $hDealStage['id'],
|
||||
'type' => 'deals',
|
||||
]
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$stage = [
|
||||
'desc' => $hDealStage['name'],
|
||||
'name' => $hDealStage['name'],
|
||||
'position' => $position,
|
||||
'wiedervorlage_view_id' => $viewId,
|
||||
'enabled' => 1,
|
||||
'ausblenden' => 0,
|
||||
];
|
||||
$stageId = $this->resubmissionWrapper->addResubmissionStage($stage);
|
||||
|
||||
if (!empty($stageId)) {
|
||||
$this->db->perform(
|
||||
'INSERT INTO `pipedrive_mappings` (`label`, `value`, `type`, `wiedervorlage_stage_id`,
|
||||
`is_system`, `wiedervorlage_view_id`)
|
||||
VALUES(:label, :value,:type, :wstage_id, :is_system, :view_id)',
|
||||
[
|
||||
'label' => $hDealStage['name'],
|
||||
'value' => $hDealStage['id'],
|
||||
'type' => 'deals',
|
||||
'wstage_id' => $stageId,
|
||||
'is_system' => 1,
|
||||
'view_id' => $viewId,
|
||||
]
|
||||
);
|
||||
}
|
||||
$position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveDealPropertyServiceException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultPipeline(): array
|
||||
{
|
||||
$response = $this->client->read('getPipelines');
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
throw new PipedriveDealPropertyServiceException($response->getError());
|
||||
}
|
||||
|
||||
$data = $response->getData();
|
||||
|
||||
return array_shift($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveDealServiceException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveValidatorException;
|
||||
use Xentral\Modules\Pipedrive\Validator\PipedriveDealValidator;
|
||||
|
||||
final class PipedriveDealService
|
||||
{
|
||||
/** @var array $allowedSyncDealsOptions */
|
||||
private $allowedSyncDealsOptions = [
|
||||
'pipedrive_recently_updated_deals' => 'getRecentlyUpdatedDeals',
|
||||
'pipedrive_all_deals' => 'getDeals',
|
||||
];
|
||||
|
||||
/** @var array $itemOption */
|
||||
private $itemOption = [
|
||||
'limit' => 100,
|
||||
'items' => 'deal',
|
||||
'start' => 0,
|
||||
'since_timestamp' => '1970-01-01 23:59:59',
|
||||
];
|
||||
|
||||
/** @var PipedriveClientService $client */
|
||||
private $client;
|
||||
|
||||
/** @var PipedriveDealValidator $validator */
|
||||
private $validator;
|
||||
|
||||
/** @var PipedriveMetaReaderService $metaReaderService */
|
||||
private $metaReaderService;
|
||||
|
||||
/**
|
||||
* @param PipedriveClientService $client
|
||||
* @param PipedriveDealValidator $validator
|
||||
* @param PipedriveMetaReaderService $metaReaderService
|
||||
*/
|
||||
public function __construct(
|
||||
PipedriveClientService $client,
|
||||
PipedriveDealValidator $validator,
|
||||
PipedriveMetaReaderService $metaReaderService
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->validator = $validator;
|
||||
$this->metaReaderService = $metaReaderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveDealServiceException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedriveValidatorException
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function createDeal(array $data = []): PipedriveServerResponseInterface
|
||||
{
|
||||
$default = ['status' => 'open', 'stage_id' => 1];
|
||||
$data += $default;
|
||||
|
||||
if (!$this->validator->isValid($data)) {
|
||||
throw new PipedriveDealServiceException(sprintf('%s::createDeal Invalid Deal data', get_class($this)));
|
||||
}
|
||||
|
||||
$deal = $this->validator->getData();
|
||||
|
||||
return $this->client->post('createDeal', $deal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dealId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getDealById(int $dealId): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->read('getDealById', [], [$dealId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getDeals(array $options = []): PipedriveServerResponseInterface
|
||||
{
|
||||
$options += $this->itemOption;
|
||||
|
||||
return $this->client->read('allDeals', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getRecentlyUpdatedDeals(array $options = []): PipedriveServerResponseInterface
|
||||
{
|
||||
$options += $this->itemOption;
|
||||
|
||||
return $this->client->read('recentlyUpdatedDeals', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dealId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function deleteDeal(int $dealId): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->delete('deleteDeal', [$dealId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dealId
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveDealServiceException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedriveValidatorException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function updateDealById(int $dealId, array $data = []): PipedriveServerResponseInterface
|
||||
{
|
||||
if (!$this->validator->isValid($data)) {
|
||||
throw new PipedriveDealServiceException(sprintf('%s::updateDealById Invalid Deal data', get_class($this)));
|
||||
}
|
||||
|
||||
$deal = $this->validator->getData();
|
||||
|
||||
return $this->client->put('updateDeal', $deal, [$dealId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveDealServiceException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function pullDeals(
|
||||
string $type = 'pipedrive_recently_updated_deals',
|
||||
array $options = []
|
||||
): PipedriveServerResponseInterface {
|
||||
if ('pipedrive_all_deals' !== $type && !array_key_exists($type, $this->allowedSyncDealsOptions)) {
|
||||
throw new PipedriveDealServiceException(sprintf('Sync Type %s not allowed', $type));
|
||||
}
|
||||
$metaFile = sprintf('%s.json', $type);
|
||||
if ($type !== 'pipedrive_all_deals') {
|
||||
$options = $this->addMetaOption($metaFile, $options);
|
||||
}
|
||||
|
||||
/** @var PipedriveServerResponseInterface $response */
|
||||
return $this->{$this->allowedSyncDealsOptions[$type]}($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $metaFile
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addMetaOption(string $metaFile, array $options) : array
|
||||
{
|
||||
$metaInfo = $this->metaReaderService->readFromFile($metaFile);
|
||||
|
||||
if (!empty($metaInfo)) {
|
||||
$timeOffset = $metaInfo['timeOffset'];
|
||||
$offset = strtotime($metaInfo['timeOffset']);
|
||||
if ($offset !== false) {
|
||||
$timeOffset = gmdate('Y-m-d H:i:s', $offset - 3600);
|
||||
}
|
||||
$options = array_merge($options, ['since_timestamp' => $timeOffset]);
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Database\Exception\DatabaseExceptionInterface;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveEventException;
|
||||
|
||||
final class PipedriveEventService
|
||||
{
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
*
|
||||
* @throws PipedriveEventException
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function add(string $event): int
|
||||
{
|
||||
$add = 'INSERT INTO `pipedrive_events` (`event`, `created_at`)
|
||||
VALUES (:event, NOW())';
|
||||
try {
|
||||
$this->db->perform($add, ['event' => $event]);
|
||||
} catch (DatabaseExceptionInterface $exception) {
|
||||
throw new PipedriveEventException($exception->getMessage());
|
||||
}
|
||||
|
||||
return $this->db->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteById(int $id): void
|
||||
{
|
||||
$this->db->perform('DELETE FROM `pipedrive_events` WHERE `id` = :id', ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAll(): void
|
||||
{
|
||||
$this->db->perform('DELETE FROM `pipedrive_events`');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $days
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteByInterval(int $days = 30): void
|
||||
{
|
||||
$sql = 'DELETE FROM `pipedrive_events` WHERE `created_at` < DATE_SUB(NOW(), INTERVAL :days DAY)';
|
||||
$this->db->perform($sql, ['days' => $days]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Components\HttpClient\Exception\TransferErrorExceptionInterface;
|
||||
use Xentral\Components\HttpClient\HttpClientFactory;
|
||||
use Xentral\Components\HttpClient\HttpClientInterface;
|
||||
use Xentral\Components\HttpClient\Request\ClientRequest;
|
||||
use \Xentral\Components\HttpClient\RequestOptions;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
|
||||
final class PipedriveHttpClientService
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
private const GET_REQUEST = 'GET';
|
||||
/** @var string */
|
||||
private const POST_REQUEST = 'POST';
|
||||
/** @var string */
|
||||
private const DELETE_REQUEST = 'DELETE';
|
||||
/** @var string */
|
||||
private const PATCH_REQUEST = 'PATCH';
|
||||
/** @var string */
|
||||
private const PUT_REQUEST = 'PUT';
|
||||
|
||||
/** @var null|string $endpoint */
|
||||
protected $endpoint;
|
||||
|
||||
/** @var array $userAgent */
|
||||
protected $userAgent = [];
|
||||
|
||||
/** @var array $hRequestVerbs */
|
||||
protected $hRequestVerbs = [
|
||||
self::GET_REQUEST => null,
|
||||
self::POST_REQUEST => 'json',
|
||||
self::PUT_REQUEST => 'json',
|
||||
self::PATCH_REQUEST => 'json',
|
||||
self::DELETE_REQUEST => null,
|
||||
];
|
||||
|
||||
/** @var int $timeout */
|
||||
private $timeout = 10;
|
||||
|
||||
/** @var array $_headers */
|
||||
private $_headers = [];
|
||||
|
||||
/** @var HttpClientInterface $client */
|
||||
private $client;
|
||||
|
||||
/** @var null|RequestOptions $requestOption */
|
||||
private $requestOption;
|
||||
|
||||
/** @var HttpClientFactory|null $factory */
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* @param HttpClientFactory $factory
|
||||
* @param int $timeout
|
||||
* @param HttpClientInterface|null $client
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*/
|
||||
public function __construct(
|
||||
HttpClientFactory $factory,
|
||||
int $timeout = 0,
|
||||
?HttpClientInterface $client = null
|
||||
) {
|
||||
if (!empty($timeout)) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
$this->factory = $factory;
|
||||
$this->client = $client ?? $this->createClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $data
|
||||
* @param array $headers
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
protected function performRequest(
|
||||
string $url,
|
||||
string $method,
|
||||
array $data = [],
|
||||
array $headers = []
|
||||
): ?PipedriveServerResponseInterface {
|
||||
$this->setHeader($headers);
|
||||
|
||||
$keyParam = $this->hRequestVerbs[$method];
|
||||
$paramData = null;
|
||||
if ($keyParam !== null && $keyParam === 'json') {
|
||||
$paramData = json_encode($data);
|
||||
}
|
||||
|
||||
$rqHeaders = array_merge(
|
||||
['Accept' => 'application/json', 'Content-Type' => 'application/json'],
|
||||
$this->getHeaders()
|
||||
);
|
||||
|
||||
$request = new ClientRequest($method, $url, $rqHeaders);
|
||||
if (!empty($paramData)) {
|
||||
if ($this->requestOption === null) {
|
||||
$this->requestOption = new RequestOptions();
|
||||
}
|
||||
$this->requestOption->setBody($paramData);
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->client->sendRequest($request, $this->requestOption);
|
||||
|
||||
return new PipedriveHttpResponseService($response);
|
||||
} catch (TransferErrorExceptionInterface $exception) {
|
||||
throw new PipedriveHttpClientException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return HttpClientInterface
|
||||
*/
|
||||
private function createClient(): HttpClientInterface
|
||||
{
|
||||
if (!is_int($this->timeout) || $this->timeout < 0) {
|
||||
throw new PipedriveHttpClientException(
|
||||
sprintf('Connection timeout must be an int >= 0, got "%s".', gettype($this->timeout))
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->factory === null) {
|
||||
throw new PipedriveHttpClientException('HttpClientFactory is missing!');
|
||||
}
|
||||
|
||||
$options = new RequestOptions();
|
||||
if ($this->timeout > 0) {
|
||||
$options->setTimeout($this->timeout);
|
||||
}
|
||||
$options->setHeader('Accept', 'application/json');
|
||||
$options->setHeader('Content-Type', 'application/json');
|
||||
|
||||
$this->requestOption = $options;
|
||||
|
||||
return $this->factory->createClient($this->requestOption);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param array $header
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
public function get(string $url, array $data = [], array $header = []): ?PipedriveServerResponseInterface
|
||||
{
|
||||
if (!empty($data)) {
|
||||
$query = parse_url($url, PHP_URL_QUERY);
|
||||
$newQuery = http_build_query($data);
|
||||
$url = $query ? $url . '&' . $newQuery : $url . '?' . $newQuery;
|
||||
}
|
||||
|
||||
return $this->performRequest($url, self::GET_REQUEST, [], $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param array $header
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
public function post(string $url, array $data = [], array $header = []): ?PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->performRequest($url, self::POST_REQUEST, $data, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param array $header
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
public function patch(string $url, array $data = [], array $header = []): ?PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->performRequest($url, self::PATCH_REQUEST, $data, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param array $header
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
public function delete(string $url, array $data = [], array $header = []): ?PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->performRequest($url, self::DELETE_REQUEST, $data, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $option
|
||||
*/
|
||||
protected function setHeader(array $option = []): void
|
||||
{
|
||||
$this->_headers += $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getHeaders(): array
|
||||
{
|
||||
$default = ['User-Agent' => 'Xentral-ERP-CRM'];
|
||||
|
||||
return $this->_headers += $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param array $header
|
||||
*
|
||||
* @throws PipedriveHttpClientException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface|null
|
||||
*/
|
||||
public function put(string $url, array $data = [], array $header = []): ?PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->performRequest($url, self::PUT_REQUEST, $data, $header);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Xentral\Components\HttpClient\Response\ServerResponseInterface;
|
||||
|
||||
final class PipedriveHttpResponseService implements PipedriveServerResponseInterface
|
||||
{
|
||||
/** @var ServerResponseInterface $response */
|
||||
private $response;
|
||||
|
||||
/** @var null|array $json */
|
||||
private $json;
|
||||
|
||||
/**
|
||||
* @param ServerResponseInterface $response
|
||||
*/
|
||||
public function __construct(ServerResponseInterface $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
|
||||
$this->json = json_decode((string)$this->response->getBody(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the json response body
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
public function getJson(): ?array
|
||||
{
|
||||
return $this->json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getBody(): StreamInterface
|
||||
{
|
||||
return $this->response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->response->getStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess(): bool
|
||||
{
|
||||
$success = false;
|
||||
if (null !== $this->json && is_array($this->json)) {
|
||||
$success = array_key_exists('success', $this->json) && $this->json['success'] === true;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData(): array
|
||||
{
|
||||
$data = [];
|
||||
if (null !== $this->json && is_array($this->json) && array_key_exists('data', $this->json)) {
|
||||
$data = $this->json['data'] ?? [];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getError(): string
|
||||
{
|
||||
$error = '';
|
||||
if (null !== $this->json && is_array($this->json) && array_key_exists('error', $this->json) &&
|
||||
!in_array($this->getStatusCode(), [200, 201])) {
|
||||
$error = $this->json['error'] ?? 'Unknown Error';
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalData(): array
|
||||
{
|
||||
$additionalData = [];
|
||||
if (null !== $this->json && is_array($this->json) && array_key_exists('additional_data', $this->json)) {
|
||||
$additionalData = $this->json['additional_data'];
|
||||
}
|
||||
|
||||
return $additionalData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function getPagination(): ?array
|
||||
{
|
||||
$pagination = null;
|
||||
if (($additional_data = $this->getAdditionalData()) && array_key_exists('pagination', $additional_data)) {
|
||||
$pagination = $additional_data['pagination'];
|
||||
}
|
||||
|
||||
return $pagination;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveExceptionInterface;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
|
||||
final class PipedriveMetaReaderService
|
||||
{
|
||||
/** @var string $tmpDir directory to save the meta file */
|
||||
private $tmpDir;
|
||||
|
||||
/**
|
||||
* @param string $tmpDir
|
||||
*/
|
||||
public function __construct(string $tmpDir)
|
||||
{
|
||||
$this->tmpDir = $tmpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function readFromFile(string $fileName): ?array
|
||||
{
|
||||
if (empty($fileName)) {
|
||||
throw new PipedriveMetaException(
|
||||
sprintf('::readFromFile() Expects Meta content to be non empty string file, %s given', $fileName)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->exists($fileName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$fullFileName = $this->getFullFileName($fileName);
|
||||
|
||||
$meta = @file_get_contents($fullFileName);
|
||||
|
||||
if (($meta = json_decode($meta, true)) === null || (json_last_error() !== JSON_ERROR_NONE)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function getFullFileName(string $fileName): ?string
|
||||
{
|
||||
$metaFile = sprintf($this->tmpDir . DIRECTORY_SEPARATOR . '%s', $fileName);
|
||||
if (!is_file($metaFile)) {
|
||||
throw new PipedriveMetaException(sprintf('File "%s" was not found', $metaFile));
|
||||
}
|
||||
|
||||
return $metaFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(string $fileName): bool
|
||||
{
|
||||
try {
|
||||
$fullFileName = $this->getFullFileName($fileName);
|
||||
|
||||
return file_exists($fullFileName) && is_file($fullFileName);
|
||||
} catch (PipedriveExceptionInterface $exception) {
|
||||
//
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasKey(string $key, string $fileName): bool
|
||||
{
|
||||
return $this->exists($fileName) && ($meta = $this->readFromFile($fileName)) && array_key_exists($key, $meta);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
|
||||
final class PipedriveMetaWriterService
|
||||
{
|
||||
/** @var string $tmpDir directory to save the meta file */
|
||||
private $tmpDir;
|
||||
|
||||
/**
|
||||
* PipedriveMetaWriterService constructor.
|
||||
*
|
||||
* @param string $tmpDir
|
||||
*/
|
||||
public function __construct(string $tmpDir)
|
||||
{
|
||||
$this->tmpDir = $tmpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
public function save(string $fileName, array $data)
|
||||
{
|
||||
if (empty($fileName)) {
|
||||
throw new PipedriveMetaException('Name cannot be empty');
|
||||
}
|
||||
|
||||
if (!function_exists('json_encode')) {
|
||||
throw new PipedriveMetaException('Required PHP extension "json" is missing.');
|
||||
}
|
||||
|
||||
$content = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
|
||||
|
||||
return file_put_contents(
|
||||
$this->getFullFileName($fileName),
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getFullFileName(string $fileName): string
|
||||
{
|
||||
if (!is_dir($this->tmpDir) && !@mkdir($this->tmpDir, 0777, true) && !is_dir($this->tmpDir)) {
|
||||
throw new PipedriveMetaException(sprintf('Directory "%s" was not created', $this->tmpDir));
|
||||
}
|
||||
|
||||
return sprintf($this->tmpDir . DIRECTORY_SEPARATOR . '%s', $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(string $fileName): bool
|
||||
{
|
||||
$metaFile = $this->getFullFileName($fileName);
|
||||
|
||||
return file_exists($metaFile) && is_file($metaFile) && @unlink($metaFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedrivePersonPropertyServiceException;
|
||||
|
||||
final class PipedrivePersonPropertyService
|
||||
{
|
||||
|
||||
/** @var PipedriveClientService $client */
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @param PipedriveClientService $client
|
||||
*/
|
||||
public function __construct(PipedriveClientService $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getProperties(): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->read('getPersonFields');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getProperty(int $id): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->read('getOnePersonField', [], [$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedrivePersonPropertyServiceException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPdLeadStatus(): array
|
||||
{
|
||||
$response = $this->getProperty(9039);
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
throw new PipedrivePersonPropertyServiceException($response->getError());
|
||||
}
|
||||
|
||||
if (($data = $response->getData()) && array_key_exists('options', $data)) {
|
||||
return $data['options'];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveHttpClientException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedrivePersonServiceException;
|
||||
use Xentral\Modules\Pipedrive\Exception\PipedriveValidatorException;
|
||||
use Xentral\Modules\Pipedrive\Validator\PipedrivePersonValidator;
|
||||
|
||||
final class PipedrivePersonService
|
||||
{
|
||||
|
||||
/** @var array $itemOption */
|
||||
private $itemOption = [
|
||||
'limit' => 100,
|
||||
'items' => 'person',
|
||||
'start' => 0,
|
||||
'since_timestamp' => '1970-01-01 23:59:59',
|
||||
];
|
||||
|
||||
/** @var string[] $allowedSyncPeronOptions */
|
||||
private $allowedSyncPeronOptions = [
|
||||
'pipedrive_recently_updated' => 'getRecentlyUpdatedPersons',
|
||||
'pipedrive_all' => 'getAllPersons',
|
||||
];
|
||||
|
||||
/** @var PipedriveClientService $client */
|
||||
private $client;
|
||||
|
||||
/** @var PipedriveMetaReaderService $metaReaderService */
|
||||
private $metaReaderService;
|
||||
|
||||
/** @var PipedrivePersonValidator $validator */
|
||||
private $validator;
|
||||
|
||||
/**
|
||||
* PipedrivePersonService constructor.
|
||||
*
|
||||
* @param PipedriveClientService $client
|
||||
* @param PipedrivePersonValidator $validator
|
||||
* @param PipedriveMetaReaderService $metaReaderService
|
||||
*/
|
||||
public function __construct(
|
||||
PipedriveClientService $client,
|
||||
PipedrivePersonValidator $validator,
|
||||
PipedriveMetaReaderService $metaReaderService
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->validator = $validator;
|
||||
$this->metaReaderService = $metaReaderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getAllPersons(array $options = []): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->read('allPersons', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getRecentlyUpdatedPersons(array $options = []): PipedriveServerResponseInterface
|
||||
{
|
||||
$options = array_merge($this->itemOption, $options);
|
||||
|
||||
return $this->client->read('recentlyUpdatedPersons', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contactId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function deleteContact(int $contactId = 0): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->delete('deleteContact', [$contactId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedrivePersonServiceException
|
||||
* @throws PipedriveValidatorException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function createContact(array $data = []): PipedriveServerResponseInterface
|
||||
{
|
||||
if (!$this->validator->isValid($data)) {
|
||||
throw new PipedrivePersonServiceException(
|
||||
sprintf('%s::createContact Invalid contact data', get_class($this))
|
||||
);
|
||||
}
|
||||
$identity = $this->formatContactIdentity($this->validator->getData());
|
||||
|
||||
return $this->client->post('createContact', $identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contactId
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveConfigurationException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedrivePersonServiceException
|
||||
* @throws PipedriveValidatorException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function updateContactById(int $contactId, array $data = []): PipedriveServerResponseInterface
|
||||
{
|
||||
if (!$this->validator->isValid($data)) {
|
||||
throw new PipedrivePersonServiceException(
|
||||
sprintf('%s::updateContactById Invalid contact data', get_class($this))
|
||||
);
|
||||
}
|
||||
|
||||
$identity = $this->formatContactIdentity($this->validator->getData());
|
||||
|
||||
return $this->client->put('updateContact', $identity, [$contactId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function formatContactIdentity(array $data): array
|
||||
{
|
||||
$identity = [];
|
||||
foreach ($data as $property => $value) {
|
||||
if (in_array($property, ['email', 'phone'])) {
|
||||
$identity[$property][] = [
|
||||
'label' => 'other',
|
||||
'value' => $value,
|
||||
];
|
||||
} else {
|
||||
$identity[$property] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedrivePersonServiceException
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function pullPersons(string $type = 'pipedrive_all', array $options = []): PipedriveServerResponseInterface
|
||||
{
|
||||
$options = array_merge($this->itemOption, $options);
|
||||
|
||||
if ('pipedrive_all' !== $type && !array_key_exists($type, $this->allowedSyncPeronOptions)) {
|
||||
throw new PipedrivePersonServiceException(sprintf('Sync Type %s not allowed', $type));
|
||||
}
|
||||
|
||||
$metaFile = sprintf('%s.json', $type);
|
||||
|
||||
if ($type !== 'pipedrive_all') {
|
||||
$options = $this->addMetaOption($metaFile, $options);
|
||||
}
|
||||
|
||||
/** @var PipedriveServerResponseInterface $response */
|
||||
return $this->{$this->allowedSyncPeronOptions[$type]}($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contactId
|
||||
*
|
||||
* @throws PipedriveClientException
|
||||
* @throws PipedriveHttpClientException
|
||||
* @throws PipedriveMetaException
|
||||
* @throws PipedriveConfigurationException
|
||||
*
|
||||
* @return PipedriveServerResponseInterface
|
||||
*/
|
||||
public function getContactById(int $contactId): PipedriveServerResponseInterface
|
||||
{
|
||||
return $this->client->read('getContactById', [], [$contactId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $metaFile
|
||||
* @param array $options
|
||||
*
|
||||
* @throws PipedriveMetaException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addMetaOption(string $metaFile, array $options) : array
|
||||
{
|
||||
$metaInfo = $this->metaReaderService->readFromFile($metaFile);
|
||||
|
||||
if (!empty($metaInfo)) {
|
||||
$timeOffset = $metaInfo['timeOffset'];
|
||||
$offset = strtotime($metaInfo['timeOffset']);
|
||||
if ($offset !== false) {
|
||||
$timeOffset = gmdate('Y-m-d H:i:s', $offset - 3600);
|
||||
}
|
||||
$options = array_merge($options, ['since_timestamp' => $timeOffset]);
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\Pipedrive\Service;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
interface PipedriveServerResponseInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the json response body
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getJson();
|
||||
|
||||
/**
|
||||
* Gets the response body.
|
||||
*
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getBody(): StreamInterface;
|
||||
|
||||
/**
|
||||
* Gets the response status code.
|
||||
*
|
||||
* @return int Status code.
|
||||
*/
|
||||
public function getStatusCode(): int;
|
||||
|
||||
/**
|
||||
* Returns the error message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getError(): string;
|
||||
|
||||
/**
|
||||
* Checks whether the call was successful or not
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess(): bool;
|
||||
|
||||
/**
|
||||
* Retrieves Data from the response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData(): array;
|
||||
|
||||
/**
|
||||
* Retrieves Additional Data from the response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalData(): array;
|
||||
}
|
||||
Reference in New Issue
Block a user