From c93917b392d2620e0e52e644a10d64fbfc92dbad Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 8 Oct 2021 08:44:40 +1300 Subject: [PATCH] Specifiy audience for event tokens --- CRM/Contact/Form/Task/LabelCommon.php | 2 +- CRM/Contact/Tokens.php | 10 +- CRM/Core/EntityTokens.php | 29 ++++- CRM/Event/Tokens.php | 5 + .../CRM/Core/BAO/MessageTemplateTest.php | 117 +++++++++++++++++- 5 files changed, 150 insertions(+), 13 deletions(-) diff --git a/CRM/Contact/Form/Task/LabelCommon.php b/CRM/Contact/Form/Task/LabelCommon.php index 5b7a295e8736..6ac8ab971cc1 100644 --- a/CRM/Contact/Form/Task/LabelCommon.php +++ b/CRM/Contact/Form/Task/LabelCommon.php @@ -144,7 +144,7 @@ public static function getRows($contactIDs, $locationTypeID, $respectDoNotMail, // $details is an array of [ contactID => contactDetails ] $tokenFields = CRM_Contact_Form_Task_LabelCommon::getTokenData($details); - foreach ($contactIDs as $value) { + foreach ($contactIDs as $value{contact.primary_) { foreach ($custom as $cfID) { if (isset($details[$value]["custom_{$cfID}"])) { $details[$value]["custom_{$cfID}"] = CRM_Core_BAO_CustomField::displayValue($details[$value]["custom_{$cfID}"], $cfID); diff --git a/CRM/Contact/Tokens.php b/CRM/Contact/Tokens.php index 16da6d691bc6..dd22c6a8613d 100644 --- a/CRM/Contact/Tokens.php +++ b/CRM/Contact/Tokens.php @@ -49,8 +49,7 @@ public static function getSubscribedEvents(): array { * * @param \Civi\Token\Event\TokenRegisterEvent $e * The registration event. Add new tokens using register(). - * - * @throws \CRM_Core_Exception + */ public function registerTokens(TokenRegisterEvent $e): void { if (!$this->checkActive($e->getTokenProcessor())) { @@ -273,7 +272,6 @@ public function onEvaluate(TokenValueEvent $e) { if (empty($messageTokens)) { return; } - $this->fieldMetadata = (array) civicrm_api4('Contact', 'getfields', ['checkPermissions' => FALSE], 'name'); foreach ($e->getRows() as $row) { if (empty($row->context['contactId']) && empty($row->context['contact'])) { @@ -313,8 +311,7 @@ public function onEvaluate(TokenValueEvent $e) { $row->format('text/html')->tokens('contact', $token, html_entity_decode($row->context['contact'][$token])); } else { - $row->format('text/html') - ->tokens('contact', $token, $this->getFieldValue($row, $token)); + parent::evaluateToken($row, $this->entity, $token, $row->context['contact']); } } } @@ -576,6 +573,7 @@ protected function getDeprecatedTokens(): array { 'street_address' => 'primary_address.street_address', 'address_id' => 'primary_address.id', 'street_number' => 'primary_address.street_number', + 'street_number_suffix' => 'primary_address.street_number_suffix', 'street_name' => 'primary_address.street_name', 'street_unit' => 'primary_address.street_unit', 'supplemental_address_1' => 'primary_address.supplemental_address_1', @@ -593,7 +591,7 @@ protected function getDeprecatedTokens(): array { 'world_region' => 'primary_address.country_id.world_region', 'phone_type' => 'primary_phone.phone_type_id:label', 'phone' => 'primary_phone.phone', - 'phone_ext' => 'primary_phone.phone_ext}', + 'phone_ext' => 'primary_phone.phone_ext', 'email' => 'primary_email.email', 'signature_text' => 'primary_email.signature_text', 'signature_html' => 'primary_email.signature_html', diff --git a/CRM/Core/EntityTokens.php b/CRM/Core/EntityTokens.php index ad8583c4b4bf..645df1529a88 100644 --- a/CRM/Core/EntityTokens.php +++ b/CRM/Core/EntityTokens.php @@ -258,7 +258,34 @@ public function isCustomField(string $fieldName) : bool { * @return bool */ public function isMoneyField(string $fieldName): bool { - return $this->getTokenMetadata()[$fieldName]['data_type'] === 'Money'; + $m = $this->getMetadataForField($fieldName); + if (!isset($m['data_type'])) { + $r = 1; + } + return $this->getMetadataForField($fieldName)['data_type'] === 'Money'; + } + + /** + * Get the metadata for the field. + * + * @param string $fieldName + * + * @return array + */ + protected function getMetadataForField($fieldName): array { + if (isset($this->getTokenMetadata()[$fieldName])) { + return $this->getTokenMetadata()[$fieldName]; + } + return $this->getTokenMetadata()[$this->getDeprecatedTokens()[$fieldName]]; + } + + /** + * Get array of deprecated tokens and the new token they map to. + * + * @return array + */ + protected function getDeprecatedTokens(): array { + return []; } /** diff --git a/CRM/Event/Tokens.php b/CRM/Event/Tokens.php index 91d5a8797b4c..b8426556190f 100644 --- a/CRM/Event/Tokens.php +++ b/CRM/Event/Tokens.php @@ -49,6 +49,7 @@ protected function getBespokeTokens(): array { 'type' => 'calculated', 'options' => NULL, 'data_type' => 'String', + 'audience' => 'user', ], 'info_url' => [ 'title' => ts('Event Info URL'), @@ -56,6 +57,7 @@ protected function getBespokeTokens(): array { 'type' => 'calculated', 'options' => NULL, 'data_type' => 'String', + 'audience' => 'user', ], 'registration_url' => [ 'title' => ts('Event Registration URL'), @@ -63,6 +65,7 @@ protected function getBespokeTokens(): array { 'type' => 'calculated', 'options' => NULL, 'data_type' => 'String', + 'audience' => 'user', ], 'contact_email' => [ 'title' => ts('Event Contact Email'), @@ -70,6 +73,7 @@ protected function getBespokeTokens(): array { 'type' => 'calculated', 'options' => NULL, 'data_type' => 'String', + 'audience' => 'user', ], 'contact_phone' => [ 'title' => ts('Event Contact Phone'), @@ -77,6 +81,7 @@ protected function getBespokeTokens(): array { 'type' => 'calculated', 'options' => NULL, 'data_type' => '', + 'audience' => 'user', ], ]; } diff --git a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php index 8e7dc2c0e059..8680c61d06e4 100644 --- a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php +++ b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php @@ -323,7 +323,7 @@ public function testContactTokens(): void { $this->hookClass->setHook('civicrm_tokens', [$this, 'hookTokens']); $this->createCustomGroupWithFieldsOfAllTypes([]); - $tokenData = $this->getAllContactTokens(); + $tokenData = $this->getOldContactTokens(); $address = $this->setupContactFromTokeData($tokenData); $advertisedTokens = CRM_Core_SelectValues::contactTokens(); $this->assertEquals($this->getAdvertisedTokens(), $advertisedTokens); @@ -458,25 +458,34 @@ public function hookTokens(array &$hookTokens): void { */ public function testContactTokensRenderedByTokenProcessor(): void { $this->createCustomGroupWithFieldsOfAllTypes([]); - $tokenData = $this->getAllContactTokens(); + $tokenData = $this->getOldContactTokens(); $address = $this->setupContactFromTokeData($tokenData); $tokenString = ''; foreach (array_keys($tokenData) as $key) { $tokenString .= "{$key}:{contact.{$key}}\n"; } + $newStyleTokenString = ''; + foreach (array_keys($this->getAdvertisedTokens()) as $key) { + $newStyleTokenString .= substr($key, 9, -1) . ' |' . $key . "\n"; + } $tokenProcessor = new TokenProcessor(Civi::dispatcher(), []); $tokenProcessor->addMessage('html', $tokenString, 'text/html'); + $tokenProcessor->addMessage('new', $newStyleTokenString, 'text/html'); + $tokenProcessor->addRow(['contactId' => $tokenData['contact_id']]); $tokenProcessor->evaluate(); $rendered = ''; foreach ($tokenProcessor->getRows() as $row) { $rendered = (string) $row->render('html'); + $newStyleRendered = $row->render('new'); } $expected = $this->getExpectedContactOutput($address['id'], $tokenData, $rendered); // @todo - this works better in token processor than in CRM_Core_Token. // once synced we can fix $this->getExpectedContactOutput to return the right thing. $expected = str_replace("preferred_communication_method:\n", "preferred_communication_method:Phone\n", $expected); $this->assertEquals($expected, $rendered); + $this->assertEquals($this->getExpectedContactOutputNewStyle($address['id'], $tokenData, $newStyleRendered), $newStyleRendered); + } /** @@ -614,7 +623,7 @@ public function getAdvertisedTokens(): array { * @throws \CRM_Core_Exception * @throws \CiviCRM_API3_Exception */ - public function getAllContactTokens(): array { + public function getOldContactTokens(): array { return [ 'contact_type' => 'Individual', 'do_not_email' => 1, @@ -666,7 +675,6 @@ public function getAllContactTokens(): array { 'postal_code' => '90210', 'geo_code_1' => '48.858093', 'geo_code_2' => '2.294694', - 'manual_geo_code' => TRUE, 'address_name' => 'The white house', 'master_id' => $this->callAPISuccess('Address', 'create', [ 'contact_id' => $this->individualCreate(), @@ -807,7 +815,6 @@ protected function getExpectedContactOutput($id, array $tokenData, string $actua postal_code:90210 geo_code_1:48.858093 geo_code_2:2.294694 -manual_geo_code:1 address_name:The white house master_id:' . $tokenData['master_id'] . ' county: @@ -841,6 +848,106 @@ protected function getExpectedContactOutput($id, array $tokenData, string $actua custom_13:Purple checksum:cs=' . $checksum . ' contact_id:' . $tokenData['contact_id'] . ' +'; + return $expected; + } + + /** + * Get the expected rendered string. + * + * @param int $id + * @param array $tokenData + * @param string $actualOutput + * + * @return string + * @throws \API_Exception + */ + protected function getExpectedContactOutputNewStyle($id, array $tokenData, string $actualOutput): string { + $checksum = substr($actualOutput, (strpos($actualOutput, 'cs=') + 3), 47); + $contact = Contact::get(FALSE)->addWhere('id', '=', $tokenData['contact_id'])->setSelect(['modified_date', 'employer_id'])->execute()->first(); + $expected = 'contact_type:label |Individual +do_not_email:label |No +do_not_phone:label |No +do_not_mail:label |Yes +do_not_sms:label |Yes +do_not_trade:label |Yes +is_opt_out:label |Yes +external_identifier |blah +sort_name |Smith, Robert +display_name |Mr. Robert Smith II +nick_name |Bob +image_URL |https://example.com +preferred_communication_method:label |Phone +preferred_language |fr_CA +preferred_mail_format:label |Both +hash |xyz +source |Contact Source +first_name |Robert +middle_name |Frank +last_name |Smith +prefix_id:label |Mr. +suffix_id:label |II +formal_title |Dogsbody +communication_style_id:label |Formal +job_title |Busy person +gender_id:label |Female +birth_date |December 31st, 1998 +employer_id |' . $contact['employer_id'] . ' +is_deleted | +created_date |January 1st, 2020 12:00 AM +modified_date |' . CRM_Utils_Date::customFormat($contact['modified_date']) . ' +addressee_display |Mr. Robert Frank Smith II +email_greeting_display |Dear Robert +postal_greeting_display |Dear Robert +employer_id.display_name |Unit Test Organization +primary_address.location_type_id:label |Home +primary_address.id |' . $id . ' +primary_address.street_address |Street Address +primary_address.street_number |123 +primary_address.street_number_suffix |S +primary_address.street_name |Main St +primary_address.street_unit |45B +primary_address.supplemental_address_1 |Round the corner +primary_address.supplemental_address_2 |Up the road +primary_address.supplemental_address_3 |By the big tree +primary_address.city |New York +primary_address.postal_code_suffix |4578 +primary_address.postal_code |90210 +primary_address.geo_code_1 |48.858093 +primary_address.geo_code_2 |2.294694 +primary_address.name |The white house +primary_address.master_id |' . $tokenData['master_id'] . ' +primary_address.county_id:label | +primary_address.state_province_id:label |TX +primary_address.country_id:label |United States +primary_phone.phone |123-456 +primary_phone.phone_ext |77 +primary_phone.phone_type_id |2 +primary_phone.phone_type_id:label |Mobile +primary_email.email |anthony_anderson@civicrm.org +primary_email.on_hold | +primary_email.signature_text |Yours sincerely +primary_email.signature_html |

Yours

+primary_im.provider_id |1 +primary_im.name |IM Screen Name +primary_OpenID |OpenID +primary_address.world_region |America South, Central, North and Caribbean +primary_website.url |http://civicrm.org +custom_9 |Mr. Spider Man II +custom_7 |New Zealand +custom_8 |France, Canada +custom_1 |Bobsled +custom_2 |Red +custom_3 |01/20/2021 12 |00AM +custom_4 |999 +custom_5 |http://civicrm.org +custom_6 | +custom_10 |Queensland +custom_11 |Victoria, New South Wales +custom_12 |Yes +custom_13 |Purple +checksum |cs=' . $checksum . ' +id |' . $tokenData['contact_id'] . ' '; return $expected; }