3

I'd like to know if there's any way to programmatically override Drupal's permissions defined in admin/user/permission.

What I've managed so far is to block a user's certain action. However, if a user is not permitted to perform an action (eg. "create custom_type content") and my module's access callback for this action returns TRUE the result is a white page. No PHP error, warning, or log entry. If FALSE is returned, I get an access denied page, as expected.

The method I used to implement custom permission is through hook_menu_alter(). Specifically, something like this (a common one for Drupal 6):

function mymodule_menu_alter(&$items) {
  $old_access_callback = $items['node/%node']['access callback'];
  $old_access_callback_add_customContent = $items['node/add/custom_type']['access callback'];

  $items['node/%node']['access callback'] = '_custom_node_access';
  $items['node/%node']['access arguments'] = array(1, $old_access_callback);

  $items['node/add/customContent']['access callback'] = '_custom_node_access';
  $items['node/add/customContent']['access arguments'] = array(1, $old_access_callback_add_customContent);
}

function _custom_node_access($node, $old_access_callback = "node_access"){
  //check if user has permission to view the node object 
  //or add new content and return TRUE or FALSE
}

Note that with 'node/%node' item, everything works as expected. When _custom_node_access() returns TRUE for a user that have no permissions to perform the certain action (add), I get a WSD. One way I found to avoid this behavior is to return my calculated result && user_access("create custom_type content") so that I can, at least, get an access denied page. Do you have any suggestion for this behavior?

Finally, _custom_node_access() seems to run more than one time every time the '/node/add/customContent' path is visited. Is there any particular reason for this?

It's been only few months since I started using Drupal so it's very likely that I'm missing something about permission...

5
  • With "node/add/customContent," _custom_node_access() should not be even invoked, as it's not defined as access callback, basing on the code you show.
    – avpaderno
    Commented Sep 10, 2011 at 15:58
  • _custom_node_access() should not be executed at all, when node/add/customContent is visited. _group_roles_node_access should be executed instead. Also, beware of the difference between node/add/custom_type and node/add/customContent.
    – Oswald
    Commented Sep 10, 2011 at 16:15
  • I meant to write _custom_node_access, not _group_roles_node_acess.
    – Alex K.
    Commented Sep 11, 2011 at 9:16
  • My real concern is why I get a WSD and not an access denied page when my callback returns true. I want just to override permission, not to set a new permission.
    – Alex K.
    Commented Sep 11, 2011 at 9:22
  • Your question is most confusing. In one sentence you say "... with 'node/%node' item, everything works as expected." and in the next sentence, you say you get a WSD. Which URL do you visit to get a WSD? Did you understand my hint about the difference between node/add/custom_type and node/add/customContent? What have you done about it?
    – Oswald
    Commented Sep 11, 2011 at 18:08

2 Answers 2

3

There is a way to override programmatically drupal's permissions defined in admin/user/permission. Example:

<?php

function set_permission($rid, $permission) {
  $result = db_result(db_query("SELECT perm FROM {permission} WHERE rid = %d", $rid));
  if (is_array($result)) {
    $permissions = array_flip(explode(', ', $result));
  } else {
    $permissions = array();
  }
  $permissions[$permission] = true;
  db_query("DELETE FROM {permission} WHERE rid = %d", $rid);
  db_query(
    "INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')",
    $rid,
    join(', ', array_keys($permissions))
  );
}

function unset_permission($rid, $permission) {
  $result = db_result(db_query("SELECT perm FROM {permission} WHERE rid = %d", $rid));
  if (is_array($result)) {
    $permissions = array_flip(explode(', ', $result));
  } else {
    $permissions = array();
  }
  unset($permissions[$permission]);
  db_query("DELETE FROM {permission} WHERE rid = %d", $rid);
  db_query(
    "INSERT INTO permission (rid, perm) VALUES (%d, '%s')",
    $rid,
    join(', ', array_keys($permissions))
  );
}
1
  • This is a word of warning for people still using D6 in 2018 – like me ;) This functions will truncate the permissions for a role because $result contains a string. So if you want to use this snippet, replace is_array() with !empty().
    – Nebel54
    Commented Aug 17, 2018 at 8:17
0

See the drupal doc how to resolve a white screen of death problem.

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.