I'm completely new to Drupal and trying to learn it, but it's pretty hard.

The Node Access module is great and I want to make functionalty for it for bulk grant for several users. The idea is to have a form grid with several users in columns and nodes and grants in rows. It will look like that: form

What I've come to so far:

function table_test_form($form, &$form_state, $node) {
  $form_values = &$form_state['values'];
  if (!$form_values) {
    $form_values = array();
// Get node titles for the first column
        $results = db_query("SELECT DISTINCT title, node.nid
      FROM node_access
      LEFT JOIN node ON node_access.nid = node.nid
      WHERE node.nid < :nid 
      ORDER BY node.nid", array(
        ':nid' => 5,
    foreach ($results as $noderow) {
      // make an array for every row
      $form_values['noderowid'][$noderow->nid] = array(
        'name' => $noderow->title,
      $current_nid = $noderow->nid;
      //Get users and grants for the current node
      $results_grants = db_query("SELECT uid, name, grant_view
      FROM node_access
      LEFT JOIN users ON uid = gid
      WHERE nid = :nid AND uid < :uid
      ORDER BY uid ", array(
        ':nid' => $current_nid,
        ':uid' => 5,

//      Tried this but didn't work
//      if ($results_grants) {
//        while ($row = $results_grants->fetchAssoc()) {
//          $items_grants[] = array(
//                                    $row['name'] => $row['grant_view']
//          );
//         }
//      }
      $items_grants = $results_grants->fetchAllKeyed(1,2); 
//    add the grants for every user to the node row
      $form_values['noderowid'][$noderow->nid][] = $items_grants;

  if (!isset($form_values['noderowid'])) {
    $form_values['noderowid'] = array();

  $noderows = $form_values['noderowid'];

  $form['nid'] = array(
    '#type' => 'hidden',
    '#value' => $node->nid,

  //  the table.
  if (is_array($noderows)) {
    $form['noderowid'] = array('#tree' => TRUE);

    foreach ($noderows as $key => $field) {
        $form['noderowid'][$key] = array();
    $form['noderowid'][$key]['name'] = array(
        '#type' => 'hidden',
        '#value' => $field['name'],
    $arr = $form['noderowid'][$key];
      //add checkboxes
            foreach ($arr as $nodetitle => $f){
                    $form['noderowid'][$key][$nodetitle] = array(
                      '#type' => 'checkbox',
                      '#default_value' => $f[$nodetitle],

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save Grants'),
  return $form;

function theme_table_test_form($variables) {
  $output = '';
  $form = $variables['form'];
  $rows = array();
//get the names of the users and put them in the header
  $uid = 5;
  $sql = "SELECT name FROM users WHERE uid < :uid  ORDER BY uid ASC";
  $result = db_query($sql, array(':uid' => $uid));

  if ($result) {
    while ($row = $result->fetchAssoc()) {
      $items[] = array(
      'data' => t($row['name'])
  // make table.
  $noderows = element_children($form['noderowid']);
  if (count($noderows) > 0) {
    $header = $items;
    $rows = array();

    foreach ($noderows as $key) {
      $row = array();

   // first column
      $row[] = $form['noderowid'][$key]['name']['#value'];
   // other columns 
      foreach(array_slice($header, 1) as $usr){
                $form['noderowid'][$key][$usr] = array();
          $row[] = drupal_render($form['noderowid'][$key][$usr]);

      $rows[] = $row;
    $output .= theme('table', array('header' => $header, 'rows' => $rows));

  $output .= drupal_render_children($form);

  return $output;

It renders the users and nodes names, but not the checkboxes.

I guess it's a pretty bad code and there are too many queries to the database, but I want to just make it work for now.

Any suggestions?


1 Answer 1


Assuming this is for D7, this is a typical case to handle using the Rules module, combined with Views Bulk Operations, with zero custom coding. So if you are "completely new to Drupal and trying to learn it" (as in your question), you may want to try to learn to walk before trying to fly. Read on for further details.

Advice: the Node Access module is unsupported (repeat: unsupported). You really should consider using the Content Access module instead.

What you actually need to do is similar to what is shown in the video about Using VBO to load list of objects into Rules, starting from about 5:30, up to 11:30. Here is a summary of what is shown in this video (quote from the linked page):

  • You need a view that lists the entities you want to work on in Rules. Note that you don't need a display of the view – and it might even be better not to have one if you don't want the view to be displayed somewhere.
  • However, you need one bulk operations field. The type of bulk operations field determines what entity type will be sent to Rules. Note that you don't need any actions enabled for the field – it is enough that it is present.
  • You need a rule that, as an action, loads entities from a VBO. (This is available under the "Views bulk operations" group.) All view displays with at least one VBO field will be selectable.
  • The action provides a list of entities, that can be used just like other lists in Rules. Combine with loops, actions and Rules Scheduler to make awesomeness happen.

For your case, for the Rules Action you can use the integration of the Content Access module with the Rules module to create a Rules Action that updates the access of the node, similar to the Rules Action I included in my sample rule included in my answer to the question "How to revoke edit access to the node's author after publishing a node?".

  • thank you for your comprehensive answer. I will try the Content access/rules/VBO solution, although I preferred custom code as it seems to me simpler and more flexible. Still I want to understand what is the problem with the form I posted and why the checkboxes don't appear. I see you really know drupal, do you have an idea what I've done wrong?
    – Toni
    Commented Aug 23, 2016 at 13:38
  • @Toni It looks like you may have created an extra account. If you wish to merge them, use the "Contact Us" link at the bottom of the page.
    – mpdonadio
    Commented Aug 23, 2016 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.