CRM_Core_ScheduledJob) */ var $jobs = NULL; /** * @var CRM_Core_ScheduledJob */ var $currentJob = NULL; var $singleRunParams = array(); var $_source = NULL; /** * Class constructor. * * @return void */ public function __construct() { $config = CRM_Core_Config::singleton(); $config->fatalErrorHandler = 'CRM_Core_JobManager_scheduledJobFatalErrorHandler'; $this->jobs = $this->_getJobs(); } /** * @param bool $auth */ public function execute($auth = TRUE) { $this->logEntry('Starting scheduled jobs execution'); if ($auth && !CRM_Utils_System::authenticateKey(TRUE)) { $this->logEntry('Could not authenticate the site key.'); } require_once 'api/api.php'; // it's not asynchronous at this stage CRM_Utils_Hook::cron($this); foreach ($this->jobs as $job) { if ($job->is_active) { if ($job->needsRunning()) { $this->executeJob($job); } } } $this->logEntry('Finishing scheduled jobs execution.'); // Set last cron date for the status check $statusPref = array( 'name' => 'checkLastCron', 'check_info' => gmdate('U'), ); CRM_Core_BAO_StatusPreference::create($statusPref); } /** * Class destructor. */ public function __destruct() { } /** * @param $entity * @param $action */ public function executeJobByAction($entity, $action) { $job = $this->_getJob(NULL, $entity, $action); $this->executeJob($job); } /** * @param int $id */ public function executeJobById($id) { $job = $this->_getJob($id); $this->executeJob($job); } /** * @param CRM_Core_ScheduledJob $job */ public function executeJob($job) { $this->currentJob = $job; $this->logEntry('Starting execution of ' . $job->name); $job->saveLastRun(); $singleRunParamsKey = strtolower($job->api_entity . '_' . $job->api_action); if (array_key_exists($singleRunParamsKey, $this->singleRunParams)) { $params = $this->singleRunParams[$singleRunParamsKey]; } else { $params = $job->apiParams; } try { $result = civicrm_api($job->api_entity, $job->api_action, $params); } catch (Exception$e) { $this->logEntry('Error while executing ' . $job->name . ': ' . $e->getMessage()); } $this->logEntry('Finished execution of ' . $job->name . ' with result: ' . $this->_apiResultToMessage($result)); $this->currentJob = FALSE; } /** * Retrieves the list of jobs from the database, * populates class param. * * @return array * ($id => CRM_Core_ScheduledJob) */ private function _getJobs() { $jobs = array(); $dao = new CRM_Core_DAO_Job(); $dao->orderBy('name'); $dao->domain_id = CRM_Core_Config::domainID(); $dao->find(); while ($dao->fetch()) { $temp = array(); CRM_Core_DAO::storeValues($dao, $temp); $jobs[$dao->id] = new CRM_Core_ScheduledJob($temp); } return $jobs; } /** * Retrieves specific job from the database by id. * and creates ScheduledJob object. * * @param int $id * @param null $entity * @param null $action * * @return CRM_Core_ScheduledJob * @throws Exception */ private function _getJob($id = NULL, $entity = NULL, $action = NULL) { if (is_null($id) && is_null($action)) { CRM_Core_Error::fatal('You need to provide either id or name to use this method'); } $dao = new CRM_Core_DAO_Job(); $dao->id = $id; $dao->api_entity = $entity; $dao->api_action = $action; $dao->find(); while ($dao->fetch()) { CRM_Core_DAO::storeValues($dao, $temp); $job = new CRM_Core_ScheduledJob($temp); } return $job; } /** * @param $entity * @param $job * @param array $params * @param null $source */ public function setSingleRunParams($entity, $job, $params, $source = NULL) { $this->_source = $source; $key = strtolower($entity . '_' . $job); $this->singleRunParams[$key] = $params; $this->singleRunParams[$key]['version'] = 3; } /** * @param string $message * * @return void * collection of permissions, null if none */ public function logEntry($message) { $domainID = CRM_Core_Config::domainID(); $dao = new CRM_Core_DAO_JobLog(); $dao->domain_id = $domainID; $dao->description = substr($message, 0, 235); if (strlen($message) > 235) { $dao->description .= " (...)"; } if ($this->currentJob) { $dao->job_id = $this->currentJob->id; $dao->name = $this->currentJob->name; $dao->command = ts("Entity:") . " " . $this->currentJob->api_entity . " " . ts("Action:") . " " . $this->currentJob->api_action; $data = ""; if (!empty($this->currentJob->parameters)) { $data .= "\n\nParameters raw (from db settings): \n" . $this->currentJob->parameters; } $singleRunParamsKey = strtolower($this->currentJob->api_entity . '_' . $this->currentJob->api_action); if (array_key_exists($singleRunParamsKey, $this->singleRunParams)) { $data .= "\n\nParameters raw (" . $this->_source . "): \n" . serialize($this->singleRunParams[$singleRunParamsKey]); $data .= "\n\nParameters parsed (and passed to API method): \n" . serialize($this->singleRunParams[$singleRunParamsKey]); } else { $data .= "\n\nParameters parsed (and passed to API method): \n" . serialize($this->currentJob->apiParams); } $data .= "\n\nFull message: \n" . $message; $dao->data = $data; } $dao->save(); } /** * @param $apiResult * * @return string */ private function _apiResultToMessage($apiResult) { $status = $apiResult['is_error'] ? ts('Failure') : ts('Success'); $msg = CRM_Utils_Array::value('error_message', $apiResult, 'empty error_message!'); $vals = CRM_Utils_Array::value('values', $apiResult, 'empty values!'); if (is_array($msg)) { $msg = serialize($msg); } if (is_array($vals)) { $vals = serialize($vals); } $message = $apiResult['is_error'] ? ', Error message: ' . $msg : " (" . $vals . ")"; return $status . $message; } } /** * @param $message * * @throws Exception */ function CRM_Core_JobManager_scheduledJobFatalErrorHandler($message) { throw new Exception("{$message['message']}: {$message['code']}"); }