-2

Table structure


<?php
//the grupo_usuarios table contains the database user groups

CREATE TABLE `grupo_usuarios` (
  `id` int(11) NOT NULL AUTOINCREMENT,
  `nombre` varchar(20) COLLATE utf8_spanish_ci NOT NULL,
  `descripcion` varchar(150) COLLATE utf8_spanish_ci NOT NULL
);

//the permisos table contains the permissions 

CREATE TABLE `permisos` (
  `id` int(11) PRIMARY KEY NOT NULL AUTOINCREMENT,
  `nombre` varchar(20) COLLATE utf8_spanish_ci NOT NULL
);

// the table tiene_asignado is the result of the many-to-many relationship between the grupo_usuarios table and permisos

CREATE TABLE `tiene_asignado` (
  `id` int(11) PRIMARY KEY NOT NULL AUTOINCREMENT,
  `id_grupo` int(11) NOT NULL,
  `id_permisos` int(11) NOT NULL,
FOREIGN KEY(id_grupo) REFERENCES grupo_usuarios(id),
FOREIGN KEY(id_permisos) REFERENCES permisos(id),
ON DELETE CASCADE ON UPDATE CASCADE
);

?>

<?php include('php/verificarSesion.php');?>
<?php    

//Storing the id of the user group received through GET from the groups.php page

if(isset($_GET['id_grupo_usuarios']) && (!empty($_GET['id_grupo_usuarios']))  && is_numeric($_GET['id_grupo_usuarios']) == 1){

   $id_grupo_usuarios = $_GET['id_grupo_usuarios'];

}else{
   
    echo "<script>
        window.location.href='verGrupo.php';
    </script>";}

?>


<?php include("plantillas/header.php"); ?>

<!-- PAGE CONTENT (permisosChex.php)-->
<section class="listadoPacientes">
<div class="container mt-3">
      <div class="row">
         <div class="col-6 col-md-5">
            <h2>Assign permissions to the group <?php echo $id_grupo_usuarios;?></h2>
            <p>Here you can check the permissions belonging to this group</p>
         </div>
  
         <div class="col-4" id="tabla">  
            <table id="tablaPacientes" class="table table-bordered table-striped" style="width:100%">  
               <thead>
                  <tr>
                   
                     <th>Permissions</th>

                         
                  </tr>
               </thead>
                    <tbody>

                     <!--START OF THE DATA SUBMISSION FORM-->

                          <form class="row formularioCrearPaciente" action="php/asignarPermisos.php" method="post" id="FormularioActualizarPaciente">
                        <input type="text" value="<?php   echo $id_grupo_usuarios; ?>" name="id_grupo_usuarios">  
<?php include("php/conexion.php")?>


<?php

//query to display all permissions
$sql = "SELECT * FROM permisos ORDER BY id DESC";

$resultado = $conexion->query($sql);

$listadoPermisos = array('data' => array());


     
   if($resultado->num_rows > 0) { 

//we will show a numbering in the table>>>>numbering: 1, 2, 3....

$numeracion = 0;
 while($fila = $resultado->fetch_array()) { 

    $numeracion = $numeracion + 1;
   
   //the permit id is stored here

   $id_permiso = $fila[0];
    $nombre = $fila['nombre'];

In this second query I get the permissions assigned to a group of users


$consulta2 = "SELECT id_permisos FROM tiene_asignado where id_grupo = $id_grupo_usuarios";

                  $resultados = $conexion->query($consulta2);

                  while( $asignados = $resultados->fetch_array()){

                         //here I store the permissions of the selected checkboxes
         
         $datos=array();

    if (is_array($asignados) == true) {

      //I assign a variable for each selected checkbox in the array
         foreach($asignados as $asignado)

      {

I relate the permissions selected from the checkbox with the id_permisos field of the table (tiene_asignado)

$datos[$asignados['id_permisos']] = true;

         } 
         }else{//END OF is_array($asignados) 

            //this is just a test
               echo "nothing";
            }

   ?>
   
   <tr>
   
      <td>  
       <?php echo $numeracion;?>
       
        <input title='create sheet of <?php echo $id_grupo_usuarios?>' type="checkbox" name="permisos[]" value="<?php echo $id_permiso;?>" class="delete-checkbox" <?php echo isset($datos[$fila[0]]) ? 'checked' : '';?> >
     
  

      
    </tr

I can only see the permissions assigned to the group when I include the input checkbox inside the second WHILE if I don't do it like that, the problem is that the inputs are also repeated, that is, if a group has 3 permissions assigned, each one of the inputs are repeated three times but it shows me the 3 permissions assigned to that group

 <?php   } //END OF THE SECOND WHILE?>

 <?php   } //END OF THE FIRST WHILE?>
          <?php     

             } //END OF IF?>

<?php  ?>
<div class="col-md-6 form-group">
<button type="submit"id="ActualizarPaciente" class="btn btn-primary">Asignar Permisos</button>
</div>
      </form>
<?php


?>
      
    </div>
  </div>
</div>

               

                    </tbody>
            </table> 
        </div>
      </div>
   </div>
</section>

<!-- END OF PAGE CONTENT -->
<!-- Including the footer of the page  -->
<?php include('plantillas/footer.php'); ?>
<!-- script js which contains the functionalities of the permission list page  -->
<!--<script src="js/verpermisosChex.js"></script>-->


  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/32391315) – Dharman May 26 '22 at 09:55

