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 | |
4367e964 |
250 | $this->add('text', 'subject', ts('Subject'), ['size' => 50, 'maxlength' => 254], TRUE); |
b68f0d01 |
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 | } |
704696b5 |
450 | } |
451 | |
452 | /** |
453 | * Save the template if update selected. |
454 | * |
455 | * @param array $formValues |
456 | * |
457 | * @throws \CiviCRM_API3_Exception |
458 | * @throws \Civi\API\Exception\UnauthorizedException |
459 | */ |
460 | protected function saveMessageTemplate($formValues) { |
461 | if (!empty($formValues['saveTemplate']) || !empty($formValues['updateTemplate'])) { |
462 | $messageTemplate = [ |
463 | 'msg_text' => $formValues['text_message'], |
464 | 'msg_html' => $formValues['html_message'], |
465 | 'msg_subject' => $formValues['subject'], |
466 | 'is_active' => TRUE, |
467 | ]; |
468 | |
469 | if (!empty($formValues['saveTemplate'])) { |
470 | $messageTemplate['msg_title'] = $formValues['saveTemplateName']; |
471 | CRM_Core_BAO_MessageTemplate::add($messageTemplate); |
472 | } |
473 | |
474 | if (!empty($formValues['template']) && !empty($formValues['updateTemplate'])) { |
475 | $messageTemplate['id'] = $formValues['template']; |
476 | unset($messageTemplate['msg_title']); |
477 | CRM_Core_BAO_MessageTemplate::add($messageTemplate); |
478 | } |
479 | } |
8a432af6 |
480 | } |
481 | |
b61322fd |
482 | /** |
483 | * List available tokens for this form. |
484 | * |
485 | * @return array |
486 | */ |
487 | public function listTokens() { |
488 | return CRM_Core_SelectValues::contactTokens(); |
489 | } |
490 | |
b68f0d01 |
491 | /** |
492 | * Get the emails from the added element. |
493 | * |
494 | * @param HTML_QuickForm_Element $element |
495 | * |
496 | * @return array |
497 | */ |
498 | protected function getEmails($element): array { |
499 | $allEmails = explode(',', $element->getValue()); |
500 | $return = []; |
501 | foreach ($allEmails as $value) { |
502 | $values = explode('::', $value); |
503 | $return[] = ['contact_id' => $values[0], 'email' => $values[1]]; |
504 | } |
505 | return $return; |
506 | } |
507 | |
5b4b9509 |
508 | /** |
509 | * Get the string for the email IDs. |
510 | * |
511 | * @param array $emailIDs |
512 | * Array of email IDs. |
513 | * |
514 | * @return string |
515 | * e.g. "Smith, Bob<bob.smith@example.com>". |
516 | * |
517 | * @throws \API_Exception |
518 | * @throws \Civi\API\Exception\UnauthorizedException |
519 | */ |
520 | protected function getEmailString(array $emailIDs): string { |
a01fb99f |
521 | if (empty($emailIDs)) { |
522 | return ''; |
523 | } |
5b4b9509 |
524 | $emails = Email::get() |
525 | ->addWhere('id', 'IN', $emailIDs) |
526 | ->setCheckPermissions(FALSE) |
527 | ->setSelect(['contact_id', 'email', 'contact.sort_name', 'contact.display_name'])->execute(); |
528 | $emailStrings = []; |
529 | foreach ($emails as $email) { |
530 | $this->contactEmails[$email['id']] = $email; |
531 | $emailStrings[] = '"' . $email['contact.sort_name'] . '" <' . $email['email'] . '>'; |
532 | } |
533 | return implode(',', $emailStrings); |
534 | } |
535 | |
536 | /** |
537 | * Get the url string. |
538 | * |
539 | * This is called after the contacts have been retrieved so we don't need to re-retrieve. |
540 | * |
541 | * @param array $emailIDs |
542 | * |
543 | * @return string |
544 | * e.g. <a href='{$contactURL}'>Bob Smith</a>' |
545 | */ |
546 | protected function getEmailUrlString(array $emailIDs): string { |
3420384b |
547 | $urls = []; |
5b4b9509 |
548 | foreach ($emailIDs as $email) { |
3420384b |
549 | $contactURL = CRM_Utils_System::url('civicrm/contact/view', ['reset' => 1, 'cid' => $this->contactEmails[$email]['contact_id']], TRUE); |
550 | $urls[] = "<a href='{$contactURL}'>" . $this->contactEmails[$email]['contact.display_name'] . '</a>'; |
5b4b9509 |
551 | } |
3420384b |
552 | return implode(', ', $urls); |
5b4b9509 |
553 | } |
554 | |
f1781890 |
555 | /** |
556 | * Set the emails that are not to be sent out. |
557 | * |
558 | * @param int $contactID |
559 | * @param array $values |
560 | */ |
561 | protected function setSuppressedEmail($contactID, $values) { |
562 | $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $contactID); |
563 | $this->suppressedEmails[$contactID] = "<a href='$contactViewUrl' title='{$values['email']}'>{$values['display_name']}</a>" . ($values['on_hold'] ? '(' . ts('on hold') . ')' : ''); |
564 | } |
565 | |
192bedd3 |
566 | /** |
567 | * Get any attachments. |
568 | * |
569 | * @param array $formValues |
570 | * |
571 | * @return array |
572 | */ |
573 | protected function getAttachments(array $formValues): array { |
574 | $attachments = []; |
575 | CRM_Core_BAO_File::formatAttachment($formValues, |
576 | $attachments, |
577 | NULL, NULL |
578 | ); |
579 | return $attachments; |
580 | } |
581 | |
541ad531 |
582 | /** |
583 | * Get the subject for the message. |
584 | * |
585 | * The case handling should possibly be on the case form..... |
586 | * |
587 | * @param string $subject |
588 | * |
589 | * @return string |
590 | */ |
591 | protected function getSubject(string $subject):string { |
592 | // CRM-5916: prepend case id hash to CiviCase-originating emails’ subjects |
593 | if (isset($this->_caseId) && is_numeric($this->_caseId)) { |
594 | $hash = substr(sha1(CIVICRM_SITE_KEY . $this->_caseId), 0, 7); |
595 | $subject = "[case #$hash] $subject"; |
596 | } |
597 | return $subject; |
598 | } |
599 | |
dee865af |
600 | /** |
601 | * Create any follow up activities. |
602 | * |
603 | * @param array $formValues |
604 | * @param int $activityId |
605 | * |
606 | * @return string |
607 | * |
608 | * @throws \CRM_Core_Exception |
609 | */ |
610 | protected function createFollowUpActivities($formValues, $activityId): string { |
611 | $params = []; |
612 | $followupStatus = ''; |
613 | $followupActivity = NULL; |
614 | if (!empty($formValues['followup_activity_type_id'])) { |
615 | $params['followup_activity_type_id'] = $formValues['followup_activity_type_id']; |
616 | $params['followup_activity_subject'] = $formValues['followup_activity_subject']; |
617 | $params['followup_date'] = $formValues['followup_date']; |
618 | $params['target_contact_id'] = $this->_contactIds; |
619 | $params['followup_assignee_contact_id'] = explode(',', $formValues['followup_assignee_contact_id']); |
620 | $followupActivity = CRM_Activity_BAO_Activity::createFollowupActivity($activityId, $params); |
621 | $followupStatus = ts('A followup activity has been scheduled.'); |
622 | |
623 | if (Civi::settings()->get('activity_assignee_notification')) { |
624 | if ($followupActivity) { |
625 | $mailToFollowupContacts = []; |
626 | $assignee = [$followupActivity->id]; |
627 | $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($assignee, TRUE, FALSE); |
628 | foreach ($assigneeContacts as $values) { |
629 | $mailToFollowupContacts[$values['email']] = $values; |
630 | } |
631 | |
632 | $sentFollowup = CRM_Activity_BAO_Activity::sendToAssignee($followupActivity, $mailToFollowupContacts); |
633 | if ($sentFollowup) { |
634 | $followupStatus .= '<br />' . ts('A copy of the follow-up activity has also been sent to follow-up assignee contacts(s).'); |
635 | } |
636 | } |
637 | } |
638 | } |
639 | return $followupStatus; |
640 | } |
641 | |
8a432af6 |
642 | } |