-
-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dev/core#2747 - Reconcile fields. Consolidate/simplify loading of APIv4-style tokens. #21079
Changes from all commits
9c7326b
0725c3f
ced4ac6
4344436
c359783
ef07f29
192bb4f
6d305ac
2d94646
6b548fa
41d741c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,13 +27,6 @@ protected function getEntityName(): string { | |
return 'contribution'; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
protected function getEntityAlias(): string { | ||
return 'contrib_'; | ||
} | ||
|
||
/** | ||
* Get the entity name for api v4 calls. | ||
* | ||
|
@@ -47,16 +40,17 @@ protected function getApiEntityName(): string { | |
} | ||
|
||
/** | ||
* Get a list of tokens for the entity for which access is permitted to. | ||
* Get a list of tokens which are loaded via APIv4. | ||
* | ||
* This list is historical and we need to question whether we | ||
* should filter out any fields (other than those fields, like api_key | ||
* on the contact entity) with permissions defined. | ||
* | ||
* @return array | ||
* Ex: ['foo', 'bar_id', 'bar_id:name', 'bar_id:label'] | ||
*/ | ||
protected function getExposedFields(): array { | ||
return [ | ||
protected function getApiTokens(): array { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So once we resolve https://lab.civicrm.org/dev/core/-/issues/2745 my expectation is we would entirely remove this function in favour of a metadata-driven function on the parent class - because there is nothing (yet) in this token class that should not be purely metadata driven At some point in the future we probably will need to add some calculated fields (paid_amount, balance_amount) but that is out of scope |
||
$fields = [ | ||
'contribution_page_id', | ||
'source', | ||
'id', | ||
|
@@ -73,28 +67,58 @@ protected function getExposedFields(): array { | |
'thankyou_date', | ||
'tax_amount', | ||
'contribution_status_id', | ||
'contribution_status_id:name', | ||
'contribution_status_id:label', | ||
'financial_type_id', | ||
'financial_type_id:name', | ||
'financial_type_id:label', | ||
'payment_instrument_id', | ||
'payment_instrument_id:name', | ||
'payment_instrument_id:label', | ||
'cancel_reason', | ||
'amount_level', | ||
'check_number', | ||
]; | ||
if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) { | ||
$fields[] = 'campaign_id'; | ||
$fields[] = 'campaign_id.name'; | ||
$fields[] = 'campaign_id.title'; | ||
} | ||
|
||
return $fields; | ||
} | ||
|
||
/** | ||
* Get tokens supporting the syntax we are migrating to. | ||
* | ||
* In general these are tokens that were not previously supported | ||
* so we can add them in the preferred way or that we have | ||
* undertaken some, as yet to be written, db update. | ||
* | ||
* See https://lab.civicrm.org/dev/core/-/issues/2650 | ||
* | ||
* @return string[] | ||
*/ | ||
public function getBasicTokens(): array { | ||
$return = []; | ||
foreach ($this->getExposedFields() as $fieldName) { | ||
$return[$fieldName] = $this->getFieldMetadata()[$fieldName]['title']; | ||
public function getAliasTokens(): array { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think at some point we will need a ie I think we have 'advertised tokens' and 'deprecatedTokens' but we shouldn't need 'aliasTokens' - that's apiv3 all over again. |
||
$aliases = []; | ||
if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) { | ||
// Unit-tests are written to use these funny tokens - but they're not valid in APIv4. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the unit tests from one of the 2 PRs used them..... the other one used |
||
$aliases['campaign'] = 'campaign_id.name'; | ||
$aliases['campaign_id:name'] = 'campaign_id.name'; | ||
$aliases['campaign_id:label'] = 'campaign_id.title'; | ||
} | ||
return $aliases; | ||
} | ||
|
||
public function getPrefetchFields(\Civi\Token\Event\TokenValueEvent $e): array { | ||
$result = parent::getPrefetchFields($e); | ||
|
||
// Always prefetch 'civicrm_contribution.currency' in case we need to format other fields (fee_amount, total_amount, etc). | ||
$result[] = 'currency'; | ||
|
||
return array_unique($result); | ||
} | ||
|
||
public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { | ||
$values = $prefetch[$row->context[$this->getEntityIDField()]]; | ||
|
||
// Any monetary fields in a `Contribution` (`fee_amount`, `total_amount`, etc) should be formatted in matching `currency`. | ||
// This formatting rule would be nonsensical in any other entity. | ||
if ($this->isApiFieldType($field, 'Money')) { | ||
return $row->format('text/plain')->tokens($entity, $field, | ||
\CRM_Utils_Money::format($values[$field], $values['currency'])); | ||
} | ||
return $return; | ||
|
||
return parent::evaluateToken($row, $entity, $field, $prefetch); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -267,38 +267,44 @@ public static function sendMailings($mappingID, $now) { | |
); | ||
|
||
$multilingual = CRM_Core_I18n::isMultilingual(); | ||
$tokenProcessor = self::createTokenProcessor($actionSchedule, $mapping); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If these changes all work - I'm all for them :-) |
||
while ($dao->fetch()) { | ||
$row = $tokenProcessor->addRow() | ||
->context('contactId', $dao->contactID) | ||
->context('actionSearchResult', (object) $dao->toArray()); | ||
|
||
// switch language if necessary | ||
if ($multilingual) { | ||
$preferred_language = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $dao->contactID, 'preferred_language'); | ||
CRM_Core_BAO_ActionSchedule::setCommunicationLanguage($actionSchedule->communication_language, $preferred_language); | ||
$row->context('locale', CRM_Core_BAO_ActionSchedule::pickLocale($actionSchedule->communication_language, $preferred_language)); | ||
} | ||
|
||
$errors = []; | ||
try { | ||
$tokenProcessor = self::createTokenProcessor($actionSchedule, $mapping); | ||
$tokenProcessor->addRow() | ||
->context('contactId', $dao->contactID) | ||
->context('actionSearchResult', (object) $dao->toArray()); | ||
foreach ($tokenProcessor->evaluate()->getRows() as $tokenRow) { | ||
if ($actionSchedule->mode === 'SMS' || $actionSchedule->mode === 'User_Preference') { | ||
CRM_Utils_Array::extend($errors, self::sendReminderSms($tokenRow, $actionSchedule, $dao->contactID)); | ||
} | ||
|
||
if ($actionSchedule->mode === 'Email' || $actionSchedule->mode === 'User_Preference') { | ||
CRM_Utils_Array::extend($errors, self::sendReminderEmail($tokenRow, $actionSchedule, $dao->contactID)); | ||
} | ||
// insert activity log record if needed | ||
if ($actionSchedule->record_activity && empty($errors)) { | ||
$caseID = empty($dao->case_id) ? NULL : $dao->case_id; | ||
CRM_Core_BAO_ActionSchedule::createMailingActivity($tokenRow, $mapping, $dao->contactID, $dao->entityID, $caseID); | ||
foreach ($dao->toArray() as $key => $value) { | ||
if (preg_match('/^tokenContext_(.*)/', $key, $m)) { | ||
if (!in_array($m[1], $tokenProcessor->context['schema'])) { | ||
$tokenProcessor->context['schema'][] = $m[1]; | ||
} | ||
$row->context($m[1], $value); | ||
} | ||
} | ||
catch (\Civi\Token\TokenException $e) { | ||
$errors['token_exception'] = $e->getMessage(); | ||
} | ||
|
||
$tokenProcessor->evaluate(); | ||
foreach ($tokenProcessor->getRows() as $tokenRow) { | ||
$dao = $tokenRow->context['actionSearchResult']; | ||
$errors = []; | ||
if ($actionSchedule->mode === 'SMS' || $actionSchedule->mode === 'User_Preference') { | ||
CRM_Utils_Array::extend($errors, self::sendReminderSms($tokenRow, $actionSchedule, $dao->contactID)); | ||
} | ||
|
||
if ($actionSchedule->mode === 'Email' || $actionSchedule->mode === 'User_Preference') { | ||
CRM_Utils_Array::extend($errors, self::sendReminderEmail($tokenRow, $actionSchedule, $dao->contactID)); | ||
} | ||
// insert activity log record if needed | ||
if ($actionSchedule->record_activity && empty($errors)) { | ||
$caseID = empty($dao->case_id) ? NULL : $dao->case_id; | ||
CRM_Core_BAO_ActionSchedule::createMailingActivity($tokenRow, $mapping, $dao->contactID, $dao->entityID, $caseID); | ||
} | ||
// update action log record | ||
$logParams = [ | ||
'id' => $dao->reminderID, | ||
|
@@ -308,7 +314,6 @@ public static function sendMailings($mappingID, $now) { | |
]; | ||
CRM_Core_BAO_ActionLog::create($logParams); | ||
} | ||
|
||
} | ||
} | ||
|
||
|
@@ -401,10 +406,11 @@ public static function getRecipientListing($mappingID, $recipientType) { | |
} | ||
|
||
/** | ||
* @param $communication_language | ||
* @param $preferred_language | ||
* @param string|null $communication_language | ||
* @param string|null $preferred_language | ||
* @return string | ||
*/ | ||
public static function setCommunicationLanguage($communication_language, $preferred_language) { | ||
public static function pickLocale($communication_language, $preferred_language) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cool |
||
$currentLocale = CRM_Core_I18n::getLocale(); | ||
$language = $currentLocale; | ||
|
||
|
@@ -425,8 +431,7 @@ public static function setCommunicationLanguage($communication_language, $prefer | |
} | ||
|
||
// change the language | ||
$i18n = CRM_Core_I18n::singleton(); | ||
$i18n->setLocale($language); | ||
return $language; | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - if changing this is definitely ok for scheduled reminders