예제 #1
0
 /**
  * {@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 build()
 {
     $form = [];
     // Get the entity for this form.
     /* @var $entity EntityInterface */
     if (!($entity = workflow_url_get_entity())) {
         return $form;
     }
     // Get the field name. Avoid error on Node Add page.
     if (!($field_name = workflow_get_field_name($entity))) {
         return $form;
     }
     /*
      * Output: generate the Transition Form.
      */
     // Create a transition, to pass to the form. No need to use setValues().
     $current_sid = workflow_node_current_state($entity, $field_name);
     $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
     $transition->setTargetEntity($entity);
     // Add the WorkflowTransitionForm to the page.
     $form = $this->entityFormBuilder()->getForm($transition, 'add');
     return $form;
 }
 /**
  * Implements workflow_transition() -> WorkflowDefaultWidget::submit().
  *
  * Overrides submit(array $form, array &$form_state).
  * Contains 2 extra parameters for D7
  *
  * @param array $form
  * @param array $form_state
  * @param array $items
  *   The value of the field.
  * @param bool $force
  *   TRUE if all access must be overridden, e.g., for Rules.
  *
  * @return int
  *   If update succeeded, the new State Id. Else, the old Id is returned.
  *
  * This is called from function _workflowfield_form_submit($form, &$form_state)
  * It is a replacement of function workflow_transition($node, $new_sid, $force, $field)
  * It performs the following actions;
  * - save a scheduled action
  * - update history
  * - restore the normal $items for the field.
  * @todo: remove update of {node_form} table. (separate task, because it has features, too)
  */
 public function submit(array $form, array &$form_state, array &$items, $force = FALSE)
 {
     $entity_type = $this->entity_type;
     $entity = $this->entity;
     // $entity_id = entity_id($entity_type, $entity);
     $field_name = isset($this->field['field_name']) ? $this->field['field_name'] : '';
     // Extract the data from $items, depending on the type of widget.
     // @todo D8: use MassageFormValues($values, $form, $form_state).
     $old_sid = workflow_node_current_state($entity, $entity_type, $field_name);
     $transition = $this->getTransition($old_sid, $items);
     $force = $force || $transition->isForced();
     $new_sid = $transition->new_sid;
     if (!$transition) {
         drupal_set_message(t('Error when try to find a WorkflowTransition.'), 'status');
         // The current value is still the previous state.
         $new_sid = $old_sid;
     } elseif ($error = $transition->isAllowed($force)) {
         drupal_set_message($error, 'error');
     } 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}['und'] = $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 value of the sid. (Execution may fail and return the old Sid.)
         $new_sid = $transition->execute($force);
     } else {
         // A scheduled transition must only be saved to the database. The entity is not changed.
         $transition->save();
         // The current value is still the previous state.
         $new_sid = $old_sid;
     }
     // 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}['und'] = $items;
     }
     return $new_sid;
 }
예제 #4
0
/**
 * 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 Node Form (Edit modus), you need the hook
 * hook_form_alter(). See below for more info.
 */
