PHPRunner tiene muchas opciones para control de acceso e incluso, para la selección de la información de una tabla, pero para algunos requisitos de nuestras aplicaciones, no son suficientes.
Como vemos, podemos hacer fácilmente que el usuario sólo pueda acceder a sus datos.
La pregunta y duda, es ¿ cómo hacemos para poder acceder a mis datos y a los datos de las personas que dependen, de forma directa o indirecta, de mí ?
En la vida real se da, bastantes veces, esta circunstancia, por ejemplo:
- Consultar los datos salariales de mis colaboradores dependientes.
- Consultar los fichajes de acceso al trabajo de mis colaboradores dependientes.
- Consultar los pedidos o venta de mis colaboradores dependientes.
La solución de este tipo de preguntas no es tan sencilla, dado que PHPRunner no tiene ningún “wizard” que nos facilite este acceso a los registros de una tabla.
Objetivo
Dada una estructura de jerarquía o dependencia entre personas, la consulta de estas personas estará regida por las siguientes normas:
- Los usuarios del grupo “administrator” podrán consultar todas las personas.
- Los usuarios podrán consultar sus datos y los de las personas que dependan de ellos directa e indirectamente.
- No existe límite en los niveles de dependencia.
Solución
Para la creación de la solución he utilizado la función de PHP de https://gist.github.com/ubermaniac/8834601 que me facilita el análisis de la jerarquía de dependencia.
DEMO: https://fhumanes.com/hierarchy/
Los usuarios que actualmente están disponibles son los que se muestran en la figura.
El Login y Password tienen el mismo dato. Os recuerdo que el login “admin” pertenece al grupo de “administrator” y es el único que podrá crear y eliminar los usuarios.
En el ejemplo se ha resuelto el problema creando una lista de códigos de usuarios “id_user”, que puede consultar el usuario y añadiendo dinámicamente en el Select de la consulta la condición de “id_user IN (1,2,3,….,7)”. Ese conjunto de “id_user” son los usuarios que puede consultar.
Lo más complejo es obtener el conjunto de “id_user” y esto se hace con este código, dejando la lista de “id’s” en una variable de sesión, para su posterior uso.
hierarcy.php
<?php // Create ARRAY with the data Hierarchy function convertToHierarchy($results, $idField='user_id', $parentIdField='Boss', $childrenField='') { $hierarchy = array(); // -- Stores the final data $itemReferences = array(); // -- temporary array, storing references to all items in a single-dimention foreach ( $results as $item ) { $id = $item[$idField]; $parentId = $item[$parentIdField]; if (isset($itemReferences[$parentId])) { // parent exists $itemReferences[$parentId][$childrenField][$id] = $item; // assign item to parent $itemReferences[$id] =& $itemReferences[$parentId][$childrenField][$id]; // reference parent's item in single-dimentional array } elseif (!$parentId || !isset($hierarchy[$parentId])) { // -- parent Id empty or does not exist. Add it to the root $hierarchy[$id] = $item; $itemReferences[$id] =& $hierarchy[$id]; } } unset($results, $item, $id, $parentId); // -- Run through the root one more time. If any child got added before it's parent, fix it. foreach ( $hierarchy as $id => &$item ) { $parentId = $item[$parentIdField]; if ( isset($itemReferences[$parentId] ) ) { // -- parent DOES exist $itemReferences[$parentId][$childrenField][$id] = $item; // -- assign it to the parent's list of children unset($hierarchy[$id]); // -- remove it from the root of the hierarchy } } unset($itemReferences, $id, $item, $parentId); return $hierarchy; } // Search the data of the connected user function findUser($hierarchy, $id_user) { foreach ($hierarchy as $v) { if ($v['id_user'] == $id_user){ // Find the id of the connected user return $v; } if (!empty($v['children'])) { // Recursive find $w = findUser($v['children'], $id_user); if (!empty($w)) { // User has already been found return $w; } } } return []; } $_SESSION['user_dependence'] = '0'; // Initialization // Create list of dependent users function listChildrenUser($hierarchy,$list) { foreach ($hierarchy as $v) { $list .= $v['id_user'].','; if (!empty($v['children'])) { // Recursive find $list = listChildrenUser($v['children'], $list); } } return $list; } global $conn; // Create auxiliary Sorting tables $results = array(); $sql = "SELECT id_user , ifnull(Boss,'') id_parent, Name FROM hierarchy_users"; if ($resql = db_query($sql,$conn)) { /* get associative array */ while ($row = db_fetch_array($resql)) { $results[] = $row; } $Hierarchy = convertToHierarchy($results,'id_user','id_parent','children'); // Create hierarchy from data $user = $_SESSION["id_user"] ; // id User connect $Hierarchy2 = array(); $list = ''; $Hierarchy2[] = findUser($Hierarchy, $user); // Create List of dependent User id $list = listChildrenUser($Hierarchy2,$list); $_SESSION['user_dependence'] = substr($list, 0,strlen($list)-1); // remove last comma } ?>
Como siempre, podréis contactar conmigo, para cualquier necesidad en [email protected]
También, como es habitual, os dejo todos los ficheros que necesitáis para que instaléis el ejemplo en vuestros equipos.