Files
luos/workflow/engine/bin/cron_single.php
Julio Cesar Laura Avendaño 0deb4847c7 PMCORE-2644
2021-01-05 18:59:16 +00:00

624 lines
23 KiB
PHP

<?php
/**
* cron_single.php
*
* @see workflow/engine/bin/cron.php
* @see workflow/engine/bin/timereventcron.php
* @see workflow/engine/bin/ldapcron.php
* @see workflow/engine/bin/sendnotificationscron.php
* @see workflow/engine/bin/webentriescron.php
* @see workflow/engine/methods/setup/cron.php
*
* @link https://wiki.processmaker.com/3.2/Executing_cron.php
*/
use Illuminate\Foundation\Http\Kernel;
require_once __DIR__ . '/../../../gulliver/system/class.g.php';
require_once __DIR__ . '/../../../bootstrap/autoload.php';
require_once __DIR__ . '/../../../bootstrap/app.php';
use ProcessMaker\Core\JobsManager;
use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\TaskScheduler\Task;
register_shutdown_function(function () {
if (class_exists("Propel")) {
Propel::close();
}
});
try {
//Verify data
if (count($argv) < 7) {
throw new Exception('Error: Invalid number of arguments');
}
for ($i = 1; $i <= 3; $i++) {
$argv[$i] = base64_decode($argv[$i]);
if (!is_dir($argv[$i])) {
throw new Exception('Error: The path "' . $argv[$i] . '" is invalid');
}
}
//Set variables
$osIsLinux = strtoupper(substr(PHP_OS, 0, 3)) != 'WIN';
$pathHome = $argv[1];
$pathTrunk = $argv[2];
$pathOutTrunk = $argv[3];
$cronName = $argv[4];
$workspace = $argv[5];
$now = $argv[6]; //date
//asynchronous flag
$asynchronous = false;
$result = array_search('+async', $argv);
if ($result !== false && is_int($result)) {
$asynchronous = true;
unset($argv[$result]);
$argv = array_values($argv);
}
//Defines constants
define('PATH_SEP', ($osIsLinux) ? '/' : '\\');
define('PATH_HOME', $pathHome);
define('PATH_TRUNK', $pathTrunk);
define('PATH_OUTTRUNK', $pathOutTrunk);
define('PATH_CLASSES', PATH_HOME . 'engine' . PATH_SEP . 'classes' . PATH_SEP);
define('SYS_LANG', 'en');
require_once(PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php');
require_once(PATH_TRUNK . 'framework' . PATH_SEP . 'src' . PATH_SEP . 'Maveriks' . PATH_SEP . 'Util' . PATH_SEP . 'ClassLoader.php');
// Class Loader - /ProcessMaker/BusinessModel
$classLoader = \Maveriks\Util\ClassLoader::getInstance();
$classLoader->add(PATH_TRUNK . 'framework' . PATH_SEP . 'src' . PATH_SEP, 'Maveriks');
$classLoader->add(PATH_TRUNK . 'workflow' . PATH_SEP . 'engine' . PATH_SEP . 'src' . PATH_SEP, 'ProcessMaker');
$classLoader->add(PATH_TRUNK . 'workflow' . PATH_SEP . 'engine' . PATH_SEP . 'src' . PATH_SEP);
// Add vendors to autoloader
$classLoader->addClass('Bootstrap', PATH_TRUNK . 'gulliver' . PATH_SEP . 'system' . PATH_SEP . 'class.bootstrap.php');
$classLoader->addModelClassPath(PATH_TRUNK . 'workflow' . PATH_SEP . 'engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP);
// Get the configurations related to the workspace
$arraySystemConfiguration = System::getSystemConfiguration('', '', $workspace);
// Define the debug value
$e_all = (defined('E_DEPRECATED')) ? E_ALL & ~E_DEPRECATED : E_ALL;
$e_all = (defined('E_STRICT')) ? $e_all & ~E_STRICT : $e_all;
$e_all = ($arraySystemConfiguration['debug']) ? $e_all : $e_all & ~E_NOTICE;
// In community version the default value is 0
$_SESSION['__SYSTEM_UTC_TIME_ZONE__'] = (int)($arraySystemConfiguration['system_utc_time_zone']) == 1;
app()->useStoragePath(realpath(PATH_DATA));
app()->make(Kernel::class)->bootstrap();
restore_error_handler();
// Do not change any of these settings directly, use env.ini instead
ini_set('display_errors', $arraySystemConfiguration['debug']);
ini_set('error_reporting', $e_all);
ini_set('short_open_tag', 'On');
ini_set('default_charset', 'UTF-8');
ini_set('soap.wsdl_cache_enabled', $arraySystemConfiguration['wsdl_cache']);
ini_set('date.timezone', $_SESSION['__SYSTEM_UTC_TIME_ZONE__'] ? 'UTC' : $arraySystemConfiguration['time_zone']);
define('DEBUG_SQL_LOG', $arraySystemConfiguration['debug_sql']);
define('DEBUG_TIME_LOG', $arraySystemConfiguration['debug_time']);
define('DEBUG_CALENDAR_LOG', $arraySystemConfiguration['debug_calendar']);
define('MEMCACHED_ENABLED', $arraySystemConfiguration['memcached']);
define('MEMCACHED_SERVER', $arraySystemConfiguration['memcached_server']);
define('TIME_ZONE', ini_get('date.timezone'));
date_default_timezone_set(TIME_ZONE);
config(['app.timezone' => TIME_ZONE]);
spl_autoload_register(['Bootstrap', 'autoloadClass']);
//Set variables
/*----------------------------------********---------------------------------*/
$dateInit = null;
$dateFinish = null;
/*----------------------------------********---------------------------------*/
$argvx = '';
for ($i = 7; $i <= count($argv) - 1; $i++) {
/*----------------------------------********---------------------------------*/
if (strpos($argv[$i], '+init-date') !== false) {
$dateInit = substr($argv[$i], 10);
} elseif (strpos($argv[$i], '+finish-date') !== false) {
$dateFinish = substr($argv[$i], 12);
} else {
/*----------------------------------********---------------------------------*/
$argvx = $argvx . (($argvx != '') ? ' ' : '') . $argv[$i];
/*----------------------------------********---------------------------------*/
}
/*----------------------------------********---------------------------------*/
}
global $sObject;
$sObject = $workspace;
//Workflow
saveLog('main', 'action', 'checking folder ' . PATH_DB . $workspace);
if (is_dir(PATH_DB . $workspace) && file_exists(PATH_DB . $workspace . PATH_SEP . 'db.php')) {
define('SYS_SYS', $workspace);
config(["system.workspace" => $workspace]);
include_once(PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths_installed.php');
include_once(PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php');
//PM Paths DATA
define('PATH_DATA_SITE', PATH_DATA . 'sites/' . config("system.workspace") . '/');
define('PATH_DOCUMENT', PATH_DATA_SITE . 'files/');
define('PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE . 'mailTemplates/');
define('PATH_DATA_PUBLIC', PATH_DATA_SITE . 'public/');
define('PATH_DATA_REPORTS', PATH_DATA_SITE . 'reports/');
define('PATH_DYNAFORM', PATH_DATA_SITE . 'xmlForms/');
define('PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE . 'usersFiles' . PATH_SEP);
define('PATH_IMAGES_ENVIRONMENT_USERS', PATH_DATA_SITE . 'usersPhotographies' . PATH_SEP);
if (is_file(PATH_DATA_SITE . PATH_SEP . '.server_info')) {
$SERVER_INFO = file_get_contents(PATH_DATA_SITE . PATH_SEP . '.server_info');
$SERVER_INFO = unserialize($SERVER_INFO);
define('SERVER_NAME', $SERVER_INFO['SERVER_NAME']);
define('SERVER_PORT', $SERVER_INFO['SERVER_PORT']);
//to do improvement G::is_https()
if ((isset($SERVER_INFO['HTTPS']) && $SERVER_INFO['HTTPS'] == 'on') ||
(isset($SERVER_INFO['HTTP_X_FORWARDED_PROTO']) && $SERVER_INFO['HTTP_X_FORWARDED_PROTO'] == 'https')) {
define('REQUEST_SCHEME', 'https');
} else {
define('REQUEST_SCHEME', $SERVER_INFO['REQUEST_SCHEME']);
}
} else {
eprintln('WARNING! No server info found!', 'red');
}
//load Processmaker translations
Bootstrap::LoadTranslationObject(SYS_LANG);
//DB
$phpCode = '';
$fileDb = fopen(PATH_DB . $workspace . PATH_SEP . 'db.php', 'r');
if ($fileDb) {
while (!feof($fileDb)) {
$buffer = fgets($fileDb, 4096); //Read a line
$phpCode .= preg_replace('/define\s*\(\s*[\x22\x27](.*)[\x22\x27]\s*,\s*(\x22.*\x22|\x27.*\x27)\s*\)\s*;/i', '$$1 = $2;', $buffer);
}
fclose($fileDb);
}
$phpCode = str_replace(['<?php', '<?', '?>'], ['', '', ''], $phpCode);
eval($phpCode);
$dsn = $DB_ADAPTER . '://' . $DB_USER . ':' . $DB_PASS . '@' . $DB_HOST . '/' . $DB_NAME;
$dsnRbac = $DB_ADAPTER . '://' . $DB_RBAC_USER . ':' . $DB_RBAC_PASS . '@' . $DB_RBAC_HOST . '/' . $DB_RBAC_NAME;
$dsnRp = $DB_ADAPTER . '://' . $DB_REPORT_USER . ':' . $DB_REPORT_PASS . '@' . $DB_REPORT_HOST . '/' . $DB_REPORT_NAME;
switch ($DB_ADAPTER) {
case 'mysql':
$dsn .= '?encoding=utf8';
$dsnRbac .= '?encoding=utf8';
break;
case 'mssql':
break;
default:
break;
}
$pro = [];
$pro['datasources']['workflow']['connection'] = $dsn;
$pro['datasources']['workflow']['adapter'] = $DB_ADAPTER;
$pro['datasources']['rbac']['connection'] = $dsnRbac;
$pro['datasources']['rbac']['adapter'] = $DB_ADAPTER;
$pro['datasources']['rp']['connection'] = $dsnRp;
$pro['datasources']['rp']['adapter'] = $DB_ADAPTER;
$oFile = fopen(PATH_CORE . 'config' . PATH_SEP . '_databases_.php', 'w');
fwrite($oFile, '<?php global $pro; return $pro; ?>');
fclose($oFile);
Propel::init(PATH_CORE . 'config' . PATH_SEP . '_databases_.php');
/**
* Load Laravel database connection
*/
$dbHost = explode(':', $DB_HOST);
config(['database.connections.workflow.host' => $dbHost[0]]);
config(['database.connections.workflow.database' => $DB_NAME]);
config(['database.connections.workflow.username' => $DB_USER]);
config(['database.connections.workflow.password' => $DB_PASS]);
if (count($dbHost) > 1) {
config(['database.connections.workflow.port' => $dbHost[1]]);
}
//Enable RBAC, We need to keep both variables in upper and lower case.
$rbac = $RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$rbac->sSystem = 'PROCESSMAKER';
if (!defined('DB_ADAPTER')) {
define('DB_ADAPTER', $DB_ADAPTER);
}
if (!defined('DB_HOST')) {
define('DB_HOST', $DB_HOST);
}
if (!defined('DB_NAME')) {
define('DB_NAME', $DB_NAME);
}
if (!defined('DB_USER')) {
define('DB_USER', $DB_USER);
}
if (!defined('DB_PASS')) {
define('DB_PASS', $DB_PASS);
}
if (!defined('SYS_SKIN')) {
define('SYS_SKIN', $arraySystemConfiguration['default_skin']);
}
$dateSystem = date('Y-m-d H:i:s');
if (empty($now)) {
$now = $dateSystem;
}
//Processing
eprintln('Processing workspace: ' . $workspace, 'green');
/**
* JobsManager
*/
JobsManager::getSingleton()->init();
// We load plugins' pmFunctions
$oPluginRegistry = PluginRegistry::loadSingleton();
$oPluginRegistry->init();
try {
switch ($cronName) {
case 'cron':
try {
$task = new Task($asynchronous, $sObject);
if (empty($argvx) || strpos($argvx, "emails") !== false) {
$task->resendEmails($now, $dateSystem);
}
if (empty($argvx) || strpos($argvx, "unpause") !== false) {
$task->unpauseApplications($now);
}
if (empty($argvx) || strpos($argvx, "calculate") !== false) {
$task->calculateDuration();
}
/*----------------------------------********---------------------------------*/
if (empty($argvx) || strpos($argvx, "calculateapp") !== false) {
$task->calculateAppDuration();
}
/*----------------------------------********---------------------------------*/
executeEvents();
executeScheduledCases();
executeUpdateAppTitle();
if (empty($argvx) || strpos($argvx, "unassigned-case") !== false) {
$task->executeCaseSelfService();
}
if (empty($argvx) || strpos($argvx, "clean-self-service-tables") !== false) {
$task->cleanSelfServiceTables();
}
if (empty($argvx) || strpos($argvx, "plugins") !== false) {
$task->executePlugins();
}
/*----------------------------------********---------------------------------*/
if (strpos($argvx, "report_by_user") !== false) {
$task->fillReportByUser($dateInit, $dateFinish);
}
if (strpos($argvx, "report_by_process") !== false) {
$task->fillReportByProcess($dateInit, $dateFinish);
}
synchronizeDrive();
synchronizeGmailLabels();
/*----------------------------------********---------------------------------*/
} catch (Exception $oError) {
saveLog("main", "error", "Error processing workspace : " . $oError->getMessage() . "\n");
}
break;
case 'ldapcron':
$task = new Task($asynchronous, $sObject);
$task->ldapcron(in_array('+debug', $argv));
break;
case 'messageeventcron':
$task = new Task($asynchronous, $sObject);
$task->messageeventcron();
break;
case 'timereventcron':
$task = new Task($asynchronous, $sObject);
$task->timerEventCron($now, true);
break;
case 'sendnotificationscron':
if (empty($argvx) || strpos($argvx, "send-notifications") !== false) {
$task = new Task($asynchronous, $sObject);
$task->sendNotifications();
}
break;
case 'webentriescron':
$task = new Task($asynchronous, $sObject);
$task->webEntriesCron();
break;
/*----------------------------------********---------------------------------*/
case 'actionsByEmailEmailResponse':
$task = new Task($asynchronous, $sObject);
$task->actionsByEmailResponse();
break;
/*----------------------------------********---------------------------------*/
}
} catch (Exception $e) {
$token = strtotime("now");
PMException::registerErrorLog($e, $token);
G::outRes(G::LoadTranslation("ID_EXCEPTION_LOG_INTERFAZ", array($token)) . "\n");
eprintln('Problem in workspace: ' . $workspace . ' it was omitted.', 'red');
}
eprintln();
}
if (file_exists(PATH_CORE . 'config' . PATH_SEP . '_databases_.php')) {
unlink(PATH_CORE . 'config' . PATH_SEP . '_databases_.php');
}
} catch (Exception $e) {
$token = strtotime("now");
PMException::registerErrorLog($e, $token);
G::outRes(G::LoadTranslation("ID_EXCEPTION_LOG_INTERFAZ", array($token)) . "\n");
}
function executeEvents()
{
global $sLastExecution;
global $argvx;
global $now;
$log = array();
if ($argvx != "" && strpos($argvx, "events") === false) {
return false;
}
setExecutionMessage("Executing events");
setExecutionResultMessage('PROCESSING');
try {
$oAppEvent = new AppEvent();
saveLog('executeEvents', 'action', "Executing Events $sLastExecution, $now ");
$n = $oAppEvent->executeEvents($now, false, $log, 1);
foreach ($log as $value) {
$arrayCron = unserialize(trim(@file_get_contents(PATH_DATA . "cron")));
$arrayCron["processcTimeStart"] = time();
@file_put_contents(PATH_DATA . "cron", serialize($arrayCron));
saveLog('executeEvents', 'action', "Execute Events : $value, $now ");
}
setExecutionMessage("|- End Execution events");
setExecutionResultMessage("Processed $n");
} catch (Exception $oError) {
setExecutionResultMessage('WITH ERRORS', 'error');
eprintln(" '-" . $oError->getMessage(), 'red');
saveLog('calculateAlertsDueDate', 'Error', 'Error Executing Events: ' . $oError->getMessage());
}
}
function executeScheduledCases($now = null)
{
try {
global $argvx;
global $now;
$log = array();
if ($argvx != "" && strpos($argvx, "scheduler") === false) {
return false;
}
setExecutionMessage("Executing the scheduled starting cases");
setExecutionResultMessage('PROCESSING');
$oCaseScheduler = new CaseScheduler();
$oCaseScheduler->caseSchedulerCron($now, $log, 1);
foreach ($log as $value) {
$arrayCron = unserialize(trim(@file_get_contents(PATH_DATA . "cron")));
$arrayCron["processcTimeStart"] = time();
@file_put_contents(PATH_DATA . "cron", serialize($arrayCron));
saveLog('executeScheduledCases', 'action', "OK Case# $value");
}
setExecutionResultMessage('DONE');
} catch (Exception $oError) {
setExecutionResultMessage('WITH ERRORS', 'error');
eprintln(" '-" . $oError->getMessage(), 'red');
}
}
function executeUpdateAppTitle()
{
try {
global $argvx;
if ($argvx != "" && strpos($argvx, "update-case-labels") === false) {
return false;
}
$criteriaConf = new Criteria("workflow");
$criteriaConf->addSelectColumn(ConfigurationPeer::OBJ_UID);
$criteriaConf->addSelectColumn(ConfigurationPeer::CFG_VALUE);
$criteriaConf->add(ConfigurationPeer::CFG_UID, "TAS_APP_TITLE_UPDATE");
$rsCriteriaConf = ConfigurationPeer::doSelectRS($criteriaConf);
$rsCriteriaConf->setFetchmode(ResultSet::FETCHMODE_ASSOC);
setExecutionMessage("Update case labels");
saveLog("updateCaseLabels", "action", "Update case labels", "c");
while ($rsCriteriaConf->next()) {
$row = $rsCriteriaConf->getRow();
$taskUid = $row["OBJ_UID"];
$lang = $row["CFG_VALUE"];
//Update case labels
$appcv = new AppCacheView();
$appcv->appTitleByTaskCaseLabelUpdate($taskUid, $lang, 1);
//Delete record
$criteria = new Criteria("workflow");
$criteria->add(ConfigurationPeer::CFG_UID, "TAS_APP_TITLE_UPDATE");
$criteria->add(ConfigurationPeer::OBJ_UID, $taskUid);
$criteria->add(ConfigurationPeer::CFG_VALUE, $lang);
$numRowDeleted = ConfigurationPeer::doDelete($criteria);
saveLog("updateCaseLabels", "action", "OK Task $taskUid");
}
setExecutionResultMessage("DONE");
} catch (Exception $e) {
setExecutionResultMessage("WITH ERRORS", "error");
eprintln(" '-" . $e->getMessage(), "red");
saveLog("updateCaseLabels", "error", "Error updating case labels: " . $e->getMessage());
}
}
/**
* @deprecated This function is only used in this file and must be deleted.
* @global string $sObject
* @global string $isDebug
* @param string $sSource
* @param string $sType
* @param string $sDescription
*/
function saveLog($sSource, $sType, $sDescription)
{
try {
global $sObject;
global $isDebug;
if ($isDebug) {
print date("H:i:s") . " ($sSource) $sType $sDescription <br />\n";
}
G::verifyPath(PATH_DATA . "log" . PATH_SEP, true);
G::log("| $sObject | " . $sSource . " | $sType | " . $sDescription, PATH_DATA);
} catch (Exception $e) {
//CONTINUE
}
}
/**
* @deprecated This function is only used in this file and must be deleted.
* @param string $m
*/
function setExecutionMessage($m)
{
$len = strlen($m);
$linesize = 60;
$rOffset = $linesize - $len;
eprint("* $m");
for ($i = 0; $i < $rOffset; $i++) {
eprint('.');
}
}
/**
* @deprecated This function is only used in this file and must be deleted.
* @param string $m
* @param string $t
*/
function setExecutionResultMessage($m, $t = '')
{
$c = 'green';
if ($t == 'error') {
$c = 'red';
}
if ($t == 'info') {
$c = 'yellow';
}
if ($t == 'warning') {
$c = 'yellow';
}
eprintln("[$m]", $c);
}
/*----------------------------------********---------------------------------*/
function synchronizeDrive()
{
try {
global $argvx;
if (strpos($argvx, "synchronize-documents-drive") === false) {
return false;
}
$licensedFeatures = PMLicensedFeatures::getSingleton();
if ($licensedFeatures->verifyfeature('AhKNjBEVXZlWUFpWE8wVTREQ0FObmo0aTdhVzhvalFic1M=')) {
$drive = new AppDocumentDrive();
if ($drive->getStatusDrive()) {
setExecutionMessage("Synchronize documents to Drive");
$drive->synchronizeDrive(true);
} else {
setExecutionMessage("It has not enabled Feature Drive");
}
} else {
setExecutionMessage("The Drive license is not enabled");
}
setExecutionResultMessage("DONE");
} catch (Exception $e) {
setExecutionResultMessage("WITH ERRORS", "error");
eprintln(" '-" . $e->getMessage(), "red");
saveLog("synchronizeDocumentsDrive", "error", "Error in synchronize documents to drive: " . $e->getMessage());
}
}
function synchronizeGmailLabels()
{
try {
global $argvx;
if (strpos($argvx, "synchronize-gmail-labels") === false) {
return false;
}
$licensedFeatures = PMLicensedFeatures::getSingleton();
if ($licensedFeatures->verifyfeature('7qhYmF1eDJWcEdwcUZpT0k4S0xTRStvdz09')) {
$pmGoogle = new PmGoogleApi();
if ($pmGoogle->getServiceGmailStatus()) {
setExecutionMessage("Synchronize labels in Gmail");
$labGmail = new labelsGmail();
$labGmail->processPendingRelabelingInQueue();
} else {
setExecutionMessage("It has not enabled Feature Gmail");
}
} else {
setExecutionMessage("The Gmail license is not enabled");
}
setExecutionResultMessage("DONE");
} catch (Exception $e) {
setExecutionResultMessage("WITH ERRORS", "error");
eprintln(" '-" . $e->getMessage(), "red");
saveLog("synchronizeGmailLabels", "error", "Error when synchronizing Gmail labels: " . $e->getMessage());
}
}
/*----------------------------------********---------------------------------*/