Skip to content

Commit

Permalink
refs #39637, gh-111, complete the ajax sync func, add report, add con…
Browse files Browse the repository at this point in the history
…tact id sync
  • Loading branch information
jimyhuang committed Jan 22, 2024
1 parent 94114fe commit 9b9205b
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 25 deletions.
113 changes: 100 additions & 13 deletions CRM/Mailing/External/SmartMarketing/Flydove.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private function apiRequestSend($apiType, $data = NULL) {
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);

$postData = array(
'token' => $token,
Expand All @@ -125,6 +125,10 @@ private function apiRequestSend($apiType, $data = NULL) {
}
curl_close($ch);
// Format the response and return it
if (!empty(CRM_Core_Config::singleton()->debug)) {
CRM_Core_Error::debug_log_message('FlydoveReqDebug-'.$apiUrl.': '.$postFields);
CRM_Core_Error::debug_log_message('FlydoveRespDebug: '.$responseData);
}
$decoded = json_decode($responseData, TRUE);
if ($decoded) {
if ($decoded['is_error']) {
Expand All @@ -150,7 +154,7 @@ private function apiRequestSend($apiType, $data = NULL) {
* @param int $providerId
* @return int batch id when success
*/
public function batchSchedule($contactIds, $destRemoteGroup, $providerId) {
public function batchSchedule($contactIds, $groupId, $destRemoteGroup, $providerId) {
$remoteGroups = $this->getRemoteGroups();
if (isset($remoteGroups[$destRemoteGroup])) {
if (!empty(count($contactIds))) {
Expand All @@ -159,8 +163,8 @@ public function batchSchedule($contactIds, $destRemoteGroup, $providerId) {
'label' => ts('Flydove').': '.ts('Manually Synchronize'),
'startCallback' => NULL,
'startCallbackArgs' => NULL,
'processCallback' => array($this, 'batchRunning'),
'processCallbackArgs' => array($contactIds, $destRemoteGroup, $providerId),
'processCallback' => array($this, 'addContactToRemote'),
'processCallbackArgs' => array($contactIds, $groupId, $destRemoteGroup, $providerId),
'finishCallback' => NULL,
'finishCallbackArgs' => NULL,
'total' => count($contactIds),
Expand Down Expand Up @@ -188,10 +192,29 @@ public function batchSchedule($contactIds, $destRemoteGroup, $providerId) {
* @static
* @return void|array
*/
public static function addContactToRemote($contactIds, $destRemoteGroup, $providerId) {
public static function addContactToRemote($contactIds, $groupId, $destRemoteGroup, $providerId) {
global $civicrm_batch;
$flydove = new CRM_Mailing_External_SmartMarketing_Flydove($providerId);
$remoteGroups = $flydove->getRemoteGroups();
// do not check remote group id if process is running
if (!empty($civicrm_batch) && $civicrm_batch->data['processed'] > 0) {
$remoteGroups = array($destRemoteGroup => 1);
}
else {
try {
$remoteGroups = $flydove->getRemoteGroups();
}
catch(CRM_Core_Exception $e) {
$errorMessage =$e->getMessage();
$errorCode =$e->getErrorCode();
if ($civicrm_batch) {
CRM_Core_Error::debug_log_message("Flydove error - : $errorCode $errorMessage");
return;
}
else {
throw new CRM_Core_Exception(ts('Flydove').':'.ts("Cannot get remote groups list."));
}
}
}
$phoneTypes = CRM_Core_OptionGroup::values('phone_type', TRUE, FALSE, FALSE, NULL, 'name');
$mobileTypeId = $phoneTypes['Mobile'];
if (isset($remoteGroups[$destRemoteGroup])) {
Expand All @@ -204,6 +227,7 @@ public static function addContactToRemote($contactIds, $destRemoteGroup, $provid
}
$limit = 10;
}
$skippedCount = 0;
for($i = 0; $i < $limit; $i++) {
$ids = array_slice($contactIds, $offset, self::BATCH_NUM);
if (empty($ids)) {
Expand Down Expand Up @@ -249,57 +273,120 @@ public static function addContactToRemote($contactIds, $destRemoteGroup, $provid
foreach($details[0] as $contactId => $detail) {
if (!CRM_Utils_Rule::email($detail['email']) || empty($detail['email'])) {
$skipped['invalid_or_empty_email'][] = $contactId;
$skippedCount++;
continue;
}
$detail['phone'] = preg_replace('/[^0-9]/', '', $detail['phone']);
if (!empty($detail['phone']) && is_string($detail['phone'])) {
$detail['phone'] = preg_replace('/[^0-9]/', '', $detail['phone']);
}
$syncData[] = array(
'email' => $detail['email'],
'phone' => !empty($detail['phone']) && strlen($detail['phone']) == 10 ? trim($detail['phone']) : '',
'title' => !empty($detail['individual_prefix']) && strlen($detail['individual_prefix']) < 10 ? $detail['individual_prefix'] : '',
'name' => !empty($detail['sort_name']) && mb_strlen($detail['sort_name']) < 50 ? $detail['sort_name'] : '',
'var1' => !empty($detail['birth_date']) && mb_strlen($detail['birth_date']) < 50 ? $detail['birth_date'] : '',
'var2' => '',
'var3' => '',
'var4' => '',
'var5' => (string) $contactId,
);
}
try {
$destRemoteGroup = (int) $destRemoteGroup;
$sendData = array(
'customers' => $syncData,
'group_ids' => array($destRemoteGroup),
);
// CRM_Core_Error::debug_var('sendData', $sendData);
$apiResult = $flydove->apiRequestSend('BatchCreateCustomer', json_encode($sendData));
if ($apiResult) {
$sliceResults[$i]['success'] = TRUE;
$sliceResults[$i]['skipped'] = $skipped;
}
if ($civicrm_batch) {
$civicrm_batch->data['processed'] += self::BATCH_NUM;
}
}
catch(CRM_Core_Exception $e) {
$errorMessage =$e->getMessage();
$errorCode =$e->getErrorCode();
CRM_Core_Error::debug_log_message("Flydove error - BatchCreateCustomer: $errorCode $errorMessage");
}

if ($civicrm_batch) {
$civicrm_batch->data['processed'] += self::BATCH_NUM;
}
$offset += self::BATCH_NUM;
usleep(500000);
}
CRM_Core_DAO::executeQuery("UPDATE civicrm_group SET last_sync = %1 WHERE id = %2", array(
1 => array(date('YmdHis'), 'String'),
2 => array($groupId, 'Integer')
));
$total = count($contactIds);
$sliceResults['#count'] = array(
'total' => $total,
'skipped' => $skippedCount,
'success' => $total - $skippedCount,
);
$sliceResults['#remote_group_id'] = is_numeric($remoteGroups[$destRemoteGroup]) ? $destRemoteGroup : $remoteGroups[$destRemoteGroup]."($destRemoteGroup)";
$sliceResults['#group_id'] = $groupId;
$report = self::formatResult($sliceResults);
if ($civicrm_batch) {
if ($civicrm_batch->data['processed'] >= $civicrm_batch->data['total']) {
$civicrm_batch->data['processed'] = $civicrm_batch->data['total'];
$civicrm_batch->data['isCompleted'] = TRUE;
}
foreach($report as $rep) {
CRM_Core_Error::debug_log_message($rep);
}
}
else {
foreach($report as $rep) {
CRM_Core_Error::debug_log_message($rep);
}
$sliceResults['#report'] = $report;
return $sliceResults;
}
}
else {
throw new CRM_Core_Exception(ts("Please provide at least 1 contact."));
if ($civicrm_batch) {
CRM_Core_Error::debug_log_message(ts('Flydove').': '."Please provide at least 1 contact.");
}
else {
throw new CRM_Core_Exception(ts("Please provide at least 1 contact."));
}
}
}
else {
throw new CRM_Core_Exception(ts('Flydove').':'.ts("Group you request doesn't exists in flydove."));
if ($civicrm_batch) {
CRM_Core_Error::debug_log_message(ts('Flydove').': '."The group you request doesn't exists in flydove.");
}
else {
throw new CRM_Core_Exception(ts('Flydove').': '.ts("The group you request doesn't exists in flydove."));
}
}
}

public static function formatResult($meta) {
$groups = CRM_Core_PseudoConstant::group();
$skippedText = array();
if (!empty($meta['#count']) && !empty($meta['#count']['skipped'])) {
foreach($meta as $idx => $slice) {
if (is_numeric($idx) && isset($slice['skipped']) && is_array($slice['skipped'])) {
foreach($slice['skipped'] as $reason => $ids) {
$skippedText[] = $reason.'('.count($ids).')';
}
}
}
}
$report['success'] = ts('Flydove').': '.ts('Success sync %1 contacts from group %2 to remote group %3', array(
1 => $meta['#count']['success'],
2 => $groups[$meta['#group_id']]."(".$meta['#group_id'].")",
3 => $meta['#remote_group_id']),
);
if (!empty($meta['#count']['skipped']) && !empty($skippedText)) {
$report['skipped'] = ts('Flydove').': '.ts('Skipped %1 contacts due to reasons: %2.', array(
1 => $meta['#count']['skipped'],
2 => implode(' / ', $skippedText)),
);
}
return $report;
}
}
48 changes: 36 additions & 12 deletions CRM/Mailing/Page/AJAX.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,47 @@ public static function addContactToRemote() {
$result = civicrm_api('group_contact', 'get', $apiParams);
if (!empty($result['values'])) {
$contactIds = array();
array_walk($result['values'], function($item) {
$contactIds[$item['contact_id']] = $item['contact_id'];
}, $contactIds);
foreach($result['values'] as $item) {
$contactIds[$item] = $item;
}
$provider = reset($providers);
$names = explode('_', $provider['name']);
$vendorName = end($names);
$smartMarketingClass = 'CRM_Mailing_External_SmartMarketing_'.$vendorName;
$smartMarketingService = new $smartMarketingClass($providerId);
try {
$batchId = $smartMarketingService->batchSchedule($contactIds, $syncData['remote_group_id'], $providerId);
$remoteResult = array(
'success' => TRUE,
'message' => ts('Because of the large amount of data you are about to perform, we have scheduled this job for the batch process. You will receive an email notification when the work is completed.'). ' &raquo; <a href="'.CRM_Utils_System::url('civicrm/admin/batch', "reset=1&id=$batchId").'" target="_blank">'.ts('Batch Job List').'</a>',
);
if (count($contactIds) > $smartMarketingClass::BATCH_NUM) {
$smartMarketingService = new $smartMarketingClass($providerId);
try {
$batchId = $smartMarketingService->batchSchedule($contactIds, $groupId, $syncData['remote_group_id'], $providerId);
$remoteResult = array(
'success' => TRUE,
'message' => '<p>'.ts('Because of the large amount of data you are about to perform, we have scheduled this job for the batch process. You will receive an email notification when the work is completed.'). '</p><p>&raquo; <a href="'.CRM_Utils_System::url('civicrm/admin/batch', "reset=1&id=$batchId").'" target="_blank">'.ts('Batch Job List').'</a></p>',
);
}
catch(CRM_Core_Exception $e) {
$remoteResult = array('success' => FALSE, 'message' => $e->getMessage());
}
}
catch(CRM_Core_Exception $e) {
$remoteResult = array('success' => FALSE, 'message' => $e->getMessage());
else {
try {
$syncResult = call_user_func(array($smartMarketingClass, 'addContactToRemote'), $contactIds, $groupId, $syncData['remote_group_id'], $providerId);
$report = 'Successful synced.';
if (!empty($syncResult['#report'])) {
$report = '';
foreach($syncResult['#report'] as $rep) {
$report .= "<p>$rep</p>";
}
}
$remoteResult = array(
'success' => TRUE,
'message' => $report,
);
}
catch(CRM_Core_Exception $e) {
$remoteResult = array(
'success' => FALSE,
'message' => ts('Synchronize error.').':'.$syncResult,
);
}
}
echo json_encode($remoteResult);
CRM_Utils_System::civiExit();
Expand Down

0 comments on commit 9b9205b

Please sign in to comment.