Early revision of a Drupal module implementing complex node workflows.
<?php
//Specify blocks generated by this module
function grad_docs_block_info() {
$blocks['student_documents_block'] = array(
'info' => t('Student Documents Block'),
'cache' => DRUPAL_NO_CACHE,
);
$blocks['faculty_assigned_documents_block'] = array(
'info' => t('Faculty Assigned Documents Block'),
'cache' => DRUPAL_NO_CACHE,
);
$blocks['assigned_tasks_block'] = array(
'info' => t('Assigned Tasks Block'),
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
//Functions for generating the "My Documents" block
function grad_docs_block_view($delta = '') {
global $user;
$block = array();
switch ($delta) {
case 'student_documents_block':
$block['subject'] = t('My Documents');
$block['content'] = student_documents_block_content($user->uid, FALSE);
break;
case 'faculty_assigned_documents_block':
$block['subject'] = t('Assigned Documents');
$block['content'] = faculty_assigned_documents_block_content($user->uid);
break;
case 'assigned_tasks_block':
$block['subject'] = t('Assigned Tasks');
$block['content'] = assigned_tasks_block_content($user->uid);
}
return $block;
}
function grad_docs_menu() {
$items['grad_docs/relationship_table'] = array(
'title' => 'Administer Relationship Table',
'page callback' => 'drupal_get_form',
'page arguments' => array('grad_docs_admin_relationship_table_form'),
'type' => MENU_NORMAL_ITEM,
'access arguments' => array('Administer Workflow Relationship Table')
);
$items['grad_docs/change_enrolment_form'] = array(
'access arguments' => array('access content'),
'page callback' => 'grad_docs_change_enrolment_form',
//'page callback' => 'drupal_get_form',
//'page arguments' => array('grad_docs_change_enrolment_form'),
'title' => 'Change Enrolment Form',
'type' => MENU_CALLBACK,
);
return $items;
}
function grad_docs_change_enrolment_form() {
//Get uid of current user
global $user;
//Query for most recent 'course_advising_form's of current user
$advising_form_nid = db_select('node', 'node')
->fields('node', array('nid'))
->condition('status', 1)
->condition('type', 'course_advising_form')
->condition('uid', $user->uid)
->orderBy('created', 'DESC')
->execute()->fetchField();
$node = node_load($advising_form_nid);
$node->status = 0;
return docs_clone_form_prepopulate($node, 'Change Enrolment Form', 'enrolment_change_form');
}
function grad_docs_admin_paths() {
if (variable_get('node_admin_theme')) {
$paths = array(
'grad_docs/change_enrolment_form' => TRUE,
);
return $paths;
}
}
function docs_clone_form_prepopulate($original_node, $new_title = NULL, $new_type = NULL) {
if (isset($original_node->nid)) {
global $user;
$node = clone $original_node;
if (isset($new_title)) {
$node->title = $new_title;
}
if (isset($new_type)) {
$node->type = $new_type;
}
$node->nid = NULL;
$node->vid = NULL;
$node->tnid = NULL;
// Anyonmymous users don't have a name.
$node->name = isset($user->name) ? $user->name : NULL;
$node->uid = $user->uid;
$node->created = NULL;
if (isset($node->book['mlid'])) {
$node->book['mlid'] = NULL;
$node->book['has_children'] = 0;
}
$node->path = NULL;
$node->files = array();
$node->title = t('Clone of !title', array('!title' => $node->title));
drupal_set_title($node->title);
if (variable_get('clone_reset_' . $node->type, FALSE)) {
$node_options = variable_get('node_options_' . $node->type, array('status', 'promote'));
// Fill in the default values.
foreach (array('status', 'moderate', 'promote', 'sticky', 'revision') as $key) {
// Cast to int since that's how they come out of the DB.
$node->$key = (int) in_array($key, $node_options);
}
}
// Let other modules do special fixing up.
//$context = array('method' => 'prepopulate', 'original_node' => $original_node);
// Make sure the file defining the node form is loaded.
$form_state = array();
$form_state['build_info']['args'] = array($node);
form_load_include($form_state, 'inc', 'node', 'node.pages');
return drupal_build_form($node->type . '_node_form', $form_state);
}
}
function grad_docs_admin_relationship_table_form($form, &$form_state) {
$module_path = drupal_get_path('module', 'grad_docs');
drupal_add_css($module_path . '/css/grad_docs.css');
$form = array();
$form['#prefix'] = '<div id="Relationship_Table_Container">';
$form['#suffix'] = '</div>';
$form['#tree'] = TRUE;
//Get all the user IDs belonging to the Staff/Faculty role
$faculty_role = user_role_load_by_name('Faculty');
$staff_role = user_role_load_by_name('Staff');
$faculty_staff_condition = db_or();
$faculty_staff_condition->condition('rid', $faculty_role->rid);
$faculty_staff_condition->condition('rid', $staff_role->rid);
$result = db_select('users_roles', 'ur')
->fields('ur', array('uid'))
->condition($faculty_staff_condition)
->execute();
foreach ($result as $record) {
$faculty_staff_user_ids[] = $record->uid;
}
//Load all the users in the Staff/Faculty role
$users_array = user_load_multiple($faculty_staff_user_ids);
$users_staff_faculty = array();
foreach ($users_array as $user) {
$user_id = $user->uid;
$first_name = $user->field_profile_firstname;
$last_name = $user->field_profile_lastname;
$users_staff_faculty[$user_id] = t($last_name['und'][0]['value'] . ', ' . $first_name['und'][0]['value'] . ' (' . $user->name . ')');
}
//Get all the user IDs belonging to the Student role
$student_role = user_role_load_by_name('Student');
$result = db_select('users_roles', 'ur')
->fields('ur', array('uid'))
->condition('rid', $student_role->rid)
->execute();
foreach ($result as $record) {
$student_user_ids[] = $record->uid;
}
$users_array = user_load_multiple($student_user_ids);
$users_students = array();
foreach ($users_array as $user) {
$user_id = $user->uid;
$first_name = $user->field_profile_firstname;
$last_name = $user->field_profile_lastname;
$users_students[$user_id] = t($last_name['und'][0]['value'] . ', ' . $first_name['und'][0]['value'] . ' (' . $user->name . ')');
}
//Lets add the "All Students" option, with uid 0
$users_students[0] = t('All Students');
//These are the relationships that may be specified
$relationships = array('Advisor' => 'Advisor', '2nd Reader' => '2nd Reader', 'OSAS Rep' => 'OSAS Rep', 'GPD Rep' => 'GPD Rep', 'MES Rep' => 'MES Rep');
//First query from the user relationship table
$database_relationship_query = db_select('grad_docs_user_relationships', 'rel_table')
->fields('rel_table', array('rel_type', 'faculty_uid', 'student_uid'));
//Join in the User entries for the Student
$database_relationship_query->innerJoin('users', 'u_s', 'u_s.uid = rel_table.student_uid');
//Join in the first and last names of the faculty member
$database_relationship_query->innerJoin('users', 'u_f', 'u_f.uid = rel_table.faculty_uid');
//1st Order the entries by the student last name, first name
//2nd Order the entries by the faculty last name, first name
//3rd Order the entries by the relationship type
$database_relationship_rows = $database_relationship_query
->orderBy('u_s.uid')
->orderBy('rel_table.rel_type', 'ASC')
->execute();
$existing_relationships = array();
foreach ($database_relationship_rows as $database_rel_row) {
$existing_relationships[] = array('rel_type' => $database_rel_row->rel_type,
'faculty_uid' => $database_rel_row->faculty_uid,
'student_uid' => $database_rel_row->student_uid);
}
//If the form is being build for the first time, add a row
if (!isset($form_state['row_count'])) {
$form_state['row_count'] = count($existing_relationships);
}
$form['relationship_container'] = array(
'#prefix' => '<div id="Relationship_Container">',
'#suffix' => '</div>'
);
//If a row count is specified, add rows of fields
if (isset($form_state['row_count'])) {
$row_count = 0;
for ($r_i = 0; $r_i < $form_state['row_count']; $r_i++) {
//Lets add another row
$row_odd_even = 'relationship_row_odd';
if ($row_count % 2 == 0)
$row_odd_even = 'relationship_row_even';
if (!isset($form_state['remove_row']) || !in_array($r_i, $form_state['remove_row'])) {
$row_count++;
$form['relationship_container']['relationship_row_' . $r_i] = array(
'#prefix' => '<div class="relationship_row ' . $row_odd_even . ' relationship_row_' . $r_i . '" >',
'#suffix' => '</div>'
);
$form['relationship_container']['relationship_row_' . $r_i]['count'] = array(
'#markup' => '<span class="relationship_row_count">' . ($row_count) . '</span>'
);
$form['relationship_container']['relationship_row_' . $r_i]['role'] = array(
'#type' => 'select',
'#attributes' => array('class' => array('relationship_role')),
'#options' => $relationships,
);
$form['relationship_container']['relationship_row_' . $r_i]['role']['#default_value']
= (isset($existing_relationships[$r_i]) ? $existing_relationships[$r_i]['rel_type'] : 'Advisor');
//This part of the form is the Student selection box
$form['relationship_container']['relationship_row_' . $r_i]['student_member'] = array(
'#type' => 'select',
'#attributes' => array('class' => array('relationship_student')),
'#options' => $users_students
);
$form['relationship_container']['relationship_row_' . $r_i]['student_member']['#default_value']
= (isset($existing_relationships[$r_i]) ? $existing_relationships[$r_i]['student_uid'] : array());
//This part of the form is the Faculty selection box
$form['relationship_container']['relationship_row_' . $r_i]['staff_faculty_member'] = array(
'#type' => 'select',
'#attributes' => array('class' => array('relationship_faculty')),
'#options' => $users_staff_faculty,
);
$form['relationship_container']['relationship_row_' . $r_i]['staff_faculty_member']['#default_value']
= (isset($existing_relationships[$r_i]) ? $existing_relationships[$r_i]['faculty_uid'] : array());
//This is the Remove button for each row
$form['relationship_container']['relationship_row_' . $r_i]['remove_button'] = array(
'#type' => 'submit',
'#limit_validation_errors' => array(array('choice')),
'#submit' => array('remove_relationship_button_submit'),
'#default_value' => t('X'),
'#name' => 'remove_button_' . $r_i,
'#ajax' => array(
'callback' => 'remove_relationship_button_callback',
'wrapper' => 'Relationship_Container',
'method' => 'replace',
'effect' => 'fade')
);
}
}
}
$form['add_another_relationship'] = array(
'#type' => 'submit',
/* '#executes_submit_callback' => FALSE, */
'#limit_validation_errors' => array(array('choice')),
'#submit' => array('add_another_relationship_button_submit'),
'#default_value' => t('Add Another Row'),
'#ajax' => array(
'callback' => 'add_another_relationship_button_callback',
'wrapper' => 'Relationship_Container',
'method' => 'replace',
'effect' => 'fade')
);
$form['submit'] = array(
'#type' => 'submit',
'#default_value' => t('Save Relationship table')
);
return $form;
}
//Functions for adding another row to the relationships
function add_another_relationship_button_submit($form, &$form_state) {
$form_state['row_count'] = $form_state['row_count'] + 1;
$form_state['rebuild'] = TRUE;
}
function add_another_relationship_button_callback($form, &$form_state) {
return $form['relationship_container'];
}
//Functions for removing a row from the table
function remove_relationship_button_submit($form, &$form_state) {
$row_name = $form_state['triggering_element']['#array_parents'][1];
$form_state['remove_row'][] = str_replace('relationship_row_', '', $row_name);
$form_state['rebuild'] = TRUE;
}
function remove_relationship_button_callback($form, &$form_state) {
return $form['relationship_container'];
}
//Function for saving the relationship table to the database
function grad_docs_admin_relationship_table_form_submit($form, &$form_state) {
$relationship_rows = $form_state['values']['relationship_container'];
$values = array();
foreach ($relationship_rows as $relationship_row) {
$values[] = array('rel_type' => $relationship_row['role'],
'student_uid' => $relationship_row['student_member'],
'faculty_uid' => $relationship_row['staff_faculty_member']);
}
//Delete all existing relationships
db_delete('grad_docs_user_relationships')->execute();
//Resave the whole relationship table
$insert_query = db_insert('grad_docs_user_relationships')->fields(array('rel_type', 'student_uid', 'faculty_uid'));
foreach ($values as $value) {
$insert_query->values($value);
}
$insert_query->execute();
drupal_set_message(t('Relationship Table has been saved.'));
}
function student_documents_block_content($user_id, $colorbox_display = FALSE) {
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
$items = array();
$block_content = null;
for ($form_types_index = 0; $form_types_index < count($form_types_array_keys); $form_types_index++) {
$form_type = $form_types_array_keys[$form_types_index];
$form_type_name = $form_types_array[$form_type]['name'];
$query = new EntityFieldQuery;
$nodes_of_type = $query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', $form_type)
->propertyCondition('uid', $user_id)
->execute();
if (isset($nodes_of_type['node'])) {
$nodes_of_type = $nodes_of_type['node'];
$block_content .= '<h3>' . $form_type_name . 's</h3>';
foreach ($nodes_of_type as $node) {
$full_node = node_load($node->nid);
//Check if forms should be displayed in a colorbox overlay
if ($colorbox_display === TRUE)
$block_content .= l($full_node->title, 'node/' . $full_node->nid, array('attributes' => array('class' => 'colorbox-node'), 'query' => array('width' => 640, 'height' => 480)));
else
$block_content .= l($full_node->title, 'node/' . $full_node->nid);
$block_content .= '<br /> ';
}
}
}
return $block_content;
}
function faculty_assigned_documents_block_content($user_id) {
global $user;
if (!in_array('Staff', $user->roles) && !in_array('Faculty', $user->roles))
return null;
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
$items = array();
$block_content = null;
for ($form_types_index = 0; $form_types_index < count($form_types_array_keys); $form_types_index++) {
$form_type = $form_types_array_keys[$form_types_index];
$form_type_name = $form_types_array[$form_type]['name'];
$query = new EntityFieldQuery;
$nodes_of_type = $query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', $form_type)
->execute();
if (isset($nodes_of_type['node'])) {
$nodes_of_type = $nodes_of_type['node'];
foreach ($nodes_of_type as $node) {
$document_state = get_document_state($node->nid);
$active_workflow = get_active_workflow($form_type);
if (isset($active_workflow) && $active_workflow != FALSE) {
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
$full_node = node_load($node->nid);
$node_author = $full_node->uid;
//Get uid of assignee of node being checked
$assignee_uid = get_assignee_uid($full_node);
//If current user is assignee of node being check, add to list
if ($user->uid == $assignee_uid) {
$block_content .= '<h3>' . $form_type_name . 's</h3>';
$block_content .= l($full_node->title, 'node/' . $full_node->nid) . '<br /> ';
}
}
}
}
}
if ($block_content == null) {
$block_content = t('No assigned documents');
}
return $block_content;
}
//Alter form pages to display Workflow details and controls
function grad_docs_page_alter(&$page) {
global $user;
$node = menu_get_object();
if (!isset($node->nid) || !isset($node->entity_view_prepared)) {
return;
}
//Get Form types
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
//Check if node is a grad form, return here if it isn't
if (!in_array($node->type, $form_types_array_keys)) {
return;
}
//Get the workflow for this type of form
$active_workflow = get_active_workflow($node->type);
//If this content type has a workflow assigned to it then get the current state of this form from the DB
if (isset($active_workflow) && $active_workflow != FALSE) {
$document_state = get_document_state($node->nid);
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
//Lets make a container for the workflow stuff
$page['content']['system_main']['nodes'][$node->nid]['workflow_details_controls'] = array(
'#weight' => -1,
'#prefix' => '<div id="workflow_details_controls">',
'#suffix' => '</div>'
);
//Output the current assignee
$page['content']['system_main']['nodes'][$node->nid]['workflow_details_controls']['workflow_assignee'] = array(
'#weight' => 0,
'#markup' => t('<div id="workflow_current_assignee"><strong>Currently with:</strong> <span>' . $assignee_role . '</span></div>')
);
//Get the approval target state, and the rejection target state
$approval_state_target = db_select('field_data_field_approval_state', 'ap_s')
->fields('ap_s', array('field_approval_state_value'))
->condition('entity_id', $workflow_state_id)
->execute()->fetchField();
$rejection_state_target = db_select('field_data_field_rejection_state', 'rj_s')
->fields('rj_s', array('field_rejection_state_value'))
->condition('entity_id', $workflow_state_id)
->execute()->fetchField();
//Get the current User's roles, incase we deal with admin
$user_roles = $user->roles;
//Add buttons depending on current user and assignee
switch ($assignee_role) {
case 'Student':
//Check that current user is indeed the author of the form
if ($user->uid == $node->uid || in_array('administrator', $user_roles)) {
if (!empty($approval_state_target)) {
$buttons = array('submit' => array('name' => 'submit_button', 'value' => 'Submit', 'workflow_target' => $approval_state_target, 'form_nid' => $node->nid));
}
$page['content']['system_main']['nodes'][$node->nid]['workflow_details_controls']['workflow_buttons'] = drupal_get_form('grad_docs_workflow_form', $buttons);
}
break;
case 'Published':
break;
default:
//Get the uid of the assignee
$assignee_uid = get_assignee_uid($node);
//Check that the current user is the assignee, and load the buttons
if ($assignee_uid == $user->uid || in_array('administrator', $user_roles)) {
if (!empty($approval_state_target)) {
$buttons['approve'] = array('name' => 'approve_button', 'value' => 'Approve', 'workflow_target' => $approval_state_target, 'form_nid' => $node->nid);
}
if (!empty($rejection_state_target)) {
$buttons['reject'] = array('name' => 'reject_button', 'value' => 'Reject', 'workflow_target' => $rejection_state_target, 'form_nid' => $node->nid);
}
$page['content']['system_main']['nodes'][$node->nid]['workflow_details_controls']['workflow_buttons'] = drupal_get_form('grad_docs_workflow_form', $buttons);
}
break;
}
}
}
//Helper functions for dealing with Workflows
function get_active_workflow($type_of_form) {
//Get all the workflows
$workflow_query = new EntityFieldQuery();
$workflow_query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'workflow');
$workflow_collection = $workflow_query->execute();
if (empty($workflow_collection))
return;
//For each workflow, check if the name of this form is specified
foreach ($workflow_collection['node'] as $workflow) {
$full_workflow = node_load($workflow->nid);
$form_types_field = $full_workflow->field_form_types;
foreach ($form_types_field['und'] as $form_type) {
if ($form_type['value'] == $type_of_form) {
$active_workflow = $full_workflow;
}
}
}
if (isset($active_workflow))
return $active_workflow;
else
return FALSE;
}
function get_document_state($nid) {
$document_state = db_select('grad_docs_document_states', 'ds')
->fields('ds', array('document_state'))
->condition('document_nid', $nid)
->execute()
->fetchField();
return $document_state;
}
function get_workflow_assignee($workflow_state_entity_id) {
$assignee_role = db_select('field_data_field_assignee', 'ass')
->fields('ass', array('field_assignee_value'))
->condition('entity_id', $workflow_state_entity_id)
->execute()
->fetchField();
return $assignee_role;
}
function get_assignee_uid($node) {
//Get the workflow for this type of form
$active_workflow = get_active_workflow($node->type);
//Get the state of the current document
$document_state = get_document_state($node->nid);
if (!isset($active_workflow) || $active_workflow === FALSE)
return FALSE;
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
//Get the uid of the assignee
switch ($assignee_role) {
case 'Student':
$assignee_uid = $node->uid;
break;
case 'Published':
$assignee_uid = FALSE;
break;
default:
$assignee_uid = db_select('grad_docs_user_relationships', 'u_rel')
->fields('u_rel', array('faculty_uid'))
->condition('student_uid', $node->uid)
->condition('rel_type', $assignee_role)
->execute()->fetchField();
//If no assignee was found, check if there is an assignee for all
if ($assignee_uid === FALSE) {
$assignee_uid = db_select('grad_docs_user_relationships', 'u_rel')
->fields('u_rel', array('faculty_uid'))
->condition('student_uid', 0)
->condition('rel_type', $assignee_role)
->execute()->fetchField();
}
break;
}
return $assignee_uid;
}
//A form showing the actual workflow buttons
function grad_docs_workflow_form($form, &$form_state, $buttons = array()) {
$form = array();
$form['#weight'] = 1;
//Now add all the buttons
foreach ($buttons as $button) {
$form_state[$button['name'] . '_target'] = $button['workflow_target'];
$form_state['current_nid'] = $button['form_nid'];
$form[$button['name']] = array(
'#type' => 'submit',
'#value' => $button['value'],
'#limit_validation_errors' => array(array('choice')),
'#submit' => array('doc_workflow_next_state_submit'),
'#name' => $button['name']
);
}
return $form;
}
function doc_workflow_next_state_submit($form, &$form_state) {
global $user;
$button_name = $form_state['triggering_element']['#array_parents'][0];
$button_target = $form_state[$button_name . '_target'];
$current_state = get_document_state($form_state['current_nid']);
//Update the state of the document in the state table to the target state
db_update('grad_docs_document_states')
->condition('document_nid', $form_state['current_nid'])
->fields(array('document_state' => $button_target))
->execute();
$node = menu_get_object();
//Get the workflow for this type of form
$active_workflow = get_active_workflow($node->type);
//Get the state of the current document
$document_state = get_document_state($node->nid);
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
//If the document reached a final state, change publishing option
if ($assignee_role == 'Published') {
$node->status = 1;
node_save($node);
}
//Lets also send an email notification
$assignee_uid = get_assignee_uid($node);
if ($assignee_uid) {
$assignee_user = user_load($assignee_uid);
}
//Lets record this action in the document history table
$button = explode('_', $button_name);
document_history_entry($form_state['current_nid'], $user->uid, $assignee_uid, $current_state, $button_target, time(), $button[0]);
//Reload the page
$request_uri = explode('/grad_docs/', request_uri());
drupal_goto($request_uri[1]);
}
function grad_docs_mail($key, &$message, $params) {
switch ($key) {
case 'document_assigned':
$account = $params['account'];
$subject = $params['subject'];
$body = $params['body'];
$message['to'] = $account->mail;
$message['subject'] = $subject;
$message['body'][] = $body;
break;
}
}
function document_history_entry($document_nid, $previous_user_uid, $current_user_uid, $previous_state, $current_state, $history_timestamp, $workflow_action) {
db_insert('grad_docs_document_history')
->fields(array('document_nid' => $document_nid,
'previous_user_uid' => $previous_user_uid,
'current_user_uid' => $current_user_uid ? $current_user_uid : 0,
'previous_state' => $previous_state,
'current_state' => $current_state,
'history_timestamp' => $history_timestamp,
'workflow_action' => $workflow_action))
->execute();
}
function doc_workflow_button_callback($form, &$form_state) {
$current_node = $form_state['current_nid'];
$node = node_load($current_node);
//Get the workflow for this type of form
$active_workflow = get_active_workflow($node->type);
//Get the state of the current document
$document_state = get_document_state($node->nid);
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
//Generate the elements that will replace the workflow details
$assignee_details = array('workflow_assignee' => array(
'#weight' => 0,
'#markup' => t('<div id="workflow_current_assignee"><strong>Currently with:</strong> <span>' . $assignee_role . '</span></div>')
),
'page_details' => array(
'#markup' => print_r($page, TRUE)
)
);
return $assignee_details;
}
function grad_docs_node_access($node, $op, $account) {
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
if (isset($node->type) && in_array($node->type, $form_types_array_keys)) {
//Get the workflow for this type of form
$active_workflow = get_active_workflow($node->type);
//Get the state of the current document
$document_state = get_document_state($node->nid);
if (!isset($active_workflow) || $active_workflow === FALSE)
return NODE_ACCESS_IGNORE;
//Get the current Assignee for this workflow based on the state
$workflow_state_id = $active_workflow->field_workflow_stage;
$workflow_state_id = $workflow_state_id['und'][$document_state - 1]['value'];
$assignee_role = get_workflow_assignee($workflow_state_id);
$assignee_uid = get_assignee_uid($node);
switch ($op) {
case 'create':
//No concern with creating form entries
return NODE_ACCESS_IGNORE;
break;
case 'view':
//Always allow node author to view form
if ($node->uid == $account->uid)
return NODE_ACCESS_ALLOW;
//Check if current user is current assignee
if (isset($assignee_uid) && $account->uid == $assignee_uid)
return NODE_ACCESS_ALLOW;
//Check if current user is related to form author, or all students
$relationship_uids = db_select('grad_docs_user_relationships', 'u_rel')
->fields('u_rel', array('faculty_uid'))
->condition('student_uid', $node->uid)
->execute();
foreach ($relationship_uids as $rel) {
if ($rel->faculty_uid == $account->uid)
return NODE_ACCESS_ALLOW;
}
//ATTENTION Combine this and the previous into one query
$global_relationships = db_select('grad_docs_user_relationships', 'u_rel')
->fields('u_rel', array('faculty_uid'))
->condition('student_uid', '0')
->execute();
foreach ($global_relationships as $glob_rel) {
if ($glob_rel->faculty_uid == $account->uid)
return NODE_ACCESS_ALLOW;
}
//Published nodes are always viewable
if ($assignee_role == 'Published')
return NODE_ACCESS_ALLOW;
//Anyone else, denied
return NODE_ACCESS_DENY;
break;
case 'update':
//Nodes assigned to Student are editable by the student
if ($assignee_role == 'Student' && $account->uid == $node->uid)
return NODE_ACCESS_ALLOW;
//Check if current user is current assignee
if (isset($assignee_uid) && $account->uid == $assignee_uid)
return NODE_ACCESS_ALLOW;
//Anyone else, denied
return NODE_ACCESS_DENY;
break;
case 'delete':
return NODE_ACCESS_DENY;
break;
}
//drupal_set_message(print_r($node, TRUE), TRUE);
return NODE_ACCESS_DENY;
}
else {
return NODE_ACCESS_IGNORE;
}
}
//Functions that update the states table when form nodes are added or removed
function grad_docs_node_insert($node) {
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
//Check if node is a grad form, create state entry if it is
if (in_array($node->type, $form_types_array_keys)) {
db_insert('grad_docs_document_states')
->fields(array(
'document_nid' => $node->nid,
'document_state' => '1'))
->execute();
}
}
function grad_docs_node_delete($node) {
$form_types_array = new ContentTypeGroup('grad_doc_forms');
$form_types_array = $form_types_array->content_types;
$form_types_array_keys = array_keys($form_types_array);
//Remove all state entries for this node
db_delete('grad_docs_document_states')
->condition('document_nid', $node->nid)
->execute();
//Remove all history entries for this node
db_delete('grad_docs_document_history')
->condition('document_nid', $node->nid)
->execute();
}
function grad_docs_permission() {
$permissions = array('Administer Workflow Relationship Table' => array(
'title' => t('Administer Workflow Relationship Table'),
)
);
return $permissions;
}