sql >> Base de Datos >  >> RDS >> Mysql

Gestión de cuentas de usuario, roles, permisos, autenticación PHP y MySQL - Parte 4

Esta es la parte 4 de una serie sobre cómo crear un sistema de administración de cuentas de usuario en PHP. Puede encontrar las otras partes aquí:parte 1, parte 2, parte 3.

Hasta ahora hemos cubierto el registro de usuarios y el inicio de sesión para el área pública. Un usuario administrador puede iniciar sesión incluso como está ahora, pero aún no hemos trabajado en la creación de cuentas de usuario administrador. Además, si ingresa http://localhost/user-accounts/admin/dashboard.php en el navegador, puede acceder a la sección de administración sin ser un usuario administrador. Pero arreglaremos todo eso pronto.

En esta parte, crearemos y actualizaremos cuentas de usuario administrador. También verificaremos que la contraseña anterior coincida antes de actualizar una cuenta de usuario.

Dentro de la carpeta admin/users, cree estos 3 archivos:

  1. userForm.php:contiene el formulario para crear y editar cuentas de usuario.
  2. userList.php:enumera todos los usuarios administrativos del sistema.
  3. userLogic.php:en el lenguaje MVC (Model-View-Controller), podemos referirnos a esto como un controlador de usuario. Contiene la lógica, como recibir información del usuario del formulario, guardarla en la base de datos, recuperarla nuevamente, manipularla, etc.

Comencemos con userForm.php. Ábrelo y pega este código en él.

formulario de usuario.php:

<?php include('../../config.php'); ?>
<?php include(INCLUDE_PATH . '/logic/common_functions.php') ?>
<?php include(ROOT_PATH . '/admin/users/userLogic.php'); ?>
<?php $roles = getAllRoles(); ?>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>UserAccounts - Create Admin user Account</title>
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
    <!-- Custome styles -->
    <link rel="stylesheet" href="../../assets/css/style.css">
  </head>
  <body>
    <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
    <div class="container" style="margin-bottom: 150px;">
      <div class="row">
        <div class="col-md-4 col-md-offset-4">
          <a href="userList.php" class="btn btn-primary" style="margin-bottom: 5px;">
            <span class="glyphicon glyphicon-chevron-left"></span>
            Users
          </a>
          <br>

          <form class="form" action="userForm.php" method="post" enctype="multipart/form-data">
            <?php if ($isEditing === true ): ?>
              <h2 class="text-center">Update Admin user</h2>
            <?php else: ?>
              <h2 class="text-center">Create Admin user</h2>
            <?php endif; ?>
            <hr>
            <!-- if editting user, we need that user's id -->
            <?php if ($isEditing === true): ?>
              <input type="hidden" name="user_id" value="<?php echo $user_id ?>">
            <?php endif; ?>
            <div class="form-group <?php echo isset($errors['username']) ? 'has-error' : '' ?>">
              <label class="control-label">Username</label>
              <input type="text" name="username" value="<?php echo $username; ?>" class="form-control">
              <?php if (isset($errors['username'])): ?>
                <span class="help-block"><?php echo $errors['username'] ?></span>
              <?php endif; ?>
            </div>
            <div class="form-group <?php echo isset($errors['email']) ? 'has-error' : '' ?>">
              <label class="control-label">Email Address</label>
              <input type="email" name="email" value="<?php echo $email; ?>" class="form-control">
              <?php if (isset($errors['email'])): ?>
                <span class="help-block"><?php echo $errors['email'] ?></span>
              <?php endif; ?>
            </div>
            <?php if ($isEditing === true ): ?>
              <div class="form-group <?php echo isset($errors['passwordOld']) ? 'has-error' : '' ?>">
                <label class="control-label">Old Password</label>
                <input type="password" name="passwordOld" class="form-control">
                <?php if (isset($errors['passwordOld'])): ?>
                  <span class="help-block"><?php echo $errors['passwordOld'] ?></span>
                <?php endif; ?>
              </div>
            <?php endif; ?>
            <div class="form-group <?php echo isset($errors['password']) ? 'has-error' : '' ?>">
              <label class="control-label">Your Password</label>
              <input type="password" name="password" class="form-control">
              <?php if (isset($errors['password'])): ?>
                <span class="help-block"><?php echo $errors['password'] ?></span>
              <?php endif; ?>
            </div>
            <div class="form-group <?php echo isset($errors['role_id']) ? 'has-error' : '' ?>">
              <label class="control-label">User Role</label>
              <select class="form-control" name="role_id">
                <option value="" ></option>
                <?php foreach ($roles as $role): ?>
                  <?php if ($role['id'] === $role_id): ?>
                    <option value="<?php echo $role['id'] ?>" selected><?php echo $role['name'] ?></option>
                  <?php else: ?>
                    <option value="<?php echo $role['id'] ?>"><?php echo $role['name'] ?></option>
                  <?php endif; ?>
                <?php endforeach; ?>
              </select>
              <?php if (isset($errors['role_id'])): ?>
                <span class="help-block"><?php echo $errors['role_id'] ?></span>
              <?php endif; ?>
            </div>
            <div class="form-group" style="text-align: center;">
              <?php if (!empty($profile_picture)): ?>
                <img src="<?php echo BASE_URL . '/assets/images/' . $profile_picture; ?>" id="profile_img" style="height: 100px; border-radius: 50%" alt="">
              <?php else: ?>
                <img src="http://via.placeholder.com/150x150" id="profile_img" style="height: 100px; border-radius: 50%" alt="">
              <?php endif; ?>
              <input type="file" name="profile_picture" id="profile_input" value="" style="display: none;">
            </div>
            <div class="form-group">
              <?php if ($isEditing === true): ?>
                <button type="submit" name="update_user" class="btn btn-success btn-block btn-lg">Update user</button>
              <?php else: ?>
                <button type="submit" name="save_user" class="btn btn-success btn-block btn-lg">Save user</button>
              <?php endif; ?>
            </div>
          </form>
        </div>
      </div>
    </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
