Skip to content

Commit

Permalink
Merge pull request #21506 from eileenmcnaughton/member_tokens
Browse files Browse the repository at this point in the history
dev/core#2832 Extend Membership tokens to 'listen' and add test cover
  • Loading branch information
colemanw authored Sep 17, 2021
2 parents 5631965 + d568dbe commit 0736bf3
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 32 deletions.
32 changes: 31 additions & 1 deletion CRM/Core/EntityTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,38 @@ public function getCurrency($row): string {
return CRM_Core_Config::singleton()->defaultCurrency;
}

/**
* Get the fields required to prefetch the entity.
*
* @param \Civi\Token\Event\TokenValueEvent $e
*
* @return array
* @throws \API_Exception
*/
public function getPrefetchFields(TokenValueEvent $e): array {
return array_intersect(array_merge($this->getActiveTokens($e), $this->getCurrencyFieldName(), ['id']), array_keys($this->getAllTokens()));
$allTokens = array_keys($this->getAllTokens());
$requiredFields = array_intersect($this->getActiveTokens($e), $allTokens);
if (empty($requiredFields)) {
return [];
}
$requiredFields = array_merge($requiredFields, array_intersect($allTokens, array_merge(['id'], $this->getCurrencyFieldName())));
foreach ($this->getDependencies() as $field => $required) {
if (in_array($field, $this->getActiveTokens($e), TRUE)) {
foreach ((array) $required as $key) {
$requiredFields[] = $key;
}
}
}
return $requiredFields;
}

/**
* Get fields which need to be returned to render another token.
*
* @return array
*/
public function getDependencies(): array {
return [];
}

}
4 changes: 2 additions & 2 deletions CRM/Member/BAO/MembershipType.php
Original file line number Diff line number Diff line change
Expand Up @@ -818,8 +818,8 @@ public static function updateAllPriceFieldValue($membershipTypeId, $params) {
* List of membershipType details keyed by membershipTypeID
* @throws \CiviCRM_API3_Exception
*/
public static function getAllMembershipTypes() {
$cacheString = __CLASS__ . __FUNCTION__ . CRM_Core_Config::domainID();
public static function getAllMembershipTypes(): array {
$cacheString = __CLASS__ . __FUNCTION__ . CRM_Core_Config::domainID() . '_' . CRM_Core_I18n::getLocale();
if (!Civi::cache('metadata')->has($cacheString)) {
$types = civicrm_api3('MembershipType', 'get', ['options' => ['limit' => 0, 'sort' => 'weight']])['values'];
$taxRates = CRM_Core_PseudoConstant::getTaxRates();
Expand Down
37 changes: 12 additions & 25 deletions CRM/Member/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,38 +55,25 @@ public function getAllTokens(): array {

/**
* @inheritDoc
*/
public function checkActive(\Civi\Token\TokenProcessor $processor) {
// Extracted from scheduled-reminders code. See the class description.
return !empty($processor->context['actionMapping'])
&& $processor->context['actionMapping']->getEntity() === 'civicrm_membership';
}

/**
* Alter action schedule query.
*
* @param \Civi\ActionSchedule\Event\MailingQueryEvent $e
*/
public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQueryEvent $e): void {
if ($e->mapping->getEntity() !== 'civicrm_membership') {
return;
}
parent::alterActionScheduleQuery($e);
$e->query
->select('mt.minimum_fee as ' . $this->getEntityAlias() . 'fee')
->join('mt', '!casMailingJoinType civicrm_membership_type mt ON e.membership_type_id = mt.id');
}

/**
* @inheritDoc
* @throws \CiviCRM_API3_Exception
*/
public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) {
if ($field === 'fee') {
$row->tokens($entity, $field, \CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($this->getFieldValue($row, $field)));
$membershipType = CRM_Member_BAO_MembershipType::getMembershipType($this->getFieldValue($row, 'membership_type_id'));
$row->tokens($entity, $field, \CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($membershipType['minimum_fee']));
}
else {
parent::evaluateToken($row, $entity, $field, $prefetch);
}
}

/**
* Get fields which need to be returned to render another token.
*
* @return array
*/
public function getDependencies(): array {
return ['fee' => 'membership_type_id'];
}

}
26 changes: 22 additions & 4 deletions tests/phpunit/CRM/Utils/TokenConsistencyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ class CRM_Utils_TokenConsistencyTest extends CiviUnitTestCase {
* @throws \CRM_Core_Exception
*/
public function tearDown(): void {
$this->quickCleanup(['civicrm_case', 'civicrm_case_type']);
$this->quickCleanup(['civicrm_case', 'civicrm_case_type'], TRUE);
parent::tearDown();
}

/**
* Test that case tokens are consistently rendered.
*
* @throws \API_Exception
* @throws \CiviCRM_API3_Exception
*/
public function testCaseTokenConsistency(): void {
Expand Down Expand Up @@ -367,7 +366,8 @@ public function testMembershipTokenConsistency(): void {
$this->restoreMembershipTypes();
$this->createCustomGroupWithFieldOfType(['extends' => 'Membership']);
$tokens = CRM_Core_SelectValues::membershipTokens();
$this->assertEquals($this->getMembershipTokens(), $tokens);
$expectedTokens = $this->getMembershipTokens();
$this->assertEquals($expectedTokens, $tokens);
$newStyleTokens = "\n{membership.status_id:label}\n{membership.membership_type_id:label}\n";
$tokenString = $newStyleTokens . implode("\n", array_keys($this->getMembershipTokens()));

Expand All @@ -393,7 +393,25 @@ public function testMembershipTokenConsistency(): void {
'body_html' => $tokenString,
]);
$this->callAPISuccess('job', 'send_reminder', []);
$mut->checkMailLog([$this->getExpectedMembershipTokenOutput() . "\nmy field"]);
$expected = $this->getExpectedMembershipTokenOutput();
// Unlike the legacy method custom fields are resolved by the processor.
$expected .= "\nmy field";
$mut->checkMailLog([$expected]);

$tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [
'controller' => __CLASS__,
'smarty' => FALSE,
'schema' => ['membershipId'],
]);
$tokens = $tokenProcessor->listTokens();
// Add in custom tokens as token processor supports these.
$expectedTokens['{membership.custom_1}'] = 'Enter text here :: Group with field text';
$this->assertEquals($expectedTokens, $tokens);
$tokenProcessor->addMessage('html', $tokenString, 'text/plain');
$tokenProcessor->addRow(['membershipId' => $this->getMembershipID()]);
$tokenProcessor->evaluate();
$this->assertEquals($expected, $tokenProcessor->getRow(0)->render('html'));

}

/**
Expand Down

0 comments on commit 0736bf3

Please sign in to comment.