Participant tokens on scheduled reminders (wip- upgrade script needed at minimum)
[civicrm-core.git] / CRM / Event / Tokens.php
index 5de70c3080bf9616a4c5b00009e6994a31e765c0..061e7197faf287649d40de246c337edb5609203c 100644 (file)
@@ -10,7 +10,8 @@
  +--------------------------------------------------------------------+
  */
 
-use Civi\ActionSchedule\Event\MailingQueryEvent;
+use Civi\Api4\Event;
+use Civi\Token\TokenRow;
 
 /**
  * Class CRM_Event_Tokens
@@ -43,9 +44,9 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens {
   public function getAllTokens(): array {
     return array_merge(
       [
-        'event_type' => ts('Event Type'),
+        'event_type_id:label' => ts('Event Type'),
         'title' => ts('Event Title'),
-        'event_id' => ts('Event ID'),
+        'id' => ts('Event ID'),
         'start_date' => ts('Event Start Date'),
         'end_date' => ts('Event End Date'),
         'summary' => ts('Event Summary'),
@@ -53,10 +54,8 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens {
         'location' => ts('Event Location'),
         'info_url' => ts('Event Info URL'),
         'registration_url' => ts('Event Registration URL'),
-        'fee_amount' => ts('Event Fee'),
         'contact_email' => ts('Event Contact Email'),
         'contact_phone' => ts('Event Contact Phone'),
-        'balance' => ts('Event Balance'),
       ],
       CRM_Utils_Token::getCustomFieldTokens('Event')
     );
@@ -64,88 +63,84 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens {
 
   /**
    * @inheritDoc
+   * @throws \API_Exception
    */
-  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_participant'))
-      || in_array($this->getEntityIDField(), $processor->context['schema'], TRUE);
+  public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) {
+    $eventID = $this->getFieldValue($row, 'id');
+    if (!$eventID) {
+      $eventID = $row->context['actionSearchResult']->event_id;
+    }
+    if (array_key_exists($field, $this->getEventTokenValues($eventID))) {
+      foreach ($this->getEventTokenValues($eventID)[$field] as $format => $value) {
+        $row->format($format)->tokens($entity, $field, $value);
+      }
+    }
   }
 
   /**
-   * Alter action schedule query.
+   * Get the tokens available for the event.
+   *
+   * Cache by event as it's l
+   *
+   * @param int|null $eventID
+   *
+   * @return array
    *
-   * @param \Civi\ActionSchedule\Event\MailingQueryEvent $e
+   * @throws \API_Exception|\CRM_Core_Exception
+   *
+   * @internal
    */