<script type="text/javascript" src="../../assets/js/display_profile_image.js"></script>

Si abrimos esta página en nuestro navegador en http://localhost/user-accounts/admin/users/userForm.php, vemos un mensaje de error que dice que estamos llamando a un método no definido getAllRoles(). Necesitamos este método porque, para crear un usuario administrador, debemos seleccionar un rol de la lista de todos los roles en la base de datos para asignar a este usuario. Así que obtendremos todos los roles de la base de datos y los completaremos en un campo de selección de opciones en el formulario.

Crearemos este método dentro del archivo userLogic.php. Así:

lógica de usuario.php:

<?php
  // variable declaration. These variables will be used in the user form
  $user_id = 0;
  $role_id = NULL;
  $username = "";
  $email = "";
  $password = "";
  $passwordConf = "";
  $profile_picture = "";
  $isEditing = false;
  $users = array();
  $errors = array();

  function getAllRoles(){
    global $conn;
    $sql = "SELECT id, name FROM roles";
    $stmt = $conn->prepare($sql);
    $stmt->execute();
    $result = $stmt->get_result();
    $roles = $result->fetch_all(MYSQLI_ASSOC);
    return $roles;
  }

Actualice en su navegador ahora verá que el error desapareció y nuestro formulario ahora está limpio en el centro de la página. ¡Genial!

Si hace clic en el menú desplegable de roles en el formulario, notará que todavía no hay roles. Esto se debe a que habíamos creado la tabla de roles en la base de datos pero no le habíamos agregado roles. Usando PHPMyAdmin o cualquier cliente MySQL que tenga, agregue los siguientes tres roles en la tabla de roles en nuestra base de datos:Administrador, Editor y Autor.

O simplemente puede ejecutar este comando de inserción SQL para insertar los tres roles a la vez:

INSERT INTO `roles`(`id`, `name`, `description`) 
VALUES  (1, 'Admin', 'Has authority of users and roles and permissions.' ), 
		(2, 'Author', 'Has full authority of own posts'), 
		(3, 'Editor', 'Has full authority over all posts')

