From 2a6d59bca479a3dbd453290096cb9e00d963bf87 Mon Sep 17 00:00:00 2001 From: davidcallizaya Date: Wed, 1 Mar 2017 09:57:37 -0400 Subject: [PATCH 1/4] HOR-2786 Load IDs from existing records for Process and Tasks that are updated during an import/update task, this way it preserves its IDs values. --- workflow/engine/classes/class.processes.php | 76 +++++++++++++++++++ .../src/ProcessMaker/Importer/Importer.php | 4 + 2 files changed, 80 insertions(+) diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index 2deceda1e..5eb8d8588 100644 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -1194,6 +1194,8 @@ class Processes { $oProcess = new Process(); if ($oProcess->processExists($row['PRO_UID'])) { + $processRow = $oProcess->load($row['PRO_UID']); + $row['PRO_ID'] = $processRow['PRO_ID']; $oProcess->update($row); } else { $oProcess->create($row); @@ -5596,6 +5598,80 @@ class Processes $this->createFilesManager($arrayProcessData["PRO_UID"], (isset($oData->filesManager)) ? $oData->filesManager : array()); } + /** + * + * @param type $oData + */ + public function loadIdsFromData($oData) + { + $this->loadIdsFor(Process::class, ProcessPeer::PRO_UID, ProcessPeer::PRO_ID, $oData['process']); + $this->loadIdsFor(Task::class, TaskPeer::TAS_UID, TaskPeer::TAS_ID, $oData['tasks']); + //The following code matches the Models and the correspondent Property + // in the imported data object, so it could be used to change the UID + // fields by ID on the other tables. + //$this->loadIdsFor(ProcessCategory::class, ProcessCategoryPeer::CATEGORY_UID, ?, $oData->processCategory); + //$this->loadIdsFor(SwimlanesElements::class, ?, ?, $oData->lanes); + //$this->loadIdsFor(Gateway::class, GatewayPeer::GAT_UID, ?, $oData->gateways); + //$this->loadIdsFor(Dynaform::class, $oData->dynaforms); + //$this->loadIdsFor(InputDocument::class, $oData->inputs); + //$this->loadIdsFor(OutputDocument::class, $oData->outputs); + //$this->loadIdsFor(Step::class, $oData->steps); + //$this->loadIdsFor(StepSupervisor::class, $oData->stepSupervisor); + //$this->loadIdsFor(Triggers::class, $oData->triggers); + //$this->loadIdsFor(StepTrigger::class, $oData->steptriggers); + //$this->loadIdsFor(TaskUser::class, ?, ?, $oData->taskusers); + //$this->loadIdsFor(Groupwf::class, $oData->groupwfs); + //$this->loadIdsFor(DbSource::class, $oData->dbconnections); + //$this->loadIdsFor(ReportTables::class, $oData->reportTablesVars); + //$this->loadIdsFor(SubProcess::class, $oData->subProcess); + //$this->loadIdsFor(CaseTracker::class, $oData->caseTracker); + //$this->loadIdsFor(CaseTrackerObject::class, $oData->caseTrackerObject); + //$this->loadIdsFor(ObjectPermission::class, $oData->objectPermissions); + //$this->loadIdsFor(Stage::class, $oData->stage); + //$this->loadIdsFor(FieldCondition::class, $oData->fieldCondition); + //$this->loadIdsFor(Event::class, $oData->event); + //$this->loadIdsFor(CaseScheduler::class, $oData->caseScheduler); + //$this->loadIdsFor(Configuration::class, $oData->taskExtraProperties); + //$this->loadIdsFor(ProcessUser::class, $oData->processUser); + //$this->loadIdsFor(ProcessVariables::class, $oData->processVariables); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntry::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntry); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntryEvent::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntryEvent); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType::class, $oData->messageType); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType\Variable::class, $oData->messageTypeVariable); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageEventDefinition::class, $arrayProcessData["PRO_UID"], $oData->messageEventDefinition); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\ScriptTask::class, $arrayProcessData["PRO_UID"], $oData->scriptTask); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\TimerEvent::class, $arrayProcessData["PRO_UID"], $oData->timerEvent); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\EmailEvent::class, $arrayProcessData["PRO_UID"], $oData->emailEvent); + //$this->loadIdsFor(AbeConfiguration::class, $arrayProcessData["PRO_UID"], $oData->abeConfiguration); + //$this->loadIdsFor(\ProcessMaker\BusinessModel\FilesManager::class, $arrayProcessData["PRO_UID"], $oData->filesManager); + return $oData; + } + + private function loadIdsFor($modelClass, $uidTableField, $idTableField, &$data) { + if(empty($data)) { + return $data; + } + if(!is_array($data)) { + throw new \Exception("invalid input data form $modelClass($key)" . json_encode($data)); + } + $uidField = explode('.', $uidTableField)[1]; + $idField = explode('.', $idTableField)[1]; + if(isset($data[$uidField])) { + //$data is an sigle row + $model = new $modelClass(); + $row = $model->load($data[$uidField]); + $data[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); + } else { + //$data is an array of row + foreach($data as &$dataRow) { + $model = new $modelClass(); + $row = $model->load($dataRow[$uidField]); + $dataRow[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); + } + } + return $data; + } + /** * this function creates a new Process, defined in the object $oData * diff --git a/workflow/engine/src/ProcessMaker/Importer/Importer.php b/workflow/engine/src/ProcessMaker/Importer/Importer.php index d8a40ecf7..b83c7fde0 100644 --- a/workflow/engine/src/ProcessMaker/Importer/Importer.php +++ b/workflow/engine/src/ProcessMaker/Importer/Importer.php @@ -363,6 +363,10 @@ abstract class Importer public function removeProject($onlyDiagram = false) { /* @var $process \Process */ + $processes = new \Processes(); + $this->importData["tables"]["workflow"] = $processes + ->loadIdsFromData($this->importData["tables"]["workflow"]); + $process = new \Process(); $process->load($this->metadata["uid"]); $this->currentProcessTitle = $process->getProTitle(); From d8f3e702802b22927f243c3b40203544e958fcb7 Mon Sep 17 00:00:00 2001 From: davidcallizaya Date: Wed, 1 Mar 2017 15:03:18 -0400 Subject: [PATCH 2/4] HOR-2786 Fixed observations od CR --- workflow/engine/classes/class.processes.php | 95 +++++++++++---------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index 5eb8d8588..a0600408e 100644 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -5599,71 +5599,74 @@ class Processes } /** - * + * * @param type $oData */ public function loadIdsFromData($oData) { $this->loadIdsFor(Process::class, ProcessPeer::PRO_UID, ProcessPeer::PRO_ID, $oData['process']); $this->loadIdsFor(Task::class, TaskPeer::TAS_UID, TaskPeer::TAS_ID, $oData['tasks']); - //The following code matches the Models and the correspondent Property - // in the imported data object, so it could be used to change the UID - // fields by ID on the other tables. - //$this->loadIdsFor(ProcessCategory::class, ProcessCategoryPeer::CATEGORY_UID, ?, $oData->processCategory); - //$this->loadIdsFor(SwimlanesElements::class, ?, ?, $oData->lanes); - //$this->loadIdsFor(Gateway::class, GatewayPeer::GAT_UID, ?, $oData->gateways); - //$this->loadIdsFor(Dynaform::class, $oData->dynaforms); - //$this->loadIdsFor(InputDocument::class, $oData->inputs); - //$this->loadIdsFor(OutputDocument::class, $oData->outputs); - //$this->loadIdsFor(Step::class, $oData->steps); - //$this->loadIdsFor(StepSupervisor::class, $oData->stepSupervisor); - //$this->loadIdsFor(Triggers::class, $oData->triggers); - //$this->loadIdsFor(StepTrigger::class, $oData->steptriggers); - //$this->loadIdsFor(TaskUser::class, ?, ?, $oData->taskusers); - //$this->loadIdsFor(Groupwf::class, $oData->groupwfs); - //$this->loadIdsFor(DbSource::class, $oData->dbconnections); - //$this->loadIdsFor(ReportTables::class, $oData->reportTablesVars); - //$this->loadIdsFor(SubProcess::class, $oData->subProcess); - //$this->loadIdsFor(CaseTracker::class, $oData->caseTracker); - //$this->loadIdsFor(CaseTrackerObject::class, $oData->caseTrackerObject); - //$this->loadIdsFor(ObjectPermission::class, $oData->objectPermissions); - //$this->loadIdsFor(Stage::class, $oData->stage); - //$this->loadIdsFor(FieldCondition::class, $oData->fieldCondition); - //$this->loadIdsFor(Event::class, $oData->event); - //$this->loadIdsFor(CaseScheduler::class, $oData->caseScheduler); - //$this->loadIdsFor(Configuration::class, $oData->taskExtraProperties); - //$this->loadIdsFor(ProcessUser::class, $oData->processUser); - //$this->loadIdsFor(ProcessVariables::class, $oData->processVariables); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntry::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntry); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntryEvent::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntryEvent); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType::class, $oData->messageType); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType\Variable::class, $oData->messageTypeVariable); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\MessageEventDefinition::class, $arrayProcessData["PRO_UID"], $oData->messageEventDefinition); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\ScriptTask::class, $arrayProcessData["PRO_UID"], $oData->scriptTask); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\TimerEvent::class, $arrayProcessData["PRO_UID"], $oData->timerEvent); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\EmailEvent::class, $arrayProcessData["PRO_UID"], $oData->emailEvent); - //$this->loadIdsFor(AbeConfiguration::class, $arrayProcessData["PRO_UID"], $oData->abeConfiguration); - //$this->loadIdsFor(\ProcessMaker\BusinessModel\FilesManager::class, $arrayProcessData["PRO_UID"], $oData->filesManager); + /** + * @todo The following code matches the Models and the correspondent Property + * in the imported data object, so it could be used to change the UID + * fields by ID on the other tables. + * $this->loadIdsFor(ProcessCategory::class, ProcessCategoryPeer::CATEGORY_UID, ?, $oData->processCategory); + * $this->loadIdsFor(SwimlanesElements::class, ?, ?, $oData->lanes); + * $this->loadIdsFor(Gateway::class, GatewayPeer::GAT_UID, ?, $oData->gateways); + * $this->loadIdsFor(Dynaform::class, $oData->dynaforms); + * $this->loadIdsFor(InputDocument::class, $oData->inputs); + * $this->loadIdsFor(OutputDocument::class, $oData->outputs); + * $this->loadIdsFor(Step::class, $oData->steps); + * $this->loadIdsFor(StepSupervisor::class, $oData->stepSupervisor); + * $this->loadIdsFor(Triggers::class, $oData->triggers); + * $this->loadIdsFor(StepTrigger::class, $oData->steptriggers); + * $this->loadIdsFor(TaskUser::class, ?, ?, $oData->taskusers); + * $this->loadIdsFor(Groupwf::class, $oData->groupwfs); + * $this->loadIdsFor(DbSource::class, $oData->dbconnections); + * $this->loadIdsFor(ReportTables::class, $oData->reportTablesVars); + * $this->loadIdsFor(SubProcess::class, $oData->subProcess); + * $this->loadIdsFor(CaseTracker::class, $oData->caseTracker); + * $this->loadIdsFor(CaseTrackerObject::class, $oData->caseTrackerObject); + * $this->loadIdsFor(ObjectPermission::class, $oData->objectPermissions); + * $this->loadIdsFor(Stage::class, $oData->stage); + * $this->loadIdsFor(FieldCondition::class, $oData->fieldCondition); + * $this->loadIdsFor(Event::class, $oData->event); + * $this->loadIdsFor(CaseScheduler::class, $oData->caseScheduler); + * $this->loadIdsFor(Configuration::class, $oData->taskExtraProperties); + * $this->loadIdsFor(ProcessUser::class, $oData->processUser); + * $this->loadIdsFor(ProcessVariables::class, $oData->processVariables); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntry::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntry); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\WebEntryEvent::class, $arrayProcessData["PRO_UID"], $arrayProcessData["PRO_CREATE_USER"], $oData->webEntryEvent); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType::class, $oData->messageType); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\MessageType\Variable::class, $oData->messageTypeVariable); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\MessageEventDefinition::class, $arrayProcessData["PRO_UID"], $oData->messageEventDefinition); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\ScriptTask::class, $arrayProcessData["PRO_UID"], $oData->scriptTask); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\TimerEvent::class, $arrayProcessData["PRO_UID"], $oData->timerEvent); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\EmailEvent::class, $arrayProcessData["PRO_UID"], $oData->emailEvent); + * $this->loadIdsFor(AbeConfiguration::class, $arrayProcessData["PRO_UID"], $oData->abeConfiguration); + * $this->loadIdsFor(\ProcessMaker\BusinessModel\FilesManager::class, $arrayProcessData["PRO_UID"], $oData->filesManager); + */ return $oData; } - private function loadIdsFor($modelClass, $uidTableField, $idTableField, &$data) { - if(empty($data)) { + private function loadIdsFor($modelClass, $uidTableField, $idTableField, &$data) + { + if (empty($data)) { return $data; } - if(!is_array($data)) { - throw new \Exception("invalid input data form $modelClass($key)" . json_encode($data)); + if (!is_array($data)) { + throw new Exception("Invalid input data form $modelClass($key)" . G::json_encode($data)); } $uidField = explode('.', $uidTableField)[1]; $idField = explode('.', $idTableField)[1]; - if(isset($data[$uidField])) { - //$data is an sigle row + if (isset($data[$uidField])) { + //$data is an single row $model = new $modelClass(); $row = $model->load($data[$uidField]); $data[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); } else { //$data is an array of row - foreach($data as &$dataRow) { + foreach ($data as &$dataRow) { $model = new $modelClass(); $row = $model->load($dataRow[$uidField]); $dataRow[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); From ba68b4f04bbc5ba2c9490d6822d36b9e35e47e42 Mon Sep 17 00:00:00 2001 From: davidcallizaya Date: Thu, 2 Mar 2017 14:11:47 -0400 Subject: [PATCH 3/4] Added ID load for classic PM processes import. --- workflow/engine/classes/class.processes.php | 30 +++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index a0600408e..dd3615b38 100644 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -5604,8 +5604,33 @@ class Processes */ public function loadIdsFromData($oData) { - $this->loadIdsFor(Process::class, ProcessPeer::PRO_UID, ProcessPeer::PRO_ID, $oData['process']); - $this->loadIdsFor(Task::class, TaskPeer::TAS_UID, TaskPeer::TAS_ID, $oData['tasks']); + if (is_array($oData)) { + $this->loadIdsFor( + Process::class, + ProcessPeer::PRO_UID, + ProcessPeer::PRO_ID, + $oData['process'] + ); + $this->loadIdsFor( + Task::class, + TaskPeer::TAS_UID, + TaskPeer::TAS_ID, + $oData['tasks'] + ); + } else { + $this->loadIdsFor( + Process::class, + ProcessPeer::PRO_UID, + ProcessPeer::PRO_ID, + $oData->process + ); + $this->loadIdsFor( + Task::class, + TaskPeer::TAS_UID, + TaskPeer::TAS_ID, + $oData->tasks + ); + } /** * @todo The following code matches the Models and the correspondent Property * in the imported data object, so it could be used to change the UID @@ -5683,6 +5708,7 @@ class Processes */ public function updateProcessFromData($oData, $pmFilename) { + $oData = $this->loadIdsFromData($oData); $this->updateProcessRow($oData->process); $this->removeProcessRows($oData->process['PRO_UID']); $this->removeAllFieldCondition($oData->dynaforms); From 05a477f95d6e351fc69f206c2ade94b4bddc0919 Mon Sep 17 00:00:00 2001 From: davidcallizaya Date: Thu, 2 Mar 2017 14:18:55 -0400 Subject: [PATCH 4/4] Add validation for loadIdsFor function. --- workflow/engine/classes/class.processes.php | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index dd3615b38..b7942ed06 100644 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -5674,27 +5674,38 @@ class Processes return $oData; } - private function loadIdsFor($modelClass, $uidTableField, $idTableField, &$data) + private function loadIdsFor($modelClass, $uidTableField, $idTableField, + &$data) { if (empty($data)) { return $data; } if (!is_array($data)) { - throw new Exception("Invalid input data form $modelClass($key)" . G::json_encode($data)); + throw new Exception("Invalid input data form $modelClass($key)".G::json_encode($data)); } - $uidField = explode('.', $uidTableField)[1]; - $idField = explode('.', $idTableField)[1]; + $uidTableFieldArray = explode('.', $uidTableField); + $idTableFieldArray = explode('.', $idTableField); + if (count($uidTableFieldArray) !== 2) { + throw new Exception('Invalid argument $uidTableField, expected a "TABLE.COLUMN" string'); + } + if (count($idTableFieldArray) !== 2) { + throw new Exception('Invalid argument $idTableField, expected a "TABLE.COLUMN" string'); + } + $uidField = $uidTableFieldArray[1]; + $idField = $idTableFieldArray[1]; if (isset($data[$uidField])) { //$data is an single row $model = new $modelClass(); $row = $model->load($data[$uidField]); - $data[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); + $data[$idField] = $model->getByName($idTableField, + BasePeer::TYPE_COLNAME); } else { //$data is an array of row foreach ($data as &$dataRow) { $model = new $modelClass(); $row = $model->load($dataRow[$uidField]); - $dataRow[$idField] = $model->getByName($idTableField, BasePeer::TYPE_COLNAME); + $dataRow[$idField] = $model->getByName($idTableField, + BasePeer::TYPE_COLNAME); } } return $data;