workflownode.module in Workflow 7.2
Hooks and functions for the 'conventional' (version D5/D6/D7.1) Workflow Node, remnants of nodeapi.
File
workflow_node/workflownode.moduleView source
<?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,
),
),
'display' => array(
'workflow_current_state' => array(
'label' => t('Workflow: Current State'),
'description' => t('Current workflow state'),
'weight' => -99,
),
'workflow' => array(
'label' => t('Workflow: State Change Form'),
'description' => t('The form for controlling workflow state changes.'),
'weight' => 99,
),
),
);
}
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);
}
}
Functions
Name![]() |
Description |
---|---|
theme_workflow_current_state | Theme the current workflow state as top line of History tab. |
workflownode_comment_insert | Implements hook_comment_insert(). |
workflownode_comment_update | Implements hook_comment_update(). |
workflownode_ctools_plugin_directory | Implements hook_ctools_plugin_directory(). |
workflownode_field_extra_fields | Implements hook_field_extra_fields(). |
workflownode_form_comment_form_alter | Implements hook_form_BASE_FORM_ID_alter(). |
workflownode_form_node_form_alter | Implements hook_form_BASE_FORM_ID_alter(). |
workflownode_node_delete | Implements hook_node_delete(). |
workflownode_node_insert | Implements hook_node_insert(). |
workflownode_node_load | Implements hook_node_load(). |
workflownode_node_update | Implements hook_node_update(). |
workflownode_node_view | Implements hook_node_view(). |
_workflownode_form_alter | Helper function to implement hook_form_alter(). |