CRM-15578 - Mailing.create - Fix updates to "groups" and "mailings". Add test.
authorTim Otten <totten@civicrm.org>
Mon, 24 Nov 2014 01:35:23 +0000 (17:35 -0800)
committerTim Otten <totten@civicrm.org>
Mon, 24 Nov 2014 01:35:23 +0000 (17:35 -0800)
CRM/Mailing/BAO/Mailing.php
api/v3/MailingGroup.php
tests/phpunit/api/v3/MailingTest.php
tests/phpunit/api/v3/SyntaxConformanceTest.php

index a18d825335e0d00ab8cb5e7c4d8da3476a50d0c4..8954babc182792ce76c6859fb00376d4319fdcd7 100644 (file)
@@ -1654,16 +1654,8 @@ ORDER BY   civicrm_email.is_bulkmail DESC
     $mg = new CRM_Mailing_DAO_MailingGroup();
     foreach (array('groups', 'mailings') as $entity) {
       foreach (array('include', 'exclude', 'base') as $type) {
-        if (isset($params[$entity]) && !empty($params[$entity][$type]) &&
-          is_array($params[$entity][$type])) {
-          foreach ($params[$entity][$type] as $entityId) {
-            $mg->reset();
-            $mg->mailing_id   = $mailing->id;
-            $mg->entity_table = ($entity == 'groups') ? $groupTableName : $mailingTableName;
-            $mg->entity_id    = $entityId;
-            $mg->group_type   = $type;
-            $mg->save();
-          }
+        if (isset($params[$entity][$type])) {
+          self::replaceGroups($mailing->id, $type, $entity, $params[$entity][$type]);
         }
       }
     }
@@ -1706,6 +1698,28 @@ ORDER BY   civicrm_email.is_bulkmail DESC
     return $mailing;
   }
 
+  /**
+   * Replace the list of recipients on a given mailing
+   *
+   * @param int $mailingId
+   * @param string $type 'include' or 'exclude'
+   * @param string $entity 'groups' or 'mailings'
+   * @param array<int> $entityIds
+   * @throws CiviCRM_API3_Exception
+   */
+  public static function replaceGroups($mailingId, $type, $entity, $entityIds) {
+    $values = array();
+    foreach ($entityIds as $entityId) {
+      $values[] = array('entity_id' => $entityId);
+    }
+    civicrm_api3('mailing_group', 'replace', array(
+      'mailing_id' =>  $mailingId,
+      'group_type' => $type,
+      'entity_table' => ($entity == 'groups') ? CRM_Contact_BAO_Group::getTableName() : CRM_Mailing_BAO_Mailing::getTableName(),
+      'values' => $values,
+    ));
+  }
+
   /**
    * get hash value of the mailing
    *
index 117c82dbf68845bc59d6ebc9e469e72ceb8a4390..c76e3635b418675c4ad3f8ac69548c04287af0c5 100644 (file)
@@ -94,6 +94,10 @@ function civicrm_api3_mailing_group_event_subscribe($params) {
   return civicrm_api('mailing_event_subscribe', 'create', $params);
 }
 
+function civicrm_api3_mailing_group_create($params) {
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
 /**
  * @param $params
  *
index 54385451961004b4831ccfef115a1924c439cdb4..6e72f7c9fa6b61ca257f180e5c28b1463e429f6b 100755 (executable)
@@ -82,6 +82,50 @@ class api_v3_MailingTest extends CiviUnitTestCase {
     $this->getAndCheck($this->_params, $result['id'], 'mailing');
   }
 
+  /**
+   * The Mailing.create API supports magic properties "groups[include,enclude]" and "mailings[include,exclude]".
+   * Make sure these work
+   */
+  public function testMagicGroups_create_update() {
+    // BEGIN SAMPLE DATA
+    $groupIDs['a'] = $this->groupCreate(array('name' => 'Example include group', 'title' => 'Example include group'));
+    $groupIDs['b'] = $this->groupCreate(array('name' => 'Example exclude group', 'title' => 'Example exclude group'));
+    $contactIDs['a'] = $this->individualCreate(array('email' => 'include.me@example.org', 'first_name' => 'Includer', 'last_name' => 'Person'));
+    $contactIDs['b'] = $this->individualCreate(array('email' => 'exclude.me@example.org', 'last_name' => 'Excluder', 'last_name' => 'Excluder'));
+    $this->callAPISuccess('GroupContact', 'create', array('group_id' => $groupIDs['a'], 'contact_id' => $contactIDs['a']));
+    $this->callAPISuccess('GroupContact', 'create', array('group_id' => $groupIDs['b'], 'contact_id' => $contactIDs['b']));
+    // END SAMPLE DATA
+
+    // ** Pass 1: Create
+    $createParams = $this->_params;
+    $createParams['groups']['include'] = array($groupIDs['a']);
+    $createParams['groups']['exclude'] = array();
+    $createParams['mailings']['include'] = array();
+    $createParams['mailings']['exclude'] = array();
+    $createResult = $this->callAPISuccess('Mailing', 'create', $createParams);
+    $getGroup1 = $this->callAPISuccess('MailingGroup', 'get', array('mailing_id' => $createResult['id']));
+    $getGroup1_ids = array_values(CRM_Utils_Array::collect('entity_id', $getGroup1['values']));
+    $this->assertEquals(array($groupIDs['a']), $getGroup1_ids);
+
+    // ** Pass 2: Update without any changes to groups[include]
+    $nullopParams = $createParams;
+    $nullopParams['id'] = $createResult['id'];
+    unset($nullopParams['groups']['include']);
+    $this->callAPISuccess('Mailing', 'create', $nullopParams);
+    $getGroup2 = $this->callAPISuccess('MailingGroup', 'get', array('mailing_id' => $createResult['id']));
+    $getGroup2_ids = array_values(CRM_Utils_Array::collect('entity_id', $getGroup2['values']));
+    $this->assertEquals(array($groupIDs['a']), $getGroup2_ids);
+
+    // ** Pass 3: Update with different groups[include]
+    $updateParams = $createParams;
+    $updateParams['id'] = $createResult['id'];
+    $updateParams['groups']['include'] = array($groupIDs['b']);
+    $this->callAPISuccess('Mailing', 'create', $updateParams);
+    $getGroup3 = $this->callAPISuccess('MailingGroup', 'get', array('mailing_id' => $createResult['id']));
+    $getGroup3_ids = array_values(CRM_Utils_Array::collect('entity_id', $getGroup3['values']));
+    $this->assertEquals(array($groupIDs['b']), $getGroup3_ids);
+  }
+
   public function testMailerPreview() {
     // BEGIN SAMPLE DATA
     $contactID =  $this->individualCreate();
index ca43477fb88d0d4d5315fa63c2f65ad2658aaee3..807959c4030a446dc74bc6f5342bb441ec2e5fa0 100644 (file)
@@ -235,7 +235,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase {
    * @return array
    */
   public static function toBeSkipped_create($sequential = FALSE) {
-    $entitiesWithoutCreate = array('MailingGroup', 'Constant', 'Entity', 'Location', 'Profile', 'MailingRecipients');
+    $entitiesWithoutCreate = array('Constant', 'Entity', 'Location', 'Profile', 'MailingRecipients');
     if ($sequential === TRUE) {
       return $entitiesWithoutCreate;
     }