public function setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $uid, $scheduled, $comment) { // A scheduled transition does not have a timestamp, yet. $stamp = 0; parent::setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $uid, $stamp, $comment); // Set the scheduled timestamp of state change. $this->scheduled = $scheduled; }
/** * 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); }
/** * Implements hook_field_delete() -> FieldItemInterface::delete(). */ public function delete($items) { global $user; $entity_type = $this->entity_type; $entity = $this->entity; $entity_id = entity_id($entity_type, $entity); $field_name = $this->field['field_name']; // Delete the record in {workflow_node} - not for Workflow Field. // Use a one-liner for better code analysis when grepping on old code. !$field_name ? workflow_delete_workflow_node_by_nid($entity_id) : NULL; // Add a history record in {workflow_node_history}. // @see drupal.org/node/2165349, comment by Bastlynn: // The reason for this history log upon delete is because Workflow module // has historically been used to track node states and accountability in // business environments where accountability for changes over time is // *absolutely* required. Think banking and/or particularly strict // retention policies for legal reasons. // // However, a deleted nid may be re-used under certain circumstances: // e.g., working with InnoDB or after restart the DB server. // This may cause that old history is associated with a new node. $old_sid = _workflow_get_sid_by_items($items); $new_sid = (int) WORKFLOW_DELETION; $comment = t('Entity deleted.'); $transition = new WorkflowTransition(); $transition->setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $user->uid, REQUEST_TIME, $comment); $transition->save(); // Delete all records for this node in {workflow_scheduled_transition}. foreach (WorkflowScheduledTransition::load($entity_type, $entity_id, $field_name) as $scheduled_transition) { $scheduled_transition->delete(); } }
/** * Extract WorkflowTransition or WorkflowScheduledTransition from the form. * * This merely extracts the transition from the form/widget. No validation. */ public function getTransition($old_sid, array $items, $field_name, stdClass $user) { $entity_type = $this->entity_type; $entity = $this->entity; // $entity_id = entity_id($entity_type, $entity); $field_name = !empty($this->field) ? $this->field['field_name'] : ''; if (isset($items[0]['transition'])) { // a complete transition was already passed on. $transition = $items[0]['transition']; } else { // Get the new Transition properties. First the new State ID. if (isset($items[0]['workflow']['workflow_sid'])) { // We have shown a workflow form. $new_sid = $items[0]['workflow']['workflow_sid']; } elseif (isset($items[0]['value'])) { // We have shown a core options widget (radios, select). $new_sid = $items[0]['value']; } else { // This may happen if only 1 option is left, and a formatter is shown. $state = workflow_state_load_single($old_sid); if (!$state->isCreationState()) { $new_sid = $old_sid; } else { // This only happens on workflows, when only one transition from // '(creation)' to another state is allowed. $workflow = $state->getWorkflow(); $new_sid = $workflow->getFirstSid($this->entity_type, $this->entity, $field_name, $user, FALSE); } } $comment = isset($items[0]['workflow']['workflow_comment']) ? $items[0]['workflow']['workflow_comment'] : ''; // Remember, the workflow_scheduled element is not set on 'add' page. $scheduled = !empty($items[0]['workflow']['workflow_scheduled']); if (!$scheduled) { $transition = new WorkflowTransition(); $transition->setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $user->uid, REQUEST_TIME, $comment); } else { // Schedule the time to change the state. // If Field Form is used, use plain values; // If Node Form is used, use fieldset 'workflow_scheduled_date_time'. $schedule = isset($items[0]['workflow']['workflow_scheduled_date_time']) ? $items[0]['workflow']['workflow_scheduled_date_time'] : $items[0]['workflow']; if (!isset($schedule['workflow_scheduled_hour'])) { $schedule['workflow_scheduled_hour'] = '00:00'; } $scheduled_date_time = $schedule['workflow_scheduled_date']['year'] . substr('0' . $schedule['workflow_scheduled_date']['month'], -2, 2) . substr('0' . $schedule['workflow_scheduled_date']['day'], -2, 2) . ' ' . $schedule['workflow_scheduled_hour'] . ' ' . $schedule['workflow_scheduled_timezone']; if ($stamp = strtotime($scheduled_date_time)) { $transition = new WorkflowScheduledTransition(); $transition->setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $user->uid, $stamp, $comment); } else { $transition = NULL; } } } return $transition; }