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