/** * HRJobContract implementation of the "replace" action. * * Replace the old set of entities (matching some given keys) with a new set of * entities (matching the same keys). * * Note: This will verify that 'values' is present, but it does not directly verify * any other parameters. * * @param string $entity entity name * @param array $params params from civicrm_api, including: * - 'values': an array of records to save * - all other items: keys which identify new/pre-existing records * @return array|int */ function _civicrm_hrjobcontract_api3_replace($entity, $params, $forceRevisionId = null) { $transaction = new CRM_Core_Transaction(); try { if (!is_array($params['values'])) { throw new Exception("Mandatory key(s) missing from params array: values"); } // Extract the keys -- somewhat scary, don't think too hard about it $baseParams = _civicrm_api3_generic_replace_base_params($params); // Lookup pre-existing records $preexisting = civicrm_api($entity, 'get', $baseParams, $params); if (civicrm_error($preexisting)) { $transaction->rollback(); return $preexisting; } // Save the new/updated records $jobcontractRevisionId = null; $creates = array(); foreach ($params['values'] as $replacement) { if (empty($replacement['id']) && empty($replacement['jobcontract_revision_id'])) { $replacement['jobcontract_revision_id'] = $jobcontractRevisionId; } if ($forceRevisionId) { $replacement['jobcontract_revision_id'] = $forceRevisionId; } // Sugar: Don't force clients to duplicate the 'key' data $replacement = array_merge($baseParams, $replacement); //$action = (isset($replacement['id']) || isset($replacement[$entity . '_id'])) ? 'update' : 'create'; $action = 'create'; $create = civicrm_api($entity, $action, $replacement); if (civicrm_error($create)) { $transaction->rollback(); return $create; } foreach ($create['values'] as $entity_id => $entity_value) { $creates[$entity_id] = $entity_value; } $entityData = CRM_Utils_Array::first($create['values']); $jobcontractRevisionId = $entityData['jobcontract_revision_id']; } // Remove stale records $staleIDs = array_diff(array_keys($preexisting['values']), array_keys($creates)); foreach ($staleIDs as $staleID) { $delete = civicrm_api($entity, 'delete', array('version' => $params['version'], 'id' => $staleID)); if (civicrm_error($delete)) { $transaction->rollback(); return $delete; } } return civicrm_api3_create_success($creates, $params); } catch (PEAR_Exception $e) { $transaction->rollback(); return civicrm_api3_create_error($e->getMessage()); } catch (Exception $e) { $transaction->rollback(); return civicrm_api3_create_error($e->getMessage()); } }
/** * 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')->where('c.is_deleted = 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 = Civi::settings()->get('mailerJobSize'); 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); }
/** * {@inheritDoc} */ public function fromApiInput($apiRequest) { // Parse options.match or options.match-mandatory $keys = NULL; // array of fields to match against if (isset($apiRequest['params'], $apiRequest['params']['options'])) { if (isset($apiRequest['params']['options']['match-mandatory'])) { $isMandatory = TRUE; $keys = $apiRequest['params']['options']['match-mandatory']; } elseif (isset($apiRequest['params']['options']['match'])) { $isMandatory = FALSE; $keys = $apiRequest['params']['options']['match']; } if (is_string($keys)) { $keys = array($keys); } } // If one of the options was specified, then try to match records. // Matching logic differs for 'create' and 'replace' actions. if ($keys !== NULL) { switch ($apiRequest['action']) { case 'create': if (empty($apiRequest['params']['id'])) { $apiRequest['params'] = $this->match($apiRequest['entity'], $apiRequest['params'], $keys, $isMandatory); } break; case 'replace': // In addition to matching on the listed keys, also match on the set-definition keys. // For example, if the $apiRequest is to "replace the set of civicrm_emails for contact_id=123 while // matching emails on location_type_id", then we would need to search for pre-existing emails using // both 'contact_id' and 'location_type_id' $baseParams = _civicrm_api3_generic_replace_base_params($apiRequest['params']); $keys = array_unique(array_merge(array_keys($baseParams), $keys)); // attempt to match each replacement item foreach ($apiRequest['params']['values'] as $offset => $createParams) { $createParams = array_merge($baseParams, $createParams); $createParams = $this->match($apiRequest['entity'], $createParams, $keys, $isMandatory); $apiRequest['params']['values'][$offset] = $createParams; } break; default: // be forgiveful of sloppily api calls } } return $apiRequest; }