diff --git a/CRM/Case/Form/Task.php b/CRM/Case/Form/Task.php index d1f318ac4322..0734653c2f3b 100644 --- a/CRM/Case/Form/Task.php +++ b/CRM/Case/Form/Task.php @@ -68,6 +68,23 @@ public function orderBy() { return 'ORDER BY ' . implode(',', $order_array); } + /** + * Get the rows from the results to be pdf-d. + * + * @return array + */ + protected function getRows(): array { + $rows = []; + foreach ($this->_contactIds as $index => $contactID) { + $caseID = $this->getVar('_caseId'); + if (empty($caseID) && !empty($this->_caseIds[$index])) { + $caseID = $this->_caseIds[$index]; + } + $rows[] = ['contactId' => $contactID, 'caseId' => $caseID]; + } + return $rows; + } + /** * Get the name of the table for the relevant entity. * diff --git a/CRM/Contact/Form/Task.php b/CRM/Contact/Form/Task.php index 67b7f2be125f..2a2ad62c635d 100644 --- a/CRM/Contact/Form/Task.php +++ b/CRM/Contact/Form/Task.php @@ -137,7 +137,7 @@ public static function preProcessCommon(&$form) { // since we don't store all contacts in prevnextcache, when user selects "all" use query to retrieve contacts // rather than prevnext cache table for most of the task actions except export where we rebuild query to fetch // final result set - $allCids[$cacheKey] = self::getContactIds($form); + $allCids[$cacheKey] = self::legacyGetContactIds($form); $form->_contactIds = []; if (empty($form->_contactIds)) { @@ -222,11 +222,16 @@ public static function preProcessCommon(&$form) { * - custom search (FIXME: does this still apply to custom search?). * When we call this function we are not using the prev/next cache * + * We've started to try to move away from these functions + * being static. Probably we need to convert the export forms + * to use a trait based approach. For now this is renamed to + * permit the use of a non-static function with this name + * * @param $form CRM_Core_Form * * @return array $contactIds */ - public static function getContactIds($form) { + protected static function legacyGetContactIds($form) { // need to perform action on all contacts // fire the query again and get the contact id's + display name $sortID = NULL; diff --git a/CRM/Contact/Form/Task/PDF.php b/CRM/Contact/Form/Task/PDF.php index 9688e912e3e6..66f1138eb594 100644 --- a/CRM/Contact/Form/Task/PDF.php +++ b/CRM/Contact/Form/Task/PDF.php @@ -110,4 +110,26 @@ public function listTokens() { return $tokens; } + /** + * Get the rows from the results to be pdf-d. + * + * @todo the case handling should be in the case pdf task. + * It needs fixing to support standalone & some url fixes + * + * similar to https://github.com/civicrm/civicrm-core/pull/21688 + * + * @return array + */ + protected function getRows(): array { + $rows = []; + foreach ($this->_contactIds as $index => $contactID) { + $caseID = $this->getVar('_caseId'); + if (empty($caseID) && !empty($this->_caseIds[$index])) { + $caseID = $this->_caseIds[$index]; + } + $rows[] = ['contactId' => $contactID, 'caseId' => $caseID]; + } + return $rows; + } + } diff --git a/CRM/Contact/Form/Task/PDFTrait.php b/CRM/Contact/Form/Task/PDFTrait.php index e0877493ce37..2cfa43c87bb8 100644 --- a/CRM/Contact/Form/Task/PDFTrait.php +++ b/CRM/Contact/Form/Task/PDFTrait.php @@ -237,16 +237,11 @@ public function postProcess(): void { [$html_message, $zip] = CRM_Utils_PDF_Document::unzipDoc($formValues['document_file_path'], $formValues['document_type']); } - foreach ($this->_contactIds as $item => $contactId) { - $caseId = $this->getVar('_caseId'); - if (empty($caseId) && !empty($this->_caseIds[$item])) { - $caseId = $this->_caseIds[$item]; - } - + foreach ($this->getRows() as $row) { $tokenHtml = CRM_Core_BAO_MessageTemplate::renderTemplate([ - 'contactId' => $contactId, + 'contactId' => $row['contactId'], 'messageTemplate' => ['msg_html' => $html_message], - 'tokenContext' => $caseId ? ['caseId' => $caseId] : [], + 'tokenContext' => array_merge($row, ['schema' => $this->getTokenSchema()]), 'disableSmarty' => (!defined('CIVICRM_MAIL_SMARTY') || !CIVICRM_MAIL_SMARTY), ])['html']; diff --git a/CRM/Core/Form/Task.php b/CRM/Core/Form/Task.php index 93051b63d6e1..81ed62d15caf 100644 --- a/CRM/Core/Form/Task.php +++ b/CRM/Core/Form/Task.php @@ -359,4 +359,26 @@ protected function getTokenSchema(): array { return ['contactId']; } + /** + * Get the rows from the results. + * + * @return array + */ + protected function getRows(): array { + $rows = []; + foreach ($this->getContactIDs() as $contactID) { + $rows[] = ['contactId' => $contactID]; + } + return $rows; + } + + /** + * Get the relevant contact IDs. + * + * @return array + */ + protected function getContactIDs(): array { + return $this->_contactIds ?? []; + } + } diff --git a/CRM/Event/Form/Task.php b/CRM/Event/Form/Task.php index e3bbae330dac..20704e0e9392 100644 --- a/CRM/Event/Form/Task.php +++ b/CRM/Event/Form/Task.php @@ -15,6 +15,8 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\Participant; + /** * Class for event form task actions. * FIXME: This needs refactoring to properly inherit from CRM_Core_Form_Task and share more functions. @@ -28,6 +30,16 @@ class CRM_Event_Form_Task extends CRM_Core_Form_Task { */ protected $_participantIds; + /** + * Rows to act on. + * + * Each row will have a participant ID & a contact ID using + * the keys the token processor expects. + * + * @var array + */ + protected $rows = []; + /** * Build all the data structures needed to build the form. * @@ -83,14 +95,36 @@ public static function preProcessCommon(&$form) { $form->setNextUrl('event'); } + /** + * Get the participant IDs. + * + * @return array + */ + public function getIDs(): array { + return $this->_participantIds; + } + /** * Given the participant id, compute the contact id * since its used for things like send email */ - public function setContactIDs() { - $this->_contactIds = CRM_Core_DAO::getContactIDsFromComponent($this->_participantIds, - 'civicrm_participant' - ); + public function setContactIDs(): void { + $this->_contactIds = $this->getContactIDs(); + } + + /** + * Get the relevant contact IDs. + * + * @return array + */ + protected function getContactIDs(): array { + if (isset($this->_contactIds)) { + return $this->_contactIds; + } + foreach ($this->getRows() as $row) { + $this->_contactIds[] = $row['contactId']; + } + return $this->_contactIds; } /** @@ -119,4 +153,35 @@ public function addDefaultButtons($title, $nextType = 'next', $backType = 'back' ]); } + /** + * Get the rows form the search, keyed to make the token processor happy. + * + * @throws \API_Exception + */ + public function getRows(): array { + if (empty($this->rows)) { + // checkPermissions set to false - in case form is bypassing in some way. + $participants = Participant::get(FALSE) + ->addWhere('id', 'IN', $this->getIDs()) + ->setSelect(['id', 'contact_id'])->execute(); + foreach ($participants as $participant) { + $this->rows[] = [ + // We map to this funky format for the token processor :-( + 'contactId' => $participant['contact_id'], + 'participantId' => $participant['id'], + ]; + } + } + return $this->rows; + } + + /** + * Get the token processor schema required to list any tokens for this task. + * + * @return array + */ + public function getTokenSchema(): array { + return ['participantId', 'contactId', 'eventId']; + } + } diff --git a/CRM/Event/Form/Task/PDF.php b/CRM/Event/Form/Task/PDF.php index 778a195f2bab..0f0d25436f4f 100644 --- a/CRM/Event/Form/Task/PDF.php +++ b/CRM/Event/Form/Task/PDF.php @@ -48,21 +48,7 @@ class CRM_Event_Form_Task_PDF extends CRM_Event_Form_Task { public function preProcess() { $this->preProcessPDF(); parent::preProcess(); - - // we have all the participant ids, so now we get the contact ids - parent::setContactIDs(); - $this->assign('single', $this->_single); } - /** - * List available tokens for this form. - * - * @return array - */ - public function listTokens() { - $tokens = CRM_Core_SelectValues::contactTokens(); - return $tokens; - } - } diff --git a/CRM/Event/ParticipantTokens.php b/CRM/Event/ParticipantTokens.php index 5733e10af9e2..f33af5d2b545 100644 --- a/CRM/Event/ParticipantTokens.php +++ b/CRM/Event/ParticipantTokens.php @@ -10,6 +10,7 @@ +--------------------------------------------------------------------+ */ +use Civi\Token\Event\TokenValueEvent; use Civi\Token\TokenRow; /** @@ -42,6 +43,21 @@ public function getCurrencyFieldName(): array { return ['fee_currency']; } + /** + * To handle variable tokens, override this function and return the active tokens. + * + * @param \Civi\Token\Event\TokenValueEvent $e + * + * @return mixed + */ + public function getActiveTokens(TokenValueEvent $e) { + $messageTokens = $e->getTokenProcessor()->getMessageTokens(); + if (!isset($messageTokens[$this->entity])) { + return isset($messageTokens['event']) ? ['event_id'] : FALSE; + } + return parent::getActiveTokens($e); + } + /** * Get any tokens with custom calculation. */ diff --git a/CRM/Member/Form/Task/PDFLetter.php b/CRM/Member/Form/Task/PDFLetter.php index d50dcffddb44..f7464b1b705f 100644 --- a/CRM/Member/Form/Task/PDFLetter.php +++ b/CRM/Member/Form/Task/PDFLetter.php @@ -137,4 +137,13 @@ public function generateHTML($membershipIDs, $messageToken, $html_message): arra return $html; } + /** + * Get the token processor schema required to list any tokens for this task. + * + * @return array + */ + public function getTokenSchema(): array { + return ['membershipId', 'contactId']; + } + }