Respuestas:
Si desea verificar si el usuario actualmente conectado tiene acceso a una página, puede usar el siguiente código:
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
// The user has access to the page in $path.
}
}
$path
es la ruta de la página que desea verificar (por ejemplo, nodo / 1, administrador / usuario / usuario).
El código funciona en Drupal 6 y versiones superiores, y es el que se usa desde menu_execute_active_handler () .
La razón por la que no sugiero llamar directamente a la devolución de llamada de acceso es porque los argumentos que deben pasarse a esa función.
El código utilizado por _menu_check_access () es el siguiente (Drupal 7):
$arguments = menu_unserialize($item['access_arguments'], $map);
// As call_user_func_array is quite slow and user_access is a very common
// callback, it is worth making a special case for it.
if ($callback == 'user_access') {
$item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
}
elseif (function_exists($callback)) {
$item['access'] = call_user_func_array($callback, $arguments);
}
El código, que debe ser lo más genérico posible, no maneja directamente un objeto de usuario. Esto significa que no es posible reemplazar el objeto de usuario para el usuario actualmente conectado con otro objeto de usuario.
El código debe ser lo suficientemente genérico como para manejar definiciones de menú como las siguientes:
$items['node/add/' . $type_url_str] = array(
'title' => $type->name,
'title callback' => 'check_plain',
'page callback' => 'node_add',
'page arguments' => array($type->type),
'access callback' => 'node_access',
'access arguments' => array('create', $type->type),
'description' => $type->description,
'file' => 'node.pages.inc',
);
$items['node/%node'] = array(
'title callback' => 'node_page_title',
'title arguments' => array(1),
// The page callback also invokes drupal_set_title() in case
// the menu router's title is overridden by a menu link.
'page callback' => 'node_page_view',
'page arguments' => array(1),
'access callback' => 'node_access',
'access arguments' => array('view', 1),
);
En ambas definiciones, los argumentos de acceso no incluyen un objeto de usuario, y node_access () en este caso usa el objeto de usuario para el usuario actualmente conectado. En el segundo caso, uno de los argumentos es el objeto de nodo que se obtiene de la URL; por ejemplo, si la URL es example.com/node/1, entonces el segundo argumento pasado a la devolución de llamada de acceso es el objeto de nodo para el nodo con ID de nodo igual a 1.
Escribir código que maneja estos casos también significaría duplicar código ya existente en Drupal. Incluso si ha duplicado ese código, aún existiría el problema de las devoluciones de llamada de acceso que verifican el acceso con el usuario actualmente conectado.
Si desea verificar si un usuario que no es el usuario actualmente conectado puede acceder a un menú, primero debe cambiar el valor de la variable global $user
, usar el código que informé al comienzo de mi respuesta y luego restaurar el valor de $user
. Para $user
saber cómo cambiar el valor de global , puede ver que se hace pasar por otro usuario de manera programática sin que el usuario actualmente conectado cierre sesión . La diferencia es que, en lugar de usar el valor devuelto por drupal_anonymous_user () , usa el valor devuelto por user_load () .
Prueba drupal_valid_path () .
La función devuelve TRUE
es la ruta pasada como argumento existe y el usuario actual tiene acceso a ella. Entonces, si está trabajando en Drupal 7 y necesita verificar el acceso del usuario actualmente conectado, es la forma más fácil de hacerlo:
if (drupal_valid_path('my/path')) {
// Your code here...
}
drupal_valid_path
hace el trabajo perfectamente y está hecho para satisfacer esta necesidad exacta. Utiliza menu_get_item y comprueba el acceso también.
drupal_valid_path
no lo ayudará.
\Drupal::service('path.validator')->isValid($path);
- vea la documentación de
Llame al access callback
que se especifica en la entrada del menú responsable de la página. Esa entrada de menú generalmente es creada por Drupal llamando a la implementación de hook_menu
y se almacena en algún lugar de la base de datos. Tenga en cuenta que los datos devueltos hook_menu
pueden ser modificados por la implementación de un módulo hook_menu_alter
.
Tenga en cuenta que algunos módulos pueden no pasar al usuario como un argumento separado (como se especifica en la access arguments
tecla de la entrada del menú), sino que pueden usar el $user
objeto global . Deberá verificar esto para cada módulo que utilice.
Echa un vistazo a la user_access()
función. Vea el enlace para los parámetros especificados para cada versión de Drupal. Desde la página de documentación de Drupal 7-8:
Parámetros
$ string El permiso, como "administrar nodos", que se está buscando.
$ cuenta (opcional) La cuenta a verificar, si no se le da uso al usuario actualmente conectado.
Valor de retorno
Boolean TRUE si el usuario actual tiene el permiso solicitado.
Todas las verificaciones de permisos en Drupal deben pasar por esta función. De esta manera, garantizamos un comportamiento constante y nos aseguramos de que el superusuario pueda realizar todas las acciones.
user_access()
no siempre es la devolución de llamada de acceso utilizada por un menú; incluso lo sería, debe conocer los argumentos de acceso a los que debe pasar user_access()
.
user_access()
, solo pensé que el OP tenía un permiso en mente para verificar si el usuario debería tener acceso. No es una pregunta muy descriptiva
Si necesita saber si un usuario puede acceder a un nodo en particular y está utilizando un módulo de acceso de nodo, puede usar node_access () . (sin un módulo de acceso de nodo solo necesitan el permiso de 'contenido de acceso').
Si desea averiguar si un usuario puede acceder a una ruta arbitraria definida por una implementación hook_menu (), puede que tenga que recuperar la entrada del menú de la base de datos y evaluar su parámetro de 'devolución de llamada de acceso'.
$node = node_load(123);
$account = user_load(456);
if (node_access("update", $node, $account) === TRUE)
{
print "access";
}