/** * Starts a workflow on a document. * * @author KnowledgeTree Team * @access public * @param string $workflow The workflow being applied * @return void|PEAR_Error Returns nothing on success | a PEAR_Error on failure */ function start_workflow($workflow) { $user = $this->can_user_access_object_requiring_permission($this->document, KTAPI_PERMISSION_WORKFLOW); if (PEAR::isError($user)) { return $user; } $workflowid = $this->document->getWorkflowId(); if (!empty($workflowid)) { return new PEAR_Error('A workflow is already defined.'); } $workflow = KTWorkflow::getByName($workflow); if (is_null($workflow) || PEAR::isError($workflow)) { return new KTAPI_Error(KTAPI_ERROR_WORKFLOW_INVALID, $workflow); } DBUtil::startTransaction(); $result = KTWorkflowUtil::startWorkflowOnDocument($workflow, $this->document); if (is_null($result) || PEAR::isError($result)) { DBUtil::rollback(); return new KTAPI_Error(KTAPI_ERROR_WORKFLOW_INVALID, $result); } DBUtil::commit(); }
function do_process_step1() { $fWizardKey = KTUtil::arrayGet($_REQUEST, 'fWizardKey'); if (!empty($fWizardKey)) { $this->errorRedirectToMain(_kt("Could not create workflow.")); exit; } $oForm =& $this->form_step1(); $res = $oForm->validate(); $data = $res['results']; // perform additional validation. $extra_errors = array(); $data['workflow_name'] = str_replace(array(' ', ' '), array(' ', ' '), $data['workflow_name']); $oWorkflow = KTWorkflow::getByName($data['workflow_name']); if (!PEAR::isError($oWorkflow)) { $extra_errors['workflow_name'][] = _kt("A workflow with that name already exists. Please choose a different name for this workflow."); } $initial_states = (array) explode("\n", $data['states']); // must be there, we validated it. $failed = array(); $states = array(); $is_first = true; $initial_state = ''; foreach ($initial_states as $sInitialStateName) { $state_name = trim($sInitialStateName); if (empty($state_name)) { continue; } if ($states[$state_name]) { $failed[] = $state_name; continue; } if ($is_first) { $is_first = false; $initial_state = $state_name; } $states[$state_name] = $state_name; } if (empty($states)) { $extra_errors['states'][] = _kt('You must provide at least one state name.'); } if (!empty($failed)) { $extra_errors['states'] = sprintf(_kt("You cannot have duplicate state names: %s"), implode(', ', $failed)); } $data['states'] = $states; $data['initial_state'] = $initial_state; $initial_transitions = (array) explode("\n", $data['transitions']); // must be there, we validated it. $failed = array(); $transitions = array(); foreach ($initial_transitions as $sInitialTransitionName) { $transition_name = trim($sInitialTransitionName); if (empty($transition_name)) { continue; } if ($transitions[$transition_name]) { $failed[] = $transition_name; continue; } $transitions[$transition_name] = $transition_name; } if (!empty($failed)) { $extra_errors['transitions'] = sprintf(_kt("You cannot have duplicate transition names: %s"), implode(', ', $failed)); } $data['transitions'] = $transitions; // handle errors. if (!empty($res['errors']) || !empty($extra_errors)) { $oForm->handleError(null, $extra_errors); } // store the data for a while. $wiz_data = (array) $_SESSION['_wiz_data']; $wiz_data[$fWizardKey] = $data; $_SESSION['_wiz_data'] =& $wiz_data; if (empty($data['transitions'])) { return $this->finalise(); // finish and go. } $this->successRedirectTo("step2", _kt("Initial data stored.")); }
function do_confirmCopy() { $oSelWorkflow = KTWorkflow::get(KTUtil::arrayGet($_REQUEST, 'workflowId', array())); $sWorkflowName = KTUtil::arrayGet($_REQUEST, 'workflowName', array()); // Check that the workflow does not exist already $sWorkflowName = str_replace(array(' ', ' '), array(' ', ' '), $sWorkflowName); $oWorkflow = KTWorkflow::getByName($sWorkflowName); if (!PEAR::isError($oWorkflow)) { return $this->errorRedirectToMain(_kt("A workflow with that name already exists. Please choose a different name for this workflow.")); } // create the initial workflow $oNewWorkflow = KTWorkflow::createFromArray(array('name' => $sWorkflowName, 'humanname' => $sWorkflowName, 'enabled' => true)); // get selected workflow states from database $oSelWorkflowStates = KTWorkflowState::getByWorkflow($oSelWorkflow); // array to store map of old and new states $aStatesMap = array(); // create new states and build old-to-new map foreach ($oSelWorkflowStates as $oOldState) { $oNewState = KTWorkflowState::createFromArray(array('workflowid' => $oNewWorkflow->getId(), 'name' => $oOldState->getName(), 'humanname' => $oOldState->getName())); $aStatesMap[oldId][] = $oOldState->getId(); $aStatesMap[newId][] = $oNewState->getId(); if (PEAR::isError($oNewState)) { $oForm->errorRedirectToMain(sprintf(_kt("Unexpected failure cloning state: %s"), $oNewState->getMessage())); } // Get all state permission assignments for old workflow transitions // and copy for copied workflow state permission assignments $aPermissionAssignments = KTWorkflowStatePermissionAssignment::getByState($oOldState); if (count($aPermissionAssignments) > 0) { foreach ($aPermissionAssignments as $oPermAssign) { for ($i = 0; $i < count($aStatesMap[oldId]); $i++) { if ($aStatesMap[oldId][$i] == $oPermAssign->getStateId()) { $iStateId = $aStatesMap[newId][$i]; $res = KTWorkflowStatePermissionAssignment::createFromArray(array('iStateId' => $iStateId, 'iPermissionId' => $oPermAssign->getPermissionId(), 'iDescriptorId' => $oPermAssign->getDescriptorId())); if (PEAR::isError($res)) { return $this->errorRedirectToMain(sprintf(_kt("Unable to copy state permission assignment: %s"), $res->getMessage())); } } } } } // Copy all disabled actions for states $aDisabled = KTWorkflowUtil::getDisabledActionsForState($oOldState); $res = KTWorkflowUtil::setDisabledActionsForState($oNewState, $aDisabled); // Copy all enabled actions for states $aDisabled = KTWorkflowUtil::getEnabledActionsForState($oOldState); $res = KTWorkflowUtil::setEnabledActionsForState($oNewState, $aDisabled); if (PEAR::isError($res)) { return $this->errorRedirectToMain(sprintf(_kt("Unable to copy disabled state actions: %s"), $res->getMessage())); } $this->copyStateNotifications($oOldState, $oNewState); } // update workflow and set initial state for ($i = 0; $i < count($aStatesMap[oldId]); $i++) { if ($oSelWorkflow->getStartStateId() == $aStatesMap[oldId][$i]) { $oNewWorkflow->setStartStateId($aStatesMap[newId][$i]); $res = $oNewWorkflow->update(); if (PEAR::isError($res)) { $this->errorRedirectToMain(sprintf(_kt("Failed to update workflow: %s"), $res->getMessage())); } } } // set controlled workflow actions $aWFActions = KTWorkflowUtil::getControlledActionsForWorkflow($oSelWorkflow); $res = KTWorkflowUtil::setControlledActionsForWorkflow($oNewWorkflow, $aWFActions); if (PEAR::isError($res)) { $this->errorRedirectToMain(sprintf(_kt("Failed to copy workflow controlled actions: %s"), $res->getMessage())); } // get selected workflow transitions from database $oSelWorkflowTransitions = KTWorkflowTransition::getByWorkflow($oSelWorkflow); // array to store map of old and new transitions $aTransitionsMap = array(); // copy transitions for workflow foreach ($oSelWorkflowTransitions as $oOldTransition) { for ($i = 0; $i < count($aStatesMap[oldId]); $i++) { if ($oOldTransition->getTargetStateId() == $aStatesMap[oldId][$i]) { $iDestState = $aStatesMap[newId][$i]; } } $oNewTransition = KTWorkflowTransition::createFromArray(array('workflowid' => $oNewWorkflow->getId(), 'Name' => $oOldTransition->getName(), 'HumanName' => $oOldTransition->getName(), 'TargetStateId' => $iDestState, 'GuardPermissionId' => null, 'GuardGroupId' => null, 'GuardRoleId' => null, 'GuardConditionId' => null)); $aTransitionsMap[oldId][] = $oOldTransition->getId(); $aTransitionsMap[newId][] = $oNewTransition->getId(); if (PEAR::isError($oNewTransition)) { $this->errorRedirectToMain(sprintf(_kt("Failed to copy transition: %s"), $oTransition->getMessage())); } // map source transitions onto states $aOldTransitionSources = KTWorkflowAdminUtil::getSourceStates($oOldTransition); $aSourceStates = array(); for ($j = 0; $j < count($aOldTransitionSources); $j++) { for ($i = 0; $i < count($aStatesMap[oldId]); $i++) { if ($aStatesMap[oldId][$i] == $aOldTransitionSources[$j]->getId()) { $aSourceStates[] = $aStatesMap[newId][$i]; continue; } } } $res = KTWorkflowAdminUtil::saveTransitionSources($oNewTransition, $aSourceStates); if (PEAR::isError($res)) { $this->errorRedirectToMain(sprintf(_kt("Failed to set transition origins: %s"), $res->getMessage())); } // Get all triggers for old workflow transitions and // copy for copied workflow transitions $aTriggers = KTWorkflowTriggerInstance::getByTransition($oOldTransition); if (count($aTriggers) > 0) { foreach ($aTriggers as $oTrigger) { for ($i = 0; $i < count($aTransitionsMap[oldId]); $i++) { if ($aTransitionsMap[oldId][$i] == $oTrigger->getTransitionId()) { $iTransitionId = $aTransitionsMap[newId][$i]; $res = KTWorkflowTriggerInstance::createFromArray(array('transitionid' => $iTransitionId, 'namespace' => $oTrigger->getNamespace(), 'config' => $oTrigger->getConfigArrayText())); if (PEAR::isError($res)) { return $this->errorRedirectToMain(sprintf(_kt("Unable to add trigger: %s"), $res->getMessage())); } } } } } } return $this->successRedirectToMain(sprintf(_kt("%s successfully copied as %s"), $oSelWorkflow->getName(), $oNewWorkflow->getName())); }