chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace MauticPlugin\MauticCrmBundle\Api;
use Mautic\PluginBundle\Exception\ApiErrorException;
use MauticPlugin\MauticCrmBundle\Integration\SugarcrmIntegration;
/**
* @property SugarcrmIntegration $integration
*/
class SugarcrmApi extends CrmApi
{
protected $object = 'Leads';
/**
* @param array $data
* @param string $method
*
* @return mixed|string
*
* @throws ApiErrorException
*/
public function request($sMethod, $data = [], $method = 'GET', $object = null)
{
if (!$object) {
$object = $this->object;
}
$tokenData = $this->integration->getKeys();
if ('6' == $tokenData['version']) {
$request_url = sprintf('%s/service/v4_1/rest.php', $tokenData['sugarcrm_url']);
$sessionParams = [
'session' => $tokenData['id'],
];
if (!isset($data['module_names'])) {
$sessionParams['module_name'] = $object;
} // Making sure that module_name is the second value of the array
else {
$sessionParams['module_names'] = $data['module_names'];
}
$sessionParams = array_merge($sessionParams, $data);
$parameters = [
'method' => $sMethod,
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode($sessionParams),
];
$response = $this->integration->makeRequest($request_url, $parameters, $method);
if (is_array($response) && !empty($response['name']) && !empty($response['number'])) {
throw new ApiErrorException($response['name'].' '.$object.' '.$sMethod.' '.$method);
} else {
return $response;
}
} else {
$request_url = sprintf('%s/rest/v10/%s', $tokenData['sugarcrm_url'], $sMethod);
$settings = [
'request_timeout' => 50,
'encode_parameters' => 'json',
];
$response = $this->integration->makeRequest($request_url, $data, $method, $settings);
if (isset($response['error'])) {
throw new ApiErrorException($response['error_message'] ?? $response['error']['message'], ('invalid_grant' == $response['error']) ? 1 : 500);
}
return $response;
}
}
/**
* @return mixed|string
*
* @throws ApiErrorException
*/
public function getLeadFields($object = null)
{
if (!$object) {
$object = $this->object;
}
if ('company' == $object) {
$object = 'Accounts'; // sugarCRM object name
} elseif ('lead' == $object || 'Lead' == $object) {
$object = 'Leads';
} elseif ('contact' == $object || 'Contact' == $object) {
$object = 'Contacts';
}
$tokenData = $this->integration->getKeys();
if ('6' == $tokenData['version']) {
return $this->request('get_module_fields', [], 'GET', $object);
} else {
$parameters = [
'module_filter' => $object,
'type_filter' => 'modules',
];
$response = $this->request('metadata', $parameters, 'GET', $object);
return $response['modules'][$object];
}
}
/**
* @return array
*
* @throws ApiErrorException
*/
public function createLead(array $fields, $lead)
{
$tokenData = $this->integration->getKeys();
$createdLeadData = [];
// search for Sugar id in mautic records first to avoid making an API call
if (is_object($lead)) {
$sugarLeadRecords = $this->integration->getSugarLeadId($lead);
}
if ('6' == $tokenData['version']) {
// if not found then go ahead and make an API call to find all the records with that email
if (isset($fields['email1']) && empty($sugarLeadRecords)) {
$sLeads = $this->getLeads(['email' => $fields['email1'], 'offset' => 0, 'max_results' => 1000], 'Leads');
$sugarLeadRecords = $sLeads['entry_list'] ?? [];
}
$leadFields = [];
foreach ($fields as $name => $value) {
if ('id' != $name) {
$leadFields[] = [
'name' => $name,
'value' => $value,
];
}
}
$parameters = [
'name_value_list' => $leadFields,
];
if (!empty($sugarLeadRecords)) {
foreach ($sugarLeadRecords as $sLeadRecord) {
$localParam = $parameters;
$sugarLeadId = ($sLeadRecord['integration_entity_id'] ?? $sLeadRecord['id']);
$sugarObject = ($sLeadRecord['integration_entity'] ?? 'Leads');
// update the converted contact if found and not the Lead
if (isset($sLeadRecord['contact_id']) && null != $sLeadRecord['contact_id'] && '' != $sLeadRecord['contact_id']) {
unset($fields['Company']); // because this record is not in the Contact object.
$localParams['name_value_list'][] = ['name' => 'id', 'value' => $sLeadRecord['contact_id']];
$createdLeadData[] = $this->request('set_entry', $localParams, 'POST', 'Contacts');
} else {
$localParams['name_value_list'][] = ['name' => 'id', 'value' => $sugarLeadId];
$createdLeadData[] = $this->request('set_entry', $localParams, 'POST', $sugarObject);
}
}
} else {
$createdLeadData = $this->request('set_entry', $parameters, 'POST', 'Leads');
}
// $createdLeadData[] = $this->request('set_entry', $parameters, 'POST');
} else {
// if not found then go ahead and make an API call to find all the records with that email
if (isset($fields['email1']) && empty($sugarLeadRecords)) {
$sLeads = $this->getLeads(['email' => $fields['email1'], 'offset' => 0, 'max_results' => 1000], 'Leads');
$sugarLeadRecords = $sLeads['records'];
}
unset($fields['id']);
if (!empty($sugarLeadRecords)) {
foreach ($sugarLeadRecords as $sLeadRecord) {
$sugarLeadId = ($sLeadRecord['integration_entity_id'] ?? $sLeadRecord['id']);
$sugarObject = ($sLeadRecord['integration_entity'] ?? 'Leads');
// update the converted contact if found and not the Lead
$config = $this->integration->mergeConfigToFeatureSettings();
$fieldsToUpdateInSugar = isset($config['update_mautic']) ? array_keys($config['update_mautic'], 1) : [];
if (isset($sLeadRecord['contact_id']) && null != $sLeadRecord['contact_id'] && '' != $sLeadRecord['contact_id']) {
unset($fields['Company']); // because this record is not in the Contact object
$fieldsToUpdateInContactsSugar = $this->integration->cleanSugarData($config, $fieldsToUpdateInSugar, 'Contacts');
$contactSugarFields = array_diff_key($fields, $fieldsToUpdateInContactsSugar);
$createdLeadData[] = $this->request("Contacts/$sugarLeadId", $contactSugarFields, 'PUT', 'Contacts');
} else {
$fieldsToUpdateInLeadsSugar = $this->integration->cleanSugarData($config, $fieldsToUpdateInSugar, 'Leads');
$leadSugarFields = array_diff_key($fields, $fieldsToUpdateInLeadsSugar);
$createdLeadData[] = $this->request("$sugarObject/$sugarLeadId", $leadSugarFields, 'PUT', $sugarObject);
}
}
} else {
$createdLeadData = $this->request('Leads', $fields, 'POST', 'Leads');
}
// $createdLeadData[] = $this->request('set_entry', $fields, 'POST', 'Leads');
}
return $createdLeadData;
}
/**
* @return array
*
* @throws ApiErrorException
*/
public function syncLeadsToSugar(array $data)
{
$tokenData = $this->integration->getKeys();
$object = $this->object;
if ('6' == $tokenData['version']) {
$leadFieldsList = [];
$response = [];
foreach ($data as $object => $leadFieldsList) {
$parameters = [
'name_value_lists' => $leadFieldsList,
];
$resp = $this->request('set_entries', $parameters, 'POST', $object);
if (!empty($resp)) {
foreach ($leadFieldsList as $k => $leadFields) {
$fields = [];
foreach ($leadFields as $item) {
$fields[$item['name']] = $item['value'];
}
if (isset($resp['ids'])) {
$result = ['reference_id' => $fields['reference_id'],
'id' => $resp['ids'][$k],
'new' => !isset($fields['id']),
'ko' => false, ];
}
if (isset($resp['error'])) {
$result['ko'] = true;
$result['error'] = $resp['error']['message'];
}
if (isset($fields['id']) && $fields['id'] != $resp['ids'][$k]) {
$result['ko'] = true;
$result['error'] = 'Returned ID does not correspond to input id';
}
$response[] = $result;
}
}
}
return $response;
} else {
$leadFieldsList = [];
$response = [];
// body is prepared for Sugar6. Translate it to sugar 7
$reference_ids = [];
foreach ($data as $object => $leadFieldsList) {
$requests = [];
$all_ids = [];
foreach ($leadFieldsList as $body) {
$fields = [];
$ids = [];
foreach ($body as $field) {
$fields[$field['name']] = $field['value'];
}
$request = [];
if (isset($fields['id'])) {
$ids['id'] = $fields['id'];
// Update record
$sugarLeadId = $fields['id'];
unset($fields['id']);
$request['method'] = 'PUT';
$request['url'] = "/v10/$object/$sugarLeadId";
$request['data'] = $fields;
} else {
// Create record
$request['data'] = $fields;
$request['url'] = '/v10/'.$object;
$request['method'] = 'POST';
}
$requests[] = $request;
$ids['reference_id'] = $fields['reference_id'];
$all_ids[] = $ids;
}
$parameters = [
'requests' => $requests,
];
$resp = $this->request('bulk', $parameters, 'POST', $object);
if (!empty($resp)) {
foreach ($resp as $k => $leadFields) {
$fields = $leadFields['contents'];
if (200 != $leadFields['status']) {
$result = ['ko' => true,
'error' => $leadFields['error'].' '.$leadFields['error_message'], ];
} else {
$result = ['reference_id' => $all_ids[$k]['reference_id'],
'id' => $fields['id'],
'new' => !isset($all_ids[$k]['id']),
'ko' => false, ];
if (isset($all_ids[$k]['id']) && $fields['id'] != $all_ids[$k]['id']) {
$result['ko'] = true;
$result['error'] = 'Returned ID does not correspond to input id';
}
}
$response[] = $result;
}
}
}
return $response;
}
}
/**
* @param $object
* TODO 7.x
*
* @return array|mixed|string
*/
public function createLeadActivity(array $activity, $object)
{
$tokenData = $this->integration->getKeys();
// 1st : set_entries to return name_value_lists (array of arrays of name/value)
$set_name_value_lists = [];
// set relationship
$module_names = []; // Contacts or Leads
$module_ids = []; // Contacts or leads ids
$link_field_names = []; // Array of mtc_webactivities_contacts or mtc_webactivities_leads
$related_ids = []; // Array of arrays of web activity array
$name_value_lists = []; // array of empty arrays
$delete_array = []; // Array of 0
// set_relationships
$s7_records = [];
// Send activities and get back sugar activities id
if (!empty($activity)) {
foreach ($activity as $sugarId => $records) {
foreach ($records['records'] as $record) {
$rec = [];
$rec[] = ['name' => 'name', 'value' => $record['name']];
$rec[] = ['name' => 'description', 'value' => $record['description']];
$rec[] = ['name' => 'url', 'value' => $records['leadUrl']];
$rec[] = ['name' => 'date_entered', 'value' => $record['dateAdded']->format('c')];
$rec[] = ['name' => 'reference_id', 'value' => $record['id'].'-'.$sugarId];
if ('Contacts' == $object) {
$rec[] = ['name' => 'contact_id_c', 'value' => $sugarId];
} else {
$rec[] = ['name' => 'lead_id_c', 'value' => $sugarId];
}
$set_name_value_lists[] = $rec; // Sugar 6
$s7_record = [];
foreach ($rec as $r) {
$s7_record[$r['name']] = $r['value'];
}
$s7_records[] = $s7_record;
}
}
$parameters = [
'name_value_lists' => $set_name_value_lists,
];
if ('6' == $tokenData['version']) {
$resp = $this->request('set_entries', $parameters, 'POST', 'mtc_WebActivities');
} else {
$requests = [];
foreach ($s7_records as $fields) {
// Create record
$request['data'] = $fields;
$request['url'] = '/v10/mtc_WebActivities';
$request['method'] = 'POST';
$requests[] = $request;
}
$parameters = [
'requests' => $requests,
];
$resp = $this->request('bulk', $parameters, 'POST', 'bulk');
}
if ('6' == $tokenData['version']) {
// Send sugar relationsips
if (!empty($resp)) {
$nbLeads = 0;
$nbAct = 0;
$idList = [];
foreach ($activity as $sugarId => $records) {
$related_ids_row = [];
$module_names[] = $object;
$module_ids[] = $sugarId;
if ('Contacts' == $object) {
$link_field_names[] = 'mtc_webactivities_contacts';
} else {
$link_field_names[] = 'mtc_webactivities_leads';
}
++$nbLeads;
foreach ($records['records'] as $record) {
$name_value_lists[] = [];
$delete_array[] = 0;
$idList[] = $sugarId;
$related_ids_row[] = $resp['ids'][$nbAct];
++$nbAct;
}
$related_ids[] = $related_ids_row;
}
$parameters = [
'module_names' => $module_names, // Contacts or Leads
'module_ids' => $module_ids, // Contacts or leads ids
'link_field_names' => $link_field_names, // Array of mtc_webactivities_contacts or mtc_webactivities_leads
'related_ids' => $related_ids, // Array of arrays of web activity array
'name_value_lists' => $name_value_lists, // array of empty arrays
'delete_array' => $delete_array, // Array of 0
];
$resp2 = $this->request('set_relationships', $parameters, 'POST', $object);
}
} else {
// Sugar 7 set relationship
if (!empty($resp)) {
$nbAct = 0;
foreach ($activity as $sugarId => $records) {
if ('Contacts' == $object) {
$link_field_name = 'mtc_webactivities_contacts';
} else {
$link_field_name = 'mtc_webactivities_leads';
}
foreach ($records['records'] as $record) {
if (!isset($resp[$nbAct]['contents']['id'])) {
continue;
} // current Web activity was not created
$wa_id = $resp[$nbAct]['contents']['id'];
$resp2 = $this->request("mtc_WebActivities/$wa_id/link/$link_field_name/$sugarId", [], 'POST');
++$nbAct;
}
}
}
}
return [];
}
}
public function getEmailBySugarUserId($query = null)
{
$tokenData = $this->integration->getKeys();
if ('6' == $tokenData['version']) {
if (isset($query['emails'])) {
$q = " users.id IN (SELECT bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (eabr.email_address_id = ea.id) WHERE bean_module = 'Users' AND ea.email_address IN ('".implode("','", $query['emails'])."') AND eabr.deleted=0) ";
}
if (isset($query['ids'])) {
$q = " users.id IN ('".implode("','", $query['ids'])."') ";
}
$data = ['filter' => 'all'];
$fields = ['id', 'email1'];
$parameters = [
'query' => $q,
'order_by' => '',
'offset' => 0,
'select_fields' => $fields,
'link_name_to_fields_array' => [/* TO BE MODIFIED */
],
'max_results' => 1000,
'deleted' => 0,
'favorites' => false,
];
$data = $this->request('get_entry_list', $parameters, 'GET', 'Users');
if (isset($query['type']) && 'BYEMAIL' == $query['type']) {
$type = 'BYEMAIL';
} else {
$type = 'BYID';
}
$res = [];
if (isset($data['entry_list'])) {
foreach ($data['entry_list'] as $record) {
$fields = [];
$fields['id'] = $record['id'];
foreach ($record['name_value_list'] as $item) {
$fields[$item['name']] = $item['value'];
}
if ('BYID' == $type) {
$res[$fields['id']] = $fields['email1'];
} elseif (isset($fields['email1'])) {
$res[$fields['email1']] = $fields['id'];
} elseif ('BYEMAIL' == $type && !isset($fields['email1'])) {
$res[$query['emails'][0]] = $fields['id'];
}
}
}
return $res;
} else {
// TODO
if (isset($query['emails'])) {
$filter[] = ['email_addresses.email_address' => ['$in' => $query['emails']]];
$filter[] = ['deleted' => '0'];
}
if (isset($query['ids'])) {
$filter[] = ['id' => ['$in' => $query['ids']]];
}
$data = ['filter' => 'all'];
$fields = ['id', 'email1', 'email'];
$parameters = [
'filter' => [['$and' => $filter]],
'offset' => 0,
'fields' => implode(',', $fields),
'max_num' => 1000,
// 'deleted' => 0,
// 'favorites' => false,
];
$data = $this->request('Users/filter', $parameters, 'GET', 'Users');
if (isset($query['type']) && 'BYEMAIL' == $query['type']) {
$type = 'BYEMAIL';
} else {
$type = 'BYID';
}
$res = [];
if (isset($data['records'])) {
foreach ($data['records'] as $record) {
if (isset($record['email'][0]['email_address']) && '' != $record['email'][0]['email_address']) {
$found_email = $record['email'][0]['email_address'];
if (isset($record['name_value_list'])) {
foreach ($record['name_value_list'] as $email) {
if ('' != $email['email_address'] && 1 == $email['primary_address']) {
$found_email = $email;
break;
}
}
}
if ('BYID' == $type) {
$res[$record['id']] = $found_email;
} else {
$res[$found_email] = $record['id'];
}
}
}
}
return $res;
}
}
public function getIdBySugarEmail($query = null)
{
if (null == $query) {
$query = ['type' => 'BYEMAIL'];
} else {
$query['type'] = 'BYEMAIL';
}
return $this->getEmailBySugarUserId($query);
}
/**
* Get SugarCRM leads.
*
* @param array $query
* @param string $object
*
* @return mixed
*/
public function getLeads($query, $object)
{
$tokenData = $this->integration->getKeys();
$availableFields = $this->integration->getIntegrationSettings()->getFeatureSettings();
switch ($object) {
case 'company':
case 'Account':
case 'Accounts':
$fields = array_keys(array_filter($availableFields['companyFields']));
break;
default:
$mixedFields = array_filter($availableFields['leadFields']);
$fields = [];
$object = ('Contacts' == $object) ? 'Contacts' : 'Leads';
foreach ($mixedFields as $sugarField => $mField) {
if (str_contains($sugarField, '__'.$object)) {
$fields[] = str_replace('__'.$object, '', $sugarField);
}
if (str_contains($sugarField, '-'.$object)) {
$fields[] = str_replace('-'.$object, '', $sugarField);
}
}
}
if ('6' == $tokenData['version']) {
$result = [];
if (!empty($fields)) {
$q = '';
$qry = [];
if (isset($query['start'])) {
$qry[] = ' '.strtolower($object).".date_modified >= '".$query['start']."' ";
}
if (isset($query['end'])) {
$qry[] = ' '.strtolower($object).".date_modified <= '".$query['end']."' ";
}
if (isset($query['email'])) {
$qry[] = " leads.id IN (SELECT bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (eabr.email_address_id = ea.id) WHERE bean_module = 'Leads' AND ea.email_address = '".$query['email']."' AND eabr.deleted=0) ";
$fields[] = 'contact_id';
}
if (isset($query['checkemail'])) {
$qry[] = ' leads.deleted=0 ';
$qry[] = " leads.id IN (SELECT bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (eabr.email_address_id = ea.id) WHERE bean_module = 'Leads' AND ea.email_address IN ('".implode("','", $query['checkemail'])."') AND eabr.deleted=0) ";
$fields[] = 'contact_id';
$fields[] = 'deleted';
}
if (isset($query['checkemail_contacts'])) {
$qry[] = ' contacts.deleted=0 ';
$qry[] = " contacts.id IN (SELECT bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (eabr.email_address_id = ea.id) WHERE bean_module = 'Contacts' AND ea.email_address IN ('".implode("','", $query['checkemail_contacts'])."') AND eabr.deleted=0) ";
$fields[] = 'deleted';
}
$q = implode('AND', $qry);
$fields[] = 'id';
$fields[] = 'date_modified';
$fields[] = 'date_entered';
$fields[] = 'assigned_user_id';
$fields[] = 'email1';
if ('Accounts' != $object) {
$fields[] = 'account_id';
}
$parameters = [
'query' => $q,
'order_by' => '',
'offset' => $query['offset'],
'select_fields' => $fields,
'link_name_to_fields_array' => [/* TO BE MODIFIED */
[
'name' => 'email_addresses',
'value' => [
'email_address',
'opt_out',
'primary_address',
],
],
],
'max_results' => $query['max_results'],
'deleted' => 0,
'favorites' => false,
];
return $this->request('get_entry_list', $parameters, 'GET', $object);
}
} else {
if (!empty($fields)) {
$q = '';
$qry = [];
$filter = [];
if (isset($query['start'])) {
$filter[] = ['date_modified' => ['$gte' => $query['start']]];
// $qry[] = ' '.strtolower($object).".date_modified >= '".$query['start']."' ";
}
if (isset($query['end'])) {
$filter[] = ['date_modified' => ['$lte' => $query['end']]];
// $qry[] = ' '.strtolower($object).".date_modified <= '".$query['end']."' ";
}
if (isset($query['email'])) {
$filter[] = ['email' => ['$equals' => $query['email']]];
// $qry[] = " leads.id IN (SELECT bean_id FROM email_addr_bean_rel eabr JOIN email_addresses ea ON (eabr.email_address_id = ea.id) WHERE bean_module = 'Leads' AND ea.email_address = '".$query['email']."' AND eabr.deleted=0) ";
$fields[] = 'contact_id';
}
if (isset($query['checkemail'])) {
$filter[] = ['email' => ['$in' => $query['checkemail']]];
$filter[] = ['deleted' => '0'];
$fields = []; // Do not need previous fields
$fields[] = 'contact_id';
$fields[] = 'deleted';
}
if (isset($query['checkemail_contacts'])) {
$filter[] = ['email' => ['$in' => $query['checkemail_contacts']]];
$filter[] = ['deleted' => '0'];
$fields = []; // Do not need previous fields
$fields[] = 'deleted';
}
$fields[] = 'id';
$fields[] = 'date_modified';
$fields[] = 'date_entered';
$fields[] = 'assigned_user_id';
$fields[] = 'email1';
if ('Accounts' != $object) {
$fields[] = 'account_id';
}
// $filter_args = ['filter' => [['$and' => $filter]]];
// $fields_arg = implode(',', $fields);
$parameters = [
// 'order_by' => '',
'filter' => [['$and' => $filter]],
'offset' => $query['offset'],
'fields' => implode(',', $fields),
'max_num' => $query['max_results'],
// 'deleted' => 0,
// 'favorites' => false,
];
return $this->request("$object/filter", $parameters, 'GET', $object);
}
}
}
}