1 Answers1

0

You are selecting all records from permisos and for each record you select all records from tiene_asignado which are in the id_grupo that's matching a value. However, it is clear that your permisos table is logically related to tiene_asignado via the id_permisos field.

So, let's take a look at your second query: it is only loading id_permisos from tiene_asignado and it is safe to assume that your permisos table has an id, maybe called id_permisos, maybe having a different name and you have already loaded the id_permisos value using your first query.

As a result, your second query seems to be unnecessary, so, you will need to remove the second query and the second while (of course, you need the content of the second while, but it does not need to be a loop). If for some reason you need to load from tiene_asignado anyway, then you can modify your first query to be a join. However, if you need help with modifying your first query, you will need to provide information about your tables, at least their fields.

EDIT

based on subsequent information found out since this answer was originally written, I recommend the usage of the following query:

$sql = "SELECT * FROM permisos p LEFT JOIN tiene_asignado ta ON p.id = ta.id_permisos AND id_grupo='".$id_grupo_usuarios."' ";)
Lajos Arpad
  • 53,986
  • 28
  • 88
  • 159
  • Hello @Lajos Arpad, what I need is to assign permissions to a group of users, and for this, first I need to show all the records of the permisos table (to see the permissions registered in the database), the table tiene_asignado is a table that has resulted of an N:N relationship between the permisos and grupo_usuarios table. That's why I thought that doing the two queries I could first obtain all the permissions, and then, the permissions assigned to a specific group of users (in the table tiene_asignado) – user287003 May 26 '22 at 09:05
  • @user287003 I understood this point. But you do not need to do two queries. You will need to `left join` the permissions table with the assigned table in the first query instead. I can help you with that, but you need to edit your question first and share the table structure of `permisos` and `tiene_asignado`. If you run `desc permisos;` and `desc tiene asignado;` directly in MySQL, then you can get those structures. Please share them in your question, let me know when you are done and I will edit my answer. – Lajos Arpad May 26 '22 at 09:08
  • the question has already been edited, I already inserted the structure of the tables although I don't know if I should have also inserted the data that I had already inserted in the tables! – user287003 May 26 '22 at 10:12
  • I have done what you have told me by executing this query **($sql = "SELECT * FROM permisos p LEFT JOIN tiene_asignado ta ON p.id = ta.id_permisos where id_grupo='".$id_grupo_usuarios."' ";)**, it shows me the permissions of the user group that I have chosen, but the problem is that what I need is that all the permissions of the permisos table be displayed and that in terms of the permissions assigned to the group of users, the checkboxes appear in a checked state, I don't know if I'm explaining myself.. – user287003 May 26 '22 at 11:03
  • @user287003 The problem is the `where` clause, that filters out permissions that do not have a match. We want to get unmatched permissions as well, so the `where` criteria needs to be moved into the `on` clause in this case. Will edit my answer shortly, will keep you posted. – Lajos Arpad May 26 '22 at 11:48
  • @user287003 edited my answer with the query I am recommending. – Lajos Arpad May 26 '22 at 11:50
  • @user287003 happy to help. If my answer solved your problem, then you may consider accepting it as the correct answer. – Lajos Arpad May 26 '22 at 12:38
  • Excuse me, how can I do that? – user287003 May 26 '22 at 12:44
  • @user287003 To the left of the answer there is a big 0, which denotes the vote status. Above and below it you see arrows for upvoting or downvoting. Below the downvote arrow there is an unchecked check mark. If you click on that, it will be green, notifying that the answer was accepted and you will earn 2 points for accepting an answer. – Lajos Arpad May 26 '22 at 12:48