CRM-16355 - reminders in multilingual sites fix
[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) {
8ea23016
SV
428 $i18n = CRM_Core_I18n::singleton();
429
430 // FIXME: convert to getLocale when https://issues.civicrm.org/jira/browse/CRM-18362 is fixed
431 global $tsLocale;
432 $currentLocale = $tsLocale;
433 $language = $currentLocale;
fadd4d37 434
07844ccf
SV
435 // prepare the language for the email
436 if ($communication_language == CRM_Core_I18n::AUTO) {
437 if (!empty($preferred_language)) {
438 $language = $preferred_language;
439 }
440 }
441 else {
442 $language = $communication_language;
443 }
444
445 // language not in the existing language, use default
273f9849 446 $languages = CRM_Core_I18n::languages(TRUE);
8ea23016
SV
447 if (!array_key_exists($language, $languages)) {
448 $language = $currentLocale;
07844ccf
SV
449 }
450
451 // change the language
8ea23016 452 $i18n->setLocale($language);
07844ccf
SV
453 }
454
c72ba2be
TO
455 /**
456 * Save a record about the delivery of a reminder email.
457 *
458 * WISHLIST: Instead of saving $actionSchedule->body_html, call this immediately after
459 * sending the message and pass in the fully rendered text of the message.
460 *
461 * @param CRM_Core_DAO_ActionSchedule $actionSchedule
50a23755 462 * @param Civi\ActionSchedule\Mapping $mapping
c72ba2be
TO
463 * @param int $contactID
464 * @param int $entityID
465 * @param int|NULL $caseID
466 * @throws CRM_Core_Exception
467 */
468 protected static function createMailingActivity($actionSchedule, $mapping, $contactID, $entityID, $caseID) {
469 $session = CRM_Core_Session::singleton();
470
9e1bf145 471 if ($mapping->getEntity() == 'civicrm_membership') {
c72ba2be
TO
472 $activityTypeID
473 = CRM_Core_OptionGroup::getValue('activity_type', 'Membership Renewal Reminder', 'name');
474 }
475 else {
476 $activityTypeID
477 = CRM_Core_OptionGroup::getValue('activity_type', 'Reminder Sent', 'name');
478 }
479
480 $activityParams = array(
481 'subject' => $actionSchedule->title,
482 'details' => $actionSchedule->body_html,
483 'source_contact_id' => $session->get('userID') ? $session->get('userID') : $contactID,
484 'target_contact_id' => $contactID,
485 'activity_date_time' => CRM_Utils_Time::getTime('YmdHis'),
486 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name'),
487 'activity_type_id' => $activityTypeID,
488 'source_record_id' => $entityID,
489 );
490 $activity = CRM_Activity_BAO_Activity::create($activityParams);
491
492 //file reminder on case if source activity is a case activity
493 if (!empty($caseID)) {
494 $caseActivityParams = array();
495 $caseActivityParams['case_id'] = $caseID;
496 $caseActivityParams['activity_id'] = $activity->id;
497 CRM_Case_BAO_Case::processCaseActivity($caseActivityParams);
498 }
499 }
500
c72ba2be 501 /**
f9ec2da6
TO
502 * @param \Civi\ActionSchedule\MappingInterface $mapping
503 * @param \CRM_Core_DAO_ActionSchedule $actionSchedule
c72ba2be
TO
504 * @return string
505 */
506 protected static function prepareMailingQuery($mapping, $actionSchedule) {
f9ec2da6
TO
507 $select = CRM_Utils_SQL_Select::from('civicrm_action_log reminder')
508 ->select("reminder.id as reminderID, reminder.contact_id as contactID, reminder.entity_table as entityTable, reminder.*, e.id AS entityID")
509 ->join('e', "!casMailingJoinType !casMappingEntity e ON !casEntityJoinExpr")
510 ->select("e.id as entityID, e.*")
511 ->where("reminder.action_schedule_id = #casActionScheduleId")
512 ->where("reminder.action_date_time IS NULL")
513 ->param(array(
514 'casActionScheduleId' => $actionSchedule->id,
515 'casMailingJoinType' => ($actionSchedule->limit_to == 0) ? 'LEFT JOIN' : 'INNER JOIN',
516 'casMappingId' => $mapping->getId(),
517 'casMappingEntity' => $mapping->getEntity(),
518 'casEntityJoinExpr' => 'e.id = reminder.entity_id',
519 ));
a1466c59
TO
520
521 if ($actionSchedule->limit_to == 0) {
a1466c59
TO
522 $select->where("e.id = reminder.entity_id OR reminder.entity_table = 'civicrm_contact'");
523 }
c72ba2be 524
f9ec2da6
TO
525 \Civi\Core\Container::singleton()->get('dispatcher')
526 ->dispatch(
527 \Civi\ActionSchedule\Events::MAILING_QUERY,
528 new \Civi\ActionSchedule\Event\MailingQueryEvent($actionSchedule, $mapping, $select)
529 );
c72ba2be 530
a1466c59 531 return $select->toSQL();
c72ba2be
TO
532 }
533
43ceab3f 534 /**
09c2328a 535 * @param \Civi\Token\TokenRow $tokenRow
d22bcd5b
TO
536 * @param CRM_Core_DAO_ActionSchedule $schedule
537 * @param int $toContactID
43ceab3f 538 * @throws CRM_Core_Exception
d22bcd5b
TO
539 * @return array
540 * List of error messages.
43ceab3f 541 */
d22bcd5b
TO
542 protected static function sendReminderSms($tokenRow, $schedule, $toContactID) {
543 $toPhoneNumber = self::pickSmsPhoneNumber($toContactID);
544 if (!$toPhoneNumber) {
545 return array("sms_phone_missing" => "Couldn't find recipient's phone number.");
546 }
547
43ceab3f
TO
548 $messageSubject = $tokenRow->render('subject');
549 $sms_body_text = $tokenRow->render('sms_body_text');
550
551 $session = CRM_Core_Session::singleton();
552 $userID = $session->get('userID') ? $session->get('userID') : $tokenRow->context['contactId'];
553 $smsParams = array(
554 'To' => $toPhoneNumber,
555 'provider_id' => $schedule->sms_provider_id,
556 'activity_subject' => $messageSubject,
557 );
558 $activityTypeID = CRM_Core_OptionGroup::getValue('activity_type',
559 'SMS',
560 'name'
561 );
562 $activityParams = array(
563 'source_contact_id' => $userID,
564 'activity_type_id' => $activityTypeID,
565 'activity_date_time' => date('YmdHis'),
566 'subject' => $messageSubject,
567 'details' => $sms_body_text,
568 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name'),
569 );
570
571 $activity = CRM_Activity_BAO_Activity::create($activityParams);
572
573 CRM_Activity_BAO_Activity::sendSMSMessage($tokenRow->context['contactId'],
574 $sms_body_text,
575 $smsParams,
576 $activity->id,
577 $userID
578 );
d22bcd5b
TO
579
580 return array();
43ceab3f
TO
581 }
582
583 /**
584 * @param CRM_Core_DAO_ActionSchedule $actionSchedule
585 * @return string
586 * Ex: "Alice <alice@example.org>".
587 */
588 protected static function pickFromEmail($actionSchedule) {
589 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
590 $fromEmailAddress = "$domainValues[0] <$domainValues[1]>";
591 if ($actionSchedule->from_email) {
592 $fromEmailAddress = "$actionSchedule->from_name <$actionSchedule->from_email>";
593 return $fromEmailAddress;
594 }
595 return $fromEmailAddress;
596 }
597
598 /**
09c2328a 599 * @param \Civi\Token\TokenRow $tokenRow
d22bcd5b
TO
600 * @param CRM_Core_DAO_ActionSchedule $schedule
601 * @param int $toContactID
602 * @return array
603 * List of error messages.
43ceab3f 604 */
d22bcd5b
TO
605 protected static function sendReminderEmail($tokenRow, $schedule, $toContactID) {
606 $toEmail = CRM_Contact_BAO_Contact::getPrimaryEmail($toContactID);
607 if (!$toEmail) {
608 return array("email_missing" => "Couldn't find recipient's email address.");
609 }
610
43ceab3f
TO
611 $body_text = $tokenRow->render('body_text');
612 $body_html = $tokenRow->render('body_html');
613 if (!$schedule->body_text) {
614 $body_text = CRM_Utils_String::htmlToText($body_html);
615 }
616
617 // set up the parameters for CRM_Utils_Mail::send
618 $mailParams = array(
619 'groupName' => 'Scheduled Reminder Sender',
620 'from' => self::pickFromEmail($schedule),
621 'toName' => $tokenRow->context['contact']['display_name'],
622 'toEmail' => $toEmail,
623 'subject' => $tokenRow->render('subject'),
624 'entity' => 'action_schedule',
625 'entity_id' => $schedule->id,
626 );
627
628 if (!$body_html || $tokenRow->context['contact']['preferred_mail_format'] == 'Text' ||
629 $tokenRow->context['contact']['preferred_mail_format'] == 'Both'
630 ) {
631 // render the &amp; entities in text mode, so that the links work
632 $mailParams['text'] = str_replace('&amp;', '&', $body_text);
633 }
634 if ($body_html && ($tokenRow->context['contact']['preferred_mail_format'] == 'HTML' ||
635 $tokenRow->context['contact']['preferred_mail_format'] == 'Both'
636 )
637 ) {
638 $mailParams['html'] = $body_html;
639 }
640 $result = CRM_Utils_Mail::send($mailParams);
d22bcd5b
TO
641 if (!$result || is_a($result, 'PEAR_Error')) {
642 return array('email_fail' => 'Failed to send message');
643 }
644
645 return array();
43ceab3f
TO
646 }
647
648 /**
649 * @param CRM_Core_DAO_ActionSchedule $schedule
50a23755 650 * @param \Civi\ActionSchedule\Mapping $mapping
43ceab3f
TO
651 * @return \Civi\Token\TokenProcessor
652 */
50a23755 653 protected static function createTokenProcessor($schedule, $mapping) {
43ceab3f
TO
654 $tp = new \Civi\Token\TokenProcessor(\Civi\Core\Container::singleton()->get('dispatcher'), array(
655 'controller' => __CLASS__,
656 'actionSchedule' => $schedule,
50a23755 657 'actionMapping' => $mapping,
43ceab3f
TO
658 'smarty' => TRUE,
659 ));
660 $tp->addMessage('body_text', $schedule->body_text, 'text/plain');
661 $tp->addMessage('body_html', $schedule->body_html, 'text/html');
662 $tp->addMessage('sms_body_text', $schedule->sms_body_text, 'text/plain');
663 $tp->addMessage('subject', $schedule->subject, 'text/plain');
664 return $tp;
665 }
666
d22bcd5b 667 /**
54957108 668 * Pick SMS phone number.
669 *
670 * @param int $smsToContactId
671 *
672 * @return NULL|string
d22bcd5b
TO
673 */
674 protected static function pickSmsPhoneNumber($smsToContactId) {
675 $toPhoneNumbers = CRM_Core_BAO_Phone::allPhones($smsToContactId, FALSE, 'Mobile', array(
676 'is_deceased' => 0,
677 'is_deleted' => 0,
678 'do_not_sms' => 0,
679 ));
680 //to get primary mobile ph,if not get a first mobile phONE
681 if (!empty($toPhoneNumbers)) {
682 $toPhoneNumberDetails = reset($toPhoneNumbers);
683 $toPhoneNumber = CRM_Utils_Array::value('phone', $toPhoneNumberDetails);
684 return $toPhoneNumber;
685 }
686 return NULL;
687 }
688
673c1c81
TO
689 /**
690 * Get the list of generic recipient types supported by all entities/mappings.
691 *
692 * @return array
693 * array(mixed $value => string $label).
694 */
0905ee5d 695 public static function getAdditionalRecipients() {
673c1c81
TO
696 return array(
697 'manual' => ts('Choose Recipient(s)'),
698 'group' => ts('Select Group'),
699 );
700 }
701
6a488035 702}