Skip to content

Commit

Permalink
CRM-19690 - Mailing API - Encode and decode template_options
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
totten committed Jan 5, 2017
1 parent 0bda941 commit 8f03c76
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
28 changes: 26 additions & 2 deletions api/v3/Mailing.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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);

}

Expand Down Expand Up @@ -229,7 +233,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;
}

/**
Expand Down
38 changes: 38 additions & 0 deletions tests/phpunit/api/v3/MailingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,44 @@ public function testTemplateTypeOptions() {
$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
Expand Down

0 comments on commit 8f03c76

Please sign in to comment.