diff --git a/workflow/engine/controllers/processProxy.php b/workflow/engine/controllers/processProxy.php index fcae2c2b1..d968cb2c3 100755 --- a/workflow/engine/controllers/processProxy.php +++ b/workflow/engine/controllers/processProxy.php @@ -447,5 +447,27 @@ class ProcessProxy extends HttpProxyController } $this->rows = $rows; } + + /** + * Generate BPMN (New record is generated) + * + * return void + */ + public function generateBpmn() + { + try { + $processUid = $_POST["processUid"]; + + $workflowBpmn = new \ProcessMaker\Project\Adapter\WorkflowBpmn(); + + $projectUid = $workflowBpmn->generateBpmn($processUid, "processUid"); + + $this->status = "OK"; + $this->projectUid = $projectUid; + } catch (Exception $e) { + $this->status = "ERROR"; + $this->message = $e->getMessage(); + } + } } diff --git a/workflow/engine/src/ProcessMaker/Exporter/Exporter.php b/workflow/engine/src/ProcessMaker/Exporter/Exporter.php index 3b7390242..c2a1e20a3 100644 --- a/workflow/engine/src/ProcessMaker/Exporter/Exporter.php +++ b/workflow/engine/src/ProcessMaker/Exporter/Exporter.php @@ -111,60 +111,12 @@ abstract class Exporter $bpmnStruct["PROCESS"] = \BpmnProcess::getAll($this->prjUid); $bpmnStruct["PROJECT"] = array(\BpmnProjectPeer::retrieveByPK($this->prjUid)->toArray()); - $oProcess = new \Processes(); - $workflowData = (array) $oProcess->getWorkflowData($this->prjUid); - $workflowData["process"]['PRO_DYNAFORMS'] = empty($workflowData["process"]['PRO_DYNAFORMS']) - ? "" : serialize($workflowData["process"]['PRO_DYNAFORMS']); - - $workflowData["process"] = array($workflowData["process"]); - $workflowData["processCategory"] = empty($workflowData["processCategory"]) ? array() : array($workflowData["processCategory"]); - + $workflow = new \ProcessMaker\Project\Workflow(); + list($workflowData, $workflowFile) = $workflow->getData($this->prjUid); $data["bpmn-definition"] = $bpmnStruct; $data["workflow-definition"] = $workflowData; - $data["workflow-files"] = array(); - - // getting dynaforms - foreach ($workflowData["dynaforms"] as $dynaform) { - $dynFile = PATH_DYNAFORM . $dynaform['DYN_FILENAME'] . '.xml'; - $data["workflow-files"]["DYNAFORMS"][] = array( - "filename" => $dynaform['DYN_TITLE'], - "filepath" => $dynaform['DYN_FILENAME'] . '.xml', - "file_content" => file_get_contents($dynFile) - ); - - $htmlFile = PATH_DYNAFORM . $dynaform['DYN_FILENAME'] . '.html'; - - if (file_exists($htmlFile)) { - $data["workflow-files"]["DYNAFORMS"][] = array( - "filename" => $dynaform['DYN_FILENAME'] . '.html', - "filepath" => $dynaform['DYN_FILENAME'] . '.html', - "file_content" => file_get_contents($htmlFile) - ); - } - } - - // getting templates files - $workspaceTargetDirs = array("TEMPLATES" => "mailTemplates", "PUBLIC" => "public"); - $workspaceDir = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP; - - foreach ($workspaceTargetDirs as $target => $workspaceTargetDir) { - $templatesDir = $workspaceDir . $workspaceTargetDir . PATH_SEP . $this->prjUid; - $templatesFiles = Util\Common::rglob("$templatesDir/*", 0, true); - - foreach ($templatesFiles as $templatesFile) { - if (is_dir($templatesFile)) { - continue; - } - - $filename = basename($templatesFile); - $data["workflow-files"][$target][] = array( - "filename" => $filename, - "filepath" => $this->prjUid . PATH_SEP . $filename, - "file_content" => file_get_contents($templatesFile) - ); - } - } + $data["workflow-files"] = $workflowFile; return $data; } diff --git a/workflow/engine/src/ProcessMaker/Importer/Importer.php b/workflow/engine/src/ProcessMaker/Importer/Importer.php index 8f32cac13..7b9fee00c 100644 --- a/workflow/engine/src/ProcessMaker/Importer/Importer.php +++ b/workflow/engine/src/ProcessMaker/Importer/Importer.php @@ -18,6 +18,8 @@ abstract class Importer const IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW = "project.import.keep_without_changing_and_create_new"; const IMPORT_OPTION_CREATE_NEW = "project.import.create_new"; + const IMPORT_OPTION_WORKFLOW_TO_BPMN_GENERATE = "project.import.workflow_to_bpmn_generate"; + const GROUP_IMPORT_OPTION_RENAME = "group.import.rename"; const GROUP_IMPORT_OPTION_MERGE_PREEXISTENT = "group.import.merge.preexistent"; const GROUP_IMPORT_OPTION_CREATE_NEW = "group.import.create_new"; @@ -29,6 +31,20 @@ abstract class Importer public abstract function load(); + /** + * Set import data + * + * @param array $arrayData Data + * + * return void + */ + public function setImportData(array $arrayData) + { + $this->importData = $arrayData; + + $this->validateImportData(); + } + /** * Verify if exists reserved words SQL * @@ -71,7 +87,16 @@ abstract class Importer public function import($option = self::IMPORT_OPTION_CREATE_NEW, $optionGroup = self::GROUP_IMPORT_OPTION_CREATE_NEW) { - $this->prepare(); + $generateUid = false; + + if ($option != self::IMPORT_OPTION_WORKFLOW_TO_BPMN_GENERATE) { + $this->prepare(); + } else { + $generateUid = true; + + $option = ""; + $optionGroup = ""; + } $name = $this->importData["tables"]["bpmn"]["project"][0]["prj_name"]; @@ -315,8 +340,8 @@ abstract class Importer $diagram["events"] = $tables["event"]; $diagram["flows"] = $tables["flow"]; $diagram["gateways"] = $tables["gateway"]; - $diagram["data"] = $tables["data"]; - $diagram["participants"] = $tables["participant"]; + $diagram["data"] = (isset($tables["data"]))? $tables["data"] : array(); + $diagram["participants"] = (isset($tables["participant"]))? $tables["participant"] : array(); $diagram["lanes"] = array(); $diagram["laneset"] = array(); $project["diagrams"] = array($diagram); @@ -415,7 +440,7 @@ abstract class Importer foreach ($arrayFiles as $key2 => $value2) { $file = $value2; - $arrayWorkflowFiles[$key1][$key2]["file_path"] = str_replace($projectUidOld, $projectUid, $file["file_path"]); + $arrayWorkflowFiles[$key1][$key2]["file_path"] = str_replace($projectUidOld, $projectUid, (isset($file["file_path"]))? $file["file_path"] : $file["filepath"]); $arrayWorkflowFiles[$key1][$key2]["file_content"] = str_replace($projectUidOld, $projectUid, $file["file_content"]); } } diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index a65e724ff..0fa806b6c 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -926,7 +926,7 @@ class BpmnWorkflow extends Project\Bpmn if ($forceInsert || is_null($dataObject)) { if ($generateUid) { - //Event + //Data unset($dataObjectData["BOU_UID"]); $uidOld = $dataObjectData["DAT_UID"]; @@ -973,7 +973,7 @@ class BpmnWorkflow extends Project\Bpmn if ($forceInsert || is_null($dataObject)) { if ($generateUid) { - //Event + //Participant unset($participantData["BOU_UID"]); $uidOld = $participantData["PAR_UID"]; @@ -993,7 +993,7 @@ class BpmnWorkflow extends Project\Bpmn Util\Logger::log("Update Participant ({$participantData["PAR_UID"]}) Skipped - No changes required"); } - $diagram["participant"][$i] = $participantData; + $diagram["participants"][$i] = $participantData; $whiteList[] = $participantData["PAR_UID"]; } diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/WorkflowBpmn.php b/workflow/engine/src/ProcessMaker/Project/Adapter/WorkflowBpmn.php index 0914008a3..90657adb6 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/WorkflowBpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/WorkflowBpmn.php @@ -86,4 +86,711 @@ class WorkflowBpmn extends Project\Workflow parent::remove(); $this->bp->remove(); } -} \ No newline at end of file + + public function generateBpmnDataEvent( + $projectUid, + $processUid, + $objectBpmnType, + $objectUid, + $objectBouX, + $objectBouY, + $objectBouWidth, + $objectBouHeight, + $eventType, + $i + ) { + try { + $eventBouWidth = 35; + $eventBouHeight = $eventBouWidth; + + $eventBouWidth2 = (int)($eventBouWidth / 2); + $eventBouHeight2 = (int)($eventBouHeight / 2); + + $eventBouHeight12 = (int)($eventBouWidth / 12); + + // + $objectBouWidth2 = (int)($objectBouWidth / 2); + $objectBouWidth4 = (int)($objectBouWidth / 4); + + //Event + $eventUid = \ProcessMaker\Util\Common::generateUID(); + + if ($objectBpmnType == "bpmnGateway" && $eventType == "END") { + //Gateway + $eventBouX = $objectBouX + $objectBouWidth + $objectBouWidth4; + $eventBouY = $objectBouY + (int)($objectBouHeight / 2) - $eventBouHeight2; + } else { + //Activity + $eventBouX = $objectBouX + $objectBouWidth2 - $eventBouWidth2; + $eventBouY = ($eventType == "START")? $objectBouY - $eventBouHeight - $eventBouHeight2 : $objectBouY + $objectBouHeight + $eventBouHeight2 + $eventBouHeight12; + } + + $arrayEvent = array( + "evn_uid" => $eventUid, + "prj_uid" => $projectUid, + "pro_uid" => $processUid, + //"evn_name" => \G::LoadTranslation(($eventType == "START")? "ID_BPMN_EVENT_START_NAME" : "ID_BPMN_EVENT_END_NAME", array($i)), + "evn_name" => "", + "evn_type" => $eventType, + "evn_marker" => "EMPTY", + "bou_x" => $eventBouX, + "bou_y" => $eventBouY, + "bou_width" => $eventBouWidth, + "bou_height" => $eventBouHeight + ); + + //Flow + if ($objectBpmnType == "bpmnGateway" && $eventType == "END") { + //Gateway + $flowX1 = $objectBouX + $objectBouWidth; + $flowY1 = $objectBouY + (int)($objectBouHeight / 2); + $flowX2 = $eventBouX; + $flowY2 = $eventBouY + $eventBouHeight2; + } else { + //Activity + $flowX1 = $objectBouX + $objectBouWidth2; + $flowY1 = ($eventType == "START")? $objectBouY - $eventBouHeight + $eventBouHeight2 : $objectBouY + $objectBouHeight; + $flowX2 = $flowX1; + $flowY2 = ($eventType == "START")? $objectBouY : $objectBouY + $objectBouHeight + $eventBouHeight2 + $eventBouHeight12; + } + + $arrayFlow = array( + "flo_uid" => \ProcessMaker\Util\Common::generateUID(), + "prj_uid" => $projectUid, + "pro_uid" => $processUid, + "flo_type" => "SEQUENCE", + "flo_element_origin" => ($eventType == "START")? $eventUid : $objectUid, + "flo_element_origin_type" => ($eventType == "START")? "bpmnEvent" : $objectBpmnType, + "flo_element_dest" => ($eventType == "START")? $objectUid : $eventUid, + "flo_element_dest_type" => ($eventType == "START")? $objectBpmnType : "bpmnEvent", + "flo_is_inmediate" => 1, + "flo_x1" => $flowX1, + "flo_y1" => $flowY1, + "flo_x2" => $flowX2, + "flo_y2" => $flowY2, + "flo_state" => json_encode( + array( + array("x" => $flowX1, "y" => $flowY1), + array("x" => $flowX1, "y" => $flowY2 - 5), + array("x" => $flowX2, "y" => $flowY2 - 5), + array("x" => $flowX2, "y" => $flowY2) + ) + ) + ); + + //Return + return array($arrayEvent, $arrayFlow); + } catch (\Exception $e) { + throw $e; + } + } + + public function generateBpmnDataGateway( + $projectUid, + $processUid, + $objectBpmnType, + $objectUid, + $objectBouX, + $objectBouY, + $objectBouWidth, + $objectBouHeight, + $gatewayType, + $gatewayName, + $gatewayDirection + ) { + try { + $gatewayBouWidth = 45; + $gatewayBouHeight = $gatewayBouWidth; + + $gatewayBouWidth2 = (int)($gatewayBouWidth / 2); + $gatewayBouHeight2 = (int)($gatewayBouHeight / 2); + + // + $objectBouWidth2 = (int)($objectBouWidth / 2); + $objectBouHeight2 = (int)($objectBouHeight / 2); + + //Gateway + $gatewayUid = \ProcessMaker\Util\Common::generateUID(); + $gatewayBouX = $objectBouX + $objectBouWidth2 - $gatewayBouWidth2; + $gatewayBouY = ($gatewayDirection == "DIVERGING")? $objectBouY + $objectBouHeight + $gatewayBouHeight2 : $objectBouY - $gatewayBouHeight - $gatewayBouHeight2; + + $arrayGateway = array( + "gat_uid" => $gatewayUid, + "prj_uid" => $projectUid, + "pro_uid" => $processUid, + "gat_type" => $gatewayType, + "gat_name" => $gatewayName, + "gat_direction" => $gatewayDirection, + "gat_default_flow" => "0", + "bou_x" => $gatewayBouX, + "bou_y" => $gatewayBouY, + "bou_width" => $gatewayBouWidth, + "bou_height" => $gatewayBouHeight + ); + + //Flow + if ($gatewayDirection == "DIVERGING") { + $flowX1 = $objectBouX + $objectBouWidth2; + $flowY1 = $objectBouY + $objectBouHeight; + $flowX2 = $flowX1; + $flowY2 = $gatewayBouY; + } else { + $flowX1 = $objectBouX + $objectBouWidth2; + $flowY1 = $gatewayBouY + $gatewayBouHeight; + $flowX2 = $flowX1; + $flowY2 = $objectBouY; + } + + $arrayFlow = array( + "flo_uid" => \ProcessMaker\Util\Common::generateUID(), + "prj_uid" => $projectUid, + "pro_uid" => $processUid, + "flo_type" => "SEQUENCE", + "flo_element_origin" => ($gatewayDirection == "DIVERGING")? $objectUid : $gatewayUid, + "flo_element_origin_type" => ($gatewayDirection == "DIVERGING")? $objectBpmnType : "bpmnGateway", + "flo_element_dest" => ($gatewayDirection == "DIVERGING")? $gatewayUid : $objectUid, + "flo_element_dest_type" => ($gatewayDirection == "DIVERGING")? "bpmnGateway" : $objectBpmnType, + "flo_is_inmediate" => 1, + "flo_x1" => $flowX1, + "flo_y1" => $flowY1, + "flo_x2" => $flowX2, + "flo_y2" => $flowY2, + "flo_state" => json_encode( + array( + array("x" => $flowX1, "y" => $flowY1), + array("x" => $flowX1, "y" => $flowY2 - 5), + array("x" => $flowX2, "y" => $flowY2 - 5), + array("x" => $flowX2, "y" => $flowY2) + ) + ) + ); + + //Return + return array($arrayGateway, $arrayFlow); + } catch (\Exception $e) { + throw $e; + } + } + + public function generateBpmnDataFlow( + $projectUid, + $processUid, + $objectOriginBpmnType, + $objectOriginUid, + $objectOriginBouX, + $objectOriginBouY, + $objectOriginBouWidth, + $objectOriginBouHeight, + $objectDestBpmnType, + $objectDestUid, + $objectDestBouX, + $objectDestBouY, + $objectDestBouWidth, + $objectDestBouHeight + ) { + try { + $objectOriginBouWidth2 = (int)($objectOriginBouWidth / 2); + $objectDestBouWidth2 = (int)($objectDestBouWidth / 2); + + $x1 = $objectOriginBouX + $objectOriginBouWidth2; + $y1 = $objectOriginBouY + $objectOriginBouHeight; + $x2 = $objectDestBouX + $objectDestBouWidth2; + $y2 = $objectDestBouY; + + //Flow + $arrayFlow = array( + "flo_uid" => \ProcessMaker\Util\Common::generateUID(), + "prj_uid" => $projectUid, + "pro_uid" => $processUid, + "flo_type" => "SEQUENCE", + "flo_element_origin" => $objectOriginUid, + "flo_element_origin_type" => $objectOriginBpmnType, + "flo_element_dest" => $objectDestUid, + "flo_element_dest_type" => $objectDestBpmnType, + "flo_is_inmediate" => 1, + "flo_x1" => $x1, + "flo_y1" => $y1, + "flo_x2" => $x2, + "flo_y2" => $y2, + "flo_state" => json_encode(array()) + ); + + //Return + return $arrayFlow; + } catch (\Exception $e) { + throw $e; + } + } + + public function generateBpmnData($processUid) + { + try { + $arrayData = array(); + + //Generate workflow data + list($arrayWorkflowData, $arrayWorkflowFile) = $this->getData($processUid); + + $arrayWorkflowData["groupwfs"] = array(); //Empty Groups + + $projectUid = $processUid; + $bpmnDiagramUid = \ProcessMaker\Util\Common::generateUID(); + $bpmnProcessUid = \ProcessMaker\Util\Common::generateUID(); + + //Generate BPMN data + $arrayBpmnData = array(); + + $arrayBpmnData["project"][] = array( + "prj_uid" => $projectUid, + "prj_name" => $arrayWorkflowData["process"][0]["PRO_TITLE"], + "prj_description" => $arrayWorkflowData["process"][0]["PRO_DESCRIPTION"], + "prj_create_date" => $arrayWorkflowData["process"][0]["PRO_CREATE_DATE"], + "prj_update_date" => $arrayWorkflowData["process"][0]["PRO_UPDATE_DATE"], + "prj_author" => $arrayWorkflowData["process"][0]["PRO_CREATE_USER"] + ); + + $arrayBpmnData["diagram"][] = array( + "dia_uid" => $bpmnDiagramUid, + "prj_uid" => $projectUid, + "dia_name" => $arrayWorkflowData["process"][0]["PRO_TITLE"] + ); + + $arrayBpmnData["process"][] = array( + "pro_uid" => $bpmnProcessUid, + "prj_uid" => $projectUid, + "dia_uid" => $bpmnDiagramUid, + "pro_name" => $arrayWorkflowData["process"][0]["PRO_TITLE"] + ); + + $eventStartCount = 0; + $eventEndCount = 0; + + $arrayActivityType = array( + "NORMAL" => "TASK", + "ADHOC" => "TASK", + "SUBPROCESS" => "SUB_PROCESS" + ); + + $arrayBpmnData["activity"] = array(); //Activity + $arrayBpmnData["event"] = array(); //Event + $arrayBpmnData["flow"] = array(); //Flow + + $arrayTaskData = array(); + + foreach ($arrayWorkflowData["tasks"] as $value) { + $arrayTask = $value; + + $arrayTaskData[$arrayTask["TAS_UID"]] = $arrayTask; + + //Activity + $activityUid = $arrayTask["TAS_UID"]; + $activityBouX = (int)($arrayTask["TAS_POSX"]); + $activityBouY = (int)($arrayTask["TAS_POSY"]); + $activityBouWidth = (int)($arrayTask["TAS_WIDTH"]); + $activityBouHeight = (int)($arrayTask["TAS_HEIGHT"]); + + $arrayBpmnData["activity"][] = array( + "act_uid" => $activityUid, + "prj_uid" => $projectUid, + "pro_uid" => $bpmnProcessUid, + "act_name" => $arrayTask["TAS_TITLE"], + "act_type" => $arrayActivityType[$arrayTask["TAS_TYPE"]], + "bou_x" => $activityBouX, + "bou_y" => $activityBouY, + "bou_width" => $activityBouWidth, + "bou_height" => $activityBouHeight + ); + + if ($arrayTask["TAS_START"] == "TRUE") { + $eventStartCount = $eventStartCount + 1; + + list($arrayEvent, $arrayFlow) = $this->generateBpmnDataEvent( + $projectUid, + $bpmnProcessUid, + "bpmnActivity", + $activityUid, + $activityBouX, + $activityBouY, + $activityBouWidth, + $activityBouHeight, + "START", + $eventStartCount + ); + + //Event - START + $arrayBpmnData["event"][] = $arrayEvent; + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + } + } + + $arrayWorkflowDataRouteSecJoin = array(); + + $arrayGatewayDivergingData = array(); + $arrayGatewayDivergingNextActivityData = array(); + + $arrayGatewayInfo = array( + "EVALUATE" => array("type" => "EXCLUSIVE", "translationUid" => "ID_BPMN_GATEWAY_NAME_EXCLUSIVE", "count" => 0), + "SELECT" => array("type" => "COMPLEX", "translationUid" => "ID_BPMN_GATEWAY_NAME_COMPLEX", "count" => 0), + "PARALLEL" => array("type" => "PARALLEL", "translationUid" => "ID_BPMN_GATEWAY_NAME_PARALLEL", "count" => 0), + "PARALLEL-BY-EVALUATION" => array("type" => "INCLUSIVE", "translationUid" => "ID_BPMN_GATEWAY_NAME_INCLUSIVE", "count" => 0) + ); + + $arrayGatewayInfoR = array( + "EXCLUSIVE" => "EVALUATE", + "COMPLEX" => "SELECT", + "PARALLEL" => "PARALLEL", + "INCLUSIVE" => "PARALLEL-BY-EVALUATION" + ); + + $arrayBpmnData["gateway"] = array(); //Gateway + + foreach ($arrayWorkflowData["routes"] as $value) { + $arrayRoute = $value; + + $arrayTask = $arrayTaskData[$arrayRoute["TAS_UID"]]; + + $activityUid = $arrayTask["TAS_UID"]; + $activityBouX = (int)($arrayTask["TAS_POSX"]); + $activityBouY = (int)($arrayTask["TAS_POSY"]); + $activityBouWidth = (int)($arrayTask["TAS_WIDTH"]); + $activityBouHeight = (int)($arrayTask["TAS_HEIGHT"]); + + $flagFlow = false; + $strFlowParams = ""; + $flagEventEnd = false; + $strEventEndParams = ""; + + switch ($arrayRoute["ROU_TYPE"]) { + case "EVALUATE": + case "SELECT": + case "PARALLEL": + case "PARALLEL-BY-EVALUATION": + if (!isset($arrayGatewayDivergingData[$activityUid])) { + $arrayGatewayInfo[$arrayRoute["ROU_TYPE"]]["count"] = $arrayGatewayInfo[$arrayRoute["ROU_TYPE"]]["count"] + 1; + + list($arrayGateway, $arrayFlow) = $this->generateBpmnDataGateway( + $projectUid, + $bpmnProcessUid, + "bpmnActivity", + $activityUid, + $activityBouX, + $activityBouY, + $activityBouWidth, + $activityBouHeight, + $arrayGatewayInfo[$arrayRoute["ROU_TYPE"]]["type"], + //\G::LoadTranslation($arrayGatewayInfo[$arrayRoute["ROU_TYPE"]]["translationUid"], array($arrayGatewayInfo[$arrayRoute["ROU_TYPE"]]["count"])), + "", + "DIVERGING" + ); + + //Gateway + $arrayBpmnData["gateway"][] = $arrayGateway; + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + + //Gateway DIVERGING + $arrayGatewayDivergingData[$activityUid] = array( + $arrayGateway["gat_uid"], + $arrayGateway["gat_type"], + $arrayGateway["bou_x"], + $arrayGateway["bou_y"], + $arrayGateway["bou_width"], + $arrayGateway["bou_height"], + ); + } + + $gatewayUid = $arrayGatewayDivergingData[$activityUid][0]; + $gatewayType = $arrayGatewayDivergingData[$activityUid][1]; + $gatewayBouX = $arrayGatewayDivergingData[$activityUid][2]; + $gatewayBouY = $arrayGatewayDivergingData[$activityUid][3]; + $gatewayBouWidth = $arrayGatewayDivergingData[$activityUid][4]; + $gatewayBouHeight = $arrayGatewayDivergingData[$activityUid][5]; + + if ($arrayRoute["ROU_NEXT_TASK"] != "-1") { + $flagFlow = true; + + $arrayTask = $arrayTaskData[$arrayRoute["ROU_NEXT_TASK"]]; + + $strFlowParams = " + \"bpmnGateway\", + \"$gatewayUid\", + $gatewayBouX, + $gatewayBouY, + $gatewayBouWidth, + $gatewayBouHeight, + \"bpmnActivity\", + \"" . $arrayTask["TAS_UID"] . "\", + " . ((int)($arrayTask["TAS_POSX"])) . ", + " . ((int)($arrayTask["TAS_POSY"])) . ", + " . ((int)($arrayTask["TAS_WIDTH"])) . ", + " . ((int)($arrayTask["TAS_HEIGHT"])) . " + "; + + //Gateway DIVERGING - Next Activity + $arrayGatewayDivergingNextActivityData[$arrayTask["TAS_UID"]] = array( + $gatewayUid, + $gatewayType, + $gatewayBouX, + $gatewayBouY, + $gatewayBouWidth, + $gatewayBouHeight + ); + } else { + $flagEventEnd = true; + + $objectBpmnType = "bpmnGateway"; + $objectUid = $gatewayUid; + $objectBouX = $gatewayBouX; + $objectBouY = $gatewayBouY; + $objectBouWidth = $gatewayBouWidth; + $objectBouHeight = $gatewayBouHeight; + } + break; + case "SEQUENTIAL": + if ($arrayRoute["ROU_NEXT_TASK"] != "-1") { + $flagFlow = true; + + $arrayTask = $arrayTaskData[$arrayRoute["ROU_NEXT_TASK"]]; + + $strFlowParams = " + \"bpmnActivity\", + \"$activityUid\", + $activityBouX, + $activityBouY, + $activityBouWidth, + $activityBouHeight, + \"bpmnActivity\", + \"" . $arrayTask["TAS_UID"] . "\", + " . ((int)($arrayTask["TAS_POSX"])) . ", + " . ((int)($arrayTask["TAS_POSY"])) . ", + " . ((int)($arrayTask["TAS_WIDTH"])) . ", + " . ((int)($arrayTask["TAS_HEIGHT"])) . " + "; + } else { + $flagEventEnd = true; + + $objectBpmnType = "bpmnActivity"; + $objectUid = $activityUid; + $objectBouX = $activityBouX; + $objectBouY = $activityBouY; + $objectBouWidth = $activityBouWidth; + $objectBouHeight = $activityBouHeight; + } + break; + case "SEC-JOIN": + $arrayWorkflowDataRouteSecJoin[] = $arrayRoute; + break; + } + + if ($flagFlow) { + eval("\$arrayFlow = \$this->generateBpmnDataFlow(\"$projectUid\", \"$bpmnProcessUid\", $strFlowParams);"); + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + } + + if ($flagEventEnd) { + $eventEndCount = $eventEndCount + 1; + + list($arrayEvent, $arrayFlow) = $this->generateBpmnDataEvent( + $projectUid, + $bpmnProcessUid, + $objectBpmnType, + $objectUid, + $objectBouX, + $objectBouY, + $objectBouWidth, + $objectBouHeight, + "END", + $eventEndCount + ); + + //Event - END + $arrayBpmnData["event"][] = $arrayEvent; + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + } + } + + //ROU_TYPE = SEC-JOIN + $arrayGatewayConvergingData = array(); + + foreach ($arrayWorkflowDataRouteSecJoin as $value) { + $arrayRoute = $value; + + $arrayTask = $arrayTaskData[$arrayRoute["TAS_UID"]]; + + $activityUid = $arrayTask["TAS_UID"]; + $activityBouX = (int)($arrayTask["TAS_POSX"]); + $activityBouY = (int)($arrayTask["TAS_POSY"]); + $activityBouWidth = (int)($arrayTask["TAS_WIDTH"]); + $activityBouHeight = (int)($arrayTask["TAS_HEIGHT"]); + + $arrayTask = $arrayTaskData[$arrayRoute["ROU_NEXT_TASK"]]; + + $nextActivityUid = $arrayTask["TAS_UID"]; + $nextActivityBouX = (int)($arrayTask["TAS_POSX"]); + $nextActivityBouY = (int)($arrayTask["TAS_POSY"]); + $nextActivityBouWidth = (int)($arrayTask["TAS_WIDTH"]); + $nextActivityBouHeight = (int)($arrayTask["TAS_HEIGHT"]); + + if (!isset($arrayGatewayConvergingData[$nextActivityUid])) { + $gatewayParentType = $arrayGatewayDivergingNextActivityData[$activityUid][1]; + + $arrayGatewayInfo[$arrayGatewayInfoR[$gatewayParentType]]["count"] = $arrayGatewayInfo[$arrayGatewayInfoR[$gatewayParentType]]["count"] + 1; + + list($arrayGateway, $arrayFlow) = $this->generateBpmnDataGateway( + $projectUid, + $bpmnProcessUid, + "bpmnActivity", + $nextActivityUid, + $nextActivityBouX, + $nextActivityBouY, + $nextActivityBouWidth, + $nextActivityBouHeight, + $arrayGatewayInfo[$arrayGatewayInfoR[$gatewayParentType]]["type"], + //\G::LoadTranslation($arrayGatewayInfo[$arrayGatewayInfoR[$gatewayParentType]]["translationUid"], array($arrayGatewayInfo[$arrayGatewayInfoR[$gatewayParentType]]["count"])), + "", + "CONVERGING" + ); + + //Gateway + $arrayBpmnData["gateway"][] = $arrayGateway; + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + + //Gateway CONVERGING + $arrayGatewayConvergingData[$nextActivityUid] = array( + $arrayGateway["gat_uid"], + $arrayGateway["gat_type"], + $arrayGateway["bou_x"], + $arrayGateway["bou_y"], + $arrayGateway["bou_width"], + $arrayGateway["bou_height"], + ); + } + + $gatewayUid = $arrayGatewayConvergingData[$nextActivityUid][0]; + $gatewayType = $arrayGatewayConvergingData[$nextActivityUid][1]; + $gatewayBouX = $arrayGatewayConvergingData[$nextActivityUid][2]; + $gatewayBouY = $arrayGatewayConvergingData[$nextActivityUid][3]; + $gatewayBouWidth = $arrayGatewayConvergingData[$nextActivityUid][4]; + $gatewayBouHeight = $arrayGatewayConvergingData[$nextActivityUid][5]; + + $arrayFlow = $this->generateBpmnDataFlow( + $projectUid, + $bpmnProcessUid, + "bpmnActivity", + $activityUid, + $activityBouX, + $activityBouY, + $activityBouWidth, + $activityBouHeight, + "bpmnGateway", + $gatewayUid, + $gatewayBouX, + $gatewayBouY, + $gatewayBouWidth, + $gatewayBouHeight + ); + + //Flow + $arrayBpmnData["flow"][] = $arrayFlow; + } + + $arrayBpmnData["artifact"] = array(); //Artifact + + foreach ($arrayWorkflowData["lanes"] as $value) { + $arrayLane = $value; + + //Artifact + $artifactUid = \ProcessMaker\Util\Common::generateUID(); + $artifactBouX = (int)($arrayLane["SWI_X"]); + $artifactBouY = (int)($arrayLane["SWI_Y"]); + + $artifactType = ($arrayLane["SWI_TYPE"] == "TEXT")? "TEXT_ANNOTATION" : (($artifactBouX == 0)? "HORIZONTAL_LINE" : "VERTICAL_LINE"); + $artifactName = ($artifactType == "TEXT_ANNOTATION")? $arrayLane["SWI_TEXT"] : ""; + $artifactBouX = ($artifactType == "TEXT_ANNOTATION")? $artifactBouX : (($artifactType == "HORIZONTAL_LINE")? -6666 : $artifactBouX); + $artifactBouY = ($artifactType == "TEXT_ANNOTATION")? $artifactBouY : (($artifactType == "HORIZONTAL_LINE")? $artifactBouY : -6666); + $artifactBouWidth = ($artifactType == "TEXT_ANNOTATION")? 100 : 0; + $artifactBouHeight = ($artifactType == "TEXT_ANNOTATION")? 30 : 0; + + $arrayBpmnData["artifact"][] = array( + "art_uid" => $artifactUid, + "prj_uid" => $projectUid, + "pro_uid" => $bpmnProcessUid, + "art_type" => $artifactType, + "art_name" => $artifactName, + "bou_x" => $artifactBouX, + "bou_y" => $artifactBouY, + "bou_width" => $artifactBouWidth, + "bou_height" => $artifactBouHeight + ); + } + + //Set data + $arrayData["tables"]["bpmn"] = $arrayBpmnData; + $arrayData["tables"]["workflow"] = $arrayWorkflowData; + + $arrayData["files"]["bpmn"] = array(); + $arrayData["files"]["workflow"] = array_change_key_case($arrayWorkflowFile, CASE_LOWER); + + //Return + return $arrayData; + } catch (\Exception $e) { + throw $e; + } + } + + public function generateBpmn($processUid, $fieldNameForException) + { + try { + //Verify data + $obj = \ProcessPeer::retrieveByPK($processUid); + + if (is_null($obj)) { + throw new \Exception(\G::LoadTranslation("ID_PROCESS_DOES_NOT_EXIST", array($fieldNameForException, $processUid))); + } + + //Verify data + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\BpmnProjectPeer::PRJ_UID); + $criteria->add(\BpmnProjectPeer::PRJ_UID, $processUid, \Criteria::EQUAL); + + $rsCriteria = \BpmnProjectPeer::doSelectRS($criteria); + + if ($rsCriteria->next()) { + throw new \Exception(\G::LoadTranslation("ID_PROJECT_IS_BPMN", array($fieldNameForException, $processUid))); + } + + //Get data + $arrayBpmnData = $this->generateBpmnData($processUid); + + $processTitle = $arrayBpmnData["tables"]["workflow"]["process"][0]["PRO_TITLE"] . " - New version - " . date("M d, H:i:s"); + + $arrayBpmnData["tables"]["bpmn"]["project"][0]["prj_name"] = $processTitle; + $arrayBpmnData["tables"]["bpmn"]["diagram"][0]["dia_name"] = $processTitle; + $arrayBpmnData["tables"]["bpmn"]["process"][0]["pro_name"] = $processTitle; + + $arrayBpmnData["tables"]["workflow"]["process"][0]["PRO_PARENT"] = $processUid; + $arrayBpmnData["tables"]["workflow"]["process"][0]["PRO_TITLE"] = $processTitle; + + //Generate + $importer = new \ProcessMaker\Importer\XmlImporter(); + $importer->setImportData($arrayBpmnData); + + $projectUid = $importer->import(\ProcessMaker\Importer\XmlImporter::IMPORT_OPTION_WORKFLOW_TO_BPMN_GENERATE); + + //Return + return $projectUid; + } catch (\Exception $e) { + throw $e; + } + } +} + diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index 394d50a7a..1582c07da 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -714,7 +714,11 @@ class Bpmn extends Handler public function addArtifact($data) { // setting defaults + $processUid = $this->getProcess("object")->getProUid(); + $data['ART_UID'] = array_key_exists('ART_UID', $data) ? $data['ART_UID'] : Common::generateUID(); + $data["PRO_UID"] = $processUid; + try { self::log("Add Artifact with data: ", $data); $artifact = new Artifact(); @@ -796,7 +800,11 @@ class Bpmn extends Handler public function addData($data) { // setting defaults + $processUid = $this->getProcess("object")->getProUid(); + $data['DATA_UID'] = array_key_exists('DAT_UID', $data) ? $data['DAT_UID'] : Common::generateUID(); + $data["PRO_UID"] = $processUid; + try { self::log("Add BpmnData with data: ", $data); $bpmnData = new \BpmnData(); @@ -878,7 +886,11 @@ class Bpmn extends Handler public function addParticipant($data) { // setting defaults + $processUid = $this->getProcess("object")->getProUid(); + $data['PAR_UID'] = array_key_exists('PAR_UID', $data) ? $data['PAR_UID'] : Common::generateUID(); + $data["PRO_UID"] = $processUid; + try { self::log("Add Participant with data: ", $data); $participant = new Participant(); diff --git a/workflow/engine/src/ProcessMaker/Project/Workflow.php b/workflow/engine/src/ProcessMaker/Project/Workflow.php index 5bf0ac6df..141919c73 100644 --- a/workflow/engine/src/ProcessMaker/Project/Workflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Workflow.php @@ -911,5 +911,74 @@ class Workflow extends Handler } } + + public function getData($processUid) + { + try { + $process = new \Processes(); + + //Get data + $workflowData = (array)($process->getWorkflowData($processUid)); + $workflowData["process"]["PRO_DYNAFORMS"] = (empty($workflowData["process"]["PRO_DYNAFORMS"]))? "" : serialize($workflowData["process"]["PRO_DYNAFORMS"]); + + $workflowData["process"] = array($workflowData["process"]); + $workflowData["processCategory"] = (empty($workflowData["processCategory"]))? array() : array($workflowData["processCategory"]); + + //Get files + $workflowFile = array(); + + //Getting DynaForms + foreach ($workflowData["dynaforms"] as $dynaform) { + $dynFile = PATH_DYNAFORM . $dynaform["DYN_FILENAME"] . ".xml"; + + $workflowFile["DYNAFORMS"][] = array( + "filename" => $dynaform["DYN_TITLE"], + "filepath" => $dynaform["DYN_FILENAME"] . ".xml", + "file_content" => file_get_contents($dynFile) + ); + + $htmlFile = PATH_DYNAFORM . $dynaform["DYN_FILENAME"] . ".html"; + + if (file_exists($htmlFile)) { + $workflowFile["DYNAFORMS"][] = array( + "filename" => $dynaform["DYN_FILENAME"] . ".html", + "filepath" => $dynaform["DYN_FILENAME"] . ".html", + "file_content" => file_get_contents($htmlFile) + ); + } + } + + //Getting templates files + $workspaceTargetDirs = array("TEMPLATES" => "mailTemplates", "PUBLIC" => "public"); + $workspaceDir = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP; + + foreach ($workspaceTargetDirs as $target => $workspaceTargetDir) { + $templatesDir = $workspaceDir . $workspaceTargetDir . PATH_SEP . $processUid; + $templatesFiles = Util\Common::rglob("$templatesDir/*", 0, true); + + foreach ($templatesFiles as $templatesFile) { + if (is_dir($templatesFile)) { + continue; + } + + $filename = basename($templatesFile); + + $workflowFile[$target][] = array( + "filename" => $filename, + "filepath" => $processUid . PATH_SEP . $filename, + "file_content" => file_get_contents($templatesFile) + ); + } + } + + //Return + self::log("Getting Workflow data Success!"); + + return array($workflowData, $workflowFile); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } } diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Project.php b/workflow/engine/src/ProcessMaker/Services/Api/Project.php index 893d5e909..3470ad1f0 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/Project.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/Project.php @@ -193,6 +193,30 @@ class Project extends Api } } + /** + * @url POST /process/:pro_uid/generate-bpmn + * + * @param string $pro_uid {@min 32}{@max 32} + * + * @status 201 + */ + public function doPostProcessGenerateBpmn($pro_uid) + { + try { + $workflowBpmn = new \ProcessMaker\Project\Adapter\WorkflowBpmn(); + + $projectUid = $workflowBpmn->generateBpmn($pro_uid, "pro_uid"); + + $arrayData = array_change_key_case(array("PRJ_UID" => $projectUid), CASE_LOWER); + + $response = $arrayData; + + return $response; + } catch (\Exception $e) { + throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); + } + } + /** * @url GET /:prj_uid/dynaforms * diff --git a/workflow/engine/templates/oauth2/accessTokenSetup.js b/workflow/engine/templates/oauth2/accessTokenSetup.js index 2f5a95c40..25f25a995 100644 --- a/workflow/engine/templates/oauth2/accessTokenSetup.js +++ b/workflow/engine/templates/oauth2/accessTokenSetup.js @@ -342,7 +342,7 @@ accessTokenSetup.application = { sm.selectRow(rowIndex, true); var record = grdpnlMain.getSelectionModel().getSelected(); - console.log(record); + if (typeof(record) != "undefined") { Ext.MessageBox.confirm( _("ID_CONFIRM"), diff --git a/workflow/engine/templates/processes/main.js b/workflow/engine/templates/processes/main.js index 988a06a1c..991f376db 100755 --- a/workflow/engine/templates/processes/main.js +++ b/workflow/engine/templates/processes/main.js @@ -394,11 +394,10 @@ Ext.onReady(function(){ } if (rowSelected.data.PROJECT_TYPE == "bpmn"){ - Ext.getCmp('edit_with_classic_editor').setDisabled(false); + Ext.getCmp("mnuGenerateBpmn").setDisabled(true); } else { - Ext.getCmp('edit_with_classic_editor').setDisabled(true); + Ext.getCmp("mnuGenerateBpmn").setDisabled(false); } - }, this); processesGrid.on('contextmenu', function (evt) { evt.preventDefault(); @@ -435,6 +434,15 @@ Ext.onReady(function(){ handler: function () { exportProcess(); } + }, + { + id: "mnuGenerateBpmn", + text: _("ID_GENERATE_BPMN_PROJECT"), + iconCls: "button_menu_ext ss_sprite ss_page_white_go", + handler: function () + { + generateBpmn(); + } } ] }); @@ -584,7 +592,7 @@ editProcess = function(typeParam) var rowSelected = processesGrid.getSelectionModel().getSelected(); if (!rowSelected) { Ext.Msg.show({ - title: '', + title: _("ID_INFORMATION"), msg: _('ID_NO_SELECTION_WARNING'), buttons: Ext.Msg.INFO, fn: function () { @@ -617,7 +625,7 @@ editNewProcess = function(){ location.href = '../designer?pro_uid='+rowSelected.data.PRO_UID } else { Ext.Msg.show({ - title:'', + title: _("ID_INFORMATION"), msg: _('ID_NO_SELECTION_WARNING'), buttons: Ext.Msg.INFO, fn: function(){}, @@ -701,7 +709,7 @@ deleteProcess = function(){ } } else { Ext.Msg.show({ - title:'', + title: _("ID_INFORMATION"), msg: _('ID_NO_SELECTION_WARNING'), buttons: Ext.Msg.INFO, fn: function(){}, @@ -743,7 +751,7 @@ function exportProcess() { } else { Ext.Msg.show({ - title: "", + title: _("ID_INFORMATION"), msg: _("ID_NO_SELECTION_WARNING"), icon: Ext.MessageBox.INFO, buttons: Ext.MessageBox.OK @@ -751,6 +759,60 @@ function exportProcess() { } } +function generateBpmn() +{ + var record = processesGrid.getSelectionModel().getSelections(); + + if (typeof(record) != "undefined") { + if (record.length == 1) { + var loadMaskGenerateBpmn = new Ext.LoadMask(Ext.getBody(), {msg: _("ID_PROCESSING")}); + var processUid = record[0].get("PRO_UID"); + + loadMaskGenerateBpmn.show(); + + Ext.Ajax.request({ + url: "../processProxy/generateBpmn", + method: "POST", + params: { + processUid: processUid + }, + + success: function (response, opts) + { + var dataResponse = Ext.util.JSON.decode(response.responseText); + + if (dataResponse.status) { + if (dataResponse.status == "OK") { + //processesGrid.store.reload(); + location.assign("../designer?prj_uid=" + dataResponse.projectUid); + } else { + Ext.MessageBox.show({ + title: _("ID_ERROR"), + icon: Ext.MessageBox.ERROR, + buttons: Ext.MessageBox.OK, + msg: dataResponse.message + }); + } + } + + loadMaskGenerateBpmn.hide(); + }, + failure: function (response, opts) + { + loadMaskGenerateBpmn.hide(); + } + }); + } else { + Ext.MessageBox.show({ + title: _("ID_INFORMATION"), + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK, + msg: _("ID_NO_SELECTION_WARNING") + }); + } + } +} + importProcessExistGroup = function() { @@ -1191,7 +1253,7 @@ function activeDeactive(){ }); } else { Ext.Msg.show({ - title:'', + title: _("ID_INFORMATION"), msg: _('ID_NO_SELECTION_WARNING'), buttons: Ext.Msg.INFO, fn: function(){}, @@ -1227,7 +1289,7 @@ function enableDisableDebug() }); } else { Ext.Msg.show({ - title:'', + title: _("ID_INFORMATION"), msg: _('ID_NO_SELECTION_WARNING'), buttons: Ext.Msg.INFO, fn: function(){},