![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/mautic.corals.io/plugins/MauticCrmBundle/Integration/ |
<?php namespace MauticPlugin\MauticCrmBundle\Integration; use Mautic\LeadBundle\Entity\Company; use Mautic\LeadBundle\Entity\Lead; use Mautic\LeadBundle\Helper\IdentifyCompanyHelper; use Mautic\PluginBundle\Entity\IntegrationEntity; use Mautic\PluginBundle\Entity\IntegrationEntityRepository; use Mautic\PluginBundle\Exception\ApiErrorException; use Psr\Http\Message\ResponseInterface; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilder; class DynamicsIntegration extends CrmAbstractIntegration { public function getName(): string { return 'Dynamics'; } public function getDisplayName(): string { return 'Dynamics CRM'; } public function getSupportedFeatures(): array { return ['push_lead', 'get_leads', 'push_leads']; } /** * Return's authentication method such as oauth2, oauth1a, key, etc. */ public function getAuthenticationType(): string { return 'oauth2'; } /** * Return array of key => label elements that will be converted to inputs to * obtain from the user. * * @return array<string, string> */ public function getRequiredKeyFields(): array { return [ 'resource' => 'mautic.integration.dynamics.resource', 'client_id' => 'mautic.integration.dynamics.client_id', 'client_secret' => 'mautic.integration.dynamics.client_secret', ]; } /** * @param FormBuilder $builder * @param array $data * @param string $formArea */ public function appendToForm(&$builder, $data, $formArea): void { $builder->add( 'updateBlanks', ChoiceType::class, [ 'choices' => [ 'mautic.integrations.blanks' => 'updateBlanks', ], 'expanded' => true, 'multiple' => true, 'label' => 'mautic.integrations.form.blanks', 'label_attr' => ['class' => 'control-label'], 'placeholder' => false, 'required' => false, ] ); if ('features' === $formArea) { $builder->add( 'objects', ChoiceType::class, [ 'choices' => [ 'mautic.dynamics.object.contact' => 'contacts', 'mautic.dynamics.object.company' => 'company', ], 'expanded' => true, 'multiple' => true, 'label' => 'mautic.dynamics.form.objects_to_pull_from', 'label_attr' => ['class' => ''], 'placeholder' => false, 'required' => false, ] ); } } public function sortFieldsAlphabetically(): bool { return false; } /** * Get the array key for the auth token. */ public function getAuthTokenKey(): string { return 'access_token'; } /** * Get the keys for the refresh token and expiry. */ public function getRefreshTokenKeys(): array { return ['refresh_token', 'expires_on']; } /** * @return string */ public function getApiUrl() { return $this->keys['resource']; } public function getAccessTokenUrl(): string { return 'https://login.microsoftonline.com/common/oauth2/token'; } public function getAuthenticationUrl(): string { return 'https://login.microsoftonline.com/common/oauth2/authorize'; } public function getAuthLoginUrl(): string { $url = parent::getAuthLoginUrl(); return $url.('&resource='.urlencode($this->keys['resource'])); } /** * @param bool $inAuthorization */ public function getBearerToken($inAuthorization = false) { if (!$inAuthorization && isset($this->keys[$this->getAuthTokenKey()])) { return $this->keys[$this->getAuthTokenKey()]; } return false; } public function getDataPriority(): bool { return true; } /** * @return string|array */ public function getFormNotes($section) { if ('custom' === $section) { return [ 'template' => '@MauticCrm/Integration/dynamics.html.twig', 'parameters' => [ ], ]; } return parent::getFormNotes($section); } /** * @return array */ public function populateLeadData($lead, $config = [], $object = 'Contacts') { if ('company' === $object) { $object = 'accounts'; } $config['object'] = $object; return parent::populateLeadData($lead, $config); } /** * Get available company fields for choices in the config UI. * * @param array $settings * * @return array */ public function getFormCompanyFields($settings = []) { return $this->getFormFieldsByObject('accounts', $settings); } /** * @param array $settings * * @return array|mixed */ public function getFormLeadFields($settings = []) { return $this->getFormFieldsByObject('contacts', $settings); } /** * @param array $settings * * @throws ApiErrorException */ public function getAvailableLeadFields($settings = []): array { $dynamicsFields = []; $silenceExceptions = $settings['silence_exceptions'] ?? true; if (isset($settings['feature_settings']['objects'])) { $dynamicsObjects = $settings['feature_settings']['objects']; } else { $settings = $this->settings->getFeatureSettings(); $dynamicsObjects = $settings['objects'] ?? ['contacts']; } try { if ($this->isAuthorized()) { if (!empty($dynamicsObjects) && is_array($dynamicsObjects)) { foreach ($dynamicsObjects as $dynamicsObject) { // Check the cache first $settings['cache_suffix'] = $cacheSuffix = '.'.$dynamicsObject; if ($fields = parent::getAvailableLeadFields($settings)) { $dynamicsFields[$dynamicsObject] = $fields; continue; } $leadObject = $this->getApiHelper()->getLeadFields($dynamicsObject); if (null === $leadObject || !array_key_exists('value', $leadObject)) { return []; } $fields = $leadObject['value']; foreach ($fields as $field) { $type = 'string'; $fieldType = $field['AttributeTypeName']['Value']; if (in_array($fieldType, [ 'LookupType', 'OwnerType', 'PicklistType', 'StateType', 'StatusType', 'UniqueidentifierType', ], true)) { continue; } elseif (in_array($fieldType, [ 'DoubleType', 'IntegerType', 'MoneyType', ], true)) { $type = 'int'; } elseif ('Boolean' === $fieldType) { $type = 'boolean'; } elseif ('DateTimeType' === $fieldType) { $type = 'datetime'; } $dynamicsFields[$dynamicsObject][$field['LogicalName']] = [ 'type' => $type, 'label' => $field['DisplayName']['UserLocalizedLabel']['Label'], 'dv' => $field['LogicalName'], 'required' => 'ApplicationRequired' === $field['RequiredLevel']['Value'], ]; } $this->cache->set('leadFields'.$cacheSuffix, $dynamicsFields[$dynamicsObject]); } } } } catch (ApiErrorException $exception) { $this->logIntegrationError($exception); if (!$silenceExceptions) { throw $exception; } return []; } return $dynamicsFields; } /** * @param Lead $lead * @param array $config * * @return array|bool */ public function pushLead($lead, $config = []) { $config = $this->mergeConfigToFeatureSettings($config); if (empty($config['leadFields'])) { return []; } $mappedData = $this->populateLeadData($lead, $config, 'contacts'); $this->amendLeadDataBeforePush($mappedData); if (empty($mappedData)) { return false; } try { if ($this->isAuthorized()) { $object = 'contacts'; /** @var IntegrationEntityRepository $integrationEntityRepo */ $integrationEntityRepo = $this->em->getRepository(IntegrationEntity::class); $integrationId = $integrationEntityRepo->getIntegrationsEntityId('Dynamics', $object, 'lead', $lead->getId()); if (!empty($integrationId)) { $integrationEntityId = $integrationId[0]['integration_entity_id']; $this->getApiHelper()->updateLead($mappedData, $integrationEntityId); return $integrationEntityId; } /** @var ResponseInterface $response */ $response = $this->getApiHelper()->createLead($mappedData, $lead); // OData-EntityId: https://clientname.crm.dynamics.com/api/data/v8.2/contacts(9844333b-c955-e711-80f1-c4346bad526c) $header = $response->getHeader('OData-EntityId'); if (preg_match('/contacts\((.+)\)/', $header, $out)) { $id = $out[1]; if (empty($integrationId)) { $integrationEntity = new IntegrationEntity(); $integrationEntity->setDateAdded(new \DateTime()); $integrationEntity->setIntegration('Dynamics'); $integrationEntity->setIntegrationEntity($object); $integrationEntity->setIntegrationEntityId($id); $integrationEntity->setInternalEntity('lead'); $integrationEntity->setInternalEntityId($lead->getId()); } else { $integrationEntity = $integrationEntityRepo->getEntity($integrationId[0]['id']); } $integrationEntity->setLastSyncDate(new \DateTime()); $this->em->persist($integrationEntity); $this->em->flush($integrationEntity); return $id; } return true; } } catch (\Exception $e) { $this->logIntegrationError($e); } return false; } /** * @param array $params * @param array|null $query */ public function getLeads($params = [], $query = null, &$executed = null, $result = [], $object = 'contacts'): int { if ('Contacts' === $object) { $object = 'contacts'; } $executed = 0; $MAX_RECORDS = 200; // Default max records is 5000 try { if ($this->isAuthorized()) { $config = $this->mergeConfigToFeatureSettings(); $fields = $config['leadFields']; $config['object'] = $object; $aFields = $this->getAvailableLeadFields($config); $mappedData = []; foreach (array_keys($fields) as $k) { if (isset($aFields[$object][$k])) { $mappedData[] = $aFields[$object][$k]['dv']; } } $oparams['request_settings']['headers']['Prefer'] = 'odata.maxpagesize='.$MAX_RECORDS; $oparams['$select'] = implode(',', $mappedData); if (isset($params['fetchAll'], $params['start']) && !$params['fetchAll']) { $oparams['$filter'] = sprintf('modifiedon ge %sZ', substr($params['start'], 0, -6)); } if (isset($params['output']) && $params['output']->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) { $progress = new ProgressBar($params['output']); $progress->start(); } while (true) { $data = $this->getApiHelper()->getLeads($oparams); if (!isset($data['value'])) { break; // no more data, exit loop } $result = $this->amendLeadDataBeforeMauticPopulate($data, $object); $executed += array_key_exists('value', $data) ? count($data['value']) : count($result); if (isset($params['output'])) { if ($params['output']->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { $params['output']->writeln($result); } else { $progress->advance(count($result)); } } if (!isset($data['@odata.nextLink'])) { break; // default exit } // prepare next loop $nextLink = $data['@odata.nextLink']; $oparams['$skiptoken'] = urldecode(substr($nextLink, strpos($nextLink, '$skiptoken=') + 11)); } if (isset($params['output']) && $params['output']->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) { $progress->finish(); } } } catch (\Exception $e) { $this->logIntegrationError($e); } return $executed; } /** * @param array $params */ public function getCompanies($params = []): int { $executed = 0; $MAX_RECORDS = 200; // Default max records is 5000 $object = 'company'; try { if ($this->isAuthorized()) { $config = $this->mergeConfigToFeatureSettings(); $fields = $config['companyFields']; $config['object'] = $object; $aFields = $this->getAvailableLeadFields($config); $mappedData = []; if (isset($aFields['company'])) { $aFields = $aFields['company']; } foreach (array_keys($fields) as $k) { $mappedData[] = $aFields[$k]['dv']; } $oparams['request_settings']['headers']['Prefer'] = 'odata.maxpagesize='.$MAX_RECORDS; $oparams['$select'] = implode(',', $mappedData); if (isset($params['fetchAll'], $params['start']) && !$params['fetchAll']) { $oparams['$filter'] = sprintf('modifiedon ge %sZ', substr($params['start'], 0, -6)); } if (isset($params['output']) && $params['output']->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) { $progress = new ProgressBar($params['output']); $progress->start(); } while (true) { $data = $this->getApiHelper()->getCompanies($oparams); if (!isset($data['value'])) { break; // no more data, exit loop } $result = $this->amendLeadDataBeforeMauticPopulate($data, $object); $executed += count($result); if (isset($params['output'])) { if ($params['output']->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { $params['output']->writeln($result); } else { $progress->advance(count($result)); } } if (!isset($data['@odata.nextLink'])) { break; // default exit } // prepare next loop $nextLink = $data['@odata.nextLink']; $oparams['$skiptoken'] = urldecode(substr($nextLink, strpos($nextLink, '$skiptoken=') + 11)); } if (isset($params['output']) && $params['output']->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) { $progress->finish(); } } } catch (\Exception $e) { $this->logIntegrationError($e); } return $executed; } /** * Amend mapped lead data before creating to Mautic. * * @param array $data * @param string $object */ public function amendLeadDataBeforeMauticPopulate($data, $object = null): array { if ('company' === $object) { $object = 'accounts'; } elseif ('Lead' === $object || 'Contact' === $object) { $object = 'contacts'; } $config = $this->mergeConfigToFeatureSettings([]); $result = []; if (isset($data['value'])) { $this->em->getConnection()->getConfiguration()->setMiddlewares([]); $entity = null; /** @var IntegrationEntityRepository $integrationEntityRepo */ $integrationEntityRepo = $this->em->getRepository(IntegrationEntity::class); $objects = $data['value']; $integrationEntities = []; /** @var array $objects */ foreach ($objects as $entityData) { $isModified = false; if ('accounts' === $object) { $recordId = $entityData['accountid']; // first try to find integration entity $integrationId = $integrationEntityRepo->getIntegrationsEntityId('Dynamics', $object, 'company', null, null, null, false, 0, 0, "'".$recordId."'"); if (count($integrationId)) { // company exists, then update local fields /** @var Company $entity */ $entity = $this->companyModel->getEntity($integrationId[0]['internal_entity_id']); $matchedFields = $this->populateMauticLeadData($entityData, $config, 'company'); // Match that data with mapped lead fields $fieldsToUpdateInMautic = $this->getPriorityFieldsForMautic($config, $object, 'mautic_company'); if (!empty($fieldsToUpdateInMautic)) { $fieldsToUpdateInMautic = array_intersect_key($config['companyFields'], array_flip($fieldsToUpdateInMautic)); $newMatchedFields = array_intersect_key($matchedFields, array_flip($fieldsToUpdateInMautic)); } else { $newMatchedFields = $matchedFields; } if (!isset($newMatchedFields['companyname'])) { if (isset($newMatchedFields['companywebsite'])) { $newMatchedFields['companyname'] = $newMatchedFields['companywebsite']; } } // update values if already empty foreach ($matchedFields as $field => $value) { if (empty($entity->getFieldValue($field))) { $newMatchedFields[$field] = $value; } } // remove unchanged fields foreach ($newMatchedFields as $k => $v) { if ($entity->getFieldValue($k) === $v) { unset($newMatchedFields[$k]); } } if (count($newMatchedFields)) { $this->companyModel->setFieldValues($entity, $newMatchedFields, false); $this->companyModel->saveEntity($entity, false); $isModified = true; } } else { $entity = $this->getMauticCompany($entityData, 'company'); } if ($entity) { $result[] = $entity->getName(); } $mauticObjectReference = 'company'; } elseif ('contacts' === $object) { $recordId = $entityData['contactid']; // first try to find integration entity $integrationId = $integrationEntityRepo->getIntegrationsEntityId('Dynamics', $object, 'lead', null, null, null, false, 0, 0, "'".$recordId."'"); if (count($integrationId)) { // lead exists, then update /** @var Lead $entity */ $entity = $this->leadModel->getEntity($integrationId[0]['internal_entity_id']); $matchedFields = $this->populateMauticLeadData($entityData, $config); // Match that data with mapped lead fields $fieldsToUpdateInMautic = $this->getPriorityFieldsForMautic($config, $object, 'mautic'); if (!empty($fieldsToUpdateInMautic)) { $fieldsToUpdateInMautic = array_intersect_key($config['leadFields'] ?? [], array_flip($fieldsToUpdateInMautic)); $newMatchedFields = array_intersect_key($matchedFields, array_flip($fieldsToUpdateInMautic)); } else { $newMatchedFields = $matchedFields; } // update values if already empty foreach ($matchedFields as $field => $value) { if (empty($entity->getFieldValue($field))) { $newMatchedFields[$field] = $value; } } // remove unchanged fields foreach ($newMatchedFields as $k => $v) { if ($entity->getFieldValue($k) === $v) { unset($newMatchedFields[$k]); } } if (count($newMatchedFields)) { $this->leadModel->setFieldValues($entity, $newMatchedFields, false, false); $this->leadModel->saveEntity($entity, false); $isModified = true; } } else { /** @var Lead $entity */ $entity = $this->getMauticLead($entityData); } if ($entity) { $result[] = $entity->getEmail(); } // Associate lead company if (!empty($entityData['parentcustomerid']) // company && $entityData['parentcustomerid'] !== $this->translator->trans( 'mautic.integration.form.lead.unknown' ) ) { $company = IdentifyCompanyHelper::identifyLeadsCompany( ['company' => $entityData['parentcustomerid']], null, $this->companyModel ); if (!empty($company[2])) { $syncLead = $this->companyModel->addLeadToCompany($company[2], $entity); $this->em->detach($company[2]); } } $mauticObjectReference = 'lead'; } else { $this->logIntegrationError( new \Exception( sprintf('Received an unexpected object "%s"', $object) ) ); continue; } if ($entity) { $integrationId = $integrationEntityRepo->getIntegrationsEntityId( 'Dynamics', $object, $mauticObjectReference, $entity->getId() ); if (0 === count($integrationId)) { $integrationEntity = new IntegrationEntity(); $integrationEntity->setDateAdded(new \DateTime()); $integrationEntity->setIntegration('Dynamics'); $integrationEntity->setIntegrationEntity($object); $integrationEntity->setIntegrationEntityId($recordId); $integrationEntity->setInternalEntity($mauticObjectReference); $integrationEntity->setInternalEntityId($entity->getId()); $integrationEntities[] = $integrationEntity; } else { $integrationEntity = $integrationEntityRepo->getEntity($integrationId[0]['id']); if ($isModified) { $integrationEntity->setLastSyncDate(new \DateTime()); $integrationEntities[] = $integrationEntity; } } $this->em->detach($entity); unset($entity); } } $integrationEntityRepo->saveEntities($integrationEntities); $this->em->clear(); unset($integrationEntityRepo, $integrationEntities); } return $result; } /** * @param array $params * * @return mixed[] */ public function pushLeads($params = []): array { $MAX_RECORDS = (isset($params['limit']) && $params['limit'] < 100) ? $params['limit'] : 100; if (isset($params['fetchAll']) && $params['fetchAll']) { $params['start'] = null; $params['end'] = null; } $object = 'contacts'; $config = $this->mergeConfigToFeatureSettings(); $integrationEntityRepo = $this->em->getRepository(IntegrationEntity::class); $fieldsToUpdateInCrm = isset($config['update_mautic']) ? array_keys($config['update_mautic'], 0) : []; $leadFields = array_unique(array_values($config['leadFields'] ?? [])); $totalUpdated = $totalCreated = $totalErrors = 0; if ($key = array_search('mauticContactTimelineLink', $leadFields)) { unset($leadFields[$key]); } if ($key = array_search('mauticContactIsContactableByEmail', $leadFields)) { unset($leadFields[$key]); } if (empty($leadFields)) { return [0, 0, 0]; } $fields = implode(', l.', $leadFields); $fields = 'l.'.$fields; $availableFields = $this->getAvailableLeadFields(['feature_settings' => ['objects' => [$object]]]); $fieldsToUpdate[$object] = array_values(array_intersect(array_keys($availableFields[$object]), $fieldsToUpdateInCrm)); $fieldsToUpdate[$object] = array_intersect_key($config['leadFields'] ?? [], array_flip($fieldsToUpdate[$object])); $progress = false; $totalToUpdate = array_sum($integrationEntityRepo->findLeadsToUpdate('Dynamics', 'lead', $fields, 0, $params['start'], $params['end'], [$object])); $totalToCreate = $integrationEntityRepo->findLeadsToCreate('Dynamics', $fields, 0, $params['start'], $params['end']); $totalCount = $totalToCreate + $totalToUpdate; if (defined('IN_MAUTIC_CONSOLE')) { // start with update if ($totalToUpdate + $totalToCreate) { $output = new ConsoleOutput(); $output->writeln("About $totalToUpdate to update and about $totalToCreate to create/update"); $output->writeln('<info>This could take some time. Please wait until the process is completed</info>'); $progress = new ProgressBar($output, $totalCount); } } // Start with contacts so we know who is a contact when we go to process converted leads $leadsToCreateInD = []; $leadsToUpdateInD = []; $integrationEntities = []; $toUpdate = $integrationEntityRepo->findLeadsToUpdate('Dynamics', 'lead', $fields, $totalToUpdate, $params['start'], $params['end'], $object, [])[$object]; if (is_array($toUpdate)) { $totalUpdated += count($toUpdate); foreach ($toUpdate as $lead) { if (isset($lead['email']) && !empty($lead['email'])) { $key = mb_strtolower($this->cleanPushData($lead['email'])); $lead = $this->getCompoundMauticFields($lead); $lead['integration_entity'] = $object; $leadsToUpdateInD[$key] = $lead; $integrationEntity = $this->em->getReference(IntegrationEntity::class, $lead['id']); $integrationEntities[] = $integrationEntity->setLastSyncDate(new \DateTime()); } } } unset($toUpdate); // create lead records, including deleted on D side (last_sync = null) /** @var array $leadsToCreate */ $leadsToCreate = $integrationEntityRepo->findLeadsToCreate('Dynamics', $fields, $totalToCreate, $params['start'], $params['end']); if (is_array($leadsToCreate)) { $totalCreated += count($leadsToCreate); foreach ($leadsToCreate as $lead) { if (isset($lead['email']) && !empty($lead['email'])) { $key = mb_strtolower($this->cleanPushData($lead['email'])); $lead = $this->getCompoundMauticFields($lead); $lead['integration_entity'] = $object; $leadsToCreateInD[$key] = $lead; } } } unset($leadsToCreate); if (count($integrationEntities)) { // Persist updated entities if applicable $integrationEntityRepo->saveEntities($integrationEntities); $this->integrationEntityModel->getRepository()->detachEntities($integrationEntities); } // update contacts $leadData = []; $rowNum = 0; foreach ($leadsToUpdateInD as $lead) { $mappedData = []; if (defined('IN_MAUTIC_CONSOLE') && $progress) { $progress->advance(); } $existingPerson = $this->getExistingRecord('emailaddress1', $lead['email'], $object); $objectFields = $this->prepareFieldsForPush($availableFields[$object]); $fieldsToUpdate[$object] = $this->getBlankFieldsToUpdate($fieldsToUpdate[$object], $existingPerson, $objectFields, $config); // Match that data with mapped lead fields foreach ($fieldsToUpdate[$object] as $k => $v) { foreach ($lead as $dk => $dv) { if ($v === $dk) { if ($dv) { if (isset($availableFields[$object][$k])) { $mappedData[$availableFields[$object][$k]['dv']] = $dv; } } } } } $leadData[$lead['integration_entity_id']] = $mappedData; ++$rowNum; // SEND 100 RECORDS AT A TIME if ($MAX_RECORDS === $rowNum) { $this->getApiHelper()->updateLeads($leadData, $object); $leadData = []; $rowNum = 0; } } $this->getApiHelper()->updateLeads($leadData, $object); // create contacts $leadData = []; $rowNum = 0; foreach ($leadsToCreateInD as $lead) { $mappedData = []; if (defined('IN_MAUTIC_CONSOLE') && $progress) { $progress->advance(); } if (!isset($config['leadFields']) || !is_iterable($config['leadFields'])) { continue; } // Match that data with mapped lead fields foreach ($config['leadFields'] as $k => $v) { foreach ($lead as $dk => $dv) { if ($v === $dk) { if ($dv) { if (isset($availableFields[$object][$k])) { $mappedData[$availableFields[$object][$k]['dv']] = $dv; } } } } } $leadData[$lead['internal_entity_id']] = $mappedData; ++$rowNum; // SEND 100 RECORDS AT A TIME if ($MAX_RECORDS === $rowNum) { $ids = $this->getApiHelper()->createLeads($leadData, $object); $this->createIntegrationEntities($ids, $object, $integrationEntityRepo); $leadData = []; $rowNum = 0; } } $ids = $this->getApiHelper()->createLeads($leadData, $object); $this->createIntegrationEntities($ids, $object, $integrationEntityRepo); if ($progress) { $progress->finish(); $output->writeln(''); } return [$totalUpdated, $totalCreated, $totalErrors]; } /** * @param array $ids * @param IntegrationEntityRepository $integrationEntityRepo */ private function createIntegrationEntities($ids, $object, $integrationEntityRepo): void { foreach ($ids as $oid => $leadId) { $this->logger->debug('CREATE INTEGRATION ENTITY: '.$oid); $integrationId = $integrationEntityRepo->getIntegrationsEntityId('Dynamics', $object, 'lead', null, null, null, false, 0, 0, "'".$oid."'" ); if (0 === count($integrationId)) { $this->createIntegrationEntity($object, $oid, 'lead', $leadId); } } } private function getExistingRecord($seachColumn, $searchValue, $object = 'contacts') { $availableFields = $this->getAvailableLeadFields(); $oparams['$select'] = implode(',', array_keys($availableFields[$object])); $oparams['$filter'] = $seachColumn.' eq \''.$searchValue.'\''; $data = $this->getApiHelper()->getLeads($oparams); return (isset($data['value'][0]) && !empty($data['value'][0])) ? $data['value'][0] : []; } }