diff --git a/Rakefile b/Rakefile index b93036c8b..c77f45a42 100644 --- a/Rakefile +++ b/Rakefile @@ -44,6 +44,7 @@ task :build => [:required] do pmUIDir = targetDir + "/pmUI" mafeDir = targetDir + "/mafe" pmdynaformDir = targetDir + "/pmdynaform" + prepareDirs([pmUIDir, mafeDir, pmdynaformDir, jsTargetDir, cssTargetDir, cssImagesTargetDir, imgTargetDir, pmUIFontsDir]) @@ -53,6 +54,7 @@ task :build => [:required] do pmuiHash = getHash(Dir.pwd + "/vendor/colosa/pmUI") mafeHash = getHash(Dir.pwd + "/vendor/colosa/MichelangeloFE") + pmdynaformHash = getHash(Dir.pwd + "/vendor/colosa/pmDynaform") hashVendors = pmuiHash+"-"+mafeHash ## Building minified JS Files @@ -94,7 +96,9 @@ task :build => [:required] do :pmui_ver => getVersion(Dir.pwd + "/vendor/colosa/pmUI"), :pmui_hash => pmuiHash, :mafe_ver => getVersion(Dir.pwd + "/vendor/colosa/MichelangeloFE"), - :mafe_hash => mafeHash + :mafe_hash => mafeHash, + :pmdynaform_ver => getVersion(Dir.pwd + "/vendor/colosa/pmDynaform"), + :pmdynaform_hash => pmdynaformHash } File.open(targetDir+"/versions", 'w+') do |writeFile| writeFile.write versions.to_json @@ -207,7 +211,11 @@ def getVersion(path) version = `rake version` end - return /([0-9\.]{5}+)/.match(version) + if version.lines.count > 1 + version = /([0-9\.]{5}+)/.match(version) + end + + return version.strip end diff --git a/build.xml b/build.xml index 5ea8ae249..2dd977b6b 100644 --- a/build.xml +++ b/build.xml @@ -32,7 +32,6 @@ - @@ -42,8 +41,6 @@ - - diff --git a/features/backend/projects/variables/basic_sequence_variables.feature b/features/backend/projects/variables/basic_sequence_variables.feature new file mode 100644 index 000000000..5a413cf46 --- /dev/null +++ b/features/backend/projects/variables/basic_sequence_variables.feature @@ -0,0 +1,104 @@ +@ProcessMakerMichelangelo @RestAPI +Feature: Process variables Resources + #GET /api/1.0/{workspace}/project/{prj_uid}/process-variables + # Get a List of process variables + Scenario: Get a List of process variables + Given that I have a valid access_token + And I request "project/14414793652a5d718b65590036026581/process-variables" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "array" + And the json data is an empty array + + #POST /api/1.0/{workspace}/project/{prj_uid}/process-variable + # Create a process variable + # Normal creation of a process variable + Scenario: Create "My variable" for a Project (Normal creation of a process variable) + Given that I have a valid access_token + And POST this data: + """ + { + "var_name": "My Variable", + "var_field_type": "text_field", + "var_field_size": 12, + "var_label": "Nombre:", + "var_dbconnection": "", + "var_sql": "", + "var_null": 0, + "var_default": "", + "var_accepted_values": "" + } + """ + And I request "project/14414793652a5d718b65590036026581/process-variable" + And the content type is "application/json" + Then the response status code should be 201 + And the response charset is "UTF-8" + And the type is "object" + And store "var_uid" in session array as variable "variable1" + + #PUT /api/1.0/{workspace}/project/{prj_uid}/process-variable/{var_uid} + # Update a process variable + Scenario: Update a process variable + Given that I have a valid access_token + And PUT this data: + """ + { + "var_name": "My Variable Modify", + "var_field_type": "text_field", + "var_field_size": 1, + "var_label": "Nombre modificado:", + "var_dbconnection": "", + "var_sql": "", + "var_null": 0, + "var_default": "", + "var_accepted_values": "" + } + """ + And that I want to update a resource with the key "variable1" stored in session array + And I request "project/14414793652a5d718b65590036026581/process-variable" + And the content type is "application/json" + Then the response status code should be 200 + + #GET /api/1.0/{workspace}/project/{prj_uid}/process-variables + # Get a List of process variables + Scenario: Get a List of process variables + Given that I have a valid access_token + And I request "project/14414793652a5d718b65590036026581/process-variables" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "array" + + #GET /api/1.0/{workspace}/project/{prj_uid}/process-variable/{var_uid} + # Get a single process variable + Scenario: Get a single process variable + Given that I have a valid access_token + And that I want to get a resource with the key "variable1" stored in session array + And I request "project/14414793652a5d718b65590036026581/process-variable" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "object" + + #DELETE /api/1.0/{workspace}/project/{prj_uid}/process-variable/{var_uid} + # Delete a process variable + Scenario: Delete a previously created process variable + Given that I have a valid access_token + And that I want to delete a resource with the key "variable1" stored in session array + And I request "project/14414793652a5d718b65590036026581/process-variable" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + + #GET /api/1.0/{workspace}/project/{prj_uid}/process-variables + # Get a List of process variables + Scenario: Get a List of process variables + Given that I have a valid access_token + And I request "project/14414793652a5d718b65590036026581/process-variables" + And the content type is "application/json" + Then the response status code should be 200 + And the response charset is "UTF-8" + And the type is "array" + And the json data is an empty array + diff --git a/workflow/engine/bin/cron.php b/workflow/engine/bin/cron.php index e9eb0eca7..c94808056 100755 --- a/workflow/engine/bin/cron.php +++ b/workflow/engine/bin/cron.php @@ -23,6 +23,7 @@ define('PATH_HOME', $pathhome); define('PATH_TRUNK', $pathTrunk); define('PATH_OUTTRUNK', $pathOutTrunk); +require_once PATH_TRUNK . "framework/src/Maveriks/Util/ClassLoader.php"; require_once (PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php'); require_once PATH_CORE . 'classes' . PATH_SEP . 'class.system.php'; diff --git a/workflow/engine/bin/cron_single.php b/workflow/engine/bin/cron_single.php index 6bf7f19b1..c82961d03 100755 --- a/workflow/engine/bin/cron_single.php +++ b/workflow/engine/bin/cron_single.php @@ -39,6 +39,7 @@ if (!defined('PATH_HOME')) { define('PATH_OUTTRUNK', $pathOutTrunk); require_once (PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php'); + require_once PATH_TRUNK . "framework/src/Maveriks/Util/ClassLoader.php"; G::LoadThirdParty('pear/json','class.json'); G::LoadThirdParty('smarty/libs','Smarty.class'); diff --git a/workflow/engine/classes/class.pluginRegistry.php b/workflow/engine/classes/class.pluginRegistry.php index d51baadc7..013134054 100755 --- a/workflow/engine/classes/class.pluginRegistry.php +++ b/workflow/engine/classes/class.pluginRegistry.php @@ -1495,5 +1495,15 @@ class PMPluginRegistry { $this->_restServiceEnabled[$sNamespace] = $enable; } + + /** + * Return all cron files registered + * + * @return array + */ + public function getCronFiles() + { + return $this->_aCronFiles; + } } diff --git a/workflow/engine/classes/model/Dynaform.php b/workflow/engine/classes/model/Dynaform.php index d48fbec92..6c7a2cf65 100755 --- a/workflow/engine/classes/model/Dynaform.php +++ b/workflow/engine/classes/model/Dynaform.php @@ -173,7 +173,9 @@ class Dynaform extends BaseDynaform if (isset($aData["DYN_CONTENT"])) { $this->setDynContent($aData["DYN_CONTENT"]); } - $this->setDynVersion( $aData['DYN_VERSION'] ); + if (isset($aData["DYN_VERSION"])) { + $this->setDynVersion( $aData['DYN_VERSION'] ); + } if ($this->validate()) { $con->begin(); $res = $this->save(); diff --git a/workflow/engine/controllers/main.php b/workflow/engine/controllers/main.php index 6fe75eeed..cc17f84eb 100644 --- a/workflow/engine/controllers/main.php +++ b/workflow/engine/controllers/main.php @@ -735,8 +735,9 @@ class Main extends Controller $versions = json_decode(file_get_contents(PATH_HTML . "lib/versions"), true); $pmuiVer = $versions["pmui_ver"]; $mafeVer = $versions["mafe_ver"]; + $pmdynaformVer = $versions["pmdynaform_ver"]; } else { - $pmuiVer = $mafeVer = "(unknown)"; + $pmuiVer = $mafeVer = $pmdynaformVer = "(unknown)"; } $sysSection = G::loadTranslation('ID_SYSTEM_INFO' ); @@ -751,6 +752,7 @@ class Main extends Controller $properties[] = array ($systemName. ' Ver.', System::getVersion() . $ee, $pmSection); $properties[] = array("PMUI JS Lib. Ver.", $pmuiVer, $pmSection); $properties[] = array("MAFE JS Lib. Ver.", $mafeVer, $pmSection); + $properties[] = array("PM Dynaform JS Lib. Ver.", $pmdynaformVer, $pmSection); if (file_exists(PATH_DATA. 'log/upgrades.log')) { $properties[] = array (G::LoadTranslation('ID_UPGRADES_PATCHES'), '' . G::LoadTranslation( 'ID_UPGRADE_VIEW_LOG') . '' ,$pmSection); diff --git a/workflow/engine/data/mysql/schema.sql b/workflow/engine/data/mysql/schema.sql index e74a4faba..3276e8474 100755 --- a/workflow/engine/data/mysql/schema.sql +++ b/workflow/engine/data/mysql/schema.sql @@ -205,6 +205,7 @@ CREATE TABLE `DYNAFORM` `DYN_TYPE` VARCHAR(20) default 'xmlform' NOT NULL, `DYN_FILENAME` VARCHAR(100) default '' NOT NULL, `DYN_CONTENT` MEDIUMTEXT, + `DYN_VERSION` INTEGER, PRIMARY KEY (`DYN_UID`) )ENGINE=InnoDB DEFAULT CHARSET='utf8' COMMENT='Forms required'; #----------------------------------------------------------------------------- diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/CaseScheduler.php b/workflow/engine/src/ProcessMaker/BusinessModel/CaseScheduler.php index 20c3fd1b3..60addfc4e 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/CaseScheduler.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/CaseScheduler.php @@ -283,8 +283,10 @@ class CaseScheduler if (!preg_match($patternDate, $caseSchedulerData['SCH_START_DATE'])) { throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_START_DATE")); } - if (!preg_match($patternDate, $caseSchedulerData['SCH_END_DATE'])) { - throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_END_DATE")); + if (!isset($caseSchedulerData['SCH_END_DATE'])) { + if (!preg_match($patternDate, $caseSchedulerData['SCH_END_DATE'])) { + throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_END_DATE")); + } } if ($caseSchedulerData['SCH_START_DATE'] == "") { throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('sch_start_date'))); @@ -568,8 +570,10 @@ class CaseScheduler if (!preg_match($patternDate, $caseSchedulerData['SCH_START_DATE'])) { throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_START_DATE")); } - if (!preg_match($patternDate, $caseSchedulerData['SCH_END_DATE'])) { - throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_END_DATE")); + if (isset($caseSchedulerData['SCH_END_DATE'])) { + if (!preg_match($patternDate, $caseSchedulerData['SCH_END_DATE'])) { + throw new \Exception(\G::LoadTranslation("ID_INVALID_SCH_END_DATE")); + } } if ($caseSchedulerData['SCH_START_DATE'] == "") { throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('sch_start_date'))); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php b/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php index 70f1b9f15..83244e39d 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/DynaForm.php @@ -10,7 +10,7 @@ class DynaForm "DYN_DESCRIPTION" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "dynaFormDescription"), "DYN_TYPE" => array("type" => "string", "required" => true, "empty" => false, "defaultValues" => array("xmlform", "grid"), "fieldNameAux" => "dynaFormType"), "DYN_CONTENT" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "dynaFormContent"), - "DYN_VERSION" => array("type" => "int", "required" => false, "empty" => false, "defaultValues" => array(), "fieldNameAux" => "dynaFormVersion") + "DYN_VERSION" => array("type" => "int", "required" => false, "empty" => true, "defaultValues" => array(1 ,2), "fieldNameAux" => "dynaFormVersion") ); private $formatFieldNameInUppercase = true; @@ -953,13 +953,17 @@ class DynaForm $record["DYN_DESCRIPTION"] = \Content::load("DYN_DESCRIPTION", "", $record["DYN_UID"], SYS_LANG); } + if ($record["DYN_VERSION"] == 0) { + $record["DYN_VERSION"] = 1; + } + return array( $this->getFieldNameByFormatFieldName("DYN_UID") => $record["DYN_UID"], $this->getFieldNameByFormatFieldName("DYN_TITLE") => $record["DYN_TITLE"], $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") => $record["DYN_VERSION"] . "" + $this->getFieldNameByFormatFieldName("DYN_VERSION") => (int)($record["DYN_VERSION"]) ); } catch (\Exception $e) { throw $e; diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php index a7d68b1f5..e10995b0e 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php @@ -191,7 +191,7 @@ class FilesManager } $content = $aData['prf_content']; if (is_string($content)) { - if (file_exists(PATH_SEP.$sDirectory)) { + if (file_exists($sDirectory)) { $directory = $sMainDirectory. PATH_SEP . $sSubDirectory . $aData['prf_filename']; throw new \Exception(\G::LoadTranslation("ID_EXISTS_FILE", array($directory))); } @@ -393,7 +393,7 @@ class FilesManager * @param string $prfUid {@min 32} {@max 32} * * - * @access public + * @access public */ public function deleteProcessFilesManager($sProcessUID, $prfUid) { diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/OutputDocument.php b/workflow/engine/src/ProcessMaker/BusinessModel/OutputDocument.php index af330057a..f6a38c298 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/OutputDocument.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/OutputDocument.php @@ -363,6 +363,7 @@ class OutputDocument require_once(PATH_TRUNK . "workflow" . PATH_SEP . "engine" . PATH_SEP . "classes" . PATH_SEP . "model" . PATH_SEP . "OutputDocument.php"); require_once (PATH_TRUNK . "workflow" . PATH_SEP . "engine" . PATH_SEP . "classes" . PATH_SEP . "model" . PATH_SEP . "ObjectPermission.php"); require_once(PATH_TRUNK . "workflow" . PATH_SEP . "engine" . PATH_SEP . "classes" . PATH_SEP . "model" . PATH_SEP . "Step.php"); + $this->throwExceptionIfItsAssignedInOtherObjects($sOutputDocumentUID, "outputDocumentUid"); \G::LoadClass( 'processMap' ); $oOutputDocument = new \OutputDocument(); $fields = $oOutputDocument->load( $sOutputDocumentUID ); @@ -443,5 +444,87 @@ class OutputDocument throw $e; } } + + /** + * Verify if the OutputDocument it's assigned in other objects + * + * @param string $outputDocumentUid Unique id of OutputDocument + * + * return array Return array (true if it's assigned or false otherwise and data) + */ + public function itsAssignedInOtherObjects($outputDocumentUid) + { + try { + $flagAssigned = false; + $arrayData = array(); + //Step + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\StepPeer::STEP_UID); + $criteria->add(\StepPeer::STEP_TYPE_OBJ, "OUTPUT_DOCUMENT", \Criteria::EQUAL); + $criteria->add(\StepPeer::STEP_UID_OBJ, $outputDocumentUid, \Criteria::EQUAL); + + $rsCriteria = \StepPeer::doSelectRS($criteria); + + if ($rsCriteria->next()) { + $flagAssigned = true; + $arrayData[] = \G::LoadTranslation("ID_STEPS"); + } + + //StepSupervisor + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\StepSupervisorPeer::STEP_UID); + $criteria->add(\StepSupervisorPeer::STEP_TYPE_OBJ, "OUTPUT_DOCUMENT", \Criteria::EQUAL); + $criteria->add(\StepSupervisorPeer::STEP_UID_OBJ, $outputDocumentUid, \Criteria::EQUAL); + + $rsCriteria = \StepSupervisorPeer::doSelectRS($criteria); + + if ($rsCriteria->next()) { + $flagAssigned = true; + $arrayData[] = \G::LoadTranslation("ID_CASES_MENU_ADMIN"); + } + + //ObjectPermission + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\ObjectPermissionPeer::OP_UID); + $criteria->add(\ObjectPermissionPeer::OP_OBJ_TYPE, "OUTPUT", \Criteria::EQUAL); + $criteria->add(\ObjectPermissionPeer::OP_OBJ_UID, $outputDocumentUid, \Criteria::EQUAL); + + $rsCriteria = \ObjectPermissionPeer::doSelectRS($criteria); + + if ($rsCriteria->next()) { + $flagAssigned = true; + $arrayData[] = \G::LoadTranslation("ID_PROCESS_PERMISSIONS"); + } + + //Return + return array($flagAssigned, $arrayData); + } catch (\Exception $e) { + throw $e; + } + } + + /** + * Verify if the OutputDocument it's assigned in other objects + * + * @param string $outputDocumentUid Unique id of OutputDocument + * @param string $fieldNameForException Field name for the exception + * + * return void Throw exception if the OutputDocument it's assigned in other objects + */ + public function throwExceptionIfItsAssignedInOtherObjects($outputDocumentUid, $fieldNameForException) + { + try { + list($flagAssigned, $arrayData) = $this->itsAssignedInOtherObjects($outputDocumentUid); + + if ($flagAssigned) { + throw new \Exception(\G::LoadTranslation("ID_OUTPUT_DOCUMENT_ITS_ASSIGNED", array($fieldNameForException, $outputDocumentUid, implode(", ", $arrayData)))); + } + } catch (\Exception $e) { + throw $e; + } + } } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php b/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php index a599c5275..7a5609a1b 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Variable.php @@ -3,38 +3,6 @@ namespace ProcessMaker\BusinessModel; class Variable { - private $arrayFieldDefinition = array( - "VAR_NAME" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varName"), - "VAR_FIELD_TYPE" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varFieldType"), - "VAR_FIELD_SIZE" => array("type" => "int", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varFieldSize"), - "VAR_LABEL" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varLabel"), - "VAR_DBCONNECTION" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varDbconnection"), - "VAR_SQL" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varSql"), - "VAR_NULL" => array("type" => "int", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varNull"), - "VAR_DEFAULT" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varDefault"), - "VAR_ACCEPTED_VALUES" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "varAcceptedValues") - ); - - private $arrayFieldNameForException = array( - "processUid" => "PRO_UID" - ); - - /** - * Constructor of the class - * - * return void - */ - public function __construct() - { - try { - foreach ($this->arrayFieldDefinition as $key => $value) { - $this->arrayFieldNameForException[$value["fieldNameAux"]] = $key; - } - } catch (\Exception $e) { - throw $e; - } - } - /** * Create Variable for a Process * @@ -47,13 +15,14 @@ class Variable { try { //Verify data - $process = new \ProcessMaker\BusinessModel\Process(); - $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); + Validator::proUid($processUid, '$prj_uid'); $arrayData = array_change_key_case($arrayData, CASE_UPPER); $this->existsName($processUid, $arrayData["VAR_NAME"]); + $this->throwExceptionFieldDefinition($arrayData); + //Create $cnn = \Propel::getConnection("workflow"); try { @@ -121,12 +90,10 @@ class Variable { try { //Verify data - $process = new \ProcessMaker\BusinessModel\Process(); - $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); - - $this->throwExceptionIfNotExistsVariable($variableUid); - + Validator::proUid($processUid, '$prj_uid'); $arrayData = array_change_key_case($arrayData, CASE_UPPER); + + $this->throwExceptionFieldDefinition($arrayData); $this->existsName($processUid, $arrayData["VAR_NAME"]); //Update $cnn = \Propel::getConnection("workflow"); @@ -183,9 +150,7 @@ class Variable { try { //Verify data - $process = new \ProcessMaker\BusinessModel\Process(); - - $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); + Validator::proUid($processUid, '$prj_uid'); $this->throwExceptionIfNotExistsVariable($variableUid); @@ -211,16 +176,12 @@ class Variable public function getVariable($processUid, $variableUid) { try { - //Verify data - $process = new \ProcessMaker\BusinessModel\Process(); - - $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); + Validator::proUid($processUid, '$prj_uid'); $this->throwExceptionIfNotExistsVariable($variableUid); //Get data - $criteria = new \Criteria("workflow"); $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_UID); @@ -279,12 +240,9 @@ class Variable { try { //Verify data - $process = new \ProcessMaker\BusinessModel\Process(); - - $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); + Validator::proUid($processUid, '$prj_uid'); //Get data - $criteria = new \Criteria("workflow"); $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_UID); @@ -331,19 +289,51 @@ class Variable } /** - * Verify if does not exist the variable in table PROCESS_VARIABLES + * Verify field definition * - * @param string $variableUid Unique id of variable + * @param array $aData Unique id of Variable to exclude * - * return void Throw exception if does not exist the variable in table PROCESS_VARIABLES */ - public function throwExceptionIfNotExistsVariable($variableUid) + public function throwExceptionFieldDefinition($aData) { try { - $obj = \ProcessVariablesPeer::retrieveByPK($variableUid); - - if (is_null($obj)) { - throw new \Exception('var_uid: '.$variableUid. ' '.\G::LoadTranslation("ID_DOES_NOT_EXIST")); + if (isset($aData["VAR_NAME"])) { + Validator::isString($aData['VAR_NAME'], '$var_name'); + } else { + throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('$var_name' ))); + } + if (isset($aData["VAR_FIELD_TYPE"])) { + Validator::isString($aData['VAR_FIELD_TYPE'], '$var_field_type'); + } else { + throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('$var_field_type' ))); + } + if (isset($aData["VAR_FIELD_SIZE"])) { + Validator::isInteger($aData["VAR_FIELD_SIZE"], '$var_field_size'); + } else { + throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('$var_field_size' ))); + } + if (isset($aData["VAR_LABEL"])) { + Validator::isString($aData['VAR_LABEL'], '$var_label'); + } else { + throw new \Exception(\G::LoadTranslation("ID_CAN_NOT_BE_NULL", array('$var_label' ))); + } + if (isset($aData["VAR_DBCONNECTION"])) { + Validator::isString($aData['VAR_DBCONNECTION'], '$var_dbconnection'); + } + if (isset($aData["VAR_SQL"])) { + Validator::isString($aData['VAR_SQL'], '$var_sql'); + } + if (isset($aData["VAR_NULL"])) { + Validator::isInteger($aData['VAR_NULL'], '$var_null'); + if ($aData["VAR_NULL"] != 0 || $aData["VAR_NULL"] !=1 ) { + throw new \Exception(\G::LoadTranslation("ID_INVALID_VALUE_ONLY_ACCEPTS_VALUES", array('$var_null','0, 1' ))); + } + } + if (isset($aData["VAR_DEFAULT"])) { + Validator::isString($aData['VAR_DEFAULT'], '$var_default'); + } + if (isset($aData["VAR_ACCEPTED_VALUES"])) { + Validator::isString($aData['VAR_ACCEPTED_VALUES'], '$var_accepted_values'); } } catch (\Exception $e) { throw $e; @@ -376,6 +366,119 @@ class Variable } } + /** + * Get required variables in the SQL + * + * @param string $sql SQL + * + * return array Return an array with required variables in the SQL + */ + public function sqlGetRequiredVariables($sql) + { + try { + $arrayVariableRequired = array(); + preg_match_all("/@[@%#\?\x24\=]([A-Za-z_]\w*)/", $sql, $arrayMatch, PREG_SET_ORDER); + + foreach ($arrayMatch as $value) { + $arrayVariableRequired[] = $value[1]; + } + + return $arrayVariableRequired; + } catch (\Exception $e) { + throw $e; + } + } + + /** + * Verify if some required variable in the SQL is missing in the variables + * + * @param string $variableName Variable name + * @param string $variableSql SQL + * @param array $arrayVariable The variables + * + * return void Throw exception if some required variable in the SQL is missing in the variables + */ + public function throwExceptionIfSomeRequiredVariableSqlIsMissingInVariables($variableName, $variableSql, array $arrayVariable) + { + try { + $arrayResult = array_diff(array_unique($this->sqlGetRequiredVariables($variableSql)), array_keys($arrayVariable)); + + if (count($arrayResult) > 0) { + throw new \Exception(\G::LoadTranslation("ID_PROCESS_VARIABLE_REQUIRED_VARIABLES_FOR_QUERY", array($variableName, implode(", ", $arrayResult)))); + } + } catch (\Exception $e) { + throw $e; + } + } + + /** + * Get all records by execute SQL + * + * @param string $processUid Unique id of Process + * @param string $variableName Variable name + * @param array $arrayVariable The variables + * + * return array Return an array with all records + */ + public function executeSql($processUid, $variableName, array $arrayVariable = array()) + { + try { + $arrayRecord = array(); + + //Verify data + $process = new \ProcessMaker\BusinessModel\Process(); + + $process->throwExceptionIfNotExistsProcess($processUid, strtolower("PRJ_UID")); + + //Set data + $variableDbConnectionUid = ""; + $variableSql = ""; + + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_DBCONNECTION); + $criteria->addSelectColumn(\ProcessVariablesPeer::VAR_SQL); + $criteria->add(\ProcessVariablesPeer::PRJ_UID, $processUid, \Criteria::EQUAL); + $criteria->add(\ProcessVariablesPeer::VAR_NAME, $variableName, \Criteria::EQUAL); + + $rsCriteria = \ProcessVariablesPeer::doSelectRS($criteria); + $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + if ($rsCriteria->next()) { + $row = $rsCriteria->getRow(); + + $variableDbConnectionUid = $row["VAR_DBCONNECTION"]; + $variableSql = $row["VAR_SQL"]; + } else { + throw new \Exception(\G::LoadTranslation("ID_PROCESS_VARIABLE_DOES_NOT_EXIST", array(strtolower("VAR_NAME"), $variableName))); + } + + //Verify data + $this->throwExceptionIfSomeRequiredVariableSqlIsMissingInVariables($variableName, $variableSql, $arrayVariable); + + //Get data + $_SESSION["PROCESS"] = $processUid; + + $cnn = \Propel::getConnection(($variableDbConnectionUid . "" != "")? $variableDbConnectionUid : "workflow"); + $stmt = $cnn->createStatement(); + + $rs = $stmt->executeQuery(\G::replaceDataField($variableSql, $arrayVariable), \ResultSet::FETCHMODE_NUM); + + while ($rs->next()) { + $row = $rs->getRow(); + + $arrayRecord[] = array( + strtolower("VALUE") => $row[0], + strtolower("TEXT") => $row[1] + ); + } + + //Return + return $arrayRecord; + } catch (\Exception $e) { + throw $e; + } + } } diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Project/Variable.php b/workflow/engine/src/ProcessMaker/Services/Api/Project/Variable.php index 9d8ec55a9..d1479fc83 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/Project/Variable.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/Project/Variable.php @@ -55,7 +55,7 @@ class Variable extends Api * * @status 201 */ - public function doPostVariable($prj_uid, array $request_data) + public function doPostVariable($prj_uid, $request_data) { try { $request_data = (array)($request_data); @@ -107,4 +107,27 @@ class Variable extends Api throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); } } -} \ No newline at end of file + + /** + * @url POST /:prj_uid/process-variable/:var_name/execute-query + * + * @param string $prj_uid {@min 32}{@max 32} + * @param string $var_name + * @param array $request_data + */ + public function doPostVariableExecuteSql($prj_uid, $var_name, $request_data) + { + try { + $variable = new \ProcessMaker\BusinessModel\Variable(); + + $arrayData = ($request_data != null)? $variable->executeSql($prj_uid, $var_name, $request_data) : $variable->executeSql($prj_uid, $var_name); + + $response = $arrayData; + + return $response; + } catch (\Exception $e) { + throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); + } + } +} + diff --git a/workflow/engine/templates/processes/main.js b/workflow/engine/templates/processes/main.js index 372c297fb..988a06a1c 100755 --- a/workflow/engine/templates/processes/main.js +++ b/workflow/engine/templates/processes/main.js @@ -227,14 +227,6 @@ Ext.onReady(function(){ text: _('ID_NEW'), iconCls: 'button_menu_ext ss_sprite ss_add', menu: [ - { - text: "New Project", - iconCls: 'silk-add', - icon: '', - handler: function () { - newProcess({type:"classicProject"}); - } - }, { text: "New BPMN Project", iconCls: 'silk-add', @@ -242,6 +234,14 @@ Ext.onReady(function(){ handler: function () { newProcess({type:"bpmnProject"}); } + }, + { + text: "New Project", + iconCls: 'silk-add', + icon: '', + handler: function () { + newProcess({type:"classicProject"}); + } } ], listeners: {