Fix membership online preview to display subject (using token)
authorEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 16 Nov 2023 22:13:55 +0000 (11:13 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 16 Nov 2023 23:30:11 +0000 (12:30 +1300)
CRM/Member/WorkflowMessage/Membership/Membership.php
Civi/Test/FormTrait.php
tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php
xml/templates/message_templates/membership_online_receipt_subject.tpl

index 03d134e2896efe242a30ce1f1259dd58a585164d..a66a7a46ec52b0bafce6b8c0a4ca95f9e1b71431 100644 (file)
@@ -1,9 +1,11 @@
 <?php
 
+use Civi\Api4\ContributionPage;
 use Civi\Api4\MembershipType;
 use Civi\Api4\PriceField;
 use Civi\Api4\PriceFieldValue;
 use Civi\Api4\PriceSet;
+use Civi\Api4\PriceSetEntity;
 use Civi\Api4\WorkflowMessage;
 use Civi\Test;
 use Civi\WorkflowMessage\GenericWorkflowMessage;
@@ -16,6 +18,10 @@ use Civi\WorkflowMessage\WorkflowMessageExample;
  */
 class CRM_Member_WorkflowMessage_Membership_Membership extends WorkflowMessageExample {
 
+  private $priceSets;
+
+  private $contributionPages;
+
   /**
    * Get the examples this class is able to deliver.
    *
@@ -35,15 +41,23 @@ class CRM_Member_WorkflowMessage_Membership_Membership extends WorkflowMessageEx
 
     foreach ($workflows as $workflow) {
       foreach ($priceSets as $priceSet) {
+        if (!$priceSet['contribution_page_id'] && $workflow === 'membership_online_receipt' & count($priceSets) > 1) {
+          // Generally the online receipt is used with a contribution page so lets' focus
+          // on those examples for it - unless none exist. It could also be used
+          // on other contributions via the send receipt method so we do want to show it if
+          // there are not better examples.
+          continue;
+        }
         yield [
           'name' => 'workflow/' . $workflow . '/' . strtolower($membershipType['name']) . '_' . strtolower($priceSet['name']) . '_' . strtolower($defaultCurrency),
-          'title' => $priceSet['title'] . ' - ' . $membershipType['name'] . ' : ' . $defaultCurrency,
+          'title' => ($priceSet['contribution_page_id'] ? $this->getContributionPage($priceSet['contribution_page_id'])['title'] : $priceSet['title']) . ' - ' . $membershipType['name'] . ' : ' . $defaultCurrency,
           'tags' => ['preview'],
           'workflow' => $workflow,
           'membership_type' => $membershipType,
           'currency' => $defaultCurrency,
           'price_set_id' => $priceSet['id'],
-          'is_show_line_items' => !$priceSets['is_quick_config'],
+          'contribution_page_id' => $priceSet['contribution_page_id'],
+          'is_show_line_items' => !$priceSet['is_quick_config'],
         ];
       }
     }
@@ -96,11 +110,17 @@ class CRM_Member_WorkflowMessage_Membership_Membership extends WorkflowMessageEx
       'fee_amount' => .99,
       'net_amount' => $example['membership_type']['minimum_amount'] - .99,
       'currency' => $example['currency'],
+      'contribution_page_id' => $example['contribution_page_id'],
       'trxn_id' => 123,
       'invoice_id' => 'I-123',
       'contribution_status_id:name' => 'Completed',
       'contribution_status_id' => \CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'),
     ];
+    if ($example['contribution_page_id']) {
+      foreach ($this->getContributionPage($example['contribution_page_id']) as $pageKey => $pageValue) {
+        $contribution['contribution_page_id.' . $pageKey] = $pageValue;
+      }
+    }
     $contribution['contribution_status_id:label'] = \CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contribution['contribution_status_id']);
 
     if (isset($example['contribution_params'])) {
@@ -145,10 +165,23 @@ class CRM_Member_WorkflowMessage_Membership_Membership extends WorkflowMessageEx
    * @throws \CRM_Core_Exception
    */
   private function getPriceSet(): ?array {
-    return (array) PriceSet::get(FALSE)
-      ->addWhere('extends', '=', CRM_Core_Component::getComponentID('CiviMember'))
-      ->addOrderBy('is_quick_config', 'DESC')
-      ->execute()->indexBy('id');
+    if (!$this->priceSets) {
+      $priceSets = (array) PriceSet::get(FALSE)
+        ->addWhere('extends', '=', CRM_Core_Component::getComponentID('CiviMember'))
+        ->addOrderBy('is_quick_config', 'DESC')
+        ->execute()->indexBy('id');
+      $priceSetEntities = PriceSetEntity::get(FALSE)
+        ->addWhere('price_set_id', 'IN', array_keys($priceSets))
+        ->addWhere('entity_table', '=', 'civicrm_contribution_page')
+        ->addOrderBy('entity_id')
+        ->addSelect('price_set_id', 'entity_id')
+        ->execute();
+      foreach ($priceSetEntities as $priceSetEntity) {
+        $priceSets[$priceSetEntity['price_set_id']]['contribution_page_id'] = $priceSetEntity['entity_id'];
+      }
+      $this->priceSets = $priceSets;
+    }
+    return $this->priceSets;
   }
 
   /**
@@ -178,4 +211,21 @@ class CRM_Member_WorkflowMessage_Membership_Membership extends WorkflowMessageEx
     $mockOrder->setLineItem($lineItem, $index);
   }
 
+  /**
+   * @param int $id
+   *
+   * @return array
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
+   */
+  private function getContributionPage(int $id): array {
+    if (!isset($this->contributionPages[$id])) {
+      $this->contributionPages[$id] = ContributionPage::get(FALSE)
+        ->addWhere('id', '=', $id)
+        ->execute()->first();
+    }
+    return $this->contributionPages[$id];
+  }
+
 }
index a194768c156366d103f6f667021c4d4925608839..77beefcc90d98e52d9b84409618d685f1e70a126 100644 (file)
@@ -68,6 +68,17 @@ trait FormTrait {
     $this->assertStringContainsString($string, $mail['body']);
   }
 
+  /**
+   * Assert that the sent mail included the supplied string.
+   *
+   * @param string $string
+   * @param int $mailIndex
+   */
+  protected function assertMailSentContainingHeaderString(string $string, int $mailIndex = 0): void {
+    $mail = $this->form->getMail()[$mailIndex];
+    $this->assertStringContainsString($string, $mail['headers']);
+  }
+
   /**
    * Assert that the sent mail included the supplied strings.
    *
index dd6ff5dfaec85ef910b6c587339b28e225ea52c5..d87cf98967278994f8204ed4108d0070a38e521f 100644 (file)
@@ -230,6 +230,8 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
       'Membership Start Date',
       '************1111',
     ], 1);
+    $this->assertMailSentContainingHeaderString('Test Contribution Page', 0);
+    $this->assertMailSentContainingHeaderString('Test Contribution Page', 1);
   }
 
   /**
index 43eed64b71bfb8020202ad754cb0ba875d205c87..7fe701830cbd68eaae78a5de7adecb11873bc73e 100644 (file)
@@ -1 +1 @@
-{if '{contribution.contribution_status_id:name}' === 'Pending'}{ts}Invoice{/ts}{else}{ts}Receipt{/ts}{/if} - {$title} - {contact.display_name}
+{if '{contribution.contribution_status_id:name}' === 'Pending'}{ts}Invoice{/ts}{else}{ts}Receipt{/ts}{/if} - {contribution.contribution_page_id.frontend_title} - {contact.display_name}