Si vuelve a cargar la página, estos roles ahora estarán disponibles en su campo de selección de roles.

En este punto, todavía no podemos crear un usuario. Pero la forma está lista. Todo lo que queda es el código que recibe los valores enviados por el formulario. Colocaremos este código en el archivo userLogic.php. Ábralo una vez más y agreguemos el código restante necesario para crear, actualizar, editar y eliminar el usuario.

lógica de usuario.php:

// ... variables declaration is up here ...
// ACTION: update user
if (isset($_POST['update_user'])) { // if user clicked update_user button ...
    $user_id = $_POST['user_id'];
    updateUser($user_id);
}
// ACTION: Save User
if (isset($_POST['save_user'])) {  // if user clicked save_user button ...
    saveUser();
}
// ACTION: fetch user for editting
if (isset($_GET["edit_user"])) {
  $user_id = $_GET["edit_user"];
  editUser($user_id);
}
// ACTION: Delete user
if (isset($_GET['delete_user'])) {
  $user_id = $_GET['delete_user'];
  deleteUser($user_id);
}

function updateUser($user_id) {
  global $conn, $errors, $username, $role_id, $email, $isEditing;
  $errors = validateUser($_POST, ['update_user', 'update_profile']);

  // receive all input values from the form
  $username = $_POST['username'];
  $email = $_POST['email'];
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT); //encrypt the password before saving in the database
  $profile_picture = uploadProfilePicture();
  if (count($errors) === 0) {
    if (isset($_POST['role_id'])) {
      $role_id = $_POST['role_id'];
    }
    $sql = "UPDATE users SET username=?, role_id=?, email=?, password=?, profile_picture=? WHERE id=?";
    $result = modifyRecord($sql, 'sisssi', [$username, $role_id, $email, $password, $profile_picture, $user_id]);

    if ($result) {
      $_SESSION['success_msg'] = "User account successfully updated";
      header("location: " . BASE_URL . "admin/users/userList.php");
      exit(0);
    }
  } else {
    // continue editting if there were errors
    $isEditing = true;
  }
}
// Save user to database
function saveUser(){
  global $conn, $errors, $username, $role_id, $email, $isEditing;
  $errors = validateUser($_POST, ['save_user']);
  // receive all input values from the form
  $username = $_POST['username'];
  $email = $_POST['email'];
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT); //encrypt the password before saving in the database
  $profile_picture = uploadProfilePicture(); // upload profile picture and return the picture name
  if (count($errors) === 0) {
    if (isset($_POST['role_id'])) {
      $role_id = $_POST['role_id'];
    }
    $sql = "INSERT INTO users SET username=?, role_id=?, email=?, password=?, profile_picture=?";
    $result = modifyRecord($sql, 'sisss', [$username, $role_id, $email, $password, $profile_picture]);

    if($result){
      $_SESSION['success_msg'] = "User account created successfully";
      header("location: " . BASE_URL . "admin/users/userList.php");
      exit(0);
    } else {
      $_SESSION['error_msg'] = "Something went wrong. Could not save user in Database";
    }
  }
}
function getAdminUsers(){
  global $conn;
  // for every user, select a user role name from roles table, and then id, role_id and username from user table
  // where the role_id on user table matches the id on roles table
  $sql = "SELECT r.name as role, u.id, u.role_id, u.username
          FROM users u
          LEFT JOIN roles r ON u.role_id=r.id
          WHERE role_id IS NOT NULL AND u.id != ?";

  $users = getMultipleRecords($sql, 'i', [$_SESSION['user']['id']]);
  return $users;
}

