CRM-12357
authorDonald A. Lobo <lobo@civicrm.org>
Mon, 15 Apr 2013 17:19:16 +0000 (10:19 -0700)
committerDonald A. Lobo <lobo@civicrm.org>
Mon, 15 Apr 2013 17:19:31 +0000 (10:19 -0700)
----------------------------------------
* CRM-12357: Split Mailings into separate tab if activity creation is disabled
  http://issues.civicrm.org/jira/browse/CRM-12357

14 files changed:
CRM/Admin/Form/Preferences/Mailing.php
CRM/Contact/Page/View/Summary.php
CRM/Event/Info.php
CRM/Event/xml/Menu/Event.xml
CRM/Mailing/BAO/Job.php
CRM/Mailing/BAO/Mailing.php
CRM/Mailing/Info.php
CRM/Mailing/Page/Tab.php [new file with mode: 0644]
CRM/Mailing/xml/Menu/Mailing.xml
CRM/Utils/REST.php
api/v3/GroupContact.php
api/v3/MailingContact.php [new file with mode: 0644]
templates/CRM/Mailing/Page/Tab.tpl [new file with mode: 0644]
tests/phpunit/api/v3/MailingContactTest.php [new file with mode: 0644]

index 1154bdddae60eb1e91b5c2cf06503cb934edc04b..1c05b927d297f8ea62589e59e22470c504abe421 100644 (file)
@@ -92,6 +92,13 @@ class CRM_Admin_Form_Preferences_Mailing extends CRM_Admin_Form_Preferences {
           'weight' => 7,
           'description' => NULL,
         ),
+        'write_activity_record' =>
+        array(
+          'html_type' => 'checkbox',
+          'title' => ts('Enable CiviMail to create activities on delivery'),
+          'weight' => 8,
+          'description' => NULL,
+        ),
       ),
     );
 
index 8ba24f8066c368ac3bd7cb04be80c6a2303d6024..7053d7f35c01f5d2e5482a429b7dde434bd2847b 100644 (file)
@@ -270,9 +270,23 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
     $components = CRM_Core_Component::getEnabledComponents();
 
     foreach ($components as $name => $component) {
-      if (CRM_Utils_Array::value($name, $this->_viewOptions) &&
-        CRM_Core_Permission::access($component->name)
+      if (
+         (CRM_Utils_Array::value($name, $this->_viewOptions) ||
+           $name == 'CiviMail') &&
+         CRM_Core_Permission::access($component->name)
       ) {
+        if ($name == 'CiviMail') {
+          // if we are writing activity records, we skip the tab
+          if (CRM_Core_BAO_Setting::getItem(
+              CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+              'write_activity_record',
+              NULL,
+              TRUE
+            )) {
+            continue;
+          }
+        }
+
         $elem = $component->registerTab();
 
         // FIXME: not very elegant, probably needs better approach
@@ -306,7 +320,27 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
       }
     }
 
-    $rest = array('activity' => ts('Activities'),
+    // check if mailings is enabled
+    // and we dont create activities for mailings
+    $mailingComp = CRM_Utils_Array::value('CiviMail', $components);
+    if (
+      $mailingComp &&
+      CRM_Core_Permission::access($mailingComp->name)
+    ) {
+      $writeActivity = CRM_Core_BAO_Setting::getItem(
+        CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+        'write_activity_record',
+        NULL,
+        TRUE
+      );
+      if (!$writeActivity) {
+        $elem = $mailingCom->registerTab();
+
+      }
+    }
+
+    $rest = array(
+      'activity' => ts('Activities'),
       'case' => ts('Cases'),
       'rel' => ts('Relationships'),
       'group' => ts('Groups'),
@@ -332,7 +366,8 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
 
     // now add all the custom tabs
     $entityType = $this->get('contactType');
-    $activeGroups = CRM_Core_BAO_CustomGroup::getActiveGroups($entityType,
+    $activeGroups = CRM_Core_BAO_CustomGroup::getActiveGroups(
+      $entityType,
       'civicrm/contact/view/cd',
       $this->_contactId
     );
index e3b595c9e3818534379063038b4d7d104a560b9c..7de7b7621a6c00a8e1d0f97453017ce3e995b4d4 100644 (file)
@@ -116,7 +116,7 @@ class CRM_Event_Info extends CRM_Core_Component_Info {
               'query' => "reset=1&action=add&context=standalone&mode=live",
               'ref' => 'new-participant-cc',
               'title' => $title,
-            )));        
+            )));
       }
     }
   }
