diff --git a/CRM/Utils/API/HTMLInputCoder.php b/CRM/Utils/API/HTMLInputCoder.php index 444de7f3eb10..7961fedd8f46 100644 --- a/CRM/Utils/API/HTMLInputCoder.php +++ b/CRM/Utils/API/HTMLInputCoder.php @@ -62,6 +62,8 @@ public function getSkipFields() { 'html_message', 'body_html', 'msg_html', + // MessageTemplate subject might contain the < character in a smarty tag + 'msg_subject', 'description', 'intro', 'thankyou_text', diff --git a/Civi/Api4/Action/MessageTemplate/Revert.php b/Civi/Api4/Action/MessageTemplate/Revert.php new file mode 100644 index 000000000000..412b9baf303c --- /dev/null +++ b/Civi/Api4/Action/MessageTemplate/Revert.php @@ -0,0 +1,39 @@ +getCheckPermissions()) + ->addSelect('id', 'master_id', 'master_id.msg_subject', 'master_id.msg_html') + ->addWhere('id', 'IN', array_column($items, 'id')) + ->execute(); + foreach ($revertable as $item) { + if (!empty($item['master_id'])) { + MessageTemplate::update(FALSE) + ->addWhere('id', '=', $item['id']) + ->addValue('msg_subject', $item['master_id.msg_subject']) + ->addValue('msg_html', $item['master_id.msg_html']) + ->execute(); + } + } + } + +} diff --git a/Civi/Api4/MessageTemplate.php b/Civi/Api4/MessageTemplate.php index b06603f9cd70..d9f931cb071c 100644 --- a/Civi/Api4/MessageTemplate.php +++ b/Civi/Api4/MessageTemplate.php @@ -20,4 +20,13 @@ */ class MessageTemplate extends Generic\DAOEntity { + /** + * @param bool $checkPermissions + * @return Action\MessageTemplate\Revert + */ + public static function revert($checkPermissions = TRUE) { + return (new Action\MessageTemplate\Revert('MessageTemplate', __FUNCTION__)) + ->setCheckPermissions($checkPermissions); + } + } diff --git a/tests/phpunit/api/v4/Entity/MessageTemplateTest.php b/tests/phpunit/api/v4/Entity/MessageTemplateTest.php index c8a98b6f0c8c..9fa6687a54f4 100644 --- a/tests/phpunit/api/v4/Entity/MessageTemplateTest.php +++ b/tests/phpunit/api/v4/Entity/MessageTemplateTest.php @@ -143,31 +143,34 @@ public function testMessageTemplateMasterID(): void { \CRM_Core_Transaction::create(TRUE)->run(function(\CRM_Core_Transaction $tx) { $tx->rollback(); - $messageTemplateID = MessageTemplate::get() + MessageTemplate::update(FALSE) + ->addWhere('workflow_name', '=', 'contribution_offline_receipt') + ->addValue('msg_subject', 'Subject test {if 1 > 2} smarty{/if}') + ->addValue('msg_html', '

Body test {if 1 > 2} markup{/if}

') + ->execute(); + + $originalTemplate = MessageTemplate::get() ->addWhere('is_default', '=', 1) ->addWhere('workflow_name', '=', 'contribution_offline_receipt') - ->addSelect('id') - ->execute()->first()['id']; - $messageTemplateIDReserved = MessageTemplate::get() + ->addSelect('id', 'msg_subject', 'msg_html', 'master_id', 'master_id.msg_subject') + ->execute()->first(); + $messageTemplateID = $originalTemplate['id']; + $reservedTemplate = MessageTemplate::get() ->addWhere('is_reserved', '=', 1) ->addWhere('workflow_name', '=', 'contribution_offline_receipt') - ->addSelect('id') - ->execute()->first()['id']; - $msgTpl = MessageTemplate::get() - ->addSelect('msg_subject', 'master_id', 'master_id.msg_subject') - ->addWhere('id', '=', $messageTemplateID) + ->addSelect('id', 'msg_subject', 'msg_html') ->execute()->first(); - // confirm subject is set - $this->assertNotNull($msgTpl['msg_subject']); - // message is unchanged from original so both of these should be null - $this->assertNull($msgTpl['master_id']); - $this->assertNull($msgTpl['master_id.msg_subject']); + $messageTemplateIDReserved = $reservedTemplate['id']; + + $this->assertEquals('Subject test {if 1 > 2} smarty{/if}', $originalTemplate['msg_subject']); + $this->assertEquals('

Body test {if 1 > 2} markup{/if}

', $originalTemplate['msg_html']); + $this->assertNull($originalTemplate['master_id']); + $this->assertNull($originalTemplate['master_id.msg_subject']); MessageTemplate::update() ->addWhere('id', '=', $messageTemplateID) ->setValues([ 'msg_subject' => 'Hello world', - 'msg_text' => 'Hello world', 'msg_html' => '

Hello world

', ]) ->execute(); @@ -176,13 +179,28 @@ public function testMessageTemplateMasterID(): void { ->addWhere('id', '=', $messageTemplateID) ->execute()->first(); // confirm subject is set - $this->assertNotNull($msgTpl['msg_subject']); + $this->assertEquals('Hello world', $msgTpl['msg_subject']); // message is changed so both of these should be set $this->assertEquals($msgTpl['master_id'], $messageTemplateIDReserved); $this->assertNotNull($msgTpl['master_id.msg_subject']); // these should be different $this->assertNotEquals($msgTpl['msg_subject'], $msgTpl['master_id.msg_subject']); + // Now revert it + MessageTemplate::revert(FALSE) + ->addWhere('id', '=', $messageTemplateID) + ->execute(); + + $msgTpl = MessageTemplate::get() + ->addSelect('msg_subject', 'msg_html', 'master_id', 'master_id.msg_subject') + ->addWhere('id', '=', $messageTemplateID) + ->execute()->first(); + // confirm subject is reverted + $this->assertEquals($originalTemplate['msg_subject'], $msgTpl['msg_subject']); + $this->assertEquals($originalTemplate['msg_html'], $msgTpl['msg_html']); + // message is unchanged from original so both of these should be null + $this->assertNull($msgTpl['master_id']); + $this->assertNull($msgTpl['master_id.msg_subject']); }); }