You are here

public function WorkflowTransitionForm::submitForm in Workflow 7.2

File

includes/Form/WorkflowTransitionForm.php, line 508
Contains \workflow\Form\WorkflowTransitionForm.

Class

WorkflowTransitionForm
Provides a Transition Form to be used in the Workflow Widget.

Code

public function submitForm(array &$form, array &$form_state, array &$items) {

  // $items is a D7 parameter.
  // @todo: clean this code up. It is the result of gluing code together.
  global $user;

  // @todo #2287057: verify if submit() really is only used for UI. If not, $user must be passed.
  $entity = $this->entity;
  $entity_type = $this->entity_type;
  $field = $this->field;
  $field_name = $field['field_name'];

  // Retrieve the data from the form.
  if (isset($form_state['values']['workflow_field'])) {

    // If $entity filled: We are on a Entity View page or Workflow History Tab page.
    // If $entity empty: We are on an Advanced Action page.
    //      $field = $form_state['values']['workflow_field'];
    //      $instance = $form_state['values']['workflow_instance'];
    //      $entity_type = $form_state['values']['workflow_entity_type'];
    //      $entity = $form_state['values']['workflow_entity'];
    //      $field_name = $field['field_name'];
  }
  elseif (isset($form_state['triggering_element'])) {

    // We are on an Entity/Node/Comment Form page (add/edit).
    $field_name = $form_state['triggering_element']['#workflow_field_name'];
  }
  else {

    // We are on an Entity/Comment Form page (add/edit).
  }

  // Determine if the transition is forced.
  // This can be set by a 'workflow_vbo action' in an additional form element.
  $force = isset($form_state['input']['workflow_force']) ? $form_state['input']['workflow_force'] : FALSE;

  // Set language. Multi-language is not supported for Workflow Node.
  $langcode = _workflow_metadata_workflow_get_properties($entity, array(), 'langcode', $entity_type, $field_name);
  if (!$entity) {

    // E.g., on VBO form.
  }
  elseif ($field_name) {

    // Save the entity, but only if we were not in edit mode.
    // Perhaps there is a better way, but for now we use 'changed' property.
    // Also test for 'is_new'. When Migrating content, the 'changed' property may be set externally.
    // Caveat: Some entities do not have 'changed' property set.
    if (!empty($entity->is_new) || isset($entity->changed) && $entity->changed == REQUEST_TIME) {

      // N.B. ONLY for Nodes!
      // We are in add/edit mode. No need to save the entity explicitly.
      //        // Add the $form_state to the $items, so we can do a getTransition() later on.
      //        $items[0]['workflow'] = $form_state['input'];
      //        // Create a Transition. The Widget knows if it is scheduled.
      //        $widget = new WorkflowDefaultWidget($field, $instance, $entity_type, $entity);
      //        $new_sid = $widget->submit($form, $form_state, $items, $force);
    }
    elseif (isset($form_state['input'])) {

      // Save $entity, but only if sid has changed.
      // Use field_attach_update for this? Save always?
      $entity->{$field_name}[$langcode][0]['workflow'] = $form_state['input'];

      // @todo & totest: Save ony the field, not the complete entity.
      // workflow_entity_field_save($entity_type, $entity, $field_name, $langcode, FALSE);
      entity_save($entity_type, $entity);
      return;

      // <-- exit!
    }
    elseif ($entity_type == 'node') {

      // N.B. ONLY for Nodes!
      // We are saving a node from a comment.
      $entity->{$field_name}[$langcode] = $items;

      // @todo & totest: Save ony the field, not the complete entity.
      // workflow_entity_field_save($entity_type, $entity, $field_name, $langcode, FALSE);
      entity_save($entity_type, $entity);
      return;

      // <-- exit!
    }
    else {

      // We are saving a non-node from an entity form.
      $entity->{$field_name}[$langcode] = $items;
    }
  }
  else {

    // For a Node API form, only contrib fields need to be filled.
    // No updating of the node itself.
    // (Unless we need to record the timestamp.)
    // Add the $form_state to the $items, so we can do a getTransition() later on.
    $items[0]['workflow'] = $form_state['input'];

    //      // Create a Transition. The Widget knows if it is scheduled.
    //      $widget = new WorkflowDefaultWidget($field, $instance, $entity_type, $entity);
    //      $new_sid = $widget->submit($form, $form_state, $items, $force);
  }

  // Extract the data from $items, depending on the type of widget.
  // @todo D8: use MassageFormValues($values, $form, $form_state).
  $old_sid = workflow_node_previous_state($entity, $entity_type, $field_name);
  if (!$old_sid) {

    // At this moment, $old_sid should have a value. If the content does not
    // have a state yet, old_sid contains '(creation)' state. But if the
    // content is not associated to a workflow, old_sid is now 0. This may
    // happen in workflow_vbo, if you assign a state to non-relevant nodes.
    $entity_id = entity_id($entity_type, $entity);
    drupal_set_message(t('Error: content @id has no workflow attached. The data is not saved.', array(
      '@id' => $entity_id,
    )), 'error');

    // The new state is still the previous state.
    $new_sid = $old_sid;
    return $new_sid;
  }

  // Now, save/execute the transition.
  $transition = $this
    ->getTransition($old_sid, $items, $field_name, $user, $form, $form_state);

  // Try to execute the transition. Return $old_sid when error.
  if (!$transition) {

    // This should only happen when testing/developing.
    drupal_set_message(t('Error: the transition from @old_sid to @new_sid could not be generated.', array(
      '@old_sid' => $old_sid,
      '@new_sid' => $new_sid,
    )), 'error');

    // The current value is still the previous state.
    $new_sid = $old_sid;
  }
  elseif ($transition
    ->isScheduled() || $transition
    ->isExecuted()) {

    // A scheduled or executed transition must only be saved to the database.
    // The entity is not changed.
    $force = $force || $transition
      ->isForced();
    $transition
      ->save();

    // The current value is still the previous state.
    $new_sid = $old_sid;
  }
  elseif (!$transition
    ->isScheduled()) {

    // Now the data is captured in the Transition, and before calling the
    // Execution, restore the default values for Workflow Field.
    // For instance, workflow_rules evaluates this.
    if ($field_name) {

      // $items = array();
      // $items[0]['value'] = $old_sid;
      // $entity->{$field_name}[$transition->language] = $items;
    }

    // It's an immediate change. Do the transition.
    // - validate option; add hook to let other modules change comment.
    // - add to history; add to watchdog
    // Return the new State ID. (Execution may fail and return the old Sid.)
    $force = $force || $transition
      ->isForced();
    $new_sid = $transition
      ->execute($force);
  }

  // The entity is still to be saved, so set to a 'normal' value.
  if ($field_name) {
    $items = array();
    $items[0]['value'] = $new_sid;
    $entity->{$field_name}[$transition->language] = $items;
  }
  return $new_sid;
}