8a432af6 |
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 | */ |
17 | |
5b4b9509 |
18 | use Civi\Api4\Email; |
19 | |
8a432af6 |
20 | /** |
21 | * This class provides the common functionality for tasks that send emails. |
22 | */ |
23 | trait CRM_Contact_Form_Task_EmailTrait { |
24 | |
25 | /** |
26 | * Are we operating in "single mode", i.e. sending email to one |
27 | * specific contact? |
28 | * |
29 | * @var bool |
30 | */ |
31 | public $_single = FALSE; |
32 | |
33 | public $_noEmails = FALSE; |
34 | |
35 | /** |
36 | * All the existing templates in the system. |
37 | * |
38 | * @var array |
39 | */ |
40 | public $_templates; |
41 | |
362e6a63 |
42 | /** |
43 | * Store "to" contact details. |
44 | * @var array |
45 | */ |
46 | public $_toContactDetails = []; |
47 | |
48 | /** |
49 | * Store all selected contact id's, that includes to, cc and bcc contacts |
50 | * @var array |
51 | */ |
52 | public $_allContactIds = []; |
53 | |
54 | /** |
55 | * Store only "to" contact ids. |
56 | * @var array |
57 | */ |
58 | public $_toContactIds = []; |
59 | |
60 | /** |
61 | * Store only "cc" contact ids. |
62 | * @var array |
63 | */ |
64 | public $_ccContactIds = []; |
65 | |
66 | /** |
67 | * Store only "bcc" contact ids. |
f7869f64 |
68 | * |
362e6a63 |
69 | * @var array |
70 | */ |
71 | public $_bccContactIds = []; |
72 | |
e94f3011 |
73 | /** |
74 | * Is the form being loaded from a search action. |
75 | * |
76 | * @var bool |
77 | */ |
78 | public $isSearchContext = TRUE; |
79 | |
5b4b9509 |
80 | public $contactEmails = []; |
81 | |
f1781890 |
82 | /** |
83 | * Contacts form whom emails could not be sent. |
84 | * |
85 | * An array of contact ids and the relevant message details. |
86 | * |
87 | * @var array |
88 | */ |
89 | protected $suppressedEmails = []; |
90 | |
e94f3011 |
91 | /** |
92 | * Getter for isSearchContext. |
93 | * |
94 | * @return bool |
95 | */ |
96 | public function isSearchContext(): bool { |
97 | return $this->isSearchContext; |
98 | } |
99 | |
100 | /** |
101 | * Setter for isSearchContext. |
102 | * |
103 | * @param bool $isSearchContext |
104 | */ |
105 | public function setIsSearchContext(bool $isSearchContext) { |
106 | $this->isSearchContext = $isSearchContext; |
107 | } |
108 | |
e656d97c |
109 | /** |
110 | * Build all the data structures needed to build the form. |
111 | * |
112 | * @throws \CiviCRM_API3_Exception |
113 | * @throws \CRM_Core_Exception |
114 | */ |
115 | public function preProcess() { |
e94f3011 |
116 | $this->traitPreProcess(); |
117 | } |
118 | |
119 | /** |
120 | * Call trait preProcess function. |
121 | * |
122 | * This function exists as a transitional arrangement so classes overriding |
123 | * preProcess can still call it. Ideally it will be melded into preProcess later. |
124 | * |
125 | * @throws \CiviCRM_API3_Exception |
126 | * @throws \CRM_Core_Exception |
127 | */ |
128 | protected function traitPreProcess() { |
e656d97c |
129 | CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($this); |
e94f3011 |
130 | if ($this->isSearchContext()) { |
131 | // Currently only the contact email form is callable outside search context. |
132 | parent::preProcess(); |
133 | } |
e656d97c |
134 | $this->setContactIDs(); |
135 | $this->assign('single', $this->_single); |
e94f3011 |
136 | if (CRM_Core_Permission::check('administer CiviCRM')) { |
137 | $this->assign('isAdmin', 1); |
138 | } |
e656d97c |
139 | } |
140 | |
f7869f64 |
141 | /** |
142 | * Build the form object. |
143 | * |
144 | * @throws \CRM_Core_Exception |
145 | */ |
146 | public function buildQuickForm() { |
147 | // Suppress form might not be required but perhaps there was a risk some other process had set it to TRUE. |
148 | $this->assign('suppressForm', FALSE); |
149 | $this->assign('emailTask', TRUE); |
150 | |
a01fb99f |
151 | $toArray = []; |
b68f0d01 |
152 | $suppressedEmails = 0; |
153 | //here we are getting logged in user id as array but we need target contact id. CRM-5988 |
154 | $cid = $this->get('cid'); |
155 | if ($cid) { |
156 | $this->_contactIds = explode(',', $cid); |
157 | } |
158 | if (count($this->_contactIds) > 1) { |
159 | $this->_single = FALSE; |
160 | } |
704696b5 |
161 | $this->bounceIfSimpleMailLimitExceeded(count($this->_contactIds)); |
b68f0d01 |
162 | |
163 | $emailAttributes = [ |
164 | 'class' => 'huge', |
165 | ]; |
166 | $to = $this->add('text', 'to', ts('To'), $emailAttributes, TRUE); |
a01fb99f |
167 | |
168 | $this->addEntityRef('cc_id', ts('CC'), [ |
169 | 'entity' => 'Email', |
170 | 'multiple' => TRUE, |
171 | ]); |
5b4b9509 |
172 | |
173 | $this->addEntityRef('bcc_id', ts('BCC'), [ |
174 | 'entity' => 'Email', |
175 | 'multiple' => TRUE, |
176 | ]); |
b68f0d01 |
177 | |
178 | if ($to->getValue()) { |
179 | $this->_toContactIds = $this->_contactIds = []; |
180 | } |
181 | $setDefaults = TRUE; |
182 | if (property_exists($this, '_context') && $this->_context === 'standalone') { |
183 | $setDefaults = FALSE; |
184 | } |
185 | |
b68f0d01 |
186 | $this->_allContactIds = $this->_toContactIds = $this->_contactIds; |
b68f0d01 |
187 | |
2067c79f |
188 | if ($to->getValue()) { |
189 | foreach ($this->getEmails($to) as $value) { |
190 | $contactId = $value['contact_id']; |
191 | $email = $value['email']; |
192 | if ($contactId) { |
193 | $this->_contactIds[] = $this->_toContactIds[] = $contactId; |
194 | $this->_toContactEmails[] = $email; |
195 | $this->_allContactIds[] = $contactId; |
196 | } |
b68f0d01 |
197 | } |
2067c79f |
198 | $setDefaults = TRUE; |
b68f0d01 |
199 | } |
200 | |
201 | //get the group of contacts as per selected by user in case of Find Activities |
202 | if (!empty($this->_activityHolderIds)) { |
203 | $contact = $this->get('contacts'); |
204 | $this->_allContactIds = $this->_contactIds = $contact; |
205 | } |
206 | |
207 | // check if we need to setdefaults and check for valid contact emails / communication preferences |
208 | if (is_array($this->_allContactIds) && $setDefaults) { |
b68f0d01 |
209 | // get the details for all selected contacts ( to, cc and bcc contacts ) |
33ced9a4 |
210 | $allContactDetails = civicrm_api3('Contact', 'get', [ |
211 | 'id' => ['IN' => $this->_allContactIds], |
212 | 'return' => ['sort_name', 'email', 'do_not_email', 'is_deceased', 'on_hold', 'display_name', 'preferred_mail_format'], |
213 | 'options' => ['limit' => 0], |
214 | ])['values']; |
b68f0d01 |
215 | |
f942a8b0 |
216 | // The contact task supports passing in email_id in a url. It supports a single email |
217 | // and is marked as having been related to CiviHR. |
218 | // The array will look like $this->_toEmail = ['email' => 'x', 'contact_id' => 2]) |
219 | // If it exists we want to use the specified email which might be different to the primary email |
220 | // that we have. |
221 | if (!empty($this->_toEmail['contact_id']) && !empty($allContactDetails[$this->_toEmail['contact_id']])) { |
222 | $allContactDetails[$this->_toEmail['contact_id']]['email'] = $this->_toEmail['email']; |
223 | } |
224 | |
b68f0d01 |
225 | // perform all validations on unique contact Ids |
33ced9a4 |
226 | foreach ($allContactDetails as $contactId => $value) { |
b68f0d01 |
227 | if ($value['do_not_email'] || empty($value['email']) || !empty($value['is_deceased']) || $value['on_hold']) { |
f1781890 |
228 | $this->setSuppressedEmail($contactId, $value); |
b68f0d01 |
229 | } |
f942a8b0 |
230 | elseif (in_array($contactId, $this->_toContactIds)) { |
231 | $this->_toContactDetails[$contactId] = $this->_contactDetails[$contactId] = $value; |
232 | $toArray[] = [ |
233 | 'text' => '"' . $value['sort_name'] . '" <' . $value['email'] . '>', |
234 | 'id' => "$contactId::{$value['email']}", |
235 | ]; |
b68f0d01 |
236 | } |
237 | } |
238 | |
239 | if (empty($toArray)) { |
240 | CRM_Core_Error::statusBounce(ts('Selected contact(s) do not have a valid email address, or communication preferences specify DO NOT EMAIL, or they are deceased or Primary email address is On Hold.')); |
241 | } |
242 | } |
243 | |
244 | $this->assign('toContact', json_encode($toArray)); |
b68f0d01 |
245 | |
f1781890 |
246 | $this->assign('suppressedEmails', count($this->suppressedEmails)); |
b68f0d01 |
247 | |
248 | $this->assign('totalSelectedContacts', count($this->_contactIds)); |
249 | |
250 | $this->add('text', 'subject', ts('Subject'), 'size=50 maxlength=254', TRUE); |
251 | |
252 | $this->add('select', 'from_email_address', ts('From'), $this->_fromEmails, TRUE); |
253 | |
254 | CRM_Mailing_BAO_Mailing::commonCompose($this); |
255 | |
256 | // add attachments |
257 | CRM_Core_BAO_File::buildAttachment($this, NULL); |
258 | |
259 | if ($this->_single) { |
260 | // also fix the user context stack |
261 | if ($this->_caseId) { |
262 | $ccid = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_CaseContact', $this->_caseId, |
263 | 'contact_id', 'case_id' |
264 | ); |
265 | $url = CRM_Utils_System::url('civicrm/contact/view/case', |
266 | "&reset=1&action=view&cid={$ccid}&id={$this->_caseId}" |
267 | ); |
268 | } |
269 | elseif ($this->_context) { |
270 | $url = CRM_Utils_System::url('civicrm/dashboard', 'reset=1'); |
271 | } |
272 | else { |
273 | $url = CRM_Utils_System::url('civicrm/contact/view', |
274 | "&show=1&action=browse&cid={$this->_contactIds[0]}&selectedChild=activity" |
275 | ); |
276 | } |
277 | |
278 | $session = CRM_Core_Session::singleton(); |
279 | $session->replaceUserContext($url); |
280 | $this->addDefaultButtons(ts('Send Email'), 'upload', 'cancel'); |
281 | } |
282 | else { |
283 | $this->addDefaultButtons(ts('Send Email'), 'upload'); |
284 | } |
285 | |
286 | $fields = [ |
287 | 'followup_assignee_contact_id' => [ |
288 | 'type' => 'entityRef', |
289 | 'label' => ts('Assigned to'), |
290 | 'attributes' => [ |
291 | 'multiple' => TRUE, |
292 | 'create' => TRUE, |
293 | 'api' => ['params' => ['is_deceased' => 0]], |
294 | ], |
295 | ], |
296 | 'followup_activity_type_id' => [ |
297 | 'type' => 'select', |
298 | 'label' => ts('Followup Activity'), |
299 | 'attributes' => ['' => '- ' . ts('select activity') . ' -'] + CRM_Core_PseudoConstant::ActivityType(FALSE), |
300 | 'extra' => ['class' => 'crm-select2'], |
301 | ], |
302 | 'followup_activity_subject' => [ |
303 | 'type' => 'text', |
304 | 'label' => ts('Subject'), |
305 | 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', |
306 | 'subject' |
307 | ), |
308 | ], |
309 | ]; |
310 | |
311 | //add followup date |
312 | $this->add('datepicker', 'followup_date', ts('in')); |
313 | |
314 | foreach ($fields as $field => $values) { |
315 | if (!empty($fields[$field])) { |
316 | $attribute = $values['attributes'] ?? NULL; |
317 | $required = !empty($values['required']); |
318 | |
319 | if ($values['type'] === 'select' && empty($attribute)) { |
320 | $this->addSelect($field, ['entity' => 'activity'], $required); |
321 | } |
322 | elseif ($values['type'] === 'entityRef') { |
323 | $this->addEntityRef($field, $values['label'], $attribute, $required); |
324 | } |
325 | else { |
326 | $this->add($values['type'], $field, $values['label'], $attribute, $required, CRM_Utils_Array::value('extra', $values)); |
327 | } |
328 | } |
329 | } |
330 | |
331 | //Added for CRM-15984: Add campaign field |
332 | CRM_Campaign_BAO_Campaign::addCampaign($this); |
333 | |
334 | $this->addFormRule(['CRM_Contact_Form_Task_EmailCommon', 'formRule'], $this); |
335 | CRM_Core_Resources::singleton()->addScriptFile('civicrm', 'templates/CRM/Contact/Form/Task/EmailCommon.js', 0, 'html-header'); |
f7869f64 |
336 | } |
337 | |
8a432af6 |
338 | /** |
339 | * Process the form after the input has been submitted and validated. |
340 | * |
341 | * @throws \CRM_Core_Exception |
342 | * @throws \CiviCRM_API3_Exception |
343 | * @throws \Civi\API\Exception\UnauthorizedException |
426b9dec |
344 | * @throws \API_Exception |
8a432af6 |
345 | */ |
346 | public function postProcess() { |
704696b5 |
347 | $this->bounceIfSimpleMailLimitExceeded(count($this->_contactIds)); |
348 | |
349 | // check and ensure that |
350 | $formValues = $this->controller->exportValues($this->getName()); |
351 | $this->submit($formValues); |
352 | } |
353 | |
354 | /** |
355 | * Bounce if there are more emails than permitted. |
356 | * |
357 | * @param int $count |
358 | * The number of emails the user is attempting to send |
359 | */ |
360 | protected function bounceIfSimpleMailLimitExceeded($count) { |
361 | $limit = Civi::settings()->get('simple_mail_limit'); |
362 | if ($count > $limit) { |
363 | CRM_Core_Error::statusBounce(ts('Please do not use this task to send a lot of emails (greater than %1). Many countries have legal requirements when sending bulk emails and the CiviMail framework has opt out functionality and domain tokens to help meet these.', |
364 | [1 => $limit] |
365 | )); |
366 | } |
367 | } |
368 | |
369 | /** |
370 | * Submit the form values. |
371 | * |
372 | * This is also accessible for testing. |
373 | * |
374 | * @param array $formValues |
375 | * |
376 | * @throws \CRM_Core_Exception |
377 | * @throws \CiviCRM_API3_Exception |
378 | * @throws \Civi\API\Exception\UnauthorizedException |
5b4b9509 |
379 | * @throws \API_Exception |
704696b5 |
380 | */ |
381 | public function submit($formValues) { |
382 | $this->saveMessageTemplate($formValues); |
383 | |
384 | $from = $formValues['from_email_address'] ?? NULL; |
385 | // dev/core#357 User Emails are keyed by their id so that the Signature is able to be added |
386 | // If we have had a contact email used here the value returned from the line above will be the |
387 | // numerical key where as $from for use in the sendEmail in Activity needs to be of format of "To Name" <toemailaddress> |
388 | $from = CRM_Utils_Mail::formatFromAddress($from); |
704696b5 |
389 | |
a01fb99f |
390 | $ccArray = $formValues['cc_id'] ? explode(',', $formValues['cc_id']) : []; |
391 | $cc = $this->getEmailString($ccArray); |
392 | $additionalDetails = empty($ccArray) ? '' : "\ncc : " . $this->getEmailUrlString($ccArray); |
704696b5 |
393 | |
a01fb99f |
394 | $bccArray = $formValues['bcc_id'] ? explode(',', $formValues['bcc_id']) : []; |
5b4b9509 |
395 | $bcc = $this->getEmailString($bccArray); |
396 | $additionalDetails .= empty($bccArray) ? '' : "\nbcc : " . $this->getEmailUrlString($bccArray); |
704696b5 |
397 | |
704696b5 |
398 | // format contact details array to handle multiple emails from same contact |
399 | $formattedContactDetails = []; |
704696b5 |
400 | foreach ($this->_contactIds as $key => $contactId) { |
401 | // if we dont have details on this contactID, we should ignore |
402 | // potentially this is due to the contact not wanting to receive email |
403 | if (!isset($this->_contactDetails[$contactId])) { |
404 | continue; |
405 | } |
406 | $email = $this->_toContactEmails[$key]; |
407 | // prevent duplicate emails if same email address is selected CRM-4067 |
408 | // we should allow same emails for different contacts |
426b9dec |
409 | $details = $this->_contactDetails[$contactId]; |
410 | $details['email'] = $email; |
411 | unset($details['email_id']); |
412 | $formattedContactDetails["{$contactId}::{$email}"] = $details; |
704696b5 |
413 | } |
414 | |
704696b5 |
415 | // send the mail |
416 | list($sent, $activityId) = CRM_Activity_BAO_Activity::sendEmail( |
417 | $formattedContactDetails, |
541ad531 |
418 | $this->getSubject($formValues['subject']), |
704696b5 |
419 | $formValues['text_message'], |
420 | $formValues['html_message'], |
421 | NULL, |
422 | NULL, |
423 | $from, |
192bedd3 |
424 | $this->getAttachments($formValues), |
704696b5 |
425 | $cc, |
426 | $bcc, |
427 | array_keys($this->_toContactDetails), |
428 | $additionalDetails, |
bbd99e79 |
429 | $this->getVar('_contributionIds') ?? [], |
704696b5 |
430 | CRM_Utils_Array::value('campaign_id', $formValues), |
431 | $this->getVar('_caseId') |
432 | ); |
433 | |
704696b5 |
434 | if ($sent) { |
dee865af |
435 | $followupStatus = $this->createFollowUpActivities($formValues, $activityId); |
704696b5 |
436 | $count_success = count($this->_toContactDetails); |
437 | CRM_Core_Session::setStatus(ts('One message was sent successfully. ', [ |
438 | 'plural' => '%count messages were sent successfully. ', |
439 | 'count' => $count_success, |
440 | ]) . $followupStatus, ts('Message Sent', ['plural' => 'Messages Sent', 'count' => $count_success]), 'success'); |
441 | } |
442 | |
f1781890 |
443 | if (!empty($this->suppressedEmails)) { |
444 | $status = '(' . ts('because no email address on file or communication preferences specify DO NOT EMAIL or Contact is deceased or Primary email address is On Hold') . ')<ul><li>' . implode('</li><li>', $this->suppressedEmails) . '</li></ul>'; |
704696b5 |
445 | CRM_Core_Session::setStatus($status, ts('One Message Not Sent', [ |
f1781890 |
446 | 'count' => count($this->suppressedEmails), |
704696b5 |
447 | 'plural' => '%count Messages Not Sent', |
448 | ]), 'info'); |
449 | } |
450 | |
451 | if (isset($this->_caseId)) { |
452 | // if case-id is found in the url, create case activity record |
453 | $cases = explode(',', $this->_caseId); |
454 | foreach ($cases as $key => $val) { |
455 | if (is_numeric($val)) { |
456 | $caseParams = [ |
457 | 'activity_id' => $activityId, |
458 | 'case_id' => $val, |
459 | ]; |
460 | CRM_Case_BAO_Case::processCaseActivity($caseParams); |
461 | } |
462 | } |
463 | } |
464 | } |
465 | |
466 | /** |
467 | * Save the template if update selected. |
468 | * |
469 | * @param array $formValues |
470 | * |
471 | * @throws \CiviCRM_API3_Exception |
472 | * @throws \Civi\API\Exception\UnauthorizedException |
473 | */ |
474 | protected function saveMessageTemplate($formValues) { |
475 | if (!empty($formValues['saveTemplate']) || !empty($formValues['updateTemplate'])) { |
476 | $messageTemplate = [ |
477 | 'msg_text' => $formValues['text_message'], |
478 | 'msg_html' => $formValues['html_message'], |
479 | 'msg_subject' => $formValues['subject'], |
480 | 'is_active' => TRUE, |
481 | ]; |
482 | |
483 | if (!empty($formValues['saveTemplate'])) { |
484 | $messageTemplate['msg_title'] = $formValues['saveTemplateName']; |
485 | CRM_Core_BAO_MessageTemplate::add($messageTemplate); |
486 | } |
487 | |
488 | if (!empty($formValues['template']) && !empty($formValues['updateTemplate'])) { |
489 | $messageTemplate['id'] = $formValues['template']; |
490 | unset($messageTemplate['msg_title']); |
491 | CRM_Core_BAO_MessageTemplate::add($messageTemplate); |
492 | } |
493 | } |
8a432af6 |
494 | } |
495 | |
b61322fd |
496 | /** |
497 | * List available tokens for this form. |
498 | * |
499 | * @return array |
500 | */ |
501 | public function listTokens() { |
502 | return CRM_Core_SelectValues::contactTokens(); |
503 | } |
504 | |
b68f0d01 |
505 | /** |
506 | * Get the emails from the added element. |
507 | * |
508 | * @param HTML_QuickForm_Element $element |
509 | * |
510 | * @return array |
511 | */ |
512 | protected function getEmails($element): array { |
513 | $allEmails = explode(',', $element->getValue()); |
514 | $return = []; |
515 | foreach ($allEmails as $value) { |
516 | $values = explode('::', $value); |
517 | $return[] = ['contact_id' => $values[0], 'email' => $values[1]]; |
518 | } |
519 | return $return; |
520 | } |
521 | |
5b4b9509 |
522 | /** |
523 | * Get the string for the email IDs. |
524 | * |
525 | * @param array $emailIDs |
526 | * Array of email IDs. |
527 | * |
528 | * @return string |
529 | * e.g. "Smith, Bob<bob.smith@example.com>". |
530 | * |
531 | * @throws \API_Exception |
532 | * @throws \Civi\API\Exception\UnauthorizedException |
533 | */ |
534 | protected function getEmailString(array $emailIDs): string { |
a01fb99f |
535 | if (empty($emailIDs)) { |
536 | return ''; |
537 | } |
5b4b9509 |
538 | $emails = Email::get() |
539 | ->addWhere('id', 'IN', $emailIDs) |
540 | ->setCheckPermissions(FALSE) |
541 | ->setSelect(['contact_id', 'email', 'contact.sort_name', 'contact.display_name'])->execute(); |
542 | $emailStrings = []; |
543 | foreach ($emails as $email) { |
544 | $this->contactEmails[$email['id']] = $email; |
545 | $emailStrings[] = '"' . $email['contact.sort_name'] . '" <' . $email['email'] . '>'; |
546 | } |
547 | return implode(',', $emailStrings); |
548 | } |
549 | |
550 | /** |
551 | * Get the url string. |
552 | * |
553 | * This is called after the contacts have been retrieved so we don't need to re-retrieve. |
554 | * |
555 | * @param array $emailIDs |
556 | * |
557 | * @return string |
558 | * e.g. <a href='{$contactURL}'>Bob Smith</a>' |
559 | */ |
560 | protected function getEmailUrlString(array $emailIDs): string { |
561 | $urlString = ''; |
562 | foreach ($emailIDs as $email) { |
563 | $contactURL = CRM_Utils_System::url('civicrm/contact/view', ['reset' => 1, 'force' => 1, 'cid' => $this->contactEmails[$email]['contact_id']], TRUE); |
564 | $urlString .= "<a href='{$contactURL}'>" . $this->contactEmails[$email]['contact.display_name'] . '</a>'; |
565 | } |
566 | return $urlString; |
567 | } |
568 | |
f1781890 |
569 | /** |
570 | * Set the emails that are not to be sent out. |
571 | * |
572 | * @param int $contactID |
573 | * @param array $values |
574 | */ |
575 | protected function setSuppressedEmail($contactID, $values) { |
576 | $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $contactID); |
577 | $this->suppressedEmails[$contactID] = "<a href='$contactViewUrl' title='{$values['email']}'>{$values['display_name']}</a>" . ($values['on_hold'] ? '(' . ts('on hold') . ')' : ''); |
578 | } |
579 | |
192bedd3 |
580 | /** |
581 | * Get any attachments. |
582 | * |
583 | * @param array $formValues |
584 | * |
585 | * @return array |
586 | */ |
587 | protected function getAttachments(array $formValues): array { |
588 | $attachments = []; |
589 | CRM_Core_BAO_File::formatAttachment($formValues, |
590 | $attachments, |
591 | NULL, NULL |
592 | ); |
593 | return $attachments; |
594 | } |
595 | |
541ad531 |
596 | /** |
597 | * Get the subject for the message. |
598 | * |
599 | * The case handling should possibly be on the case form..... |
600 | * |
601 | * @param string $subject |
602 | * |
603 | * @return string |
604 | */ |
605 | protected function getSubject(string $subject):string { |
606 | // CRM-5916: prepend case id hash to CiviCase-originating emails’ subjects |
607 | if (isset($this->_caseId) && is_numeric($this->_caseId)) { |
608 | $hash = substr(sha1(CIVICRM_SITE_KEY . $this->_caseId), 0, 7); |
609 | $subject = "[case #$hash] $subject"; |
610 | } |
611 | return $subject; |
612 | } |
613 | |
dee865af |
614 | /** |
615 | * Create any follow up activities. |
616 | * |
617 | * @param array $formValues |
618 | * @param int $activityId |
619 | * |
620 | * @return string |
621 | * |
622 | * @throws \CRM_Core_Exception |
623 | */ |
624 | protected function createFollowUpActivities($formValues, $activityId): string { |
625 | $params = []; |
626 | $followupStatus = ''; |
627 | $followupActivity = NULL; |
628 | if (!empty($formValues['followup_activity_type_id'])) { |
629 | $params['followup_activity_type_id'] = $formValues['followup_activity_type_id']; |
630 | $params['followup_activity_subject'] = $formValues['followup_activity_subject']; |
631 | $params['followup_date'] = $formValues['followup_date']; |
632 | $params['target_contact_id'] = $this->_contactIds; |
633 | $params['followup_assignee_contact_id'] = explode(',', $formValues['followup_assignee_contact_id']); |
634 | $followupActivity = CRM_Activity_BAO_Activity::createFollowupActivity($activityId, $params); |
635 | $followupStatus = ts('A followup activity has been scheduled.'); |
636 | |
637 | if (Civi::settings()->get('activity_assignee_notification')) { |
638 | if ($followupActivity) { |
639 | $mailToFollowupContacts = []; |
640 | $assignee = [$followupActivity->id]; |
641 | $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($assignee, TRUE, FALSE); |
642 | foreach ($assigneeContacts as $values) { |
643 | $mailToFollowupContacts[$values['email']] = $values; |
644 | } |
645 | |
646 | $sentFollowup = CRM_Activity_BAO_Activity::sendToAssignee($followupActivity, $mailToFollowupContacts); |
647 | if ($sentFollowup) { |
648 | $followupStatus .= '<br />' . ts('A copy of the follow-up activity has also been sent to follow-up assignee contacts(s).'); |
649 | } |
650 | } |
651 | } |
652 | } |
653 | return $followupStatus; |
654 | } |
655 | |
8a432af6 |
656 | } |