📜 ⬆️ ⬇️

Overriding permissions in Drupal 6

I want to share a way to solve a problem for building Drupal Commons. According to the requirements of the TOR, it was necessary to restrict user access to the nodes according to certain rules:


I immediately tried to implement it through hook_node_grants and hook_node_access_records , but I came to the conclusion that the solution is too bulky, buggy and littered.

And he went the other way.

Recall the registry menu. The array with the description of the element contains two parameters: access callback and access arguments . Let's try to redefine them, but save the established access callback , as the last element in the access arguments :
')
 // MYMODULE_menu_alter        function MYMODULE_menu_alter(&$items) { foreach ($items as &$item) { if (!isset($item['access arguments'])) { $item['access arguments'] = array(); } if (isset($item['access callback'])) { //  callback,    . $item['access arguments'][] = $item['access callback']; } else { // callback  ,   , Drupal 6 //  user_access() if (!empty($item['access arguments'])) { $item['access arguments'][] = 'user_access'; } else { //     -  -   $item['access arguments'][] = TRUE; } } //  callback $item['access callback'] = 'MYMODULE_access_callback'; } } 


Thanks Anonym for fixes.

It should be noted that when installing the module, I expose its weight to be very large (that is, my module will be executed last and no one will override the menu). If you have a different situation, it is better to add your parameters to the array, for example:
 $item['default access callback'] = $item['access callback']; 

But in this case, later altera will not be counted. Those. Still, it is better to set the weight of the module large.

Now callback itself:

 function MYMODULE_access_callback() { $args = func_get_args(); //  ,     TRUE, FALSE     //  ,    if (count($args) == 1) { if (is_bool($args[0])) { return $args[0]; } return $args[0](); } // callback -    $callback = $args[count($args) - 1]; $callback_args = array_slice($args, 0, count($args) - 1); //   : if (is_object($args[1]) && isset($args[1]->nid)) { //     //  ,        if (!call_user_func_array($callback, $callback_args)) { return FALSE; } // 3-  - ,    //.. node_access($op, $node, $account = NULL) if (is_object($args[2])) { $account = $args[2]; } else { global $user; $account = $user; } //   : if ($condition && some_rights()) { return TRUE; } else { return FALSE; } } //   if (!function_exists($callback)) { $dump = print_r($callback_args, TRUE); $msg = ' <b>Access callback  !</b><br /> Callback: "%callback"<br /> Callback arguments:<hr> <pre> %args </pre> '; $vars = array( '%callback' => $callback, '%args' => $callback_args ); watchdog('php', $msg, $vars, WATCHDOG_ERROR); return TRUE; } //    return call_user_func_array($callback, $callback_args); } 


For me it worked and seemed comfortable enough, maybe it would be useful to someone else.

Source: https://habr.com/ru/post/144687/


All Articles