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(); }
/** * New contacts from Mailchimp need bringing into CiviCRM. */ static function syncPullUpdates(CRM_Queue_TaskContext $ctx, $listID) { // Prepare the groups that we need to update $stats[$listID]['added'] = $stats[$listID]['removed'] = 0; // We need the membership group and any groups mapped to interest groupings with the allow MC updates option set. $membership_group_id = FALSE; $updatable_grouping_groups = array(); foreach (CRM_Mailchimp_Utils::getGroupsToSync(array(), $listID) as $groupID => $details) { if (!$details['grouping_id']) { $membership_group_id = $groupID; } elseif ($details['is_mc_update_grouping']) { // This group is one that we allow Mailchimp to update CiviCRM with. $updatable_grouping_groups[$groupID] = $details; } } // all Mailchimp table $dao = CRM_Core_DAO::executeQuery("SELECT m.*, c.groupings c_groupings\n FROM tmp_mailchimp_push_m m\n LEFT JOIN tmp_mailchimp_push_c c ON m.email = c.email\n ;"); // Loop the $dao object creating/finding contacts in CiviCRM. $groupContactRemoves = $groupContact = array(); while ($dao->fetch()) { $params = array('FNAME' => $dao->first_name, 'LNAME' => $dao->last_name, 'EMAIL' => $dao->email); // Update/create contact. $contact_id = CRM_Mailchimp_Utils::updateContactDetails($params); if ($contact_id) { // Ensure the contact is in the membership group. if (!$dao->c_groupings) { // This contact was not found in the CiviCRM table. // Therefore they are not in the membership group. // (actually they could have an email problem as well, but that's OK). // Add them into the membership group. $groupContact[$membership_group_id][] = $contact_id; $civi_groupings = array(); $stats[$listID]['added']++; } else { // This contact is in C and MC, but has differences. // unpack the group membership from CiviCRM. $civi_groupings = unserialize($dao->c_groupings); } // unpack the group membership reported by MC $mc_groupings = unserialize($dao->groupings); // Now sort out the grouping_groups for those we are supposed to allow updates for foreach ($updatable_grouping_groups as $groupID => $details) { // Should this person be in this grouping:group according to MC? if (!empty($mc_groupings[$details['grouping_id']][$details['group_id']])) { // They should be in this group. if (empty($civi_groupings[$details['grouping_id']][$details['group_id']])) { // But they're not! Plan to add them in. $groupContact[$groupID][] = $contact_id; } } else { // They should NOT be in this group. if (!empty($civi_groupings[$details['grouping_id']][$details['group_id']])) { // But they ARE. Plan to remove them. $groupContactRemoves[$groupID][] = $contact_id; } } } } } // And now, what if a contact is not in the Mailchimp list? We must remove them from the membership group. $dao = CRM_Core_DAO::executeQuery("SELECT c.contact_id\n FROM tmp_mailchimp_push_c c\n WHERE NOT EXISTS (\n SELECT m.email FROM tmp_mailchimp_push_m m WHERE m.email=c.email\n );"); // Loop the $dao object creating/finding contacts in CiviCRM. while ($dao->fetch()) { $groupContactRemoves[$membership_group_id][] = $dao->contact_id; $stats[$listID]['removed']++; } // Log group contacts which are going to be added to CiviCRM CRM_Core_Error::debug_var('Mailchimp $groupContact= ', $groupContact); // FIXME: dirty hack setting a variable in session to skip post hook require_once 'CRM/Core/Session.php'; $session = CRM_Core_Session::singleton(); $session->set('skipPostHook', 'yes'); if ($groupContact) { // We have some contacts to add into groups... foreach ($groupContact as $groupID => $contactIDs) { CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIDs, $groupID, 'Admin', 'Added'); } } // Log group contacts which are going to be removed from CiviCRM CRM_Core_Error::debug_var('Mailchimp $groupContactRemoves= ', $groupContactRemoves); if ($groupContactRemoves) { // We have some contacts to add into groups... foreach ($groupContactRemoves as $groupID => $contactIDs) { CRM_Contact_BAO_GroupContact::removeContactsFromGroup($contactIDs, $groupID, 'Admin', 'Removed'); } } // FIXME: unset variable in session $session->set('skipPostHook', ''); static::updatePullStats($stats); // Finally, finish up by removing the two temporary tables CRM_Core_DAO::executeQuery("DROP TABLE tmp_mailchimp_push_m;"); CRM_Core_DAO::executeQuery("DROP TABLE tmp_mailchimp_push_c;"); return CRM_Queue_Task::TASK_SUCCESS; }