BPMN Import/Export Updates, adding url endpoint GET /project/{prj_uid}/export
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<?php
|
||||
namespace ProcessMaker\Importer;
|
||||
|
||||
use ProcessMaker\Util;
|
||||
use ProcessMaker\Project\Adapter;
|
||||
|
||||
abstract class Importer
|
||||
{
|
||||
protected $data = array();
|
||||
protected $importData = array();
|
||||
protected $filename = "";
|
||||
protected $saveDir = "";
|
||||
|
||||
@@ -23,19 +28,55 @@ abstract class Importer
|
||||
*/
|
||||
const IMPORT_STAT_INVALID_SOURCE_FILE = 102;
|
||||
|
||||
public abstract function load();
|
||||
|
||||
public function import($option = self::IMPORT_OPTION_CREATE_NEW)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
<?php
|
||||
namespace ProcessMaker\Importer;
|
||||
|
||||
use ProcessMaker\Project\Adapter;
|
||||
use ProcessMaker\Util;
|
||||
|
||||
class XmlImporter extends Importer
|
||||
{
|
||||
/**
|
||||
@@ -12,17 +9,22 @@ class XmlImporter extends Importer
|
||||
protected $dom;
|
||||
protected $root;
|
||||
protected $version = "";
|
||||
protected $metadata;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user