diff --git a/composer.json b/composer.json index 3e840153f..143db58e7 100644 --- a/composer.json +++ b/composer.json @@ -48,6 +48,7 @@ }, "require-dev":{ "guzzle/guzzle":"~3.1.1", - "behat/behat":"2.4.*@stable" + "behat/behat":"2.4.*@stable", + "lisachenko/go-aop-php": "*" } } diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index b5f57c0b7..e8f56f694 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -144,10 +144,12 @@ class BpmnWorkflow extends Project\Bpmn // 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); + $routes = self::mapBpmnFlowsToWorkflowRoute($data, $flows, $gateways, $events); - if ($routeData !== null) { - $this->wp->addRoute($routeData["from"], $routeData["to"], $routeData["type"]); + if ($routes !== null) { + foreach ($routes as $routeData) { + $this->wp->addRoute($routeData["from"], $routeData["to"], $routeData["type"]); + } return true; } @@ -215,26 +217,13 @@ class BpmnWorkflow extends Project\Bpmn } } - - -//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']; + $result = array(); if ($flow['FLO_ELEMENT_ORIGIN_TYPE'] != "bpmnActivity") { // skip flows that comes from a element that is not an Activity @@ -252,103 +241,89 @@ class BpmnWorkflow extends Project\Bpmn switch ($flow['FLO_ELEMENT_DEST_TYPE']) { case 'bpmnActivity': // the most easy case, when the flow is connecting a activity with another activity - $result = array("from" => $fromUid, "to" => $flow['FLO_ELEMENT_DEST'], "type" => 'SEQUENTIAL'); + $result[] = array("from" => $fromUid, "to" => $flow['FLO_ELEMENT_DEST'], "type" => 'SEQUENTIAL'); break; case 'bpmnGateway': $gatUid = $flow['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 = self::findInArray($gatUid, "FLO_ELEMENT_ORIGIN", $flows); + $gatFlows = self::findInArray($gatUid, "FLO_ELEMENT_ORIGIN", $flows); - //foreach ($gatFlows as $gatFlow) { - switch ($gatFlow['FLO_ELEMENT_DEST_TYPE']) { - case 'bpmnActivity': - // getting gateway properties - //$gateway = BpmnModel::getBpmnObjectBy('Gateway', \BpmnGatewayPeer::GAT_UID, $gatUid); - $gateway = self::findInArray($gatUid, "GAT_UID", $gateways); + foreach ($gatFlows as $gatFlow) { + switch ($gatFlow['FLO_ELEMENT_DEST_TYPE']) { + case 'bpmnActivity': + // getting gateway properties + $gateways = self::findInArray($gatUid, "GAT_UID", $gateways); - 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'])); - } + if (! empty($gateways)) { + $gateway = $gateways[0]; - /*$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 - );*/ + 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'])); + } - //$this->wp->addRoute($fromUid, $gatFlow['FLO_ELEMENT_DEST'], $routeType); - $result = array("from" => $fromUid, "to" => $gatFlow['FLO_ELEMENT_DEST'], "type" => $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'] - )); + $result[] = array("from" => $fromUid, "to" => $gatFlow['FLO_ELEMENT_DEST'], "type" => $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 = $flow['FLO_ELEMENT_DEST']; - //$event = BpmnModel::getBpmnObjectBy('Event', \BpmnEventPeer::EVN_UID, $evnUid); - $event = self::findInArray($evnUid, "EVN_UID", $events); + $events = self::findInArray($evnUid, "EVN_UID", $events); - 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' - );*/ - $result = array("from" => $fromUid, "to" => "-1", "type" => $routeType); - break; - default: - throw new \LogicException("Invalid connection to Event object type"); + if (! empty($events)) { + $event = $events[0]; + + switch ($event['EVN_TYPE']) { + case 'END': + $routeType = 'SEQUENTIAL'; + $result[] = array("from" => $fromUid, "to" => "-1", "type" => $routeType); + break; + default: + throw new \LogicException("Invalid connection to Event object type"); + } } - break; } - return $result; - + return empty($result) ? null : $result; } protected static function findInArray($value, $key, $list) { + $result = array(); + foreach ($list as $item) { - if (! array_key_exists($key, $item)) { - throw new \Exception("Error: key: $key does not exist in array: " . print_r($item, true)); - } - if ($item[$key] == $value) { - return $item; + if (array_key_exists($key, $item) && $item[$key] == $value) { + $result[] = $item; } } - return null; + return $result; } public function remove() diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index 14e4af98b..59fa5a78a 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -314,19 +314,15 @@ class Bpmn extends Handler } } - public function getEvent($evnUid) + public function getEvent($evnUid, $retType = 'array') { - if (empty($this->events) || ! array_key_exists($evnUid, $this->activities)) { - $event = EventPeer::retrieveByPK($evnUid); + $event = EventPeer::retrieveByPK($evnUid); - if (! is_object($event)) { - return null; - } - - $this->events[$evnUid] = $event; + if ($retType != "object" && ! empty($activity)) { + $event = $event->toArray(); } - return $this->events[$evnUid]; + return $event; } public function getEvents($start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) diff --git a/workflow/engine/src/ProcessMaker/Project/Workflow.php b/workflow/engine/src/ProcessMaker/Project/Workflow.php index 0795b3e05..9a9bd791d 100644 --- a/workflow/engine/src/ProcessMaker/Project/Workflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Workflow.php @@ -55,6 +55,7 @@ class Workflow extends Handler public function create($data) { try { + self::log("===> Executing -> ".__METHOD__, "Create Process with data:", $data); // setting defaults $data['PRO_UID'] = array_key_exists('PRO_UID', $data) ? $data['PRO_UID'] : Hash::generateUID(); @@ -86,8 +87,10 @@ class Workflow extends Handler $calendar->assignCalendarTo($this->proUid, $data["PRO_CALENDAR"], 'PROCESS'); } - } catch (Exception $e) { - throw new \RuntimeException($e); + self::log("Create Process Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; } } @@ -98,7 +101,14 @@ class Workflow extends Handler public function remove() { - $this->deleteProcess($this->proUid); + try { + self::log("===> Executing -> ".__METHOD__, "Remove Process with uid: {$this->proUid}"); + $this->deleteProcess($this->proUid); + self::log("Remove Process Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } } public static function getList($start = null, $limit = null, $filter = "", $changeCaseTo = CASE_UPPER) @@ -142,7 +152,7 @@ class Workflow extends Handler $taskData['PRO_UID'] = $this->proUid; try { - self::log("Add Task with data: ", $taskData); + self::log("===> Executing -> ".__METHOD__, "Add Task with data: ", $taskData); $task = new Task(); $tasUid = $task->create($taskData, false); self::log("Add Task Success!"); @@ -157,12 +167,10 @@ class Workflow extends Handler public function updateTask($tasUid, $taskData) { try { - self::log("Update Task: $tasUid", "With data: ", $taskData); - + self::log("===> Executing -> ".__METHOD__, "Update Task: $tasUid", "With data: ", $taskData); $task = new Task(); $taskData['TAS_UID'] = $tasUid; $result = $task->update($taskData); - self::log("Update Task Success!"); } catch (\Exception $e) { self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); @@ -175,11 +183,9 @@ class Workflow extends Handler public function removeTask($tasUid) { try { - self::log("Remove Task: $tasUid"); - + self::log("===> Executing -> ".__METHOD__, "Remove Task: $tasUid"); $task = new Task(); $task->remove($tasUid); - self::log("Remove Task Success!"); } catch (\Exception $e) { self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); @@ -276,15 +282,16 @@ class Workflow extends Handler } //if ($delete || $type == 0 || $type == 5 || $type == 8) { if ($delete || $type == 'SEQUENTIAL' || $type == 'SEC-JOIN' || $type == 'DISCRIMINATOR') { - $oTasks = new Tasks(); + //$oTasks = new Tasks(); - $oTasks->deleteAllRoutesOfTask($this->proUid, $fromTasUid); + //$oTasks->deleteAllRoutesOfTask($this->proUid, $fromTasUid); //$oTasks->deleteAllGatewayOfTask($this->proUid, $fromTasUid); } - self::log("Add Route Success!"); - return $this->saveNewPattern($this->proUid, $fromTasUid, $toTasUid, $type, $delete); + $result = $this->saveNewPattern($this->proUid, $fromTasUid, $toTasUid, $type, $delete); + self::log("Add Route Success! -> ", $result); + return $result; } catch (\Exception $e) { self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); throw $e; @@ -293,16 +300,32 @@ class Workflow extends Handler public function updateRoute($rouUid, $routeData) { - $route = new Route(); $routeData['ROU_UID'] = $rouUid; - $route->update($routeData); + + try { + self::log("===> Executing -> ".__METHOD__, "Update Route: $rouUid with data:", $routeData); + $route = new Route(); + $route->update($routeData); + self::log("Update Route Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } } public function removeRoute($rouUid) { - $route = new Route(); + try { + self::log("===> Executing -> ".__METHOD__, "Remove Route: $rouUid"); + $route = new Route(); + $result = $route->remove($rouUid); + self::log("Remove Route Success!"); - return $route->remove($rouUid); + return $result; + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } } public function getRoute($rouUid) diff --git a/workflow/engine/src/ProcessMaker/Util/Logger.php b/workflow/engine/src/ProcessMaker/Util/Logger.php index df6909148..ffae6b795 100644 --- a/workflow/engine/src/ProcessMaker/Util/Logger.php +++ b/workflow/engine/src/ProcessMaker/Util/Logger.php @@ -17,6 +17,12 @@ class Logger protected function __construct() { $this->logFile = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'processmaker.log'; + + if (! file_exists($this->logFile)) { + file_put_contents($this->logFile, ""); + chmod($this->logFile, 0777); + } + $this->fp = fopen($this->logFile, "a+"); } @@ -40,8 +46,8 @@ class Logger fwrite($this->fp, "- " . date('Y-m-d H:i:s') . " " . $arg . PHP_EOL); } - if (count($args) > 1) - fwrite($this->fp, PHP_EOL); + //if (count($args) > 1) + // fwrite($this->fp, PHP_EOL); } public static function log() diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index 6ee522c78..6bf19659f 100755 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -884,6 +884,20 @@ try { $RBAC = &RBAC::getSingleton( PATH_DATA, session_id() ); $RBAC->sSystem = 'PROCESSMAKER'; + +// if (\System::isDebugMode()) { +// $applicationAspectKernel = \Kernel\ApplicationAspectKernel::getInstance(); +// $applicationAspectKernel->init(array( +// 'debug' => true, // Use 'false' for production mode +// // Cache directory +// 'cacheDir' => sys_get_temp_dir() . DIRECTORY_SEPARATOR, // Adjust this path if needed +// // Include paths restricts the directories where aspects should be applied, or empty for all source files +// 'includePaths' => array( +// PATH_HOME . 'engine/src/' +// ) +// )); +// } + // define and send Headers for all pages if (! defined( 'EXECUTE_BY_CRON' )) { header( "Expires: " . gmdate( "D, d M Y H:i:s", mktime( 0, 0, 0, date( 'm' ), date( 'd' ) - 1, date( 'Y' ) ) ) . " GMT" );