To jest część 4 serii poświęconej tworzeniu systemu zarządzania kontami użytkowników w PHP. Pozostałe części znajdziesz tutaj:part1, part2, part 3.
Do tej pory omówiliśmy rejestrację użytkowników i logowanie w obszarze publicznym. Administrator może się zalogować nawet teraz, ale nie pracowaliśmy jeszcze nad tworzeniem kont administratorów. Ponadto, jeśli wpiszesz http://localhost/user-accounts/admin/dashboard.php w przeglądarce, możesz uzyskać dostęp do sekcji administratora bez bycia administratorem. Ale wkrótce to wszystko naprawimy.
W tej części będziemy tworzyć, aktualizować konta użytkowników administracyjnych. Przed aktualizacją konta użytkownika zweryfikujemy również zgodność starego hasła.
W folderze admin/users utwórz te 3 pliki:
- userForm.php:Zawiera formularz do tworzenia i edycji kont użytkowników.
- userList.php:Wyświetla listę wszystkich administratorów systemu.
- userLogic.php:W żargonie MVC (Model-View-Controller) możemy odnosić się do tego jako kontroler użytkownika. Zawiera logikę, taką jak odbieranie informacji o użytkowniku z formularza, zapisywanie ich w bazie danych, ponowne ich pobieranie, manipulowanie nimi i tak dalej.
Zacznijmy od userForm.php. Otwórz go i wklej do niego ten kod.
userForm.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>
Jeśli otworzymy tę stronę w naszej przeglądarce pod adresem http://localhost/user-accounts/admin/users/userForm.php, zobaczymy komunikat o błędzie informujący, że wywołujemy niezdefiniowaną metodę getAllRoles(). Potrzebujemy tej metody, ponieważ aby utworzyć użytkownika admin, musimy wybrać rolę z listy wszystkich ról w bazie danych, aby przypisać temu użytkownikowi. Więc otrzymamy wszystkie role z bazy danych i wypełnimy je w polu wyboru opcji w formularzu.
Stworzymy tę metodę w pliku userLogic.php. Tak:
userLogic.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;
}
Odśwież w przeglądarce, teraz zobaczysz, że błąd zniknął, a nasz formularz jest teraz czysty na środku strony. Fajnie!
Jeśli klikniesz menu roli w formularzu, zauważysz, że nie ma jeszcze żadnych ról. Dzieje się tak, ponieważ stworzyliśmy tabelę ról w bazie danych, ale nie dodaliśmy do niej ról. Używając PHPMyAdmin lub dowolnego klienta MySQL, który posiadasz, dodaj następujące trzy role w tabeli ról w naszej bazie danych:Administrator, Edytor i Autor.
Możesz też po prostu uruchomić to polecenie SQL INSERT, aby wstawić wszystkie trzy role jednocześnie:
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')
Jeśli ponownie załadujesz stronę, te role staną się teraz dostępne w polu wyboru ról.
W tym momencie nie możemy jeszcze utworzyć użytkownika. Ale forma jest już ustalona. Pozostaje tylko kod, do którego trafiają wartości przesłane przez formularz. Umieścimy ten kod w pliku userLogic.php. Otwórz go jeszcze raz i dodajmy pozostały kod wymagany do tworzenia, aktualizacji, edycji i usuwania użytkownika.
userLogic.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);
}
}
Bez wypełniania formularza kliknij przycisk „Zapisz użytkownika”, a zobaczysz, że w formularzu pojawią się komunikaty potwierdzające. Używamy tej samej funkcji validateUser(), którą zdefiniowaliśmy jakiś czas temu. Widzisz więc, jak refaktoryzacja naszego kodu na takie metody chroni nas przed powtarzaniem kodu. Nawet przesyłanie obrazów jest obsługiwane przez funkcję uploadProfileImage() zdefiniowaną w jednym z poprzednich samouczków.
Stwórzmy naszego pierwszego administratora. Wypełnij formularz i kliknij przycisk „Zapisz użytkownika”. To zapisuje naszego administratora w bazie danych i przekierowuje do strony userList.php, która jest na razie pusta.
Plik userList.php ma zawierać listę użytkowników admin dostępnych w bazie danych. Napiszmy więc odpowiedni kod.
userList.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>
W naszym pliku userLogic.php sprzed jakiegoś czasu umieściliśmy metodę o nazwie getAdminUsers(). Ta metoda wybiera wszystkich administratorów z bazy danych do wyświetlenia.
Po prostu odśwież stronę userList.php w przeglądarce i voila! Mamy naszego pierwszego użytkownika Admina wymienionego w tabeli. Kliknij zielony przycisk z ikoną ołówka, aby edytować użytkownika. Możesz także kliknąć czerwony przycisk z ikoną kosza, aby usunąć użytkownika.
Role użytkownika
Teraz możemy stworzyć naszego użytkownika i przypisać mu role, ale co jeśli chcemy dodać kolejną rolę do systemu? Nie możemy polegać na uruchamianiu polecenia bezpośrednio w naszej bazie danych za każdym razem, gdy chcemy utworzyć rolę, prawda? Zakończmy tę sekcję tworzeniem, aktualizowaniem i usuwaniem ról.
Przejdź do folderu admin/roles i utwórz trzy pliki:roleForm.php, roleList.php i roleLogic.php. (Podobny do folderu użytkowników, nie?)
roleForm.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>
Jest to bardzo podobne do tego, co zrobiliśmy w przypadku użytkowników, więc nie będę tutaj zbyt wiele wyjaśniał. Przechodzimy teraz do roleLogic.php, gdzie piszemy kod wymagany do tworzenia, aktualizowania i usuwania ról.
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;
}
Ale kiedy klikniesz przycisk „Zapisz rolę”, wyświetla ostrzeżenie o niezdefiniowanej metodzie validateRole(). Podobnie jak validateUser() dla użytkowników, dodamy tę metodę validateRole() w naszym pliku common_functions.php. Więc otwórz plik i dodaj tę funkcję na dole.
common_functions.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;
}
Kliknij ponownie przycisk Zapisz rolę, a zobaczysz komunikaty o błędach.
Następnym krokiem jest plik roleList.php.
roleList.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>
W przeglądarce przejdź do http://localhost/user-accounts/admin/roles/roleList.php. A teraz możemy również tworzyć, edytować, aktualizować i usuwać role.
Jeszcze raz dziękuję za śledzenie. Mam nadzieję, że zobaczymy się w następnej części, gdzie będziemy pracować nad uprawnieniami i edycją profilu użytkownika.