Merge pull request #6251 from LevityNL/master
[civicrm-core.git] / api / v3 / Mailing.php
old mode 100644 (file)
new mode 100755 (executable)
index 74f7d8f..46c97b8
@@ -1,10 +1,9 @@
 <?php
-
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * APIv3 functions for registering/processing mailing events.
  *
  * @package CiviCRM_APIv3
- * @subpackage API_Mailing
- * @copyright CiviCRM LLC (c) 2004-2014
- * $Id$
- *
  */
 
 /**
- * Files required for this package
+ * Handle a create event.
+ *
+ * @param array $params
+ *
+ * @return array
+ *    API Success Array
+ * @throws \API_Exception
+ * @throws \Civi\API\Exception\UnauthorizedException
  */
+function civicrm_api3_mailing_create($params) {
+  if (CRM_Mailing_Info::workflowEnabled()) {
+    // Note: 'schedule mailings' and 'approve mailings' can update certain fields, but can't create.
+
+    if (empty($params['id'])) {
+      if (!CRM_Core_Permission::check('access CiviMail') && !CRM_Core_Permission::check('create mailings')) {
+        throw new \Civi\API\Exception\UnauthorizedException("Cannot create new mailing. Required permission: 'access CiviMail' or 'create mailings'");
+      }
+    }
+
+    $safeParams = array();
+    $fieldPerms = CRM_Mailing_BAO_Mailing::getWorkflowFieldPerms();
+    foreach (array_keys($params) as $field) {
+      if (CRM_Core_Permission::check($fieldPerms[$field])) {
+        $safeParams[$field] = $params[$field];
+      }
+    }
+  }
+  else {
+    $safeParams = $params;
+  }
+  $safeParams['_evil_bao_validator_'] = 'CRM_Mailing_BAO_Mailing::checkSendable';
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $safeParams);
+
+}
 
 /**
- * Handle a create event.
+ * Get tokens for one or more entity type
+ *
+ * Output will be formatted either as a flat list,
+ * or pass sequential=1 to retrieve as a hierarchy formatted for select2.
  *
  * @param array $params
- * @param array $ids
+ *   Should contain an array of entities to retrieve tokens for.
+ *
+ * @return array
+ * @throws \API_Exception
+ */
+function civicrm_api3_mailing_gettokens($params) {
+  $tokens = array();
+  foreach ((array) $params['entity'] as $ent) {
+    $func = lcfirst($ent) . 'Tokens';
+    if (!method_exists('CRM_Core_SelectValues', $func)) {
+      throw new API_Exception('Unknown token entity: ' . $ent);
+    }
+    $tokens = array_merge(CRM_Core_SelectValues::$func(), $tokens);
+  }
+  if (!empty($params['sequential'])) {
+    $tokens = CRM_Utils_Token::formatTokensForDisplay($tokens);
+  }
+  return civicrm_api3_create_success($tokens, $params, 'Mailing', 'gettokens');
+}
+
+/**
+ * Adjust Metadata for Create action.
  *
- * @return array API Success Array
+ * The metadata is used for setting defaults, documentation & validation.
+ *
+ * @param array $params
+ *   Array of parameters determined by getfields.
  */
