123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- <?php
- /**
- * @file
- * Hooks and functions for the 'conventional' (version D5/D6/D7.1) Workflow Node, remnants of nodeapi.
- */
- // Includes the hooks for the 'conventional' (version D5/D6/D7.1) Node API.
- require_once(dirname(__DIR__)) . '/workflow.node.type_map.inc';
- require_once(dirname(__DIR__)) . '/workflow.deprecated.inc';
- /**
- * Implements hook_ctools_plugin_directory().
- *
- * This lets ctools know to scan my module for a content_type plugin file
- * Detailed docks in ctools/ctools.api.php
- *
- * This is used to integrate WorkflowNode with Panels. See d.o. #1511694, #2187731
- */
- function workflownode_ctools_plugin_directory($owner, $plugin_type) {
- if ($owner == 'ctools' && !empty($plugin_type)) {
- return "plugins/$plugin_type";
- }
- }
- /**
- * Theme the current workflow state as top line of History tab.
- */
- function theme_workflow_current_state($variables) {
- $state = $variables['state'];
- return '<div class="workflow-current-state '
- . 'workflow-current-sid-' . intval($variables['sid']) . ' '
- . drupal_html_class($state)
- . '">'
- . t('Current state: <span class="state">@state</span>', array('@state' => $state))
- . '</div>';
- }
- /**
- * Implements hook_node_load().
- */
- function workflownode_node_load($nodes, $types) {
- // Get which types have workflows associated with them.
- $workflow_types = workflow_get_workflow_type_map();
- // Leave early if nodes do not have workflow.
- if (!$workflow_types || !array_intersect_key($workflow_types, array_flip($types))) {
- return;
- }
- // Read the current state for all nodes.
- $states = workflow_get_workflow_node_by_nid(array_keys($nodes));
- foreach ($nodes as $nid => $node) {
- // If it's not a workflow type, quit immediately.
- if (!array_key_exists($node->type, $workflow_types)) {
- continue;
- }
- // Nodes that existed before the workflow was defined may not have a state.
- $workflow_node = isset($states[$nid]) ? $states[$nid] : NULL;
- if (!$workflow_node) {
- if ($workflow = workflow_get_workflows_by_type($node->type, 'node')) {
- $node->workflow = $workflow->getCreationSid();
- $node->workflow_stamp = $node->created;
- }
- else {
- // Is this possible?
- }
- }
- else {
- $node->workflow = $workflow_node->sid;
- $node->workflow_stamp = $workflow_node->stamp;
- }
- }
- // As of workflow 7.x-2.x, the scheduled transition is not loaded. See issue #2138591.
- }
- /**
- * Implements hook_node_view().
- */
- function workflownode_node_view($node, $view_mode, $langcode) {
- global $user;
- $form = array();
- $entity_type = 'node'; // This hook is only for nodes.
- $entity_id = $node->nid;
- $field_name = ''; // This hook is only for workflow_node.
- $entity_bundle = $node->type;
- // Skip if there are no Node API workflows.
- if (!workflow_get_workflow_type_map_by_type($entity_bundle)) {
- return;
- }
- // Check permission, so that even with state change rights,
- // the form can be suppressed from the node view (#1893724).
- if (!user_access('show workflow state form', $user)) {
- return;
- }
- // Get the current sid. $field_name is updated with relevant value.
- $current_sid = workflow_node_current_state($node, $entity_type, $field_name);
- $current_state = workflow_state_load_single($current_sid);
- // Show current state at the top of the node display.
- $field = $instance = array();
- $node->content['workflow_current_state'] = workflow_state_formatter($entity_type, $node, $field, $instance, $current_sid);
- $node->content['workflow_current_state']['#weight'] = -99;
- if ($current_state && $current_state->showWidget('node', $node, '', $user, FALSE)) {
- $workflow = $current_state->getWorkflow();
- // 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.
- if ($workflow) {
- $field = _workflow_info_field($field_name, $workflow);
- $field_id = $field['id'];
- $instance = field_info_instance($entity_type, $field_name, $entity_bundle);
- // If no instance is found, restore the array.
- if (!is_array($instance)) {
- $instance = array();
- }
- if (!$field['id']) {
- // This is a Workflow Node workflow. Set widget options as in v7.x-1.2
- $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'] = FALSE;
- }
- }
- // By including the nid in the form id. For backwards compatiblity, do not add entity_type, field_id.
- $form_id = implode('_', array('workflow_transition_form', $entity_id));
- $form += drupal_get_form($form_id, $field, $instance, $entity_type, $node);
- $form['#weight'] = 99;
- $node->content['workflow'] = $form;
- }
- }
- /**
- * Implements hook_node_insert().
- *
- * This is executed after saving data to the database.
- * We cannot use hook_node_presave, because workflow_execute_transition() needs the nid.
- */
- function workflownode_node_insert($node) {
- global $user;
- if (!isset($node->workflow_field)) {
- // Initializing the state of the node in case no widget on Node form.
- if ($workflow = workflow_get_workflows_by_type($node->type, 'node')) {
- $comment = t('Set to initial state.');
- $force = TRUE;
- $creation_sid = $workflow->getCreationSid();
- // Get the initial state for this node.
- // Due to permissions, it might be different for each user.
- $new_sid = $workflow->getFirstSid('node', $node, null, $user, $force);
- $transition = new WorkflowTransition();
- $transition->setValues('node', $node, null, $creation_sid, $new_sid, $user->uid, REQUEST_TIME, $comment);
- // Force it to transition to the first state and get a history record.
- workflow_execute_transition('node', $node, null, $transition, $force);
- }
- }
- return workflownode_node_update($node);
- }
- /**
- * Implements hook_node_update().
- */
- function workflownode_node_update($node) {
- if (!isset($node->workflow_field)) {
- // For this type_map, user did not want a form here.
- return;
- }
- $form = array();
- // Retrieve the data from the form.
- // Add form values (field, instance, entity_type, entity), then form input.
- $form_state = array();
- $form_state['values']['workflow_field'] = $node->workflow_field;
- $form_state['values']['workflow_instance'] = $node->workflow_instance;
- $form_state['values']['workflow_entity_type'] = 'node';
- // Careful: take the fresh node here, not the one that is in the form.
- $form_state['values']['workflow_entity'] = $node;
- // For some reason, the Workflow Form does not return the form in a 'workflow' array.
- // @todo: correct this (use '#tree => TRUE'), or filter on 'workflow' elements.
- $form_state['input'] = (array) $node;
- workflow_transition_form_submit($form, $form_state);
- }
- /**
- * Implements hook_node_delete().
- */
- function workflownode_node_delete($node) {
- if (!empty($node->workflow)) {
- // Call field_info_field().
- // Generates pseudo data for workflow_node to re-use Field API.
- $field = _workflow_info_field($field_name = '', $workflow = NULL);
- $instance = array();
- $items[0]['value'] = $node->workflow;
- $workflow_field = new WorkflowItem($field, $instance, 'node', $node);
- $workflow_field->delete($items);
- }
- }
- /**
- * Implements hook_comment_insert().
- */
- function workflownode_comment_insert($comment) {
- workflownode_comment_update($comment);
- }
- /**
- * Implements hook_comment_update().
- */
- function workflownode_comment_update($comment) {
- // Retrieve the data from the form.
- if (!isset($comment->workflow_field)) {
- // For this type_map, user did not want a form here.
- return;
- }
- $form = array();
- // Retrieve the data from the form.
- // Add form values (field, instance, entity_type, entity), then form input.
- $form_state = array();
- $form_state['values']['workflow_field'] = $comment->workflow_field;
- $form_state['values']['workflow_instance'] = $comment->workflow_instance;
- $form_state['values']['workflow_entity_type'] = $comment->workflow_entity_type;
- $form_state['values']['workflow_entity'] = $comment->workflow_entity;
- // For some reason, the Workflow Form does not return the form in a 'workflow' array.
- // @todo: correct this, or filter on 'workflow' elements.
- $form_state['input'] = (array) $comment;
- workflow_transition_form_submit($form, $form_state);
- }
- /**
- * Implements hook_field_extra_fields().
- */
- function workflownode_field_extra_fields() {
- $extra = array();
- // Get all workflows by content types.
- $types = array_filter(workflow_get_workflow_type_map());
- // Add the extra fields to each content type that has a workflow.
- foreach ($types as $type => $wid) {
- $extra['node'][$type] = array(
- 'form' => array(
- 'workflow' => array(
- 'label' => t('Workflow'),
- 'description' => t('Workflow module form'),
- 'weight' => 99, // Default to bottom.
- ),
- ),
- 'display' => array(
- 'workflow_current_state' => array(
- 'label' => t('Workflow: Current State'),
- 'description' => t('Current workflow state'),
- 'weight' => -99, // Default to top.
- ),
- 'workflow' => array(
- 'label' => t('Workflow: State Change Form'),
- 'description' => t('The form for controlling workflow state changes.'),
- 'weight' => 99, // Default to bottom.
- ),
- ),
- );
- }
- return $extra;
- }
- /**
- * Implements hook_form_BASE_FORM_ID_alter().
- *
- * Shows the form only on Node Edit forms.
- */
- function workflownode_form_node_form_alter(&$form, &$form_state, $form_id) {
- _workflownode_form_alter($form, $form_state, $form_id);
- }
- /**
- * Implements hook_form_BASE_FORM_ID_alter().
- *
- * Shows the form only on Comment forms.
- */
- function workflownode_form_comment_form_alter(&$form, &$form_state, $form_id) {
- _workflownode_form_alter($form, $form_state, $form_id);
- }
- /**
- * Helper function to implement hook_form_alter().
- *
- * Is now a subfunction of workflow_form_BASE_FORM_ID_alter().
- * This is more performant (compared to 7.x-1.2 and before), since it is called
- * only on form with correct BASE_FORM_ID.
- *
- * @see http://bryanbraun.com/2013/08/17/using-hook-form-base-form-id-alter
- */
- function _workflownode_form_alter(&$form, &$form_state, $form_id) {
- // Set node to #node if available or load from nid value.
- $node = isset($form['#node']) ? $form['#node'] : node_load($form['nid']['#value']);
- $bundle = $node->type;
- $entity = $node;
- $entity_type = 'node';
- $field_name = '';
- // Skip if there are no Node API workflows.
- if (!workflow_get_workflow_type_map_by_type($bundle)) {
- return;
- }
- if ($workflow = workflow_get_workflows_by_type($bundle, 'node')) {
- $workflow_entities = variable_get('workflow_' . $bundle, array());
- // Abort if the entity type of the form is not in the list that the user
- // wants to display the workflow form on.
- if (!in_array($form['#entity_type'], $workflow_entities)) {
- return;
- }
- /*
- $form['#wf'] = $workflow;
- $form['workflow'] = array(
- '#type' => 'fieldset',
- '#title' => check_plain($label),
- '#collapsible' => TRUE,
- '#collapsed' => FALSE,
- '#weight' => 10,
- );
- */
- // Emulate a Field API interface.
- // 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, etc.
- if ($workflow) {
- $field = _workflow_info_field($field_name, $workflow);
- $field_name = $field['field_name'];
- $field_id = $field['id'];
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- if (!$field_id) {
- // This is a Workflow Node workflow. Set widget options as in v7.x-1.2
- $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;
- }
- }
- // Do not include the default 'Update Workflow' button, since we are already in an Edit form.
- $instance['widget']['settings']['submit_function'] = '';
- // Include the 'workflow form'. $form is modified by reference.
- $form = workflow_transition_form($form, $form_state, $field, $instance, $entity_type, $entity);
- }
- }
|