/** * {@inheritdoc} */ public function getState($sid) { $wid = $this->id(); $state = WorkflowState::load($sid); if (!$wid || $wid == $state->getWorkflowId()) { return $state; } return NULL; }
/** * {@inheritdoc} */ public function getToState() { $sid = $this->getToSid(); return $sid ? WorkflowState::load($sid) : NULL; }
/** * Implements hook_form_BASE_FORM_ID_alter(). * * Use this hook to alter the form. * It is only suited if you only use View Page or Workflow Tab. * If you change the state on the Entity Edit page (form), you need the hook * hook_form_alter(). See below for more info. */ function hook_form_workflow_transition_form_alter(&$form, FormStateInterface $form_state, $form_id) { // workflow_debug(__FILE__, __FUNCTION__, __LINE__, $form_id, ''); // The WorkflowTransitionForm (E.g., Workflow History tab, Block). // It has its own handling. // Todo, populate the WorkflowTranstiionForm with a Widget, so we have 1 way-of-working. // Let's take a (changeable) reference to the element. $workflow_element =& $form; // This object contains all you need. You may find it in one of two locations. /* @var $transition WorkflowTransitionInterface */ $transition = $form['workflow_transition']['#value']; // dpm($transition); // An example of customizing/overriding the workflow widget. // Beware, until now, you must do this twice: on the widget and on the form. if ($transition->getOwnerId() == 1) { drupal_set_message('I got you, user 1, you will never schedule again, and you WILL document each state change!', 'warning'); // Let's prohibit scheduling for user 1. $workflow_element['workflow_scheduling']['#access'] = FALSE; // Let's prohibit scheduling for user 1. if ($workflow_element['comment']['#access'] == TRUE) { $workflow_element['comment']['#required'] = TRUE; } } // Get the Entity. /* @var $entity \Drupal\Core\Entity\EntityInterface */ $entity = NULL; //$entity = $form['workflow_entity']['#value']; $entity_type = 'node'; // $form['workflow_entity_type']['#value']; $entity_bundle = ''; // $entity->bundle(); $sid = ''; if ($entity) { $entity_type = $entity->getEntityTypeId(); $entity_bundle = $entity->bundle(); // Get the current State ID. $sid = workflow_node_current_state($entity, $field_name = NULL); // Get the State object, if needed. $state = WorkflowState::load($sid); } // Change the form, depending on the state ID. // In the upcoming version 7.x-2.4, States should have a machine_name, too. if ($entity_type == 'node' && $entity_bundle == 'MY_NODE_TYPE') { switch ($sid) { case '2': // Change form element, form validate and form submit for state '2'. break; case '3': // Change form element, form validate and form submit for state '3'. break; } } }
/** * {@inheritdoc} */ public function getToState() { return WorkflowState::load($this->to_sid); }
/** * {@inheritdoc} * * Overrides DraggableListBuilder::submitForm(). * The WorkflowState entities are always saved. */ public function submitForm(array &$form, FormStateInterface $form_state) { // parent::submitForm($form, $form_state); // Get the Workflow from the page. /* @var $workflow \Drupal\workflow\Entity\Workflow */ if (!($workflow = workflow_ui_url_get_workflow())) { return; } // The default min_weight is -10. Work with it. $creation_weight = -11; $maxweight = $minweight = -9; foreach ($form_state->getValue($this->entitiesKey) as $sid => $value) { if (isset($this->entities[$sid])) { /* @var $state WorkflowState */ $state = $this->entities[$sid]; // Is the new state name empty? if (empty($value['label_new'])) { // No new state entered, so skip it. continue; } // Does user want to deactivate the state (reassign current content)? if ($sid && $value['status'] == 0 && $state->isActive()) { $new_sid = $value['reassign']; $new_state = WorkflowState::load($new_sid); $args = ['%workflow' => $workflow->label(), '%old_state' => $state->label(), '%new_state' => isset($new_state) ? $new_state->label() : '']; if ($value['count'] > 0) { if ($form['#last_mohican']) { $new_sid = NULL; // Do not reassign to new state. $message = 'Removing workflow states from content in the %workflow.'; drupal_set_message($this->t($message, $args)); } else { // Prepare the state delete function. $message = 'Reassigning content from %old_state to %new_state.'; drupal_set_message($this->t($message, $args)); } } // Delete the old state without orphaning content, move them to the new state. $state->deactivate($new_sid); $message = $this->t('Deactivated workflow state %old_state in %workflow.', $args); \Drupal::logger('workflow')->notice($message, []); drupal_set_message($message); } // Set a proper weight to the new state. $maxweight = max($maxweight, $state->get($this->weightKey)); // Is this a new state? if ($sid == 'placeholder' && empty(!$value['label_new'])) { // New state, add it. $state->set('id', $value['id']); // Set a proper weight to the new state. $state->set($this->weightKey, $maxweight + 1); } elseif ($value['sysid'] == WORKFLOW_CREATION_STATE) { // Set a proper weight to the creation state. $state->set($this->weightKey, $creation_weight); } else { $state->set($this->weightKey, $value['weight']); } $state->set('label', $value['label_new']); $state->set('status', $value['status']); $state->save(); } } drupal_set_message(t('The Workflow states have been updated.')); return; }
/** * Stores permission settings for workflow states. */ public function submitForm(array &$form, FormStateInterface $form_state) { foreach ($form_state->getValues() as $sid => $access) { // @todo: not waterproof; can be done smarter, using elementchildren().. if (!WorkflowState::load($sid)) { continue; } foreach ($access['view'] as $rid => $checked) { $data[$rid] = array('grant_view' => !empty($checked) ? (bool) $checked : 0, 'grant_update' => !empty($access['update'][$rid]) ? (bool) $access['update'][$rid] : 0, 'grant_delete' => !empty($access['delete'][$rid]) ? (bool) $access['delete'][$rid] : 0); } workflow_access_insert_workflow_access_by_sid($sid, $data); // Update all nodes to reflect new settings. node_access_needs_rebuild(TRUE); } parent::submitForm($form, $form_state); }
/** * {@inheritdoc} * * N.B. A large part of this function is taken from CommentDefaultFormatter. */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = array(); $output = array(); $field_name = $this->fieldDefinition->getName(); $entity = $items->getEntity(); $entity_type = $entity->getEntityTypeId(); $status = $items->status; $workflow_settings = $this->getFieldSettings(); $user = \Drupal::currentUser(); // @todo #2287057: OK? // @todo: Perhaps global user is not always the correct user. // E.g., on ScheduledTransition->execute()? But this function is mostly used in UI. $current_sid = WorkflowManager::getCurrentStateId($entity, $field_name); /* @var $current_state WorkflowState */ $current_state = WorkflowState::load($current_sid); // First compose the current value with the normal formatter from list.module. $elements = workflow_state_formatter($entity, $field_name, $current_sid); // The state must not be deleted, or corrupted. if (!$current_state) { return $elements; } // Check permission, so that even with state change rights, // the form can be suppressed from the entity view (#1893724). $type_id = $current_state->getWorkflowId(); if (!\Drupal::currentUser()->hasPermission("access {$type_id} workflow_transition form")) { return $elements; } // Workflows are added to the search results and search index by // workflow_node_update_index() instead of by this formatter, so don't // return anything if the view mode is search_index or search_result. if (in_array($this->viewMode, array('search_result', 'search_index'))) { return $elements; } if ($entity_type == 'comment') { // No Workflow form allowed on a comment display. // (Also, this avoids a lot of error messages.) return $elements; } // Only build form if user has possible target state(s). if (!$current_state->showWidget($entity, $field_name, $user, FALSE)) { return $elements; } // Create a transition, to pass to the form. No need to use setValues(). $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]); $transition->setTargetEntity($entity); // Remove the default formatter. We are now building the widget. $elements = array(); // BEGIN Copy from CommentDefaultFormatter $elements['#cache']['contexts'][] = 'user.permissions'; $output['workflows'] = []; // Add the WorkflowTransitionForm to the page. // $build = $this->viewBuilder->viewMultiple($workflows); $build = $this->entityFormBuilder()->getForm($transition, 'add'); $output['workflows'] += $build; // Only show the add workflow form if the user has permission. $elements['#cache']['contexts'][] = 'user.roles'; // Do not show the form for the print view mode. $elements[] = $output + array('#workflow_type' => $this->getFieldSetting('workflow_type'), '#workflow_display_mode' => $this->getFieldSetting('default_mode'), 'workflows' => array()); // END Copy from CommentDefaultFormatter return $elements; }