-function civicrm_api3_mailing_create($params, $ids = array()) {
-  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+function _civicrm_api3_mailing_gettokens_spec(&$params) {
+  $params['entity'] = array(
+    'api.default' => array('contact'),
+    'api.required' => 1,
+    'api.multiple' => 1,
+    'title' => 'Entity',
+    'options' => array(),
+  );
+  // Fetch a list of token functions and format to look like entity names
+  foreach (get_class_methods('CRM_Core_SelectValues') as $func) {
+    if (strpos($func, 'Tokens')) {
+      $ent = ucfirst(str_replace('Tokens', '', $func));
+      $params['entity']['options'][$ent] = $ent;
+    }
+  }
 }
 
 /**
- * Adjust Metadata for Create action
+ * Adjust Metadata for Create action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
  *
- * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array of parameters determined by getfields.
  */
 function _civicrm_api3_mailing_create_spec(&$params) {
-  $params['name']['api.required'] = 1;
-  $params['subject']['api.required'] = 1;
-  // should be able to default to 'user_contact_id' & have it work but it didn't work in test so
-  // making required for simplicity
   $params['created_id']['api.required'] = 1;
-  $params['api.mailing_job.create']['api.default'] = 1;
-  $params['api.mailing_job.create']['title'] = 'Schedule Mailing?';
+  $params['created_id']['api.default'] = 'user_contact_id';
+
+  $params['override_verp']['api.default'] = !CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+    'track_civimail_replies', NULL, FALSE
+  );
+  $params['visibility']['api.default'] = 'Public Pages';
+  $params['dedupe_email']['api.default'] = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
+    'dedupe_email_default', NULL, FALSE
+  );
+
+  $params['forward_replies']['api.default'] = FALSE;
+  $params['auto_responder']['api.default'] = FALSE;
+  $params['open_tracking']['api.default'] = TRUE;
+  $params['url_tracking']['api.default'] = TRUE;
+
+  $params['header_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Header', '');
+  $params['footer_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Footer', '');
+  $params['optout_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('OptOut', '');
+  $params['reply_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Reply', '');
+  $params['resubscribe_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Resubscribe', '');
+  $params['unsubscribe_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Unsubscribe', '');
+  $params['mailing_type']['api.default'] = 'standalone';
+  $defaultAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
+  foreach ($defaultAddress as $id => $value) {
+    if (preg_match('/"(.*)" <(.*)>/', $value, $match)) {
+      $params['from_email']['api.default'] = $match[2];
+      $params['from_name']['api.default'] = $match[1];
+    }
+  }
+}
+
+function _civicrm_api3_mailing_clone_spec(&$spec) {
+  $mailingFields = CRM_Mailing_DAO_Mailing::fields();
+  $spec['id'] = $mailingFields['id'];
+  $spec['id']['api.required'] = 1;
+}
+
+function civicrm_api3_mailing_clone($params) {
+  $BLACKLIST = array(
+    'id',
+    'is_completed',
+    'created_id',
+    'created_date',
+    'scheduled_id',
+    'scheduled_date',
+    'approver_id',
+    'approval_date',
+    'approval_status_id',
+    'approval_note',
+    'is_archived',
+    'hash',
+  );
+
+  $get = civicrm_api3('Mailing', 'getsingle', array('id' => $params['id']));
+
+  $newParams = array();
+  $newParams['debug'] = CRM_Utils_Array::value('debug', $params);
+  $newParams['groups']['include'] = array();
+  $newParams['groups']['exclude'] = array();
+  $newParams['mailings']['include'] = array();
+  $newParams['mailings']['exclude'] = array();
+  foreach ($get as $field => $value) {
+    if (!in_array($field, $BLACKLIST)) {
+      $newParams[$field] = $value;
+    }
+  }
+
+  $dao = new CRM_Mailing_DAO_MailingGroup();
+  $dao->mailing_id = $params['id'];
+  $dao->find();
+  while ($dao->fetch()) {
+    // CRM-11431; account for multi-lingual
+    $entity = (substr($dao->entity_table, 0, 15) == 'civicrm_mailing') ? 'mailings' : 'groups';
+    $newParams[$entity][strtolower($dao->group_type)][] = $dao->entity_id;
+  }
+
+  return civicrm_api3('Mailing', 'create', $newParams);
 }
 
 /**
  * Handle a delete event.
  *
  * @param array $params
- * @param array $ids
  *
- * @return array API Success Array
+ * @return array
+ *   API Success Array
  */
