phpdoc params is always an array in api
[civicrm-core.git] / api / v3 / Mailing.php
index adbd365f9858271d6d1a4ddf1614967594ffc380..3c441888569a6f90bd38b3a2d110085e3afe70b0 100755 (executable)
@@ -1,8 +1,7 @@
 <?php
-
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
  | Copyright CiviCRM LLC (c) 2004-2014                                |
  +--------------------------------------------------------------------+
  *
  */
 
-/**
- * Files required for this package
- */
-
 /**
  * Handle a create event.
  *
  * @param array $params
  * @param array $ids
  *
- * @return array API Success Array
+ * @return array
+ *   API Success Array
  */
 function civicrm_api3_mailing_create($params, $ids = array()) {
+  if (CRM_Mailing_Info::workflowEnabled()) {
+    if (!CRM_Core_Permission::check('create mailings')) {
+      throw new \Civi\API\Exception\UnauthorizedException("This system uses advanced CiviMail workflows which require additional permissions");
+    }
+    if (!CRM_Core_Permission::check('schedule mailings')) {
+      unset($params['scheduled_date']);
+      unset($params['scheduled_id']);
+    }
+    if (!CRM_Core_Permission::check('approve mailings')) {
+      unset($params['approval_date']);
+      unset($params['approver_id']);
+      unset($params['approval_status_id']);
+      unset($params['approval_note']);
+    }
+  }
   return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
+function civicrm_api3_mailing_get_token($params) {
+  if (!array_key_exists("usage", $params)) {
+    throw new API_Exception('Mandatory keys missing from params array: entity');
+  }
+
+  $tokens = CRM_Core_SelectValues::contactTokens();
+  switch ($params['usage']) {
+    case 'Mailing':
+      $tokens = array_merge(CRM_Core_SelectValues::mailingTokens(), $tokens);
+      break;
+
+    case 'ScheduleEventReminder':
+      $tokens = array_merge(CRM_Core_SelectValues::activityTokens(), $tokens);
+      $tokens = array_merge(CRM_Core_SelectValues::eventTokens(), $tokens);
+      $tokens = array_merge(CRM_Core_SelectValues::membershipTokens(), $tokens);
+      break;
+
+    case 'ManageEventScheduleReminder':
+      $tokens = array_merge(CRM_Core_SelectValues::eventTokens(), $tokens);
+      break;
+  }
+
+  return CRM_Utils_Token::formatTokensForDisplay($tokens);
+}
+
 /**
  * Adjust Metadata for Create action
  *
  * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array or 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['created_id']['api.default'] = 'user_contact_id';
   $params['api.mailing_job.create']['api.default'] = 1;
   $params['api.mailing_job.create']['title'] = 'Schedule Mailing?';
 }
@@ -75,13 +111,13 @@ function _civicrm_api3_mailing_create_spec(&$params) {
  * @param array $params
  * @param array $ids
  *
- * @return array API Success Array
+ * @return array
+ *   API Success Array
  */
 function civicrm_api3_mailing_delete($params, $ids = array()) {
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
-
 /**
  * Handle a get event.
  *
@@ -92,6 +128,59 @@ function civicrm_api3_mailing_get($params) {
   return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
 
+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
+}
+
+/**
+ * @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'];
+
+  // the BAO will autocreate the job
+  $updateParams['api.mailing_job.create'] = 0; // note: exact match to API default
+
+  // 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 +190,6 @@ function civicrm_api3_mailing_get($params) {
  * @return array
  */
 function civicrm_api3_mailing_event_bounce($params) {
-
   $body = $params['body'];
   unset($params['body']);
 
@@ -120,7 +208,8 @@ function civicrm_api3_mailing_event_bounce($params) {
  * Adjust Metadata for bounce_spec action
  *
  * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array or parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_bounce_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -147,7 +236,8 @@ function civicrm_api3_mailing_event_confirm($params) {
 
 /**
  * @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.');
@@ -184,7 +274,8 @@ function civicrm_api3_mailing_event_reply($params) {
  * Adjust Metadata for event_reply action
  *
  * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array or parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_reply_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -225,7 +316,8 @@ function civicrm_api3_mailing_event_forward($params) {
  * Adjust Metadata for event_forward action
  *
  * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array or parameters determined by getfields.
  */
 function _civicrm_api3_mailing_event_forward_spec(&$params) {
   $params['job_id']['api.required'] = 1;
@@ -246,7 +338,6 @@ function _civicrm_api3_mailing_event_forward_spec(&$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'),
@@ -319,18 +410,29 @@ function civicrm_api3_mailing_preview($params) {
   }
   $mailingParams = array('contact_id' => $contactID);
 
-  $details = CRM_Utils_Token::getTokenDetails($mailingParams, $returnProperties, TRUE, TRUE, NULL, $mailing->getFlattenedToken());
+  $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('subject' => $mime->_headers['Subject'], 'html' => $mime->getHTMLBody(), 'text' => $mime->getTXTBody()));
+  return civicrm_api3_create_success(array(
+    'id' => $params['id'],
+    'contact_id' => $contactID,
+    'subject' => $mime->_headers['Subject'],
+    'body_html' => $mime->getHTMLBody(),
+    'body_text' => $mime->getTXTBody(),
+  ));
+}
+
+function _civicrm_api3_mailing_send_test_spec(&$spec) {
+  $spec['test_group']['title'] = 'Test Group ID';
+  $spec['test_email']['title'] = 'Test Email Address';
 }
 
 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" );
+    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',
@@ -344,18 +446,17 @@ function civicrm_api3_mailing_send_test($params) {
   $testEmailParams['job_id'] = $job['id'];
   $testEmailParams['emails'] = explode(',', $testEmailParams['test_email']);
   if (!empty($params['test_email'])) {
-    $query = "
-SELECT     e.id, e.contact_id, e.email
-FROM       civicrm_email e
-INNER JOIN civicrm_contact c ON e.contact_id = c.id
-WHERE      e.email IN ('" . implode("','", $testEmailParams['emails']) . "')
-AND        e.on_hold = 0
-AND        c.is_opt_out = 0
-AND        c.do_not_email = 0
-AND        c.is_deceased = 0
-GROUP BY   e.id
-ORDER BY   e.is_bulkmail DESC, e.is_primary DESC
-";
+    $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
@@ -376,26 +477,34 @@ ORDER BY   e.is_bulkmail DESC, e.is_primary DESC
       if (!$contactId) {
         //create new contact.
         $contact   = civicrm_api3('Contact', 'create',
-          array('contact_type' => 'Individual',
+          array(
+            'contact_type' => 'Individual',
             'email' => $email,
-            'api.Email.get' => array('return' => 'id')
+            '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'],
+        array(
+          'job_id' => $job['id'],
           'email_id' => $emailId,
-          'contact_id' => $contactId
+          '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
@@ -404,38 +513,16 @@ ORDER BY   e.is_bulkmail DESC, e.is_primary DESC
   return civicrm_api3_create_success($mailDelivered);
 }
 
-function civicrm_api3_mailing_get_token($params) {
-  if (!array_key_exists("usage", $params)) {
-    throw new API_Exception('Mandatory keys missing from params array: entity');
-  }
-
-  $tokens = CRM_Core_SelectValues::contactTokens();
-  switch ($params['usage']) {
-    case 'Mailing' :
-      $tokens = array_merge(CRM_Core_SelectValues::mailingTokens(), $tokens);
-      break;
-    case 'ScheduleEventReminder' :
-      $tokens = array_merge(CRM_Core_SelectValues::activityTokens(), $tokens);
-      $tokens = array_merge(CRM_Core_SelectValues::eventTokens(), $tokens);
-      $tokens = array_merge(CRM_Core_SelectValues::membershipTokens(), $tokens);
-      break;
-    case 'ManageEventScheduleReminder' :
-      $tokens = array_merge(CRM_Core_SelectValues::eventTokens(), $tokens);
-      break;
-  }
-
-  return CRM_Utils_Token::formatTokensForDisplay($tokens);
-
-}
-
 /**
  * Adjust Metadata for send_mail action
  *
  * The metadata is used for setting defaults, documentation & validation
- * @param array $params array or parameters determined by getfields
+ * @param array $params
+ *   Array or parameters determined by getfields.
  */
 function _civicrm_api3_mailing_stats_spec(&$params) {
   $params['date']['api.default'] = 'now';
+  $params['date']['title'] = 'Date';
 }
 
 function civicrm_api3_mailing_stats($params) {
@@ -460,27 +547,31 @@ function civicrm_api3_mailing_stats($params) {
     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'])
+          $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'])
+          $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'])
+          $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'])
+          $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'])
+          $detail =>  CRM_Mailing_Event_BAO_Opened::getTotalCount($params['mailing_id'], $params['job_id'], FALSE, $params['date']),
         );
         break;
     }
@@ -492,6 +583,8 @@ function civicrm_api3_mailing_stats($params) {
  * 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(