From 6bc3944aad39af1b16bb68c187b0e3879562604d Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 2 Dec 2016 10:24:02 -0800 Subject: [PATCH] CRM-19690 - Mailing API - Encode and decode `template_options` Present API consumers with a consistent, array-based interface for reading and writing properties in a Mailing. Suppose you're submitting a REST request to create a mailing. The REST request as a whole is encoded with JSON. With the default API behavior, you would need to double-encode the `template_options`, e.g. roughly ``` POST rest.php json_encode([ entity => Mailing action => create params => [ template_options => json_encode([...]) ] ]) ``` With this patch, you only need to encode the request once. This parallels the approach used in CaseType API (for the XML `definition` field). --- api/v3/Mailing.php | 28 ++++++++++++++++++-- tests/phpunit/api/v3/MailingTest.php | 38 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/api/v3/Mailing.php b/api/v3/Mailing.php index c456276c75..35d3f2fb4c 100644 --- a/api/v3/Mailing.php +++ b/api/v3/Mailing.php @@ -43,6 +43,9 @@ * @throws \Civi\API\Exception\UnauthorizedException */ function civicrm_api3_mailing_create($params) { + if (isset($params['template_options']) && is_array($params['template_options'])) { + $params['template_options'] = $params['template_options'] === array() ? '{}' : json_encode($params['template_options']); + } if (CRM_Mailing_Info::workflowEnabled()) { // Note: 'schedule mailings' and 'approve mailings' can update certain fields, but can't create. @@ -64,7 +67,8 @@ function civicrm_api3_mailing_create($params) { $safeParams = $params; } $safeParams['_evil_bao_validator_'] = 'CRM_Mailing_BAO_Mailing::checkSendable'; - return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $safeParams); + $result = _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $safeParams); + return _civicrm_api3_mailing_get_formatResult($result); } @@ -238,7 +242,27 @@ function civicrm_api3_mailing_delete($params) { * @return array */ function civicrm_api3_mailing_get($params) { - return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); + $result = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); + return _civicrm_api3_mailing_get_formatResult($result); +} + +/** + * Format definition. + * + * @param array $result + * + * @return array + * @throws \CRM_Core_Exception + */ +function _civicrm_api3_mailing_get_formatResult($result) { + if (isset($result['values']) && is_array($result['values'])) { + foreach ($result['values'] as $key => $caseType) { + if (isset($result['values'][$key]['template_options']) && is_string($result['values'][$key]['template_options'])) { + $result['values'][$key]['template_options'] = json_decode($result['values'][$key]['template_options'], TRUE); + } + } + } + return $result; } /** diff --git a/tests/phpunit/api/v3/MailingTest.php b/tests/phpunit/api/v3/MailingTest.php index d8c65c17d6..eb60ca1085 100644 --- a/tests/phpunit/api/v3/MailingTest.php +++ b/tests/phpunit/api/v3/MailingTest.php @@ -93,6 +93,44 @@ class api_v3_MailingTest extends CiviUnitTestCase { $this->assertTrue(isset($types['values']['traditional'])); } + /** + * The `template_options` field should be treated a JSON object. + * + * This test will create, read, and update the field. + */ + public function testMailerCreateTemplateOptions() { + // 1. Create mailing with template_options. + $params = $this->_params; + $params['template_options'] = json_encode(array('foo' => 'bar_1')); + $createResult = $this->callAPISuccess('mailing', 'create', $params); + $id = $createResult['id']; + $this->assertDBQuery('{"foo":"bar_1"}', 'SELECT template_options FROM civicrm_mailing WHERE id = %1', array( + 1 => array($id, 'Int'), + )); + $this->assertEquals('bar_1', $createResult['values'][$id]['template_options']['foo']); + + // 2. Get mailing with template_options. + $getResult = $this->callAPISuccess('mailing', 'get', array( + 'id' => $id, + )); + $this->assertEquals('bar_1', $getResult['values'][$id]['template_options']['foo']); + $getValueResult = $this->callAPISuccess('mailing', 'getvalue', array( + 'id' => $id, + 'return' => 'template_options', + )); + $this->assertEquals('bar_1', $getValueResult['foo']); + + // 3. Update mailing with template_options. + $updateResult = $this->callAPISuccess('mailing', 'create', array( + 'id' => $id, + 'template_options' => array('foo' => 'bar_2'), + )); + $this->assertDBQuery('{"foo":"bar_2"}', 'SELECT template_options FROM civicrm_mailing WHERE id = %1', array( + 1 => array($id, 'Int'), + )); + $this->assertEquals('bar_2', $updateResult['values'][$id]['template_options']['foo']); + } + /** * The Mailing.create API supports magic properties "groups[include,enclude]" and "mailings[include,exclude]". * Make sure these work -- 2.25.1