/** * {@inheritdoc} */ public function execute($object = NULL) { // D7: As advanced action with Trigger 'node': // - $entity is empty; // - $context['group'] = 'node' // - $context['hook'] = 'node_insert / _update / _delete' // - $context['node'] = (Object) stdClass // - $context['entity_type'] = NULL // D7: As advanced action with Trigger 'taxonomy': // - $entity is (Object) stdClass; // - $context['type'] = 'entity' // - $context['group'] = 'taxonomy' // - $context['hook'] = 'taxonomy_term_insert / _update / _delete' // - $context['node'] = (Object) stdClass // - $context['entity_type'] = NULL // D7: As advanced action with Trigger 'workflow API': // ... // D7: As VBO action: // - $entity is (Object) stdClass; // - $context['type'] = NULL // - $context['group'] = NULL // - $context['hook'] = NULL // - $context['node'] = (Object) stdClass // - $context['entity_type'] = 'node' if (!($transition = $this->getTransitionForExecution($object))) { drupal_set_message('The entity is not valid for this action.'); return; } $force = $this->configuration['force']; $transition->force(); // Fire the transition. workflow_execute_transition($transition, $force); }
/** * {@inheritdoc} */ public static function executeScheduledTransitionsBetween($start = 0, $end = 0) { $clear_cache = FALSE; // If the time now is greater than the time to execute a transition, do it. foreach (WorkflowScheduledTransition::loadBetween($start, $end) as $scheduled_transition) { $field_name = $scheduled_transition->getFieldName(); $entity = $scheduled_transition->getTargetEntity(); // Make sure transition is still valid: the entity must still be in // the state it was in, when the transition was scheduled. // Scheduling on comments is a testing error, and leads to 'recoverable error'. $current_sid = ''; if ($entity && $entity->getEntityTypeId() !== 'comment') { $current_sid = workflow_node_current_state($entity, $field_name); } if ($current_sid && $current_sid == $scheduled_transition->getFromSid()) { // If user didn't give a comment, create one. $comment = $scheduled_transition->getComment(); if (empty($comment)) { $scheduled_transition->addDefaultComment(); } // Do transition. Force it because user who scheduled was checked. // The scheduled transition is not scheduled anymore, and is also deleted from DB. // A watchdog message is created with the result. $scheduled_transition->schedule(FALSE); $scheduled_transition->force(TRUE); workflow_execute_transition($scheduled_transition, TRUE); if (!$field_name) { $clear_cache = TRUE; } } else { // Entity is not in the same state it was when the transition // was scheduled. Defer to the entity's current state and // abandon the scheduled transition. $scheduled_transition->delete(); } } if ($clear_cache) { // Clear the cache so that if the transition resulted in a entity // being published, the anonymous user can see it. Cache::invalidateTags(array('rendered')); } }
/** * {@inheritdoc} */ public function execute($object = NULL) { if (!($transition = $this->getTransitionForExecution($object))) { drupal_set_message('The object is not valid for this action.', 'warning'); return; } /* * Set the new next state. */ $entity = $transition->getTargetEntity(); $field_name = $transition->getFieldName(); $user = $transition->getOwner(); $force = $this->configuration['force']; // $comment = $transition->getComment(); // Get the node's new State Id (which is the next available state). $to_sid = $transition->getWorkflow()->getNextSid($entity, $field_name, $user, $force); // Add actual data. $transition->to_sid = $to_sid; // Fire the transition. workflow_execute_transition($transition, $force); }
/** * Deactivate a Workflow State, moving existing content to a given State. * * @param int $new_sid * The state ID, to which all affected entities must be moved. */ public function deactivate($new_sid) { $current_sid = $this->id(); $force = TRUE; // Notify interested modules. We notify first to allow access to data before we zap it. // - re-parents any entity that we don't want to orphan, whilst deactivating a State. // - delete any lingering entity to state values. // \Drupal::moduleHandler()->invokeAll('workflow', ['state delete', $current_sid, $new_sid, NULL, $force]); // Invoke the hook. \Drupal::moduleHandler()->invokeAll('entity_' . $this->getEntityTypeId() . '_predelete', array($this, $current_sid, $new_sid)); // Re-parent any entity that we don't want to orphan, whilst deactivating a State. // TODO D8-port: State should not know about Transition: move this to Workflow->DeactivateState. if ($new_sid) { // A candidate for the batch API. // @TODO: Future updates should seriously consider setting this with batch. $user = \Drupal::currentUser(); // We can use global, since deactivate() is a UI-only function. $comment = t('Previous state deleted'); foreach (_workflow_info_fields() as $field_name => $field_info) { $entity = NULL; $entity_type = $field_info->getTargetEntityTypeId(); $field_name = $field_info->getName(); $query = \Drupal::entityQuery($entity_type); $query->condition($field_name, $current_sid, '='); $result = $entity_type == 'comment' ? array() : $query->execute(); foreach ($result as $entity_id) { $entity = \Drupal::entityManager()->getStorage($entity_type)->load($entity_id); $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]); $transition->setTargetEntity($entity); $transition->setValues($new_sid, $user->id(), REQUEST_TIME, $comment, TRUE); $transition->force($force); // Execute Transition, invoke 'pre' and 'post' events, save new state in Field-table, save also in workflow_transition_history. // For Workflow Node, only {workflow_node} and {workflow_transition_history} are updated. For Field, also the Entity itself. $new_sid = workflow_execute_transition($transition, $force); } } } // Delete the transitions this state is involved in. $workflow = Workflow::load($this->wid); foreach ($workflow->getTransitionsByStateId($current_sid, '') as $transition) { $transition->delete(); } foreach ($workflow->getTransitionsByStateId('', $current_sid) as $transition) { $transition->delete(); } // Delete the state. -- We don't actually delete, just deactivate. // This is a matter up for some debate, to delete or not to delete, since this // causes name conflicts for states. In the meantime, we just stick with what we know. // If you really want to delete the states, use workflow_cleanup module, or delete(). $this->status = FALSE; $this->save(); // Clear the cache. self::loadMultiple([], 0, TRUE); }
/** * Deactivate a Workflow State, moving existing nodes to a given State. * * @param int $new_sid * The state ID, to which all affected entities must be moved. * * D7.x-2.x: deprecated workflow_delete_workflow_states_by_sid() --> WorkflowState->deactivate() + delete() */ public function deactivate($new_sid) { global $user; // We can use global, since deactivate() is a UI-only function. $current_sid = $this->sid; $force = TRUE; // Notify interested modules. We notify first to allow access to data before we zap it. // E.g., Node API (@todo Field API): // - re-parents any nodes that we don't want to orphan, whilst deactivating a State. // - delete any lingering node to state values. module_invoke_all('workflow', 'state delete', $current_sid, $new_sid, NULL, $force); // Re-parent any nodes that we don't want to orphan, whilst deactivating a State. // This is called in WorkflowState::deactivate(). // @todo: re-parent Workflow Field, whilst deactivating a state. if ($new_sid) { // A candidate for the batch API. // @TODO: Future updates should seriously consider setting this with batch. $comment = t('Previous state deleted'); foreach (workflow_get_workflow_node_by_sid($current_sid) as $workflow_node) { // @todo: add Field support in 'state delete', by using workflow_node_history or reading current field. $entity_type = 'node'; $entity = entity_load_single('node', $workflow_node->nid); $field_name = ''; $transition = new WorkflowTransition(); $transition->setValues($entity_type, $entity, $field_name, $current_sid, $new_sid, $user->uid, REQUEST_TIME, $comment); $transition->force($force); // Execute Transition, invoke 'pre' and 'post' events, save new state in workflow_node, save also in workflow_node_history. // For Workflow Node, only {workflow_node} and {workflow_node_history} are updated. For Field, also the Entity itself. $new_sid = workflow_execute_transition($entity_type, $entity, $field_name, $transition, $force); } } // Delete any lingering node to state values. workflow_delete_workflow_node_by_sid($current_sid); // Delete the transitions this state is involved in. $workflow = workflow_load_single($this->wid); /* @var $transition WorkflowTransition */ foreach ($workflow->getTransitionsBySid($current_sid, 'ALL') as $transition) { $transition->delete(); } foreach ($workflow->getTransitionsByTargetSid($current_sid, 'ALL') as $transition) { $transition->delete(); } // Delete the state. -- We don't actually delete, just deactivate. // This is a matter up for some debate, to delete or not to delete, since this // causes name conflicts for states. In the meantime, we just stick with what we know. // If you really want to delete the states, use workflow_cleanup module, or delete(). $this->status = FALSE; $this->save(); // Clear the cache. self::getStates(0, TRUE); }
$n = node_load($ticket->nid); $url = $ticket->field_url_value; $sid = workflow_node_current_state($ticket); print $sid; // we only give chance to tickets that are newly created or previously inaccessible (perhaps due to network failure) if ($sid == $sid_creation || $sid == $sid_inaccessible || $sid == $sid_corrected) { $content = file_get_contents($url); if ($content) { // if the URL is readable if (strpos($content, $magic_str)) { // if we find the magic string print "we found the string"; $user->uid = 1; workflow_execute_transition(&$n, $sid_corrected, $comment = NULL, TRUE); $user->uid = 0; } else { print "No string, reopen"; $user->uid = 1; print $nid . " " . $sid_open; workflow_execute_transition(&$n, $sid_open, $comment = NULL, TRUE); $user->uid = 0; } } else { // url open error print "no open"; $user->uid = 1; workflow_execute_transition(&$n, $sid_inaccessible, $comment = NULL, TRUE); $user->uid = 0; } } }
public function submitForm(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) { // If Rules is available, signal the reversion. // @todo: move this Rules_invoke_event to hook outside this module. if (\Drupal::moduleHandler()->moduleExists('rules')) { rules_invoke_event('workflow_state_reverted', $this->entity); } /* @var $transition WorkflowTransitionInterface */ $transition = $this->prepareRevertedTransition($this->entity); // The entity will be updated when the transition is executed. Keep the // original one for the confirmation message. $previous_sid = $transition->getToSid(); // Force the transition because it's probably not valid. $transition->force(TRUE); $new_sid = workflow_execute_transition($transition, TRUE); $comment = $previous_sid == $new_sid ? 'State is reverted.' : 'State could not be reverted.'; drupal_set_message(t($comment), 'warning'); $form_state->setRedirect('entity.node.workflow_history', array('node' => $transition->getTargetEntityId(), 'field_name' => $transition->getFieldName())); }