public function execute(WorkflowInstance $workflow)
 {
     if (!($target = $workflow->getTarget())) {
         return true;
     }
     if (class_exists('AbstractQueuedJob') && $this->UnpublishDelay) {
         $job = new WorkflowPublishTargetJob($target, "unpublish");
         $days = $this->UnpublishDelay;
         $after = date('Y-m-d H:i:s', strtotime("+{$days} days"));
         singleton('QueuedJobService')->queueJob($job, $after);
     } else {
         if ($target->hasExtension('WorkflowEmbargoExpiryExtension')) {
             // setting future date stuff if needbe
             // set these values regardless
             $target->DesiredUnPublishDate = '';
             $target->DesiredPublishDate = '';
             $target->write();
             if ($target->hasMethod('doUnpublish')) {
                 $target->doUnpublish();
             }
         } else {
             if ($target->hasMethod('doUnpublish')) {
                 $target->doUnpublish();
             }
         }
     }
     return true;
 }
 public function execute(WorkflowInstance $workflow)
 {
     if (!($target = $workflow->getTarget())) {
         return true;
     }
     if ($target->hasField($this->Property)) {
         $target->setField($this->Property, $this->Value);
     }
     $target->write();
     return true;
 }
Exemplo n.º 3
0
 /**
  * Update the specified resource in storage.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  int  $id
  * @return \Illuminate\Http\Response
  */
 public function update(Request $request, $id)
 {
     $entity = \App\Document::find($id);
     $wi = new \WorkflowInstance('material-request', $entity->id, $entity->state, $entity);
     if ($request->get('op_type') == 'state_change') {
         $new_state = $request->get('new_state');
         $wi->setState($new_state);
         $entity->state = $new_state;
         $entity->save();
     }
     // end if op_type is state_change
     return Redirect('/');
 }
 public function execute(WorkflowInstance $workflow)
 {
     if (!($target = $workflow->getTarget())) {
         return true;
     }
     if (class_exists('AbstractQueuedJob') && $this->PublishDelay) {
         $job = new WorkflowPublishTargetJob($target);
         $days = $this->PublishDelay;
         $after = date('Y-m-d H:i:s', strtotime("+{$days} days"));
         singleton('QueuedJobService')->queueJob($job, $after);
     } else {
         $target->doPublish();
     }
     return true;
 }
 public function run($request)
 {
     $sent = 0;
     if (WorkflowInstance::get()->count()) {
         // Don't attempt the filter if no instances -- prevents a crash
         $active = WorkflowInstance::get()->innerJoin('WorkflowDefinition', '"DefinitionID" = "WorkflowDefinition"."ID"')->filter(array('WorkflowStatus' => array('Active', 'Paused'), 'RemindDays:GreaterThan' => '0'));
         $active->filter(array('RemindDays:GreaterThan' => '0'));
         if ($active) {
             foreach ($active as $instance) {
                 $edited = strtotime($instance->LastEdited);
                 $days = $instance->Definition()->RemindDays;
                 if ($edited + $days * 3600 * 24 > time()) {
                     continue;
                 }
                 $email = new Email();
                 $bcc = '';
                 $members = $instance->getAssignedMembers();
                 $target = $instance->getTarget();
                 if (!$members || !count($members)) {
                     continue;
                 }
                 $email->setSubject("Workflow Reminder: {$instance->Title}");
                 $email->setBcc(implode(', ', $members->column('Email')));
                 $email->setTemplate('WorkflowReminderEmail');
                 $email->populateTemplate(array('Instance' => $instance, 'Link' => $target instanceof SiteTree ? "admin/show/{$target->ID}" : ''));
                 $email->send();
                 $sent++;
                 $instance->LastEdited = time();
                 $instance->write();
             }
         }
     }
     echo "Sent {$sent} workflow reminder emails.\n";
 }
 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);
     }
 }
 public function execute(WorkflowInstance $workflow)
 {
     $workflow->Users()->removeAll();
     $workflow->Groups()->removeAll();
     $workflow->Users()->addMany($this->Users());
     $workflow->Groups()->addMany($this->Groups());
     if ($this->AssignInitiator) {
         $workflow->Users()->add($workflow->Initiator());
     }
     return true;
 }
 public function execute(WorkflowInstance $workflow)
 {
     $members = $workflow->getAssignedMembers();
     if (!$members || !count($members)) {
         return true;
     }
     $member = Member::currentUser();
     $initiator = $workflow->Initiator();
     $contextFields = $this->getContextFields($workflow->getTarget());
     $memberFields = $this->getMemberFields($member);
     $initiatorFields = $this->getMemberFields($initiator);
     $variables = array();
     foreach ($contextFields as $field => $val) {
         $variables["\$Context.{$field}"] = $val;
     }
     foreach ($memberFields as $field => $val) {
         $variables["\$Member.{$field}"] = $val;
     }
     foreach ($initiatorFields as $field => $val) {
         $variables["\$Initiator.{$field}"] = $val;
     }
     $pastActions = $workflow->Actions()->sort('Created DESC');
     $variables["\$CommentHistory"] = $this->customise(array('PastActions' => $pastActions, 'Now' => SS_Datetime::now()))->renderWith('CommentHistory');
     $from = str_replace(array_keys($variables), array_values($variables), $this->EmailFrom);
     $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject);
     if ($this->config()->whitelist_template_variables) {
         $item = new ArrayData(array('Initiator' => new ArrayData($initiatorFields), 'Member' => new ArrayData($memberFields), 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"]));
     } else {
         $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => $member, 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"]));
     }
     if ($this->ListingTemplateID) {
         $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID);
         $view = SSViewer::fromString($template->ItemTemplate);
     } else {
         $view = SSViewer::fromString($this->EmailTemplate);
     }
     $body = $view->process($item);
     foreach ($members as $member) {
         if ($member->Email) {
             $email = new Email();
             $email->setTo($member->Email);
             $email->setSubject($subject);
             $email->setFrom($from);
             $email->setBody($body);
             $email->send();
         }
     }
     return true;
 }
 public function process()
 {
     $sent = 0;
     $filter = array('WorkflowStatus' => array('Active', 'Paused'), 'Definition.RemindDays:GreaterThan' => 0);
     $active = WorkflowInstance::get()->filter($filter);
     foreach ($active as $instance) {
         $edited = strtotime($instance->LastEdited);
         $days = $instance->Definition()->RemindDays;
         if ($edited + $days * 3600 * 24 > time()) {
             continue;
         }
         $email = new Email();
         $bcc = '';
         $members = $instance->getAssignedMembers();
         $target = $instance->getTarget();
         if (!$members || !count($members)) {
             continue;
         }
         $email->setSubject("Workflow Reminder: {$instance->Title}");
         $email->setBcc(implode(', ', $members->column('Email')));
         $email->setTemplate('WorkflowReminderEmail');
         $email->populateTemplate(array('Instance' => $instance, 'Link' => $target instanceof SiteTree ? "admin/show/{$target->ID}" : ''));
         $email->send();
         $sent++;
         // add a comment to the workflow if possible
         $action = $instance->CurrentAction();
         $currentComment = $action->Comment;
         $action->Comment = sprintf(_t('AdvancedWorkflow.JOB_REMINDER_COMMENT', '%s: Reminder email sent\\n\\n'), date('Y-m-d H:i:s')) . $currentComment;
         try {
             $action->write();
         } catch (Exception $ex) {
             SS_Log::log($ex, SS_Log::WARN);
         }
         $instance->LastEdited = time();
         try {
             $instance->write();
         } catch (Exception $ex) {
             SS_Log::log($ex, SS_Log::WARN);
         }
     }
     $this->currentStep = 2;
     $this->isComplete = true;
     $nextDate = date('Y-m-d H:i:s', time() + $this->repeatInterval);
     $this->queuedJobService->queueJob(new WorkflowReminderJob($this->repeatInterval), $nextDate);
 }
    public function execute(WorkflowInstance $workflow)
    {
        $workflow->Users()->removeAll();
        //Due to http://open.silverstripe.org/ticket/8258, there are errors occuring if Group has been extended
        //We use a direct delete query here before ticket 8258 fixed
        //$workflow->Groups()->removeAll();
        $workflowID = $workflow->ID;
        $query = <<<SQL
\t\tDELETE FROM "WorkflowInstance_Groups" WHERE ("WorkflowInstance_Groups"."WorkflowInstanceID" = '{$workflowID}');
SQL;
        DB::query($query);
        $workflow->Users()->addMany($this->Users());
        $workflow->Groups()->addMany($this->Groups());
        if ($this->AssignInitiator) {
            $workflow->Users()->add($workflow->Initiator());
        }
        return true;
    }
 public function execute(WorkflowInstance $workflow)
 {
     $email = new Email();
     $members = $workflow->getAssignedMembers();
     $emails = '';
     if (!$members || !count($members)) {
         return;
     }
     foreach ($members as $member) {
         if ($member->Email) {
             $emails .= "{$member->Email}, ";
         }
     }
     $context = $this->getContextFields($workflow->getTarget());
     $member = $this->getMemberFields();
     $variables = array();
     foreach ($context as $field => $val) {
         $variables["\$Context.{$field}"] = $val;
     }
     foreach ($member as $field => $val) {
         $variables["\$Member.{$field}"] = $val;
     }
     $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject);
     if ($this->ListingTemplateID) {
         $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => Member::currentUser(), 'Context' => $workflow->getTarget()));
         $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID);
         $view = SSViewer::fromString($template->ItemTemplate);
         $body = $view->process($item);
     } else {
         $body = str_replace(array_keys($variables), array_values($variables), $this->EmailTemplate);
     }
     $email->setSubject($subject);
     $email->setFrom($this->EmailFrom);
     $email->setBcc(substr($emails, 0, -2));
     $email->setBody($body);
     $email->send();
     return true;
 }