function hook_form_workflow_transition_form_alter(&$form, &$form_state, $form_id)
{
    // Get the Entity.
    $entity = $form['workflow']['workflow_entity']['#value'];
    $entity_type = $form['workflow']['workflow_entity_type']['#value'];
    // Use the complicated form, which is suited for all Entity types.
    // For nodes only: $entity_type = 'node'; $entity_bundle = $entity->type;
    list(, , $entity_bundle) = entity_extract_ids($entity_type, $entity);
    // Get the current State ID.
    $sid = workflow_node_current_state($entity, $entity_type, $field_name = NULL);
    // Get the State object, if needed.
    $state = workflow_state_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 ($state->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}
  *
  * @todo D8-port: add D7-theming to TransitionListBuilder.
  */
 public function buildRow(EntityInterface $transition)
 {
     // Show the history table.
     $current_themed = FALSE;
     /* @var $transition WorkflowTransitionInterface */
     $entity = $transition->getTargetEntity();
     $field_name = $transition->getFieldName();
     $current_sid = workflow_node_current_state($entity, $field_name);
     $to_state = $transition->getToState();
     if (!$to_state) {
         // This is an invalid/deleted state.
         $to_label = WORKFLOW_MARK_STATE_IS_DELETED;
         // Add a footer to explain the addition.
         $this->footer_needed = TRUE;
     } else {
         $label = Html::escape($this->t($to_state->label()));
         if ($transition->getToSid() == $current_sid && $to_state->isActive() && !$current_themed) {
             $to_label = $label;
             if (!$current_themed) {
                 // Make a note that we have themed the current state; other times in the history
                 // of this entity where the entity was in this state do not need to be specially themed.
                 $current_themed = TRUE;
             }
         } elseif (!$to_state->isActive()) {
             $to_label = $label . WORKFLOW_MARK_STATE_IS_DELETED;
             // Add a footer to explain the addition.
             $this->footer_needed = TRUE;
         } else {
             // Regular state.
             $to_label = $label;
         }
     }
     unset($to_state);
     // Not needed anymore.
     $from_state = $transition->getFromState();
     if (!$from_state) {
         // This is an invalid/deleted state.
         $from_label = WORKFLOW_MARK_STATE_IS_DELETED;
         // Add a footer to explain the addition.
         $this->footer_needed = TRUE;
     } else {
         $label = Html::escape($this->t($from_state->label()));
         if (!$from_state->isActive()) {
             $from_label = $label . WORKFLOW_MARK_STATE_IS_DELETED;
             // Add a footer to explain the addition.
             $this->footer_needed = TRUE;
         } else {
             // Regular state.
             $from_label = $label;
         }
     }
     unset($from_state);
     // Not needed anymore.
     $owner = $transition->getOwner();
     $field_name = $transition->getFieldName();
     $field_label = $transition->getFieldName();
     $variables = array('transition' => $transition, 'extra' => '', 'from_label' => $from_label, 'to_label' => $to_label, 'user' => $owner);
     // Allow other modules to modify the row.
     \Drupal::moduleHandler()->alter('workflow_history', $variables);
     //     'class' => array('workflow_history_row'), // TODO D8-port
     $row['timestamp']['data'] = $transition->getTimestampFormatted();
     // 'class' => array('timestamp')
     // html_entity_decode() transforms chars like '&' correctly.
     if ($this->showColumnFieldname($entity)) {
         $row['field_name']['data'] = html_entity_decode($field_label);
     }
     $row['from_state']['data'] = html_entity_decode($from_label);
     // 'class' => array('previous-state-name'))
     $row['to_state']['data'] = html_entity_decode($to_label);
     // 'class' => array('state-name'))
     $row['user_name']['data'] = $owner->getUsername();
     // 'class' => array('user-name')
     $row['comment']['data'] = html_entity_decode($transition->getComment());
     // 'class' => array('log-comment')
     //    $row['comment'] = array(
     //      '#type' => 'textarea',
     //      '#default_value' => $transition->getComment(),
     //    );
     // Column 'Operations' is now added by core.
     // D7: $row['operations']['data'] = $this->buildOperations($entity);
     $row += parent::buildRow($transition);
     return $row;
 }
예제 #6
0
 /**
  * Implements hook_field_widget_form --> WidgetInterface::formElement().
  *
  * {@inheritdoc}
  *
  * Be careful: Widget may be shown in very different places. Test carefully!!
  *  - On a entity add/edit page
  *  - On a entity preview page
  *  - On a entity view page
  *  - On a entity 'workflow history' tab
  *  - On a comment display, in the comment history
  *  - On a comment form, below the comment history
  *
  * @todo D8: change "array $items" to "FieldInterface $items"
  */
 public function formElement(array $items, $delta, array $element, array &$form, array &$form_state)
 {
     global $user;
     // @todo #2287057: verify if formElement() really is only used for UI. If not, $user must be passed.
     $field = $this->field;
     $instance = $this->instance;
     $entity = $this->entity;
     $entity_type = $this->entity_type;
     $entity_id = $entity ? entity_id($entity_type, $entity) : 0;
     $field_name = $field['field_name'];
     $current_sid = FALSE;
     // $field['settings']['wid'] can be numeric or named.
     // $wid may not be specified.
     $wid = $field['settings']['wid'];
     $workflow = workflow_load_single($wid);
     $workflow_label = $workflow ? check_plain(t($workflow->label())) : '';
     // Capture settings to format the form/widget.
     $settings_title_as_name = !empty($field['settings']['widget']['name_as_title']);
     $settings_options_type = $field['settings']['widget']['options'];
     // The schedule can be hidden via field settings, ...
     $settings_schedule = !empty($field['settings']['widget']['schedule']);
     if ($settings_schedule) {
         if (isset($form_state['step']) && $form_state['step'] == 'views_bulk_operations_config_form') {
             // On VBO 'modify entity values' form, leave field settings.
             $settings_schedule = TRUE;
         } else {
             // ... and cannot be shown on a Content add page (no $entity_id),
             // ...but can be shown on a VBO 'set workflow state to..'page (no entity).
             $settings_schedule = !($entity && !$entity_id);
         }
     }
     $settings_schedule_timezone = !empty($field['settings']['widget']['schedule_timezone']);
     // Show comment, when both Field and Instance allow this.
     $settings_comment = $field['settings']['widget']['comment'];
     $options = array();
     if (!$entity) {
         // Sometimes, no entity is given. We encountered the following cases:
         // - the Field settings page,
         // - the VBO action form;
         // - the Advance Action form on admin/config/system/actions;
         // If so, show all options for the given workflow(s).
         // Set 'grouped' option. This is only valid for select list.
         $grouped = $settings_options_type == 'select';
         $options = workflow_get_workflow_state_names($wid, $grouped, $all = FALSE);
         $show_widget = TRUE;
         $default_value = isset($items[0]['value']) ? $items[0]['value'] : '0';
     } else {
         $force = FALSE;
         $current_sid = workflow_node_current_state($entity, $entity_type, $field_name);
         if ($current_state = workflow_state_load_single($current_sid)) {
             // $grouped = TRUE; // Grouped options only makes sense for multiple workflows.
             $options = $current_state->getOptions($entity_type, $entity, $field_name, $user, $force);
             $show_widget = $current_state->showWidget($entity_type, $entity, $field_name, $user, $force);
             // Determine the default value. If we are in CreationState, use a fast alternative for $workflow->getFirstSid().
             $default_value = $current_state->isCreationState() ? key($options) : $current_sid;
         } else {
             // We are in trouble! A message is already set in workflow_node_current_state().
             $show_widget = FALSE;
             $default_value = $current_sid;
         }
     }
     // Get the scheduling info. This may change the $current_sid on the Form.
     $scheduled = '0';
     $timestamp = REQUEST_TIME;
     $comment = NULL;
     if ($settings_schedule) {
         // Read scheduled information.
         // Technically you could have more than one scheduled, but this will only add the soonest one.
         foreach (WorkflowScheduledTransition::load($entity_type, $entity_id, $field_name) as $scheduled_transition) {
             $scheduled = '1';
             $default_value = $scheduled_transition->new_sid;
             $timestamp = $scheduled_transition->scheduled;
             $comment = $scheduled_transition->comment;
             break;
         }
     }
     // Fetch the form ID. This is unique for each entity, to allow multiple form per page (Views, etc.).
     // Make it uniquer by adding the field name, or else the scheduling of
     // multiple workflow_fields is not indendent.
     $form_id = $form_state['build_info']['form_id'] . '_' . $field_name;
     // Prepare a UI wrapper. This might be a fieldset.
     $element['workflow']['#type'] = 'container';
     // 'fieldset';
     $element['workflow']['#attributes'] = array('class' => array('workflow-form-container'));
     // Save the current value of the node in the form, for later Workflow-module specific references.
     // We add prefix, since #tree == FALSE.
     $element['workflow']['workflow_entity'] = array('#type' => 'value', '#value' => $this->entity);
     $element['workflow']['workflow_entity_type'] = array('#type' => 'value', '#value' => $this->entity_type);
     $element['workflow']['workflow_field'] = array('#type' => 'value', '#value' => $field);
     $element['workflow']['workflow_instance'] = array('#type' => 'value', '#value' => $instance);
     // Save the form_id, so the form values can be retrieved in submit function.
     $element['workflow']['form_id'] = array('#type' => 'value', '#value' => $form_id);
     // First of all, we add the default value in the place were normal fields
     // have it. This is to cater for 'preview' of the entity.
     $element['#default_value'] = $default_value;
     // Decide if we show a widget or a formatter.
     // There is no need to a widget when the only choice is the current sid.
     if (!$show_widget) {
         $element['workflow']['workflow_sid'] = workflow_state_formatter($entity_type, $entity, $field, $instance, $default_value);
         return $element;
         // <---- exit.
     }
     // The 'options' widget. May be removed later if 'Action buttons' are chosen.
     $element['workflow']['workflow_sid'] = array('#type' => $settings_options_type, '#title' => $settings_title_as_name ? t('Change !name state', array('!name' => $workflow_label)) : t('Target state'), '#options' => $options, '#default_value' => $default_value);
     // Display scheduling form, but only if entity is being edited and user has
     // permission. State change cannot be scheduled at entity creation because
     // that leaves the entity in the (creation) state.
     if ($settings_schedule == TRUE && user_access('schedule workflow transitions')) {
         if (variable_get('configurable_timezones', 1) && $user->uid && drupal_strlen($user->timezone)) {
             $timezone = $user->timezone;
         } else {
             $timezone = variable_get('date_default_timezone', 0);
         }
         $timezones = drupal_map_assoc(timezone_identifiers_list());
         $hours = format_date($timestamp, 'custom', 'H:i', $timezone);
         $element['workflow']['workflow_scheduled'] = array('#type' => 'radios', '#title' => t('Schedule'), '#options' => array('0' => t('Immediately'), '1' => t('Schedule for state change')), '#default_value' => $scheduled, '#attributes' => array('id' => 'scheduled_' . $form_id));
         $element['workflow']['workflow_scheduled_date_time'] = array('#type' => 'fieldset', '#title' => t('At'), '#attributes' => array('class' => array('container-inline')), '#prefix' => '<div style="margin-left: 1em;">', '#suffix' => '</div>', '#states' => array('visible' => array(':input[id="' . 'scheduled_' . $form_id . '"]' => array('value' => '1'))));
         $element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_date'] = array('#type' => 'date', '#default_value' => array('day' => date('j', $timestamp), 'month' => date('n', $timestamp), 'year' => date('Y', $timestamp)));
         $element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_hour'] = array('#type' => 'textfield', '#title' => t('Time'), '#maxlength' => 7, '#size' => 6, '#default_value' => $scheduled ? $hours : '00:00', '#element_validate' => array('_workflow_transition_form_element_validate_time'));
         $element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_timezone'] = array('#type' => $settings_schedule_timezone ? 'select' : 'hidden', '#title' => t('Time zone'), '#options' => $timezones, '#default_value' => array($timezone => $timezone));
         $element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_help'] = array('#type' => 'item', '#prefix' => '<br />', '#description' => t('Please enter a time.
       If no time is included, the default will be midnight on the specified date.
       The current time is: @time.', array('@time' => format_date(REQUEST_TIME, 'custom', 'H:i', $timezone))));
     }
     $element['workflow']['workflow_comment'] = array('#type' => $settings_comment == '0' ? 'hidden' : 'textarea', '#required' => $settings_comment == '2', '#title' => t('Workflow comment'), '#description' => t('A comment to put in the workflow log.'), '#default_value' => $comment, '#rows' => 2);
     // Finally, add Submit buttons/Action buttons.
     // Either a default 'Submit' button is added, or a button per permitted state.
     if ($settings_options_type == 'buttons') {
         // How do action buttons work? See also d.o. issue #2187151.
         // Create 'action buttons' per state option. Set $sid property on each button.
         // 1. Admin sets ['widget']['options']['#type'] = 'buttons'.
         // 2. This function formElelent() creates 'action buttons' per state option;
         //    sets $sid property on each button.
         // 3. User clicks button.
         // 4. Callback _workflow_transition_form_validate_buttons() sets proper State.
         // 5. Callback _workflow_transition_form_validate_buttons() sets Submit function.
         // @todo: this does not work yet for the Add Comment form.
         // Performance: inform workflow_form_alter() to do its job.
         _workflow_use_action_buttons(TRUE);
     }
     $submit_functions = empty($instance['widget']['settings']['submit_function']) ? array() : array($instance['widget']['settings']['submit_function']);
     if ($settings_options_type == 'buttons' || $submit_functions) {
         $element['workflow']['actions']['#type'] = 'actions';
         $element['workflow']['actions']['submit'] = array('#type' => 'submit', '#value' => t('Update workflow'), '#weight' => -5, '#attributes' => array('class' => array('form-save-default-button')));
         // The 'add submit' can explicitely set by workflowfield_field_formatter_view(),
         // to add the submit button on the Content view page and the Workflow history tab.
         // Add a submit button, but only on Entity View and History page.
         // Add the submit function only if one provided. Set the submit_callback accordingly.
         if ($submit_functions) {
             $element['workflow']['actions']['submit']['#submit'] = $submit_functions;
         } else {
             // '#submit' Must be empty, or else the submit function is not called.
             // $element['workflow']['actions']['submit']['#submit'] = array();
         }
     } else {
         // In some cases, no submit callback function is specified. This is
         // explicitly done on e.g., the node edit form, because the workflow form
         // is 'just a field'.
         // So, no Submit button is to be shown.
     }
     return $element;
 }
예제 #7
0
/**
 * 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;
        }
    }
}
예제 #8
0
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// definiton
$magic_str = "trash";
$sid_creation = 1;
$sid_open = 2;
$sid_inaccessible = 3;
$sid_corrected = 4;
global $user;
$tickets_result = db_query("SELECT nid, 'ticket' as type, field_url_value FROM content_type_ticket");
while ($ticket = db_fetch_object($tickets_result)) {
    $nid = $ticket->nid;
    $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;
예제 #9
0
 /**
  * {@inheritdoc}
  *
  * Be careful: Widget may be shown in very different places. Test carefully!!
  *  - On a entity add/edit page
  *  - On a entity preview page
  *  - On a entity view page
  *  - On a entity 'workflow history' tab
  *  - On a comment display, in the comment history
  *  - On a comment form, below the comment history
  *
  * @todo D8: change "array $items" to "FieldInterface $items"
  */
 public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state)
 {
     $wid = $this->getFieldSetting('workflow_type');
     if (!($workflow = Workflow::load($wid))) {
         // @todo: add error message.
         return $element;
     }
     /* @var $item \Drupal\workflowfield\Plugin\Field\FieldType\WorkflowItem */
     $item = $items[$delta];
     /* @var $field_config \Drupal\field\Entity\FieldConfig */
     $field_config = $item->getFieldDefinition();
     /* @var $field_storage \Drupal\field\Entity\FieldStorageConfig */
     $field_storage = $field_config->getFieldStorageDefinition();
     $field_name = $field_storage->get('field_name');
     $entity = $item->getEntity();
     $from_sid = workflow_node_current_state($entity, $field_name);
     // Create a transition, to pass to the form. No need to use setValues().
     /* @var $transition WorkflowTransition */
     $transition = WorkflowTransition::create([$from_sid, 'field_name' => $field_name]);
     $transition->setTargetEntity($entity);
     if (!$this->isDefaultValueWidget($form_state)) {
         // Here, not the $element is added, but the entity form.
         // Option 1: use the Element.
         $element['#default_value'] = $transition;
         $element += WorkflowTransitionElement::transitionElement($element, $form_state, $form);
         // Option 2: use the Form, in order to get extra fields.
         //$entity_form_builder = \Drupal::getContainer()->get('entity.form_builder');
         //$element += $entity_form_builder->getForm($transition, 'add');
         //// Remove the action button. The Entity itself has one.
         //unset($element['actions']);
         // Option 3: use the true Element.
         // $form = $this->element($form, $form_state, $transition);
         //$element['workflow_transition'] = array(
         //      '#type' => 'workflow_transition',
         //      '#title' => t('Workflow transition'),
         //      '#default_value' => $transition,
         // );
     } else {
         // @todo D8: add a default value, so people can set a default comment.
         // On the Field settings page, User may not set a default value
         // (this is done by the Workflow module).
         // @see WorkflowState::getOptions();
         // @see WorkflowDefaultWidget::formElement();
         $element = array();
         return $element;
         workflow_debug(__FILE__, __FUNCTION__, __LINE__, '', '');
         // @todo D8-port: still test this snippet.
         // @see workflowfield_form_field_config_edit_form_alter for other settings
         // The Workflow field must have a value, so set to required.
         // Unfortunately, we need hook_form_alter for this.
         //$form['required']['#default_value'] = 1;
         //$form['required']['#disabled'] = TRUE;
         // Explicitly set default value to 'creation' and show element,
         // so people can set a default comment.
         $transition->to_sid = $workflow->getCreationSid();
         $transition->setExecuted(TRUE);
         // @TODO D8-port: use a proper WorkflowTransitionElement call.
         $element['#default_value'] = $transition;
         $element += WorkflowTransitionElement::transitionElement($element, $form_state, $form);
         // No action buttons on default field settings page.
         // This is evaluated in hook_form_alter.
         _workflow_use_action_buttons(FALSE);
         // Make sure the options box is not hidden (when action buttons active).
         //$element['to_sid']['#type'] = 'select';
         $element['to_sid']['#title'] = 'Initial state';
         $element['to_sid']['#access'] = TRUE;
         unset($element['workflow_current_state']);
         return $element;
     }
     return $element;
 }
 /**
  * Prepares a transition to be reverted.
  *
  * @param \Drupal\workflow\Entity\WorkflowTransitionInterface $transition
  *   The transition to be reverted.
  *
  * @return \Drupal\workflow\Entity\WorkflowTransitionInterface
  *   The prepared transition ready to be stored.
  */
 protected function prepareRevertedTransition(WorkflowTransitionInterface $transition)
 {
     $user = \Drupal::currentUser();
     $entity = $transition->getTargetEntity();
     $field_name = $transition->getFieldName();
     $current_sid = workflow_node_current_state($entity, $field_name);
     $previous_sid = $transition->getFromSid();
     $comment = t('State reverted.');
     $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
     $transition->setTargetEntity($entity);
     $transition->setValues($previous_sid, $user->id(), REQUEST_TIME, $comment);
     return $transition;
 }
 /**
  * @return WorkflowTransitionInterface
  */
 protected function getTransitionForExecution(EntityInterface $entity)
 {
     $user = workflow_current_user();
     if (!$entity) {
         \Drupal::logger('workflow_action')->notice('Unable to get current entity - entity is not defined.', []);
         return NULL;
     }
     // Get the entity type and numeric ID.
     $entity_id = $entity->id();
     if (!$entity_id) {
         \Drupal::logger('workflow_action')->notice('Unable to get current entity ID - entity is not yet saved.', []);
         return NULL;
     }
     // In 'after saving new content', the node is already saved. Avoid second insert.
     // Todo: clone?
     $entity->enforceIsNew(FALSE);
     $config = $this->configuration;
     $field_name = workflow_get_field_name($entity, $config['field_name']);
     $current_sid = workflow_node_current_state($entity, $field_name);
     if (!$current_sid) {
         \Drupal::logger('workflow_action')->notice('Unable to get current workflow state of entity %id.', array('%id' => $entity_id));
         return NULL;
     }
     $to_sid = isset($config['to_sid']) ? $config['to_sid'] : '';
     // Get the Comment. Parse the $comment variables.
     $comment_string = $this->configuration['comment'];
     $comment = t($comment_string, array('%title' => $entity->label(), '%state' => workflow_get_sid_name($to_sid), '%user' => $user->getUsername()));
     $force = $this->configuration['force'];
     $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
     $transition->setTargetEntity($entity);
     $transition->setValues($to_sid, $user->id(), REQUEST_TIME, $comment);
     $transition->force($force);
     return $transition;
 }
