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