diff --git a/workflow/engine/methods/processes/processes_Import_Ajax.php b/workflow/engine/methods/processes/processes_Import_Ajax.php index e2f7eedad..9ca48d0a1 100644 --- a/workflow/engine/methods/processes/processes_Import_Ajax.php +++ b/workflow/engine/methods/processes/processes_Import_Ajax.php @@ -28,18 +28,19 @@ if (isset($_FILES["PROCESS_FILENAME"])) { if ($ext == "pmx") { $importer = new \ProcessMaker\Importer\XmlImporter(); - $importer->setSourceFromGlobals("PROCESS_FILENAME"); $importer->setData("usr_uid", $_SESSION['USER_LOGGED']); + $importer->setSaveDir(PATH_DOCUMENT . 'input'); + $importer->setSourceFromGlobals("PROCESS_FILENAME"); try { - $res = $importer->import(); + $prjUid = $importer->import(); $result = array( "success" => true, "catchMessage" => "", "ExistProcessInDatabase" => 0, "ExistGroupsInDatabase" => 0, - "sNewProUid" => $res[0]["new_uid"], + "sNewProUid" => $prjUid, "project_type" => "bpmn" ); } catch (Exception $e) { @@ -58,8 +59,25 @@ if (isset($_FILES["PROCESS_FILENAME"])) { echo json_encode($result); exit(0); } -} +} elseif (isset($_POST["PRO_FILENAME"]) && file_exists(PATH_DOCUMENT . 'input' . PATH_SEP . $_POST["PRO_FILENAME"])) { + switch ($_POST["IMPORT_OPTION"]) { + case 1: $option = ProcessMaker\Importer\XmlImporter::IMPORT_OPTION_OVERWRITE; break; + case 2: $option = ProcessMaker\Importer\XmlImporter::IMPORT_OPTION_DISABLE_AND_CREATE_NEW; break; + case 3: $option = ProcessMaker\Importer\XmlImporter::IMPORT_OPTION_CREATE_NEW; break; + } + + $importer = new ProcessMaker\Importer\XmlImporter(); + $importer->setData("usr_uid", $_SESSION['USER_LOGGED']); + $importer->setSourceFile(PATH_DOCUMENT . 'input' . PATH_SEP . $_POST["PRO_FILENAME"]); + + try { + $res = $importer->import($option); + } catch (\Exception $e) { + die($e->getMessage()); + } +} +die; function reservedWordsSqlValidate ($data) { $arrayAux = array (); diff --git a/workflow/engine/src/ProcessMaker/Exporter/Exporter.php b/workflow/engine/src/ProcessMaker/Exporter/Exporter.php index c7f59881d..4472a4104 100644 --- a/workflow/engine/src/ProcessMaker/Exporter/Exporter.php +++ b/workflow/engine/src/ProcessMaker/Exporter/Exporter.php @@ -58,6 +58,11 @@ abstract class Exporter return $this->projectData["PRJ_NAME"]; } + public function getProjectUid() + { + return $this->projectData["PRJ_UID"]; + } + /** * Builds Project Data Structure * @@ -68,7 +73,8 @@ abstract class Exporter $data = array(); $data["metadata"] = $this->getMetadata(); - $data["metadata"]["project_name"] = $this->getProjectName(); + $data["metadata"]["name"] = $this->getProjectName(); + $data["metadata"]["uid"] = $this->getProjectUid(); $bpmnStruct["ACTIVITY"] = \BpmnActivity::getAll($this->prjUid); $bpmnStruct["BOUND"] = \BpmnBound::getAll($this->prjUid); @@ -175,7 +181,7 @@ abstract class Exporter "export_server_addr" => isset($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"].":".$_SERVER["SERVER_PORT"] : "Unknown", "export_server_os" => PHP_OS , "export_server_php_version" => PHP_VERSION_ID, - "project_workspace" => defined("SYS_SYS") ? SYS_SYS : "Unknown", + "workspace" => defined("SYS_SYS") ? SYS_SYS : "Unknown", ); } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Importer/Importer.php b/workflow/engine/src/ProcessMaker/Importer/Importer.php index a1475c6d0..21e3d2814 100644 --- a/workflow/engine/src/ProcessMaker/Importer/Importer.php +++ b/workflow/engine/src/ProcessMaker/Importer/Importer.php @@ -10,10 +10,11 @@ abstract class Importer protected $importData = array(); protected $filename = ""; protected $saveDir = ""; + protected $metadata = array(); - const IMPORT_OPTION_OVERWRITE = "OVERWRITE_PROJECT"; - const IMPORT_OPTION_DISABLE_AND_CREATE_NEW = "DISABLE_AND_CREATE_NEW_PROJECT"; - const IMPORT_OPTION_CREATE_NEW = "CREATE_NEW_PROJECT"; + const IMPORT_OPTION_OVERWRITE = "project.import.override"; + const IMPORT_OPTION_DISABLE_AND_CREATE_NEW = "project.import.disable_and_create_new"; + const IMPORT_OPTION_CREATE_NEW = "project.import.create_new"; /** * Success, Project imported successfully. @@ -36,11 +37,27 @@ abstract class Importer switch ($option) { case self::IMPORT_OPTION_CREATE_NEW: - $result = $this->doImport(); + if ($this->targetExists()) { + throw new \Exception(sprintf( + "Project already exists, you need set an action to continue. " . + "Available actions: [%s|%s|%s].", self::IMPORT_OPTION_CREATE_NEW, + self::IMPORT_OPTION_OVERWRITE, self::IMPORT_OPTION_DISABLE_AND_CREATE_NEW + ), self::IMPORT_STAT_TARGET_ALREADY_EXISTS); + } + $generateUid = false; + $result = $this->doImport($generateUid); break; case self::IMPORT_OPTION_DISABLE_AND_CREATE_NEW: + $this->disableProject(); + // this option should generate new uid for all objects + $generateUid = true; + $result = $this->doImport($generateUid); break; case self::IMPORT_OPTION_OVERWRITE: + // this option shouldn't generate new uid for all objects + $generateUid = false; + $this->removeProject(); + $result = $this->doImport($generateUid); break; } @@ -64,14 +81,6 @@ abstract class Importer $this->importData = $this->load(); $this->validateImportData(); - - if ($this->targetExists()) { - throw new \Exception(sprintf( - "Project already exists, you need set an action to continue. " . - "Avaliable actions: [%s|%s|%s].", self::IMPORT_OPTION_CREATE_NEW, - self::IMPORT_OPTION_OVERWRITE, self::IMPORT_OPTION_DISABLE_AND_CREATE_NEW - ), self::IMPORT_STAT_TARGET_ALREADY_EXISTS); - } } public function setData($key, $value) @@ -118,9 +127,17 @@ abstract class Importer } - public function disableCurrentProject() + public function disableProject() { + $project = \ProcessMaker\Project\Adapter\BpmnWorkflow::load($this->metadata["uid"]); + $project->setDisabled(); + } + public function removeProject() + { + $project = \ProcessMaker\Project\Adapter\BpmnWorkflow::load($this->metadata["uid"]); + $force = true; + $project->remove($force); } /** @@ -179,7 +196,7 @@ abstract class Importer umask($oldUmask); } - protected function importBpmnTables(array $tables) + protected function importBpmnTables(array $tables, $generateUid = false) { // Build BPMN project struct $project = $tables["project"][0]; @@ -195,7 +212,7 @@ abstract class Importer $project["prj_author"] = isset($this->data["usr_uid"])? $this->data["usr_uid"]: "00000000000000000000000000000001"; $project["process"] = $tables["process"][0]; - return Adapter\BpmnWorkflow::createFromStruct($project); + return Adapter\BpmnWorkflow::createFromStruct($project, $generateUid); } protected function importWfTables(array $tables) @@ -239,15 +256,19 @@ abstract class Importer } } - public function doImport() + public function doImport($generateUid = true) { $tables = $this->importData["tables"]; $files = $this->importData["files"]; - $result = $this->importBpmnTables($tables["bpmn"]); + $result = $this->importBpmnTables($tables["bpmn"], $generateUid); $this->importWfTables($tables["workflow"]); $this->importWfFiles($files["workflow"]); - return $result; + if ($generateUid) { + return $result[0]["new_uid"]; + } else { + return $result; + } } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php b/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php index af9fc9670..30d1099f8 100644 --- a/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php +++ b/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php @@ -9,7 +9,6 @@ class XmlImporter extends Importer protected $dom; protected $root; protected $version = ""; - protected $metadata; public function __construct() { @@ -44,7 +43,16 @@ class XmlImporter extends Importer throw new \Exception("Invalid Document format, metadata section is missing or has multiple definition."); } - $this->metadata = $metadataNode->item(0); + $metadataNodeList = $metadataNode->item(0)->getElementsByTagName("meta"); + + if ($metadataNodeList->length == 0) { + throw new \Exception("Invalid Document format, metadata information is corrupt."); + } + + + foreach ($metadataNodeList as $metadataNode) { + $this->metadata[$metadataNode->getAttribute("key")] = $this->getTextNode($metadataNode); + } // load project definition /** @var \DOMElement[]|\DomNodeList $definitions */ diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index b5ca19702..e24791b94 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -413,42 +413,53 @@ class BpmnWorkflow extends Project\Bpmn $this->wp->remove(); } - public static function createFromStruct(array $projectData) + public static function createFromStruct(array $projectData, $generateUid = true) { $bwp = new self; $result = array(); + $data = array(); -// if (array_key_exists("prj_uid", $projectData)) { -// $result[0]["old_uid"] = $projectData["prj_uid"]; -// } else { -// $result[0]["old_uid"] = ""; -// } + if ($generateUid) { + $result[0]["old_uid"] = isset($projectData["prj_uid"]) ? $projectData["prj_uid"] : ""; + $projectData["prj_uid"] = Util\Common::generateUID(); + $result[0]["new_uid"] = $projectData["prj_uid"]; + $result[0]["object"] = "project"; + } - //$projectData["prj_uid"] = Util\Common::generateUID(); - $result[0]["new_uid"] = $projectData["prj_uid"]; - $result[0]["old_uid"] = ""; - $result[0]["object"] = "project"; + $data["PRJ_UID"] = $projectData["prj_uid"]; + $data["PRJ_AUTHOR"] = $projectData["prj_author"]; - $bwp->create(array( - "PRJ_UID" => $projectData["prj_uid"], - "PRJ_AUTHOR" => $projectData["prj_author"] - )); + $bwp->create($data); $diagramData = $processData = array(); if (array_key_exists("diagrams", $projectData) && is_array($projectData["diagrams"]) && count($projectData["diagrams"]) > 0) { $diagramData = array_change_key_case($projectData["diagrams"][0], CASE_UPPER); - } - if (array_key_exists("process", $projectData) && is_array($projectData["process"])) { - $processData = array_change_key_case($projectData["process"], CASE_UPPER); + if ($generateUid) { + $result[1]["old_uid"] = $diagramData["DIA_UID"]; + $diagramData["DIA_UID"] = Util\Common::generateUID(); + $result[1]["new_uid"] = $diagramData["DIA_UID"]; + $result[1]["object"] = "diagram"; + } } $bwp->addDiagram($diagramData); + + if (array_key_exists("process", $projectData) && is_array($projectData["process"])) { + $processData = array_change_key_case($projectData["process"], CASE_UPPER); + if ($generateUid) { + $result[2]["old_uid"] = $processData["PRO_UID"]; + $processData["PRO_UID"] = Util\Common::generateUID(); + $result[2]["new_uid"] = $processData["PRO_UID"]; + $result[2]["object"] = "process"; + } + } + $bwp->addProcess($processData); - $result = array_merge($result, self::updateFromStruct($bwp->prjUid, $projectData)); + $mappedUid = array_merge($result, self::updateFromStruct($bwp->prjUid, $projectData, $generateUid)); - return $result; + return $generateUid ? $mappedUid : $bwp->getUid(); } /** @@ -545,7 +556,7 @@ class BpmnWorkflow extends Project\Bpmn * @param $projectData * @return array */ - public static function updateFromStruct($prjUid, $projectData) + public static function updateFromStruct($prjUid, $projectData, $generateUid = true) { $diagram = isset($projectData["diagrams"]) && isset($projectData["diagrams"][0]) ? $projectData["diagrams"][0] : array(); $result = array(); @@ -564,10 +575,12 @@ class BpmnWorkflow extends Project\Bpmn $activity = $bwp->getActivity($activityData["ACT_UID"]); if (is_null($activity)) { - $oldActUid = $activityData["ACT_UID"]; - $activityData["ACT_UID"] = Util\Common::generateUID(); + if ($generateUid) { + $oldActUid = $activityData["ACT_UID"]; + $activityData["ACT_UID"] = Util\Common::generateUID(); + $result[] = array("object" => "activity", "new_uid" => $activityData["ACT_UID"], "old_uid" => $oldActUid); + } $bwp->addActivity($activityData); - $result[] = array("object" => "activity", "new_uid" => $activityData["ACT_UID"], "old_uid" => $oldActUid); } elseif (! $bwp->isEquals($activity, $activityData)) { $bwp->updateActivity($activityData["ACT_UID"], $activityData); } else { @@ -592,17 +605,19 @@ class BpmnWorkflow extends Project\Bpmn * Diagram's Gateways Handling */ $whiteList = array(); - //print_r($diagram); foreach ($diagram["gateways"] as $i => $gatewayData) { $gatewayData = array_change_key_case($gatewayData, CASE_UPPER); unset($gatewayData["_EXTENDED"]); $gateway = $bwp->getGateway($gatewayData["GAT_UID"]); if (is_null($gateway)) { - $oldActUid = $gatewayData["GAT_UID"]; - $gatewayData["GAT_UID"] = Util\Common::generateUID(); + if ($generateUid) { + $oldActUid = $gatewayData["GAT_UID"]; + $gatewayData["GAT_UID"] = Util\Common::generateUID(); + $result[] = array("object" => "gateway", "new_uid" => $gatewayData["GAT_UID"], "old_uid" => $oldActUid); + } + $bwp->addGateway($gatewayData); - $result[] = array("object" => "gateway", "new_uid" => $gatewayData["GAT_UID"], "old_uid" => $oldActUid); } elseif (! $bwp->isEquals($gateway, $gatewayData)) { $bwp->updateGateway($gatewayData["GAT_UID"], $gatewayData); } else { @@ -638,10 +653,13 @@ class BpmnWorkflow extends Project\Bpmn $event = $bwp->getEvent($eventData["EVN_UID"]); if (is_null($event)) { - $oldActUid = $eventData["EVN_UID"]; - $eventData["EVN_UID"] = Util\Common::generateUID(); + if ($generateUid) { + $oldActUid = $eventData["EVN_UID"]; + $eventData["EVN_UID"] = Util\Common::generateUID(); + $result[] = array("object" => "event", "new_uid" => $eventData["EVN_UID"], "old_uid" => $oldActUid); + } + $bwp->addEvent($eventData); - $result[] = array("object" => "event", "new_uid" => $eventData["EVN_UID"], "old_uid" => $oldActUid); } elseif (! $bwp->isEquals($event, $eventData)) { $bwp->updateEvent($eventData["EVN_UID"], $eventData); } else { @@ -672,9 +690,10 @@ class BpmnWorkflow extends Project\Bpmn $flowData = array_change_key_case($flowData, CASE_UPPER); // if it is a new flow record - if (! \BpmnFlow::exists($flowData["FLO_UID"])) { + if ($generateUid && ! \BpmnFlow::exists($flowData["FLO_UID"])) { $oldFloUid = $flowData["FLO_UID"]; $flowData["FLO_UID"] = Util\Common::generateUID(); + $result[] = array("object" => "flow", "new_uid" => $flowData["FLO_UID"], "old_uid" => $oldFloUid); $mappedUid = self::mapUid($flowData["FLO_ELEMENT_ORIGIN"], $result); if ($mappedUid !== false) { @@ -685,8 +704,6 @@ class BpmnWorkflow extends Project\Bpmn if ($mappedUid !== false) { $flowData["FLO_ELEMENT_DEST"] = $mappedUid; } - - $result[] = array("object" => "flow", "new_uid" => $flowData["FLO_UID"], "old_uid" => $oldFloUid); } $diagram["flows"][$i] = $flowData; @@ -728,4 +745,10 @@ class BpmnWorkflow extends Project\Bpmn return false; } + + public function setDisabled($value = true) + { + parent::setDisabled($value); + $this->wp->setDisabled($value); + } } diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index 07970a5a6..3c9f51e79 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -125,16 +125,22 @@ class Bpmn extends Handler $this->project->setPrjUpdateDate(date("Y-m-d H:i:s")); $this->project->save(); - $this->updateDiagram(array("DIA_NAME" => $data["PRJ_NAME"])); + if (isset($data["PRJ_NAME"])) { + $this->updateDiagram(array("DIA_NAME" => $data["PRJ_NAME"])); + } } - public function remove() + public function remove($force = false) { /* * 1. Remove Diagram related objects * 2. Remove Project related objects */ + if (! $force && ! $this->canRemove()) { + throw new \Exception("Project with prj_uid: {$this->getUid()} can not be deleted, it has started cases."); + } + self::log("Remove Project With Uid: {$this->prjUid}"); foreach ($this->getActivities() as $activity) { $this->removeActivity($activity["ACT_UID"]); @@ -201,6 +207,13 @@ class Bpmn extends Handler return $retType == "array" ? $this->project->toArray() : $this->project; } + public function canRemove() + { + // TODO this must validate if the project can be deleted or not. + // TODO the project can be deleted only if it has not any started cases + return true; + } + /* * Projects elements handlers */ @@ -730,4 +743,10 @@ class Bpmn extends Handler //self::log("checksum saved data: ", self::getChecksum($data), "checksum new data: ", self::getChecksum($newData)); return (self::getChecksum($data) !== self::getChecksum($newData)); } + + public function setDisabled($value = true) + { + $status = $value ? "DISABLED" : "ACTIVE"; + $this->update(array("PRJ_STATUS" => $status)); + } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Project/Workflow.php b/workflow/engine/src/ProcessMaker/Project/Workflow.php index e8d57847f..f8ac9275c 100644 --- a/workflow/engine/src/ProcessMaker/Project/Workflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Workflow.php @@ -98,6 +98,7 @@ class Workflow extends Handler public function update($data) { $process = new Process(); + $data["PRO_UID"] = $this->getUid(); $process->update($data); } @@ -765,4 +766,9 @@ class Workflow extends Handler } } + public function setDisabled($value = true) + { + $status = $value ? "DISABLED" : "ACTIVE"; + $this->update(array("PRO_STATUS" => $status)); + } } \ No newline at end of file