index b0267b1c2ae5870282b724acd49e66d5f2553f63..96785c4489f614bda45335a9c9a61083bb3d286f 100644 (file)
      <access_arguments>administer CiviCRM,access CiviEvent</access_arguments>
      <adminGroup>CiviEvent</adminGroup>
      <weight>415</weight>
-  </item>  
+  </item>
   <item>
      <path>civicrm/admin/setting/preferences/event</path>
      <title>CiviEvent Component Settings</title>
index 704484cedcc570885335613725b5ec565707606a..2a21d716f1968cd2e84176b80ef023702b3476ff 100644 (file)
@@ -669,7 +669,8 @@ VALUES (%1, %2, %3, %4, %5, %6, %7)
 
           // seems like we have too many of them in a row, we should
           // write stuff to disk and abort the cron job
-          $this->writeToDB($deliveredParams,
+          $this->writeToDB(
+            $deliveredParams,
             $targetParams,
             $mailing,
             $job_date
@@ -699,7 +700,8 @@ VALUES (%1, %2, %3, %4, %5, %6, %7)
 
         $count++;
         if ($count % CRM_Core_DAO::BULK_MAIL_INSERT_COUNT == 0) {
-          $this->writeToDB($deliveredParams,
+          $this->writeToDB(
+            $deliveredParams,
             $targetParams,
             $mailing,
             $job_date
@@ -733,7 +735,8 @@ VALUES (%1, %2, %3, %4, %5, %6, %7)
       }
     }
 
-    $result = $this->writeToDB($deliveredParams,
+    $result = $this->writeToDB(
+      $deliveredParams,
       $targetParams,
       $mailing,
       $job_date
@@ -835,41 +838,56 @@ AND    status IN ( 'Scheduled', 'Running', 'Paused' )
     return '';
   }
 
-  public function writeToDB(&$deliveredParams,
+  public function writeToDB(
+    &$deliveredParams,
     &$targetParams,
     &$mailing,
     $job_date
   ) {
     static $activityTypeID = NULL;
+    static $writeActivity = NULL;
 
     if (!empty($deliveredParams)) {
       CRM_Mailing_Event_BAO_Delivered::bulkCreate($deliveredParams);
       $deliveredParams = array();
     }
 
-    $result = TRUE;
-    if (!empty($targetParams) &&
-      !empty($mailing->scheduled_id)
-    ) {
+    if ($writeActivity === NULL) {
+      $writeActivity = CRM_Core_BAO_Setting::getItem(
+        CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+        'write_activity_record',
+        NULL,
+        TRUE
+      );
+    }
 
+    if (!$writeActivity) {
+      return TRUE;
+    }
+
+    $result = TRUE;
+    if (!empty($targetParams) && !empty($mailing->scheduled_id)) {
       if (!$activityTypeID) {
-        $activityTypeID = CRM_Core_OptionGroup::getValue('activity_type',
-          'Bulk Email',
-          'name'
-        );
         if ($mailing->sms_provider_id) {
           $mailing->subject = $mailing->name;
-          $activityTypeID = CRM_Core_OptionGroup::getValue('activity_type',
+          $activityTypeID = CRM_Core_OptionGroup::getValue(
+            'activity_type',
             'Mass SMS',
             'name'
           );
         }
+        else {
+          $activityTypeID = CRM_Core_OptionGroup::getValue(
+            'activity_type',
+            'Bulk Email',
+            'name'
+          );
+        }
         if (!$activityTypeID) {
           CRM_Core_Error::fatal();
         }
       }
 
-
       $activity = array(
         'source_contact_id' => $mailing->scheduled_id,
         // CRM-9519
@@ -889,14 +907,14 @@ AND    status IN ( 'Scheduled', 'Running', 'Paused' )
 SELECT id
 FROM   civicrm_activity
 WHERE  civicrm_activity.activity_type_id = %1
-AND    civicrm_activity.source_record_id = %2";
+AND    civicrm_activity.source_record_id = %2
+";
 
-      $queryParams = array(1 => array($activityTypeID, 'Integer'),
+      $queryParams = array(
+        1 => array($activityTypeID, 'Integer'),
         2 => array($this->mailing_id, 'Integer'),
       );
-      $activityID = CRM_Core_DAO::singleValueQuery($query,
-        $queryParams
-      );
+      $activityID = CRM_Core_DAO::singleValueQuery($query, $queryParams);
 
       if ($activityID) {
         $activity['id'] = $activityID;
@@ -913,9 +931,7 @@ AND    civicrm_activity.source_record_id = %2";
         }
       }
 
-      if (is_a(CRM_Activity_BAO_Activity::create($activity),
-          'CRM_Core_Error'
-        )) {
+      if (is_a(CRM_Activity_BAO_Activity::create($activity), 'CRM_Core_Error')) {
         $result = FALSE;
       }
 
index b3b406ea3cca17776e194fce514c1c23df65722c..515bf974177779841a8a606189ecc353d414533e 100644 (file)
@@ -2639,7 +2639,8 @@ WHERE  civicrm_mailing_job.id = %1
       shuffle($lockArray);
 
       // check if we are using global locks
-      $serverWideLock = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+      $serverWideLock = CRM_Core_BAO_Setting::getItem(
+        CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
         'civimail_server_wide_lock'
       );
       foreach ($lockArray as $lockID) {
index db210f66822f2fa22f5e1b59514cfcdd3e693c1a..59cc5dd8f35fd7bb3d6ee4a3ba0eb57dd9561066 100644 (file)
@@ -109,8 +109,12 @@ class CRM_Mailing_Info extends CRM_Core_Component_Info {
 
   // docs inherited from interface
   public function registerTab() {
-    // this component doesn't use contact record tabs
-    return NULL;
+    return array(
+      'title' => ts('Mailings'),
+      'id' => 'mailing',
+      'url' => 'mailing',
+      'weight' => 45,
+    );
   }
 
   // docs inherited from interface
diff --git a/CRM/Mailing/Page/Tab.php b/CRM/Mailing/Page/Tab.php
new file mode 100644 (file)
index 0000000..68d135a
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * $Id$
+ *
+ */
+
+/**
+ * This class handle mailing and contact related functions
+ *
+ */
+class CRM_Mailing_Page_Tab extends CRM_Contact_Page_View {
+  /**
+   * The action links that we need to display for the browse screen
+   *
+   * @var array
+   * @static
+   */
+  static $_links = NULL;
+  public $_permission = NULL;
+  public $_contactId = NULL;
+
+  /**
+   * This function is called when action is browse
+   *
+   * return null
+   * @access public
+   */
+  function browse() {
+  }
+
+  /**
+   * build all the data structures needed to build the form
+   *
+   * @return void
+   * @access public
+   */
+  function preProcess() {
+    $context       = CRM_Utils_Request::retrieve('context', 'String', $this);
+    $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'browse');
+    $this->_id     = CRM_Utils_Request::retrieve('id', 'Positive', $this);
+
+    $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
+    $displayName = CRM_Contact_BAO_Contact::displayName($this->_contactId);
+
+    $this->assign('contactId', $this->_contactId);
+    $this->assign('displayName', $displayName);
+
+    // check logged in url permission
+    CRM_Contact_Page_View::checkUserPermission($this);
+
+    // set page title
+    CRM_Utils_System::setTitle(ts('Mailings sent to') .  ' ' . $displayName);
+  }
+
+  /**
+   * This function is the main function that is called when the page loads,
+   * it decides the which action has to be taken for the page.
+   *
+   * return null
+   * @access public
+   */
+  function run() {
+    $this->preProcess();
+    $this->browse();
+
+    return parent::run();
+  }
+}
+
index 341126b9b1afc37d49d9b6c1f7326152933b5a45..52f972474e0e7e99323dc7f391900d9ec3ea6c55 100644 (file)
      <path>civicrm/ajax/template</path>
      <page_callback>CRM_Mailing_Page_AJAX::template</page_callback>
      <access_arguments>access CiviCRM</access_arguments>
-  </item>  
+  </item>
   <item>
      <path>civicrm/mailing/schedule</path>
      <title>Schedule Mailing</title>
      <path>civicrm/mailing/approve</path>
      <title>Approve Mailing</title>
      <page_callback>CRM_Mailing_Form_Approve</page_callback>
-     <access_arguments>approve mailings</access_arguments>     
+     <access_arguments>approve mailings</access_arguments>
      <weight>850</weight>
   </item>
+  <item>
+     <path>civicrm/contact/view/mailing</path>
+     <page_callback>CRM_Mailing_Page_Tab</page_callback>
+  </item>
 </menu>
index 28b088adf2099c31edcfc9f26efcca16d89cf16e..d48ac579eb7fa3fcaf9a0b8638ae0aaceef85669 100644 (file)
@@ -536,9 +536,11 @@ class CRM_Utils_REST {
    **/
   static function ajaxJson() {
     require_once 'api/v3/utils.php';
-    if (!$config->debug && (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) ||
+    if (!$config->debug &&
+      (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) ||
         $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest"
-      )) {
+      )
+    ) {
       $error = civicrm_api3_create_error("SECURITY ALERT: Ajax requests can only be issued by javascript clients, eg. CRM.api().",
         array(
           'IP' => $_SERVER['REMOTE_ADDR'],
@@ -590,7 +592,7 @@ class CRM_Utils_REST {
     // restrict calls to this etc
     // the request has to be sent by an ajax call. First line of protection against csrf
     $config = CRM_Core_Config::singleton();
-    if (!$config->debug &&
+    if (0 && !$config->debug &&
       (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) ||
         $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest"
       )
index fa3d34c9b04d8bf022d54b4dcb76ab421df90e43..42cdfc6163f809222f8ed308aa892b37ad828f66 100644 (file)
@@ -111,7 +111,7 @@ function civicrm_api3_group_contact_create($params) {
 
 /**
  * Adjust Metadata for Create action
- * 
+ *
  * The metadata is used for setting defaults, documentation & validation
  * @param array $params array or parameters determined by getfields
  */
@@ -158,7 +158,7 @@ function civicrm_api3_group_contact_pending($params) {
  * @param string $op
  *
  * @return Array
- * @todo behaviour is highly non-standard - need to figure out how to make this 'behave' 
+ * @todo behaviour is highly non-standard - need to figure out how to make this 'behave'
  * & at the very least return IDs & details of the groups created / changed
  */
 function _civicrm_api3_group_contact_common($params, $op = 'Added') {
@@ -185,7 +185,6 @@ function _civicrm_api3_group_contact_common($params, $op = 'Added') {
   $method = CRM_Utils_Array::value('method', $params, 'API');
   $status = CRM_Utils_Array::value('status', $params, $op);
   $tracking = CRM_Utils_Array::value('tracking', $params);
-  
 
   if ($op == 'Added' || $op == 'Pending') {
     $extraReturnValues= array(
diff --git a/api/v3/MailingContact.php b/api/v3/MailingContact.php
new file mode 100644 (file)
index 0000000..f62b04c
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * File for the CiviCRM APIv3 contact and mailing functions
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_MailingContact
+ *
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * @version $Id$
+ *
+ */
+
+/**
+ * Get all the mailings and details that a contact was involved with
+ *
+ * @param array    $params input parameters
+ *                    - key: contact_id, value: int - required
+ *                    - key: type, value: Delivered | Bounced - optional, defaults to Delivered
+ *                    - Future extensions will include: Opened, Clicked, Forwarded
+ *
+ * @return array API result
+ * @static void
+ * @access public
+ * @example CRM/Mailing/Page/Tab.php
+ *
+ */
+function civicrm_api3_mailing_contact_get($params) {
+  if (empty($params['contact_id'])) {
+    return civicrm_api3_create_error('contact_id is a required field');
+  }
+
+  if (empty($params['type'])) {
+    $params['type'] = 'Delivered';
+  }
+
+  $validTypeValues = array('Delivered', 'Bounced');
+  if (!in_array($params['type'], $validTypeValues)) {
+    return civicrm_api3_create_error(
+      'type should be one of the following: ' .
+      implode(', ', $validTypeValues)
+    );
+  }
+
+  if (!isset($params['offset'])) {
+    $params['offset'] = 0;
+  }
+
+
+  if (!isset($params['limit'])) {
+    $params['limit'] = 50;
+  }
+
+  $fnName = '_civicrm_api3_mailing_contact_get_' . strtolower($params['type']);
+  return $fnName(
+    $params['contact_id'],
+    $params['offset'],
+    $params['limit']
+  );
+}
+
+function _civicrm_api3_mailing_contact_query(
+  $type,
+  $contactID,
+  $offset,
+  $limit,
+  $selectFields,
+  $fromClause,
+  $whereClause
+) {
+  $defaultFields = array(
+    'm.id'       => 'mailing_id',
+    'm.subject'  => 'subject',
+    'c.id' => 'creator_id',
+    'c.sort_name' => 'creator_name',
+  );
+
+  if ($selectFields) {
+    $fields = array_merge($selectFields, $defaultFields);
+  }
+  else {
+    $fields = $defaultFields;
+  }
+
+  $select = array();
+  foreach ($fields as $n => $l) {
+    $select[] = "$n as $l";
+  }
+  $select = implode(', ', $select);
+
+  $sql = "
+SELECT     $select
+FROM       civicrm_mailing m
+INNER JOIN civicrm_contact c ON m.created_id = c.id
+INNER JOIN civicrm_mailing_job j ON j.mailing_id = m.id
+INNER JOIN civicrm_mailing_event_queue meq ON meq.job_id = j.id
+           $fromClause
+WHERE      j.is_test = 0
+AND        meq.contact_id = %1
+           $whereClause
+GROUP BY   m.id
+ORDER BY   j.start_date
+";
+
+  if ($limit > 0) {
+    $sql .= "
+LIMIT %2, %3
+";
+  }
+
+  $qParams = array(
+    1 => array($contactID, 'Integer'),
+    2 => array($offset, 'Integer'),
+    3 => array($limit, 'Integer')
+  );
+  $dao = CRM_Core_DAO::executeQuery($sql, $qParams);
+
+  $results = array();
+  while ($dao->fetch()) {
+    foreach ($fields as $n => $l) {
+      $results[$dao->mailing_id][$l] = $dao->$l;
+    }
+  }
+
+  $params = array(
+    'type'   => $type,
+    'contact_id' => $contactID,
+    'offset' => $offset,
+    'limit'  => $limit
+  );
+  return civicrm_api3_create_success($results, $params);
+}
+
+function _civicrm_api3_mailing_contact_get_delivered(
+  $contactID,
+  $offset,
+  $limit
+) {
+  $selectFields = array('med.time_stamp' => 'start_date');
+
+  $fromClause = "
+INNER JOIN civicrm_mailing_event_delivered med ON med.event_queue_id = meq.id
+LEFT  JOIN civicrm_mailing_event_bounce meb ON meb.event_queue_id = meq.id
+";
+
+  $whereClause = "
+AND        meb.id IS NULL
+";
+
+  return _civicrm_api3_mailing_contact_query(
+    'Delivered',
+    $contactID,
+    $offset,
+    $limit,
+    $selectFields,
+    $fromClause,
+    $whereClause
+  );
+}
+
+function _civicrm_api3_mailing_contact_get_bounced(
+  $contactID,
+  $offset,
+  $limit
+) {
+  $fromClause = "
+INNER JOIN civicrm_mailing_event_bounce meb ON meb.event_queue_id = meq.id
+";
+
+  return _civicrm_api3_mailing_contact_query(
+    'Bounced',
+    $contactID,
+    $offset,
+    $limit,
+    NULL,
+    $fromClause,
+    NULL
+  );
+}
diff --git a/templates/CRM/Mailing/Page/Tab.tpl b/templates/CRM/Mailing/Page/Tab.tpl
new file mode 100644 (file)
index 0000000..0d06a3d
--- /dev/null
@@ -0,0 +1,114 @@
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*}
+
+<div class="crm-mailing-selector">
+  <table id="contact-mailing-selector">
+    <thead>
+    <tr>
+      <th class='crm-mailing-contact-subject'>{ts}Subject{/ts}</th>
+      <th class='crm-mailing-contact_created'>{ts}Created By{/ts}</th>
+      <th class='crm-mailing-contact-date'>{ts}Date{/ts}</th>
+      <th class='crm-mailing-contact-links nosort'>&nbsp;</th>
+      <th class='hiddenElement'>&nbsp;</th>
+    </tr>
+    </thead>
+  </table>
+</div>
+{literal}
+<script type="text/javascript">
+  var oTable;
+
+  cj(function ( ) {
+    buildMailingContact( );
+  });
+
+function buildMailingContact() {
+  oTable.fnDestroy();
+
+  var columns = '';
+  var sourceUrl = {/literal}'{crmURL p="civicrm/ajax/rest" h=0 q="entity=MailingContact&action=get&sequential=1&json=1&contact_id=$contactId"}'{literal};
+
+  var ZeroRecordText = {/literal}'{ts escape="js"}No mailings found{/ts}.'{literal};
+
+  oTable = cj('#mailing-contact-selector').dataTable({
+    "bFilter"    : false,
+    "bAutoWidth" : false,
+    "aaSorting"  : [],
+    "aoColumns"  : [
+      {sClass:'crm-mailing-contact-subject'},
+      {sClass:'crm-mailing-contact_created'},
+      {sClass:'crm-mailing-contact-date'},
+      {sClass:'crm-mailing-contact-links', bSortable:false},
+      {sClass:'hiddenElement', bSortable:false}
+    ],
+    "bProcessing": true,
+    "sPaginationType": "full_numbers",
+    "sDom"       : '<"crm-datatable-pager-top"lfp>rt<"crm-datatable-pager-bottom"ip>',
+    "bServerSide": true,
+    "bJQueryUI": true,
+    "sAjaxSource": sourceUrl,
+    "iDisplayLength": 25,
+    "oLanguage": {
+      "sZeroRecords":  ZeroRecordText,
+      "sProcessing":   {/literal}"{ts escape='js'}Processing...{/ts}"{literal},
+      "sLengthMenu":   {/literal}"{ts escape='js'}Show _MENU_ entries{/ts}"{literal},
+      "sInfo":         {/literal}"{ts escape='js'}Showing _START_ to _END_ of _TOTAL_ entries{/ts}"{literal},
+      "sInfoEmpty":    {/literal}"{ts escape='js'}Showing 0 to 0 of 0 entries{/ts}"{literal},
+      "sInfoFiltered": {/literal}"{ts escape='js'}(filtered from _MAX_ total entries){/ts}"{literal},
+      "sSearch":       {/literal}"{ts escape='js'}Search:{/ts}"{literal},
+      "oPaginate": {
+        "sFirst":    {/literal}"{ts escape='js'}First{/ts}"{literal},
+        "sPrevious": {/literal}"{ts escape='js'}Previous{/ts}"{literal},
+        "sNext":     {/literal}"{ts escape='js'}Next{/ts}"{literal},
+        "sLast":     {/literal}"{ts escape='js'}Last{/ts}"{literal}
+      }
+    },
+    "fnDrawCallback": function() { setSelectorClass(); },
+    "fnServerData": function ( sSource, aoData, fnCallback ) {
+        aoData.push( {name:'contact_id', value: {/literal}{$contactId}{literal}},
+      {name:'admin',   value: {/literal}'{$admin}'{literal}}
+      );
+
+      cj.ajax( {
+        "dataType": 'json',
+        "type": "POST",
+        "url": sSource,
+        "data": aoData,
+        "success": fnCallxback,
+        // CRM-10244
+        "dataFilter": function(data, type) { return data.replace(/[\n\v\t]/g, " "); }
+      });
+    }
+  });
+}
+
+function setSelectorClass( ) {
+  cj('#contact-mailing-selector' + ' td:last-child').each( function( ) {
+    cj(this).parent().addClass(cj(this).text() );
+  });
+}
+</script>
+{/literal}
diff --git a/tests/phpunit/api/v3/MailingContactTest.php b/tests/phpunit/api/v3/MailingContactTest.php
new file mode 100644 (file)
index 0000000..2142119
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+// $Id$
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * File for the CiviCRM APIv3 job functions
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_MailingContact
+ *
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * @version $Id: Job.php 30879 2010-11-22 15:45:55Z shot $
+ *
+ */
+require_once 'CiviTest/CiviUnitTestCase.php';
+class api_v3_MailingContactTest extends CiviUnitTestCase {
+  protected $_apiversion;
+
+  function setUp() {
+    parent::setUp();
+    $this->quickCleanup(
+      array(
+        'civicrm_mailing',
+        'civicrm_job',
+        'civicrm_mailing_event_queue',
+        'civicrm_mailing_event_delivered',
+        'civicrm_mailing_event_bounced',
+      )
+    );
+  }
+
+  function tearDown() {
+    parent::tearDown();
+  }
+
+  function testMailingContactDelivered( ) {
+    $op = new PHPUnit_Extensions_Database_Operation_Insert();
+    $op->execute($this->_dbconn,
+      new PHPUnit_Extensions_Database_DataSet_FlatXMLDataSet(
+        dirname(__FILE__) . '/dataset/mailing_contact.xml'
+      )
+    );
+  }
+}
\ No newline at end of file