public function testExecuteImmediateWorkflow() { $def = $this->createDefinition(); $actions = $def->Actions(); $firstAction = $def->getInitialAction(); $this->assertEquals('Step One', $firstAction->Title); $instance = new WorkflowInstance(); $instance->beginWorkflow($def); $this->assertTrue($instance->CurrentActionID > 0); $instance->execute(); // the instance should be complete, and have two finished workflow action // instances. $actions = $instance->Actions(); $this->assertEquals(2, $actions->Count()); foreach ($actions as $action) { $this->assertTrue((bool) $action->Finished); } }
/** * Need to override the whole process method to be able to catch the fact * that we might be editing a resumed entry * * @param Array Data * @param Form Form * @return Redirection */ public function process($data, $form) { Session::set("FormInfo.{$form->FormName()}.data", $data); Session::clear("FormInfo.{$form->FormName()}.errors"); foreach ($this->Fields() as $field) { $messages[$field->Name] = $field->getErrorMessage()->HTML(); $formField = $field->getFormField(); if ($field->Required && $field->CustomRules()->Count() == 0) { if (isset($data[$field->Name])) { $formField->setValue($data[$field->Name]); } if (!isset($data[$field->Name]) || !$data[$field->Name] || !$formField->validate($form->getValidator())) { $form->addErrorMessage($field->Name, $field->getErrorMessage(), 'bad'); } } } if (Session::get("FormInfo.{$form->FormName()}.errors")) { Controller::curr()->redirectBack(); return; } $submission = $this->processSubmission($data, $form); if ($submission) { if ($this->data()->WorkflowID) { $submission->SubmissionStatus = EditableUserDefinedForm::PENDING; } else { $submission->SubmissionStatus = EditableUserDefinedForm::COMPLETE; } $submission->write(); if ($submission->SubmissionStatus == EditableUserDefinedForm::PENDING) { $instance = new WorkflowInstance(); $instance->beginWorkflow($this->data()->getSubmissionWorkflow(), $submission); $instance->execute(); } } // set a session variable from the security ID to stop people accessing // the finished method directly. if (!$this->DisableAuthenicatedFinishAction) { if (isset($data['SecurityID'])) { Session::set('FormProcessed', $data['SecurityID']); } else { // if the form has had tokens disabled we still need to set FormProcessed // to allow us to get through the finshed method if (!$this->Form()->getSecurityToken()->isEnabled()) { $randNum = rand(1, 1000); $randHash = md5($randNum); Session::set('FormProcessed', $randHash); Session::set('FormProcessedNum', $randNum); } } } if (!$this->DisableSaveSubmissions) { Session::set('userformssubmission' . $this->ID, $submission->ID); } $referrer = isset($data['Referrer']) ? '?referrer=' . urlencode($data['Referrer']) : ""; return $this->redirect($this->Link('finished') . $referrer . $this->config()->finished_anchor); }
/** * For a context around this test, see: https://github.com/silverstripe-australia/advancedworkflow/issues/141 * * 1). Create a workflow definition * 2). Step the content into that workflow * 3). Delete the workflow * 4). Check that the content: * i). Has no remaining related actions * ii). Can be re-assigned a new Workflow * 5). Check that the object under workflow, maintains its status (Draft, Published etc) */ public function testDeleteWorkflowTargetStillWorks() { // 1). Create a workflow definition $def = $this->createDefinition(); $page = Page::create(); $page->Title = 'dummy test'; $page->WorkflowDefinitionID = $def->ID; // Normally done via CMS Versioned::reading_stage('Stage'); $page->write(); // Check $page is in draft, pre-deletion $status = $page->getIsAddedToStage() && !$page->getExistsOnLive(); $this->assertTrue($status); // 2). Step the content into that workflow $instance = new WorkflowInstance(); $instance->beginWorkflow($def, $page); $instance->execute(); // Check the content is assigned $testPage = DataObject::get_by_id('Page', $page->ID); $this->assertEquals($instance->TargetID, $testPage->ID); // 3). Delete the workflow $def->delete(); // Check $testPage is _still_ in draft, post-deletion $status = $testPage->getIsAddedToStage() && !$testPage->getExistsOnLive(); $this->assertTrue($status); /* * 4). i). Check that the content: Has no remaining related actions * Note: WorkflowApplicable::WorkflowDefinitionID does _not_ get updated until assigned a new workflow * so we can use it to check that all related actions are gone */ $defID = $testPage->WorkflowDefinitionID; $this->assertEquals(0, DataObject::get('WorkflowAction')->filter('WorkflowDefID', $defID)->count()); /* * 4). ii). Check that the content: Can be re-assigned a new Workflow Definition */ $newDef = $this->createDefinition(); $testPage->WorkflowDefinitionID = $newDef->ID; // Normally done via CMS $instance = new WorkflowInstance(); $instance->beginWorkflow($newDef, $testPage); $instance->execute(); // Check the content is assigned to the new Workflow Definition correctly $this->assertEquals($newDef->ID, $testPage->WorkflowDefinitionID); $this->assertEquals($newDef->Actions()->count(), DataObject::get('WorkflowAction')->filter('WorkflowDefID', $newDef->ID)->count()); // 5). Check that the object under workflow, maintains its status $newDef2 = $this->createDefinition(); // Login so SiteTree::canPublish() returns true $testPage->WorkflowDefinitionID = $newDef2->ID; // Normally done via CMS $this->logInWithPermission(); $testPage->doPublish(); // Check $testPage is published, pre-deletion (getStatusFlags() returns empty array) $this->assertTrue($testPage->getExistsOnLive()); $instance = new WorkflowInstance(); $instance->beginWorkflow($newDef2, $testPage); $instance->execute(); // Now delete the related WorkflowDefinition and ensure status is the same (i.e. so it's not 'modified' for example) $newDef2->delete(); // Check $testPage is _still_ published, post-deletion (getStatusFlags() returns empty array) $this->assertTrue($testPage->getExistsOnLive()); }
public function testPastPublishWithWorkflowInEffect() { $definition = $this->createDefinition(); $page = new Page(); $page->Title = 'My page'; $page->WorkflowDefinitionID = $definition->ID; $page->write(); // No publish $this->assertEmpty($page->PublishJobID); $this->assertEmpty($page->UnPublishJobID); // Set a past publish date $page->DesiredPublishDate = '2010-01-01 00:00:00'; $page->write(); // Workflow is in effect. No jobs have been created yet as it's not approved. $this->assertEmpty($page->PublishJobID); $this->assertEmpty($page->UnPublishJobID); // Advance the workflow so we can see what happens $instance = new WorkflowInstance(); $instance->beginWorkflow($definition, $page); $instance->execute(); // execute the "publish" workflow action $action = new PublishItemWorkflowAction(); $action->execute($instance); // re-fetch the Page again. $page = Page::get()->byId($page->ID); // We now have a PublishOnDate field set $this->assertEquals('2010-01-01 00:00:00', $page->PublishOnDate); $this->assertEmpty($page->DesiredPublishDate); // Publish job has been setup $this->assertNotEmpty($page->PublishJobID); $this->assertEmpty($page->UnPublishJobID); // Check that this publish job is set for immediate run $publish = strtotime($page->PublishJob()->StartAfter); $this->assertEmpty($publish); }
/** * Starts the workflow for the given data object, assuming it or a parent has * a definition specified. * * @param DataObject $object */ public function startWorkflow(DataObject $object) { $existing = $this->getWorkflowFor($object); if ($existing) { throw new ExistingWorkflowException(_t('WorkflowService.EXISTING_WORKFLOW_ERROR', "That object already has a workflow running")); } $definition = $this->getDefinitionFor($object); if ($definition) { $instance = new WorkflowInstance(); $instance->beginWorkflow($definition, $object); $instance->execute(); } }
/** * Starts the workflow for the given data object, assuming it or a parent has * a definition specified. * * @param DataObject $object */ public function startWorkflow(DataObject $object, $workflowID = null) { $existing = $this->getWorkflowFor($object); if ($existing) { throw new ExistingWorkflowException(_t('WorkflowService.EXISTING_WORKFLOW_ERROR', "That object already has a workflow running")); } $definition = null; if ($workflowID) { // Retrieve the workflow definition that has been triggered. $definition = $this->getDefinitionByID($object, $workflowID); } if (is_null($definition)) { // Fall back to the main workflow definition. $definition = $this->getDefinitionFor($object); } if ($definition) { $instance = new WorkflowInstance(); $instance->beginWorkflow($definition, $object); $instance->execute(); } }