import bpmn projects (1st commit - still not functional)
This commit is contained in:
@@ -23,6 +23,16 @@
|
|||||||
*/
|
*/
|
||||||
ini_set( 'max_execution_time', '0' );
|
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");
|
||||||
|
$importer->import();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
function reservedWordsSqlValidate ($data)
|
function reservedWordsSqlValidate ($data)
|
||||||
{
|
{
|
||||||
$arrayAux = array ();
|
$arrayAux = array ();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ abstract class Exporter
|
|||||||
/**
|
/**
|
||||||
* Exporter version
|
* Exporter version
|
||||||
*/
|
*/
|
||||||
const VERSION = "2.0";
|
const VERSION = "3.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \ProcessMaker\Project\Adapter\BpmnWorkflow
|
* @var \ProcessMaker\Project\Adapter\BpmnWorkflow
|
||||||
@@ -67,8 +67,8 @@ abstract class Exporter
|
|||||||
{
|
{
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
$data["Metadata"] = $this->getMetadata();
|
$data["metadata"] = $this->getMetadata();
|
||||||
$data["Metadata"]["project_name"] = $this->getProjectName();
|
$data["metadata"]["project_name"] = $this->getProjectName();
|
||||||
|
|
||||||
$bpmnStruct["ACTIVITY"] = \BpmnActivity::getAll($this->prjUid);
|
$bpmnStruct["ACTIVITY"] = \BpmnActivity::getAll($this->prjUid);
|
||||||
$bpmnStruct["BOUND"] = \BpmnBound::getAll($this->prjUid);
|
$bpmnStruct["BOUND"] = \BpmnBound::getAll($this->prjUid);
|
||||||
@@ -95,9 +95,9 @@ abstract class Exporter
|
|||||||
$workflowData["processCategory"] = empty($workflowData["processCategory"]) ? array() : $workflowData["processCategory"];
|
$workflowData["processCategory"] = empty($workflowData["processCategory"]) ? array() : $workflowData["processCategory"];
|
||||||
|
|
||||||
|
|
||||||
$data["BPMN-Definition"] = $bpmnStruct;
|
$data["bpmn-definition"] = $bpmnStruct;
|
||||||
$data["Workflow-Definition"] = $workflowData;
|
$data["workflow-definition"] = $workflowData;
|
||||||
$data["Workflow-Files"] = array();
|
$data["workflow-files"] = array();
|
||||||
|
|
||||||
// getting dynaforms
|
// getting dynaforms
|
||||||
$dynaforms = array();
|
$dynaforms = array();
|
||||||
@@ -113,7 +113,7 @@ abstract class Exporter
|
|||||||
$htmlFile = PATH_DYNAFORM . $dynaform['DYN_FILENAME'] . '.html';
|
$htmlFile = PATH_DYNAFORM . $dynaform['DYN_FILENAME'] . '.html';
|
||||||
|
|
||||||
if (file_exists($htmlFile)) {
|
if (file_exists($htmlFile)) {
|
||||||
$data["Workflow-Files"]["DYNAFORMS"][] = array(
|
$data["workflow-files"]["DYNAFORMS"][] = array(
|
||||||
"filename" => $dynaform['DYN_FILENAME'] . '.html',
|
"filename" => $dynaform['DYN_FILENAME'] . '.html',
|
||||||
"filepath" => $dynaform['DYN_FILENAME'] . '.html',
|
"filepath" => $dynaform['DYN_FILENAME'] . '.html',
|
||||||
"file_content" => file_get_contents($htmlFile)
|
"file_content" => file_get_contents($htmlFile)
|
||||||
@@ -132,7 +132,7 @@ abstract class Exporter
|
|||||||
foreach ($templatesFiles as $templatesFile) {
|
foreach ($templatesFiles as $templatesFile) {
|
||||||
if (is_dir($templatesFile)) continue;
|
if (is_dir($templatesFile)) continue;
|
||||||
|
|
||||||
$data["Workflow-Files"][$target][] = array(
|
$data["workflow-files"][$target][] = array(
|
||||||
"filename" => basename($templatesFile),
|
"filename" => basename($templatesFile),
|
||||||
"filepath" => str_replace($templatesDir, "", $templatesFile),
|
"filepath" => str_replace($templatesDir, "", $templatesFile),
|
||||||
"file_content" => file_get_contents($templatesFile)
|
"file_content" => file_get_contents($templatesFile)
|
||||||
@@ -148,7 +148,7 @@ abstract class Exporter
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getContainerName()
|
public static function getContainerName()
|
||||||
{
|
{
|
||||||
return "ProcessMaker-Project";
|
return "ProcessMaker-Project";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,21 +38,20 @@ class XmlExporter extends Exporter
|
|||||||
*/
|
*/
|
||||||
public function build()
|
public function build()
|
||||||
{
|
{
|
||||||
$this->rootNode = $this->dom->createElement($this->getContainerName());
|
$this->rootNode = $this->dom->createElement(self::getContainerName());
|
||||||
$this->rootNode->setAttribute("version", self::getVersion());
|
$this->rootNode->setAttribute("version", self::getVersion());
|
||||||
$this->dom->appendChild($this->rootNode);
|
$this->dom->appendChild($this->rootNode);
|
||||||
|
|
||||||
$data = $this->buildData();
|
$data = $this->buildData();
|
||||||
|
|
||||||
// metadata set up
|
// metadata set up
|
||||||
$metadata = $data["Metadata"];
|
$metadata = $data["metadata"];
|
||||||
$metadataNode = $this->dom->createElement("Metadata");
|
$metadataNode = $this->dom->createElement("metadata");
|
||||||
|
|
||||||
foreach ($metadata as $key => $value) {
|
foreach ($metadata as $key => $value) {
|
||||||
$metaNode = $this->dom->createElement("meta:$key");
|
$metaNode = $this->dom->createElement("meta");
|
||||||
//$metaNode->setAttribute("key", $key);
|
$metaNode->setAttribute("key", $key);
|
||||||
//$metaNode->setAttribute("value", $value);
|
$metaNode->appendChild($this->getTextNode($value));
|
||||||
$metaNode->appendChild($this->dom->createTextNode($value));
|
|
||||||
$metadataNode->appendChild($metaNode);
|
$metadataNode->appendChild($metaNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,10 +59,10 @@ class XmlExporter extends Exporter
|
|||||||
// end setting metadata
|
// end setting metadata
|
||||||
|
|
||||||
// bpmn struct data set up
|
// bpmn struct data set up
|
||||||
$dbData = array("BPMN" => $data["BPMN-Definition"], "Workflow" => $data["Workflow-Definition"]);
|
$dbData = array("BPMN" => $data["bpmn-definition"], "workflow" => $data["workflow-definition"]);
|
||||||
//file_put_contents("/home/erik/out.log", print_r($dbData, true)); die;
|
|
||||||
foreach ($dbData as $sectionName => $sectionData) {
|
foreach ($dbData as $sectionName => $sectionData) {
|
||||||
$dataNode = $this->dom->createElement("Definition");
|
$dataNode = $this->dom->createElement("definition");
|
||||||
$dataNode->setAttribute("class", $sectionName);
|
$dataNode->setAttribute("class", $sectionName);
|
||||||
|
|
||||||
foreach ($sectionData as $elementName => $elementData) {
|
foreach ($sectionData as $elementName => $elementData) {
|
||||||
@@ -73,19 +72,10 @@ class XmlExporter extends Exporter
|
|||||||
foreach ($elementData as $recordData) {
|
foreach ($elementData as $recordData) {
|
||||||
$recordNode = $this->dom->createElement("record");
|
$recordNode = $this->dom->createElement("record");
|
||||||
$recordData = array_change_key_case($recordData, CASE_LOWER);
|
$recordData = array_change_key_case($recordData, CASE_LOWER);
|
||||||
//var_dump($recordData); die;
|
|
||||||
|
|
||||||
|
|
||||||
foreach ($recordData as $key => $value) {
|
foreach ($recordData as $key => $value) {
|
||||||
$columnNode = $this->dom->createElement($key);
|
$columnNode = $this->dom->createElement($key);
|
||||||
|
$columnNode->appendChild($this->getTextNode($value));
|
||||||
if (preg_match('/^[\w\s\.]+$/', $value, $match) || empty($value)) {
|
|
||||||
$textNode = $this->dom->createTextNode($value);
|
|
||||||
} else {
|
|
||||||
$textNode = $this->dom->createCDATASection($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$columnNode->appendChild($textNode);
|
|
||||||
$recordNode->appendChild($columnNode);
|
$recordNode->appendChild($columnNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,20 +88,16 @@ class XmlExporter extends Exporter
|
|||||||
$this->rootNode->appendChild($dataNode);
|
$this->rootNode->appendChild($dataNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
$workflowFilesNode = $this->dom->createElement("Workflow-Files");
|
$workflowFilesNode = $this->dom->createElement("workflow-files");
|
||||||
|
|
||||||
// workflow dynaforms files
|
// workflow dynaforms files
|
||||||
foreach ($data["Workflow-Files"] as $elementName => $elementData) {
|
foreach ($data["workflow-files"] as $elementName => $elementData) {
|
||||||
foreach ($elementData as $fileData) {
|
foreach ($elementData as $fileData) {
|
||||||
$fileNode = $this->dom->createElement("file");
|
$fileNode = $this->dom->createElement("file");
|
||||||
$fileNode->setAttribute("target", strtolower($elementName));
|
$fileNode->setAttribute("target", strtolower($elementName));
|
||||||
|
|
||||||
$filenameNode = $this->dom->createElement("file_name");
|
$filenameNode = $this->dom->createElement("file_name");
|
||||||
if (preg_match('/^[\w\s\.\-]+$/', $fileData["filename"], $match)) {
|
$filenameNode->appendChild($this->getTextNode($fileData["filename"]));
|
||||||
$filenameNode->appendChild($this->dom->createTextNode($fileData["filename"]));
|
|
||||||
} else {
|
|
||||||
$filenameNode->appendChild($this->dom->createCDATASection($fileData["filename"]));
|
|
||||||
}
|
|
||||||
$fileNode->appendChild($filenameNode);
|
$fileNode->appendChild($filenameNode);
|
||||||
|
|
||||||
$filepathNode = $this->dom->createElement("file_path");
|
$filepathNode = $this->dom->createElement("file_path");
|
||||||
@@ -146,4 +132,13 @@ class XmlExporter extends Exporter
|
|||||||
$this->build();
|
$this->build();
|
||||||
return $this->dom->saveXml();
|
return $this->dom->saveXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getTextNode($value)
|
||||||
|
{
|
||||||
|
if (preg_match('/^[\w\s\.\-]+$/', $value, $match)) {
|
||||||
|
return $this->dom->createTextNode($value);
|
||||||
|
} else {
|
||||||
|
return $this->dom->createCDATASection($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,16 +24,66 @@ abstract class Importer
|
|||||||
const IMPORT_STAT_INVALID_SOURCE_FILE = 102;
|
const IMPORT_STAT_INVALID_SOURCE_FILE = 102;
|
||||||
|
|
||||||
|
|
||||||
public abstract function import();
|
public function import($option = self::IMPORT_OPTION_CREATE_NEW)
|
||||||
public abstract function validateSource();
|
{
|
||||||
public abstract function targetExists();
|
switch ($option) {
|
||||||
|
case self::IMPORT_OPTION_CREATE_NEW:
|
||||||
|
$this->prepare();
|
||||||
|
$this->createNewProject();
|
||||||
|
break;
|
||||||
|
case self::IMPORT_OPTION_DISABLE_AND_CREATE_NEW:
|
||||||
|
break;
|
||||||
|
case self::IMPORT_OPTION_OVERWRITE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the source file
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function validateSource()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify if the project already exists
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function targetExists()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createNewProject()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateProject()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableCurrentProject()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the temporal file save directory
|
||||||
|
* @param $dirName
|
||||||
|
*/
|
||||||
public function setSaveDir($dirName)
|
public function setSaveDir($dirName)
|
||||||
{
|
{
|
||||||
$this->saveDir = rtrim($dirName, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
$this->saveDir = rtrim($dirName, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the temporal file save directory
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getSaveDir()
|
public function getSaveDir()
|
||||||
{
|
{
|
||||||
if (empty($this->saveDir)) {
|
if (empty($this->saveDir)) {
|
||||||
@@ -43,11 +93,20 @@ abstract class Importer
|
|||||||
return $this->saveDir;
|
return $this->saveDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the temporal source file
|
||||||
|
* @param $filename
|
||||||
|
*/
|
||||||
public function setSourceFile($filename)
|
public function setSourceFile($filename)
|
||||||
{
|
{
|
||||||
$this->filename = $filename;
|
$this->filename = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set source from Global Http Request resource
|
||||||
|
* @param $varName
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
public function setSourceFromGlobals($varName)
|
public function setSourceFromGlobals($varName)
|
||||||
{
|
{
|
||||||
/*[PROCESS_FILENAME] => Array
|
/*[PROCESS_FILENAME] => Array
|
||||||
@@ -77,6 +136,11 @@ abstract class Importer
|
|||||||
umask($oldUmask);
|
umask($oldUmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare for import, it makes all validations needed
|
||||||
|
* @return int
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
public function prepare()
|
public function prepare()
|
||||||
{
|
{
|
||||||
if ($this->validateSource() === false) {
|
if ($this->validateSource() === false) {
|
||||||
|
|||||||
@@ -1,17 +1,133 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace ProcessMaker\Importer;
|
namespace ProcessMaker\Importer;
|
||||||
|
|
||||||
class XmlImporter
|
class XmlImporter extends Importer
|
||||||
{
|
{
|
||||||
public $filename = "";
|
/**
|
||||||
|
* @var \DOMDocument
|
||||||
|
*/
|
||||||
|
protected $dom;
|
||||||
|
protected $root;
|
||||||
|
protected $version = "";
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->dom = new \DOMDocument();
|
||||||
|
}
|
||||||
|
|
||||||
public function setSourceFile($filename)
|
public function setSourceFile($filename)
|
||||||
{
|
{
|
||||||
$this->filename = $filename;
|
$this->filename = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function load()
|
||||||
|
{
|
||||||
|
$this->dom->load($this->filename);
|
||||||
|
$this->root = $this->dom->documentElement;
|
||||||
|
|
||||||
|
// validate version
|
||||||
|
$this->version = $this->root->getAttribute("version");
|
||||||
|
|
||||||
|
if (empty($this->version)) {
|
||||||
|
throw new \Exception("ProcessMaker Project version is missing on file source.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read metadata section
|
||||||
|
$metadata = $this->root->getElementsByTagName("metadata");
|
||||||
|
|
||||||
|
if ($metadata->length != 1) {
|
||||||
|
throw new \Exception("Invalid Document format, metadata section is missing or has multiple definition.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = $metadata->item(0);
|
||||||
|
|
||||||
|
// load project definition
|
||||||
|
/** @var \DOMElement[]|\DomNodeList $definitions */
|
||||||
|
$definitions = $this->root->getElementsByTagName("definition");
|
||||||
|
|
||||||
|
if ($definitions->length == 0) {
|
||||||
|
throw new \Exception("Definition section is missing.");
|
||||||
|
} elseif ($definitions->length < 2) {
|
||||||
|
throw new \Exception("Definition section is incomplete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$tables = array();
|
||||||
|
|
||||||
|
foreach ($definitions as $definition) {
|
||||||
|
$defClass = strtoupper($definition->getAttribute("class"));
|
||||||
|
$tables[$defClass] = array();
|
||||||
|
|
||||||
|
// getting tables def
|
||||||
|
// first we need to know if the project already exists
|
||||||
|
/** @var \DOMElement[] $tablesNodeList */
|
||||||
|
$tablesNodeList = $definition->getElementsByTagName("table");
|
||||||
|
|
||||||
|
foreach ($tablesNodeList as $tableNode) {
|
||||||
|
$tableName = strtoupper($tableNode->getAttribute("name"));
|
||||||
|
$tables[$defClass][$tableName] = array();
|
||||||
|
/** @var \DOMElement[] $recordsNodeList */
|
||||||
|
$recordsNodeList = $tableNode->getElementsByTagName("record");
|
||||||
|
|
||||||
|
foreach ($recordsNodeList as $recordsNode) {
|
||||||
|
if (! $recordsNode->hasChildNodes()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = array();
|
||||||
|
|
||||||
|
foreach ($recordsNode->childNodes as $columnNode) {
|
||||||
|
if ($columnNode->nodeName == "#text") continue;
|
||||||
|
$columns[strtoupper($columnNode->nodeName)] = self::getNodeText($columnNode);;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tables[$defClass][$tableName][] = $columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$wfFilesNodeList = $this->root->getElementsByTagName("workflow-files");
|
||||||
|
$wfFiles = array();
|
||||||
|
|
||||||
|
if ($wfFilesNodeList->length > 0) {
|
||||||
|
$filesNodeList = $wfFilesNodeList->item(0)->getElementsByTagName("file");
|
||||||
|
|
||||||
|
foreach ($filesNodeList as $fileNode) {
|
||||||
|
$target = $fileNode->getAttribute("target");
|
||||||
|
|
||||||
|
if (! isset($wfFiles[$target])) {
|
||||||
|
$wfFiles[$target] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileContent = self::getNodeText($fileNode->getElementsByTagName("file_content")->item(0));
|
||||||
|
$fileContent = base64_decode($fileContent);
|
||||||
|
|
||||||
|
$wfFiles[$target][] = array(
|
||||||
|
"file_name" => self::getNodeText($fileNode->getElementsByTagName("file_name")->item(0)),
|
||||||
|
"file_path" => self::getNodeText($fileNode->getElementsByTagName("file_path")->item(0)),
|
||||||
|
"file_content" => $fileContent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_r($tables);
|
||||||
|
print_r($wfFiles);
|
||||||
|
|
||||||
|
|
||||||
|
// load workflow definition
|
||||||
|
// load workflow files
|
||||||
|
}
|
||||||
|
|
||||||
public function import()
|
public function import()
|
||||||
{
|
{
|
||||||
|
$this->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getNodeText($node)
|
||||||
|
{
|
||||||
|
if ($node->nodeType == XML_ELEMENT_NODE) {
|
||||||
|
return $node->textContent;
|
||||||
|
} else if ($node->nodeType == XML_TEXT_NODE || $node->nodeType == XML_CDATA_SECTION_NODE) {
|
||||||
|
return (string) simplexml_import_dom($node->parentNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user