diff --git a/workflow/engine/methods/processes/processes_Import_Ajax.php b/workflow/engine/methods/processes/processes_Import_Ajax.php index 010785d32..c7908fff7 100644 --- a/workflow/engine/methods/processes/processes_Import_Ajax.php +++ b/workflow/engine/methods/processes/processes_Import_Ajax.php @@ -23,22 +23,36 @@ */ ini_set( 'max_execution_time', '0' ); - $ext = pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION); if ($ext == "pmx") { $importer = new \ProcessMaker\Importer\XmlImporter(); $importer->setSourceFromGlobals("PROCESS_FILENAME"); - $data = array("usr_uid" => $_SESSION['USER_LOGGED']); - $res = $importer->import($data); - $result = array( - "success" => true, - "catchMessage" => "", - "ExistProcessInDatabase" => 0, - "ExistGroupsInDatabase" => 0, - "sNewProUid" => $res[0]["new_uid"], - "project_type" => "bpmn" - ); + $importer->setData("usr_uid", $_SESSION['USER_LOGGED']); + + try { + $res = $importer->import(); + + $result = array( + "success" => true, + "catchMessage" => "", + "ExistProcessInDatabase" => 0, + "ExistGroupsInDatabase" => 0, + "sNewProUid" => $res[0]["new_uid"], + "project_type" => "bpmn" + ); + } catch (Exception $e) { + $result = array( + "success" => true, + "catchMessage" => "", //$e->getMessage(), + "ExistProcessInDatabase" => 1, + "ExistGroupsInDatabase" => 0, + "groupBeforeAccion" => "uploadFileNewProcess", + "sNewProUid" => "63626727053359dabb8fee8019503780", + "proFileName" => $_FILES['PROCESS_FILENAME']['name'], + "project_type" => "bpmn" + ); + } echo json_encode($result); exit(0); diff --git a/workflow/engine/src/ProcessMaker/Importer/Importer.php b/workflow/engine/src/ProcessMaker/Importer/Importer.php index c1f2327b8..a1475c6d0 100644 --- a/workflow/engine/src/ProcessMaker/Importer/Importer.php +++ b/workflow/engine/src/ProcessMaker/Importer/Importer.php @@ -1,8 +1,13 @@ prepare(); + switch ($option) { case self::IMPORT_OPTION_CREATE_NEW: - $this->prepare(); - $this->createNewProject(); + $result = $this->doImport(); break; case self::IMPORT_OPTION_DISABLE_AND_CREATE_NEW: break; case self::IMPORT_OPTION_OVERWRITE: break; } + + return $result; + } + + /** + * Prepare for import, it makes all validations needed + * @return int + * @throws \Exception + */ + public function prepare() + { + if ($this->validateSource() === false) { + throw new \Exception( + "Error, Invalid file type or the file have corrupt data", + self::IMPORT_STAT_INVALID_SOURCE_FILE + ); + } + + $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) + { + $this->data[$key] = $value; } /** @@ -47,18 +88,29 @@ abstract class Importer return true; } + public function validateImportData() + { + if (! isset($this->importData["tables"]["bpmn"])) { + throw new \Exception("BPMN Definition is missing."); + } + if (! isset($this->importData["tables"]["bpmn"]["project"]) || count($this->importData["tables"]["bpmn"]["project"]) !== 1) { + throw new \Exception("BPMN table: \"Project\", definition is missing or has multiple definition."); + } + + return true; + } + /** * Verify if the project already exists * @return mixed */ public function targetExists() { - return false; - } + $prjUid = $this->importData["tables"]["bpmn"]["project"][0]["prj_uid"]; - public function createNewProject() - { + $bpmnProject = \BpmnProjectPeer::retrieveByPK($prjUid); + return is_object($bpmnProject); } public function updateProject() @@ -109,15 +161,6 @@ abstract class Importer */ public function setSourceFromGlobals($varName) { - /*[PROCESS_FILENAME] => Array - ( - [name] => sample29.pm - [type] => application/pm - [tmp_name] => /tmp/phpvHpCVO - [error] => 0 - [size] => 1260881 - )*/ - if (! array_key_exists($varName, $_FILES)) { throw new \Exception("Couldn't find specified source \"$varName\" in PHP Globals"); } @@ -136,28 +179,75 @@ abstract class Importer umask($oldUmask); } - /** - * Prepare for import, it makes all validations needed - * @return int - * @throws \Exception - */ - public function prepare() + protected function importBpmnTables(array $tables) { - if ($this->validateSource() === false) { - throw new \Exception( - "Error, Invalid file type or the file have corrupt data", - self::IMPORT_STAT_INVALID_SOURCE_FILE - ); - } + // Build BPMN project struct + $project = $tables["project"][0]; + $diagram = $tables["diagram"][0]; + $diagram["activities"] = $tables["activity"]; + $diagram["artifacts"] = array(); + $diagram["events"] = $tables["event"]; + $diagram["flows"] = $tables["flow"]; + $diagram["gateways"] = $tables["gateway"]; + $diagram["lanes"] = array(); + $diagram["laneset"] = array(); + $project["diagrams"] = array($diagram); + $project["prj_author"] = isset($this->data["usr_uid"])? $this->data["usr_uid"]: "00000000000000000000000000000001"; + $project["process"] = $tables["process"][0]; - 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); - } + return Adapter\BpmnWorkflow::createFromStruct($project); + } - return self::IMPORT_STAT_SUCCESS; + protected function importWfTables(array $tables) + { + $tables = (object) $tables; + + $processes = new \Processes(); + $processes->createProcessPropertiesFromData($tables); + } + + protected function importWfFiles(array $workflowFiles) + { + foreach ($workflowFiles as $target => $files) { + switch ($target) { + case "dynaforms": + $basePath = PATH_DYNAFORM; + break; + case "public": + $basePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP; + break; + case "templates": + $basePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "mailTemplates" . PATH_SEP; + break; + default: + $basePath = ""; + } + + if (empty($basePath)) continue; + + foreach ($files as $file) { + $filename = $basePath . $file["file_path"]; + $path = dirname($filename); + + if (! is_dir($path)) { + Util\Common::mk_dir($path, 0775); + } + + file_put_contents($filename, $file["file_content"]); + chmod($filename, 0775); + } + } + } + + public function doImport() + { + $tables = $this->importData["tables"]; + $files = $this->importData["files"]; + + $result = $this->importBpmnTables($tables["bpmn"]); + $this->importWfTables($tables["workflow"]); + $this->importWfFiles($files["workflow"]); + + 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 deab8ee90..af9fc9670 100644 --- a/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php +++ b/workflow/engine/src/ProcessMaker/Importer/XmlImporter.php @@ -1,9 +1,6 @@ dom = new \DOMDocument(); } - public function setSourceFile($filename) - { - $this->filename = $filename; - } - + /** + * @return array + * Example: + * array( + * "tables" => array("bpmn" => array(), "workflow" => array()) + * "files" => array("bpmn" => array(), "workflow" => array()) + * ) + * @throws \Exception + */ public function load() { $this->dom->load($this->filename); @@ -36,13 +38,13 @@ class XmlImporter extends Importer } // read metadata section - $metadata = $this->root->getElementsByTagName("metadata"); + $metadataNode = $this->root->getElementsByTagName("metadata"); - if ($metadata->length != 1) { + if ($metadataNode->length != 1) { throw new \Exception("Invalid Document format, metadata section is missing or has multiple definition."); } - $metadata = $metadata->item(0); + $this->metadata = $metadataNode->item(0); // load project definition /** @var \DOMElement[]|\DomNodeList $definitions */ @@ -57,7 +59,7 @@ class XmlImporter extends Importer $tables = array(); foreach ($definitions as $definition) { - $defClass = strtoupper($definition->getAttribute("class")); + $defClass = strtolower($definition->getAttribute("class")); $tables[$defClass] = array(); // getting tables def @@ -66,7 +68,7 @@ class XmlImporter extends Importer $tablesNodeList = $definition->getElementsByTagName("table"); foreach ($tablesNodeList as $tableNode) { - $tableName = $tableNode->getAttribute("name"); //strtoupper($tableNode->getAttribute("name")); + $tableName = strtolower($tableNode->getAttribute("name")); $tables[$defClass][$tableName] = array(); /** @var \DOMElement[] $recordsNodeList */ $recordsNodeList = $tableNode->getElementsByTagName("record"); @@ -80,9 +82,9 @@ class XmlImporter extends Importer foreach ($recordsNode->childNodes as $columnNode) { if ($columnNode->nodeName == "#text") continue; - //$columns[strtoupper($columnNode->nodeName)] = self::createTextNode($columnNode);; - $columnName = $defClass == "WORKFLOW" ? strtoupper($columnNode->nodeName) : $columnNode->nodeName; - $columns[$columnName] = self::createTextNode($columnNode); + //$columns[strtoupper($columnNode->nodeName)] = self::getTextNode($columnNode);; + $columnName = $defClass == "workflow" ? strtoupper($columnNode->nodeName) : $columnNode->nodeName; + $columns[$columnName] = self::getTextNode($columnNode); } $tables[$defClass][$tableName][] = $columns; @@ -97,54 +99,28 @@ class XmlImporter extends Importer $filesNodeList = $wfFilesNodeList->item(0)->getElementsByTagName("file"); foreach ($filesNodeList as $fileNode) { - $target = $fileNode->getAttribute("target"); + $target = strtolower($fileNode->getAttribute("target")); if (! isset($wfFiles[$target])) { $wfFiles[$target] = array(); } - $fileContent = self::createTextNode($fileNode->getElementsByTagName("file_content")->item(0)); - $fileContent = base64_decode($fileContent); - + $fileContent = self::getTextNode($fileNode->getElementsByTagName("file_content")->item(0)); $wfFiles[$target][] = array( - "file_name" => self::createTextNode($fileNode->getElementsByTagName("file_name")->item(0)), - "file_path" => self::createTextNode($fileNode->getElementsByTagName("file_path")->item(0)), - "file_content" => $fileContent + "file_name" => self::getTextNode($fileNode->getElementsByTagName("file_name")->item(0)), + "file_path" => self::getTextNode($fileNode->getElementsByTagName("file_path")->item(0)), + "file_content" => base64_decode($fileContent) ); } } - //print_r($tables); - //print_r($wfFiles); - return array($tables, $wfFiles); + return array( + "tables" => $tables, + "files" => array("workflow" => $wfFiles, "bpmn" => array()) + ); } - public function import($data = array()) - { - list($tables, $files) = $this->load(); - - // Build BPMN project struct - $project = $tables["BPMN"]["PROJECT"][0]; - $diagram = $tables["BPMN"]["DIAGRAM"][0]; - $diagram["activities"] = $tables["BPMN"]["ACTIVITY"]; - $diagram["artifacts"] = array(); - $diagram["events"] = $tables["BPMN"]["EVENT"]; - $diagram["flows"] = $tables["BPMN"]["FLOW"]; - $diagram["gateways"] = $tables["BPMN"]["GATEWAY"]; - $diagram["lanes"] = array(); - $diagram["laneset"] = array(); - $project["diagrams"] = array($diagram); - $project["prj_author"] = isset($data["usr_uid"])? $data["usr_uid"]: "00000000000000000000000000000001"; - $project["process"] = $tables["BPMN"]["PROCESS"][0]; - $result = Adapter\BpmnWorkflow::createFromStruct($project); - - $this->importWfTables($tables["WORKFLOW"]); - $this->importWfFiles($files); - - return $result; - } - - private static function createTextNode($node) + private static function getTextNode($node) { if ($node->nodeType == XML_ELEMENT_NODE) { return $node->textContent; @@ -152,42 +128,4 @@ class XmlImporter extends Importer return (string) simplexml_import_dom($node->parentNode); } } - - private static function importWfFiles(array $workflowFiles) - { - foreach ($workflowFiles as $target => $files) { - switch ($target) { - case "dynaforms": $basePath = PATH_DYNAFORM; break; - case "public": - $basePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP; - break; - case "templates": - $basePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "mailTemplates" . PATH_SEP; - break; - default: $basePath = ""; - } - - if (empty($basePath)) continue; - - foreach ($files as $file) { - $filename = $basePath . $file["file_path"]; - $path = dirname($filename); - - if (! is_dir($path)) { - Util\Common::mk_dir($path, 0775); - } - - file_put_contents($filename, $file["file_content"]); - chmod($filename, 0775); - } - } - } - - public function importWfTables($tables) - { - $tables = (object) $tables; - - $processes = new \Processes(); - $processes->createProcessPropertiesFromData($tables); - } } \ No newline at end of file diff --git a/workflow/engine/src/Services/Api/ProcessMaker/Project.php b/workflow/engine/src/Services/Api/ProcessMaker/Project.php index ed9e38505..aa6733106 100644 --- a/workflow/engine/src/Services/Api/ProcessMaker/Project.php +++ b/workflow/engine/src/Services/Api/ProcessMaker/Project.php @@ -73,6 +73,29 @@ class Project extends Api } } + /** + * @url GET /:prj_uid/export + * + * @param string $prj_uid {@min 32}{@max 32} + */ + public function export($prj_uid) + { + $exporter = new \ProcessMaker\Exporter\XmlExporter($prj_uid); + + $outputDir = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "files" . PATH_SEP . "output" . PATH_SEP; + $version = \ProcessMaker\Util\Common::getLastVersion($outputDir . $exporter->getProjectName() . "-*.pmx") + 1; + $outputFilename = $outputDir . sprintf("%s-%s.%s", $exporter->getProjectName(), $version, "pmx"); + + $exporter->saveExport($outputFilename); + + $httpStream = new \ProcessMaker\Util\IO\HttpStream(); + $fileExtension = pathinfo($outputFilename, PATHINFO_EXTENSION); + + $httpStream->loadFromFile($outputFilename); + $httpStream->setHeader("Content-Type", "application/$fileExtension"); + $httpStream->send(); + } + /** * @url GET /:prj_uid/process *