-  public function alterActionScheduleQuery(MailingQueryEvent $e): void {
-    if ($e->mapping->getEntity() !== 'civicrm_participant') {
-      return;
-    }
+  protected function getEventTokenValues(int $eventID = NULL): array {
+    $cacheKey = __CLASS__ . 'event_tokens' . $eventID . '_' . CRM_Core_I18n::getLocale();
+    if (!Civi::cache('metadata')->has($cacheKey)) {
+      $event = Event::get(FALSE)->addWhere('id', '=', $eventID)
+        ->setSelect([
+          'event_type_id',
+          'title',
+          'id',
+          'start_date',
+          'end_date',
+          'summary',
+          'description',
+          'loc_block_id',
+          'loc_block_id.address_id.street_address',
+          'loc_block_id.address_id.city',
+          'loc_block_id.address_id.state_province_id:label',
+          'loc_block_id.address_id.postal_code',
+          'loc_block_id.email_id.email',
+          'loc_block_id.phone_id.phone',
+          'custom.*',
+        ])
+        ->execute()->first();
+      $tokens['location']['text/plain'] = \CRM_Utils_Address::format([
+        'street_address' => $event['loc_block_id.address_id.street_address'],
+        'city' => $event['loc_block_id.address_id.city'],
+        'state_province' => $event['loc_block_id.address_id.state_province_id:label'],
+        'postal_code' => $event['loc_block_id.address_id.postal_code'],
 
-    // FIXME: seems too broad.
-    $e->query->select('e.*');
-    $e->query->select('ov.label as event_type, ev.title, ev.id as event_id, ev.start_date, ev.end_date, ev.summary, ev.description, address.street_address, address.city, address.state_province_id, address.postal_code, email.email as contact_email, phone.phone as contact_phone');
-    $e->query->join('participant_stuff', "
-!casMailingJoinType civicrm_event ev ON e.event_id = ev.id
-!casMailingJoinType civicrm_option_group og ON og.name = 'event_type'
-!casMailingJoinType civicrm_option_value ov ON ev.event_type_id = ov.value AND ov.option_group_id = og.id
-LEFT JOIN civicrm_loc_block lb ON lb.id = ev.loc_block_id
-LEFT JOIN civicrm_address address ON address.id = lb.address_id
-LEFT JOIN civicrm_email email ON email.id = lb.email_id
-LEFT JOIN civicrm_phone phone ON phone.id = lb.phone_id
-");
-  }
-
-  /**
-   * @inheritDoc
-   */
-  public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) {
-    $actionSearchResult = $row->context['actionSearchResult'];
+      ]);
+      $tokens['info_url']['text/html'] = \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $eventID, TRUE, NULL, FALSE);
+      $tokens['registration_url']['text/html'] = \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $eventID, TRUE, NULL, FALSE);
+      $tokens['start_date']['text/html'] = !empty($event['start_date']) ? new DateTime($event['start_date']) : '';
+      $tokens['end_date']['text/html'] = !empty($event['end_date']) ? new DateTime($event['end_date']) : '';
+      $tokens['event_type_id:label']['text/html'] = CRM_Core_PseudoConstant::getLabel('CRM_Event_BAO_Event', 'event_type_id', $event['event_type_id']);
+      $tokens['contact_phone']['text/html'] = $event['loc_block_id.phone_id.phone'];
+      $tokens['contact_email']['text/html'] = $event['loc_block_id.email_id.email'];
 
-    if ($field == 'location') {
-      $loc = [];
-      $stateProvince = \CRM_Core_PseudoConstant::stateProvince();
-      $loc['street_address'] = $actionSearchResult->street_address;
-      $loc['city'] = $actionSearchResult->city;
-      $loc['state_province'] = $stateProvince[$actionSearchResult->state_province_id] ?? NULL;
-      $loc['postal_code'] = $actionSearchResult->postal_code;
-      //$entityTokenParams[$tokenEntity][$field] = \CRM_Utils_Address::format($loc);
-      $row->tokens($entity, $field, \CRM_Utils_Address::format($loc));
-    }
-    elseif ($field == 'info_url') {
-      $row
-        ->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE));
-    }
-    elseif ($field == 'registration_url') {
-      $row
-        ->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE));
-    }
-    elseif (in_array($field, ['start_date', 'end_date'])) {
-      $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($actionSearchResult->$field));
-    }
-    elseif ($field == 'balance') {
-      if ($actionSearchResult->entityTable == 'civicrm_contact') {
-        $balancePay = 'N/A';
+      foreach (array_keys($this->getAllTokens()) as $field) {
+        if (!isset($tokens[$field])) {
+          if ($this->isCustomField($field)) {
+            $this->prefetch[$eventID] = $event;
+            $tokens[$field]['text/html'] = $this->getCustomFieldValue($eventID, $field);
+          }
+          else {
+            $tokens[$field]['text/html'] = $event[$field];
+          }
+        }
       }
-      elseif (!empty($actionSearchResult->entityID)) {
-        $info = \CRM_Contribute_BAO_Contribution::getPaymentInfo($actionSearchResult->entityID, 'event');
-        $balancePay = $info['balance'] ?? NULL;
-        $balancePay = \CRM_Utils_Money::format($balancePay);
-      }
-      $row->tokens($entity, $field, $balancePay);
-    }
-    elseif ($field == 'fee_amount') {
-      $row->tokens($entity, $field, \CRM_Utils_Money::format($actionSearchResult->$field));
-    }
-    elseif (isset($actionSearchResult->$field)) {
-      $row->tokens($entity, $field, $actionSearchResult->$field);
-    }
-    elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
-      $row->customToken($entity, $cfID, $actionSearchResult->event_id);
-    }
-    else {
-      $row->tokens($entity, $field, '');
+      Civi::cache('metadata')->set($cacheKey, $tokens);
     }
+    return Civi::cache('metadata')->get($cacheKey);
   }
 
 }