Exemplo n.º 12
0
 /**
  * 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());
 }
 /**
  * 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);
 }
Exemplo n.º 14
0
 public function WorkflowInstances()
 {
     return WorkflowInstance::get()->filter(array('TargetClass' => $this->ownerBaseClass, 'TargetID' => $this->owner->ID));
 }
 /**
  * When deleting an action from a workflow definition, make sure that workflows currently paused on that action
  * are deleted
  * Also removes all outbound transitions
  */
 public function onAfterDelete()
 {
     parent::onAfterDelete();
     $wfActionInstances = WorkflowActionInstance::get()->leftJoin("WorkflowInstance", '"WorkflowInstance"."ID" = "WorkflowActionInstance"."WorkflowID"')->where(sprintf('"BaseActionID" = %d AND ("WorkflowStatus" IN (\'Active\',\'Paused\'))', $this->ID));
     foreach ($wfActionInstances as $wfActionInstance) {
         $wfInstances = WorkflowInstance::get()->filter('CurrentActionID', $wfActionInstance->ID);
         foreach ($wfInstances as $wfInstance) {
             $wfInstance->Groups()->removeAll();
             $wfInstance->Users()->removeAll();
             $wfInstance->delete();
         }
         $wfActionInstance->delete();
     }
     // Delete outbound transitions
     $transitions = WorkflowTransition::get()->filter('ActionID', $this->ID);
     foreach ($transitions as $transition) {
         $transition->Groups()->removeAll();
         $transition->Users()->removeAll();
         $transition->delete();
     }
 }
Exemplo n.º 16
0
 /**
  * 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();
     }
 }
 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();
     }
 }