Add upgrade routine to remove old action schedule token
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 30 Jul 2021 08:22:34 +0000 (20:22 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 2 Aug 2021 05:17:18 +0000 (17:17 +1200)
This adds a routing to swap out the action schedule tokens on upgrade.

Given the token is completely invisible in the UI it's unlikely it is in use anywhere but
rather than just remove it from Contribute_Tokens this adds the upgrade
routine to remove this token, and others

CRM/Contribute/Tokens.php
CRM/Upgrade/Incremental/Base.php
CRM/Upgrade/Incremental/MessageTemplates.php
CRM/Upgrade/Incremental/php/FiveFortyOne.php
tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php
tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php

index 6ff9a0c63731ac433bbe6fd3fc859497d1922fec..52511402d42cc71d32f4f81f376706c459bce9b4 100644 (file)
@@ -78,7 +78,6 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber {
       'id' => 'contribution_id',
       'payment_instrument' => 'payment_instrument_id',
       'source' => 'contribution_source',
-      'status' => 'contribution_status_id',
       'type' => 'financial_type_id',
       'cancel_date' => 'contribution_cancel_date',
     ];
@@ -129,10 +128,6 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber {
     $tokens['id'] = ts('Contribution ID');
     $tokens['payment_instrument'] = ts('Payment Instrument');
     $tokens['source'] = ts('Contribution Source');
-    // Per https://lab.civicrm.org/dev/core/-/issues/2650
-    // the intent is to deprecate this field in favour of
-    // {contribution.contribution_status_id:label}
-    $tokens['status'] = ts('Contribution Status');
     $tokens['type'] = ts('Financial Type');
     $tokens = array_merge($tokens, $this->getPseudoTokens(), CRM_Utils_Token::getCustomFieldTokens('Contribution'));
     parent::__construct('contribution', $tokens);
@@ -196,9 +191,6 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber {
       $row->tokens($entity, $field, $this->getPseudoValue($split[0], $split[1], $actionSearchResult->{"contrib_$split[0]"} ?? NULL));
     }
     elseif (in_array($field, array_keys($this->getBasicTokens()))) {
-      // For now we just ensure that the label fields do not override the
-      // id field here.
-      // Later we will add support for contribution_status_id:label
       $row->tokens($entity, $field, $fieldValue);
     }
     else {
index eda62c7956af84859427cfbe722ec6d85e33f6cd..940fb3b0d1bb5034857b92f92517287414a13c38 100644 (file)
@@ -248,6 +248,22 @@ class CRM_Upgrade_Incremental_Base {
     return TRUE;
   }
 
+  /**
+   * Updated a message token within a template.
+   *
+   * @param CRM_Queue_TaskContext $ctx
+   * @param string $old
+   * @param string $new
+   * @param $version
+   *
+   * @return bool
+   */
+  public static function updateActionScheduleToken($ctx, string $old, string $new, $version):bool {
+    $messageObj = new CRM_Upgrade_Incremental_MessageTemplates($version);
+    $messageObj->replaceTokenInActionSchedule($old, $new);
+    return TRUE;
+  }
+
   /**
    * Re-save any valid values from contribute settings into the normal setting
    * format.
index a783ffd0233f58eb9a81e396c46015a27d440063..944a1e69da06c82ca7606400ede00e63a7fd99ab 100644 (file)
@@ -289,6 +289,23 @@ class CRM_Upgrade_Incremental_MessageTemplates {
     ");
   }
 
+  /**
+   * Replace a token with the new preferred option.
+   *
+   * @param string $old
+   * @param string $new
+   */
+  public function replaceTokenInActionSchedule(string $old, string $new): void {
+    $oldToken = '{' . $old . '}';
+    $newToken = '{' . $new . '}';
+    CRM_Core_DAO::executeQuery("UPDATE civicrm_action_schedule
+      SET
+        body_text = REPLACE(body_text, '$oldToken', '$newToken'),
+        subject = REPLACE(subject, '$oldToken', '$newToken'),
+        body_html = REPLACE(body_html, '$oldToken', '$newToken')
+    ");
+  }
+
   /**
    * Get warnings for users if the replaced string is still present.
    *
index ca3e5c0f477270d77b741fcd7da8a2b9a06df8bc..fedf856c160681c945cdc656647f3b3bc0f94746 100644 (file)
@@ -65,6 +65,12 @@ class CRM_Upgrade_Incremental_php_FiveFortyOne extends CRM_Upgrade_Incremental_B
   public function upgrade_5_41_alpha1($rev) {
     $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
     $this->addTask('Install legacy custom search extension', 'installCustomSearches');
+    $this->addTask('Replace legacy displayName smarty token in Invoice workflow template',
+      'updateMessageToken', 'contribution_invoice_receipt', '$display_name', 'contact.display_name', $rev
+    );
+    $this->addTask('Replace contribution status token in action schedule',
+      'updateActionScheduleToken', 'contribution.status', 'contribution.contribution_status_id:label', $rev
+    );
   }
 
   /**
index a2d1bc7c08dda28673250c35b453d0aa910463f9..cc729e728f1cad4f914d12ae0fffe2512980d5d7 100644 (file)
@@ -231,10 +231,10 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr
     $this->schedule->recipient_listing = CRM_Utils_Array::implodePadded([3]);
   }
 
-  public function useHelloFirstNameStatus() {
-    $this->schedule->subject = 'Hello, {contact.first_name}. @{contribution.status}. (via subject)';
-    $this->schedule->body_html = '<p>Hello, {contact.first_name}. @{contribution.status}. (via body_html)</p>';
-    $this->schedule->body_text = 'Hello, {contact.first_name}. @{contribution.status} (via body_text)';
+  public function useHelloFirstNameStatus(): void {
+    $this->schedule->subject = 'Hello, {contact.first_name}. @{contribution.contribution_status_id:name}. (via subject)';
+    $this->schedule->body_html = '<p>Hello, {contact.first_name}. @{contribution.contribution_status_id:name}. (via body_html)</p>';
+    $this->schedule->body_text = 'Hello, {contact.first_name}. @{contribution.contribution_status_id:name} (via body_text)';
   }
 
   /**
@@ -252,6 +252,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr
   public function testTokenRendering(): void {
     $this->targetDate = '20150201000107';
     \CRM_Utils_Time::setTime('2015-02-01 00:00:00');
+    \CRM_Core_DAO::executeQuery("UPDATE civicrm_option_value SET label = 'Completed Label**' where label = 'Completed' AND name = 'Completed'");
+
     $this->addAliceDues();
     $this->scheduleForAny();
     $this->startOnTime();
@@ -260,8 +262,9 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr
       first name = {contact.first_name}
       receive_date = {contribution.receive_date}
       contribution status id = {contribution.contribution_status_id}
-      legacy style status = {contribution.status}
-      new style status = {contribution.contribution_status_id:name}';
+      new style status = {contribution.contribution_status_id:name}
+      new style label = {contribution.contribution_status_id:label}
+    ';
     $this->schedule->save();
     $this->callAPISuccess('job', 'send_reminder', []);
     $expected = [
@@ -269,7 +272,7 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr
       'receive_date = February 1st, 2015 12:00 AM',
       'contribution status id = 1',
       'new style status = Completed',
-      'legacy style status = Completed',
+      'new style label = Completed Label**',
     ];
     $this->mut->checkMailLog($expected);
 
index 72582c6c93085a9cb1e57ba162b1c0125595f76d..b3dc1ca9adfde6374b0090bdf7aa10962619943c 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Civi\Api4\ActionSchedule;
 use Civi\Api4\MessageTemplate;
 
 /**
@@ -10,14 +11,15 @@ class CRM_Upgrade_Incremental_BaseTest extends CiviUnitTestCase {
   use CRMTraits_Custom_CustomDataTrait;
 
   public function tearDown(): void {
-    $this->quickCleanup(['civicrm_saved_search']);
+    $this->quickCleanup(['civicrm_saved_search', 'civicrm_action_schedule']);
+    parent::tearDown();
   }
 
   /**
    * Test message upgrade process.
    */
-  public function testMessageTemplateUpgrade() {
-    $workFlowID = civicrm_api3('OptionValue', 'getvalue', ['return' => 'id', 'name' => 'membership_online_receipt', 'options' => ['limit' => 1, 'sort' => 'id DESC']]);
+  public function testMessageTemplateUpgrade(): void {
+    $workFlowID = $this->callAPISuccessGetValue('OptionValue', ['return' => 'id', 'name' => 'membership_online_receipt', 'options' => ['limit' => 1, 'sort' => 'id DESC']]);
 
     $templates = $this->callAPISuccess('MessageTemplate', 'get', ['workflow_id' => $workFlowID])['values'];
     foreach ($templates as $template) {
@@ -64,6 +66,33 @@ class CRM_Upgrade_Incremental_BaseTest extends CiviUnitTestCase {
     $this->revertTemplateToReservedTemplate('contribution_invoice_receipt');
   }
 
+  /**
+   * Test that a $this->string replacement in a message template can be done.
+   *
+   * @throws \API_Exception
+   */
+  public function testActionScheduleStringReplace(): void {
+    ActionSchedule::create(FALSE)->setValues([
+      'title' => 'schedule',
+      'absolute_date' => '2021-01-01',
+      'start_action_date' => '2021-01-01',
+      'mapping_id' => 1,
+      'entity_value' => 1,
+      'body_text' => 'blah {contribution.status}',
+      'body_html' => 'blah {contribution.status}',
+      'subject' => 'blah {contribution.status}',
+    ])->execute();
+
+    $upgrader = new CRM_Upgrade_Incremental_MessageTemplates('5.41.0');
+    $upgrader->replaceTokenInActionSchedule('contribution.status', 'contribution.contribution_status_id:label');
+    $templates = ActionSchedule::get()->addSelect('body_html', 'subject', 'body_text')->execute();
+    foreach ($templates as $template) {
+      $this->assertEquals('blah {contribution.contribution_status_id:label}', $template['body_html']);
+      $this->assertEquals('blah {contribution.contribution_status_id:label}', $template['body_text']);
+      $this->assertEquals('blah {contribution.contribution_status_id:label}', $template['subject']);
+    }
+  }
+
   /**
    * Test message upgrade process only edits the default if the template is customised.
    */