function editUser($user_id){
  global $conn, $user_id, $role_id, $username, $email, $isEditing, $profile_picture;

  $sql = "SELECT * FROM users WHERE id=?";
  $user = getSingleRecord($sql, 'i', [$user_id]);

  $user_id = $user['id'];
  $role_id = $user['role_id'];
  $username = $user['username'];
  $profile_picture = $user['profile_picture'];
  $email = $user['email'];
  $isEditing = true;
}
function deleteUser($user_id) {
  global $conn;
  $sql = "DELETE FROM users WHERE id=?";
  $result = modifyRecord($sql, 'i', [$user_id]);

  if ($result) {
    $_SESSION['success_msg'] = "User trashed!!";
    header("location: " . BASE_URL . "admin/users/userList.php");
    exit(0);
  }
}

Sin rellenar el formulario, haz clic en el botón 'Guardar usuario' y verás que aparecen los mensajes de validación en el formulario. Estamos usando la misma función validarUser() que definimos hace un tiempo. Entonces puede ver cómo la refactorización de nuestro código en dichos métodos nos evita repetir el código. Incluso la carga de imágenes es manejada por uploadProfileImage() definido en uno de los tutoriales anteriores.

Vamos a crear nuestro primer usuario administrador. Rellene el formulario y haga clic en el botón 'Guardar usuario'. Esto guarda a nuestro usuario administrador en la base de datos y lo redirige a la página userList.php que está vacía por ahora.

Se supone que el archivo userList.php enumera los usuarios administradores disponibles en la base de datos. Así que escribamos el código para eso.

listausuarios.php:

<?php include('../../config.php') ?>
<?php include(ROOT_PATH . '/admin/users/userLogic.php') ?>
<?php
  $adminUsers = getAdminUsers();
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Admin Area - Users </title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custome styles -->
  <link rel="stylesheet" href="../../static/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
  <div class="col-md-8 col-md-offset-2">
    <a href="userForm.php" class="btn btn-success">
      <span class="glyphicon glyphicon-plus"></span>
      Create new user
    </a>
    <hr>
    <h1 class="text-center">Admin Users</h1>
    <br />
    <?php if (isset($users)): ?>
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>N</th>
            <th>Username</th>
            <th>Role</th>
            <th colspan="2" class="text-center">Action</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach ($adminUsers as $key => $value): ?>
            <tr>
              <td><?php echo $key + 1; ?></td>
              <td><?php echo $value['username'] ?></td>
              <td><?php echo $value['role']; ?></td>
              <td class="text-center">
                <a href="<?php echo BASE_URL ?>admin/users/userForm.php?edit_user=<?php echo $value['id'] ?>" class="btn btn-sm btn-success">
                  <span class="glyphicon glyphicon-pencil"></span>
                </a>
              </td>
              <td class="text-center">
                <a href="<?php echo BASE_URL ?>admin/users/userForm.php?delete_user=<?php echo $value['id'] ?>" class="btn btn-sm btn-danger">
                  <span class="glyphicon glyphicon-trash"></span>
                </a>
              </td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    <?php else: ?>
      <h2 class="text-center">No users in database</h2>
    <?php endif; ?>
  </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
</body>
</html>

En nuestro archivo userLogic.php de hace un tiempo, incluimos un método llamado getAdminUsers(). Este método selecciona todos los usuarios administradores de la base de datos para mostrarlos.

¡Simplemente actualice la página userList.php en el navegador y listo! Tenemos nuestro primer usuario administrador listado en una tabla. Haga clic en el botón verde con el icono del lápiz para editar el usuario. También puede hacer clic en el botón rojo con el icono de la papelera para eliminar el usuario.

Funciones de usuario

Ahora podemos crear nuestro usuario y asignarle roles, pero ¿y si queremos agregar otro rol al sistema? No podemos confiar en ejecutar un comando directamente en nuestra base de datos cada vez que queremos crear un rol, ¿verdad? Terminemos esta sección con Creación, actualización y eliminación de funciones.

Vaya a la carpeta admin/roles y cree tres archivos:roleForm.php, roleList.php y roleLogic.php. (Similar a la carpeta de usuarios, ¿no?)

rolForm.php:

<?php include('../../config.php') ?>
<?php include(ROOT_PATH . '/includes/logic/common_functions.php') ?>
<?php include(ROOT_PATH . '/admin/roles/roleLogic.php') ?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Admin - Create new role </title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custom styles -->
  <link rel="stylesheet" href="../../static/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
  <div class="col-md-8 col-md-offset-2">
      <a href="roleList.php" class="btn btn-primary">
        <span class="glyphicon glyphicon-chevron-left"></span>
        Roles
      </a>
      <hr>
      <form class="form" action="roleForm.php" method="post">
        <?php if ($isEditting === true): ?>
          <h1 class="text-center">Update Role</h1>
        <?php else: ?>
          <h1 class="text-center">Create Role</h1>
        <?php endif; ?>
        <br />

        <?php if ($isEditting === true): ?>
          <input type="hidden" name="role_id" value="<?php echo $role_id ?>">
        <?php endif; ?>
        <div class="form-group <?php echo isset($errors['name']) ? 'has-error': '' ?>">
          <label class="control-label">Role name</label>
          <input type="text" name="name" value="<?php echo $name; ?>" class="form-control">
          <?php if (isset($errors['name'])): ?>
            <span class="help-block"><?php echo $errors['name'] ?></span>
          <?php endif; ?>
        </div>
        <div class="form-group <?php echo isset($errors['description']) ? 'has-error': '' ?>">
          <label class="control-label">Description</label>
          <textarea name="description" value="<?php echo $description; ?>"  rows="3" cols="10" class="form-control"><?php echo $description; ?></textarea>
          <?php if (isset($errors['description'])): ?>
            <span class="help-block"><?php echo $errors['description'] ?></span>
          <?php endif; ?>
        </div>
        <div class="form-group">
          <?php if ($isEditting === true): ?>
            <button type="submit" name="update_role" class="btn btn-primary">Update Role</button>
          <?php else: ?>
            <button type="submit" name="save_role" class="btn btn-success">Save Role</button>
          <?php endif; ?>
        </div>
      </form>
  </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
</body>
</html>

Esto es muy similar a lo que hicimos en el caso de los usuarios, así que no daré mucha explicación aquí. Procedemos ahora a roleLogic.php donde escribimos el código requerido para crear, actualizar y eliminar roles.

roleLogic.php:

<?php
  $role_id = 0;
  $name = "";
  $description = "";
  $isEditting = false;
  $roles = array();
  $errors = array();

  // ACTION: update role
  if (isset($_POST['update_role'])) {
      $role_id = $_POST['role_id'];
      updateRole($role_id);
  }
  // ACTION: Save Role
  if (isset($_POST['save_role'])) {
      saveRole();
  }
  // ACTION: fetch role for editting
  if (isset($_GET["edit_role"])) {
    $role_id = $_GET['edit_role'];
    editRole($role_id);
  }
  // ACTION: Delete role
  if (isset($_GET['delete_role'])) {
    $role_id = $_GET['delete_role'];
    deleteRole($role_id);
  }
  // Save role to database
  function saveRole(){
    global $conn, $errors, $name, $description;
    $errors = validateRole($_POST, ['save_role']);
    if (count($errors) === 0) {
       // receive form values
       $name = $_POST['name'];
       $description = $_POST['description'];
       $sql = "INSERT INTO roles SET name=?, description=?";
       $result = modifyRecord($sql, 'ss', [$name, $description]);

       if ($result) {
         $_SESSION['success_msg'] = "Role created successfully";
         header("location: " . BASE_URL . "admin/roles/roleList.php");
         exit(0);
       } else {
         $_SESSION['error_msg'] = "Something went wrong. Could not save role in Database";
       }
    }
  }
  function updateRole($role_id){
    global $conn, $errors, $name, $isEditting; // pull in global form variables into function
    $errors = validateRole($_POST, ['update_role']); // validate form
    if (count($errors) === 0) {
      // receive form values
      $name = $_POST['name'];
      $description = $_POST['description'];
      $sql = "UPDATE roles SET name=?, description=? WHERE id=?";
      $result = modifyRecord($sql, 'ssi', [$name, $description, $role_id]);

      if ($result) {
        $_SESSION['success_msg'] = "Role successfully updated";
        $isEditting = false;
        header("location: " . BASE_URL . "admin/roles/roleList.php");
        exit(0);
      } else {
        $_SESSION['error_msg'] = "Something went wrong. Could not save role in Database";
      }
    }
  }
  function editRole($role_id){
    global $conn, $name, $description, $isEditting;
    $sql = "SELECT * FROM roles WHERE id=? LIMIT 1";
    $role = getSingleRecord($sql, 'i', [$role_id]);

    $role_id = $role['id'];
    $name = $role['name'];
    $description = $role['description'];
    $isEditting = true;
  }
  function deleteRole($role_id) {
    global $conn;
    $sql = "DELETE FROM roles WHERE id=?";
    $result = modifyRecord($sql, 'i', [$role_id]);
    if ($result) {
      $_SESSION['success_msg'] = "Role trashed!!";
      header("location: " . BASE_URL . "admin/roles/roleList.php");
      exit(0);
    }
  }
  function getAllRoles(){
    global $conn;
    $sql = "SELECT id, name FROM roles";
    $roles = getMultipleRecords($sql);
    return $roles;
  }

