diff --git a/workflow/engine/classes/model/BpmnGateway.php b/workflow/engine/classes/model/BpmnGateway.php index 812123973..107c16f64 100644 --- a/workflow/engine/classes/model/BpmnGateway.php +++ b/workflow/engine/classes/model/BpmnGateway.php @@ -74,13 +74,13 @@ class BpmnGateway extends BaseBpmnGateway $rs = BpmnGatewayPeer::doSelectRS($c); $rs->setFetchmode(\ResultSet::FETCHMODE_ASSOC); - $activities = array(); + $events = array(); while ($rs->next()) { - $activities[] = $changeCaseTo !== CASE_UPPER ? array_change_key_case($rs->getRow(), CASE_LOWER) : $rs->getRow(); + $events[] = $changeCaseTo !== CASE_UPPER ? array_change_key_case($rs->getRow(), CASE_LOWER) : $rs->getRow(); } - return $activities; + return $events; } // OVERRIDES diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index e599871ef..b5f57c0b7 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -141,114 +141,97 @@ class BpmnWorkflow extends Project\Bpmn { parent::addFlow($data); + // to add a workflow route + // - activity -> activity ==> route + // - activity -> gateway -> activity ==> selection, evaluation, parallel or parallel by evaluation route $routeData = self::mapBpmnFlowsToWorkflowRoute($data, $flows, $gateways, $events); if ($routeData !== null) { $this->wp->addRoute($routeData["from"], $routeData["to"], $routeData["type"]); + + return true; } - return; + // to add start event->activity as initial or end task + switch ($data["FLO_ELEMENT_ORIGIN_TYPE"]) { + case "bpmnEvent": + switch ($data["FLO_ELEMENT_DEST_TYPE"]) { + case "bpmnActivity": + $event = \BpmnEventPeer::retrieveByPK($data["FLO_ELEMENT_ORIGIN"]); - $fromUid = $data['FLO_ELEMENT_ORIGIN']; + switch ($event && $event->getEvnType()) { + case "START": + self::log("Setting Task:" . $data["FLO_ELEMENT_DEST"] . " as STARTING TASK"); - if ($data['FLO_TYPE'] != 'SEQUENCE') { - throw new \LogicException(sprintf( - "Unsupported flow type: %s, ProcessMaker only support type '', Given: '%s'", - 'SEQUENCE', $data['FLO_TYPE'] - )); - } + // then set that activity/task as "Start Task" + $this->wp->updateTask($data["FLO_ELEMENT_DEST"], array("TAS_START" => "TRUE")); - switch ($data['FLO_ELEMENT_DEST_TYPE']) { - case 'bpmnActivity': - // the most easy case, when the flow is connecting a activity with another activity - /*$data = array( - 'ROU_UID' => $data['FLO_UID'], //Hash::generateUID(), - 'PRO_UID' => $this->getUid(), - 'TAS_UID' => $fromUid, - 'ROU_NEXT_TASK' => $data['FLO_ELEMENT_DEST'], - 'ROU_TYPE' => 'SEQUENTIAL' - );*/ - $this->wp->addRoute($fromUid, $data['FLO_ELEMENT_DEST'], 'SEQUENTIAL'); - break; - case 'bpmnGateway': - $gatUid = $data['FLO_ELEMENT_DEST']; - // if it is a gateway it can fork one or more routes - //$gatFlows = BpmnModel::getBpmnCollectionBy('Flow', \BpmnFlowPeer::FLO_ELEMENT_ORIGIN, $gatUid); - $gatFlow = \BpmnFlow::findOneBy(\BpmnFlowPeer::FLO_ELEMENT_ORIGIN, $gatUid)->toArray();; - self::log("=================================>", $gatFlow); - - //foreach ($gatFlows as $gatFlow) { - switch ($gatFlow['FLO_ELEMENT_DEST_TYPE']) { - case 'bpmnActivity': - // getting gateway properties - //$gateway = BpmnModel::getBpmnObjectBy('Gateway', \BpmnGatewayPeer::GAT_UID, $gatUid); - $gateway = \BpmnGateway::findOneBy(\BpmnGatewayPeer::GAT_UID, $gatUid)->toArray(); - - - switch ($gateway['GAT_TYPE']) { - case 'SELECTION': - $routeType = 'SELECT'; - break; - case 'EVALUATION': - $routeType = 'EVALUATE'; - break; - case 'PARALLEL': - $routeType = 'PARALLEL'; - break; - case 'PARALLEL_EVALUATION': - $routeType = 'PARALLEL-BY-EVALUATION'; - break; - case 'PARALLEL_JOIN': - $routeType = 'SEC-JOIN'; - break; - default: - throw new \LogicException(sprintf("Unsupported Gateway type: %s", $gateway['GAT_TYPE'])); - } - - /*$routes[] = array( - 'ROU_UID' => $gatFlow['FLO_UID'], //Hash::generateUID(), - 'PRO_UID' => $this->getUid(), - 'TAS_UID' => $fromUid, - 'ROU_NEXT_TASK' => $gatFlow['FLO_ELEMENT_DEST'], - 'ROU_TYPE' => $routeType - );*/ - - $this->wp->addRoute($fromUid, $gatFlow['FLO_ELEMENT_DEST'], $routeType); - break; - default: - // for processmaker is only allowed flows between "gateway -> activity" - // any another flow is considered invalid - throw new \LogicException(sprintf( - "For ProcessMaker is only allowed flows between \"gateway -> activity\" " . PHP_EOL . - "Given: bpmnGateway -> " . $gatFlow['FLO_ELEMENT_DEST_TYPE'] - )); - } - //} - break; - case 'bpmnEvent': - $evnUid = $data['FLO_ELEMENT_DEST']; - $event = BpmnModel::getBpmnObjectBy('Event', \BpmnEventPeer::EVN_UID, $evnUid); - - switch ($event['EVN_TYPE']) { - case 'END': - $routeType = 'SEQUENTIAL'; - $routes[] = array( - 'ROU_UID' => $data['FLO_UID'], //Hash::generateUID(), - 'PRO_UID' => $this->getUid(), - 'TAS_UID' => $fromUid, - 'ROU_NEXT_TASK' => '-1', - 'ROU_TYPE' => $routeType, - '_action' => 'CREATE' - ); + self::log("Setting as \"Stating Task\" Success!"); + break; + } break; - default: - throw new \LogicException("Invalid connection to Event object type"); } - break; } } + + public function addEvent($data) + { + if (! array_key_exists("EVN_TYPE", $data)) { + throw new \RuntimeException("Required param \"EVN_TYPE\" is missing."); + } + + parent::addEvent($data); + } + + public function removeEvent($evnUid) + { + $flow = \BpmnFlowPeer::retrieveByPK($evnUid); + + if (! is_null($flow)) { + $data = $flow->toArray(); + + // to add start event->activity as initial or end task + switch ($data["FLO_ELEMENT_ORIGIN_TYPE"]) { + case "bpmnEvent": + switch ($data["FLO_ELEMENT_DEST_TYPE"]) { + case "bpmnActivity": + $event = \BpmnEventPeer::retrieveByPK($data["FLO_ELEMENT_ORIGIN"]); + + switch ($event && $event->getEvnType()) { + case "START": + self::log("Unset Task:" . $data["FLO_ELEMENT_DEST"] . " as NOT STARTING TASK"); + + // then set that activity/task as "Start Task" + $this->wp->updateTask($data["FLO_ELEMENT_DEST"], array("TAS_START" => "FALSE")); + + self::log("Unset as \"Stating Task\" Success!"); + break; + } + break; + } + break; + } + } + + + +//for end event +// switch ($flow->getFloElementOriginType()) { +// case "bpmnActivity": +// switch ($flow->getFloElementDestType()) { +// case "bpmnEvent": +// +// break; +// } +// break; +// } + + parent::removeEvent($evnUid); + + } + public static function mapBpmnFlowsToWorkflowRoute($flow, $flows, $gateways, $events) { $fromUid = $flow['FLO_ELEMENT_ORIGIN']; diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index a5d94ed43..14e4af98b 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -298,13 +298,20 @@ class Bpmn extends Handler // setting defaults $data['EVN_UID'] = array_key_exists('EVN_UID', $data) ? $data['EVN_UID'] : Hash::generateUID(); - $event = new Event(); - $event->fromArray($data); - $event->setPrjUid($this->project->getPrjUid()); - $event->setProUid($this->getProcess("object")->getProUid()); - $event->save(); + try { + self::log("Add Event with data: ", $data); - $this->events[$event->getEvnUid()] = $event; + $event = new Event(); + $event->fromArray($data); + $event->setPrjUid($this->project->getPrjUid()); + $event->setProUid($this->getProcess("object")->getProUid()); + $event->save(); + + self::log("Add Event Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } } public function getEvent($evnUid) @@ -322,10 +329,44 @@ class Bpmn extends Handler return $this->events[$evnUid]; } - public function getEvents($retType = "array") + public function getEvents($start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) { - //return Event::getAll($this->project->getPrjUid(), null, null, '', 'object'); - return array(); + if (is_array($start)) { + extract($start); + } + + return Event::getAll($this->project->getPrjUid(), null, null, '', $changeCaseTo); + } + + public function updateEvent($evnUid, $data) + { + try { + self::log("Update Event: $evnUid", "With data: ", $data); + + $event = EventPeer::retrieveByPk($evnUid); + $event->fromArray($data); + $event->save(); + + self::log("Update Event Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + + public function removeEvent($evnUid) + { + try { + self::log("Remove Event: $evnUid"); + + $event = EventPeer::retrieveByPK($evnUid); + $event->delete(); + + self::log("Remove Event Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } } public function addGateway($data) @@ -384,7 +425,7 @@ class Bpmn extends Handler extract($start); } - return Gateway::getAll($this->getUid(), null, null, '', $changeCaseTo); + return Gateway::getAll($this->getUid(), $start, $limit, $filter, $changeCaseTo); } public function removeGateway($gatUid) diff --git a/workflow/engine/src/Services/Api/ProcessMaker/Project.php b/workflow/engine/src/Services/Api/ProcessMaker/Project.php index 51153bb20..268a71519 100644 --- a/workflow/engine/src/Services/Api/ProcessMaker/Project.php +++ b/workflow/engine/src/Services/Api/ProcessMaker/Project.php @@ -45,15 +45,17 @@ class Project extends Api $process = $bwp->getProcess(); $diagram["pro_uid"] = $process["PRO_UID"]; + $configList = array("changeCaseTo" => CASE_LOWER); + if (! is_null($diagram)) { $diagram = array_change_key_case($diagram, CASE_LOWER); - $diagram["activities"] = $bwp->getActivities(array("changeCaseTo" => CASE_LOWER)); - $diagram["events"] = $bwp->getEvents(); - $diagram["gateways"] = $bwp->getGateways(array("changeCaseTo" => CASE_LOWER)); - $diagram["flows"] = $bwp->getFlows(array("changeCaseTo" => CASE_LOWER)); - $diagram["artifacts"] = $bwp->getArtifacts(); - $diagram["laneset"] = $bwp->getLanesets(); - $diagram["lanes"] = $bwp->getLanes(); + $diagram["activities"] = $bwp->getActivities($configList); + $diagram["events"] = $bwp->getEvents($configList); + $diagram["gateways"] = $bwp->getGateways($configList); + $diagram["flows"] = $bwp->getFlows($configList); + $diagram["artifacts"] = $bwp->getArtifacts($configList); + $diagram["laneset"] = $bwp->getLanesets($configList); + $diagram["lanes"] = $bwp->getLanes($configList); $project["diagrams"][] = $diagram; } @@ -182,6 +184,41 @@ class Project extends Api } } + /* + * Diagram's Events Handling + */ + $whiteList = array(); + foreach ($diagram["events"] as $i => $eventData) { + $eventData = array_change_key_case($eventData, CASE_UPPER); + + // gateway exists ? + if ($event = $bwp->getEvent($eventData["EVN_UID"])) { + // then update activity + $bwp->updateEvent($eventData["EVN_UID"], $eventData); + } else { + // if not exists then create it + $oldActUid = $eventData["EVN_UID"]; + $eventData["EVN_UID"] = Hash::generateUID(); + + $bwp->addEvent($eventData); + + $result[] = array("object" => "event", "new_uid" => $eventData["EVN_UID"], "old_uid" => $oldActUid); + $diagram["events"][$i] = $eventData; + } + + $whiteList[] = $eventData["EVN_UID"]; + } + + $events = $bwp->getEvents(); + + // looking for removed elements + foreach ($events as $eventData) { + if (! in_array($eventData["EVN_UID"], $whiteList)) { + // If it is not in the white list so, then remove them + $bwp->removeEvent($eventData["EVN_UID"]); + } + } + /* * Diagram's Flows Handling