3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
13 * This api is used for working with scheduled "cron" jobs.
15 * @package CiviCRM_APIv3
19 * Adjust metadata for "Create" action.
21 * The metadata is used for setting defaults, documentation & validation.
23 * @param array $params
24 * Array of parameters determined by getfields.
26 function _civicrm_api3_job_create_spec(&$params) {
27 $params['run_frequency']['api.required'] = 1;
28 $params['name']['api.required'] = 1;
29 $params['api_entity']['api.required'] = 1;
30 $params['api_action']['api.required'] = 1;
32 $params['domain_id']['api.default'] = CRM_Core_Config
::domainID();
33 $params['is_active']['api.default'] = 1;
37 * Create scheduled job.
39 * @param array $params
40 * Associative array of property name/value pairs to insert in new job.
44 function civicrm_api3_job_create($params) {
45 return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__
), $params, 'Job');
49 * Adjust metadata for clone spec action.
53 function _civicrm_api3_job_clone_spec(&$spec) {
54 $spec['id']['title'] = 'Job ID to clone';
55 $spec['id']['type'] = CRM_Utils_Type
::T_INT
;
56 $spec['id']['api.required'] = 1;
57 $spec['is_active']['title'] = 'Job is Active?';
58 $spec['is_active']['type'] = CRM_Utils_Type
::T_BOOLEAN
;
59 $spec['is_active']['api.required'] = 0;
65 * @param array $params
68 * @throws \API_Exception
69 * @throws \CiviCRM_API3_Exception
71 function civicrm_api3_job_clone($params) {
72 if (empty($params['id'])) {
73 throw new API_Exception("Mandatory key(s) missing from params array: id field is required");
77 $params['last_run'] = 'null';
78 $params['scheduled_run_date'] = 'null';
79 $newJobDAO = CRM_Core_BAO_Job
::copy($id, $params);
80 return civicrm_api3('Job', 'get', ['id' => $newJobDAO->id
]);
84 * Retrieve one or more job.
86 * @param array $params
91 function civicrm_api3_job_get($params) {
92 return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__
), $params);
98 * @param array $params
100 function civicrm_api3_job_delete($params) {
101 _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__
), $params);
105 * Dumb wrapper to execute scheduled jobs.
107 * Always creates success - errors and results are handled in the job log.
109 * @param array $params
110 * input parameters (unused).
115 function civicrm_api3_job_execute($params) {
117 $facility = new CRM_Core_JobManager();
118 $facility->execute(FALSE);
120 // Always creates success - results are handled elsewhere.
121 return civicrm_api3_create_success(1, $params, 'Job');
125 * Adjust Metadata for Execute action.
127 * @param array $params
128 * Array of parameters determined by getfields.
130 function _civicrm_api3_job_execute_spec(&$params) {
134 * Geocode group of contacts based on given params.
136 * @param array $params
142 function civicrm_api3_job_geocode($params) {
143 $gc = new CRM_Utils_Address_BatchUpdate($params);
145 $result = $gc->run();
147 if ($result['is_error'] == 0) {
148 return civicrm_api3_create_success($result['messages']);
151 return civicrm_api3_create_error($result['messages']);
156 * First check on Code documentation.
158 * @param array $params
160 function _civicrm_api3_job_geocode_spec(&$params) {
162 'title' => 'Starting Contact ID',
163 'type' => CRM_Utils_Type
::T_INT
,
166 'title' => 'Ending Contact ID',
167 'type' => CRM_Utils_Type
::T_INT
,
169 $params['geocoding'] = [
170 'title' => 'Geocode address?',
171 'type' => CRM_Utils_Type
::T_BOOLEAN
,
174 'title' => 'Parse street address?',
175 'type' => CRM_Utils_Type
::T_BOOLEAN
,
177 $params['throttle'] = [
178 'title' => 'Throttle?',
179 'description' => 'If enabled, geo-codes at a slow rate',
180 'type' => CRM_Utils_Type
::T_BOOLEAN
,
185 * Send the scheduled reminders for all contacts (either for activities or events).
187 * @param array $params
188 * (reference ) input parameters.
189 * now - the time to use, in YmdHis format
190 * - makes testing a bit simpler since we can simulate past/future time
194 function civicrm_api3_job_send_reminder($params) {
195 //note that $params['rowCount' can be overridden by one of the preferred syntaxes ($options['limit'] = x
196 //It's not clear whether than syntax can be passed in via the UI config - but this keeps the pre 4.4.4 behaviour
197 // in that case (ie. makes it non-configurable via the UI). Another approach would be to set a default of 0
198 // in the _spec function - but since that is a deprecated value it seems more contentious than this approach
199 $params['rowCount'] = 0;
200 $lock = Civi
::lockManager()->acquire('worker.core.ActionSchedule');
201 if (!$lock->isAcquired()) {
202 return civicrm_api3_create_error('Could not acquire lock, another ActionSchedule process is running');
205 $result = CRM_Core_BAO_ActionSchedule
::processQueue(CRM_Utils_Array
::value('now', $params), $params);
208 if ($result['is_error'] == 0) {
209 return civicrm_api3_create_success();
212 return civicrm_api3_create_error($result['messages']);
217 * Adjust metadata for "send_reminder" action.
219 * The metadata is used for setting defaults, documentation & validation.
221 * @param array $params
222 * Array of parameters determined by getfields.
224 function _civicrm_api3_job_send_reminder(&$params) {
225 //@todo this function will now take all fields in action_schedule as params
226 // as it is calling the api fn to set the filters - update getfields to reflect
228 'type' => CRM_Utils_Type
::T_INT
,
229 'title' => 'Action Schedule ID',
234 * Execute a specific report instance and send the output via email.
236 * @param array $params
237 * (reference ) input parameters.
238 * sendmail - Boolean - should email be sent?, required
239 * instanceId - Integer - the report instance ID
240 * resetVal - Integer - should we reset form state (always true)?
244 function civicrm_api3_job_mail_report($params) {
245 $result = CRM_Report_Utils_Report
::processReport($params);
247 if ($result['is_error'] == 0) {
248 // this should be handling by throwing exceptions but can't remove until we can test that.
249 return civicrm_api3_create_success();
252 return civicrm_api3_create_error($result['messages']);
257 * This method allows to update Email Greetings, Postal Greetings and Addressee for a specific contact type.
259 * IMPORTANT: You must first create valid option value before using via admin interface.
260 * Check option lists for Email Greetings, Postal Greetings and Addressee
262 * @todo - is this here by mistake or should it be added to _spec function :id - Integer - greetings option group.
264 * @param array $params
268 function civicrm_api3_job_update_greeting($params) {
269 if (isset($params['ct']) && isset($params['gt'])) {
270 $ct = explode(',', $params['ct']);
271 $gt = explode(',', $params['gt']);
272 foreach ($ct as $ctKey => $ctValue) {
273 foreach ($gt as $gtKey => $gtValue) {
274 $params['ct'] = trim($ctValue);
275 $params['gt'] = trim($gtValue);
276 CRM_Contact_BAO_Contact_Utils
::updateGreeting($params);
281 CRM_Contact_BAO_Contact_Utils
::updateGreeting($params);
283 return civicrm_api3_create_success();
287 * Adjust Metadata for Get action.
289 * The metadata is used for setting defaults, documentation & validation.
291 * @param array $params
292 * Array of parameters determined by getfields.
294 function _civicrm_api3_job_update_greeting_spec(&$params) {
297 'title' => 'Contact Type',
298 'type' => CRM_Utils_Type
::T_STRING
,
302 'title' => 'Greeting Type',
303 'type' => CRM_Utils_Type
::T_STRING
,
308 * Mass update pledge statuses.
310 * @param array $params
314 function civicrm_api3_job_process_pledge($params) {
315 // *** Uncomment the next line if you want automated reminders to be sent
316 // $params['send_reminders'] = true;
317 $result = CRM_Pledge_BAO_Pledge
::updatePledgeStatus($params);
319 if ($result['is_error'] == 0) {
320 // experiment: detailed execution log is a result here
321 return civicrm_api3_create_success($result['messages']);
324 return civicrm_api3_create_error($result['error_message']);
329 * Process mail queue.
331 * @param array $params
335 function civicrm_api3_job_process_mailing($params) {
336 $mailsProcessedOrig = CRM_Mailing_BAO_MailingJob
::$mailsProcessed;
339 CRM_Core_BAO_Setting
::isAPIJobAllowedToRun($params);
341 catch (Exception
$e) {
342 return civicrm_api3_create_error($e->getMessage());
345 if (!CRM_Mailing_BAO_Mailing
::processQueue()) {
346 return civicrm_api3_create_error('Process Queue failed');
350 'processed' => CRM_Mailing_BAO_MailingJob
::$mailsProcessed - $mailsProcessedOrig,
352 return civicrm_api3_create_success($values, $params, 'Job', 'process_mailing');
359 * @param array $params
363 function civicrm_api3_job_process_sms($params) {
364 $mailsProcessedOrig = CRM_Mailing_BAO_MailingJob
::$mailsProcessed;
366 if (!CRM_Mailing_BAO_Mailing
::processQueue('sms')) {
367 return civicrm_api3_create_error('Process Queue failed');
371 'processed' => CRM_Mailing_BAO_MailingJob
::$mailsProcessed - $mailsProcessedOrig,
373 return civicrm_api3_create_success($values, $params, 'Job', 'process_sms');
378 * Job to get mail responses from civiMailing.
380 * @param array $params
384 function civicrm_api3_job_fetch_bounces($params) {
385 $lock = Civi
::lockManager()->acquire('worker.mailing.EmailProcessor');
386 if (!$lock->isAcquired()) {
387 return civicrm_api3_create_error('Could not acquire lock, another EmailProcessor process is running');
389 CRM_Utils_Mail_EmailProcessor
::processBounces($params['is_create_activities']);
392 return civicrm_api3_create_success(1, $params, 'Job', 'fetch_bounces');
396 * Metadata for bounce function.
398 * @param array $params
400 function _civicrm_api3_job_fetch_bounces_spec(&$params) {
401 $params['is_create_activities'] = [
403 'type' => CRM_Utils_Type
::T_BOOLEAN
,
404 'title' => ts('Create activities for replies?'),
409 * Job to get mail and create activities.
411 * @param array $params
415 function civicrm_api3_job_fetch_activities($params) {
416 $lock = Civi
::lockManager()->acquire('worker.mailing.EmailProcessor');
417 if (!$lock->isAcquired()) {
418 return civicrm_api3_create_error('Could not acquire lock, another EmailProcessor process is running');
422 CRM_Utils_Mail_EmailProcessor
::processActivities();
425 return civicrm_api3_create_success($values, $params, 'Job', 'fetch_activities');
427 catch (Exception
$e) {
429 return civicrm_api3_create_error($e->getMessage());
434 * Process participant statuses.
436 * @param array $params
440 * array of properties, if error an array with an error id and error message
442 function civicrm_api3_job_process_participant($params) {
443 $result = CRM_Event_BAO_ParticipantStatusType
::process($params);
445 if (!$result['is_error']) {
446 return civicrm_api3_create_success(implode("\r\r", $result['messages']));
449 return civicrm_api3_create_error('Error while processing participant statuses');
454 * This api checks and updates the status of all membership records for a given domain.
456 * The function uses the calc_membership_status and update_contact_membership APIs.
459 * Sending renewal reminders has been migrated from this job to the Scheduled Reminders function as of 4.3.
461 * @param array $params
462 * Input parameters NOT USED.
465 * true if success, else false
467 function civicrm_api3_job_process_membership($params) {
468 $lock = Civi
::lockManager()->acquire('worker.member.UpdateMembership');
469 if (!$lock->isAcquired()) {
470 return civicrm_api3_create_error('Could not acquire lock, another Membership Processing process is running');
473 $result = CRM_Member_BAO_Membership
::updateAllMembershipStatus();
476 if ($result['is_error'] == 0) {
477 return civicrm_api3_create_success($result['messages'], $params, 'Job', 'process_membership');
480 return civicrm_api3_create_error($result['messages']);
485 * This api checks and updates the status of all survey respondents.
487 * @param array $params
488 * (reference ) input parameters.
491 * true if success, else false
493 function civicrm_api3_job_process_respondent($params) {
494 $result = CRM_Campaign_BAO_Survey
::releaseRespondent($params);
496 if ($result['is_error'] == 0) {
497 return civicrm_api3_create_success();
500 return civicrm_api3_create_error($result['messages']);
505 * Merges given pair of duplicate contacts.
507 * @param array $params
512 * @throws \CiviCRM_API3_Exception
514 function civicrm_api3_job_process_batch_merge($params) {
515 $rule_group_id = CRM_Utils_Array
::value('rule_group_id', $params);
516 if (!$rule_group_id) {
517 $rule_group_id = civicrm_api3('RuleGroup', 'getvalue', [
518 'contact_type' => 'Individual',
519 'used' => 'Unsupervised',
521 'options' => ['limit' => 1],
524 $rgid = CRM_Utils_Array
::value('rgid', $params);
525 $gid = CRM_Utils_Array
::value('gid', $params);
526 $mode = CRM_Utils_Array
::value('mode', $params, 'safe');
528 $result = CRM_Dedupe_Merger
::batchMerge($rule_group_id, $gid, $mode, 1, 2, CRM_Utils_Array
::value('criteria', $params, []), CRM_Utils_Array
::value('check_permissions', $params), NULL, $params['search_limit']);
530 return civicrm_api3_create_success($result, $params);
534 * Metadata for batch merge function.
538 function _civicrm_api3_job_process_batch_merge_spec(&$params) {
539 $params['rule_group_id'] = [
540 'title' => 'Dedupe rule group id, defaults to Contact Unsupervised rule',
541 'type' => CRM_Utils_Type
::T_INT
,
542 'api.aliases' => ['rgid'],
545 'title' => 'group id',
546 'type' => CRM_Utils_Type
::T_INT
,
550 'description' => 'helps decide how to behave when there are conflicts. A \'safe\' value skips the merge if there are no conflicts. Does a force merge otherwise.',
551 'type' => CRM_Utils_Type
::T_STRING
,
553 $params['auto_flip'] = [
554 'title' => 'Auto Flip',
555 'description' => 'let the api decide which contact to retain and which to delete?',
556 'type' => CRM_Utils_Type
::T_BOOLEAN
,
558 $params['search_limit'] = [
559 'title' => ts('Number of contacts to look for matches for.'),
560 'type' => CRM_Utils_Type
::T_INT
,
561 'api.default' => (int) Civi
::settings()->get('dedupe_default_limit'),
567 * Runs handlePaymentCron method in the specified payment processor.
569 * @param array $params
572 * Expected @params array keys are: INCORRECTLY DOCUMENTED AND SHOULD BE IN THE _spec function
573 * for retrieval via getfields.
574 * {string 'processor_name' - the name of the payment processor, eg: Sagepay}
576 function civicrm_api3_job_run_payment_cron($params) {
579 CRM_Core_Payment
::handlePaymentMethod(
590 CRM_Core_Payment
::handlePaymentMethod(
602 * This api cleans up all the old session entries and temp tables.
604 * We recommend that sites run this on an hourly basis.
606 * @param array $params
607 * Sends in various config parameters to decide what needs to be cleaned.
609 function civicrm_api3_job_cleanup($params) {
610 $session = CRM_Utils_Array
::value('session', $params, TRUE);
611 $tempTable = CRM_Utils_Array
::value('tempTables', $params, TRUE);
612 $jobLog = CRM_Utils_Array
::value('jobLog', $params, TRUE);
613 $expired = CRM_Utils_Array
::value('expiredDbCache', $params, TRUE);
614 $prevNext = CRM_Utils_Array
::value('prevNext', $params, TRUE);
615 $dbCache = CRM_Utils_Array
::value('dbCache', $params, FALSE);
616 $memCache = CRM_Utils_Array
::value('memCache', $params, FALSE);
617 $tplCache = CRM_Utils_Array
::value('tplCache', $params, FALSE);
618 $wordRplc = CRM_Utils_Array
::value('wordRplc', $params, FALSE);
620 if ($session ||
$tempTable ||
$prevNext ||
$expired) {
621 CRM_Core_BAO_Cache
::cleanup($session, $tempTable, $prevNext, $expired);
625 CRM_Core_BAO_Job
::cleanup();
629 $config = CRM_Core_Config
::singleton();
630 $config->cleanup(1, FALSE);
634 CRM_Core_Config
::clearDBCache();
638 CRM_Utils_System
::flushCache();
642 CRM_Core_BAO_WordReplacement
::rebuild();
647 * Set expired relationships to disabled.
649 * @param array $params
652 * @throws \API_Exception
654 function civicrm_api3_job_disable_expired_relationships($params) {
655 $result = CRM_Contact_BAO_Relationship
::disableExpiredRelationships();
657 throw new API_Exception('Failed to disable all expired relationships.');
659 return civicrm_api3_create_success(1, $params, 'Job', 'disable_expired_relationships');
663 * This api reloads all the smart groups.
665 * If the org has a large number of smart groups it is recommended that they use the limit clause
666 * to limit the number of smart groups evaluated on a per job basis.
668 * Might also help to increase the smartGroupCacheTimeout and use the cache.
670 * @param array $params
673 * @throws \API_Exception
675 function civicrm_api3_job_group_rebuild($params) {
676 $lock = Civi
::lockManager()->acquire('worker.core.GroupRebuild');
677 if (!$lock->isAcquired()) {
678 throw new API_Exception('Could not acquire lock, another GroupRebuild process is running');
681 $limit = CRM_Utils_Array
::value('limit', $params, 0);
683 CRM_Contact_BAO_GroupContactCache
::loadAll(NULL, $limit);
686 return civicrm_api3_create_success();
690 * Flush smart groups caches.
692 * This job purges aged smart group cache data (based on the timeout value). Sites can decide whether they want this
693 * job and / or the group cache rebuild job to run. In some cases performance is better when old caches are cleared out
694 * prior to any attempt to rebuild them. Also, many sites are very happy to have caches built on demand, provided the
695 * user is not having to wait for deadlocks to clear when invalidating them.
697 * @param array $params
700 * @throws \API_Exception
702 function civicrm_api3_job_group_cache_flush($params) {
703 CRM_Contact_BAO_GroupContactCache
::deterministicCacheFlush();
704 return civicrm_api3_create_success();
708 * Check for CiviCRM software updates.
710 * Anonymous site statistics are sent back to civicrm.org during this check.
712 function civicrm_api3_job_version_check() {
713 $vc = new CRM_Utils_VersionCheck();
715 return civicrm_api3_create_success();