View source
<?php
define('WORKFLOW_CREATION', 1);
define('WORKFLOW_CREATION_DEFAULT_WEIGHT', -50);
define('WORKFLOW_DELETION', 0);
function workflow_perm() {
return array(
'schedule workflow transitions',
);
}
function workflow_menu() {
$items['node/%node/workflow'] = array(
'title' => 'Workflow',
'type' => MENU_LOCAL_TASK,
'access callback' => 'workflow_node_tab_access',
'access arguments' => array(
1,
),
'page callback' => 'workflow_tab_page',
'page arguments' => array(
1,
),
'file' => 'workflow.pages.inc',
'weight' => 2,
);
return $items;
}
function workflow_node_tab_access($node = NULL) {
global $user;
$wid = workflow_get_workflow_for_type($node->type);
if ($wid === FALSE) {
return FALSE;
}
$roles = array_keys($user->roles);
if ($node->uid == $user->uid) {
$roles = array_merge(array(
'author',
), $roles);
}
$workflow = db_fetch_object(db_query("SELECT * FROM {workflows} WHERE wid = %d", $wid));
$allowed_roles = $workflow->tab_roles ? explode(',', $workflow->tab_roles) : array();
if (user_access('administer nodes') || array_intersect($roles, $allowed_roles)) {
return TRUE;
}
else {
return FALSE;
}
}
function workflow_theme() {
return array(
'workflow_history_table_row' => array(
'arguments' => array(
'history' => NULL,
'old_state_name' => NULL,
'state_name' => null,
),
),
'workflow_history_table' => array(
'arguments' => array(
'rows' => array(),
'footer' => NULL,
),
),
'workflow_current_state' => array(
'arguments' => array(
'state_name' => NULL,
),
),
'workflow_deleted_state' => array(
'arguments' => array(
'state_name' => NULL,
),
),
);
}
function workflow_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'load':
$node->_workflow = workflow_node_current_state($node);
$res = db_query('SELECT * FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);
if ($row = db_fetch_object($res)) {
$node->_workflow_scheduled_sid = $row->sid;
$node->_workflow_scheduled_timestamp = $row->scheduled;
$node->_workflow_scheduled_comment = $row->comment;
}
break;
case 'insert':
if (empty($node->workflow)) {
$choices = workflow_field_choices($node);
$keys = array_keys($choices);
$sid = array_shift($keys);
}
case 'update':
$wid = workflow_get_workflow_for_type($node->type);
if (!$wid) {
break;
}
if (!isset($sid)) {
$sid = $node->workflow;
}
workflow_transition($node, $sid);
break;
case 'delete':
$node->workflow_stamp = time();
db_query("DELETE FROM {workflow_node} WHERE nid = %d", $node->nid);
_workflow_write_history($node, WORKFLOW_DELETION, t('Node deleted'));
db_query("DELETE FROM {workflow_scheduled_transition} WHERE nid = %d", $node->nid);
break;
}
}
function workflow_comment($a1, $op) {
if (($op == 'insert' || $op == 'update') && isset($a1['workflow'])) {
$node = node_load($a1['nid']);
$sid = $a1['workflow'];
$node->workflow_comment = $a1['workflow_comment'];
if (isset($a1['workflow_scheduled'])) {
$node->workflow_scheduled = $a1['workflow_scheduled'];
$node->workflow_scheduled_date = $a1['workflow_scheduled_date'];
$node->workflow_scheduled_hour = $a1['workflow_scheduled_hour'];
}
workflow_transition($node, $sid);
}
}
function workflow_transition($node, $sid) {
if (array_key_exists($sid, workflow_field_choices($node))) {
$node->workflow_scheduled = isset($node->workflow_scheduled) ? $node->workflow_scheduled : FALSE;
if (!$node->workflow_scheduled) {
workflow_execute_transition($node, $sid, isset($node->workflow_comment) ? $node->workflow_comment : NULL);
}
else {
$comment = $node->workflow_comment;
$old_sid = workflow_node_current_state($node);
if ($node->workflow_scheduled_date['day'] < 10) {
$node->workflow_scheduled_date['day'] = '0' . $node->workflow_scheduled_date['day'];
}
if ($node->workflow_scheduled_date['month'] < 10) {
$node->workflow_scheduled_date['month'] = '0' . $node->workflow_scheduled_date['month'];
}
if (!$node->workflow_scheduled_hour) {
$node->workflow_scheduled_hour = '00:00';
}
$scheduled = $node->workflow_scheduled_date['year'] . $node->workflow_scheduled_date['month'] . $node->workflow_scheduled_date['day'] . ' ' . $node->workflow_scheduled_hour . 'Z';
if ($scheduled = strtotime($scheduled)) {
global $user;
if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
$timezone = $user->timezone;
}
else {
$timezone = variable_get('date_default_timezone', 0);
}
$scheduled = $scheduled - $timezone;
db_query("DELETE FROM {workflow_scheduled_transition} WHERE nid = %d", $node->nid);
db_query("INSERT INTO {workflow_scheduled_transition} VALUES (%d, %d, %d, %d, '%s')", $node->nid, $old_sid, $sid, $scheduled, $comment);
$state_name = workflow_get_state_name($sid);
watchdog('workflow', '@node_title scheduled for state change to %state_name on !scheduled_date', array(
'@node_title' => $node->title,
'%state_name' => $state_name,
'!scheduled_date' => format_date($scheduled),
), WATCHDOG_NOTICE, l('view', "node/{$node->nid}/workflow"));
drupal_set_message(t('@node_title is scheduled for state change to %state_name on !scheduled_date', array(
'@node_title' => $node->title,
'%state_name' => $state_name,
'!scheduled_date' => format_date($scheduled),
)));
}
}
}
}
function workflow_node_form(&$form, $form_state, $title, $name, $current, $choices, $timestamp = NULL, $comment = NULL) {
if (sizeof($choices) == 1) {
$form['workflow'][$name] = array(
'#type' => 'hidden',
'#value' => $current,
);
}
else {
$form['workflow'][$name] = array(
'#type' => 'radios',
'#title' => $form['#wf']->options['name_as_title'] ? $title : '',
'#options' => $choices,
'#name' => $name,
'#parents' => array(
'workflow',
),
'#default_value' => $current,
);
if (!(arg(0) == 'node' && arg(1) == 'add') && user_access('schedule workflow transitions')) {
$scheduled = $timestamp ? 1 : 0;
$timestamp = $scheduled ? $timestamp : time();
$form['workflow']['workflow_scheduled'] = array(
'#type' => 'radios',
'#title' => t('Schedule'),
'#options' => array(
t('Immediately'),
t('Schedule for state change at:'),
),
'#default_value' => isset($form_state['values']['workflow_scheduled']) ? $form_state['values']['workflow_scheduled'] : $scheduled,
);
$form['workflow']['workflow_scheduled_date'] = array(
'#type' => 'date',
'#default_value' => array(
'day' => isset($form_state['values']['workflow_scheduled_date']['day']) ? $form_state['values']['workflow_scheduled_date']['day'] : format_date($timestamp, 'custom', 'j'),
'month' => isset($form_state['values']['workflow_scheduled_date']['month']) ? $form_state['values']['workflow_scheduled_date']['month'] : format_date($timestamp, 'custom', 'n'),
'year' => isset($form_state['values']['workflow_scheduled_date']['year']) ? $form_state['values']['workflow_scheduled_date']['year'] : format_date($timestamp, 'custom', 'Y'),
),
);
$hours = format_date($timestamp, 'custom', 'H:i');
$form['workflow']['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: ') . format_date(time()),
'#default_value' => $scheduled ? isset($form_state['values']['workflow_scheduled_hour']) ? $form_state['values']['workflow_scheduled_hour'] : $hours : NULL,
);
}
if (isset($form['#tab'])) {
$determiner = 'comment_log_tab';
}
else {
$determiner = 'comment_log_node';
}
$form['workflow']['workflow_comment'] = array(
'#type' => $form['#wf']->options[$determiner] ? 'textarea' : 'hidden',
'#title' => t('Comment'),
'#description' => t('A comment to put in the workflow log.'),
'#default_value' => $comment,
'#rows' => 2,
);
}
}
function workflow_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'comment_form' || isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
if (isset($form['#node'])) {
$node = $form['#node'];
if (!in_array('node', variable_get('workflow_' . $node->type, array(
'node',
)))) {
return;
}
}
else {
$type = db_result(db_query("SELECT type FROM {node} WHERE nid = %d", $form['nid']['#value']));
if (!in_array('comment', variable_get('workflow_' . $type, array(
'node',
)))) {
return;
}
$node = node_load($form['nid']['#value']);
}
$choices = workflow_field_choices($node);
$wid = workflow_get_workflow_for_type($node->type);
$states = workflow_get_states($wid);
$current = isset($form_state['values']['workflow']) ? $form_state['values']['workflow'] : workflow_node_current_state($node);
$min = $states[$current] == t('(creation)') ? 1 : 2;
if (count($choices) < $min) {
return;
}
$workflow = workflow_load($wid);
$form['#wf'] = $workflow;
$name = check_plain($workflow->name);
if (!isset($choices[$current])) {
$array = array_keys($choices);
$current = $array[0];
}
if (sizeof($choices) > 1) {
$form['workflow'] = array(
'#type' => 'fieldset',
'#title' => $name,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => 10,
);
}
$timestamp = NULL;
$comment = '';
if (isset($node->_workflow_scheduled_timestamp) && isset($node->_workflow_scheduled_sid)) {
$current = $node->_workflow_scheduled_sid;
$timestamp = $node->_workflow_scheduled_timestamp;
$comment = $node->_workflow_scheduled_comment;
}
if (isset($form_state['values']['workflow_comment'])) {
$comment = $form_state['values']['workflow_comment'];
}
workflow_node_form($form, $form_state, $name, $name, $current, $choices, $timestamp, $comment);
}
}
function workflow_execute_transition($node, $sid, $comment = NULL, $force = FALSE) {
global $user;
$old_sid = workflow_node_current_state($node);
if ($old_sid == $sid) {
if ($comment && !$node->_workflow_scheduled_comment) {
$node->workflow_stamp = time();
db_query("UPDATE {workflow_node} SET stamp = %d WHERE nid = %d", $node->workflow_stamp, $node->nid);
$result = module_invoke_all('workflow', 'transition pre', $old_sid, $sid, $node);
_workflow_write_history($node, $sid, $comment);
unset($node->workflow_comment);
$result = module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);
if (module_exists('rules')) {
rules_invoke_event('workflow_comment_added', $node, $old_sid, $sid);
}
}
return;
}
$tid = workflow_get_transition_id($old_sid, $sid);
if (!$tid && !$force) {
watchdog('workflow', 'Attempt to go to nonexistent transition (from %old to %new)', array(
'%old' => $old_sid,
'%new' => $sid,
WATCHDOG_ERROR,
));
return;
}
if ($user->uid != 1 && !$force) {
if (!workflow_transition_allowed($tid, array_merge(array_keys($user->roles), array(
'author',
)))) {
watchdog('workflow', 'User %user not allowed to go from state %old to %new', array(
'%user' => $user->name,
'%old' => $old_sid,
'%new' => $sid,
WATCHDOG_NOTICE,
));
return;
}
}
$result = module_invoke_all('workflow', 'transition pre', $old_sid, $sid, $node);
if (in_array(FALSE, $result)) {
watchdog('workflow', 'Transition vetoed by module.');
return;
}
if (!isset($node->_workflow)) {
$node->_workflow = $old_sid;
}
_workflow_node_to_state($node, $sid, $comment);
$node->_workflow = $sid;
$state_name = workflow_get_state_name($sid);
$type = node_get_types('name', $node->type);
watchdog('workflow', 'State of @type %node_title set to %state_name', array(
'@type' => $type,
'%node_title' => $node->title,
'%state_name' => $state_name,
), WATCHDOG_NOTICE, l('view', 'node/' . $node->nid));
module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);
db_query('DELETE FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);
if (module_exists('rules')) {
rules_invoke_event('workflow_state_changed', $node, $old_sid, $sid);
}
return $sid;
}
function workflow_field_choices($node) {
global $user;
$wid = workflow_get_workflow_for_type($node->type);
if (!$wid) {
return array();
}
$states = workflow_get_states($wid);
$roles = array_keys($user->roles);
$current_sid = workflow_node_current_state($node);
if ($user->uid == $node->uid && $node->uid > 0 || arg(0) == 'node' && arg(1) == 'add') {
$roles += array(
'author' => 'author',
);
}
if ($user->uid == 1) {
$roles = 'ALL';
}
$transitions = workflow_allowable_transitions($current_sid, 'to', $roles);
if ($current_sid == _workflow_creation_state($wid)) {
unset($transitions[$current_sid]);
}
return $transitions;
}
function workflow_node_current_state($node) {
$sid = FALSE;
if (!empty($node->nid)) {
$sid = db_result(db_query('SELECT sid FROM {workflow_node} WHERE nid = %d', $node->nid));
}
if (!$sid && !empty($node->type)) {
$wid = workflow_get_workflow_for_type($node->type);
$sid = _workflow_creation_state($wid);
}
return $sid;
}
function _workflow_creation_state($wid) {
static $cache;
if (!isset($cache[$wid])) {
$result = db_result(db_query("SELECT sid FROM {workflow_states} WHERE wid = %d AND sysid = %d", $wid, WORKFLOW_CREATION));
$cache[$wid] = $result;
}
return $cache[$wid];
}
function workflow_load($wid) {
$workflow = db_fetch_object(db_query('SELECT * FROM {workflows} WHERE wid = %d', $wid));
$workflow->options = unserialize($workflow->options);
return $workflow;
}
function workflow_update_transitions($transitions = array()) {
if (!$transitions) {
return;
}
foreach ($transitions as $from => $to_data) {
foreach ($to_data as $to => $role_data) {
foreach ($role_data as $role => $can_do) {
if ($can_do) {
workflow_transition_add_role($from, $to, $role);
}
else {
workflow_transition_delete_role($from, $to, $role);
}
}
}
}
db_query("DELETE FROM {workflow_transitions} WHERE roles = ''");
}
function workflow_transition_add_role($from, $to, $role) {
$transition = array(
'sid' => $from,
'target_sid' => $to,
'roles' => $role,
);
$tid = workflow_get_transition_id($from, $to);
if ($tid) {
$roles = db_result(db_query("SELECT roles FROM {workflow_transitions} WHERE tid=%d", $tid));
$roles = explode(',', $roles);
if (array_search($role, $roles) === FALSE) {
$roles[] = $role;
$transition['roles'] = implode(',', $roles);
$transition['tid'] = $tid;
drupal_write_record('workflow_transitions', $transition, 'tid');
}
}
else {
drupal_write_record('workflow_transitions', $transition);
}
}
function workflow_transition_delete_role($from, $to, $role) {
$tid = workflow_get_transition_id($from, $to);
if ($tid) {
$roles = db_result(db_query("SELECT roles FROM {workflow_transitions} WHERE tid=%d", $tid));
$roles = explode(',', $roles);
if (($i = array_search($role, $roles)) !== FALSE) {
unset($roles[$i]);
db_query("UPDATE {workflow_transitions} SET roles='%s' WHERE tid=%d", implode(',', $roles), $tid);
}
}
}
function workflow_transition_allowed($tid, $role = NULL) {
$allowed = db_result(db_query("SELECT roles FROM {workflow_transitions} WHERE tid = %d", $tid));
$allowed = explode(',', $allowed);
if ($role) {
if (!is_array($role)) {
$role = array(
$role,
);
}
return array_intersect($role, $allowed) == TRUE;
}
}
function workflow_is_system_state($state) {
static $states;
if (!isset($states)) {
$states = array(
t('(creation)') => TRUE,
);
}
return isset($states[$state]);
}
function workflow_get_name($wid) {
return db_result(db_query("SELECT name FROM {workflows} WHERE wid = %d", $wid));
}
function workflow_get_workflow_for_type($type) {
static $cache;
if (!isset($cache[$type])) {
$wid = db_result(db_query("SELECT wid FROM {workflow_type_map} WHERE type = '%s'", $type));
$cache[$type] = $wid;
}
else {
$wid = $cache[$type];
}
return $wid > 0 ? $wid : FALSE;
}
function workflow_get_all() {
$workflows = array();
$result = db_query("SELECT wid, name FROM {workflows} ORDER BY name ASC");
while ($data = db_fetch_object($result)) {
$workflows[$data->wid] = check_plain(t($data->name));
}
return $workflows;
}
function workflow_create($name) {
$workflow = array(
'name' => $name,
'options' => serialize(array(
'comment_log_node' => 1,
'comment_log_tab' => 1,
)),
);
drupal_write_record('workflows', $workflow);
workflow_state_save(array(
'wid' => $workflow['wid'],
'state' => t('(creation)'),
'sysid' => WORKFLOW_CREATION,
'weight' => WORKFLOW_CREATION_DEFAULT_WEIGHT,
));
menu_rebuild();
return $workflow['wid'];
}
function workflow_update($wid, $name, $tab_roles, $options) {
db_query("UPDATE {workflows} SET name = '%s', tab_roles = '%s', options = '%s' WHERE wid = %d", $name, implode(',', $tab_roles), serialize($options), $wid);
menu_rebuild();
}
function workflow_deletewf($wid) {
$wf = workflow_get_name($wid);
$result = db_query('SELECT sid FROM {workflow_states} WHERE wid = %d', $wid);
while ($data = db_fetch_object($result)) {
workflow_state_delete($data->sid);
db_query('DELETE FROM {workflow_node} WHERE sid = %d', $data->sid);
}
db_query("DELETE FROM {workflow_type_map} WHERE wid = %d", $wid);
db_query('DELETE FROM {workflows} WHERE wid = %d', $wid);
module_invoke_all('workflow', 'workflow delete', $wid, NULL, NULL);
cache_clear_all('*', 'cache_menu', TRUE);
menu_rebuild();
}
function workflow_get_states($wid = NULL) {
$states = array();
if (isset($wid)) {
$result = db_query("SELECT sid, state FROM {workflow_states} WHERE wid = %d AND status = 1 ORDER BY weight, sid", $wid);
while ($data = db_fetch_object($result)) {
$states[$data->sid] = check_plain(t($data->state));
}
}
else {
$result = db_query("SELECT ws.sid, ws.state, w.name FROM {workflow_states} ws INNER JOIN {workflows} w ON ws.wid = w.wid WHERE status = 1 ORDER BY sid");
while ($data = db_fetch_object($result)) {
$states[$data->sid] = check_plain(t($data->name)) . ': ' . check_plain(t($data->state));
}
}
return $states;
}
function workflow_get_state($sid) {
$state = array();
$result = db_query('SELECT wid, state, weight, sysid, status FROM {workflow_states} WHERE sid = %d', $sid);
$data = db_fetch_object($result);
$state['wid'] = $data->wid;
$state['state'] = $data->state;
$state['weight'] = $data->weight;
$state['sysid'] = $data->sysid;
$state['status'] = $data->status;
return $state;
}
function workflow_get_state_name($sid) {
return db_result(db_query('SELECT state FROM {workflow_states} WHERE sid = %d', $sid));
}
function workflow_state_save($state) {
if (!isset($state['sid'])) {
drupal_write_record('workflow_states', $state);
}
else {
drupal_write_record('workflow_states', $state, 'sid');
}
return $state['sid'];
}
function workflow_state_delete($sid, $new_sid = NULL) {
if ($new_sid) {
$node = new stdClass();
$node->workflow_stamp = time();
$result = db_query("SELECT nid FROM {workflow_node} WHERE sid = %d", $sid);
while ($data = db_fetch_object($result)) {
$node->nid = $data->nid;
$node->_workflow = $sid;
_workflow_write_history($node, $new_sid, t('Previous state deleted'));
db_query("UPDATE {workflow_node} SET sid = %d WHERE nid = %d AND sid = %d", $new_sid, $data->nid, $sid);
}
}
else {
db_query('DELETE from {workflow_node} WHERE sid = %d', $sid);
}
$preexisting = array();
$result = db_query("SELECT sid, target_sid FROM {workflow_transitions} WHERE sid = %d OR target_sid = %d", $sid, $sid);
while ($data = db_fetch_object($result)) {
$preexisting[$data->sid][$data->target_sid] = TRUE;
}
foreach ($preexisting as $from => $array) {
foreach (array_keys($array) as $target_id) {
$tid = workflow_get_transition_id($from, $target_id);
workflow_transition_delete($tid);
}
}
db_query("UPDATE {workflow_states} SET status = 0 WHERE sid = %d", $sid);
module_invoke_all('workflow', 'state delete', $sid, NULL, NULL);
}
function workflow_transition_delete($tid) {
if (function_exists('workflow_actions_get_actions')) {
$actions = workflow_actions_get_actions($tid);
foreach ($actions as $aid => $type) {
workflow_actions_actions_remove($tid, $aid);
}
}
db_query("DELETE FROM {workflow_transitions} WHERE tid = %d", $tid);
module_invoke_all('workflow', 'transition delete', $tid, NULL, NULL);
}
function workflow_allowable_transitions($sid, $dir = 'to', $roles = 'ALL') {
$transitions = array();
if ($dir == 'to') {
$field = 'target_sid';
$field_where = 'sid';
}
else {
$field = 'sid';
$field_where = 'target_sid';
}
$result = db_query("(SELECT t.tid, t.%s as state_id, s.state AS state_name, s.weight AS state_weight " . "FROM {workflow_transitions} t " . "INNER JOIN {workflow_states} s " . "ON s.sid = t.%s " . "WHERE t.%s = %d AND s.status = 1 " . "ORDER BY state_weight) " . "UNION " . "(SELECT s.sid as tid, s.sid as state_id, s.state as state_name, s.weight as state_weight " . "FROM {workflow_states} s " . "WHERE s.sid = %d AND s.status = 1) " . "ORDER BY state_weight, state_id", $field, $field, $field_where, $sid, $sid);
while ($t = db_fetch_object($result)) {
if ($roles == 'ALL' || $sid == $t->state_id || workflow_transition_allowed($t->tid, $roles)) {
$transitions[$t->state_id] = check_plain(t($t->state_name));
}
}
return $transitions;
}
function workflow_types_save($form_values) {
db_query("DELETE FROM {workflow_type_map}");
$node_types = node_get_types();
foreach ($node_types as $type => $name) {
db_query("INSERT INTO {workflow_type_map} (type, wid) VALUES ('%s', %d)", $type, $form_values[$type]['workflow']);
variable_set('workflow_' . $type, array_keys(array_filter($form_values[$type]['placement'])));
}
}
function workflow_get_transition_id($from, $to) {
return db_result(db_query("SELECT tid FROM {workflow_transitions} WHERE sid= %d AND target_sid= %d", $from, $to));
}
function _workflow_node_to_state($node, $sid, $comment = NULL) {
global $user;
$node->workflow_stamp = time();
if (db_result(db_query("SELECT nid FROM {workflow_node} WHERE nid = %d", $node->nid))) {
db_query("UPDATE {workflow_node} SET sid = %d, uid = %d, stamp = %d WHERE nid = %d", $sid, $user->uid, $node->workflow_stamp, $node->nid);
}
else {
db_query("INSERT INTO {workflow_node} (nid, sid, uid, stamp) VALUES (%d, %d, %d, %d)", $node->nid, $sid, $user->uid, $node->workflow_stamp);
}
_workflow_write_history($node, $sid, $comment);
}
function _workflow_write_history($node, $sid, $comment) {
global $user;
db_query("INSERT INTO {workflow_node_history} (nid, old_sid, sid, uid, comment, stamp) VALUES (%d, %d, %d, %d, '%s', %d)", $node->nid, $node->_workflow, $sid, $user->uid, $comment, $node->workflow_stamp);
}
function workflow_get_roles() {
static $roles = NULL;
if (!$roles) {
$result = db_query('SELECT * FROM {role} ORDER BY name');
$roles = array(
'author' => 'author',
);
while ($data = db_fetch_object($result)) {
$roles[$data->rid] = check_plain($data->name);
}
}
return $roles;
}
function workflow_cron() {
$clear_cache = FALSE;
$nodes = db_query('SELECT * FROM {workflow_scheduled_transition} s WHERE s.scheduled > 0 AND s.scheduled < %d', time());
while ($row = db_fetch_object($nodes)) {
$node = node_load($row->nid);
if ($node->_workflow == $row->old_sid) {
workflow_execute_transition($node, $row->sid, $row->comment, TRUE);
watchdog('content', '%type: scheduled transition of %title.', array(
'%type' => t($node->type),
'%title' => $node->title,
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
$clear_cache = TRUE;
}
else {
db_query('DELETE FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);
}
}
if ($clear_cache) {
cache_clear_all();
}
}
function workflow_token_values($type, $object = NULL) {
$values = array();
switch ($type) {
case 'node':
case 'workflow':
$node = (object) $object;
if ($wid = workflow_get_workflow_for_type($node->type)) {
$values['workflow-name'] = workflow_get_name($wid);
$states = workflow_get_states($wid);
}
else {
break;
}
$result = db_query_range("SELECT h.* FROM {workflow_node_history} h WHERE nid = %d ORDER BY stamp DESC", $node->nid, 0, 1);
if ($row = db_fetch_object($result)) {
$account = user_load(array(
'uid' => $row->uid,
));
$comment = $row->comment;
}
if (isset($node->workflow) && !isset($node->workflow_stamp)) {
$sid = $node->workflow;
$old_sid = isset($row->sid) ? $row->sid : _workflow_creation_state($wid);
$date = time();
$user_name = $node->uid ? $node->name : variable_get('anonymous', 'Anonymous');
$uid = $node->uid;
$mail = $node->uid ? $node->user_mail : '';
$comment = isset($node->workflow_comment) ? $node->workflow_comment : '';
}
else {
if (!isset($node->workflow) && empty($row->sid)) {
$choices = workflow_field_choices($node);
$keys = array_keys($choices);
$sid = array_shift($keys);
$old_sid = _workflow_creation_state($wid);
$date = time();
$user_name = $node->uid ? $node->name : variable_get('anonymous', 'Anonymous');
$uid = $node->uid;
$mail = $node->uid ? $node->user_mail : '';
$comment = isset($node->workflow_comment) ? $node->workflow_comment : '';
}
else {
$sid = $row->sid;
$old_sid = $row->old_sid;
$date = $row->stamp;
$user_name = $account->uid ? $account->name : variable_get('anonymous', 'Anonymous');
$uid = $account->uid;
$mail = $account->uid ? $account->mail : '';
}
}
$values['workflow-current-state-name'] = $states[$sid];
$values['workflow-old-state-name'] = $states[$old_sid];
$values['workflow-current-state-date-iso'] = date('Ymdhis', $date);
$values['workflow-current-state-date-tstamp'] = $date;
$values['workflow-current-state-date-formatted'] = format_date($date);
$values['workflow-current-state-date-small'] = format_date($date, 'small');
$values['workflow-current-state-date-medium'] = format_date($date, 'medium');
$values['workflow-current-state-date-large'] = format_date($date, 'large');
$values['workflow-current-state-updating-user-name'] = check_plain($user_name);
$values['workflow-current-state-updating-user-uid'] = $uid;
$values['workflow-current-state-updating-user-mail'] = check_plain($mail);
$values['workflow-current-state-log-entry'] = filter_xss($comment, array(
'a',
'em',
'strong',
));
break;
}
return $values;
}
function workflow_token_list($type = 'all') {
$tokens = array();
if ($type == 'workflow' || $type == 'node' || $type == 'all') {
$tokens['workflow']['workflow-name'] = 'Name of workflow appied to this node';
$tokens['workflow']['workflow-current-state-name'] = 'Current state of content';
$tokens['workflow']['workflow-old-state-name'] = 'Old state of content';
$tokens['workflow']['workflow-current-state-date-iso'] = 'Date of last state change (ISO)';
$tokens['workflow']['workflow-current-state-date-tstamp'] = 'Date of last state change (timestamp)';
$tokens['workflow']['workflow-current-state-date-formatted'] = 'Date of last state change (site default)';
$tokens['workflow']['workflow-current-state-date-small'] = 'Date of last state change (small format)';
$tokens['workflow']['workflow-current-state-date-medium'] = 'Date of last state change (medium format)';
$tokens['workflow']['workflow-current-state-date-large'] = 'Date of last state change (large format)';
$tokens['workflow']['workflow-current-state-updating-user-name'] = 'Username of last state changer';
$tokens['workflow']['workflow-current-state-updating-user-uid'] = 'uid of last state changer';
$tokens['workflow']['workflow-current-state-updating-user-mail'] = 'email of last state changer';
$tokens['workflow']['workflow-current-state-log-entry'] = 'Last workflow comment log';
$tokens['node'] = $tokens['workflow'];
}
return $tokens;
}
function workflow_content_extra_fields($type_name) {
$extra = array();
if (!in_array('node', variable_get('workflow_' . $type_name, array(
'node',
)))) {
return;
}
$extra['workflow'] = array(
'label' => t('Workflow'),
'description' => t('Workflow module form'),
'weight' => 10,
);
return $extra;
}
function workflow_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'delete':
db_query("UPDATE {workflow_node} SET uid = 0 WHERE uid = %d", $account->uid);
db_query("UPDATE {workflow_node_history} SET uid = 0 WHERE uid = %d", $account->uid);
break;
}
}