-function civicrm_api3_mailing_delete($params, $ids = array()) {
+function civicrm_api3_mailing_delete($params) {
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
-
 /**
  * Handle a get event.
  *
  * @param array $params
+ *
  * @return array
  */
 function civicrm_api3_mailing_get($params) {
   return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
+/**
+ * Adjust metadata for mailing submit api function.
+ *
+ * @param array $spec
+ */
+function _civicrm_api3_mailing_submit_spec(&$spec) {
+  $mailingFields = CRM_Mailing_DAO_Mailing::fields();
+  $spec['id'] = $mailingFields['id'];
+  $spec['scheduled_date'] = $mailingFields['scheduled_date'];
+  $spec['approval_date'] = $mailingFields['approval_date'];
+  $spec['approval_status_id'] = $mailingFields['approval_status_id'];
+  $spec['approval_note'] = $mailingFields['approval_note'];
+  // _skip_evil_bao_auto_recipients_: bool
+}
+
+/**
+ * Mailing submit.
+ *
+ * @param array $params
+ *
+ * @return array
+ * @throws API_Exception
+ */
+function civicrm_api3_mailing_submit($params) {
+  civicrm_api3_verify_mandatory($params, 'CRM_Mailing_DAO_Mailing', array('id'));
+
+  if (!isset($params['scheduled_date']) && !isset($updateParams['approval_date'])) {
+    throw new API_Exception("Missing parameter scheduled_date and/or approval_date");
+  }
+  if (!is_numeric(CRM_Core_Session::getLoggedInContactID())) {
+    throw new API_Exception("Failed to determine current user");
+  }
+
+  $updateParams = array();
+  $updateParams['id'] = $params['id'];
+
+  // Note: we'll pass along scheduling/approval fields, but they may get ignored
+  // if we don't have permission.
+  if (isset($params['scheduled_date'])) {
+    $updateParams['scheduled_date'] = $params['scheduled_date'];
+    $updateParams['scheduled_id'] = CRM_Core_Session::getLoggedInContactID();
+  }
+  if (isset($params['approval_date'])) {
+    $updateParams['approval_date'] = $params['approval_date'];
+    $updateParams['approver_id'] = CRM_Core_Session::getLoggedInContactID();
+    $updateParams['approval_status_id'] = CRM_Utils_Array::value('approval_status_id', $updateParams, CRM_Core_OptionGroup::getDefaultValue('mail_approval_status'));
+  }
+  if (isset($params['approval_note'])) {
+    $updateParams['approval_note'] = $params['approval_note'];
+  }
+  if (isset($params['_skip_evil_bao_auto_recipients_'])) {
+    $updateParams['_skip_evil_bao_auto_recipients_'] = $params['_skip_evil_bao_auto_recipients_'];
+  }
+
+  $updateParams['options']['reload'] = 1;
+  return civicrm_api3('Mailing', 'create', $updateParams);
+}
+
 /**
  * Process a bounce event by passing through to the BAOs.
  *
@@ -101,7 +299,6 @@ function civicrm_api3_mailing_get($params) {
  * @return array
  */
 function civicrm_api3_mailing_event_bounce($params) {
-
   $body = $params['body'];
   unset($params['body']);
 
@@ -111,16 +308,17 @@ function civicrm_api3_mailing_event_bounce($params) {
     return civicrm_api3_create_success($params);
   }
   else {
-    throw new API_Exception(ts('Queue event could not be found'),'no_queue_event
-      ');
+    throw new API_Exception(ts('Queue event could not be found'), 'no_queue_event');
   }
 }
 
 /**
- * Adjust Metadata for bounce_spec action
+ * Adjust Metadata for bounce_spec action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
  *
- * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array of parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_bounce_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -134,7 +332,8 @@ function _civicrm_api3_mailing_event_bounce_spec(&$params) {
 }
 
 /**
- * Handle a confirm event
+ * Handle a confirm event.
+ *
  * @deprecated
  *
  * @param array $params
@@ -142,19 +341,22 @@ function _civicrm_api3_mailing_event_bounce_spec(&$params) {
  * @return array
  */
 function civicrm_api3_mailing_event_confirm($params) {
-  return civicrm_api('mailing_event_confirm', 'create', $params);
+  return civicrm_api('MailingEventConfirm', 'create', $params);
 }
 
 /**
+ * Declare deprecated functions.
+ *
  * @deprecated api notice
- * @return array of deprecated actions
+ * @return array
+ *   Array of deprecated actions
  */
 function _civicrm_api3_mailing_deprecation() {
   return array('event_confirm' => 'Mailing api "event_confirm" action is deprecated. Use the mailing_event_confirm api instead.');
 }
 
 /**
- * Handle a reply event
+ * Handle a reply event.
  *
  * @param array $params
  *
@@ -181,10 +383,12 @@ function civicrm_api3_mailing_event_reply($params) {
 }
 
 /**
- * Adjust Metadata for event_reply action
+ * Adjust Metadata for event_reply action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
  *
- * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array of parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_reply_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -198,7 +402,7 @@ function _civicrm_api3_mailing_event_reply_spec(&$params) {
 }
 
 /**
- * Handle a forward event
+ * Handle a forward event.
  *
  * @param array $params
  *
@@ -222,10 +426,12 @@ function civicrm_api3_mailing_event_forward($params) {
 }
 
 /**
- * Adjust Metadata for event_forward action
+ * Adjust Metadata for event_forward action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
  *
- * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array of parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_forward_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -239,14 +445,13 @@ function _civicrm_api3_mailing_event_forward_spec(&$params) {
 }
 
 /**
- * Handle a click event
+ * Handle a click event.
  *
  * @param array $params
  *
  * @return array
  */
 function civicrm_api3_mailing_event_click($params) {
-
   civicrm_api3_verify_mandatory($params,
     'CRM_Mailing_Event_DAO_TrackableURLOpen',
     array('event_queue_id', 'url_id'),
@@ -266,7 +471,7 @@ function civicrm_api3_mailing_event_click($params) {
 }
 
 /**
- * Handle an open event
+ * Handle an open event.
  *
  * @param array $params
  *
@@ -291,9 +496,244 @@ function civicrm_api3_mailing_event_open($params) {
 }
 
 /**
- * Fix the reset dates on the email record based on when a mail was last delivered
+ * Preview mailing.
+ *
+ * @param array $params
+ *   Array per getfields metadata.
+ *
+ * @return array
+ * @throws \API_Exception
+ */
+function civicrm_api3_mailing_preview($params) {
+  civicrm_api3_verify_mandatory($params,
+    'CRM_Mailing_DAO_Mailing',
+    array('id'),
+    FALSE
+  );
+
+  $fromEmail = NULL;
+  if (!empty($params['from_email'])) {
+    $fromEmail = $params['from_email'];
+  }
+
+  $session = CRM_Core_Session::singleton();
+  $mailing = new CRM_Mailing_BAO_Mailing();
+  $mailing->id = $params['id'];
+  $mailing->find(TRUE);
+
+  CRM_Mailing_BAO_Mailing::tokenReplace($mailing);
+
+  // get and format attachments
+  $attachments = CRM_Core_BAO_File::getEntityFile('civicrm_mailing', $mailing->id);
+
+  $returnProperties = $mailing->getReturnProperties();
+  $contactID = CRM_Utils_Array::value('contact_id', $params);
+  if (!$contactID) {
+    $contactID = $session->get('userID');
+  }
+  $mailingParams = array('contact_id' => $contactID);
+
+  $details = CRM_Utils_Token::getTokenDetails($mailingParams, $returnProperties, TRUE, TRUE, NULL, $mailing->getFlattenedTokens());
+
+  $mime = &$mailing->compose(NULL, NULL, NULL, $session->get('userID'), $fromEmail, $fromEmail,
+    TRUE, $details[0][$contactID], $attachments
+  );
+
+  return civicrm_api3_create_success(array(
+    'id' => $params['id'],
+    'contact_id' => $contactID,
+    'subject' => $mime->_headers['Subject'],
+    'body_html' => $mime->getHTMLBody(),
+    'body_text' => $mime->getTXTBody(),
+  ));
+}
+
+/**
+ * Adjust metadata for send test function.
+ *
+ * @param array $spec
+ */
+function _civicrm_api3_mailing_send_test_spec(&$spec) {
+  $spec['test_group']['title'] = 'Test Group ID';
+  $spec['test_email']['title'] = 'Test Email Address';
+}
+
+/**
+ * Send test mailing.
+ *
+ * @param array $params
+ *
+ * @return array
+ * @throws \API_Exception
+ * @throws \CiviCRM_API3_Exception
+ */
+function civicrm_api3_mailing_send_test($params) {
+  if (!array_key_exists('test_group', $params) && !array_key_exists('test_email', $params)) {
+    throw new API_Exception("Mandatory key(s) missing from params array: test_group and/or test_email field are required");
+  }
+  civicrm_api3_verify_mandatory($params,
+    'CRM_Mailing_DAO_MailingJob',
+    array('mailing_id'),
+    FALSE
+  );
+
+  $testEmailParams = _civicrm_api3_generic_replace_base_params($params);
+  $testEmailParams['is_test'] = 1;
+  $job = civicrm_api3('MailingJob', 'create', $testEmailParams);
+  $testEmailParams['job_id'] = $job['id'];
+  $testEmailParams['emails'] = explode(',', $testEmailParams['test_email']);
+  if (!empty($params['test_email'])) {
+    $query = CRM_Utils_SQL_Select::from('civicrm_email e')
+        ->select(array('e.id', 'e.contact_id', 'e.email'))
+        ->join('c', 'INNER JOIN civicrm_contact c ON e.contact_id = c.id')
+        ->where('e.email IN (@emails)', array('@emails' => $testEmailParams['emails']))
+        ->where('e.on_hold = 0')
+        ->where('c.is_opt_out = 0')
+        ->where('c.do_not_email = 0')
+        ->where('c.is_deceased = 0')
+        ->groupBy('e.id')
+        ->orderBy(array('e.is_bulkmail DESC', 'e.is_primary DESC'))
+        ->toSQL();
+    $dao = CRM_Core_DAO::executeQuery($query);
+    $emailDetail = array();
+    // fetch contact_id and email id for all existing emails
+    while ($dao->fetch()) {
+      $emailDetail[$dao->email] = array(
+        'contact_id' => $dao->contact_id,
+        'email_id' => $dao->id,
+      );
+    }
+    $dao->free();
+    foreach ($testEmailParams['emails'] as $key => $email) {
+      $email = trim($email);
+      $contactId = $emailId = NULL;
+      if (array_key_exists($email, $emailDetail)) {
+        $emailId = $emailDetail[$email]['email_id'];
+        $contactId = $emailDetail[$email]['contact_id'];
+      }
+      if (!$contactId) {
+        //create new contact.
+        $contact   = civicrm_api3('Contact', 'create',
+          array(
+            'contact_type' => 'Individual',
+            'email' => $email,
+            'api.Email.get' => array('return' => 'id'),
+          )
+        );
+        $contactId = $contact['id'];
+        $emailId   = $contact['values'][$contactId]['api.Email.get']['id'];
+      }
+      civicrm_api3('MailingEventQueue', 'create',
+        array(
+          'job_id' => $job['id'],
+          'email_id' => $emailId,
+          'contact_id' => $contactId,
+        )
+      );
+    }
+  }
+
+  $isComplete = FALSE;
+  $config = CRM_Core_Config::singleton();
+  $mailerJobSize = (property_exists($config, 'mailerJobSize')) ? $config->mailerJobSize : NULL;
+  while (!$isComplete) {
+    // Q: In CRM_Mailing_BAO_Mailing::processQueue(), the three runJobs*()
+    // functions are all called. Why does Mailing.send_test only call one?
+    // CRM_Mailing_BAO_MailingJob::runJobs_pre($mailerJobSize, NULL);
+    $isComplete = CRM_Mailing_BAO_MailingJob::runJobs($testEmailParams);
+    // CRM_Mailing_BAO_MailingJob::runJobs_post(NULL);
+  }
+
+  //return delivered mail info
+  $mailDelivered = CRM_Mailing_Event_BAO_Delivered::getRows($params['mailing_id'], $job['id'], TRUE, NULL, NULL, NULL, TRUE);
+
+  return civicrm_api3_create_success($mailDelivered);
+}
+
+/**
+ * Adjust Metadata for send_mail action.
+ *
+ * The metadata is used for setting defaults, documentation & validation.
+ *
+ * @param array $params
+ *   Array of parameters determined by getfields.
+ */
+function _civicrm_api3_mailing_stats_spec(&$params) {
+  $params['date']['api.default'] = 'now';
+  $params['date']['title'] = 'Date';
+}
+
+/**
+ * Function which needs to be explained.
+ *
+ * @param array $params
+ *
+ * @return array
+ * @throws \API_Exception
+ */
+function civicrm_api3_mailing_stats($params) {
+  civicrm_api3_verify_mandatory($params,
+    'CRM_Mailing_DAO_MailingJob',
+    array('mailing_id'),
+    FALSE
+  );
+
+  if ($params['date'] == 'now') {
+    $params['date'] = date('YmdHis');
+  }
+  else {
+    $params['date'] = CRM_Utils_Date::processDate($params['date'] . ' ' . $params['date_time']);
+  }
+
+  $stats[$params['mailing_id']] = array();
+  if (empty($params['job_id'])) {
+    $params['job_id'] = NULL;
+  }
+  foreach (array('Delivered', 'Bounces', 'Unsubscribers', 'Unique Clicks', 'Opened') as $detail) {
+    switch ($detail) {
+      case 'Delivered':
+        $stats[$params['mailing_id']] += array(
+          $detail => CRM_Mailing_Event_BAO_Delivered::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, $params['date']),
+        );
+        break;
+
+      case 'Bounces':
+        $stats[$params['mailing_id']] += array(
+          $detail => CRM_Mailing_Event_BAO_Bounce::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, $params['date']),
+        );
+        break;
+
+      case 'Unsubscribers':
+        $stats[$params['mailing_id']] += array(
+          $detail => CRM_Mailing_Event_BAO_Unsubscribe::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, NULL, $params['date']),
+        );
+        break;
+
+      case 'Unique Clicks':
+        $stats[$params['mailing_id']] += array(
+          $detail => CRM_Mailing_Event_BAO_TrackableURLOpen::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, NULL, $params['date']),
+        );
+        break;
+
+      case 'Opened':
+        $stats[$params['mailing_id']] += array(
+          $detail => CRM_Mailing_Event_BAO_Opened::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, $params['date']),
+        );
+        break;
+    }
+  }
+  return civicrm_api3_create_success($stats);
+}
+
+/**
+ * Fix the reset dates on the email record based on when a mail was last delivered.
+ *
  * We only consider mailings that were completed and finished in the last 3 to 7 days
  * Both the min and max days can be set via the params
+ *
+ * @param array $params
+ *
+ * @return array
  */
 function civicrm_api3_mailing_update_email_resetdate($params) {
   CRM_Mailing_Event_BAO_Delivered::updateEmailResetDate(
@@ -302,5 +742,3 @@ function civicrm_api3_mailing_update_email_resetdate($params) {
   );
   return civicrm_api3_create_success();
 }
-
-