function finalise()
 {
     $fWizardKey = KTUtil::arrayGet($_REQUEST, 'fWizardKey');
     if (!empty($fWizardKey)) {
         $this->errorRedirectToMain(_kt("Could not create workflow."));
         exit;
     }
     $wiz_data = $_SESSION['_wiz_data'][$fWizardKey];
     // gather all our data.  we're sure this is all good and healthy.
     $states = $wiz_data['states'];
     $transitions = $wiz_data['transitions'];
     $from = $wiz_data['from'];
     $to = $wiz_data['to'];
     $initial_state = $wiz_data['initial_state'];
     $workflow_name = $wiz_data['workflow_name'];
     $this->startTransaction();
     // create the initial workflow
     $oWorkflow = KTWorkflow::createFromArray(array('name' => $workflow_name, 'humanname' => $workflow_name, 'enabled' => true));
     if (PEAR::isError($oWorkflow)) {
         $this->errorRedirectToMain(sprintf(_kt("Failed to create workflow: %s"), $oWorkflow->getMessage()));
     }
     $iWorkflowId = $oWorkflow->getId();
     // create the states.
     $aStates = array();
     foreach ($states as $state_name) {
         $oState = KTWorkflowState::createFromArray(array('workflowid' => $iWorkflowId, 'name' => $state_name, 'humanname' => $state_name));
         if (PEAR::isError($oState)) {
             $this->errorRedirectToMain(sprintf(_kt("Failed to create state: %s"), $oState->getMessage()));
         }
         $aStates[$state_name] = $oState;
     }
     // update the initial state on workflow
     $oInitialState = $aStates[$initial_state];
     $oWorkflow->setStartStateId($oInitialState->getId());
     $res = $oWorkflow->update();
     if (PEAR::isError($res)) {
         $this->errorRedirectToMain(sprintf(_kt("Failed to update workflow: %s"), $res->getMessage()));
     }
     // next, we create and hook up the transitions.
     $aTransitions = array();
     foreach ($transitions as $transition) {
         $dest_name = $to[$transition];
         $oDestState = $aStates[$dest_name];
         $oTransition = KTWorkflowTransition::createFromArray(array("WorkflowId" => $iWorkflowId, "Name" => $transition, "HumanName" => $transition, "TargetStateId" => $oDestState->getId(), "GuardPermissionId" => null, "GuardGroupId" => null, "GuardRoleId" => null, "GuardConditionId" => null));
         if (PEAR::isError($oTransition)) {
             $this->errorRedirectToMain(sprintf(_kt("Failed to create transition: %s"), $oTransition->getMessage()));
         }
         // hook up source states.
         $state_ids = array();
         $sources = (array) $from[$transition];
         foreach ($sources as $state_name) {
             // must exist.
             $oState = $aStates[$state_name];
             $state_ids[] = $oState->getId();
         }
         $res = KTWorkflowAdminUtil::saveTransitionSources($oTransition, $state_ids);
         if (PEAR::isError($res)) {
             $this->errorRedirectToMain(sprintf(_kt("Failed to set transition origins: %s"), $res->getMessage()));
         }
     }
     $this->commitTransaction();
     // finally, we want to redirect the user to the parent dispatcher somehow.
     // FIXME nbm:  how do you recommend we do this?
     $base = $_SERVER['PHP_SELF'];
     $qs = sprintf("action=view&fWorkflowId=%d", $oWorkflow->getId());
     $url = KTUtil::addQueryString($base, $qs);
     $this->addInfoMessage(_kt("Your new workflow has been created.  You may want to configure security and notifications from the menu on the left."));
     redirect($url);
 }
 function do_createtransitions()
 {
     $oForm = $this->form_addtransitions();
     $res = $oForm->validate();
     $data = $res['results'];
     $errors = $res['errors'];
     $extra_errors = array();
     // we want to check for duplicates, empties, etc.
     $initial_transitions = (array) explode("\n", $data['transitions']);
     $failed = array();
     $old_transitions = array();
     $transitions = array();
     foreach ($initial_transitions as $sName) {
         $transition_name = trim($sName);
         if (empty($transition_name)) {
             continue;
         }
         if ($transitions[$transition_name]) {
             $failed[] = $transition_name;
             continue;
         }
         // check for pre-existing states.
         $exists = KTWorkflowTransition::nameExists($sName, $this->oWorkflow);
         if ($exists) {
             $old_transitions[] = $sName;
         }
         $transitions[$transition_name] = $transition_name;
     }
     if (empty($transitions)) {
         $extra_errors['transitions'][] = _kt('You must provide at least one transition name.');
     }
     if (!empty($failed)) {
         $extra_errors['transitions'][] = sprintf(_kt("You cannot have duplicate transition names: %s"), implode(', ', $failed));
     }
     if (!empty($old_states)) {
         $extra_errors['transitions'][] = sprintf(_kt("You cannot use transition names that are in use: %s"), implode(', ', $old_transitions));
     }
     // handle any errors.
     if (!empty($errors) || !empty($extra_errors)) {
         $oForm->handleError(null, $extra_errors);
     }
     $this->startTransaction();
     $transition_ids = array();
     $oState = KTWorkflowState::get($this->oWorkflow->getStartStateId());
     foreach ($transitions as $transition_name) {
         $oTransition = KTWorkflowTransition::createFromArray(array("WorkflowId" => $this->oWorkflow->getId(), "Name" => $transition_name, "HumanName" => $transition_name, "TargetStateId" => $oState->getId(), "GuardPermissionId" => null, "GuardGroupId" => null, "GuardRoleId" => null, "GuardConditionId" => null));
         if (PEAR::isError($oTransition)) {
             $oForm->handleError(sprintf(_kt("Unexpected failure creating transition: %s"), $oTransition->getMessage()));
         }
         $transition_ids[] = $oTransition->getId();
     }
     $transition_ids_query = array();
     foreach ($transition_ids as $id) {
         $transition_ids_query[] = sprintf('transition_ids[%s]=%s', $id, $id);
     }
     $transition_ids_query = implode('&', $transition_ids_query);
     $this->successRedirectTo('transitionconnections', _kt("New Transitions Created."), $transition_ids_query);
 }