CRM-13422 - Consolidate extra rules for contact reminders
[civicrm-core.git] / CRM / Core / BAO / ActionSchedule.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
7cceb474
TO
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
6a488035
TO
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
006389de 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
e7112fa7 31 * @copyright CiviCRM LLC (c) 2004-2015
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * This class contains functions for managing Scheduled Reminders
38 */
39class CRM_Core_BAO_ActionSchedule extends CRM_Core_DAO_ActionSchedule {
40
b5c2afd0 41 /**
50a23755 42 * @param array $filters
9e1bf145 43 * Filter by property (e.g. 'id').
b5c2afd0 44 * @return array
50a23755 45 * Array(scalar $id => Mapping $mapping).
b5c2afd0 46 */
50a23755 47 public static function getMappings($filters = NULL) {
6a488035
TO
48 static $_action_mapping;
49
50a23755 50 if ($_action_mapping === NULL) {
9c8748cc
TO
51 $event = \Civi\Core\Container::singleton()->get('dispatcher')
52 ->dispatch(\Civi\ActionSchedule\Events::MAPPINGS,
53 new \Civi\ActionSchedule\Event\MappingRegisterEvent());
54 $_action_mapping = $event->getMappings();
6a488035
TO
55 }
56
9e1bf145 57 if (empty($filters)) {
50a23755 58 return $_action_mapping;
6a488035 59 }
9e1bf145
TO
60 elseif (isset($filters['id'])) {
61 return array(
62 $filters['id'] => $_action_mapping[$filters['id']],
63 );
64 }
65 else {
66 throw new CRM_Core_Exception("getMappings() called with unsupported filter: " . implode(', ', array_keys($filters)));
8d657dde 67 }
8d657dde
AH
68 }
69
7f0141d8
TO
70 /**
71 * @param string|int $id
72 * @return \Civi\ActionSchedule\Mapping|NULL
73 */
74 public static function getMapping($id) {
75 $mappings = self::getMappings();
76 return isset($mappings[$id]) ? $mappings[$id] : NULL;
77 }
78
6a488035
TO
79 /**
80 * Retrieve list of selections/drop downs for Scheduled Reminder form
81 *
6a0b768e
TO
82 * @param bool $id
83 * Mapping id.
6a488035 84 *
a6c01b45
CW
85 * @return array
86 * associated array of all the drop downs in the form
6a488035 87 */
00be9182 88 public static function getSelection($id = NULL) {
50a23755 89 $mappings = CRM_Core_BAO_ActionSchedule::getMappings();
d3600e68 90 $selectedMapping = $mappings[$id ? $id : 1];
6a488035 91
d3600e68 92 $entityValueLabels = array();
50a23755
TO
93 foreach ($mappings as $mapping) {
94 /** @var \Civi\ActionSchedule\Mapping $mapping */
d3600e68 95 $entityValueLabels[$mapping->getId()] = $mapping->getValueLabels();
018d5e02
TO
96 $valueLabel = array('- ' . strtolower($mapping->getValueHeader()) . ' -');
97 $entityValueLabels[$mapping->getId()] = $valueLabel + $entityValueLabels[$mapping->getId()];
d3600e68 98 }
6a488035 99
d3600e68
TO
100 $entityStatusLabels = array();
101 foreach ($mappings as $mapping) {
102 /** @var \Civi\ActionSchedule\Mapping $mapping */
9e1bf145
TO
103 $statusLabel = array('- ' . strtolower($mapping->getStatusHeader()) . ' -');
104 $entityStatusLabels[$mapping->getId()] = $entityValueLabels[$mapping->getId()];
105 foreach ($entityStatusLabels[$mapping->getId()] as $kkey => & $vval) {
50a23755 106 $vval = $statusLabel + $mapping->getStatusLabels($kkey);
6a488035
TO
107 }
108 }
50a23755 109
d3600e68 110 $entityRecipientLabels = $selectedMapping->getRecipientTypes() + self::getAdditionalRecipients();
9e1bf145 111
6a488035 112 return array(
d3600e68 113 'sel1' => CRM_Utils_Array::collectMethod('getLabel', $mappings),
50a23755
TO
114 'sel2' => $entityValueLabels,
115 'sel3' => $entityStatusLabels,
d3600e68 116 'sel4' => $selectedMapping->getDateFields(),
50a23755 117 'sel5' => $entityRecipientLabels,
d3600e68
TO
118 'entityMapping' => CRM_Utils_Array::collectMethod('getEntity', $mappings),
119 'recipientMapping' => array_combine(array_keys($entityRecipientLabels), array_keys($entityRecipientLabels)),
6a488035
TO
120 );
121 }
122
b5c2afd0 123 /**
50a23755 124 * @param int $mappingId
dc3c81b1 125 * @param int $isLimit
b5c2afd0
EM
126 *
127 * @return array
128 */
50a23755
TO
129 public static function getSelection1($mappingId = NULL, $isLimit = NULL) {
130 $mappings = CRM_Core_BAO_ActionSchedule::getMappings(array(
131 'id' => $mappingId,
132 ));
133 $dateFieldLabels = $entityRecipientLabels = array();
6a488035 134
50a23755
TO
135 foreach ($mappings as $mapping) {
136 /** @var \Civi\ActionSchedule\Mapping $mapping */
137 $dateFieldLabels = $mapping->getDateFields();
673c1c81 138 $entityRecipientLabels = $mapping->getRecipientTypes(!$isLimit) + self::getAdditionalRecipients();
6a488035
TO
139 }
140
141 return array(
50a23755
TO
142 'sel4' => $dateFieldLabels,
143 'sel5' => $entityRecipientLabels,
144 'recipientMapping' => array_combine(array_keys($entityRecipientLabels), array_keys($entityRecipientLabels)),
6a488035
TO
145 );
146 }
147
148 /**
fe482240 149 * Retrieve list of Scheduled Reminders.
6a488035 150 *
6a0b768e
TO
151 * @param bool $namesOnly
152 * Return simple list of names.
da6b46f4 153 *
77e16391
TO
154 * @param \Civi\ActionSchedule\Mapping|NULL $filterMapping
155 * Filter by the schedule's mapping type.
156 * @param int $filterValue
157 * Filter by the schedule's entity_value.
6a488035 158 *
a6c01b45
CW
159 * @return array
160 * (reference) reminder list
6a488035 161 */
77e16391 162 public static function &getList($namesOnly = FALSE, $filterMapping = NULL, $filterValue = NULL) {
6a488035
TO
163 $query = "
164SELECT
165 title,
6a488035 166 cas.id as id,
50a23755 167 cas.mapping_id,
6a488035 168 cas.entity_value as entityValueIds,
6a488035
TO
169 cas.entity_status as entityStatusIds,
170 cas.start_action_date as entityDate,
171 cas.start_action_offset,
172 cas.start_action_unit,
173 cas.start_action_condition,
174 cas.absolute_date,
175 is_repeat,
176 is_active
177
178FROM civicrm_action_schedule cas
6a488035 179";
50a23755 180 $queryParams = array();
62933949 181 $where = " WHERE 1 ";
77e16391
TO
182 if ($filterMapping and $filterValue) {
183 $where .= " AND cas.entity_value = %1 AND cas.mapping_id = %2";
184 $queryParams[1] = array($filterValue, 'Integer');
4d5ef3de 185 $queryParams[2] = array($filterMapping->getId(), 'String');
6a488035 186 }
62933949 187 $where .= " AND cas.used_for IS NULL";
188 $query .= $where;
50a23755 189 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
6a488035 190 while ($dao->fetch()) {
77e16391
TO
191 /** @var Civi\ActionSchedule\Mapping $filterMapping */
192 $filterMapping = CRM_Utils_Array::first(self::getMappings(array(
50a23755
TO
193 'id' => $dao->mapping_id,
194 )));
6a488035
TO
195 $list[$dao->id]['id'] = $dao->id;
196 $list[$dao->id]['title'] = $dao->title;
197 $list[$dao->id]['start_action_offset'] = $dao->start_action_offset;
198 $list[$dao->id]['start_action_unit'] = $dao->start_action_unit;
199 $list[$dao->id]['start_action_condition'] = $dao->start_action_condition;
200 $list[$dao->id]['entityDate'] = ucwords(str_replace('_', ' ', $dao->entityDate));
201 $list[$dao->id]['absolute_date'] = $dao->absolute_date;
9e1bf145 202 $list[$dao->id]['entity'] = $filterMapping->getLabel();
50a23755 203 $list[$dao->id]['value'] = implode(', ', CRM_Utils_Array::subset(
77e16391 204 $filterMapping->getValueLabels(),
50a23755
TO
205 explode(CRM_Core_DAO::VALUE_SEPARATOR, $dao->entityValueIds)
206 ));
207 $list[$dao->id]['status'] = implode(', ', CRM_Utils_Array::subset(
77e16391 208 $filterMapping->getStatusLabels($dao->entityValueIds),
50a23755
TO
209 explode(CRM_Core_DAO::VALUE_SEPARATOR, $dao->entityStatusIds)
210 ));
6a488035
TO
211 $list[$dao->id]['is_repeat'] = $dao->is_repeat;
212 $list[$dao->id]['is_active'] = $dao->is_active;
213 }
214
215 return $list;
216 }
217
6a488035 218 /**
fe482240 219 * Add the schedules reminders in the db.
6a488035 220 *
6a0b768e
TO
221 * @param array $params
222 * (reference ) an assoc array of name/value pairs.
223 * @param array $ids
244bbdd8 224 * Unused variable.
6a488035 225 *
c490a46a 226 * @return CRM_Core_DAO_ActionSchedule
6a488035 227 */
00be9182 228 public static function add(&$params, $ids = array()) {
6a488035
TO
229 $actionSchedule = new CRM_Core_DAO_ActionSchedule();
230 $actionSchedule->copyValues($params);
231
232 return $actionSchedule->save();
233 }
234
235 /**
fe482240
EM
236 * Retrieve DB object based on input parameters.
237 *
238 * It also stores all the retrieved values in the default array.
6a488035 239 *
6a0b768e
TO
240 * @param array $params
241 * (reference ) an assoc array of name/value pairs.
242 * @param array $values
243 * (reference ) an assoc array to hold the flattened values.
6a488035 244 *
16b10e64
CW
245 * @return CRM_Core_DAO_ActionSchedule|null
246 * object on success, null otherwise
6a488035 247 */
00be9182 248 public static function retrieve(&$params, &$values) {
6a488035
TO
249 if (empty($params)) {
250 return NULL;
251 }
252 $actionSchedule = new CRM_Core_DAO_ActionSchedule();
253
254 $actionSchedule->copyValues($params);
255
256 if ($actionSchedule->find(TRUE)) {
257 $ids['actionSchedule'] = $actionSchedule->id;
258
259 CRM_Core_DAO::storeValues($actionSchedule, $values);
260
261 return $actionSchedule;
262 }
263 return NULL;
264 }
265
266 /**
fe482240 267 * Delete a Reminder.
6a488035 268 *
6a0b768e
TO
269 * @param int $id
270 * ID of the Reminder to be deleted.
6a488035 271 *
6a488035 272 */
00be9182 273 public static function del($id) {
6a488035
TO
274 if ($id) {
275 $dao = new CRM_Core_DAO_ActionSchedule();
276 $dao->id = $id;
277 if ($dao->find(TRUE)) {
278 $dao->delete();
279 return;
280 }
281 }
282 CRM_Core_Error::fatal(ts('Invalid value passed to delete function.'));
283 }
284
285 /**
fe482240 286 * Update the is_active flag in the db.
6a488035 287 *
6a0b768e
TO
288 * @param int $id
289 * Id of the database record.
290 * @param bool $is_active
291 * Value we want to set the is_active field.
6a488035 292 *
a6c01b45
CW
293 * @return Object
294 * DAO object on success, null otherwise
6a488035 295 */
00be9182 296 public static function setIsActive($id, $is_active) {
6a488035
TO
297 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_ActionSchedule', $id, 'is_active', $is_active);
298 }
299
b5c2afd0 300 /**
100fef9d 301 * @param int $mappingID
b5c2afd0
EM
302 * @param $now
303 *
304 * @throws CRM_Core_Exception
305 */
00be9182 306 public static function sendMailings($mappingID, $now) {
50a23755
TO
307 $mapping = CRM_Utils_Array::first(self::getMappings(array(
308 'id' => $mappingID,
309 )));
6a488035
TO
310
311 $actionSchedule = new CRM_Core_DAO_ActionSchedule();
312 $actionSchedule->mapping_id = $mappingID;
313 $actionSchedule->is_active = 1;
314 $actionSchedule->find(FALSE);
315
6a488035 316 while ($actionSchedule->fetch()) {
5b16d8b6 317 $query = CRM_Core_BAO_ActionSchedule::prepareMailingQuery($mapping, $actionSchedule);
6a488035 318 $dao = CRM_Core_DAO::executeQuery($query,
3e315abc 319 array(1 => array($actionSchedule->id, 'Integer'))
6a488035
TO
320 );
321
07844ccf 322 $multilingual = CRM_Core_I18n::isMultilingual();
6a488035 323 while ($dao->fetch()) {
07844ccf
SV
324 // switch language if necessary
325 if ($multilingual) {
c72ba2be 326 $preferred_language = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $dao->contactID, 'preferred_language');
07844ccf
SV
327 CRM_Core_BAO_ActionSchedule::setCommunicationLanguage($actionSchedule->communication_language, $preferred_language);
328 }
329
d22bcd5b
TO
330 $errors = array();
331 try {
50a23755 332 $tokenProcessor = self::createTokenProcessor($actionSchedule, $mapping);
d22bcd5b
TO
333 $tokenProcessor->addRow()
334 ->context('contactId', $dao->contactID)
50a23755 335 ->context('actionSearchResult', (object) $dao->toArray());
d22bcd5b
TO
336 foreach ($tokenProcessor->evaluate()->getRows() as $tokenRow) {
337 if ($actionSchedule->mode == 'SMS' or $actionSchedule->mode == 'User_Preference') {
338 CRM_Utils_Array::extend($errors, self::sendReminderSms($tokenRow, $actionSchedule, $dao->contactID));
43ceab3f 339 }
6a488035 340
d22bcd5b
TO
341 if ($actionSchedule->mode == 'Email' or $actionSchedule->mode == 'User_Preference') {
342 CRM_Utils_Array::extend($errors, self::sendReminderEmail($tokenRow, $actionSchedule, $dao->contactID));
43ceab3f
TO
343 }
344 }
6a488035 345 }
d22bcd5b
TO
346 catch (\Civi\Token\TokenException $e) {
347 $errors['token_exception'] = $e->getMessage();
6a488035
TO
348 }
349
350 // update action log record
351 $logParams = array(
352 'id' => $dao->reminderID,
d22bcd5b
TO
353 'is_error' => !empty($errors),
354 'message' => empty($errors) ? "null" : implode(' ', $errors),
6a488035
TO
355 'action_date_time' => $now,
356 );
357 CRM_Core_BAO_ActionLog::create($logParams);
358
359 // insert activity log record if needed
d22bcd5b 360 if ($actionSchedule->record_activity && empty($errors)) {
c72ba2be 361 $caseID = empty($dao->case_id) ? NULL : $dao->case_id;
5b16d8b6 362 CRM_Core_BAO_ActionSchedule::createMailingActivity($actionSchedule, $mapping, $dao->contactID, $dao->entityID, $caseID);
6a488035
TO
363 }
364 }
365
366 $dao->free();
367 }
368 }
369
b5c2afd0 370 /**
100fef9d 371 * @param int $mappingID
b5c2afd0
EM
372 * @param $now
373 * @param array $params
374 *
375 * @throws API_Exception
376 */
00be9182 377 public static function buildRecipientContacts($mappingID, $now, $params = array()) {
6a488035
TO
378 $actionSchedule = new CRM_Core_DAO_ActionSchedule();
379 $actionSchedule->mapping_id = $mappingID;
380 $actionSchedule->is_active = 1;
22e263ad 381 if (!empty($params)) {
244bbdd8 382 _civicrm_api3_dao_set_filter($actionSchedule, $params, FALSE);
73f3e293 383 }
6a488035
TO
384 $actionSchedule->find();
385
386 while ($actionSchedule->fetch()) {
77e16391 387 /** @var \Civi\ActionSchedule\Mapping $mapping */
50a23755
TO
388 $mapping = CRM_Utils_Array::first(self::getMappings(array(
389 'id' => $mappingID,
390 )));
c09bacfd
TO
391 $builder = new \Civi\ActionSchedule\RecipientBuilder($now, $actionSchedule, $mapping);
392 $builder->build();
6a488035
TO
393 }
394 }
395
b5c2afd0
EM
396 /**
397 * @param null $now
398 * @param array $params
399 *
400 * @return array
401 */
00be9182 402 public static function processQueue($now = NULL, $params = array()) {
6a488035
TO
403 $now = $now ? CRM_Utils_Time::setTime($now) : CRM_Utils_Time::getTime();
404
50a23755 405 $mappings = CRM_Core_BAO_ActionSchedule::getMappings();
6a488035 406 foreach ($mappings as $mappingID => $mapping) {
5b16d8b6
TO
407 CRM_Core_BAO_ActionSchedule::buildRecipientContacts($mappingID, $now, $params);
408 CRM_Core_BAO_ActionSchedule::sendMailings($mappingID, $now);
6a488035
TO
409 }
410
411 $result = array(
412 'is_error' => 0,
413 'messages' => ts('Sent all scheduled reminders successfully'),
414 );
415 return $result;
416 }
417
9a4df24c 418 /**
100fef9d
CW
419 * @param int $id
420 * @param int $mappingID
9a4df24c
EM
421 *
422 * @return null|string
423 */
00be9182 424 public static function isConfigured($id, $mappingID) {
6a488035
TO
425 $queryString = "SELECT count(id) FROM civicrm_action_schedule
426 WHERE mapping_id = %1 AND
427 entity_value = %2";
428
3e315abc 429 $params = array(
4d5ef3de 430 1 => array($mappingID, 'String'),
3e315abc 431 2 => array($id, 'Integer'),
6a488035
TO
432 );
433 return CRM_Core_DAO::singleValueQuery($queryString, $params);
434 }
435
b5c2afd0 436 /**
100fef9d 437 * @param int $mappingID
b5c2afd0
EM
438 * @param $recipientType
439 *
440 * @return array
441 */
00be9182 442 public static function getRecipientListing($mappingID, $recipientType) {
77e16391
TO
443 if (!$mappingID) {
444 return array();
6a488035
TO
445 }
446
77e16391 447 /** @var \Civi\ActionSchedule\Mapping $mapping */
50a23755
TO
448 $mapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array(
449 'id' => $mappingID,
450 )));
77e16391 451 return $mapping->getRecipientListing($recipientType);
6a488035 452 }
96025800 453
07844ccf
SV
454 /**
455 * @param $communication_language
456 * @param $preferred_language
457 */
458 public static function setCommunicationLanguage($communication_language, $preferred_language) {
459 $config = CRM_Core_Config::singleton();
460 $language = $config->lcMessages;
fadd4d37 461
07844ccf
SV
462 // prepare the language for the email
463 if ($communication_language == CRM_Core_I18n::AUTO) {
464 if (!empty($preferred_language)) {
465 $language = $preferred_language;
466 }
467 }
468 else {
469 $language = $communication_language;
470 }
471
472 // language not in the existing language, use default
273f9849
SV
473 $languages = CRM_Core_I18n::languages(TRUE);
474 if (!in_array($language, $languages)) {
07844ccf
SV
475 $language = $config->lcMessages;
476 }
477
478 // change the language
479 $i18n = CRM_Core_I18n::singleton();
480 $i18n->setLanguage($language);
481 }
482
c72ba2be
TO
483 /**
484 * Save a record about the delivery of a reminder email.
485 *
486 * WISHLIST: Instead of saving $actionSchedule->body_html, call this immediately after
487 * sending the message and pass in the fully rendered text of the message.
488 *
489 * @param CRM_Core_DAO_ActionSchedule $actionSchedule
50a23755 490 * @param Civi\ActionSchedule\Mapping $mapping
c72ba2be
TO
491 * @param int $contactID
492 * @param int $entityID
493 * @param int|NULL $caseID
494 * @throws CRM_Core_Exception
495 */
496 protected static function createMailingActivity($actionSchedule, $mapping, $contactID, $entityID, $caseID) {
497 $session = CRM_Core_Session::singleton();
498
9e1bf145 499 if ($mapping->getEntity() == 'civicrm_membership') {
c72ba2be
TO
500 $activityTypeID
501 = CRM_Core_OptionGroup::getValue('activity_type', 'Membership Renewal Reminder', 'name');
502 }
503 else {
504 $activityTypeID
505 = CRM_Core_OptionGroup::getValue('activity_type', 'Reminder Sent', 'name');
506 }
507
508 $activityParams = array(
509 'subject' => $actionSchedule->title,
510 'details' => $actionSchedule->body_html,
511 'source_contact_id' => $session->get('userID') ? $session->get('userID') : $contactID,
512 'target_contact_id' => $contactID,
513 'activity_date_time' => CRM_Utils_Time::getTime('YmdHis'),
514 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name'),
515 'activity_type_id' => $activityTypeID,
516 'source_record_id' => $entityID,
517 );
518 $activity = CRM_Activity_BAO_Activity::create($activityParams);
519
520 //file reminder on case if source activity is a case activity
521 if (!empty($caseID)) {
522 $caseActivityParams = array();
523 $caseActivityParams['case_id'] = $caseID;
524 $caseActivityParams['activity_id'] = $activity->id;
525 CRM_Case_BAO_Case::processCaseActivity($caseActivityParams);
526 }
527 }
528
c72ba2be 529 /**
f9ec2da6
TO
530 * @param \Civi\ActionSchedule\MappingInterface $mapping
531 * @param \CRM_Core_DAO_ActionSchedule $actionSchedule
c72ba2be
TO
532 * @return string
533 */
534 protected static function prepareMailingQuery($mapping, $actionSchedule) {
f9ec2da6
TO
535 $select = CRM_Utils_SQL_Select::from('civicrm_action_log reminder')
536 ->select("reminder.id as reminderID, reminder.contact_id as contactID, reminder.entity_table as entityTable, reminder.*, e.id AS entityID")
537 ->join('e', "!casMailingJoinType !casMappingEntity e ON !casEntityJoinExpr")
538 ->select("e.id as entityID, e.*")
539 ->where("reminder.action_schedule_id = #casActionScheduleId")
540 ->where("reminder.action_date_time IS NULL")
541 ->param(array(
542 'casActionScheduleId' => $actionSchedule->id,
543 'casMailingJoinType' => ($actionSchedule->limit_to == 0) ? 'LEFT JOIN' : 'INNER JOIN',
544 'casMappingId' => $mapping->getId(),
545 'casMappingEntity' => $mapping->getEntity(),
546 'casEntityJoinExpr' => 'e.id = reminder.entity_id',
547 ));
a1466c59
TO
548
549 if ($actionSchedule->limit_to == 0) {
a1466c59
TO
550 $select->where("e.id = reminder.entity_id OR reminder.entity_table = 'civicrm_contact'");
551 }
c72ba2be 552
f9ec2da6
TO
553 \Civi\Core\Container::singleton()->get('dispatcher')
554 ->dispatch(
555 \Civi\ActionSchedule\Events::MAILING_QUERY,
556 new \Civi\ActionSchedule\Event\MailingQueryEvent($actionSchedule, $mapping, $select)
557 );
c72ba2be 558
a1466c59 559 return $select->toSQL();
c72ba2be
TO
560 }
561
43ceab3f 562 /**
09c2328a 563 * @param \Civi\Token\TokenRow $tokenRow
d22bcd5b
TO
564 * @param CRM_Core_DAO_ActionSchedule $schedule
565 * @param int $toContactID
43ceab3f 566 * @throws CRM_Core_Exception
d22bcd5b
TO
567 * @return array
568 * List of error messages.
43ceab3f 569 */
d22bcd5b
TO
570 protected static function sendReminderSms($tokenRow, $schedule, $toContactID) {
571 $toPhoneNumber = self::pickSmsPhoneNumber($toContactID);
572 if (!$toPhoneNumber) {
573 return array("sms_phone_missing" => "Couldn't find recipient's phone number.");
574 }
575
43ceab3f
TO
576 $messageSubject = $tokenRow->render('subject');
577 $sms_body_text = $tokenRow->render('sms_body_text');
578
579 $session = CRM_Core_Session::singleton();
580 $userID = $session->get('userID') ? $session->get('userID') : $tokenRow->context['contactId'];
581 $smsParams = array(
582 'To' => $toPhoneNumber,
583 'provider_id' => $schedule->sms_provider_id,
584 'activity_subject' => $messageSubject,
585 );
586 $activityTypeID = CRM_Core_OptionGroup::getValue('activity_type',
587 'SMS',
588 'name'
589 );
590 $activityParams = array(
591 'source_contact_id' => $userID,
592 'activity_type_id' => $activityTypeID,
593 'activity_date_time' => date('YmdHis'),
594 'subject' => $messageSubject,
595 'details' => $sms_body_text,
596 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name'),
597 );
598
599 $activity = CRM_Activity_BAO_Activity::create($activityParams);
600
601 CRM_Activity_BAO_Activity::sendSMSMessage($tokenRow->context['contactId'],
602 $sms_body_text,
603 $smsParams,
604 $activity->id,
605 $userID
606 );
d22bcd5b
TO
607
608 return array();
43ceab3f
TO
609 }
610
611 /**
612 * @param CRM_Core_DAO_ActionSchedule $actionSchedule
613 * @return string
614 * Ex: "Alice <alice@example.org>".
615 */
616 protected static function pickFromEmail($actionSchedule) {
617 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
618 $fromEmailAddress = "$domainValues[0] <$domainValues[1]>";
619 if ($actionSchedule->from_email) {
620 $fromEmailAddress = "$actionSchedule->from_name <$actionSchedule->from_email>";
621 return $fromEmailAddress;
622 }
623 return $fromEmailAddress;
624 }
625
626 /**
09c2328a 627 * @param \Civi\Token\TokenRow $tokenRow
d22bcd5b
TO
628 * @param CRM_Core_DAO_ActionSchedule $schedule
629 * @param int $toContactID
630 * @return array
631 * List of error messages.
43ceab3f 632 */
d22bcd5b
TO
633 protected static function sendReminderEmail($tokenRow, $schedule, $toContactID) {
634 $toEmail = CRM_Contact_BAO_Contact::getPrimaryEmail($toContactID);
635 if (!$toEmail) {
636 return array("email_missing" => "Couldn't find recipient's email address.");
637 }
638
43ceab3f
TO
639 $body_text = $tokenRow->render('body_text');
640 $body_html = $tokenRow->render('body_html');
641 if (!$schedule->body_text) {
642 $body_text = CRM_Utils_String::htmlToText($body_html);
643 }
644
645 // set up the parameters for CRM_Utils_Mail::send
646 $mailParams = array(
647 'groupName' => 'Scheduled Reminder Sender',
648 'from' => self::pickFromEmail($schedule),
649 'toName' => $tokenRow->context['contact']['display_name'],
650 'toEmail' => $toEmail,
651 'subject' => $tokenRow->render('subject'),
652 'entity' => 'action_schedule',
653 'entity_id' => $schedule->id,
654 );
655
656 if (!$body_html || $tokenRow->context['contact']['preferred_mail_format'] == 'Text' ||
657 $tokenRow->context['contact']['preferred_mail_format'] == 'Both'
658 ) {
659 // render the &amp; entities in text mode, so that the links work
660 $mailParams['text'] = str_replace('&amp;', '&', $body_text);
661 }
662 if ($body_html && ($tokenRow->context['contact']['preferred_mail_format'] == 'HTML' ||
663 $tokenRow->context['contact']['preferred_mail_format'] == 'Both'
664 )
665 ) {
666 $mailParams['html'] = $body_html;
667 }
668 $result = CRM_Utils_Mail::send($mailParams);
d22bcd5b
TO
669 if (!$result || is_a($result, 'PEAR_Error')) {
670 return array('email_fail' => 'Failed to send message');
671 }
672
673 return array();
43ceab3f
TO
674 }
675
676 /**
677 * @param CRM_Core_DAO_ActionSchedule $schedule
50a23755 678 * @param \Civi\ActionSchedule\Mapping $mapping
43ceab3f
TO
679 * @return \Civi\Token\TokenProcessor
680 */
50a23755 681 protected static function createTokenProcessor($schedule, $mapping) {
43ceab3f
TO
682 $tp = new \Civi\Token\TokenProcessor(\Civi\Core\Container::singleton()->get('dispatcher'), array(
683 'controller' => __CLASS__,
684 'actionSchedule' => $schedule,
50a23755 685 'actionMapping' => $mapping,
43ceab3f
TO
686 'smarty' => TRUE,
687 ));
688 $tp->addMessage('body_text', $schedule->body_text, 'text/plain');
689 $tp->addMessage('body_html', $schedule->body_html, 'text/html');
690 $tp->addMessage('sms_body_text', $schedule->sms_body_text, 'text/plain');
691 $tp->addMessage('subject', $schedule->subject, 'text/plain');
692 return $tp;
693 }
694
d22bcd5b
TO
695 /**
696 * @param $dao
697 * @return string|NULL
698 */
699 protected static function pickSmsPhoneNumber($smsToContactId) {
700 $toPhoneNumbers = CRM_Core_BAO_Phone::allPhones($smsToContactId, FALSE, 'Mobile', array(
701 'is_deceased' => 0,
702 'is_deleted' => 0,
703 'do_not_sms' => 0,
704 ));
705 //to get primary mobile ph,if not get a first mobile phONE
706 if (!empty($toPhoneNumbers)) {
707 $toPhoneNumberDetails = reset($toPhoneNumbers);
708 $toPhoneNumber = CRM_Utils_Array::value('phone', $toPhoneNumberDetails);
709 return $toPhoneNumber;
710 }
711 return NULL;
712 }
713
673c1c81
TO
714 /**
715 * Get the list of generic recipient types supported by all entities/mappings.
716 *
717 * @return array
718 * array(mixed $value => string $label).
719 */
720 protected static function getAdditionalRecipients() {
721 return array(
722 'manual' => ts('Choose Recipient(s)'),
723 'group' => ts('Select Group'),
724 );
725 }
726
6a488035 727}