array_keys($account->roles), 'workflow_access_owner' => array($account->uid), ); } /** * Implementation of hook_node_access_records(). * * Returns a list of grant records for the passed in node object. */ function workflow_access_node_access_records($node) { if (workflow_access_disabling()) { return; } $grants = array(); $sid = db_result(db_query("SELECT sid FROM {workflow_node} WHERE nid = %d", $node->nid)); // We have state information about this node, so get permissions for this state. if (is_numeric($sid)) { $result = db_query('SELECT * FROM {workflow_access} WHERE sid = %d', $sid); while ($grant = db_fetch_object($result)) { $grants[] = array( 'realm' => ($grant->rid == -1) ? 'workflow_access_owner' : 'workflow_access', 'gid' => ($grant->rid == -1) ? $node->uid : $grant->rid, 'grant_view' => $grant->grant_view, 'grant_update' => $grant->grant_update, 'grant_delete' => $grant->grant_delete ); } } return $grants; } /** * Implementation of hook_form_alter(). * * Add a "three dimensional" (state, role, permission type) configuration * interface to the workflow edit form. */ function workflow_access_form_alter($form_id, &$form) { // We only work with the workflow edit form. if ($form_id != 'workflow_edit_form') { return; } // A list of roles available on the site and our // special -1 role used to represent the node author. $rids = array('-1' => t('author')); $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name"); while ($obj = db_fetch_object($result)) { $rids[$obj->rid] = $obj->name; } $form['workflow_access'] = array('#type' => 'fieldset', '#title' => t('Access control'), '#collapsible' => TRUE, '#tree' => TRUE, ); // Add a table for every workflow state. $states = workflow_get_states($form['wid']['#value']); foreach ($states as $sid => $state) { $view = $update = $delete = array(); $result = db_query("SELECT * from {workflow_access} where sid = %d", $sid); // Allow view grants by default for anonymous and authenticated users, // if no grants were set up earlier. if (db_num_rows($result) == 0) { $view = array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID); } while ($access = db_fetch_object($result)) { if ($access->grant_view) { $view[] = $access->rid; } if ($access->grant_update) { $update[] = $access->rid; } if ($access->grant_delete) { $delete[] = $access->rid; } } $form['workflow_access'][$sid] = array( '#type' => 'fieldset', '#title' => $state, '#collapsible' => TRUE, '#tree' => TRUE, ); $form['workflow_access'][$sid]['view'] = array( '#type' => 'checkboxes', '#options' => $rids, '#default_value' => $view, '#title' => t('Roles who can view posts in this state'), '#prefix' => '
', ); $form['workflow_access'][$sid]['update'] = array( '#type' => 'checkboxes', '#options' => $rids, '#default_value' => $update, '#title' => t('Roles who can edit posts in this state'), '#prefix' => "", ); $form['workflow_access'][$sid]['delete'] = array( '#type' => 'checkboxes', '#options' => $rids, '#default_value' => $delete, '#title' => t('Roles who can delete posts in this state'), '#prefix' => "", '#suffix' => "
", ); } // Place our block comfortably down the page. $form['submit']['#weight'] = 10; $form['#submit'] += array('workflow_access_form_submit' => array()); } /** * Store permission settings for workflow states. */ function workflow_access_form_submit($form_id, $form_values) { foreach ($form_values['workflow_access'] as $sid => $access) { // Ignore irrelevant keys. if (!is_numeric($sid)) { continue; } $grants = array(); db_query("DELETE FROM {workflow_access} WHERE sid = %d", $sid); foreach ($access['view'] as $rid => $checked) { $grants[] = array( 'realm' => ($rid == -1) ? 'workflow_access_owner' : 'workflow_access', 'gid' => ($rid == -1) ? $node->uid : $rid, 'grant_view' => (bool) $checked, 'grant_update' => (bool) $access['update'][$rid], 'grant_delete' => (bool) $access['delete'][$rid], ); db_query("INSERT INTO {workflow_access} (sid, rid, grant_view, grant_update, grant_delete) VALUES (%d, %d, %d, %d, %d)", $sid, $rid, (bool) $checked, (bool) $access['update'][$rid], (bool) $access['delete'][$rid]); } // Update all nodes having some workflow state to reflect new settings. $result = db_query("SELECT n.nid FROM {node} n LEFT JOIN {workflow_node} wn ON wn.nid = n.nid WHERE wn.sid = %d", $sid); while ($node = db_fetch_object($result)) { // TODO: this only works with workflow_access realm, not the workflow_access_owner realm?! node_access_write_grants(node_load($node->nid), $grants, 'workflow_access'); } } drupal_set_message(t('Workflow access permissions updated.')); } /** * Implementation of hook_workflow(). * * Update grants when a node changes workflow state. */ function workflow_access_workflow($op, $old_sid, $sid, $node) { if ($op == 'transition post' && $old_sid != $sid) { node_access_acquire_grants($node); } }