- $msg
+ " . $this->getSessionMessageForSupervisor() . "
@@ -1323,6 +1294,7 @@ class PmDynaform
$this->getTheStringVariableForGoogleMaps() . "\n" .
"\n" .
"\n" .
+ $this->getSessionMessage() .
"
\n" .
"
\n" .
" \n" .
@@ -2238,4 +2210,53 @@ class PmDynaform
$result = 'var googleMaps = ' . G::json_encode($googleMaps) . ';';
return $result;
}
+
+ /**
+ * Get session message.
+ *
+ * @return string
+ *
+ * @see PmDynaform->printEdit()
+ * @see PmDynaform->printABE()
+ * @link https://wiki.processmaker.com/3.1/Multiple_File_Uploader#File_Extensions
+ */
+ public function getSessionMessage()
+ {
+ $message = "";
+ if (isset($_SESSION['G_MESSAGE_TYPE']) && isset($_SESSION['G_MESSAGE'])) {
+ $color = "green";
+ if ($_SESSION['G_MESSAGE_TYPE'] === "ERROR") {
+ $color = "red";
+ }
+ if ($_SESSION['G_MESSAGE_TYPE'] === "WARNING") {
+ $color = "#C3C380";
+ }
+ if ($_SESSION['G_MESSAGE_TYPE'] === "INFO") {
+ $color = "green";
+ }
+ $message = "
" . $_SESSION['G_MESSAGE_TYPE'] . ": " . $_SESSION['G_MESSAGE'] . "
";
+ unset($_SESSION['G_MESSAGE_TYPE']);
+ unset($_SESSION['G_MESSAGE']);
+ }
+ return $message;
+ }
+
+ /**
+ * Get session message for supervisor.
+ *
+ * @return string
+ *
+ * @see PmDynaform->printEditSupervisor();
+ * @link https://wiki.processmaker.com/3.1/Multiple_File_Uploader#File_Extensions
+ */
+ public function getSessionMessageForSupervisor()
+ {
+ $message = "";
+ if (isset($_SESSION["G_MESSAGE_TYPE"]) && isset($_SESSION["G_MESSAGE"])) {
+ $message = "
" . G::LoadTranslation("ID_INFO") . ": " . $_SESSION["G_MESSAGE"] . "
";
+ unset($_SESSION["G_MESSAGE_TYPE"]);
+ unset($_SESSION["G_MESSAGE"]);
+ }
+ return $message;
+ }
}
diff --git a/workflow/engine/classes/PmTable.php b/workflow/engine/classes/PmTable.php
index b6e7eb075..11a1e7490 100644
--- a/workflow/engine/classes/PmTable.php
+++ b/workflow/engine/classes/PmTable.php
@@ -1006,4 +1006,24 @@ class PmTable
}
return $oCriteria;
}
+
+ /**
+ * Get the type of the column ex: string, int, double, boolean
+ *
+ * @param string $pmTablePeer
+ * @param string $tableName
+ * @param string $columnName
+ *
+ * @return string
+ */
+ public static function getTypeOfColumn($pmTablePeer, $tableName, $columnName)
+ {
+ try {
+ $type = $pmTablePeer::getMapBuilder()->getDatabaseMap()->getTable($tableName)->getColumn($columnName)->getCreoleType();
+ } catch (Exception $e) {
+ return '';
+ }
+
+ return $type;
+ }
}
diff --git a/workflow/engine/methods/cases/cases_SaveData.php b/workflow/engine/methods/cases/cases_SaveData.php
index a218bd604..fe69df0c2 100644
--- a/workflow/engine/methods/cases/cases_SaveData.php
+++ b/workflow/engine/methods/cases/cases_SaveData.php
@@ -50,12 +50,18 @@ if (!isset($_SESSION['USER_LOGGED'])) {
}
}
-ValidationUploadedFiles::getValidationUploadedFiles()->dispatch(function($validator) {
+/**
+ * To do: The following evaluation must be moved after saving the data (so as not to lose the data entered in the form).
+ * It only remains because it is an old behavior, which must be defined by "Product Owner".
+ * @see workflow/engine/methods/services/ActionsByEmailDataFormPost.php
+ */
+$validator = ValidationUploadedFiles::getValidationUploadedFiles()->runRulesForFileEmpty();
+if ($validator->fails()) {
G::SendMessageText($validator->getMessage(), "ERROR");
$url = explode("sys" . config("system.workspace"), $_SERVER['HTTP_REFERER']);
G::header("location: " . "/sys" . config("system.workspace") . $url[1]);
die();
-});
+}
try {
if ($_GET['APP_UID'] !== $_SESSION['APPLICATION']) {
diff --git a/workflow/engine/methods/services/ActionsByEmailDataFormPost.php b/workflow/engine/methods/services/ActionsByEmailDataFormPost.php
index 1b0c83c09..32198a3d8 100644
--- a/workflow/engine/methods/services/ActionsByEmailDataFormPost.php
+++ b/workflow/engine/methods/services/ActionsByEmailDataFormPost.php
@@ -5,11 +5,26 @@
* @link https://wiki.processmaker.com/3.3/Actions_by_Email#Link_to_Fill_a_Form
*/
-use ProcessMaker\ChangeLog\ChangeLog;
use ProcessMaker\BusinessModel\Cases\InputDocument;
+use ProcessMaker\ChangeLog\ChangeLog;
+use ProcessMaker\Validation\ValidationUploadedFiles;
if (PMLicensedFeatures::getSingleton()
->verifyfeature('zLhSk5TeEQrNFI2RXFEVktyUGpnczV1WEJNWVp6cjYxbTU3R29mVXVZNWhZQT0=')) {
+
+ /**
+ * To do: The following evaluation must be moved after saving the data (so as not to lose the data entered in the form).
+ * It only remains because it is an old behavior, which must be defined by "Product Owner".
+ * @see workflow/engine/methods/cases/cases_SaveData.php
+ */
+ $validator = ValidationUploadedFiles::getValidationUploadedFiles()->runRulesForFileEmpty();
+ if ($validator->fails()) {
+ G::SendMessageText($validator->getMessage(), "ERROR");
+ $url = explode("sys" . config("system.workspace"), $_SERVER['HTTP_REFERER']);
+ G::header("location: " . "/sys" . config("system.workspace") . $url[1]);
+ die();
+ }
+
$G_PUBLISH = new Publisher();
try {
diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php
index 4532b0f69..d0aa34cb7 100644
--- a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php
+++ b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php
@@ -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;
@@ -3502,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
*/
@@ -3511,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 {
@@ -3549,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
diff --git a/workflow/engine/src/ProcessMaker/Util/DateTime.php b/workflow/engine/src/ProcessMaker/Util/DateTime.php
index 26dba185f..d30d35a7e 100644
--- a/workflow/engine/src/ProcessMaker/Util/DateTime.php
+++ b/workflow/engine/src/ProcessMaker/Util/DateTime.php
@@ -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
diff --git a/workflow/engine/src/ProcessMaker/Util/helpers.php b/workflow/engine/src/ProcessMaker/Util/helpers.php
index 58afa158e..b3d93a2ae 100644
--- a/workflow/engine/src/ProcessMaker/Util/helpers.php
+++ b/workflow/engine/src/ProcessMaker/Util/helpers.php
@@ -401,27 +401,27 @@ function verifyCsrfToken($request)
}
/**
- * Get the difference between to multidimensional array
+ * 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 arrayDiffRecursive(array $array1, array $array2)
+ */
+function getDiffBetweenModifiedVariables(array $array1, array $array2)
{
$difference = [];
foreach ($array1 as $key => $value) {
if (is_array($value)) {
- if (!isset($array2[$key])) {
+ if ($value !== $array2[$key]) {
$difference[$key] = $value;
- } elseif (!is_array($array2[$key])) {
+ }
+ } 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;
- } else {
- $new_diff = arrayDiffRecursive($value, $array2[$key]);
- if (!empty($new_diff)) {
- $difference[$key] = $new_diff;
- }
}
} elseif (!isset($array2[$key]) || $array2[$key] != $value) {
$difference[$key] = $value;