Skip to content

Commit

Permalink
MessageTemplate API - Fix saving of templates with workflow_name sans…
Browse files Browse the repository at this point in the history
… workflow_id

Overview
--------

This fixes a bug when saving (updating) a `MessageTemplate` record that
involves a `workflow_name` and no `workflow_id`. It is an alternative to #21674.

Steps to  reproduce
-------------------

Suppose you read a MessagTemplate with values:

```php
$values = ['workflow_name' => 'foo', 'workflow_id' => NULL, ...]
```

Then you save it back:

```php
civicrm_api4('MessageTemplate', 'update', [
  'values' => $values
]);
```

Before
------

The `update` raises an exception.

After
-----

The `update` works.
  • Loading branch information
totten committed Oct 1, 2021
1 parent 9d6c81e commit d53da69
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 1 deletion.
5 changes: 4 additions & 1 deletion CRM/Core/BAO/MessageTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ public static function add(&$params) {
}

// The workflow_id and workflow_name should be sync'd. But what mix of inputs do we have to work with?
switch ((empty($params['workflow_id']) ? '' : 'id') . (empty($params['workflow_name']) ? '' : 'name')) {
$empty = function ($key) use (&$params) {
return empty($params[$key]) || $params[$key] === 'null';
};
switch (($empty('workflow_id') ? '' : 'id') . ($empty('workflow_name') ? '' : 'name')) {
case 'id':
$params['workflow_name'] = array_search($params['workflow_id'], self::getWorkflowNameIdMap());
break;
Expand Down
119 changes: 119 additions & 0 deletions tests/phpunit/api/v4/Entity/MessageTemplateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

/**
*
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/

namespace api\v4\Entity;

use api\v4\UnitTestCase;
use Civi\Test\DbTestTrait;
use Civi\Test\GenericAssertionsTrait;
use Civi\Test\TransactionalInterface;

/**
* @group headless
*/
class MessageTemplateTest extends UnitTestCase implements TransactionalInterface {

use GenericAssertionsTrait;
use DbTestTrait;

private $baseTpl = [
'msg_title' => 'My Template',
'msg_subject' => 'My Subject',
'msg_text' => 'My body as text',
'msg_html' => '<p>My body as HTML</p>',
'is_reserved' => TRUE,
'is_default' => FALSE,
];

/**
* Create/update a MessageTemplate with workflow_name and no corresponding workflow_id.
*/
public function testWorkflowName_clean() {
$create = civicrm_api4('MessageTemplate', 'create', [
'values' => $this->baseTpl + ['workflow_name' => 'first', 'workflow_id' => NULL],
])->single();
$this->assertDBQuery('first', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery(NULL, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);

civicrm_api4('MessageTemplate', 'update', [
'where' => [['id', '=', $create['id']]],
'values' => ['workflow_name' => 'second', 'workflow_id' => NULL],
])->single();
$this->assertDBQuery('second', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery(NULL, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
}

/**
* Create/update a MessageTemplate with workflow_name - a name which happens to have an older/corresponding workflow_id.
*/
public function testWorkflowName_legacyMatch() {
[$firstId, $secondId] = $this->createFirstSecond();

$create = civicrm_api4('MessageTemplate', 'create', [
'values' => $this->baseTpl + ['workflow_name' => 'first', 'workflow_id' => NULL],
])->single();
$this->assertDBQuery('first', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery($firstId, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);

civicrm_api4('MessageTemplate', 'update', [
'where' => [['id', '=', $create['id']]],
'values' => ['workflow_name' => 'second', 'workflow_id' => NULL],
])->single();
$this->assertDBQuery('second', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery($secondId, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
}

/**
* Create/update a MessageTempalte with workflow_id. Ensure the newer workflow_name is set.
*/
public function testWorkflowId_legacyMatch() {
[$firstId, $secondId] = $this->createFirstSecond();

$create = civicrm_api4('MessageTemplate', 'create', [
'values' => $this->baseTpl + ['workflow_id' => $firstId, 'workflow_name' => NULL],
])->single();
$this->assertDBQuery('first', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery($firstId, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);

civicrm_api4('MessageTemplate', 'update', [
'where' => [['id', '=', $create['id']]],
'values' => ['workflow_id' => $secondId, 'workflow_name' => NULL],
])->single();
$this->assertDBQuery('second', 'SELECT workflow_name FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
$this->assertDBQuery($secondId, 'SELECT workflow_id FROM civicrm_msg_template WHERE id = %1', [1 => [$create['id'], 'Int']]);
}

protected function createFirstSecond() {
$first = civicrm_api4('OptionValue', 'create', [
'values' => [
'option_group_id:name' => 'msg_tpl_workflow_meta',
'label' => 'First',
'name' => 'first',
],
]);
$second = civicrm_api4('OptionValue', 'create', [
'values' => [
'option_group_id:name' => 'msg_tpl_workflow_meta',
'label' => 'Second',
'name' => 'second',
],
]);
return [$first->single()['id'], $second->single()['id']];
}

}

0 comments on commit d53da69

Please sign in to comment.