From 7e3dc8aae322512dcad70067effe2674271270e9 Mon Sep 17 00:00:00 2001 From: Victor Saisa Lopez Date: Thu, 4 Dec 2014 11:40:52 -0400 Subject: [PATCH 1/3] PM-937 "Add Gateway to Gateway support" SOLVED Issue: Add Gateway to Gateway support Cause: Nueva solicitud de funciones Solution: - Se ha implementado esta nueva funcionalidad "Gateway to Gateway" de un BPMN-Project a un ProcessMaker-Project - Se ha agregado un nuevo tipo de Task (GATEWAYTOGATEWAY) que sirve de puente para conectar un Gateway con otro Gateway --- workflow/engine/classes/class.derivation.php | 247 ++++++++++-------- .../classes/model/map/TaskMapBuilder.php | 2 +- workflow/engine/config/schema.xml | 2 +- .../Project/Adapter/BpmnWorkflow.php | 186 +++++++------ .../src/ProcessMaker/Project/Workflow.php | 28 ++ 5 files changed, 278 insertions(+), 187 deletions(-) diff --git a/workflow/engine/classes/class.derivation.php b/workflow/engine/classes/class.derivation.php index b3e19e1f9..3a922e9a3 100755 --- a/workflow/engine/classes/class.derivation.php +++ b/workflow/engine/classes/class.derivation.php @@ -50,75 +50,73 @@ class Derivation var $case; /** - * prepareInformationTaskDerivation + * prepareInformationTask * - * @param array $arrayDerivation Derivation + * @param array $arrayTaskData Task data (derivation) * * return array Return array */ - public function prepareInformationTaskDerivation(array $arrayDerivation) + public function prepareInformationTask(array $arrayTaskData) { try { $task = new Task(); - $taskFields = $task->load($arrayDerivation["TAS_UID"]); + $arrayTaskData = G::array_merges($arrayTaskData, $task->load($arrayTaskData["TAS_UID"])); - $arrayDerivation = G::array_merges($arrayDerivation, $taskFields); + //2. If next case is an special case + if ((int)($arrayTaskData["ROU_NEXT_TASK"]) < 0) { + $arrayTaskData["NEXT_TASK"]["TAS_UID"] = (int)($arrayTaskData["ROU_NEXT_TASK"]); + $arrayTaskData["NEXT_TASK"]["TAS_ASSIGN_TYPE"] = "nobody"; + $arrayTaskData["NEXT_TASK"]["TAS_PRIORITY_VARIABLE"] = ""; + $arrayTaskData["NEXT_TASK"]["TAS_DEF_PROC_CODE"] = ""; + $arrayTaskData["NEXT_TASK"]["TAS_PARENT"] = ""; + $arrayTaskData["NEXT_TASK"]["TAS_TRANSFER_FLY"] = ""; - //2. if next case is an special case - if ((int)($arrayDerivation["ROU_NEXT_TASK"]) < 0) { - $arrayDerivation["NEXT_TASK"]["TAS_UID"] = (int)($arrayDerivation["ROU_NEXT_TASK"]); - $arrayDerivation["NEXT_TASK"]["TAS_ASSIGN_TYPE"] = "nobody"; - $arrayDerivation["NEXT_TASK"]["TAS_PRIORITY_VARIABLE"] = ""; - $arrayDerivation["NEXT_TASK"]["TAS_DEF_PROC_CODE"] = ""; - $arrayDerivation["NEXT_TASK"]["TAS_PARENT"] = ""; - $arrayDerivation["NEXT_TASK"]["TAS_TRANSFER_FLY"] = ""; - - switch ($arrayDerivation["ROU_NEXT_TASK"]) { + switch ($arrayTaskData["ROU_NEXT_TASK"]) { case -1: - $arrayDerivation["NEXT_TASK"]["TAS_TITLE"] = G::LoadTranslation("ID_END_OF_PROCESS"); + $arrayTaskData["NEXT_TASK"]["TAS_TITLE"] = G::LoadTranslation("ID_END_OF_PROCESS"); break; case -2: - $arrayDerivation["NEXT_TASK"]["TAS_TITLE"] = G::LoadTranslation("ID_TAREA_COLGANTE"); + $arrayTaskData["NEXT_TASK"]["TAS_TITLE"] = G::LoadTranslation("ID_TAREA_COLGANTE"); break; } - $arrayDerivation["NEXT_TASK"]["USR_UID"] = ""; - $arrayDerivation["NEXT_TASK"]["USER_ASSIGNED"] = array("USR_UID" => ""); + $arrayTaskData["NEXT_TASK"]["USR_UID"] = ""; + $arrayTaskData["NEXT_TASK"]["USER_ASSIGNED"] = array("USR_UID" => ""); } else { - //3. load the task information of normal NEXT_TASK - $arrayDerivation["NEXT_TASK"] = $task->load($arrayDerivation["ROU_NEXT_TASK"]); //print $arrayDerivation["ROU_NEXT_TASK"]." **** ".$arrayDerivation["NEXT_TASK"]["TAS_TYPE"]."
"; + //3. Load the task information of normal NEXT_TASK + $arrayTaskData["NEXT_TASK"] = $task->load($arrayTaskData["ROU_NEXT_TASK"]); //print $arrayTaskData["ROU_NEXT_TASK"]." **** ".$arrayTaskData["NEXT_TASK"]["TAS_TYPE"]."
"; - if ($arrayDerivation["NEXT_TASK"]["TAS_TYPE"] == "SUBPROCESS") { - $sTaskParent = $arrayDerivation["NEXT_TASK"]["TAS_UID"]; + if ($arrayTaskData["NEXT_TASK"]["TAS_TYPE"] == "SUBPROCESS") { + $taskParent = $arrayTaskData["NEXT_TASK"]["TAS_UID"]; $criteria = new Criteria("workflow"); - $criteria->add(SubProcessPeer::PRO_PARENT, $arrayDerivation["PRO_UID"]); - $criteria->add(SubProcessPeer::TAS_PARENT, $arrayDerivation["NEXT_TASK"]["TAS_UID"]); + $criteria->add(SubProcessPeer::PRO_PARENT, $arrayTaskData["PRO_UID"]); + $criteria->add(SubProcessPeer::TAS_PARENT, $arrayTaskData["NEXT_TASK"]["TAS_UID"]); $rsCriteria = SubProcessPeer::doSelectRS($criteria); $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); $rsCriteria->next(); $row = $rsCriteria->getRow(); - $arrayDerivation["ROU_NEXT_TASK"] = $row["TAS_UID"]; //print "
Life is just a lonely highway"; - $arrayDerivation["NEXT_TASK"] = $task->load($arrayDerivation["ROU_NEXT_TASK"]); //print "
Life is just a lonely highway";print"
"; + $arrayTaskData["ROU_NEXT_TASK"] = $row["TAS_UID"]; //print "
Life is just a lonely highway"; + $arrayTaskData["NEXT_TASK"] = $task->load($arrayTaskData["ROU_NEXT_TASK"]); //print "
Life is just a lonely highway";print"
"; $process = new Process(); $row = $process->load($row["PRO_UID"]); - $arrayDerivation["NEXT_TASK"]["TAS_TITLE"] .= " (" . $row["PRO_TITLE"] . ")"; - $arrayDerivation["NEXT_TASK"]["TAS_PARENT"] = $sTaskParent; + $arrayTaskData["NEXT_TASK"]["TAS_TITLE"] .= " (" . $row["PRO_TITLE"] . ")"; + $arrayTaskData["NEXT_TASK"]["TAS_PARENT"] = $taskParent; - //unset($task, $process, $row, $sTaskParent); + //unset($task, $process, $row, $taskParent); } else { - $arrayDerivation["NEXT_TASK"]["TAS_PARENT"] = ""; + $arrayTaskData["NEXT_TASK"]["TAS_PARENT"] = ""; } - $arrayDerivation["NEXT_TASK"]["USER_ASSIGNED"] = $this->getNextAssignedUser($arrayDerivation); + $arrayTaskData["NEXT_TASK"]["USER_ASSIGNED"] = ($arrayTaskData["NEXT_TASK"]["TAS_TYPE"] != "GATEWAYTOGATEWAY")? $this->getNextAssignedUser($arrayTaskData) : array("USR_UID" => ""); } //Return - return $arrayDerivation; + return $arrayTaskData; } catch (Exception $e) { throw $e; } @@ -127,92 +125,129 @@ class Derivation /** * prepareInformation * - * @param array $aData - * @return $taskInfo + * @param array $arrayData Data + * @param string $taskUid Unique id of Task + * + * return array Return array */ - function prepareInformation ($aData) + public function prepareInformation(array $arrayData, $taskUid = "") { - $oTask = new Task(); - //SELECT * - //FROM APP_DELEGATION AS A - //LEFT JOIN TASK AS T ON(T.TAS_UID = A.TAS_UID) - //LEFT JOIN ROUTE AS R ON(R.TAS_UID = A.TAS_UID) - //WHERE - //APP_UID = '$aData['APP_UID']' - //AND DEL_INDEX = '$aData['DEL_INDEX']' - $c = new Criteria( 'workflow' ); - $c->clearSelectColumns(); - $c->addSelectColumn(AppDelegationPeer::TAS_UID); - $c->addSelectColumn(RoutePeer::ROU_NEXT_TASK); - $c->addSelectColumn(RoutePeer::ROU_TYPE); - $c->addSelectColumn(RoutePeer::ROU_DEFAULT); - $c->addSelectColumn(RoutePeer::ROU_CONDITION); - $c->addJoin( AppDelegationPeer::TAS_UID, TaskPeer::TAS_UID, Criteria::LEFT_JOIN ); - $c->addJoin( AppDelegationPeer::TAS_UID, RoutePeer::TAS_UID, Criteria::LEFT_JOIN ); - $c->add( AppDelegationPeer::APP_UID, $aData['APP_UID'] ); - $c->add( AppDelegationPeer::DEL_INDEX, $aData['DEL_INDEX'] ); - $c->addAscendingOrderByColumn( RoutePeer::ROU_CASE ); - $rs = AppDelegationPeer::doSelectRs( $c ); - $rs->setFetchmode( ResultSet::FETCHMODE_ASSOC ); - $rs->next(); - $aDerivation = $rs->getRow(); - $i = 0; - $taskInfo = array(); - $arrayDerivationDefault = array(); - - $oUser = new Users(); - if (!class_exists('Cases')) { - G::LoadClass('case'); - } - $this->case = new Cases(); - // 1. there is no rule - if (is_null( $aDerivation['ROU_NEXT_TASK'] )) { - throw (new Exception( G::LoadTranslation( 'ID_NO_DERIVATION_RULE' ) )); - } - - while (is_array( $aDerivation )) { - $aDerivation = G::array_merges($aDerivation, $aData); - - if ((int)($aDerivation["ROU_DEFAULT"]) == 1) { - $arrayDerivationDefault = $aDerivation; + try { + if (!class_exists("Cases")) { + G::LoadClass("case"); } - $bContinue = true; + $this->case = new Cases(); + $task = new Task(); - //evaluate the condition if there are conditions defined. - if (isset( $aDerivation['ROU_CONDITION'] ) && trim( $aDerivation['ROU_CONDITION'] ) != '' && ($aDerivation['ROU_TYPE'] != 'SELECT' || $aDerivation['ROU_TYPE'] == 'PARALLEL-BY-EVALUATION')) { - $AppFields = $this->case->loadCase( $aData['APP_UID'] ); - G::LoadClass( 'pmScript' ); - $oPMScript = new PMScript(); - $oPMScript->setFields( $AppFields['APP_DATA'] ); - $oPMScript->setScript( $aDerivation['ROU_CONDITION'] ); - $bContinue = $oPMScript->evaluate(); + $arrayNextTask = array(); + $arrayNextTaskDefault = array(); + $i = 0; + + //SELECT * + //FROM APP_DELEGATION AS A + //LEFT JOIN TASK AS T ON(T.TAS_UID = A.TAS_UID) + //LEFT JOIN ROUTE AS R ON(R.TAS_UID = A.TAS_UID) + //WHERE + //APP_UID = '$arrayData["APP_UID"]' + //AND DEL_INDEX = '$arrayData["DEL_INDEX"]' + + $criteria = new Criteria("workflow"); + + $criteria->addSelectColumn(RoutePeer::TAS_UID); + $criteria->addSelectColumn(RoutePeer::ROU_NEXT_TASK); + $criteria->addSelectColumn(RoutePeer::ROU_TYPE); + $criteria->addSelectColumn(RoutePeer::ROU_DEFAULT); + $criteria->addSelectColumn(RoutePeer::ROU_CONDITION); + + if ($taskUid != "") { + $criteria->add(RoutePeer::TAS_UID, $taskUid, Criteria::EQUAL); + $criteria->addAscendingOrderByColumn(RoutePeer::ROU_CASE); + + $rsCriteria = RoutePeer::doSelectRS($criteria); + } else { + $criteria->addJoin(AppDelegationPeer::TAS_UID, TaskPeer::TAS_UID, Criteria::LEFT_JOIN); + $criteria->addJoin(AppDelegationPeer::TAS_UID, RoutePeer::TAS_UID, Criteria::LEFT_JOIN); + $criteria->add(AppDelegationPeer::APP_UID, $arrayData["APP_UID"], Criteria::EQUAL); + $criteria->add(AppDelegationPeer::DEL_INDEX, $arrayData["DEL_INDEX"], Criteria::EQUAL); + $criteria->addAscendingOrderByColumn(RoutePeer::ROU_CASE); + + $rsCriteria = AppDelegationPeer::doSelectRS($criteria); } - if ($aDerivation['ROU_TYPE'] == 'EVALUATE') { - if (count( $taskInfo ) >= 1) { - $bContinue = false; + $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + while ($rsCriteria->next()) { + $arrayRouteData = G::array_merges($rsCriteria->getRow(), $arrayData); + + if ((int)($arrayRouteData["ROU_DEFAULT"]) == 1) { + $arrayNextTaskDefault = $arrayRouteData; + } + + $flagContinue = true; + + //Evaluate the condition if there are conditions defined + if (isset($arrayRouteData["ROU_CONDITION"]) && trim($arrayRouteData["ROU_CONDITION"]) != "" && ($arrayRouteData["ROU_TYPE"] != "SELECT" || $arrayRouteData["ROU_TYPE"] == "PARALLEL-BY-EVALUATION")) { + G::LoadClass("pmScript"); + + $arrayApplicationData = $this->case->loadCase($arrayData["APP_UID"]); + + $pmScript = new PMScript(); + $pmScript->setFields($arrayApplicationData["APP_DATA"]); + $pmScript->setScript($arrayRouteData["ROU_CONDITION"]); + $flagContinue = $pmScript->evaluate(); + } + + if (isset($arrayRouteData["ROU_CONDITION"]) && trim($arrayRouteData["ROU_CONDITION"]) == "" && $arrayRouteData["ROU_NEXT_TASK"] != "-1") { + $arrayTaskData = $task->load($arrayRouteData["ROU_NEXT_TASK"]); + + if ($arrayTaskData["TAS_TYPE"] == "GATEWAYTOGATEWAY") { + $flagContinue = false; + } + } + + if ($arrayRouteData["ROU_TYPE"] == "EVALUATE" && count($arrayNextTask) > 0) { + $flagContinue = false; + } + + if ($flagContinue) { + $arrayNextTask[++$i] = $this->prepareInformationTask($arrayRouteData); } } - if ($bContinue) { - $i++; - - $taskInfo[$i] = $this->prepareInformationTaskDerivation($aDerivation); + if (count($arrayNextTask) == 0 && count($arrayNextTaskDefault) > 0) { + $arrayNextTask[++$i] = $this->prepareInformationTask($arrayNextTaskDefault); } - $rs->next(); - $aDerivation = $rs->getRow(); + //Check Task GATEWAYTOGATEWAY + $arrayNextTaskBk = $arrayNextTask; + $arrayNextTask = array(); + $i = 0; + + foreach ($arrayNextTaskBk as $value) { + $arrayNextTaskData = $value; + + if ($arrayNextTaskData["NEXT_TASK"]["TAS_UID"] != "-1" && $arrayNextTaskData["NEXT_TASK"]["TAS_TYPE"] == "GATEWAYTOGATEWAY") { + $arrayAux = $this->prepareInformation($arrayData, $arrayNextTaskData["NEXT_TASK"]["TAS_UID"]); + + foreach ($arrayAux as $value2) { + $arrayNextTask[++$i] = $value2; + } + } else { + $arrayNextTask[++$i] = $arrayNextTaskData; + } + } + + //1. There is no rule + if (count($arrayNextTask) == 0) { + throw new Exception(G::LoadTranslation("ID_NO_DERIVATION_RULE")); + } + + //Return + return $arrayNextTask; + } catch (Exception $e) { + throw $e; } - - if (count($taskInfo) == 0 && count($arrayDerivationDefault) > 0) { - $i++; - - $taskInfo[$i] = $this->prepareInformationTaskDerivation($arrayDerivationDefault); - } - - //Return - return $taskInfo; } /** diff --git a/workflow/engine/classes/model/map/TaskMapBuilder.php b/workflow/engine/classes/model/map/TaskMapBuilder.php index a3ed5c8a4..b48972412 100755 --- a/workflow/engine/classes/model/map/TaskMapBuilder.php +++ b/workflow/engine/classes/model/map/TaskMapBuilder.php @@ -159,7 +159,7 @@ class TaskMapBuilder /*----------------------------------********---------------------------------*/ $tMap->addColumn('TAS_SELFSERVICE_EXECUTION', 'TasSelfserviceExecution', 'string', CreoleTypes::VARCHAR, false, 15); /*----------------------------------********---------------------------------*/ - $tMap->addValidator('TAS_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|ADHOC|SUBPROCESS|HIDDEN', 'Please select a valid value for TAS_TYPE.'); + $tMap->addValidator('TAS_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|ADHOC|SUBPROCESS|HIDDEN|GATEWAYTOGATEWAY', 'Please enter a valid value for TAS_TYPE'); $tMap->addValidator('TAS_TIMEUNIT', 'validValues', 'propel.validator.ValidValuesValidator', 'MINUTES|HOURS|DAYS|WEEKS|MONTHS', 'Please select a valid value for TAS_TIMEUNIT.'); diff --git a/workflow/engine/config/schema.xml b/workflow/engine/config/schema.xml index d6cb61027..c19f8ba8d 100755 --- a/workflow/engine/config/schema.xml +++ b/workflow/engine/config/schema.xml @@ -1248,7 +1248,7 @@ - + diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index 813f0f168..d1c19fbb2 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -436,104 +436,132 @@ class BpmnWorkflow extends Project\Bpmn } } + public function mapBpmnGatewayToWorkflowRoutes($activityUid, $gatewayUid) + { + try { + $arrayGatewayData = \BpmnGateway::findOneBy(\BpmnGatewayPeer::GAT_UID, $gatewayUid)->toArray(); + + switch ($arrayGatewayData["GAT_TYPE"]) { + //case "SELECTION": + case self::BPMN_GATEWAY_COMPLEX: + $routeType = "SELECT"; + break; + //case "EVALUATION": + case self::BPMN_GATEWAY_EXCLUSIVE: + $routeType = "EVALUATE"; + break; + //case "PARALLEL": + case self::BPMN_GATEWAY_PARALLEL: + if ($arrayGatewayData["GAT_DIRECTION"] == "DIVERGING") { + $routeType = "PARALLEL"; + } else { + if ($arrayGatewayData["GAT_DIRECTION"] == "CONVERGING") { + $routeType = "SEC-JOIN"; + } else { + throw new \LogicException( + "Invalid Gateway direction, accepted values: [DIVERGING|CONVERGING], given: " . $arrayGatewayData["GAT_DIRECTION"] + ); + } + } + break; + //case "PARALLEL_EVALUATION": + case self::BPMN_GATEWAY_INCLUSIVE: + if ($arrayGatewayData["GAT_DIRECTION"] == "DIVERGING") { + $routeType = "PARALLEL-BY-EVALUATION"; + } else { + if ($arrayGatewayData["GAT_DIRECTION"] == "CONVERGING") { + $routeType = "SEC-JOIN"; + } else { + throw new \LogicException( + "Invalid Gateway direction, accepted values: [DIVERGING|CONVERGING], given: " . $arrayGatewayData["GAT_DIRECTION"] + ); + } + } + break; + default: + throw new \LogicException("Unsupported Gateway type: " . $arrayGatewayData["GAT_TYPE"]); + break; + } + + $arrayGatewayFlowData = \BpmnFlow::findAllBy(array( + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN => $gatewayUid, + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN_TYPE => "bpmnGateway" + )); + + if ($arrayGatewayFlowData > 0) { + $this->wp->resetTaskRoutes($activityUid); + } + + foreach ($arrayGatewayFlowData as $value) { + $arrayFlowData = $value->toArray(); + + $routeDefault = (array_key_exists("FLO_TYPE", $arrayFlowData) && $arrayFlowData["FLO_TYPE"] == "DEFAULT")? 1 : 0; + $routeCondition = (array_key_exists("FLO_CONDITION", $arrayFlowData))? $arrayFlowData["FLO_CONDITION"] : ""; + + switch ($arrayFlowData["FLO_ELEMENT_DEST_TYPE"]) { + case "bpmnActivity": + case "bpmnEvent": + //Gateway ----> Activity + //Gateway ----> Event + if ($arrayFlowData["FLO_ELEMENT_DEST_TYPE"] == "bpmnEvent") { + $event = \BpmnEventPeer::retrieveByPK($arrayFlowData["FLO_ELEMENT_DEST"]); + + if ($event->getEvnType() == "END") { + $result = $this->wp->addRoute($activityUid, -1, $routeType, $routeCondition, $routeDefault); + } + } else { + $result = $this->wp->addRoute($activityUid, $arrayFlowData["FLO_ELEMENT_DEST"], $routeType, $routeCondition, $routeDefault); + } + break; + case "bpmnGateway": + //Gateway ----> Gateway + $taskUid = $this->wp->addTask(array( + "TAS_TYPE" => "GATEWAYTOGATEWAY", + "TAS_TITLE" => "GATEWAYTOGATEWAY", + "TAS_POSX" => (int)($arrayFlowData["FLO_X1"]), + "TAS_POSY" => (int)($arrayFlowData["FLO_Y1"]) + )); + + $result = $this->wp->addRoute($activityUid, $taskUid, $routeType, $routeCondition, $routeDefault); + + $this->mapBpmnGatewayToWorkflowRoutes($taskUid, $arrayFlowData["FLO_ELEMENT_DEST"]); + break; + default: + //For processmaker is only allowed flows between: "gateway -> activity", "gateway -> gateway" + //any another flow is considered invalid + throw new \LogicException( + "For ProcessMaker is only allowed flows between: \"gateway -> activity\", \"gateway -> gateway\" " . PHP_EOL . + "Given: bpmnGateway -> " . $arrayFlowData["FLO_ELEMENT_DEST_TYPE"] + ); + } + } + } catch (\Exception $e) { + throw $e; + } + } + public function mapBpmnFlowsToWorkflowRoutes() { + $this->wp->deleteTaskGatewayToGateway($this->wp->getUid()); + $activities = $this->getActivities(); foreach ($activities as $activity) { - $flows = \BpmnFlow::findAllBy(array( \BpmnFlowPeer::FLO_ELEMENT_ORIGIN => $activity["ACT_UID"], \BpmnFlowPeer::FLO_ELEMENT_ORIGIN_TYPE => "bpmnActivity" )); - // foreach ($flows as $flow) { switch ($flow->getFloElementDestType()) { case "bpmnActivity": // (activity -> activity) $this->wp->addRoute($activity["ACT_UID"], $flow->getFloElementDest(), "SEQUENTIAL"); break; - case "bpmnGateway": // (activity -> gateway) // we must find the related flows: gateway -> - $gatUid = $flow->getFloElementDest(); - $gatewayFlows = \BpmnFlow::findAllBy(array( - \BpmnFlowPeer::FLO_ELEMENT_ORIGIN => $gatUid, - \BpmnFlowPeer::FLO_ELEMENT_ORIGIN_TYPE => "bpmnGateway" - )); - - if ($gatewayFlows > 0) { - $this->wp->resetTaskRoutes($activity["ACT_UID"]); - } - - foreach ($gatewayFlows as $gatewayFlow) { - $gatewayFlow = $gatewayFlow->toArray(); - - switch ($gatewayFlow['FLO_ELEMENT_DEST_TYPE']) { - case 'bpmnEvent': - case 'bpmnActivity': - // (gateway -> activity) - $gateway = \BpmnGateway::findOneBy(\BpmnGatewayPeer::GAT_UID, $gatUid)->toArray(); - switch ($gateway["GAT_TYPE"]) { - //case 'SELECTION': - case self::BPMN_GATEWAY_COMPLEX: - $routeType = "SELECT"; - break; - //case 'EVALUATION': - case self::BPMN_GATEWAY_EXCLUSIVE: - $routeType = "EVALUATE"; - break; - //case 'PARALLEL': - case self::BPMN_GATEWAY_PARALLEL: - if ($gateway["GAT_DIRECTION"] == "DIVERGING") { - $routeType = "PARALLEL"; - } elseif ($gateway["GAT_DIRECTION"] == "CONVERGING") { - $routeType = "SEC-JOIN"; - } else { - throw new \LogicException(sprintf( - "Invalid Gateway direction, accepted values: [%s|%s], given: %s.", - "DIVERGING", "CONVERGING", $gateway["GAT_DIRECTION"] - )); - } - break; - //case 'PARALLEL_EVALUATION': - case self::BPMN_GATEWAY_INCLUSIVE: - if ($gateway["GAT_DIRECTION"] == "DIVERGING") { - $routeType = "PARALLEL-BY-EVALUATION"; - } elseif ($gateway["GAT_DIRECTION"] == "CONVERGING") { - $routeType = "SEC-JOIN"; - } else { - throw new \LogicException(sprintf( - "Invalid Gateway direction, accepted values: [%s|%s], given: %s.", - "DIVERGING", "CONVERGING", $gateway["GAT_DIRECTION"] - )); - } - break; - default: - throw new \LogicException(sprintf("Unsupported Gateway type: %s", $gateway['GAT_TYPE'])); - } - $condition = array_key_exists('FLO_CONDITION', $gatewayFlow) ? $gatewayFlow["FLO_CONDITION"] : ''; - - if ($gatewayFlow['FLO_ELEMENT_DEST_TYPE'] == 'bpmnEvent') { - $event = \BpmnEventPeer::retrieveByPK($gatewayFlow['FLO_ELEMENT_DEST']); - if ($event->getEvnType() == "END") { - $this->wp->addRoute($activity["ACT_UID"], -1, $routeType, $condition); - } - } else { - $this->wp->addRoute($activity["ACT_UID"], $gatewayFlow["FLO_ELEMENT_DEST"], $routeType, $condition, ($gatewayFlow["FLO_TYPE"] == "DEFAULT")? 1 : 0); - } - 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 -> " . $gatewayFlow['FLO_ELEMENT_DEST_TYPE'] - )); - } - } + $this->mapBpmnGatewayToWorkflowRoutes($activity["ACT_UID"], $flow->getFloElementDest()); break; } } diff --git a/workflow/engine/src/ProcessMaker/Project/Workflow.php b/workflow/engine/src/ProcessMaker/Project/Workflow.php index cfe469619..2cd8698a2 100644 --- a/workflow/engine/src/ProcessMaker/Project/Workflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Workflow.php @@ -1161,5 +1161,33 @@ class Workflow extends Handler throw $e; } } + + public function deleteTaskGatewayToGateway($processUid) + { + try { + $task = new \Tasks(); + + $criteria = new \Criteria("workflow"); + + $criteria->addSelectColumn(\TaskPeer::TAS_UID); + $criteria->add(\TaskPeer::PRO_UID, $processUid, \Criteria::EQUAL); + $criteria->add(\TaskPeer::TAS_TYPE, "GATEWAYTOGATEWAY", \Criteria::EQUAL); + + $rsCriteria = \TaskPeer::doSelectRS($criteria); + $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + while ($rsCriteria->next()) { + $row = $rsCriteria->getRow(); + + $taskUid = $row["TAS_UID"]; + + $task->deleteTask($taskUid); + } + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + + throw $e; + } + } } From da7f546adeff31eaa12c36335f33fa70fc8b96bd Mon Sep 17 00:00:00 2001 From: Victor Saisa Lopez Date: Tue, 9 Dec 2014 10:50:14 -0400 Subject: [PATCH 2/3] PM-1099 "El archivo plugin.singleton se reescribe muchas..." SOLVED Issue: El archivo plugin.singleton se reescribe muchas veces para un solo request Cause: Al instanciar un objeto de la clase "pmLicenseManager" se hace una llamada al metodo "activateFeatures", y este proceso ocasiona que cuando un usuario haga un request a un determinado modulo de ProcessMaker se hagan varias llamadas al metodo "activateFeatures" Solution: Se ha agregado un parametro al contructor de la clase "pmLicenseManager" el cual evita la ejecucion del metodo "activateFeatures" --- workflow/engine/classes/class.licensedFeatures.php | 3 ++- workflow/engine/classes/class.pmLicenseManager.php | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/workflow/engine/classes/class.licensedFeatures.php b/workflow/engine/classes/class.licensedFeatures.php index a7baf8d45..2136ec33c 100644 --- a/workflow/engine/classes/class.licensedFeatures.php +++ b/workflow/engine/classes/class.licensedFeatures.php @@ -68,7 +68,8 @@ class PMLicensedFeatures if (!class_exists("pmLicenseManager")) { require_once ("classes" . PATH_SEP . "class.pmLicenseManager.php"); } - $licenseManager = pmLicenseManager::getSingleton(); + + $licenseManager = pmLicenseManager::getSingleton(false); $_SESSION['__sw__'] = true; $padl = new padl(); diff --git a/workflow/engine/classes/class.pmLicenseManager.php b/workflow/engine/classes/class.pmLicenseManager.php index e2b2dd7a4..4e95560e2 100644 --- a/workflow/engine/classes/class.pmLicenseManager.php +++ b/workflow/engine/classes/class.pmLicenseManager.php @@ -10,7 +10,7 @@ class pmLicenseManager private static $instance = null; - public function __construct() + public function __construct($flagActivatePlugins = true) { G::LoadClass('serverConfiguration'); $oServerConf = &serverConf::getSingleton(); @@ -109,13 +109,15 @@ class pmLicenseManager $oServerConf->setProperty ( 'LICENSE_INFO', $licInfoA ); } - $this->activateFeatures (); + if ($flagActivatePlugins) { + $this->activateFeatures(); + } } - public static function getSingleton() + public static function getSingleton($flagActivatePlugins = true) { if (self::$instance == null) { - self::$instance = new pmLicenseManager(); + self::$instance = new pmLicenseManager($flagActivatePlugins); } return self::$instance; } From a1be8644ae376a08077bc9dcd05a7028f328df82 Mon Sep 17 00:00:00 2001 From: Victor Saisa Lopez Date: Tue, 9 Dec 2014 17:08:50 -0400 Subject: [PATCH 3/3] PM-1105 "Al actualizar ProcessMaker de la version 2.5.2 a..." SOLVED Issue: Al actualizar ProcessMaker de la version 2.5.2 a la version 2.8 se pierden los dashboard configurados con el advanced dashboard Cause: Este problema es debido a que se ha modificado un dashlet que el sistema a creado, y el sistema restaura justamente esos registros en cada upgrade Solution: Se esta quitando los DASHLET_INSTANCE del archivo "check.data" para que no los actualize en cada upgrade --- workflow/engine/data/check.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow/engine/data/check.data b/workflow/engine/data/check.data index 3cc35a488..48e6e2e09 100644 --- a/workflow/engine/data/check.data +++ b/workflow/engine/data/check.data @@ -1 +1 @@ -a:8:{i:0;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000001";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:22:"dashletOpenVSCompleted";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:29:"Open Cases VS Completed Cases";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:29:"Open Cases VS Completed Cases";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2011-10-28 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2011-10-28 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:1;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000002";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:28:"dashletProcessMakerCommunity";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:22:"ProcessMaker Community";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:44:"ProcessMaker Community Links and Information";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-01 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-01 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";s:1:"1";}}s:6:"action";i:4;}i:2;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000003";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:29:"dashletProcessMakerEnterprise";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:42:"ProcessMaker Enterprise Plugins and Addons";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:147:"The following list of Enterprise plug-ins includes features and functionality that extend and enhance ProcessMaker's performance and functionality.";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:10:"2011-12-05";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:10:"2011-12-05";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:3;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000004";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:16:"dashletRssReader";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:17:"Simple RSS reader";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:34:"Simple RSS reader for ProcessMaker";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2012-04-16 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2012-04-16 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:4;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:16:"DASHLET_INSTANCE";s:4:"keys";a:1:{i:0;s:11:"DAS_INS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:11:"DAS_INS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000001";}i:1;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000001";}i:2;a:3:{s:5:"field";s:18:"DAS_INS_OWNER_TYPE";s:4:"type";s:4:"text";s:5:"value";s:9:"EVERYBODY";}i:3;a:3:{s:5:"field";s:17:"DAS_INS_OWNER_UID";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:4;a:3:{s:5:"field";s:29:"DAS_INS_ADDITIONAL_PROPERTIES";s:4:"type";s:4:"text";s:5:"value";s:224:"a:7:{s:20:"DAS_INS_CONTEXT_TIME";s:5:"TODAY";s:12:"DAS_RED_FROM";s:1:"0";s:10:"DAS_RED_TO";s:2:"30";s:15:"DAS_YELLOW_FROM";s:2:"30";s:13:"DAS_YELLOW_TO";s:2:"50";s:14:"DAS_GREEN_FROM";s:2:"50";s:12:"DAS_GREEN_TO";s:3:"100";}";}i:5;a:3:{s:5:"field";s:19:"DAS_INS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-02 00:00:00";}i:6;a:3:{s:5:"field";s:19:"DAS_INS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-02 00:00:00";}i:7;a:3:{s:5:"field";s:14:"DAS_INS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:5;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:16:"DASHLET_INSTANCE";s:4:"keys";a:1:{i:0;s:11:"DAS_INS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:11:"DAS_INS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000002";}i:1;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000002";}i:2;a:3:{s:5:"field";s:18:"DAS_INS_OWNER_TYPE";s:4:"type";s:4:"text";s:5:"value";s:9:"EVERYBODY";}i:3;a:3:{s:5:"field";s:17:"DAS_INS_OWNER_UID";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:4;a:3:{s:5:"field";s:29:"DAS_INS_ADDITIONAL_PROPERTIES";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:5;a:3:{s:5:"field";s:19:"DAS_INS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-02 00:00:00";}i:6;a:3:{s:5:"field";s:19:"DAS_INS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-02 00:00:00";}i:7;a:3:{s:5:"field";s:14:"DAS_INS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:6;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:16:"DASHLET_INSTANCE";s:4:"keys";a:1:{i:0;s:11:"DAS_INS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:11:"DAS_INS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000003";}i:1;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000003";}i:2;a:3:{s:5:"field";s:18:"DAS_INS_OWNER_TYPE";s:4:"type";s:4:"text";s:5:"value";s:9:"EVERYBODY";}i:3;a:3:{s:5:"field";s:17:"DAS_INS_OWNER_UID";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:4;a:3:{s:5:"field";s:29:"DAS_INS_ADDITIONAL_PROPERTIES";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:5;a:3:{s:5:"field";s:19:"DAS_INS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-05 00:00:00";}i:6;a:3:{s:5:"field";s:19:"DAS_INS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-05 00:00:00";}i:7;a:3:{s:5:"field";s:14:"DAS_INS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:7;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:16:"DASHLET_INSTANCE";s:4:"keys";a:1:{i:0;s:11:"DAS_INS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:11:"DAS_INS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000004";}i:1;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000004";}i:2;a:3:{s:5:"field";s:18:"DAS_INS_OWNER_TYPE";s:4:"type";s:4:"text";s:5:"value";s:9:"EVERYBODY";}i:3;a:3:{s:5:"field";s:17:"DAS_INS_OWNER_UID";s:4:"type";s:4:"text";s:5:"value";s:0:"";}i:4;a:3:{s:5:"field";s:29:"DAS_INS_ADDITIONAL_PROPERTIES";s:4:"type";s:4:"text";s:5:"value";s:143:"a:2:{s:13:"DAS_INS_TITLE";s:15:"PM Plugins News";s:7:"DAS_URL";s:71:"http://license.processmaker.com/syspmLicenseSrv/en/green/services/rssAP";}";}i:5;a:3:{s:5:"field";s:19:"DAS_INS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2012-04-16 00:00:00";}i:6;a:3:{s:5:"field";s:19:"DAS_INS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2012-04-16 00:00:00";}i:7;a:3:{s:5:"field";s:14:"DAS_INS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}} \ No newline at end of file +a:4:{i:0;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000001";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:22:"dashletOpenVSCompleted";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:29:"Open Cases VS Completed Cases";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:29:"Open Cases VS Completed Cases";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2011-10-28 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2011-10-28 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:1;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000002";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:28:"dashletProcessMakerCommunity";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:22:"ProcessMaker Community";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:44:"ProcessMaker Community Links and Information";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-01 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:19:"2011-12-01 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";s:1:"1";}}s:6:"action";i:4;}i:2;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000003";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:29:"dashletProcessMakerEnterprise";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:42:"ProcessMaker Enterprise Plugins and Addons";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:147:"The following list of Enterprise plug-ins includes features and functionality that extend and enhance ProcessMaker's performance and functionality.";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:10:"2011-12-05";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:10:"2011-12-05";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}i:3;a:5:{s:2:"db";s:2:"wf";s:5:"table";s:7:"DASHLET";s:4:"keys";a:1:{i:0;s:7:"DAS_UID";}s:4:"data";a:8:{i:0;a:3:{s:5:"field";s:7:"DAS_UID";s:4:"type";s:4:"text";s:5:"value";s:32:"00000000000000000000000000000004";}i:1;a:3:{s:5:"field";s:9:"DAS_CLASS";s:4:"type";s:4:"text";s:5:"value";s:16:"dashletRssReader";}i:2;a:3:{s:5:"field";s:9:"DAS_TITLE";s:4:"type";s:4:"text";s:5:"value";s:17:"Simple RSS reader";}i:3;a:3:{s:5:"field";s:15:"DAS_DESCRIPTION";s:4:"type";s:4:"text";s:5:"value";s:34:"Simple RSS reader for ProcessMaker";}i:4;a:3:{s:5:"field";s:11:"DAS_VERSION";s:4:"type";s:4:"text";s:5:"value";s:3:"1.0";}i:5;a:3:{s:5:"field";s:15:"DAS_CREATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2012-04-16 00:00:00";}i:6;a:3:{s:5:"field";s:15:"DAS_UPDATE_DATE";s:4:"type";s:4:"date";s:5:"value";s:20:" 2012-04-16 00:00:00";}i:7;a:3:{s:5:"field";s:10:"DAS_STATUS";s:4:"type";s:3:"int";s:5:"value";i:1;}}s:6:"action";i:4;}} \ No newline at end of file