Add workflow_name column to civicrm_msg_template, deprecate workflow_id
authoreileen <emcnaughton@wikimedia.org>
Mon, 4 May 2020 00:49:48 +0000 (12:49 +1200)
committerTim Otten <totten@civicrm.org>
Thu, 7 May 2020 07:30:53 +0000 (00:30 -0700)
CRM/Admin/Page/MessageTemplates.php
CRM/Core/BAO/MessageTemplate.php
CRM/Core/DAO/MessageTemplate.php
CRM/Upgrade/Incremental/php/FiveTwentySix.php
Civi/Api4/Generic/DAOGetAction.php
api/v3/MessageTemplate.php
tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php
tests/phpunit/api/v3/ActivityTest.php
xml/schema/Core/MessageTemplate.xml
xml/templates/civicrm_msg_template.tpl

index 4eb05bb68713afd3f0fcdf046d6f1523d6eb349d..3363ac410fbcee74d488d90325dfa06622d78840 100644 (file)
@@ -257,7 +257,7 @@ class CRM_Admin_Page_MessageTemplates extends CRM_Core_Page_Basic {
       // populate action links
       $this->action($messageTemplate, $action, $values[$messageTemplate->id], $links, CRM_Core_Permission::EDIT);
 
-      if (!$messageTemplate->workflow_id) {
+      if (!$messageTemplate->workflow_name) {
         $userTemplates[$messageTemplate->id] = $values[$messageTemplate->id];
       }
       elseif (!$messageTemplate->is_reserved) {
index bf12a16a204878b18ca843aefe8418a66f52a8fd..ff9cb3f9c933e6842fcafbc84bce576a0e58295e 100644 (file)
@@ -15,6 +15,8 @@
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
 
+use Civi\Api4\MessageTemplate;
+
 require_once 'Mail/mime.php';
 
 /**
@@ -345,11 +347,10 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
    * @return array
    *   Array of four parameters: a boolean whether the email was sent, and the subject, text and HTML templates
    * @throws \CRM_Core_Exception
+   * @throws \API_Exception
    */
   public static function sendTemplate($params) {
     $defaults = [
-      // option group name of the template
-      'groupName' => NULL,
       // option value name of the template
       'valueName' => NULL,
       // ID of the template
@@ -386,49 +387,38 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
 
     CRM_Utils_Hook::alterMailParams($params, 'messageTemplate');
 
-    if ((!$params['groupName'] ||
-        !$params['valueName']
-      ) &&
-      !$params['messageTemplateID']
-    ) {
-      throw new CRM_Core_Exception(ts("Message template's option group and/or option value or ID missing."));
+    if (!$params['valueName'] && !$params['messageTemplateID']) {
+      throw new CRM_Core_Exception(ts("Message template's option value or ID missing."));
     }
 
+    $apiCall = MessageTemplate::get()
+      ->setCheckPermissions(FALSE)
+      ->addSelect('msg_subject', 'msg_text', 'msg_html', 'pdf_format_id', 'id')
+      ->addWhere('is_default', '=', 1);
+
     if ($params['messageTemplateID']) {
-      // fetch the three elements from the db based on id
-      $query = 'SELECT msg_subject subject, msg_text text, msg_html html, pdf_format_id format
-                      FROM civicrm_msg_template mt
-                      WHERE mt.id = %1 AND mt.is_default = 1';
-      $sqlParams = [1 => [$params['messageTemplateID'], 'String']];
+      $apiCall->addWhere('id', '=', (int) $params['messageTemplateID']);
     }
     else {
-      // fetch the three elements from the db based on option_group and option_value names
-      $query = 'SELECT msg_subject subject, msg_text text, msg_html html, pdf_format_id format
-                      FROM civicrm_msg_template mt
-                      JOIN civicrm_option_value ov ON workflow_id = ov.id
-                      JOIN civicrm_option_group og ON ov.option_group_id = og.id
-                      WHERE og.name = %1 AND ov.name = %2 AND mt.is_default = 1';
-      $sqlParams = [1 => [$params['groupName'], 'String'], 2 => [$params['valueName'], 'String']];
+      $apiCall->addWhere('workflow_name', '=', $params['valueName']);
     }
-    $dao = CRM_Core_DAO::executeQuery($query, $sqlParams);
-    $dao->fetch();
+    $messageTemplate = $apiCall->execute()->first();
 
-    if (!$dao->N) {
+    if (empty($messageTemplate['id'])) {
       if ($params['messageTemplateID']) {
         throw new CRM_Core_Exception(ts('No such message template: id=%1.', [1 => $params['messageTemplateID']]));
       }
-      throw new CRM_Core_Exception(ts('No such message template: option group %1, option value %2.', [
-        1 => $params['groupName'],
-        2 => $params['valueName'],
-      ]));
+      throw new CRM_Core_Exception(ts('No message template with workflow name %2.', [2 => $params['valueName']]));
     }
 
     $mailContent = [
-      'subject' => $dao->subject,
-      'text' => $dao->text,
-      'html' => $dao->html,
-      'format' => $dao->format,
-      'groupName' => $params['groupName'],
+      'subject' => $messageTemplate['msg_subject'],
+      'text' => $messageTemplate['msg_text'],
+      'html' => $messageTemplate['msg_html'],
+      'format' => $messageTemplate['pdf_format_id'],
+      // Group name is a deprecated parameter. At some point it will not be passed out.
+      // https://github.com/civicrm/civicrm-core/pull/17180
+      'groupName' => $params['groupName'] ?? NULL,
       'valueName' => $params['valueName'],
       'messageTemplateID' => $params['messageTemplateID'],
     ];
@@ -439,9 +429,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
     if ($params['isTest']) {
       $query = "SELECT msg_subject subject, msg_text text, msg_html html
                       FROM civicrm_msg_template mt
-                      JOIN civicrm_option_value ov ON workflow_id = ov.id
-                      JOIN civicrm_option_group og ON ov.option_group_id = og.id
-                      WHERE og.name = 'msg_tpl_workflow_meta' AND ov.name = 'test_preview' AND mt.is_default = 1";
+                      WHERE workflow_name = 'test_preview' AND mt.is_default = 1";
       $testDao = CRM_Core_DAO::executeQuery($query);
       $testDao->fetch();
 
@@ -493,7 +481,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
         $returnProperties,
         FALSE, FALSE, NULL,
         CRM_Utils_Token::flattenTokens($tokens),
-        // we should consider adding groupName and valueName here
+        // we should consider adding valueName here
         'CRM_Core_BAO_MessageTemplate'
       );
       $contact = $contact[$contactID];
@@ -513,7 +501,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
         [$contactID],
         NULL,
         CRM_Utils_Token::flattenTokens($tokens),
-        // we should consider adding groupName and valueName here
+        // we should consider adding valueName here
         'CRM_Core_BAO_MessageTemplate'
       );
       $contact = $contactArray[$contactID];
index 71fa8870ef9c416b78124cc6ddc835d6c2ac741d..f9d7dcb6754e11ccc9d6f8bee8cfb0f976d9dafe 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Core/MessageTemplate.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:41d8acdc31465a852930f88cf1604224)
+ * (GenCodeChecksum:90ed9b8ad7299f01d2f83ea90b7b7a15)
  */
 
 /**
@@ -75,6 +75,11 @@ class CRM_Core_DAO_MessageTemplate extends CRM_Core_DAO {
    */
   public $workflow_id;
 
+  /**
+   * @var string
+   */
+  public $workflow_name;
+
   /**
    * is this the default message template for the workflow referenced by workflow_id?
    *
@@ -197,7 +202,7 @@ class CRM_Core_DAO_MessageTemplate extends CRM_Core_DAO {
         'workflow_id' => [
           'name' => 'workflow_id',
           'type' => CRM_Utils_Type::T_INT,
-          'title' => ts('Message Template Workflow'),
+          'title' => ts('Deprecated field for Message Template Workflow.'),
           'description' => ts('a pseudo-FK to civicrm_option_value'),
           'where' => 'civicrm_msg_template.workflow_id',
           'table_name' => 'civicrm_msg_template',
@@ -205,6 +210,18 @@ class CRM_Core_DAO_MessageTemplate extends CRM_Core_DAO {
           'bao' => 'CRM_Core_BAO_MessageTemplate',
           'localizable' => 0,
         ],
+        'workflow_name' => [
+          'name' => 'workflow_name',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => ts('Message Template Workflow Name'),
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'where' => 'civicrm_msg_template.workflow_name',
+          'table_name' => 'civicrm_msg_template',
+          'entity' => 'MessageTemplate',
+          'bao' => 'CRM_Core_BAO_MessageTemplate',
+          'localizable' => 0,
+        ],
         'is_default' => [
           'name' => 'is_default',
           'type' => CRM_Utils_Type::T_BOOLEAN,
index 1980c9e3b980b734e0f1aa03ca9bf279d44424ea..0cd6dd3abf7cf98779dafd3f01f5e93641ba93b7 100644 (file)
@@ -60,11 +60,26 @@ class CRM_Upgrade_Incremental_php_FiveTwentySix extends CRM_Upgrade_Incremental_
   public function upgrade_5_26_alpha1($rev) {
     $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
     $this->addTask('Add option value for nl_BE', 'addNLBEOptionValue');
+    $this->addTask('Add workflow_name to civicrm_msg_template', 'addColumn', 'civicrm_msg_template', 'workflow_name',
+      "VARCHAR(255) DEFAULT NULL COMMENT 'Name of workflow'", FALSE, '5.26.0');
+    $this->addTask('Populate workflow_name in civicrm_msg_template', 'populateWorkflowName');
+
     // 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.
   }
 
+  /**
+   * Update workflow_name based on workflow_id values.
+   */
+  public function populateWorkflowName() {
+    CRM_Core_DAO::executeQuery('UPDATE civicrm_msg_template
+      LEFT JOIN  civicrm_option_value ov ON ov.id = workflow_id
+      SET workflow_name = ov.name'
+    );
+    return TRUE;
+  }
+
   /**
    * Add option value for nl_BE language.
    *
index ab7d85b966d3ab1802b2b0dd2219a95f54b34854..73098f5a5cf0f6d809bc8758355b66752a155e1c 100644 (file)
@@ -14,8 +14,6 @@
  *
  * @package CRM
  * @copyright CiviCRM LLC https://civicrm.org/licensing
- * $Id$
- *
  */
 
 
index 839bae64783ce8fb157e2dbffb056086e85fb8ec..8f33ce88c59578bd0f0ed0c3cdbb9d1651642953 100644 (file)
@@ -83,7 +83,9 @@ function civicrm_api3_message_template_get($params) {
  * Sends a template.
  *
  * @param array $params
+ *
  * @throws API_Exception
+ * @throws \CRM_Core_Exception
  */
 function civicrm_api3_message_template_send($params) {
   // Change external param names to internal ones
@@ -97,12 +99,12 @@ function civicrm_api3_message_template_send($params) {
     }
   }
   if (empty($params['messageTemplateID'])) {
-    if (empty($params['groupName']) || empty($params['valueName'])) {
+    if (empty($params['valueName'])) {
       // Can't use civicrm_api3_verify_mandatory for this because it would give the wrong field names
       throw new API_Exception(
-        "Mandatory key(s) missing from params array: requires id or option_group_name + option_value_name",
-        "mandatory_missing",
-        ["fields" => ['id', 'option_group_name', 'option_value_name']]
+        'Mandatory key(s) missing from params array: requires id or option_value_name',
+        'mandatory_missing',
+        ['fields' => ['id', 'option_value_name']]
       );
     }
   }
@@ -124,11 +126,6 @@ function _civicrm_api3_message_template_send_spec(&$params) {
   $params['id']['api.aliases'] = ['messageTemplateID', 'message_template_id'];
   $params['id']['type'] = CRM_Utils_Type::T_INT;
 
-  $params['option_group_name']['description'] = 'option group name of the template (required if no id supplied)';
-  $params['option_group_name']['title'] = 'Option Group Name';
-  $params['option_group_name']['api.aliases'] = ['groupName'];
-  $params['option_group_name']['type'] = CRM_Utils_Type::T_STRING;
-
   $params['option_value_name']['description'] = 'option value name of the template (required if no id supplied)';
   $params['option_value_name']['title'] = 'Option Value Name';
   $params['option_value_name']['api.aliases'] = ['valueName'];
index fd50f2212af91c9932b2184ad9dd2d101637b3a7..05f7e3e6d77a1fdc1763e078964ded027cf6d3bc 100644 (file)
@@ -14,6 +14,11 @@ class CRM_Core_BAO_MessageTemplateTest extends CiviUnitTestCase {
     parent::tearDown();
   }
 
+  /**
+   * Test message template send.
+   *
+   * @throws \CRM_Core_Exception
+   */
   public function testCaseActivityCopyTemplate() {
     $client_id = $this->individualCreate();
     $contact_id = $this->individualCreate();
@@ -36,9 +41,8 @@ class CRM_Core_BAO_MessageTemplateTest extends CiviUnitTestCase {
       'idHash' => substr(sha1(CIVICRM_SITE_KEY . '1234'), 0, 7),
     ];
 
-    list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate(
+    list($sent, $subject, $message) = CRM_Core_BAO_MessageTemplate::sendTemplate(
       [
-        'groupName' => 'msg_tpl_workflow_case',
         'valueName' => 'case_activity',
         'contactId' => $contact_id,
         'tplParams' => $tplParams,
index c3bd0573abd8a20536a84e3742259563aca69ab6..7db390114fbc6c8e22bc0c56b4552de1414314d5 100644 (file)
@@ -318,6 +318,8 @@ class api_v3_ActivityTest extends CiviUnitTestCase {
 
   /**
    * Test civicrm_activity_create() with valid parameters.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testActivityCreate() {
 
index b400d66eea4c0f5a4e8be6f0ca98667637502dad..ef3e0cf6f95af41d0a5b6cd5a5dfcd314dbeb38b 100644 (file)
   </field>
   <field>
     <name>workflow_id</name>
-    <title>Message Template Workflow</title>
+    <title>Deprecated field for Message Template Workflow.</title>
     <type>int unsigned</type>
     <comment>a pseudo-FK to civicrm_option_value</comment>
     <add>3.1</add>
   </field>
+  <field>
+    <name>workflow_name</name>
+    <title>Message Template Workflow Name</title>
+    <type>varchar</type>
+    <length>255</length>
+    <add>5.26</add>
+  </field>
   <field>
     <name>is_default</name>
     <title>Message Template Is Default?</title>
index b664df6674688f173fcf434df3f15c27ea01e7fd..8fcd5fe0354575b7fe35dd9b8b9d42bdd0ba0749 100644 (file)
@@ -103,14 +103,14 @@ INSERT INTO civicrm_option_value
 {/foreach}
 
 INSERT INTO civicrm_msg_template
-  (msg_title,      msg_subject,                  msg_text,                  msg_html,                  workflow_id,        is_default, is_reserved) VALUES
+  (msg_title,      msg_subject,                  msg_text,                  msg_html,    workflow_name,              workflow_id,        is_default, is_reserved) VALUES
 {foreach from=$ovNames key=gName item=ovs name=for_groups}
 {foreach from=$ovs key=vName item=title name=for_values}
       {fetch assign=subject file="`$gencodeXmlDir`/templates/message_templates/`$vName`_subject.tpl"}
       {fetch assign=text    file="`$gencodeXmlDir`/templates/message_templates/`$vName`_text.tpl"}
       {fetch assign=html    file="`$gencodeXmlDir`/templates/message_templates/`$vName`_html.tpl"}
-      ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', @tpl_ovid_{$vName}, 1,          0),
-      ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', @tpl_ovid_{$vName}, 0,          1) {if $smarty.foreach.for_groups.last and $smarty.foreach.for_values.last};{else},{/if}
+      ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', '{$vName}', @tpl_ovid_{$vName}, 1,          0),
+      ('{$title}', '{$subject|escape:"quotes"}', '{$text|escape:"quotes"}', '{$html|escape:"quotes"}', '{$vName}', @tpl_ovid_{$vName}, 0,          1) {if $smarty.foreach.for_groups.last and $smarty.foreach.for_values.last};{else},{/if}
 {/foreach}
 {/foreach}