public function WorkflowDefaultWidget::formElement in Workflow 7
Same name and namespace in other branches
- 7.2 includes/Field/WorkflowDefaultWidget.php \WorkflowDefaultWidget::formElement()
Implements hook_field_widget_form --> WidgetInterface::formElement().
Be careful: this widget may be shown in very different places. Test carefully!!
- On a node add/edit page
- On a node preview page
- On a node view page
- On a node '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"
File
- includes/
Field/ WorkflowDefaultWidget.php, line 66 - Contains workflow\includes\Field\WorkflowDefaultWidget.
Class
- WorkflowDefaultWidget
- Plugin implementation of the 'workflow_default' widget. @todo D8: Replace "extends WorkflowD7WidgetBase" by "extends WidgetBase" or perhaps by "extends OptionsWidgetBase" from Options module.
Code
public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
$field_name = $this->field['field_name'];
$entity = $this->entity;
$entity_type = $this->entity_type;
$entity_id = isset($entity->nid) ? $entity->nid : entity_id($entity_type, $entity);
if (!$entity) {
// If no entity given, do not show a form. E.g., on the field settings page.
return $element;
}
// Capture settings to format the form/widget.
$settings_title_as_name = $this->field['settings']['widget']['name_as_title'] && $this->instance['widget']['settings']['name_as_title'];
// The schedule cannot be shown on a Content add page.
$settings_schedule = $this->field['settings']['widget']['schedule'] && $entity_id;
$settings_schedule_timezone = $this->field['settings']['widget']['schedule_timezone'];
$settings_comment = $this->field['settings']['widget']['comment'] && $this->instance['widget']['settings']['comment'] ? 'textarea' : 'hidden';
// The 'add submit' setting is explicitely set by workflowfield_field_formatter_view(), to add the submit button on the Content view page.
$settings_submit = isset($this->instance['widget']['settings']['submit']) ? TRUE : FALSE;
$workflow = Workflow::load($this->field['settings']['wid']);
// @todo: Get the current sid for content, comment, preview.
if (count($items)) {
// A normal Content edit.
$sid = _workflow_get_sid_by_items($items);
}
else {
// We are on a Content add or Comment add (which do not have a state, yet),
// or we are viewing existing content, which didn't have a state before.
//@todo: why/when would field_get_items returns a result, if $items is already empty?
$items = field_get_items($entity_type, $entity, $field_name);
if ($items) {
$sid = _workflow_get_sid_by_items($items);
}
}
if (empty($sid)) {
// Content add page: No valid sid is given, so get the first state.
// or a states has been deleted.
$sid = $workflow
->getFirstSid($entity_type, $entity);
}
$state = WorkflowState::load($sid);
$options = $state
->getOptions($entity_type, $entity);
// 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';
$sid = $scheduled_transition->sid;
$timestamp = $scheduled_transition->scheduled;
$comment = $scheduled_transition->comment;
break;
}
}
// Stop if user has no new target state(s) to choose.
if (!workflow_show_form($sid, $workflow, $options)) {
//dpm('show only formatter for ' . $sid , __FUNCTION__);
return $element;
}
$label = $workflow
->label();
$element['workflow'] = array(
'#type' => 'fieldset',
'#title' => $label,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
// Save the current value of the node in the form, for later reference.
$element['workflow']['#node'] = $entity;
$element['workflow']['#entity'] = $entity;
$element['#node'] = $entity;
$element['#entity'] = $entity;
//dpm(array_pop($options));
//dpm(array_pop($options));
if (count($options) == 1) {
// Add the State widget/formatter
// @todo: add real formatter, instead.
// @todo: TEST THIS USE CASE.
// There is no need to show the single choice.
// A form choice would be an array with the key of the state.
$state = key($options);
// $element['workflow'][$label] = array(
$element['workflow']['workflow_options'] = array(
'#type' => 'value',
'#value' => array(
$state => $state,
),
);
}
else {
// @todo: Q: why are we overwriting 'fieldset' with 'container' ?
// A: this is because you'd want the form in a vertical tab, and a fieldset makes no sense there.
$element['workflow']['#type'] = 'container';
$element['workflow']['#attributes'] = array(
'class' => array(
'workflow-form-container',
),
);
$element['workflow']['workflow_options'] = array(
'#type' => $this->field['settings']['widget']['options'],
'#title' => $settings_title_as_name ? t('Change !name state', array(
'!name' => $label,
)) : '',
'#options' => $options,
// '#name' => $label,
// '#parents' => array('workflow'),
'#default_value' => $sid,
);
}
// 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')) {
// Caveat: for the #states to work in multi-node view, the name is suffixed by unique ID.
if (isset($form['#id']) && $form['#id'] == 'comment-form') {
// This is already the name for Node API and now also for Comment form.
// We assume there is only one Comment form on a page.
$element_name = 'workflow_scheduled';
}
else {
// This name allows for multiple nodes on a page.
// @todo: #states doesn't work yet for non-Node entities.
$element_name = 'workflow_scheduled' . '-' . $entity_type . '-' . $entity_id;
}
// $element['workflow']['workflow_scheduled'] = array(
$element['workflow'][$element_name] = array(
'#type' => 'radios',
'#title' => t('Schedule'),
'#options' => array(
'0' => t('Immediately'),
'1' => t('Schedule for state change'),
),
'#default_value' => $scheduled,
);
$element['workflow']['workflow_scheduled_date_time'] = array(
'#type' => 'fieldset',
'#title' => t('At'),
'#prefix' => '<div style="margin-left: 1em;">',
'#suffix' => '</div>',
'#states' => array(
// 'visible' => array(':input[name="workflow_scheduled"]' => array('value' => '1')),
// 'invisible' => array(':input[name="workflow_scheduled"]' => array('value' => '0')),
'visible' => array(
':input[name="' . $element_name . '"]' => array(
'value' => '1',
),
),
'invisible' => array(
':input[name="' . $element_name . '"]' => array(
'value' => '0',
),
),
),
);
$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),
),
);
$hours = format_date($timestamp, 'custom', 'H:i');
$element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_hour'] = array(
'#type' => 'textfield',
'#description' => t('Please enter a time in 24 hour (eg. HH:MM) format.
If no time is included, the default will be midnight on the specified date.
The current time is: @time', array(
'@time' => $hours,
)),
'#default_value' => $scheduled ? isset($form_state['values']['workflow_scheduled_hour']) ? $form_state['values']['workflow_scheduled_hour'] : $hours : '00:00',
);
global $user;
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());
$element['workflow']['workflow_scheduled_date_time']['workflow_scheduled_timezone'] = array(
'#type' => $settings_schedule_timezone ? 'select' : 'hidden',
'#options' => $timezones,
'#title' => t('Time zone'),
'#default_value' => array(
$timezone => $timezone,
),
);
}
$element['workflow']['workflow_comment'] = array(
'#type' => $settings_comment,
'#title' => t('Workflow comment'),
'#description' => t('A comment to put in the workflow log.'),
'#default_value' => $comment,
'#rows' => 2,
);
if ($settings_submit) {
// Add a submit button, but only on Entity View and History page.
$element['workflow']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update workflow'),
'#executes_submit_callback' => TRUE,
'#submit' => array(
'workflowfield_field_widget_form_submit',
),
);
}
return $element;
}