예제 #12
0
 /**
  * Returns the next state for the current state.
  *
  * @param string $entity_type
  *   The type of the entity at hand.
  * @param object $entity
  *   The entity at hand. May be NULL (E.g., on a Field settings page).
  * @param $field_name
  * @param $user
  * @param bool $force
  *
  * @return int $sid
  *   A state ID.
  */
 public function getNextSid($entity_type, $entity, $field_name, $user, $force = FALSE)
 {
     $new_sid = workflow_node_current_state($entity, $entity_type, $field_name);
     if ($new_sid && ($new_state = workflow_state_load_single($new_sid))) {
         /* @var $current_state WorkflowState */
         $options = $new_state->getOptions($entity_type, $entity, $field_name, $user, $force);
         // Loop over every option. To find the next one.
         $flag = $new_state->isCreationState();
         foreach ($options as $sid => $name) {
             if ($flag) {
                 $new_sid = $sid;
                 break;
             }
             if ($sid == $new_state->sid) {
                 $flag = TRUE;
             }
         }
     }
     return $new_sid;
 }
예제 #13
0
 if ($node->_workflow != 12) {
     print l('Cancel Certificate', 'crlt/certificate/cancel/' . $node->nid, array('query' => array('destination' => implode('/', arg())))) . '<br />';
 }
 $wid = workflow_get_workflow_for_type($node->type);
 $states_per_page = 250;
 $states = array();
 $result = db_query("SELECT sid, state FROM {workflow_states} WHERE status = 1 ORDER BY sid");
 while ($data = db_fetch_object($result)) {
     $states[$data->sid] = check_plain(t($data->state));
 }
 $deleted_states = array();
 $result = db_query("SELECT sid, state FROM {workflow_states} WHERE status = 0 ORDER BY sid");
 while ($data = db_fetch_object($result)) {
     $deleted_states[$data->sid] = check_plain(t($data->state));
 }
 $current = workflow_node_current_state($node);
 // theme_workflow_current_state() must run state through check_plain().
 $output = '<p>' . t('Current state: <strong>!state</strong>', array('!state' => $states[$current])) . "</p>\n";
 $result = pager_query("SELECT h.*, u.name FROM {workflow_node_history} h LEFT JOIN {users} u ON h.uid = u.uid WHERE nid = %d ORDER BY hid DESC", $states_per_page, 0, NULL, $node->nid);
 $rows = array();
 while ($history = db_fetch_object($result)) {
     if ($history->sid == $current && !isset($deleted_states[$history->sid]) && !isset($current_themed)) {
         // Theme the current state differently so it stands out.
         $state_name = $states[$history->sid];
         // Make a note that we have themed the current state; other times in the history
         // of this node where the node was in this state do not need to be specially themed.
         $current_themed = TRUE;
     } elseif (isset($deleted_states[$history->sid])) {
         // The state has been deleted, but we include it in the history.
         $state_name = $deleted_states[$history->sid];
         $footer_needed = TRUE;
 /**
  * Generates an overview table of older revisions of a node,
  * but only if this::historyAccess() allows it.
  *
  * @param \Drupal\node\NodeInterface $node
  *   A node object.
  *
  * @return array
  *   An array as expected by drupal_render().
  */
 public function historyOverview(EntityInterface $node = NULL)
 {
     $form = array();
     /*
      * Get data from parameters.
      */
     // TODO D8-port: make Workflow History tab happen for every entity_type.
     // For workflow_tab_page with multiple workflows, use a separate view. See [#2217291].
     // @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController.
     //    workflow_debug(__FILE__, __FUNCTION__, __LINE__);  // @todo D8-port: still test this snippet.
     // ATM it only works for Nodes and Terms.
     // This is a hack. The Route should always pass an object.
     // On view tab, $entity is object,
     // On workflow tab, $entity is id().
     // Get the entity for this form.
     if (!($entity = workflow_url_get_entity($node))) {
         return $form;
     }
     /*
      * Get derived data from parameters.
      */
     if (!($field_name = workflow_get_field_name($entity, workflow_url_get_field_name()))) {
         return $form;
     }
     /*
      * Step 1: generate the Transition Form.
      */
     // Create a transition, to pass to the form. No need to use setValues().
     $current_sid = workflow_node_current_state($entity, $field_name);
     $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
     $transition->setTargetEntity($entity);
     // Add the WorkflowTransitionForm to the page.
     $form = $this->entityFormBuilder()->getForm($transition, 'add');
     /*
      * Step 2: generate the Transition History List.
      */
     $entity_type = 'workflow_transition';
     // $form = $this->listing('workflow_transition');
     $list_builder = $this->entityManager()->getListBuilder($entity_type);
     // Add the Node explicitly, since $list_builder expects a Transition.
     $list_builder->workflow_entity = $entity;
     $form += $list_builder->render();
     /*
      * Finally: sort the elements (overriding their weight).
      */
     // $form['#weight'] = 10;
     $form['actions']['#weight'] = 100;
     $form['workflow_list_title']['#weight'] = 200;
     $form['table']['#weight'] = 201;
     return $form;
 }
예제 #15
0
function ecogig_neat_preprocess_node(&$variables)
{
    $node = $variables['node'];
    if ($node->type == 'dataset') {
        $workflow = !empty($node->field_dataset_workflow['und'][0]['value']) ? $node->field_dataset_workflow['und'][0]['value'] : '';
        $workflow = workflow_node_current_state($node);
        if (!empty($workflow)) {
            $state = ecogig_workflow_get_state_name($workflow);
            $comment = ecogig_workflow_get_latest_comment($node->nid);
            $variables['workflow_state'] = !empty($state) ? $state : '';
            $variables['workflow_comment'] = !empty($comment) ? $comment : '';
        }
        $record_type = !empty($node->field_record_type[LANGUAGE_NONE][0]['taxonomy_term']) ? $node->field_record_type[LANGUAGE_NONE][0]['taxonomy_term'] : '';
        if (!empty($record_type)) {
            $icon_class = !empty($record_type->field_icon_class[LANGUAGE_NONE][0]['value']) ? $record_type->field_icon_class[LANGUAGE_NONE][0]['value'] : '';
            $type_name = $record_type->name;
            $variables['record_type_icon'] = $icon_class;
            $variables['record_type_name'] = $type_name;
            $variables['record_type_body'] = $record_type->description;
            $variables['record_type_tid'] = $record_type->tid;
        }
        if (node_access('update', $node)) {
            drupal_add_js(drupal_get_path('module', 'dataset_record_type') . '/js/dataset_record_type.js', 'file');
            $vocab = taxonomy_vocabulary_machine_name_load('dataset_record_types');
            $terms = taxonomy_get_tree($vocab->vid);
            $variables['record_type_options'] = $terms;
        }
    }
}
 /**
  * {@inheritdoc}
  *
  * @param array $form
  * @param array $form_state
  * @param WorkflowTransition
  *  The Transition to be edited, created.
  *
  * @return
  *  The enhanced form structure.
  */
 public function buildForm(array $form, array &$form_state)
 {
     global $user;
     /* @var $transition WorkflowTransition */
     $transition = NULL;
     if (isset($form_state['WorkflowTransition'])) {
         // If provided, get data from WorkflowTransition.
         // This happens when calling entity_ui_get_form(), like in the
         // WorkflowTransition Comment Edit form.
         $transition = $form_state['WorkflowTransition'];
         $field_name = $transition->field_name;
         $workflow = $transition->getWorkflow();
         $wid = $transition->wid;
         $entity = $this->entity = $transition->getEntity();
         $entity_type = $this->entity_type = $transition->entity_type;
         // Figure out the $entity's bundle and id.
         list(, , $entity_bundle) = entity_extract_ids($entity_type, $entity);
         $entity_id = entity_id($entity_type, $entity);
         // Show the current state and the Workflow form to allow state changing.
         // N.B. This part is replicated in hook_node_view, workflow_tab_page, workflow_vbo, transition_edit.
         // @todo: support multiple workflows per entity.
         // For workflow_tab_page with multiple workflows, use a separate view. See [#2217291].
         $field = _workflow_info_field($field_name, $workflow);
         $instance = $this->instance + field_info_instance($entity_type, $field_name, $entity_bundle);
     } else {
         // Get data from normal parameters.
         $entity = $this->entity;
         $entity_type = $this->entity_type;
         $entity_id = $entity ? entity_id($entity_type, $entity) : 0;
         $field = $this->field;
         $field_name = $field['field_name'];
         $instance = $this->instance;
         // $field['settings']['wid'] can be numeric or named.
         // $wid may not be specified.
         $wid = $field['settings']['wid'];
         $workflow = workflow_load_single($wid);
     }
     $force = FALSE;
     // Get values.
     // Current sid and default value may differ in a scheduled transition.
     // Set 'grouped' option. Only valid for select list and undefined/multiple workflows.
     $settings_options_type = $field['settings']['widget']['options'];
     $grouped = $settings_options_type == 'select';
     if ($transition) {
         // If a Transition is passed as parameter, use this.
         if ($transition->isExecuted()) {
             // We are editing an existing/executed/not-scheduled transition.
             // Only the comments may be changed!
             // Fetch the old state for the formatter on top of form.
             $current_state = $transition->getOldState();
             $current_sid = $current_state->sid;
             // The states may not be changed anymore.
             $new_state = $transition->getNewState();
             $options = array($new_state->sid => $new_state->label());
             // We need the widget to edit the comment.
             $show_widget = TRUE;
         } else {
             $current_state = $transition->getOldState();
             $current_sid = $current_state->sid;
             $options = $current_state->getOptions($entity_type, $entity, $field_name, $user, $force);
             $show_widget = $current_state->showWidget($entity_type, $entity, $field_name, $user, $force);
         }
         $default_value = $transition->new_sid;
     } elseif (!$entity) {
         // Sometimes, no entity is given. We encountered the following cases:
         // - the Field settings page,
         // - the VBO action form;
         // - the Advance Action form on admin/config/system/actions;
         // If so, show all options for the given workflow(s).
         $options = workflow_get_workflow_state_names($wid, $grouped, $all = FALSE);
         $show_widget = TRUE;
         $default_value = $current_sid = isset($items[0]['value']) ? $items[0]['value'] : '0';
     } else {
         $current_sid = workflow_node_current_state($entity, $entity_type, $field_name);
         if ($current_state = workflow_state_load_single($current_sid)) {
             /* @var $current_state WorkflowTransition */
             $options = $current_state->getOptions($entity_type, $entity, $field_name, $user, $force);
             $show_widget = $current_state->showWidget($entity_type, $entity, $field_name, $user, $force);
             $default_value = !$current_state->isCreationState() ? $current_sid : $workflow->getFirstSid($entity_type, $entity, $field_name, $user, FALSE);
         } else {
             // We are in trouble! A message is already set in workflow_node_current_state().
             $options = array();
             $show_widget = FALSE;
             $default_value = $current_sid;
         }
         // Get the scheduling info. This may change the $default_value on the Form.
         // Read scheduled information, only if an entity exists.
         // Technically you could have more than one scheduled, but this will only add the soonest one.
         foreach (WorkflowScheduledTransition::load($entity_type, $entity_id, $field_name, 1) as $transition) {
             $default_value = $transition->new_sid;
             break;
         }
     }
     // Prepare a new transition, if still not provided.
     if (!$transition) {
         $transition = new WorkflowTransition(array('old_sid' => $default_value, 'stamp' => REQUEST_TIME));
     }
     // Fetch the form ID. This is unique for each entity, to allow multiple form per page (Views, etc.).
     // Make it uniquer by adding the field name, or else the scheduling of
     // multiple workflow_fields is not independent of each other.
     // IF we are truly on a Transition form (so, not a Node Form with widget)
     // then change the form id, too.
     $form_id = $this->getFormId();
     if (!isset($form_state['build_info']['base_form_id'])) {
         // Strange: on node form, the base_form_id is node_form,
         // but on term form, it is not set.
         // In both cases, it is OK.
     } else {
         if ($form_state['build_info']['base_form_id'] == 'workflow_transition_wrapper_form') {
             $form_state['build_info']['base_form_id'] = 'workflow_transition_form';
         }
         if ($form_state['build_info']['base_form_id'] == 'workflow_transition_form') {
             $form_state['build_info']['form_id'] = $form_id;
         }
     }
     $workflow_label = $workflow ? check_plain(t($workflow->label())) : '';
     // Change settings locally.
     if (!$field_name) {
         // This is a Workflow Node workflow. Set widget options as in v7.x-1.2
         if ($form_state['build_info']['base_form_id'] == 'node_form') {
             $field['settings']['widget']['comment'] = isset($workflow->options['comment_log_node']) ? $workflow->options['comment_log_node'] : 1;
             // vs. ['comment_log_tab'];
             $field['settings']['widget']['current_status'] = TRUE;
         } else {
             $field['settings']['widget']['comment'] = isset($workflow->options['comment_log_tab']) ? $workflow->options['comment_log_tab'] : 1;
             // vs. ['comment_log_node'];
             $field['settings']['widget']['current_status'] = TRUE;
         }
     }
     // Capture settings to format the form/widget.
     $settings_title_as_name = !empty($field['settings']['widget']['name_as_title']);
     $settings_fieldset = isset($field['settings']['widget']['fieldset']) ? $field['settings']['widget']['fieldset'] : 0;
     $settings_options_type = $field['settings']['widget']['options'];
     // The scheduling info can be hidden via field settings, ...
     // You may not schedule an existing Transition.
     // You must have the correct permission.
     $settings_schedule = !empty($field['settings']['widget']['schedule']) && !$transition->isExecuted() && user_access('schedule workflow transitions');
     if ($settings_schedule) {
         if (isset($form_state['step']) && $form_state['step'] == 'views_bulk_operations_config_form') {
             // On VBO 'modify entity values' form, leave field settings.
             $settings_schedule = TRUE;
         } else {
             // ... and cannot be shown on a Content add page (no $entity_id),
             // ...but can be shown on a VBO 'set workflow state to..'page (no entity).
             $settings_schedule = !($entity && !$entity_id);
         }
     }
     $settings_schedule_timezone = !empty($field['settings']['widget']['schedule_timezone']);
     // Show comment, when both Field and Instance allow this.
     $settings_comment = $field['settings']['widget']['comment'];
     // Save the current value of the node in the form, for later Workflow-module specific references.
     // We add prefix, since #tree == FALSE.
     $element['workflow']['workflow_entity'] = array('#type' => 'value', '#value' => $this->entity);
     $element['workflow']['workflow_entity_type'] = array('#type' => 'value', '#value' => $this->entity_type);
     $element['workflow']['workflow_field'] = array('#type' => 'value', '#value' => $field);
     $element['workflow']['workflow_instance'] = array('#type' => 'value', '#value' => $instance);
     // Save the form_id, so the form values can be retrieved in submit function.
     $element['workflow']['form_id'] = array('#type' => 'value', '#value' => $form_id);
     // Save the hid, when editing an existing transition.
     $element['workflow']['workflow_hid'] = array('#type' => 'hidden', '#value' => $transition->hid);
     // Add the default value in the place where normal fields
     // have it. This is to cater for 'preview' of the entity.
     $element['#default_value'] = $default_value;
     // Decide if we show a widget or a formatter.
     // There is no need for a widget when the only option is the current sid.
     // Show state formatter before the rest of the form,
     // when transition is scheduled or widget is hidden.
     if (!$show_widget || $transition->isScheduled() || $transition->isExecuted()) {
         $form['workflow_current_state'] = workflow_state_formatter($entity_type, $entity, $field, $instance, $current_sid);
         // Set a proper weight, which works for Workflow Options in select list AND action buttons.
         $form['workflow_current_state']['#weight'] = -0.005;
     }
     // Add class following node-form pattern (both on form and container).
     $workflow_type_id = $workflow ? $workflow->getName() : 'none';
     // No workflow on New Action form.
     $element['workflow']['#attributes']['class'][] = 'workflow-transition-container';
     $element['workflow']['#attributes']['class'][] = 'workflow-transition-' . $workflow_type_id . '-container';
     // Add class for D7-backwards compatibility (only on container).
     $element['workflow']['#attributes']['class'][] = 'workflow-form-container';
     if (!$show_widget) {
         // Show no widget.
         $element['workflow']['workflow_sid']['#type'] = 'value';
         $element['workflow']['workflow_sid']['#value'] = $default_value;
         $element['workflow']['workflow_sid']['#options'] = $options;
         // In case action buttons need them.
         $form += $element;
         return $form;
         // <---- exit.
     } else {
         // Prepare a UI wrapper. This might be a fieldset or a container.
         if ($settings_fieldset == 0) {
             // Use 'container'.
             $element['workflow'] += array('#type' => 'container');
         } else {
             $element['workflow'] += array('#type' => 'fieldset', '#title' => t($workflow_label), '#collapsible' => TRUE, '#collapsed' => $settings_fieldset == 1 ? FALSE : TRUE);
         }
         // The 'options' widget. May be removed later if 'Action buttons' are chosen.
         // The help text is not available for container. Let's add it to the
         // State box.
         $help_text = isset($instance['description']) ? $instance['description'] : '';
         $element['workflow']['workflow_sid'] = array('#type' => $settings_options_type, '#title' => $settings_title_as_name ? t('Change !name state', array('!name' => $workflow_label)) : t('Target state'), '#access' => TRUE, '#options' => $options, '#default_value' => $default_value, '#description' => $help_text);
     }
     // Display scheduling form, but only if entity is being edited and user has
     // permission. State change cannot be scheduled at entity creation because
     // that leaves the entity in the (creation) state.
     if ($settings_schedule == TRUE) {
         if (variable_get('configurable_timezones', 1) && $user->uid && drupal_strlen($user->timezone)) {
             $timezone = $user->timezone;
         } else {
             $timezone = variable_get('date_default_timezone', 0);
         }
         $timezones = drupal_map_assoc(timezone_identifiers_list());
         $timestamp = $transition->getTimestamp();
         $hours = !$transition->isScheduled() ? '00:00' : format_date($timestamp, 'custom', 'H:i', $timezone);
         // Add a container, so checkbox and time stay together in extra fields.
         $element['workflow']['workflow_scheduling'] = array('#type' => 'container', '#tree' => TRUE);
         $element['workflow']['workflow_scheduling']['scheduled'] = array('#type' => 'radios', '#title' => t('Schedule'), '#options' => array('0' => t('Immediately'), '1' => t('Schedule for state change')), '#default_value' => $transition->isScheduled() ? '1' : '0', '#attributes' => array('class' => array(drupal_html_class('scheduled_' . $form_id))));
         $element['workflow']['workflow_scheduling']['date_time'] = array('#type' => 'fieldset', '#title' => t('At'), '#attributes' => array('class' => array('container-inline')), '#prefix' => '<div style="margin-left: 1em;">', '#suffix' => '</div>', '#states' => array('visible' => array('input.' . drupal_html_class('scheduled_' . $form_id) => array('value' => '1'))));
         $element['workflow']['workflow_scheduling']['date_time']['workflow_scheduled_date'] = array('#type' => 'date', '#default_value' => array('day' => date('j', $timestamp), 'month' => date('n', $timestamp), 'year' => date('Y', $timestamp)));
         $element['workflow']['workflow_scheduling']['date_time']['workflow_scheduled_hour'] = array('#type' => 'textfield', '#title' => t('Time'), '#maxlength' => 7, '#size' => 6, '#default_value' => $hours, '#element_validate' => array('_workflow_transition_form_element_validate_time'));
         $element['workflow']['workflow_scheduling']['date_time']['workflow_scheduled_timezone'] = array('#type' => $settings_schedule_timezone ? 'select' : 'hidden', '#title' => t('Time zone'), '#options' => $timezones, '#default_value' => array($timezone => $timezone));
         $element['workflow']['workflow_scheduling']['date_time']['workflow_scheduled_help'] = array('#type' => 'item', '#prefix' => '<br />', '#description' => t('Please enter a time.
       If no time is included, the default will be midnight on the specified date.
       The current time is: @time.', array('@time' => format_date(REQUEST_TIME, 'custom', 'H:i', $timezone))));
     }
     $element['workflow']['workflow_comment'] = array('#type' => 'textarea', '#required' => $settings_comment == '2', '#access' => $settings_comment != '0', '#title' => t('Workflow comment'), '#description' => t('A comment to put in the workflow log.'), '#default_value' => $transition->comment, '#rows' => 2);
     // Add the fields and extra_fields from the WorkflowTransition.
     // Because we have a 'workflow' wrapper, it doesn't work flawlessly.
     field_attach_form('WorkflowTransition', $transition, $element['workflow'], $form_state);
     // Undo the following elements from field_attach_from. They mess up $this->getTransition().
     // - '#parents' corrupts the Defaultwidget.
     unset($element['workflow']['#parents']);
     // - '#pre_render' adds the exra_fields from workflow_field_extra_fields().
     //   That doesn't work, since 'workflow' is not of #type 'form', but
     //   'container' or 'fieldset', and must be executed separately,.
     $element['workflow']['#pre_render'] = array_diff($element['workflow']['#pre_render'], array('_field_extra_fields_pre_render'));
     // Add extra fields.
     $rescue_value = $element['workflow']['#type'];
     $element['workflow']['#type'] = 'form';
     $element['workflow'] = _field_extra_fields_pre_render($element['workflow']);
     $element['workflow']['#type'] = $rescue_value;
     // Finally, add Submit buttons/Action buttons.
     // Either a default 'Submit' button is added, or a button per permitted state.
     if ($settings_options_type == 'buttons') {
         // How do action buttons work? See also d.o. issue #2187151.
         // Create 'action buttons' per state option. Set $sid property on each button.
         // 1. Admin sets ['widget']['options']['#type'] = 'buttons'.
         // 2. This function formElement() creates 'action buttons' per state option;
         //    sets $sid property on each button.
         // 3. User clicks button.
         // 4. Callback _workflow_transition_form_validate_buttons() sets proper State.
         // 5. Callback _workflow_transition_form_validate_buttons() sets Submit function.
         // @todo: this does not work yet for the Add Comment form.
         // Performance: inform workflow_form_alter() to do its job.
         _workflow_use_action_buttons(TRUE);
         // Hide the options box. It will be replaced by action buttons.
         $element['workflow']['workflow_sid']['#type'] = 'select';
         $element['workflow']['workflow_sid']['#access'] = FALSE;
     }
     if ($form_state['build_info']['base_form_id'] == 'workflow_transition_form') {
         // Add action buttons on WorkflowTransitionForm (history tab, formatter)
         // but not on Entity form, and not if action_buttons is selected.
         // you can explicitly NOT add a submit button, e.g., on VBO page.
         if ($instance['widget']['settings']['submit_function'] !== '') {
             // @todo D8: put buttons outside of 'workflow' element, in the standard location.
             $element['workflow']['actions']['#type'] = 'actions';
             $element['workflow']['actions']['submit'] = array('#type' => 'submit', '#value' => t('Update workflow'), '#weight' => -5, '#attributes' => array('class' => array('form-save-default-button')));
             // The 'add submit' can explicitly set by workflowfield_field_formatter_view(),
             // to add the submit button on the Content view page and the Workflow history tab.
             // Add a submit button, but only on Entity View and History page.
             // Add the submit function only if one provided. Set the submit_callback accordingly.
             if (!empty($instance['widget']['settings']['submit_function'])) {
                 $element['workflow']['actions']['submit']['#submit'] = array($instance['widget']['settings']['submit_function']);
             } else {
                 // '#submit' Must be empty, or else the submit function is not called.
                 // $element['workflow']['actions']['submit']['#submit'] = array();
             }
         }
     }
     /*
         $submit_functions = empty($instance['widget']['settings']['submit_function']) ? array() : array($instance['widget']['settings']['submit_function']);
         if ($settings_options_type == 'buttons' || $submit_functions) {
         }
         else {
      // In some cases, no submit callback function is specified. This is
      // explicitly done on e.g., the node edit form, because the workflow form
      // is 'just a field'.
      // So, no Submit button is to be shown.
         }
     */
     $form += $element;
     // Add class following node-form pattern (both on form and container).
     $workflow_type_id = $workflow ? $workflow->getName() : 'none';
     // No workflow on New Action form.
     $form['#attributes']['class'][] = 'workflow-transition-form';
     $form['#attributes']['class'][] = 'workflow-transition-' . $workflow_type_id . '-form';
     return $form;
 }