Pero cuando hace clic en el botón 'Guardar rol', muestra una advertencia sobre un método de validación de rol () indefinido. Al igual que el método validateUser() para usuarios, agregaremos este método validateRole() en nuestro archivo common_functions.php. Así que abra el archivo y agregue esta función al final.

funciones_comunes.php:

// ... other functions up here ...

// Accept a post object, validates post and return an array with the error messages
function validateRole($role, $ignoreFields) {
    global $conn;
    $errors = [];
    foreach ($role as $key => $value) {
      if (in_array($key, $ignoreFields)) {
          continue;
      }
      if (empty($role[$key])) {
        $errors[$key] = "This field is required";
      }
    }
    return $errors;
}

Haga clic en el botón Guardar rol nuevamente y verá los mensajes de error que se muestran.

El siguiente es el archivo roleList.php.

lista de roles.php:

<?php include('../../config.php') ?>
<?php include(ROOT_PATH . '/admin/roles/roleLogic.php') ?>
<?php
  $roles = getAllRoles();
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Admin Area - User Roles </title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custome styles -->
  <link rel="stylesheet" href="../../static/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
  <div class="col-md-8 col-md-offset-2">
    <a href="roleForm.php" class="btn btn-success">
      <span class="glyphicon glyphicon-plus"></span>
      Create new role
    </a>
    <hr>
    <h1 class="text-center">User Roles</h1>
    <br />
    <?php if (isset($roles)): ?>
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>N</th>
            <th>Role name</th>
            <th colspan="3" class="text-center">Action</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach ($roles as $key => $value): ?>
            <tr>
              <td><?php echo $key + 1; ?></td>
              <td><?php echo $value['name'] ?></td>
              <td class="text-center">
                <a href="<?php echo BASE_URL ?>admin/roles/assignPermissions.php?assign_permissions=<?php echo $value['id'] ?>" class="btn btn-sm btn-info">
                  permissions
                </a>
              </td>
              <td class="text-center">
                <a href="<?php echo BASE_URL ?>admin/roles/roleForm.php?edit_role=<?php echo $value['id'] ?>" class="btn btn-sm btn-success">
                  <span class="glyphicon glyphicon-pencil"></span>
                </a>
              </td>
              <td class="text-center">
                <a href="<?php echo BASE_URL ?>admin/roles/roleForm.php?delete_role=<?php echo $value['id'] ?>" class="btn btn-sm btn-danger">
                  <span class="glyphicon glyphicon-trash"></span>
                </a>
              </td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    <?php else: ?>
      <h2 class="text-center">No roles in database</h2>
    <?php endif; ?>
  </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
</body>
</html>

En su navegador, vaya a http://localhost/user-accounts/admin/roles/roleList.php. Y ahora también podemos crear, editar, actualizar y eliminar roles.

Una vez más gracias por seguir. Con suerte, te veré en la siguiente parte donde trabajaremos en los permisos y la edición del perfil de usuario.