Reconcile remaining fields between scheduled reminders and legacy tokens
[civicrm-core.git] / CRM / Contribute / Tokens.php
index 93a8747e277ae5d7c44ecce6949f6b59fa235f85..ca1b952cc7fb842cfc24209b783d14d6f0c90d87 100644 (file)
  +--------------------------------------------------------------------+
  */
 
-use Civi\ActionSchedule\Event\MailingQueryEvent;
-use Civi\Token\AbstractTokenSubscriber;
-use Civi\Token\TokenProcessor;
-use Civi\Token\TokenRow;
-
 /**
  * Class CRM_Contribute_Tokens
  *
@@ -23,114 +18,90 @@ use Civi\Token\TokenRow;
  * At time of writing, we don't have any particularly special tokens -- we just
  * do some basic formatting based on the corresponding DB field.
  */
-class CRM_Contribute_Tokens extends AbstractTokenSubscriber {
+class CRM_Contribute_Tokens extends CRM_Core_EntityTokens {
 
   /**
-   * Get a list of tokens whose name and title match the DB fields.
-   * @return array
+   * @return string
    */
-  protected function getPassthruTokens(): array {
-    return [
-      'contribution_page_id',
-      'receive_date',
-      'total_amount',
-      'fee_amount',
-      'net_amount',
-      'trxn_id',
-      'invoice_id',
-      'currency',
-      'contribution_cancel_date',
-      'receipt_date',
-      'thankyou_date',
-      'tax_amount',
-    ];
+  protected function getEntityName(): string {
+    return 'contribution';
   }
 
   /**
-   * Get alias tokens.
-   *
-   * @return array
+   * @return string
    */
-  protected function getAliasTokens(): array {
-    return [
-      'id' => 'contribution_id',
-      'payment_instrument' => 'payment_instrument_id',
-      'source' => 'contribution_source',
-      'status' => 'contribution_status_id',
-      'type' => 'financial_type_id',
-      'cancel_date' => 'contribution_cancel_date',
-    ];
+  protected function getEntityAlias(): string {
+    return 'contrib_';
   }
 
   /**
-   * Class constructor.
-   */
-  public function __construct() {
-    $tokens = CRM_Utils_Array::subset(
-      CRM_Utils_Array::collect('title', CRM_Contribute_DAO_Contribution::fields()),
-      $this->getPassthruTokens()
-    );
-    $tokens['id'] = ts('Contribution ID');
-    $tokens['payment_instrument'] = ts('Payment Instrument');
-    $tokens['source'] = ts('Contribution Source');
-    $tokens['status'] = ts('Contribution Status');
-    $tokens['type'] = ts('Financial Type');
-    $tokens = array_merge($tokens, CRM_Utils_Token::getCustomFieldTokens('Contribution'));
-    parent::__construct('contribution', $tokens);
-  }
-
-  /**
-   * Check if the token processor is active.
+   * Get the entity name for api v4 calls.
    *
-   * @param \Civi\Token\TokenProcessor $processor
+   * In practice this IS just ucfirst($this->GetEntityName)
+   * but declaring it seems more legible.
    *
-   * @return bool
+   * @return string
    */
-  public function checkActive(TokenProcessor $processor) {
-    return !empty($processor->context['actionMapping'])
-      && $processor->context['actionMapping']->getEntity() === 'civicrm_contribution';
+  protected function getApiEntityName(): string {
+    return 'Contribution';
   }
 
   /**
-   * Alter action schedule query.
+   * Get a list of tokens for the entity for which access is permitted to.
    *
-   * @param \Civi\ActionSchedule\Event\MailingQueryEvent $e
+   * 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
    */
-  public function alterActionScheduleQuery(MailingQueryEvent $e): void {
-    if ($e->mapping->getEntity() !== 'civicrm_contribution') {
-      return;
-    }
-
-    $fields = CRM_Contribute_DAO_Contribution::fields();
-    foreach ($this->getPassthruTokens() as $token) {
-      $e->query->select("e." . $fields[$token]['name'] . " AS contrib_{$token}");
-    }
-    foreach ($this->getAliasTokens() as $alias => $orig) {
-      $e->query->select("e." . $fields[$orig]['name'] . " AS contrib_{$alias}");
+  protected function getExposedFields(): array {
+    $fields = [
+      'contribution_page_id',
+      'source',
+      'id',
+      'receive_date',
+      'total_amount',
+      'fee_amount',
+      'net_amount',
+      'non_deductible_amount',
+      'trxn_id',
+      'invoice_id',
+      'currency',
+      'cancel_date',
+      'receipt_date',
+      'thankyou_date',
+      'tax_amount',
+      'contribution_status_id',
+      'financial_type_id',
+      'payment_instrument_id',
+      'cancel_reason',
+      'amount_level',
+      'check_number',
+    ];
+    if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) {
+      $fields[] = 'campaign_id';
     }
+    return $fields;
   }
 
   /**
-   * @inheritDoc
+   * 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 evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) {
-    $actionSearchResult = $row->context['actionSearchResult'];
-    $fieldValue = $actionSearchResult->{"contrib_$field"} ?? NULL;
-
-    $aliasTokens = $this->getAliasTokens();
-    if (in_array($field, ['total_amount', 'fee_amount', 'net_amount'])) {
-      return $row->format('text/plain')->tokens($entity, $field,
-        \CRM_Utils_Money::format($fieldValue, $actionSearchResult->contrib_currency));
-    }
-    elseif (isset($aliasTokens[$field])) {
-      $row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $aliasTokens[$field], $fieldValue);
-    }
-    elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
-      $row->customToken($entity, $cfID, $actionSearchResult->entity_id);
-    }
-    else {
-      $row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $field, $fieldValue);
+  public function getBasicTokens(): array {
+    $return = [];
+    foreach ($this->getExposedFields() as $fieldName) {
+      $return[$fieldName] = $this->getFieldMetadata()[$fieldName]['title'];
     }
+    return $return;
   }
 
 }