3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 require_once 'Mail/mime.php';
40 * Class CRM_Mailing_Event_BAO_Subscribe
42 class CRM_Mailing_Event_BAO_Subscribe
extends CRM_Mailing_Event_DAO_Subscribe
{
47 function __construct() {
48 parent
::__construct();
52 * Register a subscription event. Create a new contact if one does not
55 * @param int $group_id The group id to subscribe to
56 * @param string $email The email address of the (new) contact
57 * @param int $contactId Currently used during event registration/contribution.
58 * Specifically to avoid linking group to wrong duplicate contact
59 * during event registration.
60 * @param string $context
62 * @return int|null $se_id The id of the subscription event, null on failure
66 public static function &subscribe($group_id, $email, $contactId = NULL, $context = NULL) {
67 // CRM-1797 - allow subscription only to public groups
68 $params = array('id' => (int) $group_id);
73 $bao = CRM_Contact_BAO_Group
::retrieve($params, $defaults);
74 if ($bao && substr($bao->visibility
, 0, 6) != 'Public' && $context != 'profile') {
78 $strtolower = function_exists('mb_strtolower') ?
'mb_strtolower' : 'strtolower';
79 $email = $strtolower($email);
81 // process the query only if no contactId
83 $contact_id = $contactId;
86 /* First, find out if the contact already exists */
89 SELECT DISTINCT contact_a.id as contact_id
90 FROM civicrm_contact contact_a
91 LEFT JOIN civicrm_email ON contact_a.id = civicrm_email.contact_id
92 WHERE civicrm_email.email = %1 AND contact_a.is_deleted = 0";
94 $params = array(1 => array($email, 'String'));
95 $dao = CRM_Core_DAO
::executeQuery($query, $params);
97 // lets just use the first contact id we got
99 $contact_id = $dao->contact_id
;
104 $transaction = new CRM_Core_Transaction();
107 require_once 'CRM/Utils/DeprecatedUtils.php';
109 /* If the contact does not exist, create one. */
112 'contact_type' => 'Individual',
115 $locationType = CRM_Core_BAO_LocationType
::getDefault();
118 'location_type_id' => $locationType->id
,
120 _civicrm_api3_deprecated_add_formatted_param($value, $formatted);
122 $formatted['onDuplicate'] = CRM_Import_Parser
::DUPLICATE_SKIP
;
123 $formatted['fixAddress'] = TRUE;
124 require_once 'api/api.php';
125 $contact = civicrm_api('contact', 'create', $formatted);
126 if (civicrm_error($contact)) {
129 $contact_id = $contact['id'];
131 elseif (!is_numeric($contact_id) &&
132 (int ) $contact_id > 0
134 // make sure contact_id is numeric
139 /* Get the primary email id from the contact to use as a hash input */
141 $dao = new CRM_Core_DAO();
144 SELECT civicrm_email.id as email_id
146 WHERE civicrm_email.email = %1
147 AND civicrm_email.contact_id = %2";
148 $params = array(1 => array($email, 'String'),
149 2 => array($contact_id, 'Integer'),
151 $dao = CRM_Core_DAO
::executeQuery($query, $params);
153 if (!$dao->fetch()) {
154 CRM_Core_Error
::fatal('Please file an issue with the backtrace');
158 $se = new CRM_Mailing_Event_BAO_Subscribe();
159 $se->group_id
= $group_id;
160 $se->contact_id
= $contact_id;
161 $se->time_stamp
= date('YmdHis');
162 $se->hash
= substr(sha1("{$group_id}:{$contact_id}:{$dao->email_id}:" . time()),
167 $contacts = array($contact_id);
168 CRM_Contact_BAO_GroupContact
::addContactsToGroup($contacts, $group_id,
169 'Email', 'Pending', $se->id
172 $transaction->commit();
177 * Verify the hash of a subscription event
179 * @param int $contact_id ID of the contact
180 * @param int $subscribe_id ID of the subscription event
181 * @param string $hash Hash to verify
183 * @return object|null The subscribe event object, or null on failure
187 public static function &verify($contact_id, $subscribe_id, $hash) {
189 $se = new CRM_Mailing_Event_BAO_Subscribe();
190 $se->contact_id
= $contact_id;
191 $se->id
= $subscribe_id;
193 if ($se->find(TRUE)) {
200 * Ask a contact for subscription confirmation (opt-in)
202 * @param string $email The email address
207 public function send_confirm_request($email) {
208 $config = CRM_Core_Config
::singleton();
210 $domain = CRM_Core_BAO_Domain
::getDomain();
212 //get the default domain email address.
213 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
215 $localpart = CRM_Core_BAO_MailSettings
::defaultLocalpart();
216 $emailDomain = CRM_Core_BAO_MailSettings
::defaultDomain();
218 $confirm = implode($config->verpSeparator
,
227 $group = new CRM_Contact_BAO_Group();
228 $group->id
= $this->group_id
;
231 $component = new CRM_Mailing_BAO_Component();
232 $component->is_default
= 1;
233 $component->is_active
= 1;
234 $component->component_type
= 'Subscribe';
236 $component->find(TRUE);
239 'Subject' => $component->subject
,
240 'From' => "\"{$domainEmailName}\" <{$domainEmailAddress}>",
242 'Reply-To' => $confirm,
243 'Return-Path' => "do-not-reply@$emailDomain",
246 $url = CRM_Utils_System
::url('civicrm/mailing/confirm',
247 "reset=1&cid={$this->contact_id}&sid={$this->id}&h={$this->hash}",
251 $html = $component->body_html
;
253 if ($component->body_text
) {
254 $text = $component->body_text
;
257 $text = CRM_Utils_String
::htmlToText($component->body_html
);
260 $bao = new CRM_Mailing_BAO_Mailing();
261 $bao->body_text
= $text;
262 $bao->body_html
= $html;
263 $tokens = $bao->getTokens();
265 $html = CRM_Utils_Token
::replaceDomainTokens($html, $domain, TRUE, $tokens['html']);
266 $html = CRM_Utils_Token
::replaceSubscribeTokens($html,
271 $text = CRM_Utils_Token
::replaceDomainTokens($text, $domain, FALSE, $tokens['text']);
272 $text = CRM_Utils_Token
::replaceSubscribeTokens($text,
276 // render the & entities in text mode, so that the links work
277 $text = str_replace('&', '&', $text);
279 $message = new Mail_mime("\n");
281 $message->setHTMLBody($html);
282 $message->setTxtBody($text);
283 $b = CRM_Utils_Mail
::setMimeParams($message);
284 $h = $message->headers($headers);
285 CRM_Mailing_BAO_Mailing
::addMessageIdHeader($h, 's',
290 $mailer = $config->getMailer();
292 if (is_object($mailer)) {
293 $errorScope = CRM_Core_TemporaryErrorScope
::ignoreException();
294 $mailer->send($email, $h, $b);
300 * Get the domain object given a subscribe event
302 * @param int $subscribe_id ID of the subscribe event
304 * @return object $domain The domain owning the event
308 public static function &getDomain($subscribe_id) {
309 return CRM_Core_BAO_Domain
::getDomain();
313 * Get the group details to which given email belongs
315 * @param string $email email of the contact
316 * @param int $contactID contactID if we want an exact match
318 * @return array $groups array of group ids
321 public static function getContactGroups($email, $contactID = NULL) {
324 SELECT DISTINCT group_a.group_id, group_a.status, civicrm_group.title
325 FROM civicrm_group_contact group_a
326 LEFT JOIN civicrm_group ON civicrm_group.id = group_a.group_id
327 LEFT JOIN civicrm_contact ON ( group_a.contact_id = civicrm_contact.id )
328 WHERE civicrm_contact.id = %1";
330 $params = array(1 => array($contactID, 'Integer'));
333 $strtolower = function_exists('mb_strtolower') ?
'mb_strtolower' : 'strtolower';
334 $email = $strtolower($email);
337 SELECT DISTINCT group_a.group_id, group_a.status, civicrm_group.title
338 FROM civicrm_group_contact group_a
339 LEFT JOIN civicrm_group ON civicrm_group.id = group_a.group_id
340 LEFT JOIN civicrm_contact ON ( group_a.contact_id = civicrm_contact.id ) AND civicrm_contact.is_deleted = 0
341 LEFT JOIN civicrm_email ON civicrm_contact.id = civicrm_email.contact_id
342 WHERE civicrm_email.email = %1";
344 $params = array(1 => array($email, 'String'));
347 $dao = CRM_Core_DAO
::executeQuery($query, $params);
349 while ($dao->fetch()) {
350 $groups[$dao->group_id
] = array(
351 'id' => $dao->group_id
,
352 'title' => $dao->title
,
353 'status' => $dao->status
,
362 * Send subscribe mail
364 * @param array $groups the list of group ids for subscribe
365 * @param array $params the list of email
366 * @param int $contactId Currently used during event registration/contribution.
367 * Specifically to avoid linking group to wrong duplicate contact
368 * during event registration.
369 * @param string $context
375 public static function commonSubscribe(&$groups, &$params, $contactId = NULL, $context = NULL) {
376 $contactGroups = CRM_Mailing_Event_BAO_Subscribe
::getContactGroups($params['email'], $contactId);
379 foreach ($groups as $groupID) {
380 $title = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupID, 'title');
381 if (array_key_exists($groupID, $contactGroups) && $contactGroups[$groupID]['status'] != 'Removed') {
382 $group[$groupID]['title'] = $contactGroups[$groupID]['title'];
384 $group[$groupID]['status'] = $contactGroups[$groupID]['status'];
385 $status = ts('You are already subscribed in %1, your subscription is %2.', array(1 => $group[$groupID]['title'], 2 => $group[$groupID]['status']));
386 CRM_Utils_System
::setUFMessage($status);
390 $se = self
::subscribe($groupID,
391 $params['email'], $contactId, $context
395 $groupAdded[] = $title;
397 // Ask the contact for confirmation
398 $se->send_confirm_request($params['email']);
402 $groupFailed[] = $title;
406 $groupTitle = implode(', ', $groupAdded);
407 CRM_Utils_System
::setUFMessage(ts('Your subscription request has been submitted for %1. Check your inbox shortly for the confirmation email(s). If you do not see a confirmation email, please check your spam/junk mail folder.', array(1 => $groupTitle)));
409 elseif ($success === FALSE) {
410 $groupTitle = implode(',', $groupFailed);
411 CRM_Utils_System
::setUFMessage(ts('We had a problem processing your subscription request for %1. You have tried to subscribe to a private group and/or we encountered a database error. Please contact the site administrator.', array(1 => $groupTitle)));