X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=tests%2Fphpunit%2FCRM%2FUtils%2FTokenConsistencyTest.php;h=7e7f00c1f14beb690744372264e0320914d4d179;hb=d49e8eec43de89b0acef94e8c0fb5ef05507be23;hp=b1c36e62aa2ead14b1d116d34f75325298476d9f;hpb=07f3305395d6c5ba1830e9558cd547fd43c6fe20;p=civicrm-core.git diff --git a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php index b1c36e62aa..7e7f00c1f1 100644 --- a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php +++ b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php @@ -44,12 +44,9 @@ class CRM_Utils_TokenConsistencyTest extends CiviUnitTestCase { /** * Post test cleanup. - * - * @throws \API_Exception - * @throws \CRM_Core_Exception */ public function tearDown(): void { - $this->quickCleanup(['civicrm_case', 'civicrm_case_type'], TRUE); + $this->quickCleanup(['civicrm_case', 'civicrm_case_type', 'civicrm_participant', 'civicrm_event'], TRUE); parent::tearDown(); } @@ -65,7 +62,7 @@ class CRM_Utils_TokenConsistencyTest extends CiviUnitTestCase { $tokens = CRM_Core_SelectValues::caseTokens(); $this->assertEquals($this->getCaseTokens(), $tokens); $caseID = $this->getCaseID(); - $tokenString = implode("\n", array_keys($this->getCaseTokens())); + $tokenString = $this->getTokenString(array_keys($this->getCaseTokens())); $tokenHtml = CRM_Utils_Token::replaceCaseTokens($caseID, $tokenString, ['case' => $this->getCaseTokenKeys()]); $this->assertEquals($this->getExpectedCaseTokenOutput(), $tokenHtml); // Now do the same without passing in 'knownTokens' @@ -75,21 +72,12 @@ class CRM_Utils_TokenConsistencyTest extends CiviUnitTestCase { // And check our deprecated tokens still work. $tokenHtml = CRM_Utils_Token::replaceCaseTokens($caseID, '{case.case_type_id} {case.status_id}'); $this->assertEquals('Housing Support Ongoing', $tokenHtml); - - $additionalTokensFromProcessor = [ - '{case.case_type_id}' => 'Case Type ID', - '{case.status_id}' => 'Case Status', - '{case.case_type_id:name}' => 'Machine name: Case Type', - '{case.status_id:name}' => 'Machine name: Case Status', - ]; - $expectedTokens = array_merge($this->getCaseTokens(), $additionalTokensFromProcessor); - $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ 'controller' => __CLASS__, 'smarty' => FALSE, 'schema' => ['caseId'], ]); - $this->assertEquals(array_merge($expectedTokens, $this->getDomainTokens()), $tokenProcessor->listTokens()); + $this->assertEquals(array_merge($this->getCaseTokens(), $this->getDomainTokens()), $tokenProcessor->listTokens()); $tokenProcessor->addRow([ 'caseId' => $this->getCaseID(), ]); @@ -108,16 +96,17 @@ class CRM_Utils_TokenConsistencyTest extends CiviUnitTestCase { * @return string */ protected function getExpectedCaseTokenOutput(): string { - return '1 -Housing Support -Case Subject -July 23rd, 2021 -July 26th, 2021 -case details -Ongoing -No -' . CRM_Utils_Date::customFormat($this->case['created_date']) . ' -' . CRM_Utils_Date::customFormat($this->case['modified_date']) . ' + return 'case.id :1 +case.case_type_id:label :Housing Support +case.subject :Case Subject +case.start_date :July 23rd, 2021 +case.end_date :July 26th, 2021 +case.details :case details +case.status_id:label :Ongoing +case.is_deleted:label :No +case.created_date :' . CRM_Utils_Date::customFormat($this->case['created_date']) . ' +case.modified_date :' . CRM_Utils_Date::customFormat($this->case['modified_date']) . ' +case.custom_1 :' . ' '; } @@ -207,8 +196,9 @@ No 'smarty' => FALSE, 'schema' => ['contribution_recurId'], ]); - $this->assertEquals(array_merge($this->getContributionRecurTokens(), $this->getDomainTokens()), $tokenProcessor->listTokens()); - $tokenString = implode("\n", array_keys($this->getContributionRecurTokens())); + $expectedTokens = array_merge($this->getContributionRecurTokens(), $this->getDomainTokens()); + $this->assertEquals(array_diff_key($expectedTokens, $this->getUnadvertisedTokens()), $tokenProcessor->listTokens()); + $tokenString = $this->getTokenString(array_keys($this->getContributionRecurTokens())); $tokenProcessor->addMessage('html', $tokenString, 'text/plain'); $tokenProcessor->addRow(['contribution_recurId' => $this->getContributionRecurID()]); @@ -216,6 +206,73 @@ No $this->assertEquals($this->getExpectedContributionRecurTokenOutPut(), $tokenProcessor->getRow(0)->render('html')); } + /** + * Get tokens that are not advertised via listTokens. + * + * @return string[] + */ + public function getUnadvertisedTokens(): array { + return [ + '{membership.status_id}' => 'Status ID', + '{membership.membership_type_id}' => 'Membership Type ID', + '{membership.status_id:name}' => 'Machine name: Status', + '{membership.membership_type_id:name}' => 'Machine name: Membership Type', + '{contribution_recur.frequency_unit}' => 'Frequency Unit', + '{contribution_recur.contribution_status_id}' => 'Status', + '{contribution_recur.payment_processor_id}' => 'Payment Processor ID', + '{contribution_recur.financial_type_id}' => 'Financial Type ID', + '{contribution_recur.payment_instrument_id}' => 'Payment Method', + '{contribution_recur.frequency_unit:name}' => 'Machine name: Frequency Unit', + '{contribution_recur.payment_instrument_id:name}' => 'Machine name: Payment Method', + '{contribution_recur.contribution_status_id:name}' => 'Machine name: Status', + '{contribution_recur.payment_processor_id:name}' => 'Machine name: Payment Processor', + '{contribution_recur.financial_type_id:name}' => 'Machine name: Financial Type', + '{participant.status_id:name}' => 'Machine name: Status', + '{participant.role_id:name}' => 'Machine name: Participant Role', + '{participant.status_id}' => 'Status ID', + '{participant.role_id}' => 'Participant Role ID', + ]; + } + + /** + * Test tokens in 2 ways to ensure consistent handling. + * + * 1) as part of the greeting processing + * 2) via the token processor. + * + */ + public function testOddTokens(): void { + + $variants = [ + [ + 'string' => '{contact.individual_prefix}{ }{contact.first_name}{ }{contact.middle_name}{ }{contact.last_name}{ }{contact.individual_suffix}', + 'expected' => 'Mr. Anthony Anderson II', + ], + [ + 'string' => '{contact.prefix_id:label}{ }{contact.first_name}{ }{contact.middle_name}{ }{contact.last_name}{ }{contact.suffix_id:label}', + 'expected' => 'Mr. Anthony Anderson II', + ], + ]; + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ + 'smarty' => FALSE, + 'schema' => ['contactId'], + ]); + $contactID = $this->individualCreate(['middle_name' => '']); + $tokenProcessor->addRow(['contactId' => $contactID]); + $tokenProcessor->evaluate(); + foreach ($variants as $index => $variant) { + $tokenProcessor->addMessage($index, $variant['string'], 'text/plain'); + } + $tokenProcessor->evaluate(); + $result = $tokenProcessor->getRow(0); + foreach ($variants as $index => $variant) { + $greetingString = $variant['string']; + CRM_Utils_Token::replaceGreetingTokens($greetingString, $this->callAPISuccessGetSingle('Contact', ['id' => $contactID]), $contactID); + $this->assertEquals($variant['expected'], $greetingString); + $this->assertEquals($variant['expected'], $result->render($index)); + } + } + /** * Get the contribution recur tokens keyed by the token. * @@ -288,6 +345,7 @@ No 'start_date' => '2021-07-23 15:39:20', 'end_date' => '2021-07-26 18:07:20', 'cancel_date' => '2021-08-19 09:12:45', + 'next_sched_contribution_date' => '2021-09-08', 'cancel_reason' => 'Because', 'amount' => 5990.99, 'currency' => 'EUR', @@ -321,43 +379,45 @@ No * @return string */ protected function getExpectedContributionRecurTokenOutPut(): string { - return $this->getContributionRecurID() . ' -€ 5,990.99 -EUR -year -2 -24 -July 23rd, 2021 3:39 PM -' . CRM_Utils_Date::customFormat($this->contributionRecur['create_date']) . ' -' . CRM_Utils_Date::customFormat($this->contributionRecur['modified_date']) . ' -August 19th, 2021 9:12 AM -Because -July 26th, 2021 6:07 PM -abc -1 -123 -inv123 -2 -Yes -15 - -0 -January 3rd, 2020 12:00 AM -Yes -1 -2 -4 -Yes -year -year -Pending Label** -Pending -Dummy (test) -Dummy (test) -Member Dues -Member Dues -Check -Check'; + return 'contribution_recur.id :' . $this->getContributionRecurID() . ' +contribution_recur.amount :€ 5,990.99 +contribution_recur.currency :EUR +contribution_recur.frequency_unit :year +contribution_recur.frequency_interval :2 +contribution_recur.installments :24 +contribution_recur.start_date :July 23rd, 2021 3:39 PM +contribution_recur.create_date :' . CRM_Utils_Date::customFormat($this->contributionRecur['create_date']) . ' +contribution_recur.modified_date :' . CRM_Utils_Date::customFormat($this->contributionRecur['modified_date']) . ' +contribution_recur.cancel_date :August 19th, 2021 9:12 AM +contribution_recur.cancel_reason :Because +contribution_recur.end_date :July 26th, 2021 6:07 PM +contribution_recur.processor_id :abc +contribution_recur.payment_token_id :1 +contribution_recur.trxn_id :123 +contribution_recur.invoice_id :inv123 +contribution_recur.contribution_status_id :2 +contribution_recur.is_test:label :Yes +contribution_recur.cycle_day :15 +contribution_recur.next_sched_contribution_date :September 8th, 2021 +contribution_recur.failure_count :0 +contribution_recur.failure_retry_date :January 3rd, 2020 +contribution_recur.auto_renew:label :Yes +contribution_recur.payment_processor_id :1 +contribution_recur.financial_type_id :2 +contribution_recur.payment_instrument_id :4 +contribution_recur.is_email_receipt:label :Yes +contribution_recur.frequency_unit:label :year +contribution_recur.frequency_unit:name :year +contribution_recur.contribution_status_id:label :Pending Label** +contribution_recur.contribution_status_id:name :Pending +contribution_recur.payment_processor_id:label :Dummy (test) +contribution_recur.payment_processor_id:name :Dummy (test) +contribution_recur.financial_type_id:label :Member Dues +contribution_recur.financial_type_id:name :Member Dues +contribution_recur.payment_instrument_id:label :Check +contribution_recur.payment_instrument_id:name :Check +'; + } /** @@ -409,7 +469,7 @@ Check'; ]); $tokens = $tokenProcessor->listTokens(); // Add in custom tokens as token processor supports these. - $expectedTokens['{membership.custom_1}'] = 'Enter text here :: Group with field text'; + $expectedTokens = array_merge($expectedTokens, $this->getTokensAdvertisedByTokenProcessorButNotLegacy()); $this->assertEquals(array_merge($expectedTokens, $this->getDomainTokens()), $tokens); $tokenProcessor->addMessage('html', $tokenString, 'text/plain'); $tokenProcessor->addRow(['membershipId' => $this->getMembershipID()]); @@ -418,6 +478,19 @@ Check'; } + /** + * Get the advertised tokens the legacy function doesn't know about. + * + * @return string[] + */ + public function getTokensAdvertisedByTokenProcessorButNotLegacy(): array { + return [ + '{membership.custom_1}' => 'Enter text here :: Group with field text', + '{membership.source}' => 'Source', + '{membership.status_override_end_date}' => 'Status Override End Date', + ]; + } + /** * Get declared membership tokens. * @@ -426,11 +499,11 @@ Check'; public function getMembershipTokens(): array { return [ '{membership.id}' => 'Membership ID', - '{membership.status_id:label}' => 'Membership Status', + '{membership.status_id:label}' => 'Status', '{membership.membership_type_id:label}' => 'Membership Type', '{membership.start_date}' => 'Membership Start Date', - '{membership.join_date}' => 'Membership Join Date', - '{membership.end_date}' => 'Membership End Date', + '{membership.join_date}' => 'Member Since', + '{membership.end_date}' => 'Membership Expiration Date', '{membership.fee}' => 'Membership Fee', ]; } @@ -450,30 +523,56 @@ Check'; return $this->ids['Membership'][0]; } + /** + * Get expected output from token parsing. + * + * @return string + */ + protected function getExpectedParticipantTokenOutput(): string { + return 'participant.status_id :2 +participant.role_id :1 +participant.register_date :February 19th, 2007 +participant.source :Wimbeldon +participant.fee_level :steep +participant.fee_amount :$ 50.00 +participant.registered_by_id : +participant.transferred_to_contact_id : +participant.role_id:label :Attendee +participant.balance : +participant.custom_2 :99999 +participant.id :2 +participant.fee_currency :USD +participant.discount_amount : +participant.status_id:label :Attended +participant.status_id:name :Attended +participant.role_id:name :Attendee +participant.is_test:label :No +participant.must_wait : +'; + } + /** * Get expected output from token parsing. * * @return string */ protected function getExpectedEventTokenOutput(): string { - return ' -1 -Annual CiviCRM meet -October 21st, 2008 12:00 AM -October 23rd, 2008 12:00 AM -Conference -If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now -event@example.com -456 789 -event description -15 Walton St + return 'event.id :' . $this->ids['event'][0] . ' +event.title :Annual CiviCRM meet +event.start_date :October 21st, 2008 +event.end_date :October 23rd, 2008 +event.event_type_id:label :Conference +event.summary :If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now +event.contact_email :event@example.com +event.contact_phone :456 789 +event.description :event description +event.location :15 Walton St Emerald City, Maine 90210 -$ 50.00 -' . CRM_Utils_System::url('civicrm/event/info', NULL, TRUE) . '&reset=1&id=1 -' . CRM_Utils_System::url('civicrm/event/register', NULL, TRUE) . '&reset=1&id=1 - -my field'; +event.info_url :' . CRM_Utils_System::url('civicrm/event/info', NULL, TRUE) . '&reset=1&id=1 +event.registration_url :' . CRM_Utils_System::url('civicrm/event/register', NULL, TRUE) . '&reset=1&id=1 +event.custom_1 :my field +'; } /** @@ -501,9 +600,47 @@ December 21st, 2007 */ public function testParticipantTokenConsistency(): void { $this->createLoggedInUser(); - $this->createCustomGroupWithFieldOfType(['extends' => 'Participant']); + $this->setupParticipantScheduledReminder(); + $tokens = CRM_Core_SelectValues::participantTokens(); - $this->assertEquals($this->getParticipantTokens(), $tokens); + $this->assertEquals(array_diff_key($this->getParticipantTokens(), $this->getUnadvertisedTokens()), $tokens); + + $mut = new CiviMailUtils($this); + + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ + 'controller' => __CLASS__, + 'smarty' => FALSE, + 'schema' => ['participantId'], + ]); + $this->assertEquals(array_merge($tokens, $this->getDomainTokens()), $tokenProcessor->listTokens()); + + $this->callAPISuccess('job', 'send_reminder', []); + $expected = $this->getExpectedParticipantTokenOutput(); + $mut->checkMailLog([$expected]); + + $tokenProcessor->addMessage('html', $this->getTokenString(array_keys($this->getParticipantTokens())), 'text/plain'); + $tokenProcessor->addRow(['participantId' => $this->ids['participant'][0]]); + $tokenProcessor->evaluate(); + $this->assertEquals($expected, $tokenProcessor->getRow(0)->render('html')); + + } + + /** + * Test that membership tokens are consistently rendered. + * + * @throws \API_Exception + * @throws \CRM_Core_Exception + */ + public function testParticipantCustomDateToken(): void { + $this->createEventAndParticipant(); + $dateFieldID = $this->createDateCustomField(['custom_group_id' => $this->ids['CustomGroup']['participant_'], 'default_value' => ''])['id']; + $input = '{participant.custom_' . $dateFieldID . '}'; + $input .= '{participant.' . $this->getCustomFieldName('participant_int') . '}'; + $tokenHtml = CRM_Core_BAO_MessageTemplate::renderTemplate([ + 'messageTemplate' => ['msg_html' => $input], + 'tokenContext' => array_merge(['participantId' => $this->ids['participant'][0]], ['schema' => ['participantId', 'eventId']]), + ])['html']; + $this->assertEquals(99999, $tokenHtml); } /** @@ -514,16 +651,24 @@ December 21st, 2007 public function getParticipantTokens(): array { return [ '{participant.status_id}' => 'Status ID', - '{participant.role_id}' => 'Participant Role (ID)', + '{participant.role_id}' => 'Participant Role ID', '{participant.register_date}' => 'Register date', '{participant.source}' => 'Participant Source', '{participant.fee_level}' => 'Fee level', '{participant.fee_amount}' => 'Fee Amount', '{participant.registered_by_id}' => 'Registered By Participant ID', '{participant.transferred_to_contact_id}' => 'Transferred to Contact ID', - '{participant.role_id:label}' => 'Participant Role (label)', - '{participant.fee_label}' => 'Fee Label', - '{participant.' . $this->getCustomFieldName('text') . '}' => 'Enter text here :: Group with field text', + '{participant.role_id:label}' => 'Participant Role', + '{participant.balance}' => 'Event Balance', + '{participant.' . $this->getCustomFieldName('participant_int') . '}' => 'Enter integer here :: participant_Group with field int', + '{participant.id}' => 'Participant ID', + '{participant.fee_currency}' => 'Fee Currency', + '{participant.discount_amount}' => 'Discount Amount', + '{participant.status_id:label}' => 'Status', + '{participant.status_id:name}' => 'Machine name: Status', + '{participant.role_id:name}' => 'Machine name: Participant Role', + '{participant.is_test:label}' => 'Test', + '{participant.must_wait}' => 'Must Wait on List', ]; } @@ -539,9 +684,50 @@ December 21st, 2007 ]); $tokens['{domain.id}'] = 'Domain ID'; $tokens['{domain.description}'] = 'Domain Description'; + $tokens['{domain.now}'] = 'Current time/date'; $this->assertEquals($tokens, $tokenProcessor->listTokens()); } + /** + * @throws \API_Exception + * @throws \CRM_Core_Exception + */ + public function testDomainNow(): void { + putenv('TIME_FUNC=frozen'); + CRM_Utils_Time::setTime('2021-09-18 23:58:00'); + $modifiers = [ + 'shortdate' => '09/18/2021', + '%B %Y' => 'September 2021', + ]; + foreach ($modifiers as $filter => $expected) { + $resolved = CRM_Core_BAO_MessageTemplate::renderTemplate([ + 'messageTemplate' => [ + 'msg_text' => '{domain.now|crmDate:"' . $filter . '"}', + ], + ])['text']; + $this->assertEquals($expected, $resolved); + } + $resolved = CRM_Core_BAO_MessageTemplate::renderTemplate([ + 'messageTemplate' => [ + 'msg_text' => '{domain.now}', + ], + ])['text']; + $this->assertEquals('September 18th, 2021 11:58 PM', $resolved); + + // This example is malformed - no quotes + try { + $resolved = CRM_Core_BAO_MessageTemplate::renderTemplate([ + 'messageTemplate' => [ + 'msg_text' => '{domain.now|crmDate:shortdate}', + ], + ])['text']; + $this->fail('Expected unquoted parameter to fail'); + } + catch (\CRM_Core_Exception $e) { + $this->assertRegExp(';Malformed token param;', $e->getMessage()); + } + } + /** * Get declared participant tokens. * @@ -555,18 +741,21 @@ December 21st, 2007 '{domain.email}' => 'Domain (organization) email', '{domain.id}' => ts('Domain ID'), '{domain.description}' => ts('Domain Description'), + '{domain.now}' => 'Current time/date', ]; } /** - * Test that domain tokens are consistently rendered. + * Test that event tokens are consistently rendered. + * + * @throws \API_Exception */ public function testEventTokenConsistency(): void { $mut = new CiviMailUtils($this); $this->setupParticipantScheduledReminder(); $tokens = CRM_Core_SelectValues::eventTokens(); - $this->assertEquals($this->getEventTokens(), $tokens); + $this->assertEquals(array_merge($this->getEventTokens()), $tokens); $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ 'controller' => __CLASS__, 'smarty' => FALSE, @@ -574,44 +763,64 @@ December 21st, 2007 ]); $this->assertEquals(array_merge($tokens, $this->getDomainTokens()), $tokenProcessor->listTokens()); + $expectedEventString = $this->getExpectedEventTokenOutput(); $this->callAPISuccess('job', 'send_reminder', []); - $expected = $this->getExpectedEventTokenOutput(); - $mut->checkMailLog([$expected]); + $expectedParticipantString = $this->getExpectedParticipantTokenOutput(); + $toCheck = array_merge(explode("\n", $expectedEventString), explode("\n", $expectedParticipantString)); + $toCheck[] = $expectedEventString; + $toCheck[] = $expectedParticipantString; + $mut->checkMailLog($toCheck); + $tokens = array_keys($this->getEventTokens()); + $html = $this->getTokenString($tokens); + $tokenProcessor->addMessage('html', $html, 'text/plain'); + $tokenProcessor->addRow(['eventId' => $this->ids['event'][0]]); + $tokenProcessor->evaluate(); + $this->assertEquals($expectedEventString, $tokenProcessor->getRow(0)->render('html')); } /** - * Set up scheduled reminder for participants. + * Test that event tokens work absent participant tokens. * * @throws \API_Exception */ - public function setupParticipantScheduledReminder(): void { - $this->createCustomGroupWithFieldOfType(['extends' => 'Event']); - $emailID = Email::create()->setValues(['email' => 'event@example.com'])->execute()->first()['id']; - $addressID = Address::create()->setValues([ - 'street_address' => '15 Walton St', - 'supplemental_address_1' => 'up the road', - 'city' => 'Emerald City', - 'state_province_id:label' => 'Maine', - 'postal_code' => 90210, - ])->execute()->first()['id']; - $phoneID = Phone::create()->setValues(['phone' => '456 789'])->execute()->first()['id']; + public function testEventTokenConsistencyNoParticipantTokens(): void { + $mut = new CiviMailUtils($this); + $this->setupParticipantScheduledReminder(FALSE); - $locationBlockID = LocBlock::save(FALSE)->setRecords([ - [ - 'email_id' => $emailID, - 'address_id' => $addressID, - 'phone_id' => $phoneID, - ], - ])->execute()->first()['id']; - $event = $this->eventCreate([ - 'description' => 'event description', - $this->getCustomFieldName('text') => 'my field', - 'loc_block_id' => $locationBlockID, + $this->callAPISuccess('job', 'send_reminder', []); + $expected = $this->getExpectedEventTokenOutput(); + // Checking these individually is easier to decipher discrepancies + // but we also want to check in entirety. + $toCheck = explode("\n", $expected); + $toCheck[] = $expected; + $mut->checkMailLog($toCheck); + + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ + 'controller' => __CLASS__, + 'smarty' => FALSE, + 'schema' => ['eventId'], ]); - // Create an unrelated participant record so that the ids don't match. - // this prevents things working just because the id 'happens to be valid' - $this->participantCreate(['register_date' => '2020-01-01', 'event_id' => $event['id']]); - $this->participantCreate(['event_id' => $event['id'], 'fee_amount' => 50]); + $html = $this->getTokenString(array_keys($this->getEventTokens())); + + $tokenProcessor->addMessage('html', $html, 'text/plain'); + $tokenProcessor->addRow(['eventId' => $this->ids['event'][0]]); + $tokenProcessor->evaluate(); + $this->assertEquals($expected, $tokenProcessor->getRow(0)->render('html')); + + } + + /** + * Set up scheduled reminder for participants. + * + * @throws \API_Exception + */ + public function setupParticipantScheduledReminder($includeParticipant = TRUE): void { + $this->createEventAndParticipant(); + $tokens = array_keys($this->getEventTokens()); + if ($includeParticipant) { + $tokens = array_keys(array_merge($this->getEventTokens(), $this->getParticipantTokens())); + } + $html = $this->getTokenString($tokens); CRM_Utils_Time::setTime('2007-02-20 15:00:00'); $this->callAPISuccess('action_schedule', 'create', [ 'title' => 'job', @@ -622,7 +831,7 @@ December 21st, 2007 'start_action_offset' => 1, 'start_action_condition' => 'after', 'start_action_unit' => 'day', - 'body_html' => implode("\n", array_keys($this->getEventTokens())), + 'body_html' => $html, ]); } @@ -633,22 +842,83 @@ December 21st, 2007 */ protected function getEventTokens(): array { return [ - '{event.event_id}' => 'Event ID', + '{event.id}' => 'Event ID', '{event.title}' => 'Event Title', '{event.start_date}' => 'Event Start Date', '{event.end_date}' => 'Event End Date', - '{event.event_type}' => 'Event Type', + '{event.event_type_id:label}' => 'Event Type', '{event.summary}' => 'Event Summary', '{event.contact_email}' => 'Event Contact Email', '{event.contact_phone}' => 'Event Contact Phone', '{event.description}' => 'Event Description', '{event.location}' => 'Event Location', - '{event.fee_amount}' => 'Event Fee', '{event.info_url}' => 'Event Info URL', '{event.registration_url}' => 'Event Registration URL', - '{event.balance}' => 'Event Balance', '{event.' . $this->getCustomFieldName('text') . '}' => 'Enter text here :: Group with field text', ]; } + /** + * @param array $tokens + * + * @return string + */ + protected function getTokenString(array $tokens): string { + $html = ''; + foreach ($tokens as $token) { + $html .= substr($token, 1, -1) . ' :' . $token . "\n"; + } + return $html; + } + + /** + * Create an event with a participant. + * + * @throws \API_Exception + */ + protected function createEventAndParticipant(): void { + $this->createCustomGroupWithFieldOfType(['extends' => 'Event']); + $this->createCustomGroupWithFieldOfType(['extends' => 'Participant'], 'int', 'participant_'); + $emailID = Email::create() + ->setValues(['email' => 'event@example.com']) + ->execute() + ->first()['id']; + $addressID = Address::create()->setValues([ + 'street_address' => '15 Walton St', + 'supplemental_address_1' => 'up the road', + 'city' => 'Emerald City', + 'state_province_id:label' => 'Maine', + 'postal_code' => 90210, + ])->execute()->first()['id']; + $phoneID = Phone::create() + ->setValues(['phone' => '456 789']) + ->execute() + ->first()['id']; + + $locationBlockID = LocBlock::save(FALSE)->setRecords([ + [ + 'email_id' => $emailID, + 'address_id' => $addressID, + 'phone_id' => $phoneID, + ], + ])->execute()->first()['id']; + $this->ids['event'][0] = $this->eventCreate([ + 'description' => 'event description', + $this->getCustomFieldName('text') => 'my field', + 'loc_block_id' => $locationBlockID, + ])['id']; + // Create an unrelated participant record so that the ids don't match. + // this prevents things working just because the id 'happens to be valid' + $this->participantCreate([ + 'register_date' => '2020-01-01', + 'event_id' => $this->ids['event'][0], + ]); + $this->ids['participant'][0] = $this->participantCreate([ + 'event_id' => $this->ids['event'][0], + 'fee_amount' => 50, + 'fee_level' => 'steep', + $this->getCustomFieldName('participant_int') => '99999', + ]); + } + }