Add function to update message tokens during upgrade
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 16 Jul 2021 22:08:49 +0000 (10:08 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 27 Jul 2021 09:08:20 +0000 (21:08 +1200)
In conjunction with https://github.com/civicrm/civicrm-core/pull/20867

CRM/Contribute/Form/Task/Invoice.php
CRM/Upgrade/Incremental/Base.php
CRM/Upgrade/Incremental/MessageTemplates.php
CRM/Upgrade/Incremental/php/FiveFortyOne.php
tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php

index 64e903df881fc77590307d4965e7378ba3317daa..8d3b16769e465a0e6a4504edc071766e16199ab7 100644 (file)
@@ -374,7 +374,6 @@ class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task {
         'invoice_date' => $invoiceDate,
         'dueDate' => $dueDate,
         'notes' => $invoiceNotes,
-        'display_name' => $contribution->_relatedObjects['contact']->display_name,
         'lineItem' => $lineItem,
         'dataArray' => $dataArray,
         'refundedStatusId' => $refundedStatusId,
index b51992a9a4d42bc5f0f81402e7eb0f2c305ae6c4..eda62c7956af84859427cfbe722ec6d85e33f6cd 100644 (file)
@@ -229,7 +229,23 @@ class CRM_Upgrade_Incremental_Base {
   public static function updateMessageTemplates($ctx, $version) {
     $messageTemplateObject = new CRM_Upgrade_Incremental_MessageTemplates($version);
     $messageTemplateObject->updateTemplates();
+  }
 
+  /**
+   * Updated a message token within a template.
+   *
+   * @param CRM_Queue_TaskContext $ctx
+   * @param string $workflowName
+   * @param string $old
+   * @param string $new
+   * @param $version
+   *
+   * @return bool
+   */
+  public static function updateMessageToken($ctx, string $workflowName, string $old, string $new, $version):bool {
+    $messageObj = new CRM_Upgrade_Incremental_MessageTemplates($version);
+    $messageObj->replaceTokenInTemplate($workflowName, $old, $new);
+    return TRUE;
   }
 
   /**
index 441b068f1ec4f7bc54ed9b8441a308b10b402db9..a783ffd0233f58eb9a81e396c46015a27d440063 100644 (file)
@@ -270,6 +270,57 @@ class CRM_Upgrade_Incremental_MessageTemplates {
     return $return;
   }
 
+  /**
+   * Replace a token with the new preferred option.
+   *
+   * @param string $workflowName
+   * @param string $old
+   * @param string $new
+   */
+  public function replaceTokenInTemplate(string $workflowName, string $old, string $new): void {
+    $oldToken = '{' . $old . '}';
+    $newToken = '{' . $new . '}';
+    CRM_Core_DAO::executeQuery("UPDATE civicrm_msg_template
+      SET
+        msg_text = REPLACE(msg_text, '$oldToken', '$newToken'),
+        msg_subject = REPLACE(msg_subject, '$oldToken', '$newToken'),
+        msg_html = REPLACE(msg_html, '$oldToken', '$newToken')
+      WHERE workflow_name = '$workflowName'
+    ");
+  }
+
+  /**
+   * Get warnings for users if the replaced string is still present.
+   *
+   * This might be the case when used in an IF and for now we will recommend
+   * manual intervention.
+   *
+   * @param string $workflowName
+   * @param string $old
+   * @param string $new
+   *
+   * @return string
+   */
+  public function getMessageTemplateWarning(string $workflowName, string $old, string $new) {
+    if (CRM_Core_DAO::singleValueQuery("
+      SELECT COUNT(*)
+      FROM civicrm_msg_template
+      WHERE workflow_name = '$workflowName'
+      AND (
+        msg_html LIKE '%$old%'
+        OR msg_subject LIKE '%$old%'
+        OR civicrm_msg_template.msg_text LIKE '%$old%'
+      )
+    ")) {
+      return ts('Please review your %1 message template and remove references to the token %2 as it has been replaced by %3', [
+        1 => $workflowName,
+        2 => '{' . $old . '}',
+        3 => '{' . $new . '}',
+      ]);
+    }
+    return '';
+  }
+
   /**
    * Get the upgrade messages.
    */
index c77a863a160303a202cc68820054813eea6f938d..ad4d85154a963307b1517a1a9822797477624fc4 100644 (file)
@@ -43,6 +43,8 @@ class CRM_Upgrade_Incremental_php_FiveFortyOne extends CRM_Upgrade_Incremental_B
    *   an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
    */
   public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
+    $templateUpgrader = new CRM_Upgrade_Incremental_MessageTemplates($rev);
+    $postUpgradeMessage .= $templateUpgrader->getMessageTemplateWarning('contribution_invoice_receipt', '$display_name', 'contact.display_name');
     // Example: Generate a post-upgrade message.
     // if ($rev == '5.12.34') {
     //   $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
@@ -55,18 +57,17 @@ class CRM_Upgrade_Incremental_php_FiveFortyOne extends CRM_Upgrade_Incremental_B
    * (change the x in the function name):
    */
 
-  //  /**
-  //   * Upgrade function.
-  //   *
-  //   * @param string $rev
-  //   */
-  //  public function upgrade_5_0_x($rev) {
-  //    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
-  //    $this->addTask('Do the foo change', 'taskFoo', ...);
-  //    // Additional tasks here...
-  //    // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
-  //    // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
-  //  }
+  /**
+   * Upgrade function.
+   *
+   * @param string $rev
+   */
+  public function upgrade_5_41_alpha1($rev) {
+    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+    $this->addTask('Replace legacy displayName smarty token in Invoice workflow template',
+      'updateMessageToken', 'contribution_invoice_receipt', '$display_name', 'contact.display_name', $rev
+    );
+  }
 
   // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) {
   //   return TRUE;
index 0777030be00db1312ec9cb0b3f27ba753ec88de5..72582c6c93085a9cb1e57ba162b1c0125595f76d 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Civi\Api4\MessageTemplate;
+
 /**
  * Class CRM_UF_Page_ProfileEditorTest
  * @group headless
@@ -37,6 +39,31 @@ class CRM_Upgrade_Incremental_BaseTest extends CiviUnitTestCase {
     }
   }
 
+  /**
+   * Test that a string replacement in a message template can be done.
+   *
+   * @throws \API_Exception
+   */
+  public function testMessageTemplateStringReplace(): void {
+    MessageTemplate::update()->setValues(['msg_html' => '{$display_name}'])->addWhere(
+      'workflow_name', '=', 'contribution_invoice_receipt'
+    )->execute();
+    $upgrader = new CRM_Upgrade_Incremental_MessageTemplates('5.41.0');
+    $messages = $upgrader->getMessageTemplateWarning('contribution_invoice_receipt', '$display_name', 'contact.display_name');
+    $this->assertEquals('Please review your contribution_invoice_receipt message template and remove references to the token {$display_name} as it has been replaced by {contact.display_name}', $messages);
+    $upgrader->replaceTokenInTemplate('contribution_invoice_receipt', '$display_name', 'contact.display_name');
+    $templates = MessageTemplate::get()->addSelect('msg_html')
+      ->addWhere(
+        'workflow_name', '=', 'contribution_invoice_receipt'
+      )->execute();
+    foreach ($templates as $template) {
+      $this->assertEquals('{contact.display_name}', $template['msg_html']);
+    }
+    $messages = $upgrader->getMessageTemplateWarning('contribution_invoice_receipt', '$display_name', 'contact.display_name');
+    $this->assertEquals('', $messages);
+    $this->revertTemplateToReservedTemplate('contribution_invoice_receipt');
+  }
+
   /**
    * Test message upgrade process only edits the default if the template is customised.
    */