/** * Returns the allowed values for the current state. * * @deprecated workflow_field_choices() --> WorkflowState->getOptions() */ public function getOptions($entity_type, $entity, $force = FALSE) { global $user; static $cache = array(); // Entity-specific cache per page load. $options = array(); if (!$entity) { // If no entity is given, no result (e.g., on a Field settings page). $options = array(); return $options; } $entity_id = entity_id($entity_type, $entity); $current_sid = $this->sid; // Get options from page cache. if (isset($cache[$entity_type][$entity_id][$force][$current_sid])) { $options = $cache[$entity_type][$entity_id][$force][$current_sid]; return $options; } $workflow = Workflow::load($this->wid); if ($workflow) { $roles = array_keys($user->roles); // If this is a new page, give the authorship role. if (!$entity_id) { $roles = array_merge(array('author'), $roles); } elseif (isset($entity->uid) && $entity->uid == $user->uid && $user->uid > 0) { $roles = array_merge(array('author'), $roles); } // Superuser is special. And $force allows Rules to cause transition. if ($user->uid == 1 || $force) { $roles = 'ALL'; } // Workflow_allowable_transitions() does not return the entire transition row. Would like it to, but doesn't. // Instead it returns just the allowable data as: // [tid] => 1 [state_id] => 1 [state_name] => (creation) [state_weight] => -50 $transitions = workflow_allowable_transitions($current_sid, 'to', $roles); // Include current state if it is not the (creation) state. foreach ($transitions as $transition) { if ($transition->sysid != WORKFLOW_CREATION && !$force) { // Invoke a callback indicating that we are collecting state choices. // Modules may veto a choice by returning FALSE. // In this case, the choice is never presented to the user. // @todo: for better performance, call a hook only once: can we find a way to pass all transitions at once $result = module_invoke_all('workflow', 'transition permitted', $current_sid, $transition->state_id, $entity, $field_name = ''); // Did anybody veto this choice? if (!in_array(FALSE, $result)) { // If not vetoed, add to list. $options[$transition->state_id] = check_plain(t($transition->state_name)); } } } // Save to entity-specific cache. $cache[$entity_type][$entity_id][$force][$current_sid] = $options; } return $options; }
/** * Implements hook_field_widget_form --> WidgetInterface::formElement(). * * {@inheritdoc} * * Be careful: this 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, $langcode, array &$form, array &$form_state) { $field_name = $this->field['field_name']; $field = $this->instance; $instance = $this->instance; $entity = $this->entity; $entity_type = $this->entity_type; $entity_id = 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 = !empty($this->field['settings']['widget']['name_as_title']); // The schedule cannot be shown on a Content add page. $settings_schedule = !empty($this->field['settings']['widget']['schedule']) && $entity_id; $settings_schedule_timezone = !empty($this->field['settings']['widget']['schedule_timezone']); // Show comment, when both Field and Instance allow this. $settings_comment = $this->field['settings']['widget']['comment'] ? 'textarea' : 'hidden'; $workflow = Workflow::load($this->field['settings']['wid']); $current_sid = workflow_node_current_state($entity, $entity_type, $field_name); $current_state = WorkflowState::load($current_sid); $options = array(); $options = $current_state->getOptions($entity_type, $entity); // 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; // 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'; $current_sid = $scheduled_transition->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.). $form_id = $form_state['build_info']['form_id']; $element_scheduled_name = 'workflow_scheduled_' . $form_id; $element_options_name = 'workflow_options_' . $form_id; $element_scheduled_name = 'workflow_scheduled'; $element_options_name = 'workflow_options'; $elt_state_name = 'workflow_scheduled_' . $form_id; $label = $workflow->label(); // Prepare a wrapper. This might be a fieldset. $element['workflow']['#type'] = 'container'; $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' => $this->field); $element['workflow']['workflow_instance'] = array('#type' => 'value', '#value' => $this->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 (!$current_state->showWidget($options)) { $element['workflow'][$element_options_name] = workflow_state_formatter($entity_type, $entity, $field, $instance); return $element; } else { $element['workflow'][$element_options_name] = array('#type' => $this->field['settings']['widget']['options'], '#title' => $settings_title_as_name ? t('Change !name state', array('!name' => $label)) : '', '#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')) { 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()); $hours = format_date($timestamp, 'custom', 'H:i', $timezone); // $element['workflow']['workflow_scheduled'] = array( $element['workflow'][$element_scheduled_name] = 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' => 5, '#size' => 6, '#default_value' => $scheduled ? $hours : '00:00'); $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 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' => format_date(REQUEST_TIME, 'custom', 'H:i', $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); // 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. if (!empty($this->instance['widget']['settings']['submit_function'])) { // 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($this->instance['widget']['settings']['submit_function'])); } return $element; }
/** * Given information, update or insert a new workflow. * * @deprecated: workflow_update_workflows() --> Workflow->save() */ public function save($create_creation_state = TRUE) { $wid = $this->wid; if (isset($this->tab_roles) && is_array($this->tab_roles)) { $this->tab_roles = implode(',', $this->tab_roles); } if (is_array($this->options)) { $this->options = serialize($this->options); } if ($wid > 0 && Workflow::load($wid)) { drupal_write_record('workflows', $this, 'wid'); } else { drupal_write_record('workflows', $this); if ($create_creation_state) { $creation_state = $this->getCreationState(); $creation_state->save(); } } // Update the page cache. self::$workflows[$wid] = $this; }