solve conflicts

This commit is contained in:
Rodrigo Quelca
2019-05-17 11:16:18 -04:00
218 changed files with 11380 additions and 9660 deletions

View File

@@ -4,30 +4,27 @@ namespace ProcessMaker\BusinessModel;
use AbeConfiguration;
use AbeConfigurationPeer;
use AppMessage;
use AbeRequests;
use AbeRequestsPeer;
use AbeResponsesPeer;
use ApplicationPeer;
use AppDelegation;
use AppDelegationPeer;
use AppMessage;
use Criteria;
use DynaformPeer;
use EmailServerPeer;
use Exception;
use G;
use Publisher;
use ProcessMaker\BusinessModel\EmailServer;
use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry;
use PmDynaform;
use PMLicensedFeatures;
use ProcessPeer;
use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry;
use Publisher;
use ResultSet;
use SpoolRun;
use Users as ClassUsers;
use stdClass;
use UsersPeer;
use TaskPeer;
use Users as ClassUsers;
use WsBase;
/**
* Description of ActionsByEmailService
@@ -269,12 +266,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
@@ -335,10 +335,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'] = '';
}
@@ -362,6 +367,9 @@ class ActionsByEmail
*
* @return string $message
* @throws Exception
*
* @see workflow/engine/methods/actionsByEmail/actionsByEmailAjax.php
* @see \ProcessMaker\Services\Api\ActionsByEmail::forwardMail()
*/
public function forwardMail(array $arrayData)
{
@@ -393,7 +401,7 @@ class ActionsByEmail
'',
$dataRes['APP_UID'],
$dataRes['DEL_INDEX'],
'TEST',
WsBase::MESSAGE_TYPE_ACTIONS_BY_EMAIL,
$dataRes['ABE_REQ_SUBJECT'],
$aSetup['MESS_ACCOUNT'],
$dataRes['ABE_REQ_SENT_TO'],
@@ -403,7 +411,7 @@ class ActionsByEmail
'',
'',
'pending',
'',
1,
'',
false,
isset($dataRes['APP_NUMBER']) ? $dataRes['APP_NUMBER'] : 0,
@@ -439,10 +447,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)
{
@@ -457,6 +469,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);
@@ -472,17 +485,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
}
}
@@ -542,49 +559,57 @@ class ActionsByEmail
}
/**
* Get the decision from Actions By Email by BPMN dynaform
* @param array $arrayData
*
* @return string $message
* Get the decision from Actions By Email by BPMN dynaform.
*
* @param array $dataRes
* @return string
*
* @see ActionsByEmail->viewForm()
* @link https://wiki.processmaker.com/3.3/Actions_by_Email
*/
public function viewFormBpmn(array $dataRes)
{
$_SESSION['CURRENT_DYN_UID'] = trim($dataRes['DYN_UID']);
$configuration['DYN_UID'] = trim($dataRes['DYN_UID']);
$_SESSION['CURRENT_DYN_UID'] = trim($dataRes['DYN_UID']);
$configuration['DYN_UID'] = trim($dataRes['DYN_UID']);
$configuration['CURRENT_DYNAFORM'] = trim($dataRes['DYN_UID']);
$configuration['PRO_UID'] = trim($dataRes['PRO_UID']);
$configuration['PRO_UID'] = trim($dataRes['PRO_UID']);
$criteriaD = new Criteria();
$criteriaD->addSelectColumn(\DynaformPeer::DYN_CONTENT);
$criteriaD->addSelectColumn(\DynaformPeer::PRO_UID);
$criteriaD->add(\DynaformPeer::DYN_UID, trim($dataRes['DYN_UID']));
$resultD = \DynaformPeer::doSelectRS($criteriaD);
$criteriaD->addSelectColumn(DynaformPeer::DYN_CONTENT);
$criteriaD->addSelectColumn(DynaformPeer::PRO_UID);
$criteriaD->add(DynaformPeer::DYN_UID, trim($dataRes['DYN_UID']));
$resultD = DynaformPeer::doSelectRS($criteriaD);
$resultD->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$resultD->next();
$configuration = $resultD->getRow();
$field = new \stdClass();
$field = new stdClass();
$field->type = '';
$field->label = '';
$field->options = [];
$obj = new PmDynaform($configuration);
$message = G::LoadTranslation('ID_CASE_RESPONSE_NOT_AVAILABLE');
if ($dataRes['ABE_RES_DATA'] !== '') {
$value = unserialize($dataRes['ABE_RES_DATA']);
$actionField = str_replace(array('@@','@#','@=','@%','@?','@$'), '', $dataRes['ABE_ACTION_FIELD']);
$variables = G::json_decode($configuration['DYN_CONTENT'], true);
$value = unserialize($dataRes['ABE_RES_DATA']);
$actionField = str_replace(['@@', '@#', '@=', '@%', '@?', '@$'], '', $dataRes['ABE_ACTION_FIELD']);
$variables = G::json_decode($configuration['DYN_CONTENT'], true);
if (is_array($value)) {
if(isset($variables['items'][0]['items'])) {
if (isset($variables['items'][0]['items'])) {
$fields = $variables['items'][0]['items'];
}
} else {
if(isset($variables['items'][0]['items'])) {
if (isset($variables['items'][0]['items'])) {
$fields = $variables['items'][0]['items'];
foreach ($fields as $key => $row) {
foreach($row as $var) {
if(isset($var['variable'])) {
foreach ($row as $var) {
if (isset($var['variable'])) {
if ($var['variable'] === $actionField) {
$field->label = isset($var['label']) ? $var['label'] : '';
$field->type = isset($var['type']) ? $var['type'] : '';
$field->type = isset($var['type']) ? $var['type'] : '';
$values = $var['options'];
foreach ($values as $val){
foreach ($values as $val) {
$field->options[$val['value']] = $val['value'];
}
}
@@ -592,28 +617,39 @@ class ActionsByEmail
}
}
}
$message = '';
switch ($field->type) {
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');
$message = $field->label . ': ';
$message .= $value == 1 ? G::LoadTranslation('ID_YES') : G::LoadTranslation('ID_NO');
break;
case 'checkgroup':
case 'checkbox':
$message .= $field->label . ': ';
$message .= ($value == 'On') ? G::loadTranslation('ID_CHECK') : G::loadTranslation('ID_UNCHECK');
$message = $field->label . ': ';
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;
}

View File

@@ -21,6 +21,7 @@ use BpmnEngineServicesSearchIndex;
use Cases as ClassesCases;
use CasesPeer;
use Configurations;
use CreoleTypes;
use Criteria;
use DBAdapter;
use EntitySolrRequestData;
@@ -32,6 +33,7 @@ use InputDocument;
use InvalidIndexSearchTextException;
use ListParticipatedLast;
use PmDynaform;
use PmTable;
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
use ProcessMaker\BusinessModel\Task as BmTask;
use ProcessMaker\BusinessModel\User as BmUser;
@@ -39,16 +41,16 @@ use ProcessMaker\Core\System;
use ProcessMaker\Exception\UploadException;
use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Services\OAuth2\Server;
use ProcessMaker\Util\DateTime as UtilDateTime;
use ProcessMaker\Validation\ExceptionRestApi;
use ProcessMaker\Validation\Validator as FileValidator;
use ProcessPeer;
use ProcessUser;
use ProcessUserPeer;
use RBAC;
use ResultSet;
use RoutePeer;
use SubApplication;
use SubProcessPeer;
use Task as ModelTask;
use TaskPeer;
use Tasks as ClassesTasks;
@@ -61,6 +63,8 @@ class Cases
{
private $formatFieldNameInUppercase = true;
private $messageResponse = [];
private $solr = null;
private $solrEnv = null;
const MB_IN_KB = 1024;
const UNIT_MB = 'MB';
@@ -237,26 +241,11 @@ class Cases
public function getListCounters($userUid, array $arrayType)
{
try {
$solrEnabled = false;
$solrConf = System::solrEnv();
if ($solrConf !== false) {
$ApplicationSolrIndex = new AppSolr(
$solrConf['solr_enabled'],
$solrConf['solr_host'],
$solrConf['solr_instance']
);
if ($ApplicationSolrIndex->isSolrEnabled() && $solrConf['solr_enabled'] == true) {
$solrEnabled = true;
}
}
$appCacheView = new AppCacheView();
if ($solrEnabled) {
if ($this->isSolrEnabled()) {
$arrayListCounter = array_merge(
$ApplicationSolrIndex->getCasesCount($userUid),
$this->solr->getCasesCount($userUid),
$appCacheView->getAllCounters(['completed', 'cancelled'], $userUid)
);
} else {
@@ -422,6 +411,28 @@ class Cases
return $response;
}
/**
* Verify if Solr is Enabled
*
* @return bool
*/
private function isSolrEnabled()
{
$solrEnabled = false;
$this->solrEnv = !empty($this->solrEnv) ? $this->solrEnv : System::solrEnv();
if ($this->solrEnv !== false) {
$this->solr = !empty($this->solr) ? $this->solr : new AppSolr(
$this->solrEnv['solr_enabled'],
$this->solrEnv['solr_host'],
$this->solrEnv['solr_instance']
);
if ($this->solr->isSolrEnabled() && $this->solrEnv["solr_enabled"] == true) {
$solrEnabled = true;
}
}
return $solrEnabled;
}
/**
* Get data of a Case
*
@@ -434,21 +445,11 @@ class Cases
public function getCaseInfo($applicationUid, $userUid)
{
try {
$solrEnabled = 0;
if (($solrEnv = System::solrEnv()) !== false) {
$appSolr = new AppSolr(
$solrEnv["solr_enabled"],
$solrEnv["solr_host"],
$solrEnv["solr_instance"]
);
if ($appSolr->isSolrEnabled() && $solrEnv["solr_enabled"] == true) {
//Check if there are missing records to reindex and reindex them
$appSolr->synchronizePendingApplications();
$solrEnabled = 1;
}
}
if ($solrEnabled == 1) {
if ($this->isSolrEnabled()) {
try {
//Check if there are missing records to reindex and reindex them
$this->solr->synchronizePendingApplications();
$arrayData = array();
$delegationIndexes = array();
$columsToInclude = array("APP_UID");
@@ -464,7 +465,7 @@ class Cases
$columsToIncludeFinal = array_merge($columsToInclude, $delegationIndexes);
$solrRequestData = EntitySolrRequestData::createForRequestPagination(
array(
"workspace" => $solrEnv["solr_instance"],
"workspace" => $this->solrEnv["solr_instance"],
"startAfter" => 0,
"pageSize" => 1000,
"searchText" => $solrSearchText,
@@ -476,7 +477,7 @@ class Cases
)
);
//Use search index to return list of cases
$searchIndex = new BpmnEngineServicesSearchIndex($appSolr->isSolrEnabled(), $solrEnv["solr_host"]);
$searchIndex = new BpmnEngineServicesSearchIndex($this->solr->isSolrEnabled(), $this->solrEnv["solr_host"]);
//Execute query
$solrQueryResult = $searchIndex->getDataTablePaginatedList($solrRequestData);
//Get the missing data from database
@@ -484,7 +485,7 @@ class Cases
foreach ($solrQueryResult->aaData as $i => $data) {
$arrayApplicationUid[] = $data["APP_UID"];
}
$aaappsDBData = $appSolr->getListApplicationDelegationData($arrayApplicationUid);
$aaappsDBData = $this->solr->getListApplicationDelegationData($arrayApplicationUid);
foreach ($solrQueryResult->aaData as $i => $data) {
//Initialize array
$delIndexes = array(); //Store all the delegation indexes
@@ -513,7 +514,7 @@ class Cases
$aRow["APP_UID"] = $data["APP_UID"];
//Get delegation data from DB
//Filter data from db
$indexes = $appSolr->aaSearchRecords($aaappsDBData, array(
$indexes = $this->solr->aaSearchRecords($aaappsDBData, array(
"APP_UID" => $applicationUid,
"DEL_INDEX" => $delIndex
));
@@ -662,6 +663,31 @@ class Cases
}
}
/**
* Get data of a sub-process case
*
* @param string $applicationUid Unique Case Id
* @param string $userUid Unique User Id
*
* @return array Return an array with information of Cases
* @throws Exception
*/
public function getCaseInfoSubProcess($applicationUid, $userUid)
{
try {
$response = [];
$subApplication = new SubApplication();
$data = $subApplication->loadByAppUidParent($applicationUid);
foreach ($data as $item) {
$response[] = $this->getCaseInfo($item['APP_UID'], $userUid);
}
return $response;
} catch (Exception $e) {
throw $e;
}
}
/**
* Get data Task Case
*
@@ -2104,6 +2130,11 @@ class Cases
*
* @param string $applicationUid Unique id of Case
*
* @see workflow/engine/src/ProcessMaker/Services/Api/Cases.php
* @see workflow/engine/src/ProcessMaker/Services/Api/Light.php
*
* @link https://wiki.processmaker.com/3.3/REST_API_Cases/Cases#Get_Case.27s_Tasks:_GET_.2Fcases.2F.7Bapp_uid.7D.2Ftasks
*
* @return array Return an array with all Tasks of Case
* @throws Exception
*/
@@ -2127,33 +2158,20 @@ class Cases
$taskUid = "";
//Get data
//SQL
$delimiter = DBAdapter::getStringDelimiter();
//Obtain the list of tasks and their respectives users assigned to each one for an specific case
$case = new ClassesCases();
$rsTasks = $case->getTasksInfoForACase($applicationUid, $processUid);
$criteria = new Criteria("workflow");
while ($rsTasks->next()) {
$row = $rsTasks->getRow();
$criteria->addSelectColumn(TaskPeer::TAS_UID);
$criteria->addSelectColumn(TaskPeer::TAS_TITLE);
$criteria->addSelectColumn(TaskPeer::TAS_DESCRIPTION);
$criteria->addSelectColumn(TaskPeer::TAS_START);
$criteria->addSelectColumn(TaskPeer::TAS_TYPE);
$criteria->addSelectColumn(TaskPeer::TAS_DERIVATION);
$criteria->addSelectColumn(TaskPeer::TAS_ASSIGN_TYPE);
$criteria->addSelectColumn(UsersPeer::USR_UID);
$criteria->addSelectColumn(UsersPeer::USR_USERNAME);
$criteria->addSelectColumn(UsersPeer::USR_FIRSTNAME);
$criteria->addSelectColumn(UsersPeer::USR_LASTNAME);
$criteria->addJoin(TaskPeer::TAS_LAST_ASSIGNED, UsersPeer::USR_UID, Criteria::LEFT_JOIN);
$criteria->add(TaskPeer::PRO_UID, $processUid, Criteria::EQUAL);
$rsCriteria = TaskPeer::doSelectRS($criteria);
$rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC);
while ($rsCriteria->next()) {
$row = $rsCriteria->getRow();
//If the task is a multiple task
if ($row["TAS_ASSIGN_TYPE"] == 'MULTIPLE_INSTANCE' || $row["TAS_ASSIGN_TYPE"] == 'MULTIPLE_INSTANCE_VALUE_BASED') {
$row["USR_UID"] = "";
$row["USR_USERNAME"] = "";
$row["USR_FIRSTNAME"] = "";
$row["USR_LASTNAME"] = "";
}
//Task
if ($row["TAS_TYPE"] == "NORMAL") {
@@ -2165,17 +2183,9 @@ class Cases
$row["TAS_TITLE"] = $task->getTasTitle();
}
} else {
$criteria2 = new Criteria("workflow");
$criteria2->addSelectColumn(SubProcessPeer::PRO_UID);
$criteria2->addSelectColumn(TaskPeer::TAS_TITLE);
$criteria2->addSelectColumn(TaskPeer::TAS_DESCRIPTION);
$criteria2->addJoin(SubProcessPeer::TAS_PARENT, TaskPeer::TAS_UID, Criteria::LEFT_JOIN);
$criteria2->add(SubProcessPeer::PRO_PARENT, $processUid);
$criteria2->add(SubProcessPeer::TAS_PARENT, $row["TAS_UID"]);
$rsCriteria2 = SubProcessPeer::doSelectRS($criteria2);
$rsCriteria2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
//Get the task information when the task type is different from normal
$rsCriteria2 = $case->getTaskInfoForSubProcess($processUid, $row["TAS_UID"]);
$rsCriteria2->next();
@@ -2191,18 +2201,8 @@ class Cases
$routeType = "";
$arrayRoute = array();
$criteria2 = new Criteria("workflow");
$criteria2->addAsColumn("ROU_NUMBER", RoutePeer::ROU_CASE);
$criteria2->addSelectColumn(RoutePeer::ROU_TYPE);
$criteria2->addSelectColumn(RoutePeer::ROU_CONDITION);
$criteria2->addAsColumn("TAS_UID", RoutePeer::ROU_NEXT_TASK);
$criteria2->add(RoutePeer::PRO_UID, $processUid, Criteria::EQUAL);
$criteria2->add(RoutePeer::TAS_UID, $row["TAS_UID"], Criteria::EQUAL);
$criteria2->addAscendingOrderByColumn("ROU_NUMBER");
$rsCriteria2 = RoutePeer::doSelectRS($criteria2);
$rsCriteria2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
//Get the routes of a task
$rsCriteria2 = $case->getTaskRoutes($processUid, $row["TAS_UID"]);
while ($rsCriteria2->next()) {
$row2 = $rsCriteria2->getRow();
@@ -2219,25 +2219,7 @@ class Cases
//Delegations
$arrayAppDelegation = array();
$criteria2 = new Criteria("workflow");
$criteria2->addSelectColumn(AppDelegationPeer::DEL_INDEX);
$criteria2->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE);
$criteria2->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE);
$criteria2->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE);
$criteria2->addSelectColumn(UsersPeer::USR_UID);
$criteria2->addSelectColumn(UsersPeer::USR_USERNAME);
$criteria2->addSelectColumn(UsersPeer::USR_FIRSTNAME);
$criteria2->addSelectColumn(UsersPeer::USR_LASTNAME);
$criteria2->addJoin(AppDelegationPeer::USR_UID, UsersPeer::USR_UID, Criteria::LEFT_JOIN);
$criteria2->add(AppDelegationPeer::APP_UID, $applicationUid, Criteria::EQUAL);
$criteria2->add(AppDelegationPeer::TAS_UID, $row["TAS_UID"], Criteria::EQUAL);
$criteria2->addAscendingOrderByColumn(AppDelegationPeer::DEL_INDEX);
$rsCriteria2 = AppDelegationPeer::doSelectRS($criteria2);
$rsCriteria2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$rsCriteria2 = $case->getCaseDelegations($applicationUid, $row["TAS_UID"]);
while ($rsCriteria2->next()) {
$row2 = $rsCriteria2->getRow();
@@ -2268,8 +2250,10 @@ class Cases
$appDelegationDuration = G::LoadTranslation("ID_NOT_FINISHED");
if (!empty($row2["DEL_FINISH_DATE"]) && !empty($row2["DEL_INIT_DATE"])) {
$t = strtotime($row2["DEL_FINISH_DATE"]) - strtotime($row2["DEL_INIT_DATE"]);
$date = empty($row2["DEL_INIT_DATE"]) ? $row2["DEL_DELEGATE_DATE"] : $row2["DEL_INIT_DATE"];
if (!empty($row2["DEL_FINISH_DATE"]) && !empty($date)) {
$t = strtotime($row2["DEL_FINISH_DATE"]) - strtotime($date);
$h = $t * (1 / 60) * (1 / 60);
$m = ($h - (int)($h)) * (60 / 1);
@@ -2290,40 +2274,22 @@ class Cases
$this->getFieldNameByFormatFieldName("DEL_FINISH_DATE") => $arrayAppDelegationDate["DEL_FINISH_DATE"]["dateFormated"],
$this->getFieldNameByFormatFieldName("DEL_DURATION") => $appDelegationDuration,
$this->getFieldNameByFormatFieldName("USR_UID") => $row2["USR_UID"],
$this->getFieldNameByFormatFieldName("USR_USERNAME") => $row2["USR_USERNAME"] . "",
$this->getFieldNameByFormatFieldName("USR_FIRSTNAME") => $row2["USR_FIRSTNAME"] . "",
$this->getFieldNameByFormatFieldName("USR_LASTNAME") => $row2["USR_LASTNAME"] . ""
$this->getFieldNameByFormatFieldName("USR_USERNAME") => $row2["USR_USERNAME"],
$this->getFieldNameByFormatFieldName("USR_FIRSTNAME") => $row2["USR_FIRSTNAME"],
$this->getFieldNameByFormatFieldName("USR_LASTNAME") => $row2["USR_LASTNAME"]
);
}
//Status
$status = "";
//$criteria2
$criteria2 = new Criteria("workflow");
$criteria2->addAsColumn("CANT", "COUNT(" . AppDelegationPeer::APP_UID . ")");
$criteria2->addAsColumn("FINISH", "MIN(" . AppDelegationPeer::DEL_FINISH_DATE . ")");
$criteria2->add(AppDelegationPeer::APP_UID, $applicationUid, Criteria::EQUAL);
$criteria2->add(AppDelegationPeer::TAS_UID, $row["TAS_UID"], Criteria::EQUAL);
$rsCriteria2 = AppDelegationPeer::doSelectRS($criteria2);
$rsCriteria2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$rsCriteria2 = $case->getTotalAndMinDateForACase($applicationUid, $row["TAS_UID"]);
$rsCriteria2->next();
$row2 = $rsCriteria2->getRow();
//$criteria3
$criteria3 = new Criteria("workflow");
$criteria3->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE);
$criteria3->add(AppDelegationPeer::APP_UID, $applicationUid, Criteria::EQUAL);
$criteria3->add(AppDelegationPeer::TAS_UID, $row["TAS_UID"], Criteria::EQUAL);
$criteria3->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL);
$rsCriteria3 = AppDelegationPeer::doSelectRS($criteria3);
$rsCriteria3->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$rsCriteria3 = $case->getDelegationFinishDate($applicationUid, $row["TAS_UID"]);
$rsCriteria3->next();
@@ -3538,7 +3504,7 @@ class Cases
* @param string $listPeer , name of the list class
* @param string $search , the parameter for search in the table
* @param string $additionalClassName , name of the className of pmtable
* @param array $additionalColumns , columns related to the custom cases list
* @param array $additionalColumns , columns related to the custom cases list ex: TABLE_NAME.COLUMN_NAME
*
* @throws PropelException
*/
@@ -3547,31 +3513,35 @@ class Cases
$listPeer,
$search,
$additionalClassName = '',
$additionalColumns = array()
$additionalColumns = []
) {
$oTmpCriteria = '';
$tmpCriteria = '';
//If we have additional tables configured in the custom cases list, prepare the variables for search
if (count($additionalColumns) > 0) {
require_once(PATH_DATA_SITE . 'classes' . PATH_SEP . $additionalClassName . '.php');
$oNewCriteria = new Criteria("workflow");
$oTmpCriteria = $oNewCriteria->getNewCriterion(current($additionalColumns), "%" . $search . "%",
Criteria::LIKE);
$columnPivot = current($additionalColumns);
$tableAndColumn = explode(".", $columnPivot);
$type = PmTable::getTypeOfColumn($listPeer, $tableAndColumn[0], $tableAndColumn[1]);
$tmpCriteria = $this->defineCriteriaByColumnType($type, $columnPivot, $search);
//We prepare the query related to the custom cases list
foreach (array_slice($additionalColumns, 1) as $value) {
$oTmpCriteria = $oNewCriteria->getNewCriterion($value, "%" . $search . "%",
Criteria::LIKE)->addOr($oTmpCriteria);
foreach (array_slice($additionalColumns, 1) as $column) {
$tableAndColumn = explode(".", $column);
$type = PmTable::getTypeOfColumn($listPeer, $tableAndColumn[0], $tableAndColumn[1]);
$tmpCriteria = $this->defineCriteriaByColumnType($type, $column, $search)->addOr($tmpCriteria);
}
}
if (!empty($oTmpCriteria)) {
if (!empty($tmpCriteria)) {
$criteria->add(
$criteria->getNewCriterion($listPeer::APP_TITLE, '%' . $search . '%', Criteria::LIKE)->addOr(
$criteria->getNewCriterion($listPeer::APP_TAS_TITLE, '%' . $search . '%', Criteria::LIKE)->addOr(
$criteria->getNewCriterion($listPeer::APP_PRO_TITLE, '%' . $search . '%',
Criteria::LIKE)->addOr(
$criteria->getNewCriterion($listPeer::APP_NUMBER, $search, Criteria::EQUAL)->addOr(
$oTmpCriteria
$tmpCriteria
))))
);
} else {
@@ -3585,6 +3555,58 @@ class Cases
}
}
/**
* Define the criteria according to the column type
*
* @param string $fieldType
* @param string $column
* @param string $search
*
* @return Criteria
*/
private function defineCriteriaByColumnType($fieldType, $column, $search)
{
$newCriteria = new Criteria("workflow");
switch ($fieldType) {
case CreoleTypes::BOOLEAN:
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::EQUAL);
break;
case CreoleTypes::BIGINT:
case CreoleTypes::INTEGER:
case CreoleTypes::SMALLINT:
case CreoleTypes::TINYINT:
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::EQUAL);
break;
case CreoleTypes::REAL:
case CreoleTypes::DECIMAL:
case CreoleTypes::DOUBLE:
case CreoleTypes::FLOAT:
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::LIKE);
break;
case CreoleTypes::CHAR:
case CreoleTypes::LONGVARCHAR:
case CreoleTypes::VARCHAR:
$criteria = $newCriteria->getNewCriterion($column, "%" . $search . "%", Criteria::LIKE);
break;
case CreoleTypes::DATE:
case CreoleTypes::TIME:
case CreoleTypes::TIMESTAMP://DATETIME
//@todo use the same constant in other places
if (preg_match(UtilDateTime::REGEX_IS_DATE,
$search, $arrayMatch)) {
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::GREATER_EQUAL);
} else {
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::EQUAL);
}
break;
default:
$criteria = $newCriteria->getNewCriterion($column, $search, Criteria::EQUAL);
}
return $criteria;
}
/**
* This function get the table.column by order by the result
* We can include the additional table related to the custom cases list

View File

@@ -937,7 +937,7 @@ class InputDocument
*/
public function uploadFileCase($files, $caseInstance, $aData, $userUid, $appUid, $delIndex)
{
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
ValidationUploadedFiles::getValidationUploadedFiles()->dispatch(function($validator) {
G::SendMessageText($validator->getMessage(), "ERROR");
$url = explode("sys" . config("system.workspace"), $_SERVER['HTTP_REFERER']);
G::header("location: " . "/sys" . config("system.workspace") . $url[1]);

View File

@@ -1,6 +1,9 @@
<?php
namespace ProcessMaker\BusinessModel\Cases;
use G;
use OutputDocument as ClassesOutputDocument;
use PEAR;
use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry;
@@ -451,7 +454,8 @@ class OutputDocument
$oOutputDocument = new \OutputDocument();
$aOD = $oOutputDocument->load($outputID);
$Fields = $oCase->loadCase($sApplication);
$sFilename = preg_replace('[^A-Za-z0-9_]', '_', \G::replaceDataField($aOD['OUT_DOC_FILENAME'], $Fields['APP_DATA']));
$outDocFile = replacePrefixes($aOD['OUT_DOC_FILENAME']);
$sFilename = preg_replace('[^A-Za-z0-9_]', '_', \G::replaceDataField($outDocFile, $Fields['APP_DATA']));
require_once(PATH_TRUNK . "workflow" . PATH_SEP . "engine" . PATH_SEP . "classes" . PATH_SEP . "model" . PATH_SEP . "AppFolder.php");
require_once(PATH_TRUNK . "workflow" . PATH_SEP . "engine" . PATH_SEP . "classes" . PATH_SEP . "model" . PATH_SEP . "AppDocument.php");
//Get the Custom Folder ID (create if necessary)
@@ -591,21 +595,31 @@ class OutputDocument
}
}
/*
/**
* Generate the output document
* @param string $sUID
* @param array $aFields
* @param string $sPath
* @return variant
*
* @param string $outDocUid
* @param array $caseFields
* @param string $path
* @param string $filename
* @param string $content
* @param bool $landscape
* @param string $typeDocsToGen
* @param array $properties
* @param string $application
*
* @return mixed
*
* @see this->addCasesOutputDocument()
*/
public function generate($sUID, $aFields, $sPath, $sFilename, $sContent, $sLandscape = false, $sTypeDocToGener = 'BOTH', $aProperties = array(), $sApplication)
public function generate($outDocUid, $caseFields, $path, $filename, $content, $landscape = false, $typeDocsToGen = 'BOTH', $properties = [], $application = '')
{
if (($sUID != '') && is_array($aFields) && ($sPath != '')) {
$sContent = \G::replaceDataGridField($sContent, $aFields);
\G::verifyPath($sPath, true);
if (($outDocUid != '') && is_array($caseFields) && ($path != '')) {
$content = G::replaceDataGridField($content, $caseFields, true, true);
G::verifyPath($path, true);
//Start - Create .doc
$oFile = fopen($sPath . $sFilename . '.doc', 'wb');
$size = array();
$fp = fopen($path . $filename . '.doc', 'wb');
$size = [];
$size["Letter"] = "216mm 279mm";
$size["Legal"] = "216mm 357mm";
$size["Executive"] = "184mm 267mm";
@@ -626,6 +640,7 @@ class OutputDocument
$size["Screenshot640"] = "640mm 480mm";
$size["Screenshot800"] = "800mm 600mm";
$size["Screenshot1024"] = "1024mm 768mm";
$sizeLandscape = [];
$sizeLandscape["Letter"] = "279mm 216mm";
$sizeLandscape["Legal"] = "357mm 216mm";
$sizeLandscape["Executive"] = "267mm 184mm";
@@ -646,31 +661,31 @@ class OutputDocument
$sizeLandscape["Screenshot640"] = "480mm 640mm";
$sizeLandscape["Screenshot800"] = "600mm 800mm";
$sizeLandscape["Screenshot1024"] = "768mm 1024mm";
if (!isset($aProperties['media'])) {
$aProperties['media'] = 'Letter';
if (!isset($properties['media'])) {
$properties['media'] = 'Letter';
}
if ($sLandscape) {
$media = $sizeLandscape[$aProperties['media']];
if ($landscape) {
$media = $sizeLandscape[$properties['media']];
} else {
$media = $size[$aProperties['media']];
$media = $size[$properties['media']];
}
$marginLeft = '15';
if (isset($aProperties['margins']['left'])) {
$marginLeft = $aProperties['margins']['left'];
if (isset($properties['margins']['left'])) {
$marginLeft = $properties['margins']['left'];
}
$marginRight = '15';
if (isset($aProperties['margins']['right'])) {
$marginRight = $aProperties['margins']['right'];
if (isset($properties['margins']['right'])) {
$marginRight = $properties['margins']['right'];
}
$marginTop = '15';
if (isset($aProperties['margins']['top'])) {
$marginTop = $aProperties['margins']['top'];
if (isset($properties['margins']['top'])) {
$marginTop = $properties['margins']['top'];
}
$marginBottom = '15';
if (isset($aProperties['margins']['bottom'])) {
$marginBottom = $aProperties['margins']['bottom'];
if (isset($properties['margins']['bottom'])) {
$marginBottom = $properties['margins']['bottom'];
}
fwrite($oFile, '<html xmlns:v="urn:schemas-microsoft-com:vml"
fwrite($fp, '<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
@@ -715,40 +730,40 @@ class OutputDocument
</head>
<body>
<div class=WordSection1>');
fwrite($oFile, $sContent);
fwrite($oFile, "\n</div></body></html>\n\n");
fclose($oFile);
fwrite($fp, $content);
fwrite($fp, "\n</div></body></html>\n\n");
fclose($fp);
/* End - Create .doc */
if ($sTypeDocToGener == 'BOTH' || $sTypeDocToGener == 'PDF') {
$oFile = fopen($sPath . $sFilename . '.html', 'wb');
fwrite($oFile, $sContent);
fclose($oFile);
if ($typeDocsToGen == 'BOTH' || $typeDocsToGen == 'PDF') {
$fp = fopen($path . $filename . '.html', 'wb');
fwrite($fp, $content);
fclose($fp);
/* Start - Create .pdf */
if (isset($aProperties['report_generator'])) {
switch ($aProperties['report_generator']) {
if (isset($properties['report_generator'])) {
switch ($properties['report_generator']) {
case 'TCPDF':
$o = new \OutputDocument();
if (strlen($sContent) == 0) {
$o = new ClassesOutputDocument();
if (strlen($content) == 0) {
libxml_use_internal_errors(true);
$o->generateTcpdf($sUID, $aFields, $sPath, $sFilename, ' ', $sLandscape, $aProperties);
$o->generateTcpdf($outDocUid, $caseFields, $path, $filename, ' ', $landscape, $properties);
libxml_use_internal_errors(false);
} else {
$o->generateTcpdf($sUID, $aFields, $sPath, $sFilename, $sContent, $sLandscape, $aProperties);
$o->generateTcpdf($outDocUid, $caseFields, $path, $filename, $content, $landscape, $properties);
}
break;
case 'HTML2PDF':
default:
$this->generateHtml2ps_pdf($sUID, $aFields, $sPath, $sFilename, $sContent, $sLandscape, $aProperties, $sApplication);
$this->generateHtml2ps_pdf($outDocUid, $caseFields, $path, $filename, $content, $landscape, $properties, $application);
break;
}
} else {
$this->generateHtml2ps_pdf($sUID, $aFields, $sPath, $sFilename, $sContent, $sLandscape, $aProperties);
$this->generateHtml2ps_pdf($outDocUid, $caseFields, $path, $filename, $content, $landscape, $properties);
}
}
//end if $sTypeDocToGener
//end if $typeDocsToGen
/* End - Create .pdf */
} else {
return \PEAR::raiseError(
return PEAR::raiseError(
null,
G_ERROR_USER_UID,
null,

View File

@@ -966,9 +966,10 @@ class DynaForm
if ($record['DYN_VERSION'] === 0) {
$record['DYN_VERSION'] = 1;
}
//to do, this line should be removed. Related to PMC-196.
$record['DYN_CONTENT'] = G::fixStringCorrupted($record['DYN_CONTENT']);
$record['DYN_CONTENT'] = preg_replace_callback("/\\\\u([a-f0-9]{4})/", function ($m) {
return "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$m[1]')))";
return iconv('UCS-4LE', 'UTF-8', pack('V', hexdec('U' . $m[1])));
}, $record['DYN_CONTENT']);
return array(
@@ -977,7 +978,7 @@ class DynaForm
$this->getFieldNameByFormatFieldName('DYN_DESCRIPTION') => $record['DYN_DESCRIPTION'] . '',
$this->getFieldNameByFormatFieldName('DYN_TYPE') => $record['DYN_TYPE'] . '',
$this->getFieldNameByFormatFieldName('DYN_CONTENT') => $record['DYN_CONTENT'] . '',
$this->getFieldNameByFormatFieldName('DYN_VERSION') => (int)$record['DYN_VERSION'],
$this->getFieldNameByFormatFieldName('DYN_VERSION') => (int) $record['DYN_VERSION'],
$this->getFieldNameByFormatFieldName('DYN_UPDATE_DATE') => $record['DYN_UPDATE_DATE']
);
} catch (\Exception $e) {

View File

@@ -14,6 +14,7 @@ use ProcessMaker\Util\Common;
use Propel;
use ResultSet;
use UsersPeer;
use WsBase;
class EmailEvent
{
@@ -455,11 +456,13 @@ class EmailEvent
* @param string $prj_uid Unique id of Project
* @param string $eventUid Unique id of event
* @param array $arrayApplicationData Case data
* @param int $tasId id of task
*
* @return void
* @throws Exception
* @see \Derivation::executeEvent()
*/
public function sendEmail($appUID, $prj_uid, $eventUid, $arrayApplicationData)
public function sendEmail($appUID, $prj_uid, $eventUid, $arrayApplicationData, $tasId = 0)
{
if (!$this->existsEvent($prj_uid, $eventUid)) {
throw new Exception(G::LoadTranslation('ID_EMAIL_EVENT_DEFINITION_DOES_NOT_EXIST'));
@@ -511,7 +514,9 @@ class EmailEvent
}
}
if (!empty($emailTo)) {
PMFSendMessage(
$ws = new WsBase();
$ws->setTaskId($tasId);
$ws->sendMessage(
$appUID,
G::buildFrom($configEmailData),
$emailTo,
@@ -523,7 +528,9 @@ class EmailEvent
[],
true,
0,
$configEmailData
$configEmailData,
0,
WsBase::MESSAGE_TYPE_EMAIL_EVENT
);
} else {
Bootstrap::registerMonolog(

View File

@@ -8,6 +8,7 @@ use G;
use ProcessMaker\Core\System;
use SpoolRun;
use TemplatePower;
use WsBase;
class EmailServer
{
@@ -156,6 +157,7 @@ class EmailServer
*
* @return array, return array with result of send test mail
* @throws Exception
* @see EmailServer->testConnectionByStep()
*/
public function sendTestMail(array $arrayData)
{
@@ -203,7 +205,7 @@ class EmailServer
'',
'',
0,
'TEST',
WsBase::MESSAGE_TYPE_TEST_EMAIL,
G::LoadTranslation("ID_MESS_TEST_SUBJECT"),
G::buildFrom($configuration),
$arrayData["TO"],

View File

@@ -1,7 +1,10 @@
<?php
namespace ProcessMaker\BusinessModel;
use G;
use Exception;
use PmDynaform;
use ProcessMaker\Util\PhpShorthandByte;
class InputDocument
{
@@ -288,7 +291,10 @@ class InputDocument
* @param string $processUid Unique id of Process
* @param array $arrayData Data
*
* return array Return data of the new InputDocument created
* @return array Return data of the new InputDocument created
*
* @see \ProcessMaker\Services\Api\Project\InputDocument->doPostInputDocument()
* @link https://wiki.processmaker.com/3.0/Input_Documents#Creating_Input_Documents
*/
public function create($processUid, $arrayData)
{
@@ -310,6 +316,8 @@ class InputDocument
$flagDataDestinationPath = (isset($arrayData["INP_DOC_DESTINATION_PATH"]))? 1 : 0;
$flagDataTags = (isset($arrayData["INP_DOC_TAGS"]))? 1 : 0;
$this->throwExceptionIfMaximumFileSizeExceed(intval($arrayData["INP_DOC_MAX_FILESIZE"]), $arrayData["INP_DOC_MAX_FILESIZE_UNIT"]);
//Create
$inputDocument = new \InputDocument();
@@ -348,8 +356,11 @@ class InputDocument
*
* @param string $inputDocumentUid Unique id of InputDocument
* @param array $arrayData Data
*
* return array Return data of the InputDocument updated
*
* @return array Return data of the InputDocument updated
*
* @see \ProcessMaker\Services\Api\Project\InputDocument->doPutInputDocument()
* @link https://wiki.processmaker.com/3.0/Input_Documents#Creating_Input_Documents
*/
public function update($inputDocumentUid, $arrayData)
{
@@ -374,6 +385,8 @@ class InputDocument
if (isset($arrayData["INP_DOC_TITLE"])) {
$this->throwExceptionIfExistsTitle($processUid, $arrayData["INP_DOC_TITLE"], $this->arrayFieldNameForException["inputDocumentTitle"], $inputDocumentUid);
}
$this->throwExceptionIfMaximumFileSizeExceed(intval($arrayData["INP_DOC_MAX_FILESIZE"]), $arrayData["INP_DOC_MAX_FILESIZE_UNIT"]);
//Update
$arrayData["INP_DOC_UID"] = $inputDocumentUid;
@@ -519,7 +532,7 @@ class InputDocument
*
* @param string $inputDocumentUid Unique id of InputDocument
*
* return array Return an array with data of an InputDocument
* @return array Return an array with data of an InputDocument
*/
public function getInputDocument($inputDocumentUid)
{
@@ -544,5 +557,71 @@ class InputDocument
throw $e;
}
}
/**
* Throw exception if maximum file size exceed to php directives.
*
* @param int $value
* @param string $unit
* @throws Exception
*
* @see ProcessMaker\BusinessModel\InputDocument->create()
* @see ProcessMaker\BusinessModel\InputDocument->update()
* @link https://wiki.processmaker.com/3.2/Input_Documents
*/
public function throwExceptionIfMaximumFileSizeExceed($value, $unit)
{
//The value of 'INP_DOC_MAX_FILESIZE_UNIT' can only take two values: 'KB'and 'MB'.
if ($unit === "MB") {
$value = $value * (1024 ** 2);
}
if ($unit === "KB") {
$value = $value * (1024 ** 1);
}
$object = $this->getMaxFileSize();
if ($object->uploadMaxFileSizeBytes < $value) {
throw new Exception(G::LoadTranslation("ID_THE_MAXIMUM_VALUE_OF_THIS_FIELD_IS", [$object->uploadMaxFileSize]));
}
}
/**
* To upload large files, post_max_size value must be larger than upload_max_filesize.
* Generally speaking, memory_limit should be larger than post_max_size. When an integer
* is used, the value is measured in bytes. The shorthand notation may also be used.
* If the size of post data is greater than post_max_size, the $_POST and $_FILES
* superglobals are empty.
*
* @return object
*
* @see ProcessMaker\BusinessModel\InputDocument->throwExceptionIfMaximumFileSizeExceed()
* @link https://wiki.processmaker.com/3.2/Input_Documents
* @link http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
*/
public function getMaxFileSize()
{
$phpShorthandByte = new PhpShorthandByte();
$postMaxSize = ini_get("post_max_size");
$postMaxSizeBytes = $phpShorthandByte->valueToBytes($postMaxSize);
$uploadMaxFileSize = ini_get("upload_max_filesize");
$uploadMaxFileSizeBytes = $phpShorthandByte->valueToBytes($uploadMaxFileSize);
if ($postMaxSizeBytes < $uploadMaxFileSizeBytes) {
$uploadMaxFileSize = $postMaxSize;
$uploadMaxFileSizeBytes = $postMaxSizeBytes;
}
//according to the acceptance criteria the information is always shown in MBytes
$uploadMaxFileSizeMBytes = $uploadMaxFileSizeBytes / (1024 ** 2); //conversion constant
$uploadMaxFileSizeUnit = "MB"; //short processmaker notation, https://wiki.processmaker.com/3.0/File_control#Size_Unity
$uploadMaxFileSizePhpUnit = "M"; //short php notation, http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
$result = [
"uploadMaxFileSize" => $phpShorthandByte->getFormatBytes($uploadMaxFileSizeMBytes . $uploadMaxFileSizePhpUnit),
"uploadMaxFileSizeBytes" => $uploadMaxFileSizeBytes,
"uploadMaxFileSizeMBytes" => $uploadMaxFileSizeMBytes,
"uploadMaxFileSizeUnit" => $uploadMaxFileSizeUnit
];
return (object) $result;
}
}

View File

@@ -415,6 +415,7 @@ class Light
$oCase = new Cases();
$Fields = $oCase->loadCase($cas_uid);
//@todo Find a better way to define session variables
$_SESSION["APPLICATION"] = $cas_uid;
$_SESSION["PROCESS"] = $prj_uid;
$_SESSION["TASK"] = $act_uid;
@@ -453,6 +454,7 @@ class Light
try {
$oCase = new Cases();
$Fields = $oCase->loadCase($app_uid);
//@todo Find a better way to define session variables
$_SESSION["APPLICATION"] = $app_uid;
$_SESSION["PROCESS"] = $Fields['PRO_UID'];
$_SESSION["TASK"] = $tas_uid;
@@ -1488,6 +1490,7 @@ class Light
}
$response['listLanguage'] = $languagesList;
if (isset($params['fileLimit']) && $params['fileLimit']) {
//to do: ProcessMaker\BusinessModel\InputDocument->getMaxFileSize()
$postMaxSize = $this->return_bytes(ini_get('post_max_size'));
$uploadMaxFileSize = $this->return_bytes(ini_get('upload_max_filesize'));
if ($postMaxSize < $uploadMaxFileSize) {

View File

@@ -17,9 +17,9 @@ use ProcessMaker\Core\System;
class PushMessageAndroid
{
private $url = 'https://android.googleapis.com/gcm/send';
private $serverApiKey = "AIzaSyBO-VLXGhjf0PPlwmPFTPQEKIBfVDydLAk";
private $devices = array();
private $url = 'https://fcm.googleapis.com/fcm/send';
private $serverApiKey = "AAAAMvip2iU:APA91bHFAvHmCsSh0zbRaC9Xo2EPIbbRYzehkFAKUdXmj_ZVBOOO52npae183LYUONHjNPHaKo1MqT4BWiEuTF7HVEMfwn05XOA-h1LQ_bJ0ezAA35l-wADPq5VtKDiHT1VFGW1oeU7L";
private $devices = [];
private $numberDevices = 0;
/**
@@ -78,24 +78,24 @@ class PushMessageAndroid
}
if (!is_null($data)) {
$fields = array(
$fields = [
'registration_ids' => $this->devices,
'data' => array(
"message" => $message,
"data" => $data
),
);
'notification' => [
"body" => $message,
"data" => $data,
],
];
} else {
$fields = array(
$fields = [
'registration_ids' => $this->devices,
'data' => array("message" => $message),
);
'data' => ["message" => $message],
];
}
$headers = array(
$headers = [
'Authorization: key=' . $this->serverApiKey,
'Content-Type: application/json'
);
];
// Open connection
$ch = curl_init();

View File

@@ -117,7 +117,7 @@ class ProcessMap
$tmpData[5] = "";
$tmpData[6] = $lanes['lan_name'];
$tmpData[7] = "";
$tmpData[8] = $lanes['lan_uid'];
$tmpData[8] = array_key_exists('lan_uid', $lanes) ? $lanes['lan_uid']: "";
$tmpData[9] = "";
$tmpData[10] = $lanes['bou_container'];
@@ -719,7 +719,7 @@ class ProcessMap
if($element['bou_container'] != "bpmnDiagram"){
$resRec = $this->getNewPoints($element['bou_element'],$element['bou_container']);
}
if($element['lns_uid'] == $idElement || $element['lan_uid'] == $idElement){
if ($element['lns_uid'] == $idElement || (array_key_exists('lan_uid', $element) ? $element['lan_uid'] == $idElement : false)) {
$result = array($element['bou_x'] + $resRec[0],$element['bou_y'] + $resRec[1]);
}
}

View File

@@ -4,6 +4,7 @@ namespace ProcessMaker\BusinessModel;
use AdditionalTables;
use AdditionalTablesPeer;
use Configurations;
use G;
use Exception;
@@ -328,6 +329,11 @@ class ReportTable
*
* @param array $arrayData
* @param bool $flagAlterTable
*
* @see pmTablesProxy->save()
* @see ProcessMaker\BusinessModel\ReportTable->createStructureOfTables()
* @see Table->validateTableBeforeUpdate()
* @link https://wiki.processmaker.com/3.1/Report_Tables
*
* @return object
*/
@@ -560,6 +566,7 @@ class ReportTable
//Delete Report Table
$resultDeleteReportTable = $pmTablesProxy->delete($obj);
}
$this->updateConfigurationCaseList($additionalTableUid, $columns);
} catch (Exception $e) {
$buildResult = ob_get_contents();
@@ -578,11 +585,126 @@ class ReportTable
$result->trace = $e->getTraceAsString();
}
//Return
return $result;
}
/**
* Update the Custom Case List fields configuration.
*
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function updateConfigurationCaseList($addTabUid, $columns)
{
$actions = [
"todo", "draft", "sent", "unassigned", "paused", "completed", "cancelled"
];
$conf = new Configurations();
foreach ($actions as $action) {
$confCasesList = $conf->loadObject("casesList", $action, "", "", "");
$sw = is_array($confCasesList) && !empty($confCasesList) && !empty($confCasesList['PMTable']) && $confCasesList['PMTable'] === $addTabUid;
if ($sw) {
$this->addFieldsToCustomCaseList($confCasesList['first']['data'], $confCasesList['second']['data'], $columns);
$this->removeFieldsFromCustomCaseList($confCasesList['first']['data'], $columns);
$this->removeFieldsFromCustomCaseList($confCasesList['second']['data'], $columns);
$conf->saveObject($confCasesList, "casesList", $action);
}
}
}
/**
* Add fields to Custom Case List.
* @param array $data1
* @param array $data2
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function addFieldsToCustomCaseList(&$data1, $data2, $columns)
{
$all = [];
$type = 'PM Table';
$this->loadFieldTypeValues($data1, $all, $type);
$this->loadFieldTypeValues($data2, $all, $type);
foreach ($all as $value) {
foreach ($columns as $index => $column) {
if ($value['name'] === $column->field_name) {
unset($columns[$index]);
break;
}
}
}
$defaults = ["APP_UID", "APP_NUMBER", "APP_STATUS"];
foreach ($defaults as $value) {
foreach ($columns as $index => $column) {
if ($value === $column->field_name) {
unset($columns[$index]);
break;
}
}
}
foreach ($columns as $value) {
$data1[] = [
"name" => $column->field_name,
"fieldType" => $type
];
}
}
/**
* Load field type values.
*
* @param array $fields
* @param array $all
* @param string $type
*/
private function loadFieldTypeValues($fields, array &$all, $type)
{
foreach ($fields as $value) {
if ($value['fieldType'] === $type) {
$all[] = $value;
}
}
}
/**
* Remove fields from Custom Cases List.
*
* @param array $data
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function removeFieldsFromCustomCaseList(&$data, $columns)
{
$n = count($data);
for ($key = 0; $key < $n; $key++) {
if ($data[$key]['fieldType'] === 'PM Table') {
$remove = true;
foreach ($columns as $column) {
if ($data[$key]['name'] === $column->field_name) {
$remove = false;
break;
}
}
if ($remove === true) {
unset($data[$key]);
$data = array_values($data);
$key = 0;
$n = count($data);
}
}
}
}
/**
* Create the structure of tables
*

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -21,6 +21,7 @@ use IsoCountryPeer;
use IsoLocationPeer;
use IsoSubdivisionPeer;
use ListParticipatedLast;
use OauthClients;
use PMmemcached;
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
use ProcessMaker\Plugins\PluginRegistry;
@@ -1023,6 +1024,9 @@ class User
//Update in workflow
$result = $user->update($arrayData);
if (isset($arrayData['USR_STATUS'])) {
$arrayData['USR_STATUS'] == 'INACTIVE' ? RBAC::destroySessionUser($userUid) : null;
}
//Save Calendar assigment
if (isset($arrayData["USR_CALENDAR"])) {
@@ -1330,6 +1334,9 @@ class User
$criteria->add(DashletInstancePeer::DAS_INS_OWNER_UID, $UID);
$criteria->add(DashletInstancePeer::DAS_INS_OWNER_TYPE, 'USER');
DashletInstancePeer::doDelete($criteria);
//Destroy session after delete user
RBAC::destroySessionUser($usrUid);
(new OauthClients())->removeByUser($usrUid);
}
} catch (Exception $e) {
throw $e;
@@ -1998,4 +2005,111 @@ class User
return $isSupervisor;
}
}
/**
* It changes the password of the user specified by its identifier, optionally
* the value of $userLang can be sent, otherwise the system value is taken.
* In case of success, the updated user returns.
*
* @global object $RBAC
* @param string $usrUid
* @param string $usrPassword
* @param string $userLang
*
* @return string
*
* @see workflow/engine/methods/login/authentication.php
* @see workflow/engine/methods/login/changePassword.php
* @link https://wiki.processmaker.com/3.0/Managing_Users#Creating_New_Users
*/
public function changePassword($usrUid, $usrPassword, $userLang = "")
{
global $RBAC;
$users = new Users();
$user = $users->load($usrUid);
$data = [];
$data['USR_UID'] = $user['USR_UID'];
$data['USR_USERNAME'] = $user['USR_USERNAME'];
$data['USR_PASSWORD'] = Bootstrap::hashPassword($usrPassword);
$data['USR_FIRSTNAME'] = $user['USR_FIRSTNAME'];
$data['USR_LASTNAME'] = $user['USR_LASTNAME'];
$data['USR_EMAIL'] = $user['USR_EMAIL'];
$data['USR_DUE_DATE'] = $user['USR_DUE_DATE'];
$data['USR_UPDATE_DATE'] = date('Y-m-d H:i:s');
$RBAC->updateUser($data, $user['USR_ROLE']);
$data['USR_COUNTRY'] = $user['USR_COUNTRY'];
$data['USR_CITY'] = $user['USR_CITY'];
$data['USR_LOCATION'] = $user['USR_LOCATION'];
$data['USR_ADDRESS'] = $user['USR_ADDRESS'];
$data['USR_PHONE'] = $user['USR_PHONE'];
$data['USR_ZIP_CODE'] = $user['USR_ZIP_CODE'];
$data['USR_POSITION'] = $user['USR_POSITION'];
$users->update($data);
$usersProperties = new UsersProperties();
$userProperty = $usersProperties->load($usrUid);
$history = unserialize($userProperty['USR_PASSWORD_HISTORY']);
if (!is_array($history)) {
$history = [];
}
if (!defined('PPP_PASSWORD_HISTORY')) {
define('PPP_PASSWORD_HISTORY', 0);
}
if (PPP_PASSWORD_HISTORY > 0) {
if (count($history) >= PPP_PASSWORD_HISTORY) {
array_shift($history);
}
$history[] = $usrPassword;
}
$userProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s');
$userProperty['USR_LOGGED_NEXT_TIME'] = 0;
$userProperty['USR_PASSWORD_HISTORY'] = serialize($history);
$usersProperties->update($userProperty);
if (class_exists('redirectDetail')) {
if (isset($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'])) {
$userRole = $RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'];
}
$pluginRegistry = PluginRegistry::loadSingleton();
$redirectLogin = $pluginRegistry->getRedirectLogins();
if (isset($redirectLogin)) {
if (is_array($redirectLogin)) {
foreach ($redirectLogin as $detail) {
if (isset($detail->sPathMethod)) {
if ($detail->equalRoleCodeTo($userRole)) {
$user['__REDIRECT_PATH__'] = '/sys' . config('system.workspace') . '/' . SYS_LANG . '/' . SYS_SKIN . '/' . $detail->getPathMethod();
return $user;
}
}
}
}
}
}
$lang = "";
if ($userLang !== "") {
$lang = $userLang;
} else {
if (defined('SYS_LANG')) {
$lang = SYS_LANG;
} else {
$lang = 'en';
}
}
$location = $usersProperties->redirectTo($usrUid, $lang);
$user['__REDIRECT_PATH__'] = $location;
return $user;
}
}

View File

@@ -1534,7 +1534,8 @@ class System
*/
public static function getServerProtocol()
{
return G::is_https() ? "https://" : "http://";
$envProtocol = defined("REQUEST_SCHEME") && REQUEST_SCHEME === "https";
return G::is_https() || $envProtocol ? "https://" : "http://";
}
/**
@@ -1577,7 +1578,7 @@ class System
public static function getServerHost()
{
$port = self::getServerPort();
if (!empty($port) && $port != '80') {
if (!empty($port) && $port != '80' && $port != '443') {
return self::getServerHostname() . ':' . $port;
}
return self::getServerHostname();
@@ -1597,11 +1598,25 @@ class System
* Get server main path (protocol + host + port + workspace + lang + skin).
*
* @return string
* @see ProcessMaker\BusinessModel\ProjectUser->projectWsUserCanStartTask()
* @see ProcessMaker\BusinessModel\ProjectUser->userLogin()
* @see ProcessMaker\BusinessModel\WebEntry->getWebEntryDataFromRecord()
* @see ProcessMaker\BusinessModel\WebEntryEvent->getGeneratedLink()
* @see ProcessMaker\Core\System\ActionsByEmailCoreClass->sendActionsByEmail()
* @see ProcessMaker\Core\System\webEntryProxy->checkCredentials()
* @see ProcessMaker\Core\System\webEntryProxy->save()
* @see workflow/engine/classes/ProcessMap.php ProcessMap->listNewWebEntry()
* @see workflow/engine/classes/ProcessMap.php ProcessMap->webEntry()
* @see workflow/engine/controllers/caseSchedulerProxy.php caseSchedulerProxy->checkCredentials()
* @see workflow/engine/methods/cases/cases_SchedulerValidateUser.php
* @see workflow/engine/methods/processes/processes_webEntryGenerate.php
* @see workflow/engine/methods/processes/processes_webEntryValidate.php
* @see workflow/engine/methods/processes/webEntry_Val_Assig.php
*/
public static function getServerMainPath()
{
$conf = new Configurations();
$skin = defined("SYS_SKIN") ? SYS_SKIN : $conf->getConfiguration('SKIN_CRON', '');
$config = self::getSystemConfiguration();
$skin = defined("SYS_SKIN") ? SYS_SKIN : $config['default_skin'];
return self::getServerProtocolHost() . '/sys' . config("system.workspace") . '/' . SYS_LANG . '/' . $skin;
}

View File

@@ -0,0 +1,14 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class AppAssignSelfServiceValue extends Model
{
protected $table = 'APP_ASSIGN_SELF_SERVICE_VALUE';
protected $primaryKey = 'ID';
// We do not have create/update timestamps for this table
public $timestamps = false;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class AppAssignSelfServiceValueGroup extends Model
{
protected $table = 'APP_ASSIGN_SELF_SERVICE_VALUE_GROUP';
// We do not have create/update timestamps for this table
public $timestamps = false;
}

View File

@@ -0,0 +1,27 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class Application extends Model
{
protected $table = "APPLICATION";
// No timestamps
public $timestamps = false;
public function delegations()
{
return $this->hasMany(Delegation::class, 'APP_UID', 'APP_UID');
}
public function parent()
{
return $this->hasOne(Application::class, 'APP_PARENT', 'APP_UID');
}
public function currentUser()
{
return $this->hasOne(User::class, 'APP_CUR_USER', 'USR_UID');
}
}

View File

@@ -0,0 +1,333 @@
<?php
namespace ProcessMaker\Model;
use G;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Delegation extends Model
{
protected $table = "APP_DELEGATION";
// We don't have our standard timestamp columns
public $timestamps = false;
/**
* Returns the application this delegation belongs to
*/
public function application()
{
return $this->belongsTo(Application::class, 'APP_UID', 'APP_UID');
}
/**
* Returns the user this delegation belongs to
*/
public function user()
{
return $this->belongsTo(User::class, 'USR_ID', 'USR_ID');
}
/**
* Return the process task this belongs to
*/
public function task()
{
return $this->belongsTo(Task::class, 'TAS_ID', 'TAS_ID');
}
/**
* Return the process this delegation belongs to
*/
public function process()
{
return $this->belongsTo(Process::class, 'PRO_ID', 'PRO_ID');
}
/**
* Searches for delegations which match certain criteria
*
* The query is related to advanced search with different filters
* We can search by process, status of case, category of process, users, delegate date from and to
*
* @param integer $userId The USR_ID to search for (Note, this is no longer the USR_UID)
* @param integer $start for the pagination
* @param integer $limit for the pagination
* @param string $search
* @param integer $process the pro_id
* @param integer $status of the case
* @param string $dir if the order is DESC or ASC
* @param string $sort name of column by sort, can be:
* [APP_NUMBER, APP_TITLE, APP_PRO_TITLE, APP_TAS_TITLE, APP_CURRENT_USER, APP_UPDATE_DATE, DEL_DELEGATE_DATE, DEL_TASK_DUE_DATE, APP_STATUS_LABEL]
* @param string $category uid for the process
* @param date $dateFrom
* @param date $dateTo
* @param string $filterBy name of column for a specific search, can be: [APP_NUMBER, APP_TITLE, TAS_TITLE]
* @return array $result result of the query
*/
public static function search(
$userId = null,
// Default pagination values
$start = 0,
$limit = 25,
$search = null,
$process = null,
$status = null,
$dir = null,
$sort = null,
$category = null,
$dateFrom = null,
$dateTo = null,
$filterBy = 'APP_TITLE'
) {
$search = trim($search);
// Start the query builder, selecting our base attributes
$selectColumns = [
'APPLICATION.APP_NUMBER',
'APPLICATION.APP_UID',
'APPLICATION.APP_STATUS',
'APPLICATION.APP_STATUS AS APP_STATUS_LABEL',
'APPLICATION.PRO_UID',
'APPLICATION.APP_CREATE_DATE',
'APPLICATION.APP_FINISH_DATE',
'APPLICATION.APP_UPDATE_DATE',
'APPLICATION.APP_TITLE',
'APP_DELEGATION.USR_UID',
'APP_DELEGATION.TAS_UID',
'APP_DELEGATION.USR_ID',
'APP_DELEGATION.PRO_ID',
'APP_DELEGATION.DEL_INDEX',
'APP_DELEGATION.DEL_LAST_INDEX',
'APP_DELEGATION.DEL_DELEGATE_DATE',
'APP_DELEGATION.DEL_INIT_DATE',
'APP_DELEGATION.DEL_FINISH_DATE',
'APP_DELEGATION.DEL_TASK_DUE_DATE',
'APP_DELEGATION.DEL_RISK_DATE',
'APP_DELEGATION.DEL_THREAD_STATUS',
'APP_DELEGATION.DEL_PRIORITY',
'APP_DELEGATION.DEL_DURATION',
'APP_DELEGATION.DEL_QUEUE_DURATION',
'APP_DELEGATION.DEL_STARTED',
'APP_DELEGATION.DEL_DELAY_DURATION',
'APP_DELEGATION.DEL_FINISHED',
'APP_DELEGATION.DEL_DELAYED',
'APP_DELEGATION.DEL_DELAY_DURATION',
'TASK.TAS_TITLE AS APP_TAS_TITLE',
'TASK.TAS_TYPE AS APP_TAS_TYPE',
];
$query = DB::table('APP_DELEGATION')->select(DB::raw(implode(',', $selectColumns)));
// Add join for task, filtering for task title if needed
// It doesn't make sense for us to search for any delegations that match tasks that are events or web entry
$query->join('TASK', function ($join) use ($filterBy, $search) {
$join->on('APP_DELEGATION.TAS_ID', '=', 'TASK.TAS_ID')
->whereNotIn('TASK.TAS_TYPE', [
'WEBENTRYEVENT',
'END-MESSAGE-EVENT',
'START-MESSAGE-EVENT',
'INTERMEDIATE-THROW',
]);
if ($filterBy == 'TAS_TITLE' && $search) {
$join->where('TASK.TAS_TITLE', 'LIKE', "%${search}%");
}
});
// Add join for application, taking care of status and filtering if necessary
$query->join('APPLICATION', function ($join) use ($filterBy, $search, $status, $query) {
$join->on('APP_DELEGATION.APP_NUMBER', '=', 'APPLICATION.APP_NUMBER');
if ($filterBy == 'APP_TITLE' && $search) {
$join->where('APPLICATION.APP_TITLE', 'LIKE', "%${search}%");
}
// Based on the below, we can further limit the join so that we have a smaller data set based on join criteria
switch ($status) {
case 1: //DRAFT
$join->where('APPLICATION.APP_STATUS_ID', 1);
break;
case 2: //TO_DO
$join->where('APPLICATION.APP_STATUS_ID', 2);
break;
case 3: //COMPLETED
$join->where('APPLICATION.APP_STATUS_ID', 3);
break;
case 4: //CANCELLED
$join->where('APPLICATION.APP_STATUS_ID', 4);
break;
case "PAUSED":
$join->where('APPLICATION.APP_STATUS', 'TO_DO');
break;
default: //All status
// Don't do anything here, we'll need to do the more advanced where below
}
});
// Add join for process, but only for certain scenarios such as category or process
if (($category && !$process) || $sort == 'APP_PRO_TITLE') {
$query->join('PROCESS', function ($join) use ($category) {
$join->on('APP_DELEGATION.PRO_ID', '=', 'PROCESS.PRO_ID');
if ($category) {
$join->where('PROCESS.PRO_CATEGORY', $category);
}
});
}
// Add join for user, but only for certain scenarios as sorting
if ($sort == 'APP_CURRENT_USER') {
$query->join('USERS', function ($join) use ($userId) {
$join->on('APP_DELEGATION.USR_ID', '=', 'USERS.USR_ID');
});
}
// Search for specified user
if ($userId) {
$query->where('APP_DELEGATION.USR_ID', $userId);
}
// Search for specified process
if ($process) {
$query->where('APP_DELEGATION.PRO_ID', $process);
}
// Search for an app/case number
if ($filterBy == 'APP_NUMBER' && $search) {
$query->where('APP_DELEGATION.APP_NUMBER', 'LIKE', "%${search}%");
}
// Date range filter
if (!empty($dateFrom)) {
$query->where('APP_DELEGATION.DEL_DELEGATE_DATE', '>=', $dateFrom);
}
if (!empty($dateTo)) {
$dateTo = $dateTo . " 23:59:59";
// This is inclusive
$query->where('APP_DELEGATION.DEL_DELEGATE_DATE', '<=', $dateTo);
}
// Status Filter
// This is tricky, the below behavior is combined with the application join behavior above
switch ($status) {
case 1: //DRAFT
$query->where('APP_DELEGATION.DEL_THREAD_STATUS', 'OPEN');
break;
case 2: //TO_DO
$query->where('APP_DELEGATION.DEL_THREAD_STATUS', 'OPEN');
break;
case 3: //COMPLETED
$query->where('APP_DELEGATION.DEL_LAST_INDEX', 1);
break;
case 4: //CANCELLED
$query->where('APP_DELEGATION.DEL_LAST_INDEX', 1);
break;
case "PAUSED":
// Do nothing, as the app status check for TO_DO is performed in the join above
break;
default: //All statuses.
$query->where(function ($query) {
// Check to see if thread status is open
$query->where('APP_DELEGATION.DEL_THREAD_STATUS', 'OPEN')
->orWhere(function ($query) {
// Or, we make sure if the thread is closed, and it's the last delegation, and if the app is completed or cancelled
$query->where('APP_DELEGATION.DEL_THREAD_STATUS', 'CLOSED')
->where('APP_DELEGATION.DEL_LAST_INDEX', 1)
->whereIn('APPLICATION.APP_STATUS_ID', [3, 4]);
});
});
break;
}
// Add any sort if needed
if($sort) {
switch ($sort) {
case 'APP_NUMBER':
$query->orderBy('APP_DELEGATION.APP_NUMBER', $dir);
break;
case 'APP_PRO_TITLE':
// We can do this because we joined the process table if sorting by it
$query->orderBy('PROCESS.PRO_TITLE', $dir);
break;
case 'APP_TAS_TITLE':
$query->orderBy('TASK.TAS_TITLE', $dir);
break;
case 'APP_CURRENT_USER':
// We can do this because we joined the user table if sorting by it
$query->orderBy('USERS.USR_LASTNAME', $dir);
$query->orderBy('USERS.USR_FIRSTNAME', $dir);
break;
default:
$query->orderBy($sort, $dir);
}
}
// Add pagination to the query
$query = $query->offset($start)
->limit($limit);
// Fetch results and transform to a laravel collection
$results = $query->get();
// Transform with additional data
$priorities = ['1' => 'VL', '2' => 'L', '3' => 'N', '4' => 'H', '5' => 'VH'];
$results->transform(function ($item, $key) use ($priorities) {
// Convert to an array as our results must be an array
$item = json_decode(json_encode($item), true);
// If it's assigned, fetch the user
if($item['USR_ID']) {
$user = User::where('USR_ID', $item['USR_ID'])->first();
} else {
$user = null;
}
$process = Process::where('PRO_ID', $item['PRO_ID'])->first();
// Rewrite priority string
if ($item['DEL_PRIORITY']) {
$item['DEL_PRIORITY'] = G::LoadTranslation("ID_PRIORITY_{$priorities[$item['DEL_PRIORITY']]}");
}
// Merge in desired application data
if ($item['APP_STATUS']) {
$item['APP_STATUS_LABEL'] = G::LoadTranslation("ID_${item['APP_STATUS']}");
} else {
$item['APP_STATUS_LABEL'] = $item['APP_STATUS'];
}
// Merge in desired process data
// Handle situation where the process might not be in the system anymore
$item['APP_PRO_TITLE'] = $process ? $process->PRO_TITLE : '';
// Merge in desired user data
$item['USR_LASTNAME'] = $user ? $user->USR_LASTNAME : '';
$item['USR_FIRSTNAME'] = $user ? $user->USR_FIRSTNAME : '';
$item['USR_USERNAME'] = $user ? $user->USR_USERNAME : '';
//@todo: this section needs to use 'User Name Display Format', currently in the extJs is defined this
$item["APP_CURRENT_USER"] = $item["USR_LASTNAME"] . ' ' . $item["USR_FIRSTNAME"];
$item["APPDELCR_APP_TAS_TITLE"] = '';
$item["USRCR_USR_UID"] = $item["USR_UID"];
$item["USRCR_USR_FIRSTNAME"] = $item["USR_FIRSTNAME"];
$item["USRCR_USR_LASTNAME"] = $item["USR_LASTNAME"];
$item["USRCR_USR_USERNAME"] = $item["USR_USERNAME"];
$item["APP_OVERDUE_PERCENTAGE"] = '';
return $item;
});
// Remove any empty erroenous data
$results = $results->filter();
// Bundle into response array
$response = [
// Fake totalCount to show pagination
'totalCount' => $start + $limit + 1,
'sql' => $query->toSql(),
'bindings' => $query->getBindings(),
'data' => $results->values()->toArray(),
];
return $response;
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
/**
* Class Dynaform
* @package ProcessMaker\Model
*
* Represents a dynaform object in the system.
*/
class Dynaform extends Model
{
protected $table = 'DYNAFORM';
public $timestamps = false;
public function process()
{
return $this->belongsTo(Process::class, 'PRO_UID', 'PRO_UID');
}
/**
* Get dynaforms by PRO_UID.
* @param string $proUid
* @return object
*/
public static function getByProUid($proUid)
{
return DB::table('DYNAFORM')
->select()
->where('DYNAFORM.PRO_UID', '=', $proUid)
->get();
}
/**
* Get dynaform by DYN_UID.
* @param string $dynUid
* @return object
*/
public static function getByDynUid($dynUid)
{
return DB::table('DYNAFORM')
->select()
->where('DYNAFORM.DYN_UID', '=', $dynUid)
->first();
}
/**
* Get dynaforms by PRO_UID except the DYN_UID specified in the second parameter.
* @param string $proUid
* @param string $dynUid
* @return object
*/
public static function getByProUidExceptDynUid($proUid, $dynUid)
{
return DB::table('DYNAFORM')
->select()
->where('DYNAFORM.PRO_UID', '=', $proUid)
->where('DYNAFORM.DYN_UID', '!=', $dynUid)
->get();
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class GroupUser extends Model
{
protected $table = 'GROUP_USER';
// We do not have create/update timestamps for this table
public $timestamps = false;
}

View File

@@ -0,0 +1,14 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class Groupwf extends Model
{
protected $table = 'GROUPWF';
protected $primaryKey = 'GRP_ID';
// We do not have create/update timestamps for this table
public $timestamps = false;
}

View File

@@ -0,0 +1,70 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
use ListUnassigned as PropelListUnassigned;
class ListUnassigned extends Model
{
protected $table = "LIST_UNASSIGNED";
// No timestamps
public $timestamps = false;
/**
* Returns the application this belongs to
*/
public function application()
{
return $this->belongsTo(Application::class, 'APP_UID', 'APP_UID');
}
/**
* Return the process task this belongs to
*/
public function task()
{
return $this->belongsTo(Task::class, 'TAS_ID', 'TAS_ID');
}
/**
* Return the process this belongs to
*/
public function process()
{
return $this->belongsTo(Process::class, 'PRO_ID', 'PRO_ID');
}
/**
* Get count
*
* @param string $userUid
* @param array $filters
*
* @return array
*/
public static function doCount($userUid, $filters = [])
{
$list = new PropelListUnassigned();
$result = $list->getCountList($userUid, $filters);
return $result;
}
/**
* Search data
*
* @param string $userUid
* @param array $filters
*
* @return array
*/
public static function loadList($userUid, $filters = [])
{
$list = new PropelListUnassigned();
$result = $list->loadList($userUid, $filters);
return $result;
}
}

View File

@@ -14,8 +14,29 @@ class Process extends Model
{
// Set our table name
protected $table = 'PROCESS';
// We do have a created at, but we don't store an updated at
// Our custom timestamp columns
const CREATED_AT = 'PRO_CREATE_DATE';
const UPDATED_AT = null;
const UPDATED_AT = 'PRO_UPDATE_DATE';
/**
* Retrieve all applications that belong to this process
*/
public function applications()
{
return $this->hasMany(Application::class, 'PRO_ID', 'PRO_ID');
}
}
public function tasks()
{
return $this->hasMany(Task::class, 'PRO_UID', 'PRO_UID');
}
public function creator()
{
return $this->hasOne(User::class, 'PRO_CREATE_USER', 'USR_UID');
}
public function category()
{
return $this->hasOne(ProcessCategory::class, 'PRO_CATEGORY', 'CATEGORY_UID');
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
/**
* Class ProcessCategory
* @package ProcessMaker\Model
*
* Represents a process category object in the system.
*/
class ProcessCategory extends Model
{
// Set our table name
protected $table = 'PROCESS_CATEGORY';
public $timestamps = false;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
/**
* Class Process
* @package ProcessMaker\Model
*
* Represents a business process object in the system.
*/
class Route extends Model
{
// Set our table name
protected $table = 'ROUTE';
public $timestamps = false;
}

View File

@@ -0,0 +1,23 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $table = 'TASK';
protected $primaryKey = 'TAS_ID';
// We do not have create/update timestamps for this table
public $timestamps = false;
public function process()
{
return $this->belongsTo(Process::class, 'PRO_UID', 'PRO_UID');
}
public function delegations()
{
return $this->hasMany(Delegation::class, 'TAS_ID', 'TAS_ID');
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class TaskUser extends Model
{
protected $table = 'TASK_USER';
public $timestamps = false;
}

View File

@@ -0,0 +1,21 @@
<?php
namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = "USERS";
// Our custom timestamp columns
const CREATED_AT = 'USR_CREATE_DATE';
const UPDATED_AT = 'USR_UPDATE_DATE';
/**
* Returns the delegations this user has (all of them)
*/
public function delegations()
{
return $this->hasMany(Delegation::class, 'USR_ID', 'USR_ID');
}
}

View File

@@ -1427,4 +1427,31 @@ class Cases extends Api
return $response;
}
/**
* Return information for sub process cases
*
* @url GET /:app_uid/sub-process-cases
*
* @param string $app_uid {@min 32}{@max 32}
*
* @return array
* @throws Exception
*
* @access protected
* @class AccessControl {@permission PM_CASES}
*/
public function doGetCaseSubProcess($app_uid)
{
try {
$case = new BmCases();
$case->setFormatFieldNameInUppercase(false);
$caseInfo = $case->getCaseInfoSubProcess($app_uid, $this->getUserId());
$caseInfo = DateTime::convertUtcToIso8601($caseInfo, $this->arrayFieldIso8601);
return $caseInfo;
} catch (Exception $e) {
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
}
}

View File

@@ -1038,6 +1038,7 @@ class Light extends Api
}
$userUid = $this->getUserId();
//@todo Find a better way to define session variables
$_SESSION["APPLICATION"] = $app_uid;
$_SESSION["PROCESS"] = $pro_uid;
//$_SESSION["TASK"] = "";
@@ -2009,6 +2010,7 @@ class Light extends Api
if ($alreadyRouted) {
throw (new RestException(Api::STAT_APP_EXCEPTION, G::LoadTranslation('ID_CASE_DELEGATION_ALREADY_CLOSED')));
}
//@todo Find a better way to define session variables
$_SESSION["APPLICATION"] = $app_uid;
$_SESSION["PROCESS"] = $pro_uid;
$_SESSION["INDEX"] = $app_index;

View File

@@ -7,6 +7,7 @@ class DateTime
const REGEXPDATE = '[1-9]\d{3}\-(?:0[1-9]|1[0-2])\-(?:0[1-9]|[12][0-9]|3[01])';
const REGEXPTIME = '(?:[0-1]\d|2[0-3])\:[0-5]\d\:[0-5]\d';
const REGEX_IS_DATE = '/^([1-9]\d{3})\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])(?:\s([0-1]\d|2[0-3])\:([0-5]\d)\:([0-5]\d))?$/';
/**
* Get Time Zone Offset by Time Zone ID

View File

@@ -2,17 +2,18 @@
namespace ProcessMaker\Util;
use Configurations;
use Criteria;
use ResultSet;
use FieldsPeer;
use ReportTablePeer;
use CaseConsolidatedCorePeer;
use ConsolidatedCases;
use AdditionalTablesPeer;
use PmTable;
use ReportVarPeer;
use AdditionalTables;
use AdditionalTablesPeer;
use CaseConsolidatedCorePeer;
use Configurations;
use ConsolidatedCases;
use Criteria;
use FieldsPeer;
use PmTable;
use ProcessMaker\Core\System;
use ReportTablePeer;
use ReportVarPeer;
use ResultSet;
use stdClass;
/**
@@ -73,6 +74,7 @@ class FixReferencePath
* @param string $directory
* @param string $pathData
* @return void
* @see workflow/engine/classes/WorkspaceTools.php WorkspaceTools->fixReferencePathFiles()
*/
public function runProcess($directory, $pathData)
{
@@ -81,8 +83,8 @@ class FixReferencePath
//task, it is removed at the end of the method.
$_SERVER["REQUEST_URI"] = "";
if (!defined("SYS_SKIN")) {
$conf = new Configurations();
define("SYS_SKIN", $conf->getConfiguration('SKIN_CRON', ''));
$config = System::getSystemConfiguration();
define("SYS_SKIN", $config['default_skin']);
}
$criteria = new Criteria("workflow");

View File

@@ -0,0 +1,82 @@
<?php
namespace ProcessMaker\Util;
class PhpShorthandByte
{
private $units;
private $terminal;
/**
* Constructor.
* Supported format php directives:
* [number]G
* [number]K
* [number]M
*/
function __construct()
{
$this->units = ['K', 'M', 'G'];
$this->terminal = "bytes";
}
/**
* Convert value string to bytes, for directives php.ini
*
* @param string $value
* @return integer
*
* @see ProcessMaker\BusinessModel\InputDocument->getMaxFileSize()
* @link http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
*/
public function valueToBytes($value)
{
foreach ($this->units as $i => $unit) {
$number = $this->getNumberValue($value, $unit);
if ($number !== null) {
$result = $number * (1024 ** ($i + 1));
return $result;
}
}
return intval($value);
}
/**
* Get number value and validate expresion.
* Valid expresion is: [number][unit]
*
* @param string $string
* @param string $unit
* @return integer|null
*
* @see ProcessMaker\Util\PhpShorthandByte->valueToBytes()
* @link http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
*/
public function getNumberValue($string, $unit)
{
$string = preg_replace('/\s+/', '', $string);
$isCorrect = preg_match("/\d+{$unit}/", $string);
if ($isCorrect === 1) {
$result = rtrim($string, $unit);
return intval($result);
}
return null;
}
/**
* Get format bytes.
*
* @param string $value
* @return string
*/
public function getFormatBytes($value)
{
foreach ($this->units as $i => $unit) {
$number = $this->getNumberValue($value, $unit);
if ($number !== null) {
return $number . " " . $unit . $this->terminal;
}
}
return $value;
}
}

View File

@@ -400,6 +400,81 @@ function verifyCsrfToken($request)
}
}
/**
* Get the difference between to arrays
* If the element is an array we will to keep the value from $array1
* If the element is an object we will to keep the value from $array1
*
* @param array $array1
* @param array $array2
*
* @return array
*/
function getDiffBetweenModifiedVariables(array $array1, array $array2)
{
$difference = [];
foreach ($array1 as $key => $value) {
if (is_array($value)) {
if ($value !== $array2[$key]) {
$difference[$key] = $value;
}
} elseif (is_object($value)) {
// When using ===, it means object variables are identical and they refer to the same instance of the same class.
if ($value != $array2[$key]) {
$difference[$key] = $value;
}
} elseif (!isset($array2[$key]) || $array2[$key] != $value) {
$difference[$key] = $value;
}
}
return $difference;
}
/**
* Replace all supported variables prefixes to the prefix sent
*
* @param string $outDocFilename
* @param string $prefix
*
* @return string
*
* @see cases_Step.php
* @see \ProcessMaker\BusinessModel\Cases\OutputDocument::addCasesOutputDocument()
* @link https://wiki.processmaker.com/3.2/Triggers#Typing_rules_for_Case_Variables
*/
function replacePrefixes($outDocFilename, $prefix = '@=')
{
$outDocFile = str_replace(['@@', '@#', '@=', '@%', '@?', '@$', '@&', '@Q', '@q', '@!'], $prefix, $outDocFilename);
return $outDocFile;
}
/**
* Encoding header filename used in Content-Disposition
*
* @param string $fileName
* @param string $replacement
*
* @return string
*
* @see cases_Step.php
* @see \ProcessMaker\BusinessModel\Cases\OutputDocument::addCasesOutputDocument()
*/
function fixContentDispositionFilename($fileName, $replacement = '_')
{
//(double quote) has to be removed
//(forward slash) has to replaced by underscore
//(backslash) has to replaced by underscore
$default = [
'/[\"]/' => '',
'/[\\|\/]/' => $replacement,
'/\\\\/' => $replacement
];
return preg_replace(array_keys($default), array_values($default), $fileName);
}
/**
* Get the current user CSRF token.
*
@@ -410,6 +485,33 @@ function csrfToken()
return isset($_SESSION['USR_CSRF_TOKEN']) ? $_SESSION['USR_CSRF_TOKEN'] : '';
}
/**
* Check if a string is a valid HTML code
*
* @param string $string
*
* @return bool
*
* @see G::replaceDataField()
*/
function stringIsValidHtml($string)
{
// To validate we use the DOMDocument class
$doc = new DOMDocument('1.0', 'UTF-8');
// Clean previous errors
libxml_clear_errors();
// This line have to be silenced because if the string is not an HTML a Warning is displayed
@$doc->loadHTML($string);
// Get last error parsing the HTML
$libXmlError = libxml_get_last_error();
// If the attribute "textContent" is empty or exists libxml errors, is not a valid HTML
return $doc->textContent !== '' && empty($libXmlError);
}
// Methods deleted in PHP 7.x, added in this file in order to keep compatibility with old libraries included/used in ProcessMaker
if (!function_exists('set_magic_quotes_runtime')) {
function set_magic_quotes_runtime($value) {

View File

@@ -8,6 +8,7 @@ use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Cache;
use ProcessMaker\Core\System;
use ProcessMaker\Services\OAuth2\Server;
use ProcessMaker\Util\PhpShorthandByte;
use Symfony\Component\HttpFoundation\File\File;
class ValidationUploadedFiles
@@ -169,6 +170,8 @@ class ValidationUploadedFiles
* File upload validation.
*
* @return $this
*
* @see workflow/public_html/sysGeneric.php
*/
public function runRulesToAllUploadedFiles()
{
@@ -177,6 +180,12 @@ class ValidationUploadedFiles
return;
}
$this->fails = [];
$validator = $this->runRulesForFileEmpty();
if ($validator->fails()) {
$this->fails[] = $validator;
}
foreach ($files as $file) {
$data = (object) $file;
if (!is_array($data->name) || !is_array($data->tmp_name)) {
@@ -207,16 +216,77 @@ class ValidationUploadedFiles
}
}
}
return $this;
}
/**
* Run rules if files is empty.
*
* @see ProcessMaker\Validation\ValidationUploadedFiles->runRulesToAllUploadedFiles()
* @see Luracast\Restler\Format\UploadFormat->decode()
*/
public function runRulesForFileEmpty()
{
$validator = new Validator();
//rule: validate $_SERVER['CONTENT_LENGTH']
$rule = $validator->addRule();
$rule->validate(null, function($file) use ($rule) {
//according to the acceptance criteria the information is always shown in MBytes
$phpShorthandByte = new PhpShorthandByte();
$postMaxSize = ini_get("post_max_size");
$postMaxSizeBytes = $phpShorthandByte->valueToBytes($postMaxSize);
$uploadMaxFileSize = ini_get("upload_max_filesize");
$uploadMaxFileSizeBytes = $phpShorthandByte->valueToBytes($uploadMaxFileSize);
if ($postMaxSizeBytes < $uploadMaxFileSizeBytes) {
$uploadMaxFileSize = $postMaxSize;
$uploadMaxFileSizeBytes = $postMaxSizeBytes;
}
//according to the acceptance criteria the information is always shown in MBytes
$uploadMaxFileSizeMBytes = $uploadMaxFileSizeBytes / (1024 ** 2); //conversion constant
$message = G::LoadTranslation('ID_THE_FILE_SIZE_IS_BIGGER_THAN_THE_MAXIMUM_ALLOWED', [$uploadMaxFileSizeMBytes]);
$rule->message($message);
/**
* If you can, you may want to set post_max_size to a low value (say 1M) to make
* testing easier. First test to see how your script behaves. Try uploading a file
* that is larger than post_max_size. If you do you will get a message like this
* in your error log:
*
* [09-Jun-2010 19:28:01] PHP Warning: POST Content-Length of 30980857 bytes exceeds
* the limit of 2097152 bytes in Unknown on line 0
*
* This makes the script is not completed.
*
* Solving the problem:
* The PHP documentation http://php.net/manual/en/ini.core.php#ini.post-max-size
* provides a hack to solve this problem:
*
* If the size of post data is greater than post_max_size, the $_POST and $_FILES
* superglobals are empty.
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($_POST) && empty($_FILES) && $_SERVER['CONTENT_LENGTH'] > 0) {
return true;
}
return false;
})
->status(400)
->log(function($rule) {
Bootstrap::registerMonologPhpUploadExecution('phpUpload', 400, $rule->getMessage(), "");
});
return $validator->validate();
}
/**
* Get the first error and call the argument function.
*
* @param function $callback
* @return $this
*/
public function dispach($callback)
public function dispatch($callback)
{
if (!empty($this->fails[0])) {
if (!empty($callback) && is_callable($callback)) {