diff --git a/workflow/engine/classes/Cases.php b/workflow/engine/classes/Cases.php index fa26b3871..3523da74e 100644 --- a/workflow/engine/classes/Cases.php +++ b/workflow/engine/classes/Cases.php @@ -3484,8 +3484,19 @@ class Cases * @param string $stepUidObj * @param string $triggerType * @param string $labelAssignment + * @param bool $useGlobal, needs to have the value true if the same case in execution is affected with this trigger * * @return array + * + * @see Cases::executeTriggers() + * @see Cases::getExecuteTriggerProcess() + * @see WsBase::executeTriggerFromDerivate() + * @see ScriptTask::execScriptByActivityUid() + * + * @link https://wiki.processmaker.com/3.2/Triggers#Custom_Trigger + * @link https://wiki.processmaker.com/3.2/Triggers#When_action_cases + * @link https://wiki.processmaker.com/3.1/Triggers + * @link https://wiki.processmaker.com/3.1/Tasks#ScriptTask */ public function executeTriggerFromList( array $triggersList, @@ -3493,16 +3504,24 @@ class Cases $stepType, $stepUidObj, $triggerType, - $labelAssignment = '' + $labelAssignment = '', + $useGlobal = true ) { if (count($triggersList) > 0) { - global $oPMScript; + if ($useGlobal) { + /** + * The global $oPMScript is necessary when the trigger can be update the appData related to the case + * in execution + */ + global $oPMScript; + } $this->addTriggerMessageExecution("
" . $labelAssignment . "
"); if (!isset($oPMScript)) { $oPMScript = new PMScript(); } + $oPMScript->setFields($fieldsCase); /*----------------------------------********---------------------------------*/ @@ -4338,14 +4357,15 @@ class Cases * @param string $appUid * @param integer $delIndex * @param string $usrUid + * @param bool $executeSameCase + * + * @see Ajax::cancelCase() + * @see cases_Ajax + * @see WsBase::cancelCase() * - * @return boolean|string */ - public function cancelCase($appUid, $delIndex = null, $usrUid = null) + public function cancelCase($appUid, $delIndex = null, $usrUid = null, $executeSameCase = true) { - /** Execute a trigger when a case is cancelled */ - $this->getExecuteTriggerProcess($appUid, 'CANCELED'); - $caseFields = $this->loadCase($appUid); $appStatusCurrent = $caseFields['APP_STATUS']; @@ -4374,6 +4394,9 @@ class Cases ); $delay->create($rowDelay); + /** Execute a trigger when a case is cancelled */ + $this->getExecuteTriggerProcess($appUid, 'CANCELED', $executeSameCase); + /*----------------------------------********---------------------------------*/ $dataList = [ 'APP_UID' => $appUid, @@ -7249,40 +7272,56 @@ class Cases return $response; } - public function getExecuteTriggerProcess($appUid, $action) + /** + * Execute triggers when committing an action in cases + * + * @param string $appUid + * @param string $action, can be [OPEN, CANCELED, PAUSED, REASSIGNED, DELETED, CREATE, UNPAUSE] + * @param bool $executeSameCase + * + * @return bool + * + * @see cases_Open.php + * @see cancelCase/Cases.php pauseCase/Cases.php reassignCase/Cases.php removeCase/Cases.php unpauseCase/Cases.php on + * @link https://wiki.processmaker.com/3.2/Triggers#When_action_cases + */ + public function getExecuteTriggerProcess($appUid, $action, $executeSameCase = true) { - if ((!isset($appUid) && $appUid == '') || (!isset($action) && $action == '')) { + if (empty($appUid) || empty($action)) { return false; } - $aFields = $this->loadCase($appUid); - $proUid = $aFields['PRO_UID']; - require_once("classes/model/Process.php"); + $fieldsCase = $this->loadCase($appUid); + $proUid = $fieldsCase['PRO_UID']; + + //Set some global system variables + $fieldsCase['APP_DATA']['APPLICATION'] = $appUid; + $fieldsCase['APP_DATA']['PROCESS'] = $proUid; + + //Get the trigger configured in the process action $appProcess = new Process(); - $arrayWebBotTrigger = $appProcess->getTriggerWebBotProcess($proUid, $action); + $triggersList = $appProcess->getTriggerWebBotProcess($proUid, $action); - if ($arrayWebBotTrigger['TRI_WEBBOT'] != false && $arrayWebBotTrigger['TRI_WEBBOT'] != '') { - global $oPMScript; - $aFields['APP_DATA']['APPLICATION'] = $appUid; - $aFields['APP_DATA']['PROCESS'] = $proUid; - $oPMScript = new PMScript(); - $oPMScript->setDataTrigger($arrayWebBotTrigger); - $oPMScript->setFields($aFields['APP_DATA']); - $oPMScript->setScript($arrayWebBotTrigger['TRI_WEBBOT']); - $oPMScript->setExecutedOn(PMScript::PROCESS_ACTION); - $oPMScript->execute(); + if (!empty($triggersList)){ + //Execute the trigger defined in the process action + $fieldsCase['APP_DATA'] = $this->executeTriggerFromList( + $triggersList, + $fieldsCase['APP_DATA'], + 'PROCESS_ACTION', + '', + '', + '', + $executeSameCase + ); - $aFields['APP_DATA'] = array_merge($aFields['APP_DATA'], $oPMScript->aFields); - unset($aFields['APP_STATUS']); - unset($aFields['APP_PROC_STATUS']); - unset($aFields['APP_PROC_CODE']); - unset($aFields['APP_PIN']); - $this->updateCase($aFields['APP_UID'], $aFields); + //Update the case + $this->updateCase($appUid, $fieldsCase); return true; + } else { + return false; } - return false; } /** diff --git a/workflow/engine/classes/WsBase.php b/workflow/engine/classes/WsBase.php index badbde4f4..e0fb0c01f 100644 --- a/workflow/engine/classes/WsBase.php +++ b/workflow/engine/classes/WsBase.php @@ -10,6 +10,7 @@ class WsBase { public $stored_system_variables; //boolean public $wsSessionId; //web service session id, if the wsbase function is used from a WS request + private $flagSameCase = true; public function __construct($params = null) { @@ -22,6 +23,28 @@ class WsBase } } + /** + * Get the flagSameCase + * + * @return boolean + */ + public function getFlagSameCase() + { + return $this->flagSameCase; + } + + /** + * Set the flagSameCase + * + * @param boolean $var + * + * @return void + */ + public function setFlagSameCase($var) + { + $this->flagSameCase = $var; + } + /** * function to start a web services session in ProcessMaker * @@ -2204,6 +2227,8 @@ class WsBase * @param string $labelAssignment , label related to the triggerType * * @return string $varTriggers updated + * + * @see WsBase::derivateCase() */ public function executeTriggerFromDerivate( $appUid, @@ -2269,10 +2294,14 @@ class WsBase * * @param string $userId * @param string $caseId - * @param string $delIndex - * @param array $tasks + * @param integer $delIndex * @param bool $bExecuteTriggersBeforeAssignment + * @param array $tasks + * * @return $result will return an object + * + * @see PMFDerivateCase()/class.pmFunctions.php on + * @link https://wiki.processmaker.com/3.2/ProcessMaker_Functions/Case_Routing_Functions#PMFDerivateCase.28.29 */ public function derivateCase($userId, $caseId, $delIndex, $bExecuteTriggersBeforeAssignment = false, $tasks = []) { @@ -3087,6 +3116,10 @@ class WsBase public function cancelCase($caseUid, $delIndex, $userUid) { $g = new G(); + //We will to review if the current case in execution will be execute the same + if (isset($_SESSION["APPLICATION"]) && $_SESSION["APPLICATION"] !== $caseUid){ + $this->setFlagSameCase(false); + } try { $g->sessionVarSave(); @@ -3112,7 +3145,7 @@ class WsBase /** If those parameters are null we will to force the cancelCase */ if (is_null($delIndex) && is_null($userUid)) { /*----------------------------------********---------------------------------*/ - $case->cancelCase($caseUid, null, null); + $case->cancelCase($caseUid, null, null, $this->getFlagSameCase()); $result = self::messageExecuteSuccessfully(); $g->sessionVarRestore(); @@ -3149,7 +3182,7 @@ class WsBase /** Cancel case */ - $case->cancelCase($caseUid, (int)$delIndex, $userUid); + $case->cancelCase($caseUid, (int)$delIndex, $userUid, $this->getFlagSameCase()); //Define the result of the cancelCase $result = self::messageExecuteSuccessfully(); diff --git a/workflow/engine/classes/class.pmScript.php b/workflow/engine/classes/class.pmScript.php index 8b2d2a643..a3abf4590 100644 --- a/workflow/engine/classes/class.pmScript.php +++ b/workflow/engine/classes/class.pmScript.php @@ -290,6 +290,12 @@ class PMScript $executedOn = self::UNDEFINED_ORIGIN; } break; + case 'PROCESS_ACTION': + $executedOn = self::PROCESS_ACTION; + break; + case 'SCRIPT_TASK': + $executedOn = self::SCRIPT_TASK; + break; default: $executedOn = self::UNDEFINED_ORIGIN; break; diff --git a/workflow/engine/classes/model/Process.php b/workflow/engine/classes/model/Process.php index 7e895d69d..69c59feec 100644 --- a/workflow/engine/classes/model/Process.php +++ b/workflow/engine/classes/model/Process.php @@ -775,11 +775,22 @@ class Process extends BaseProcess return $aProc; } + /** + * Get the trigger configured in committing an action in cases + * + * @param string $proUid + * @param string $action + * + * @return mixed + * + * @see Cases::getExecuteTriggerProcess() + * @link https://wiki.processmaker.com/3.2/Triggers#When_action_cases + */ public function getTriggerWebBotProcess($proUid, $action) { require_once("classes/model/Triggers.php"); - if ((! isset($proUid) && $proUid == '') || (! isset($action) && $action == '')) { + if (empty($proUid) || empty($action)){ return false; } @@ -788,40 +799,41 @@ class Process extends BaseProcess switch ($action) { case 'CREATE': - $var = ProcessPeer::PRO_TRI_CREATE; + $columnName = ProcessPeer::PRO_TRI_CREATE; break; case 'OPEN': - $var = ProcessPeer::PRO_TRI_OPEN; + $columnName = ProcessPeer::PRO_TRI_OPEN; break; case 'DELETED': - $var = ProcessPeer::PRO_TRI_DELETED; + $columnName = ProcessPeer::PRO_TRI_DELETED; break; case 'CANCELED': - $var = ProcessPeer::PRO_TRI_CANCELED; + $columnName = ProcessPeer::PRO_TRI_CANCELED; break; case 'PAUSED': - $var = ProcessPeer::PRO_TRI_PAUSED; + $columnName = ProcessPeer::PRO_TRI_PAUSED; break; case 'REASSIGNED': - $var = ProcessPeer::PRO_TRI_REASSIGNED; + $columnName = ProcessPeer::PRO_TRI_REASSIGNED; break; case "UNPAUSE": - $var = ProcessPeer::PRO_TRI_UNPAUSED; + $columnName = ProcessPeer::PRO_TRI_UNPAUSED; break; } - $oCriteria = new Criteria('workflow'); - $oCriteria->addSelectColumn($var); - $oCriteria->addSelectColumn(TriggersPeer::TRI_UID); - $oCriteria->addSelectColumn(TriggersPeer::TRI_WEBBOT); - $oCriteria->addJoin($var, TriggersPeer::TRI_UID, Criteria::LEFT_JOIN); - $oCriteria->add(ProcessPeer::PRO_UID, $proUid); - $oDataSet = ProcessPeer::doSelectRS($oCriteria, Propel::getDbConnection('workflow_ro')); + $criteria = new Criteria('workflow'); + $criteria->addSelectColumn($columnName); + $criteria->addSelectColumn(TriggersPeer::TRI_UID); + $criteria->addSelectColumn(TriggersPeer::TRI_WEBBOT); + $criteria->addSelectColumn(TriggersPeer::TRI_TITLE); + $criteria->addJoin($columnName, TriggersPeer::TRI_UID, Criteria::LEFT_JOIN); + $criteria->add(ProcessPeer::PRO_UID, $proUid); + $criteria->add($columnName, '', Criteria::NOT_EQUAL); + $dataSet = ProcessPeer::doSelectRS($criteria, Propel::getDbConnection('workflow_ro')); + $dataSet->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $oDataSet->setFetchmode(ResultSet::FETCHMODE_ASSOC); - if ($oDataSet->next()) { - $row = $oDataSet->getRow(); - $arrayWebBotTrigger = ['TRI_UID' => $row['TRI_UID'], 'TRI_WEBBOT' => $row['TRI_WEBBOT']]; + if ($dataSet->next()) { + $arrayWebBotTrigger[] = $dataSet->getRow(); } //Return diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/ScriptTask.php b/workflow/engine/src/ProcessMaker/BusinessModel/ScriptTask.php index 371eb0bae..509b46b93 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/ScriptTask.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/ScriptTask.php @@ -10,6 +10,7 @@ use PMScript; use ResultSet; use ScriptTaskPeer; use TaskPeer; +use Triggers as ModelTriggers; use TriggersPeer; class ScriptTask @@ -602,13 +603,16 @@ class ScriptTask } /** - * Execute Script + * Execute the trigger related to the script task * * @param string $activityUid Unique id of task * @param array $arrayApplicationData Case data * * @return array * @throws Exception + * + * @see Derivation::derivate() + * @link https://wiki.processmaker.com/3.1/Tasks#ScriptTask */ public function execScriptByActivityUid($activityUid, array $arrayApplicationData) { @@ -625,34 +629,35 @@ class ScriptTask if ($rsCriteria->next()) { $row = $rsCriteria->getRow(); $scriptTasObjUid = $row["SCRTAS_OBJ_UID"]; - $trigger = TriggersPeer::retrieveByPK($scriptTasObjUid); + $trigger = new ModelTriggers(); + $triggersList[] = $trigger->load($scriptTasObjUid); - if (!is_null($trigger)) { - //We will be update the status before execute the trigger related to the script task + if (!empty($triggersList)){ $case = new ClassesCases(); - $result = $case->updateCase($arrayApplicationData["APP_UID"], $arrayApplicationData); + //We will be update the status before execute the trigger related to the script task + $case->updateCase($arrayApplicationData["APP_UID"], $arrayApplicationData); - //Some Pmf functions uses this global variable $oPMScript for review the aFields defined - global $oPMScript; - $oPMScript = new PMScript(); - $oPMScript->setDataTrigger($trigger->toArray(BasePeer::TYPE_FIELDNAME)); - $oPMScript->setFields($arrayApplicationData["APP_DATA"]); - $oPMScript->setScript($trigger->getTriWebbot()); - $oPMScript->setExecutedOn(PMScript::SCRIPT_TASK); - $oPMScript->execute(); + //Execute the trigger defined in the script task + $arrayApplicationData['APP_DATA'] = $case->executeTriggerFromList( + $triggersList, + $arrayApplicationData['APP_DATA'], + 'SCRIPT_TASK', + '', + '' + ); - if (isset($oPMScript->aFields["__ERROR__"])) { - G::log("Case Uid: " . $arrayApplicationData["APP_UID"] . ", Error: " . $oPMScript->aFields["__ERROR__"], + $case->updateCase($arrayApplicationData['APP_UID'], $arrayApplicationData); + + if (isset($arrayApplicationData['APP_DATA']['__ERROR__'])) { + G::log("Case Uid: " . $arrayApplicationData["APP_UID"] . ", Error: " . $arrayApplicationData['APP_DATA']['__ERROR__'], PATH_DATA, "ScriptTask.log"); } - $arrayApplicationData["APP_DATA"] = $oPMScript->aFields; - $result = $case->updateCase($arrayApplicationData["APP_UID"], $arrayApplicationData); } } } //Return - return $arrayApplicationData["APP_DATA"]; + return $arrayApplicationData['APP_DATA']; } catch (Exception $e) { throw $e; }