diff --git a/gulliver/system/class.bootstrap.php b/gulliver/system/class.bootstrap.php index 058c4c835..a5874a76b 100644 --- a/gulliver/system/class.bootstrap.php +++ b/gulliver/system/class.bootstrap.php @@ -2683,30 +2683,54 @@ class Bootstrap * Get the default information from the context * * @return array + * + * @see AdditionalTables->populateReportTable + * @see AppAssignSelfServiceValueGroup->createRow + * @see Bootstrap->registerMonologPhpUploadExecution() + * @see Cases->loadDataSendEmail() + * @see Cases->removeCase() + * @see Cases->reportTableDeleteRecord() + * @see Derivation->derivate + * @see G->logTriggerExecution() + * @see LdapAdvanced->VerifyLogin + * @see ldapadvancedClassCron->executeCron + * @see PmDynaform->__construct + * @see pmTablesProxy->genDataReport + * @see Processes->createFiles + * @see ProcessMaker\AuditLog\AuditLog->register + * @see ProcessMaker\Util\ParseSoapVariableName->buildVariableName + * @see RBAC->checkAutomaticRegister() + * @see workflow/engine/classes/class.pmFunctions.php::executeQuery + + * @link https://wiki.processmaker.com/3.3/Actions_by_Email + * @link https://wiki.processmaker.com/3.2/ProcessMaker_Functions + * @link https://wiki.processmaker.com/3.1/Report_Tables + * @link https://wiki.processmaker.com/3.2/Cases/Running_Cases + * @link https://wiki.processmaker.com/3.3/login + * @link https://wiki.processmaker.com/3.2/Executing_cron.php + * @link https://wiki.processmaker.com/3.2/HTML5_Responsive_DynaForm_Designer + * @link https://wiki.processmaker.com/3.2/Audit_Log + * @link https://wiki.processmaker.com/3.0/ProcessMaker_WSDL_Web_Services */ public static function getDefaultContextLog() { - - global $RBAC; $info = [ 'ip' => G::getIpAddress(), 'workspace' => !empty(config('system.workspace')) ? config('system.workspace') : 'Undefined Workspace', - 'timeZone' => DateTime::convertUtcToTimeZone(date('Y-m-d H:m:s')) + 'timeZone' => DateTime::convertUtcToTimeZone(date('Y-m-d H:m:s')), + 'usrUid' => G::LoadTranslation('UID_UNDEFINED_USER') ]; - if ($RBAC !== null) { - $userInfo = [ - 'usrUid' => $RBAC->aUserInfo['USER_INFO']['USR_UID'] - ]; - $info = array_merge($info, $userInfo); + global $RBAC; + if (!empty($RBAC) && !empty($RBAC->aUserInfo['USER_INFO']) && !empty($RBAC->aUserInfo['USER_INFO']['USR_UID'])) { + $info['usrUid'] = $RBAC->aUserInfo['USER_INFO']['USR_UID']; + return $info; } - //Some endpoints can defined the USER_LOGGED - if (empty($info['usrUid'])) { - $user = !empty($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : G::LoadTranslation('UID_UNDEFINED_USER'); - $userInfo = [ - 'usrUid' => $user - ]; - $info = array_merge($info, $userInfo); + + //if default session exists + if (!empty($_SESSION['USER_LOGGED'])) { + $info['usrUid'] = $_SESSION['USER_LOGGED']; + return $info; } return $info; diff --git a/workflow/engine/bin/cron_single.php b/workflow/engine/bin/cron_single.php index 64cacd92b..0bca4967c 100644 --- a/workflow/engine/bin/cron_single.php +++ b/workflow/engine/bin/cron_single.php @@ -1,5 +1,16 @@ getConfiguration('SKIN_CRON', '')); + } //Set Time Zone $systemUtcTimeZone = false; diff --git a/workflow/engine/classes/ActionsByEmailCoreClass.php b/workflow/engine/classes/ActionsByEmailCoreClass.php index f1a8ead4e..75c0be2de 100644 --- a/workflow/engine/classes/ActionsByEmailCoreClass.php +++ b/workflow/engine/classes/ActionsByEmailCoreClass.php @@ -468,6 +468,16 @@ class ActionsByEmailCoreClass extends PMPlugin global $RBAC; $currentUser = $RBAC->aUserInfo['USER_INFO']; $from = ($currentUser["USR_FIRSTNAME"] . ' ' . $currentUser["USR_LASTNAME"] . ' <' . $currentUser["USR_EMAIL"] . '>'); + + if ($RBAC != null && is_array($RBAC->aUserInfo['USER_INFO'])) { + $currentUser = $RBAC->aUserInfo['USER_INFO']; + $from = ($currentUser["USR_FIRSTNAME"] . ' ' . $currentUser["USR_LASTNAME"] . ' <' . $currentUser["USR_EMAIL"] . '>'); + } else { + $usersPeer = UsersPeer::retrieveByPK($this->getUser()); + if (!empty($usersPeer)) { + $from = ($usersPeer->getUsrFirstname() . ' ' . $usersPeer->getUsrLastname() . ' <' . $usersPeer->getUsrEmail() . '>'); + } + } } } //Define the email from @@ -584,13 +594,16 @@ class ActionsByEmailCoreClass extends PMPlugin } /** - * Send the action by email + * Send Actions By Email. * + * @global object $RBAC * @param object $data * @param array $dataAbe - * - * @return void + * @return type * @throws Exception + * + * @see AppDelegation->createAppDelegation() + * @link https://wiki.processmaker.com/3.3/Actions_by_Email */ public function sendActionsByEmail($data, array $dataAbe) { diff --git a/workflow/engine/classes/Derivation.php b/workflow/engine/classes/Derivation.php index 124a4dd2a..f4a34571f 100644 --- a/workflow/engine/classes/Derivation.php +++ b/workflow/engine/classes/Derivation.php @@ -845,7 +845,8 @@ class Derivation return $arrayDerivationResult; } - /** Route the case + /** + * Route the case * If need to create another thread we can execute the doDerivate * * @param array $currentDelegation @@ -853,7 +854,11 @@ class Derivation * @param bool $removeList * * @return void - * @throws /Exception + * @throws Exception + * + * @see beforeDerivate() + * @see doDerivation() + * @see verifyIsCaseChild() */ function derivate(array $currentDelegation, array $nextDelegations, $removeList = true) { @@ -1049,6 +1054,9 @@ class Derivation break; default: $iNewDelIndex = $this->doDerivation($currentDelegation, $nextDel, $appFields, $aSP); + //Load Case Data again because the information could be change in method "doDerivation" + $verifyApplication = $this->case->loadCase($currentDelegation['APP_UID']); + $appFields['APP_DATA'] = $verifyApplication['APP_DATA']; //When the users route the case in the same time if($iNewDelIndex !== 0){ $arrayDerivationResult[] = [ diff --git a/workflow/engine/classes/License_Application.php b/workflow/engine/classes/License_Application.php index 93edf4462..f93cbf14f 100644 --- a/workflow/engine/classes/License_Application.php +++ b/workflow/engine/classes/License_Application.php @@ -27,12 +27,18 @@ class license_application extends Padl * * @access public * @param $use_mcrypt boolean Determines if mcrypt encryption is used or not (defaults to true, - * however if mcrypt is not available, it is set to false) + * however if mcrypt is not available, it is set to false) * @param $use_time boolean Sets if time binding should be used in the key (defaults to true) * @param $use_server boolean Sets if server binding should be used in the key (defaults to true) * @param $allow_local boolean Sets if server binding is in use then localhost servers are valid (defaults to false) - * */ - public function license_application($license_path = 'license.dat', $use_mcrypt = true, $use_time = true, $use_server = true, $allow_local = false, $challenge = false) + * + * @see PmLicenseManager::__construct() + * @see PmLicenseManager::installLicense() + * @see PmLicenseManager::validateLicense() + * @link https://wiki.processmaker.com/3.2/Enterprise_Manager_Tool#Importing_a_License + * @link https://wiki.processmaker.com/3.2/Upgrading_ProcessMaker#Activating_the_License + */ + public function __construct($license_path = 'license.dat', $use_mcrypt = true, $use_time = true, $use_server = true, $allow_local = false, $challenge = false) { //Check to see if the class has been secured if (isset($_SESSION)) { @@ -145,15 +151,15 @@ class license_application extends Padl * * @access private * @return string config file data - * */ + * @see _get_ip_address() + * @see _get_mac_address() + */ public function _get_config() { # check to see if the class has been secured $this->_check_secure(); - if (ini_get('safe_mode')) { - # returns invalid because server is in safe mode thus not allowing - # sbin reads but will still allow it to open. a bit weird that one. - return 'SAFE_MODE'; + if (!$this->USE_SERVER) { + return 'NOT_USE_SERVER_CONFIG'; } # if anyone has any clues for windows environments # or other server types let me know @@ -198,15 +204,17 @@ class license_application extends Padl * @return array IP Address(s) if found (Note one machine may have more than one ip) * @return string ERROR_OPEN means config can't be found and thus not opened * @return string IP_404 means ip adress doesn't exist in the config file and can't be found in the $_SERVER - * @return string SAFE_MODE means server is in safe mode so config can't be read - * */ + * @return string NOT_USE_SERVER_CONFIG the server configuration is not used in license validation. + * + * @see set_server_vars() + */ public function _get_ip_address() { $ips = array(); # get the cofig file $conf = $this->_get_config(); # if the conf has returned and error return it - if ($conf != 'SAFE_MODE' && $conf != 'ERROR_OPEN') { + if ($conf != 'NOT_USE_SERVER_CONFIG' && $conf != 'ERROR_OPEN') { # if anyone has any clues for windows environments # or other server types let me know $os = strtolower(PHP_OS); @@ -266,7 +274,7 @@ class license_application extends Padl return $ips; } # failed to find an ip check for conf error or return 404 - if ($conf == 'SAFE_MODE' || $conf == 'ERROR_OPEN') { + if ($conf == 'NOT_USE_SERVER_CONFIG' || $conf == 'ERROR_OPEN') { return $conf; } return 'IP_404'; @@ -283,8 +291,10 @@ class license_application extends Padl * @return string Mac address if found * @return string ERROR_OPEN means config can't be found and thus not opened * @return string MAC_404 means mac adress doesn't exist in the config file - * @return string SAFE_MODE means server is in safe mode so config can't be read - * */ + * @return string NOT_USE_SERVER_CONFIG the server configuration is not used in license validation. + * + * @see __construct() + */ public function _get_mac_address() { # open the config file diff --git a/workflow/engine/classes/PmDynaform.php b/workflow/engine/classes/PmDynaform.php index b85c92107..4169c3a10 100644 --- a/workflow/engine/classes/PmDynaform.php +++ b/workflow/engine/classes/PmDynaform.php @@ -1359,9 +1359,20 @@ class PmDynaform exit(); } + /** + * Print PmDynaform for Action by Email. + * + * @param array $record + * @return string + * + * @see ActionsByEmailCoreClass->sendActionsByEmail() + * @link https://wiki.processmaker.com/3.3/Actions_by_Email + */ public function printPmDynaformAbe($record) { - ob_clean(); + if (ob_get_length() > 0) { + ob_clean(); + } $this->record = $record; $json = G::json_decode($this->record["DYN_CONTENT"]); $this->jsonr($json); diff --git a/workflow/engine/classes/model/AbeConfiguration.php b/workflow/engine/classes/model/AbeConfiguration.php index 6722958cf..90679a92e 100644 --- a/workflow/engine/classes/model/AbeConfiguration.php +++ b/workflow/engine/classes/model/AbeConfiguration.php @@ -50,6 +50,17 @@ class AbeConfiguration extends BaseAbeConfiguration } } + /** + * Create or update. + * + * @param array $data + * @throws Exception + * + * @see Processes->createActionsByEmail() + * @see ProcessMaker\BusinessModel\ActionsByEmail->saveConfiguration() + * @see ProcessMaker\BusinessModel\ActionsByEmail->saveConfiguration2() + * @link https://wiki.processmaker.com/3.3/Actions_by_Email#Configuration + */ public function createOrUpdate($data) { foreach ($data as $field => $value) { @@ -72,6 +83,11 @@ class AbeConfiguration extends BaseAbeConfiguration } else { $abeConfigurationInstance = AbeConfigurationPeer::retrieveByPK($data['ABE_UID']); } + //Only the 'FIELD' and 'LINK' types have a DYN_UID, + //the DYN_UID field is empty when the type is 'CUSTOM'. + if ($data['ABE_TYPE'] === 'CUSTOM') { + $data['DYN_UID'] = ''; + } if (isset($data['ABE_CUSTOM_GRID'])) { $data['ABE_CUSTOM_GRID'] = serialize($data['ABE_CUSTOM_GRID']); diff --git a/workflow/engine/classes/model/AppNotes.php b/workflow/engine/classes/model/AppNotes.php index 57db63a23..e40a75068 100644 --- a/workflow/engine/classes/model/AppNotes.php +++ b/workflow/engine/classes/model/AppNotes.php @@ -169,9 +169,14 @@ class AppNotes extends BaseAppNotes $configuration['MESS_ENGINE'] = ''; } - $users = new Users(); - $userInfo = $users->load($usrUid); - $authorName = ((($userInfo['USR_FIRSTNAME'] != '') || ($userInfo['USR_LASTNAME'] != '')) ? $userInfo['USR_FIRSTNAME'] . ' ' . $userInfo['USR_LASTNAME'] . ' ' : '') . '<' . $userInfo['USR_EMAIL'] . '>'; + //This value can be empty when the previous task is: 'Script Task', 'Timer Event' or other without user. + if (!empty($usrUid)) { + $users = new Users(); + $userInfo = $users->load($usrUid); + $authorName = ((($userInfo['USR_FIRSTNAME'] != '') || ($userInfo['USR_LASTNAME'] != '')) ? $userInfo['USR_FIRSTNAME'] . ' ' . $userInfo['USR_LASTNAME'] . ' ' : '') . '<' . $userInfo['USR_EMAIL'] . '>'; + } else { + $authorName = G::LoadTranslation('UID_UNDEFINED_USER'); + } $cases = new Cases(); $fieldCase = $cases->loadCase($appUid, $delIndex); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/ActionsByEmail.php b/workflow/engine/src/ProcessMaker/BusinessModel/ActionsByEmail.php index 7764ad001..77f1581f9 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/ActionsByEmail.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/ActionsByEmail.php @@ -265,12 +265,15 @@ class ActionsByEmail } /** - * Get the information for the log - * + * Get the information for the log. + * * @param array $arrayData - * * @return array - */ + * + * @see ProcessMaker\Services\Api\ActionsByEmail->loadActionByEmail() + * @see workflow/engine/methods/actionsByEmail/actionsByEmailAjax.php + * @link https://wiki.processmaker.com/3.3/Actions_by_Email + */ public function loadActionByEmail(array $arrayData) { //Get the total @@ -331,10 +334,15 @@ class ActionsByEmail //Get the previous user $appDelegation = new AppDelegation(); $usrUid = $appDelegation->getUserAssignedInThread($data[$index]['APP_UID'], $data[$index]['DEL_PREVIOUS']); - $users = new ClassUsers(); - $dataRes = $users->load($usrUid); - if (!empty($dataRes)) { - $data[$index]['USER'] = $dataRes['USR_FIRSTNAME'] . ' ' . $dataRes['USR_LASTNAME']; + //This value can be empty when the previous task is: 'Script Task', 'Timer Event' or other without user. + if (!empty($usrUid)) { + $users = new ClassUsers(); + $dataRes = $users->load($usrUid); + if (!empty($dataRes)) { + $data[$index]['USER'] = $dataRes['USR_FIRSTNAME'] . ' ' . $dataRes['USR_LASTNAME']; + } else { + $data[$index]['USER'] = ''; + } } else { $data[$index]['USER'] = ''; } @@ -435,10 +443,14 @@ class ActionsByEmail } /** - * Get the decision from Actions By Email and check if is Bpmn Process + * Get the decision from Actions By Email and check if is Bpmn Process. * @param array $arrayData * * @return string $message + * + * @see workflow/engine/methods/actionsByEmail/actionsByEmailAjax.php + * @see ProcessMaker\Services\Api\ActionsByEmail->viewForm() + * @link https://wiki.processmaker.com/3.3/Actions_by_Email#Actions_by_Email_Log */ public function viewForm(array $arrayData) { @@ -453,6 +465,7 @@ class ActionsByEmail $criteria->addSelectColumn(AbeConfigurationPeer::TAS_UID); $criteria->addSelectColumn(AbeConfigurationPeer::DYN_UID); $criteria->addSelectColumn(AbeConfigurationPeer::ABE_ACTION_FIELD); + $criteria->addSelectColumn(AbeConfigurationPeer::ABE_TYPE); $criteria->addSelectColumn(AbeRequestsPeer::ABE_REQ_UID); $criteria->addSelectColumn(AbeRequestsPeer::APP_UID); @@ -468,17 +481,21 @@ class ActionsByEmail $resultRes->setFetchmode(ResultSet::FETCHMODE_ASSOC); $resultRes->next(); - $dataRes = Array(); + $dataRes = []; $message = G::LoadTranslation('ID_USER_NOT_RESPONDED_REQUEST'); if ($dataRes = $resultRes->getRow()) { $_SESSION['CURRENT_DYN_UID'] = trim($dataRes['DYN_UID']); $process = new \Process(); $isBpmn = $process->isBpmnProcess($dataRes['PRO_UID']); - if($isBpmn) { - $message = $this->viewFormBpmn($dataRes); + if ($isBpmn) { + if ($dataRes['ABE_TYPE'] === 'FIELD') { + $message = $this->viewFormBpmn($dataRes); + } else { + $message = G::LoadTranslation('ID_CASE_RESPONSE_NOT_AVAILABLE'); + } } else { - $message = $this->viewFormClassic($dataRes); + $message = $this->viewFormClassic($dataRes); //to do, review this function } } @@ -538,11 +555,13 @@ class ActionsByEmail } /** - * Get the decision from Actions By Email by BPMN dynaform - * + * Get the decision from Actions By Email by BPMN dynaform. + * * @param array $dataRes - * - * @return string $message + * @return string + * + * @see ActionsByEmail->viewForm() + * @link https://wiki.processmaker.com/3.3/Actions_by_Email */ public function viewFormBpmn(array $dataRes) { @@ -599,9 +618,15 @@ class ActionsByEmail case 'dropdown': case 'radiogroup': case 'radio': - $message = $field->label . ': '; - $message .= $field->options[$value]; + if (!empty($field->options[$value])) { + $message = $field->label . ': '; + $message .= $field->options[$value]; + } break; + /** + * 'yesno' is deprecated in version ProcessMaker 3.x.x. + * @deprecated + */ case 'yesno': $message = $field->label . ': '; $message .= $value == 1 ? G::LoadTranslation('ID_YES') : G::LoadTranslation('ID_NO'); @@ -609,13 +634,18 @@ class ActionsByEmail case 'checkgroup': case 'checkbox': $message = $field->label . ': '; - $message .= $value == 'On' ? G::LoadTranslation('ID_CHECK') : G::LoadTranslation('ID_UNCHECK'); + if (!empty($value)) { + /** + * Value 'On' is deprecated in version ProcessMaker 3.x.x. + * now return '1'. + * @deprecated + */ + $message .= ($value == 'On' || $value == '1') ? G::LoadTranslation('ID_CHECK') : G::LoadTranslation('ID_UNCHECK'); + } break; } } } - - //Return return $message; } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/TimerEvent.php b/workflow/engine/src/ProcessMaker/BusinessModel/TimerEvent.php index 3496b1268..c997f2508 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/TimerEvent.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/TimerEvent.php @@ -1200,11 +1200,14 @@ class TimerEvent /** * Start/Continue case by Timer-Event - * + * * @param string $datetime Datetime (yyyy-mm-dd hh:ii:ss) - * @param bool $frontEnd Flag to represent the terminal front-end - * - * return void + * @param bool $frontEnd Flag to represent the terminal front-end + * @throws \Exception + * + * @see workflow/engine/bin/cron_single.php + * @link https://wiki.processmaker.com/3.3/Actions_by_Email + * @link https://wiki.processmaker.com/3.2/Executing_cron.php */ public function startContinueCaseByTimerEvent($datetime, $frontEnd = false) { @@ -1622,6 +1625,8 @@ class TimerEvent $delIndex = $row["DEL_INDEX"]; $delDelegateDate = $row["DEL_DELEGATE_DATE"]; $bpmnEventName = $row["EVN_NAME"]; + $taskUid = !empty($arrayApplicationData['APP_DATA']) && !empty($arrayApplicationData['APP_DATA']['TASK']) ? + $arrayApplicationData['APP_DATA']['TASK'] : ''; //Continue the case $continueCaseDate = $delDelegateDate;