/** * Create a new bounce event, update the email address if necessary */ static function &create(&$params) { $q =& CRM_Mailing_Event_BAO_Queue::verify($params['job_id'], $params['event_queue_id'], $params['hash']); $success = NULL; if (!$q) { return $success; } $transaction = new CRM_Core_Transaction(); $bounce = new CRM_Mailing_Event_BAO_Bounce(); $bounce->time_stamp = date('YmdHis'); // if we dont have a valid bounce type, we should set it // to bounce_type_id 11 which is Syntax error. this allows such email // addresses to be bounce a few more time before being put on hold // CRM-4814 // we changed this behavior since this bounce type might be due to some issue // with the connection or smtp server etc if (empty($params['bounce_type_id'])) { $params['bounce_type_id'] = 11; if (empty($params['bounce_reason'])) { $params['bounce_reason'] = ts('Unknown bounce type: Could not parse bounce email'); } } $bounce->copyValues($params); $bounce->save(); $success = TRUE; $bounceTable = CRM_Mailing_Event_BAO_Bounce::getTableName(); $bounceType = CRM_Mailing_DAO_BounceType::getTableName(); $emailTable = CRM_Core_BAO_Email::getTableName(); $queueTable = CRM_Mailing_Event_BAO_Queue::getTableName(); $bounce->reset(); // might want to put distinct inside the count $query = "SELECT count({$bounceTable}.id) as bounces,\n {$bounceType}.hold_threshold as threshold\n FROM {$bounceTable}\n INNER JOIN {$bounceType}\n ON {$bounceTable}.bounce_type_id = {$bounceType}.id\n INNER JOIN {$queueTable}\n ON {$bounceTable}.event_queue_id = {$queueTable}.id\n INNER JOIN {$emailTable}\n ON {$queueTable}.email_id = {$emailTable}.id\n WHERE {$emailTable}.id = {$q->email_id}\n AND ({$emailTable}.reset_date IS NULL\n OR {$bounceTable}.time_stamp >= {$emailTable}.reset_date)\n GROUP BY {$bounceTable}.bounce_type_id\n ORDER BY threshold, bounces desc"; $bounce->query($query); while ($bounce->fetch()) { if ($bounce->bounces >= $bounce->threshold) { $email = new CRM_Core_BAO_Email(); $email->id = $q->email_id; $email->on_hold = TRUE; $email->hold_date = date('YmdHis'); $email->save(); break; } } $transaction->commit(); return $success; }
/** * Create a new bounce event, update the email address if necessary */ static function &create(&$params) { $q =& CRM_Mailing_Event_BAO_Queue::verify($params['job_id'], $params['event_queue_id'], $params['hash']); $success = null; if (!$q) { return $success; } require_once 'CRM/Core/Transaction.php'; $transaction = new CRM_Core_Transaction(); $bounce = new CRM_Mailing_Event_BAO_Bounce(); $bounce->time_stamp = date('YmdHis'); // if we dont have a valid bounce type, we should set it // to bounce_type_id 6 which is Invalid. this allows such email // addresses to be put on hold immediately, CRM-4814 if (empty($params['bounce_type_id'])) { $params['bounce_type_id'] = 6; $params['bounce_reason'] = ts('Unknown bounce type: Could not parse bounce email'); } $bounce->copyValues($params); $bounce->save(); $success = true; $bounceTable = CRM_Mailing_Event_BAO_Bounce::getTableName(); $bounceType = CRM_Mailing_DAO_BounceType::getTableName(); $emailTable = CRM_Core_BAO_Email::getTableName(); $queueTable = CRM_Mailing_Event_BAO_Queue::getTableName(); $bounce->reset(); // might want to put distinct inside the count $query = "SELECT count({$bounceTable}.id) as bounces,\n {$bounceType}.hold_threshold as threshold\n FROM {$bounceTable}\n INNER JOIN {$bounceType}\n ON {$bounceTable}.bounce_type_id = {$bounceType}.id\n INNER JOIN {$queueTable}\n ON {$bounceTable}.event_queue_id = {$queueTable}.id\n INNER JOIN {$emailTable}\n ON {$queueTable}.email_id = {$emailTable}.id\n WHERE {$emailTable}.id = {$q->email_id}\n AND ({$emailTable}.reset_date IS NULL\n OR {$bounceTable}.time_stamp >= {$emailTable}.reset_date)\n GROUP BY {$bounceTable}.bounce_type_id\n ORDER BY threshold, bounces desc"; $bounce->query($query); while ($bounce->fetch()) { if ($bounce->bounces >= $bounce->threshold) { $email = new CRM_Core_BAO_Email(); $email->id = $q->email_id; $email->on_hold = true; $email->hold_date = date('YmdHis'); $email->save(); break; } } $transaction->commit(); return $success; }
/** * Create a new delivery event. * * @param array $params * Associative array of delivery event values. * * @return void */ public static function &create(&$params) { $q =& CRM_Mailing_Event_BAO_Queue::verify($params['job_id'], $params['event_queue_id'], $params['hash']); if (!$q) { return NULL; } $q->free(); $delivered = new CRM_Mailing_Event_BAO_Delivered(); $delivered->time_stamp = date('YmdHis'); $delivered->copyValues($params); $delivered->save(); $queue = new CRM_Mailing_Event_BAO_Queue(); $queue->id = $params['event_queue_id']; $queue->find(TRUE); while ($queue->fetch()) { $email = new CRM_Core_BAO_Email(); $email->id = $queue->email_id; $email->hold_date = ''; $email->reset_date = date('YmdHis'); $email->save(); } return $delivered; }
function run() { $my_key = CRM_Core_BAO_Setting::getItem(self::MC_SETTING_GROUP, 'security_key', NULL, FALSE); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run $my_key= ', $my_key); if (CRM_Core_Config::singleton()->userPermissionClass->isModulePermissionSupported() && !CRM_Mailchimp_Permission::check('allow webhook posts')) { CRM_Core_Error::fatal(); } // Check the key // @todo is this a DOS attack vector? seems a lot of work for saying 403, go away, to a robot! if (!isset($_GET['key']) || $_GET['key'] != $my_key) { CRM_Core_Error::fatal(); } if (!empty($_POST['data']['list_id']) && !empty($_POST['type'])) { $requestType = $_POST['type']; $requestData = $_POST['data']; switch ($requestType) { case 'subscribe': case 'unsubscribe': case 'profile': // Create/Update contact details in CiviCRM $delay = $requestType == 'profile'; $contactID = CRM_Mailchimp_Utils::updateContactDetails($requestData['merges'], $delay); $contactArray = array($contactID); // Subscribe/Unsubscribe to related CiviCRM groups self::manageCiviCRMGroupSubcription($contactID, $requestData, $requestType); CRM_Mailchimp_Utils::checkDebug('Start - CRM_Mailchimp_Page_WebHook run $_POST= ', $_POST); CRM_Mailchimp_Utils::checkDebug('Start - CRM_Mailchimp_Page_WebHook run $contactID= ', $contactID); CRM_Mailchimp_Utils::checkDebug('Start - CRM_Mailchimp_Page_WebHook run $requestData= ', $requestData); CRM_Mailchimp_Utils::checkDebug('Start - CRM_Mailchimp_Page_WebHook run $requestType= ', $requestType); break; case 'upemail': // Mailchimp Email Update event // Try to find the email address $email = new CRM_Core_BAO_Email(); $email->get('email', $requestData['old_email']); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run- case upemail $requestData[old_email]= ', $requestData['old_email']); // If the Email was found. if (!empty($email->contact_id)) { $email->email = $requestData['new_email']; $email->save(); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run- case upemail inside condition $requestData[new_email]= ', $requestData['new_email']); } break; case 'cleaned': // Try to find the email address $email = new CRM_Core_BAO_Email(); $email->get('email', $requestData['email']); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run - case cleaned $requestData[new_email]= ', $requestData['email']); // If the Email was found. if (!empty($email->contact_id)) { $email->on_hold = 1; $email->holdEmail($email); $email->save(); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run - case cleaned inside condition $email= ', $email); CRM_Mailchimp_Utils::checkDebug('CRM_Mailchimp_Page_WebHook run - case cleaned inside condition $requestData[new_email]= ', $requestData['email']); } break; default: // unhandled webhook CRM_Mailchimp_Utils::checkDebug('End- CRM_Mailchimp_Page_WebHook run $contactID= ', $contactID); CRM_Mailchimp_Utils::checkDebug('End- CRM_Mailchimp_Page_WebHook run $requestData= ', $requestData); CRM_Mailchimp_Utils::checkDebug('End- CRM_Mailchimp_Page_WebHook run $requestType= ', $requestType); CRM_Mailchimp_Utils::checkDebug('End - CRM_Mailchimp_Page_WebHook run $email= ', $email); } } // Return the JSON output header('Content-type: application/json'); $data = NULL; // We should ideally throw some status print json_encode($data); CRM_Utils_System::civiExit(); }
function testDetermineMailchimpEmailForContact() { $params = array('first_name' => 'MCFirst', 'last_name' => 'MCLast', 'contact_type' => 'Individual', 'do_not_email' => TRUE); $initial_contact = CRM_Contact_BAO_Contact::add($params); $primary_email = new CRM_Core_BAO_Email(); $primary_email->contact_id = $initial_contact->id; $primary_email->email = '*****@*****.**'; $primary_email->is_primary = TRUE; $primary_email->save(); $bulk_email = new CRM_Core_BAO_Email(); $bulk_email->contact_id = $initial_contact->id; $bulk_email->email = '*****@*****.**'; $bulk_email->is_bulkmail = TRUE; $bulk_email->save(); $contact = CRM_CiviMailchimp_Utils::getContactById($initial_contact->id); // Test that a contact with do_not_mail does not return an email address. $mailchimp_email = CRM_CiviMailchimp_Utils::determineMailchimpEmailForContact($contact); $this->assertNull($mailchimp_email); // Test that a contact with is_opt_out does not return an email address. $contact->do_not_email = FALSE; $contact->is_opt_out = TRUE; $contact->save(); $mailchimp_email = CRM_CiviMailchimp_Utils::determineMailchimpEmailForContact($contact); $this->assertNull($mailchimp_email); // Test that a is_bulkmail email is returned rather than an is_primary one. $contact->is_opt_out = FALSE; $contact->save(); $mailchimp_email = CRM_CiviMailchimp_Utils::determineMailchimpEmailForContact($contact); $this->assertEquals($bulk_email->email, $mailchimp_email); // Test that is_primary email is returned if no is_bulkmail email exists. $bulk_email->is_bulkmail = FALSE; $bulk_email->save(); $contact = CRM_CiviMailchimp_Utils::getContactById($initial_contact->id); $mailchimp_email = CRM_CiviMailchimp_Utils::determineMailchimpEmailForContact($contact); $this->assertEquals($primary_email->email, $mailchimp_email); // Test that is_primary email marked on_hold with no is_bulkmail email // does not return an email address. $primary_email->on_hold = TRUE; $primary_email->save(); $contact = CRM_CiviMailchimp_Utils::getContactById($initial_contact->id); $mailchimp_email = CRM_CiviMailchimp_Utils::determineMailchimpEmailForContact($contact); $this->assertNull($mailchimp_email); }
function testMailchimpWebhookCleaned() { $sample_data = self::sampleRequestSubscribeOrProfileUpdate(); $contact = CRM_CiviMailchimp_Utils::createContactFromMailchimpRequest($sample_data); $sync_settings = CRM_CiviMailchimp_BAO_SyncSettingsTest::createTestGroupAndSyncSettings('test_group_mailchimp_webhook_cleaned'); CRM_Contact_BAO_GroupContact::addContactsToGroup(array($contact->id), $sync_settings->civicrm_group_id); $email2 = new CRM_Core_BAO_Email(); $email2->contact_id = $contact->id; $email2->email = 'civimailchimp_cleaned_test' . rand() . '@civimailchimp.org'; $email2->save(); $clean_request = self::getCleanRequestFromSampleProfileData($sample_data); CRM_CiviMailchimp_Page_Webhook::mailchimpWebhookCleaned($clean_request); $mailchimp_contact = CRM_CiviMailchimp_Utils::getContactById($contact->id); $this->assertEquals($mailchimp_contact->email[0]->on_hold, 1); $this->assertEquals($mailchimp_contact->email[1]->on_hold, 0); }